| 56 |
#define INTBLOB_LEN 20 |
#define INTBLOB_LEN 20 |
| 57 |
#define SIGBLOB_LEN (2*INTBLOB_LEN) |
#define SIGBLOB_LEN (2*INTBLOB_LEN) |
| 58 |
|
|
| 59 |
|
// |
| 60 |
|
// SSH2 data structure |
| 61 |
|
// |
| 62 |
|
|
| 63 |
|
// channel data structure |
| 64 |
|
#define CHANNEL_MAX 100 |
| 65 |
|
|
| 66 |
|
enum channel_type { |
| 67 |
|
TYPE_SHELL, TYPE_PORTFWD, |
| 68 |
|
}; |
| 69 |
|
|
| 70 |
|
typedef struct bufchain { |
| 71 |
|
buffer_t *msg; |
| 72 |
|
struct bufchain *next; |
| 73 |
|
} bufchain_t; |
| 74 |
|
|
| 75 |
|
typedef struct channel { |
| 76 |
|
int used; |
| 77 |
|
int self_id; |
| 78 |
|
int remote_id; |
| 79 |
|
unsigned int local_window; |
| 80 |
|
unsigned int local_window_max; |
| 81 |
|
unsigned int local_consumed; |
| 82 |
|
unsigned int local_maxpacket; |
| 83 |
|
unsigned int remote_window; |
| 84 |
|
unsigned int remote_maxpacket; |
| 85 |
|
enum channel_type type; |
| 86 |
|
int local_num; |
| 87 |
|
bufchain_t *bufchain; |
| 88 |
|
} Channel_t; |
| 89 |
|
|
| 90 |
|
static Channel_t channels[CHANNEL_MAX]; |
| 91 |
|
|
| 92 |
static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04"; |
static char ssh_ttymodes[] = "\x01\x03\x02\x1c\x03\x08\x04\x15\x05\x04"; |
| 93 |
|
|
| 94 |
static void try_send_credentials(PTInstVar pvar); |
static void try_send_credentials(PTInstVar pvar); |
| 124 |
void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end); |
void SSH2_dispatch_add_range_message(unsigned char begin, unsigned char end); |
| 125 |
int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); |
int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); |
| 126 |
static void start_ssh_heartbeat_thread(PTInstVar pvar); |
static void start_ssh_heartbeat_thread(PTInstVar pvar); |
| 127 |
|
static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen); |
|
|
|
|
// |
|
|
// SSH2 data structure |
|
|
// |
|
|
|
|
|
// channel data structure |
|
|
#define CHANNEL_MAX 100 |
|
|
|
|
|
enum channel_type { |
|
|
TYPE_SHELL, TYPE_PORTFWD, |
|
|
}; |
|
|
|
|
|
typedef struct bufchain { |
|
|
buffer_t *msg; |
|
|
struct bufchain *next; |
|
|
} bufchain_t; |
|
|
|
|
|
typedef struct channel { |
|
|
int used; |
|
|
int self_id; |
|
|
int remote_id; |
|
|
unsigned int local_window; |
|
|
unsigned int local_window_max; |
|
|
unsigned int local_consumed; |
|
|
unsigned int local_maxpacket; |
|
|
unsigned int remote_window; |
|
|
unsigned int remote_maxpacket; |
|
|
enum channel_type type; |
|
|
int local_num; |
|
|
bufchain_t *bufchain; |
|
|
} Channel_t; |
|
|
|
|
|
static Channel_t channels[CHANNEL_MAX]; |
|
| 128 |
|
|
| 129 |
// |
// |
| 130 |
// channel function |
// channel function |
| 2617 |
} |
} |
| 2618 |
|
|
| 2619 |
} else { // for SSH2(yutaka) |
} else { // for SSH2(yutaka) |
| 2620 |
buffer_t *msg; |
Channel_t *c = ssh2_channel_lookup(pvar->shell_id); |
| 2621 |
unsigned char *outmsg; |
SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen); |
|
unsigned int len; |
|
|
Channel_t *c; |
|
|
|
|
|
// SSH2鍵交換中の場合、パケットを捨てる。(2005.6.19 yutaka) |
|
|
if (pvar->rekeying) { |
|
|
// TODO: 理想としてはパケット破棄ではなく、パケット読み取り遅延にしたいところだが、 |
|
|
// 将来直すことにする。 |
|
|
c = NULL; |
|
|
|
|
|
return; |
|
|
} |
|
|
|
|
|
c = ssh2_channel_lookup(pvar->shell_id); |
|
|
if (c == NULL) |
|
|
return; |
|
|
|
|
|
if (buflen > c->remote_window) { |
|
|
buflen = c->remote_window; |
|
|
} |
|
|
if (buflen > 0) { |
|
|
msg = buffer_init(); |
|
|
if (msg == NULL) { |
|
|
// TODO: error check |
|
|
return; |
|
|
} |
|
|
buffer_put_int(msg, c->remote_id); |
|
|
buffer_put_string(msg, (char *)buf, buflen); |
|
|
|
|
|
len = buffer_len(msg); |
|
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
|
|
memcpy(outmsg, buffer_ptr(msg), len); |
|
|
finish_send_packet(pvar); |
|
|
buffer_free(msg); |
|
|
|
|
|
// remote window sizeの調整 |
|
|
if (buflen <= c->remote_window) { |
|
|
c->remote_window -= buflen; |
|
|
} |
|
|
else { |
|
|
c->remote_window = 0; |
|
|
} |
|
|
} |
|
| 2622 |
} |
} |
| 2623 |
|
|
| 2624 |
} |
} |
| 2832 |
|
|
| 2833 |
} |
} |
| 2834 |
|
|
| 2835 |
|
static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen) |
| 2836 |
|
{ |
| 2837 |
|
buffer_t *msg; |
| 2838 |
|
unsigned char *outmsg; |
| 2839 |
|
unsigned int len; |
| 2840 |
|
|
| 2841 |
|
// SSH2鍵交換中の場合、パケットを捨てる。(2005.6.19 yutaka) |
| 2842 |
|
if (pvar->rekeying) { |
| 2843 |
|
// TODO: 理想としてはパケット破棄ではなく、パケット読み取り遅延にしたいところだが、 |
| 2844 |
|
// 将来直すことにする。 |
| 2845 |
|
c = NULL; |
| 2846 |
|
|
| 2847 |
|
return; |
| 2848 |
|
} |
| 2849 |
|
|
| 2850 |
|
if (c == NULL) |
| 2851 |
|
return; |
| 2852 |
|
|
| 2853 |
|
if ((unsigned int)buflen > c->remote_window) { |
| 2854 |
|
unsigned int offset = c->remote_window; |
| 2855 |
|
// 送れないデータはいったん保存しておく |
| 2856 |
|
ssh2_channel_add_bufchain(c, buf + offset, buflen - offset); |
| 2857 |
|
buflen = offset; |
| 2858 |
|
} |
| 2859 |
|
if (buflen > 0) { |
| 2860 |
|
msg = buffer_init(); |
| 2861 |
|
if (msg == NULL) { |
| 2862 |
|
// TODO: error check |
| 2863 |
|
return; |
| 2864 |
|
} |
| 2865 |
|
buffer_put_int(msg, c->remote_id); |
| 2866 |
|
buffer_put_string(msg, (char *)buf, buflen); |
| 2867 |
|
|
| 2868 |
|
len = buffer_len(msg); |
| 2869 |
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
| 2870 |
|
//if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0; |
| 2871 |
|
memcpy(outmsg, buffer_ptr(msg), len); |
| 2872 |
|
finish_send_packet(pvar); |
| 2873 |
|
buffer_free(msg); |
| 2874 |
|
//debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len); |
| 2875 |
|
|
| 2876 |
|
// remote window sizeの調整 |
| 2877 |
|
if (buflen <= c->remote_window) { |
| 2878 |
|
c->remote_window -= buflen; |
| 2879 |
|
} |
| 2880 |
|
else { |
| 2881 |
|
c->remote_window = 0; |
| 2882 |
|
} |
| 2883 |
|
} |
| 2884 |
|
} |
| 2885 |
|
|
| 2886 |
/* support for port forwarding */ |
/* support for port forwarding */ |
| 2887 |
void SSH_channel_send(PTInstVar pvar, int channel_num, |
void SSH_channel_send(PTInstVar pvar, int channel_num, |
| 2888 |
uint32 remote_channel_num, |
uint32 remote_channel_num, |
| 2889 |
unsigned char FAR * buf, int len) |
unsigned char FAR * buf, int len) |
| 2890 |
{ |
{ |
|
unsigned int buflen = len; |
|
|
|
|
| 2891 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 2892 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2893 |
begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len); |
begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len); |
| 2932 |
|
|
| 2933 |
} else { |
} else { |
| 2934 |
// ポートフォワーディングにおいてクライアントからの送信要求を、SSH通信に乗せてサーバまで送り届ける。 |
// ポートフォワーディングにおいてクライアントからの送信要求を、SSH通信に乗せてサーバまで送り届ける。 |
| 2935 |
buffer_t *msg; |
Channel_t *c = ssh2_local_channel_lookup(channel_num); |
| 2936 |
unsigned char *outmsg; |
SSH2_send_channel_data(pvar, c, buf, len); |
|
unsigned int len; |
|
|
Channel_t *c; |
|
|
|
|
|
// SSH2鍵交換中の場合、パケットを捨てる。(2005.6.19 yutaka) |
|
|
if (pvar->rekeying) { |
|
|
// TODO: 理想としてはパケット破棄ではなく、パケット読み取り遅延にしたいところだが、 |
|
|
// 将来直すことにする。 |
|
|
c = NULL; |
|
|
|
|
|
return; |
|
|
} |
|
|
|
|
|
c = ssh2_local_channel_lookup(channel_num); |
|
|
if (c == NULL) |
|
|
return; |
|
|
|
|
|
if ((unsigned int)buflen > c->remote_window) { |
|
|
unsigned int offset = c->remote_window; |
|
|
// 送れないデータはいったん保存しておく |
|
|
ssh2_channel_add_bufchain(c, buf + offset, buflen - offset); |
|
|
buflen = offset; |
|
|
} |
|
|
if (buflen > 0) { |
|
|
msg = buffer_init(); |
|
|
if (msg == NULL) { |
|
|
// TODO: error check |
|
|
return; |
|
|
} |
|
|
buffer_put_int(msg, c->remote_id); |
|
|
buffer_put_string(msg, (char *)buf, buflen); |
|
|
|
|
|
len = buffer_len(msg); |
|
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
|
|
//if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0; |
|
|
memcpy(outmsg, buffer_ptr(msg), len); |
|
|
finish_send_packet(pvar); |
|
|
buffer_free(msg); |
|
|
//debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len); |
|
|
|
|
|
// remote window sizeの調整 |
|
|
if (buflen <= c->remote_window) { |
|
|
c->remote_window -= buflen; |
|
|
} |
|
|
else { |
|
|
c->remote_window = 0; |
|
|
} |
|
|
} |
|
| 2937 |
} |
} |
| 2938 |
|
|
| 2939 |
} |
} |