| 109 |
#define CHANNEL_MAX 100 |
#define CHANNEL_MAX 100 |
| 110 |
|
|
| 111 |
enum channel_type { |
enum channel_type { |
| 112 |
TYPE_SHELL, TYPE_PORTFWD, |
TYPE_SHELL, TYPE_PORTFWD, |
| 113 |
}; |
}; |
| 114 |
|
|
| 115 |
typedef struct channel { |
typedef struct channel { |
| 263 |
|
|
| 264 |
static memtag_t memtags[MEMTAG_MAX]; |
static memtag_t memtags[MEMTAG_MAX]; |
| 265 |
static int memtag_count = 0; |
static int memtag_count = 0; |
| 266 |
static int memtag_use = 0; |
static int memtag_use = 0; |
| 267 |
|
|
| 268 |
/* ダンプラインをフォーマット表示する */ |
/* ダンプラインをフォーマット表示する */ |
| 269 |
static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt) |
static void displine_memdump(FILE *fp, int addr, int *bytes, int byte_cnt) |
| 665 |
|
|
| 666 |
if (pvar->decomp_buffer == NULL) { |
if (pvar->decomp_buffer == NULL) { |
| 667 |
pvar->decomp_buffer = buffer_init(); |
pvar->decomp_buffer = buffer_init(); |
| 668 |
if (pvar->decomp_buffer == NULL) |
if (pvar->decomp_buffer == NULL) |
| 669 |
return SSH_MSG_NONE; |
return SSH_MSG_NONE; |
| 670 |
} |
} |
| 671 |
// 一度確保したバッファは使い回すので初期化を忘れずに。 |
// 一度確保したバッファは使い回すので初期化を忘れずに。 |
| 731 |
|
|
| 732 |
#define finish_send_packet(pvar) finish_send_packet_special((pvar), 0) |
#define finish_send_packet(pvar) finish_send_packet_special((pvar), 0) |
| 733 |
|
|
| 734 |
// 送信リトライ関数の追加 |
// 送信リトライ関数の追加 |
| 735 |
// |
// |
| 736 |
// WinSockの send() はバッファサイズ(len)よりも少ない値を正常時に返してくる |
// WinSockの send() はバッファサイズ(len)よりも少ない値を正常時に返してくる |
| 737 |
// ことがあるので、その場合はエラーとしない。 |
// ことがあるので、その場合はエラーとしない。 |
| 853 |
データ構造 |
データ構造 |
| 854 |
pvar->ssh_state.outbuf: |
pvar->ssh_state.outbuf: |
| 855 |
offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD |
offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ... EOD |
| 856 |
<--ignore---> ^^^^^^^^ <---- payload ---> |
<--ignore---> ^^^^^^^^ <---- payload ---> |
| 857 |
packet length |
packet length |
| 858 |
|
|
| 859 |
^^padding |
^^padding |
| 860 |
|
|
| 861 |
<----------------------------> |
<----------------------------> |
| 862 |
SSH2 sending data on TCP |
SSH2 sending data on TCP |
| 863 |
|
|
| 864 |
NOTE: |
NOTE: |
| 865 |
payload = type(1) + raw-data |
payload = type(1) + raw-data |
| 866 |
len = ssh_state.outgoing_packet_len = payload size |
len = ssh_state.outgoing_packet_len = payload size |
| 871 |
pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) && |
pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) && |
| 872 |
pvar->ssh2_keys[MODE_OUT].comp.enabled) { |
pvar->ssh2_keys[MODE_OUT].comp.enabled) { |
| 873 |
// このバッファは packet-length(4) + padding(1) + payload(any) を示す。 |
// このバッファは packet-length(4) + padding(1) + payload(any) を示す。 |
| 874 |
msg = buffer_init(); |
msg = buffer_init(); |
| 875 |
if (msg == NULL) { |
if (msg == NULL) { |
| 876 |
// TODO: error check |
// TODO: error check |
| 877 |
return; |
return; |
| 924 |
|
|
| 925 |
pvar->ssh_state.sender_sequence_number++; |
pvar->ssh_state.sender_sequence_number++; |
| 926 |
|
|
| 927 |
// 送信時刻を記録 |
// 送信時刻を記録 |
| 928 |
pvar->ssh_heartbeat_tick = time(NULL); |
pvar->ssh_heartbeat_tick = time(NULL); |
| 929 |
} |
} |
| 930 |
|
|
| 1432 |
enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug); |
enque_handler(pvar, SSH2_MSG_DEBUG, handle_debug); |
| 1433 |
enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit); |
enque_handler(pvar, SSH2_MSG_KEXINIT, handle_SSH2_kexinit); |
| 1434 |
enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented); |
enque_handler(pvar, SSH2_MSG_KEXDH_INIT, handle_unimplemented); |
| 1435 |
enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply); |
enque_handler(pvar, SSH2_MSG_KEXDH_REPLY, handle_SSH2_dh_common_reply); |
| 1436 |
enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply); |
enque_handler(pvar, SSH2_MSG_KEX_DH_GEX_REPLY, handle_SSH2_dh_gex_reply); |
| 1437 |
enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys); |
enque_handler(pvar, SSH2_MSG_NEWKEYS, handle_SSH2_newkeys); |
| 1438 |
enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest); |
enque_handler(pvar, SSH2_MSG_SERVICE_ACCEPT, handle_SSH2_authrequest); |
| 1439 |
enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success); |
enque_handler(pvar, SSH2_MSG_USERAUTH_SUCCESS, handle_SSH2_userauth_success); |
| 1488 |
#if 0 |
#if 0 |
| 1489 |
// for calculate SSH2 hash |
// for calculate SSH2 hash |
| 1490 |
// サーババージョンの保存(改行は取り除くこと) |
// サーババージョンの保存(改行は取り除くこと) |
| 1491 |
if (ID_len >= sizeof(pvar->server_version_string)) |
if (ID_len >= sizeof(pvar->server_version_string)) |
| 1492 |
return FALSE; |
return FALSE; |
| 1493 |
strncpy(pvar->server_version_string, ID, ID_len); |
strncpy(pvar->server_version_string, ID, ID_len); |
| 1494 |
#endif |
#endif |
| 1602 |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
| 1603 |
pvar->ssh_state.payload + 8, local_port, |
pvar->ssh_state.payload + 8, local_port, |
| 1604 |
pvar->ssh_state.payload + 16 + host_len, |
pvar->ssh_state.payload + 16 + host_len, |
| 1605 |
originator_len, |
originator_len, |
| 1606 |
NULL); |
NULL); |
| 1607 |
} |
} |
| 1608 |
} else { |
} else { |
| 2045 |
= { handle_TIS_challenge, handle_auth_failure }; |
= { handle_TIS_challenge, handle_auth_failure }; |
| 2046 |
|
|
| 2047 |
// SSH2の場合は以下の処理をスキップ |
// SSH2の場合は以下の処理をスキップ |
| 2048 |
if (SSHv2(pvar)) |
if (SSHv2(pvar)) |
| 2049 |
goto skip_ssh2; |
goto skip_ssh2; |
| 2050 |
|
|
| 2051 |
switch (cred->method) { |
switch (cred->method) { |
| 2332 |
// TODO: error check |
// TODO: error check |
| 2333 |
return; |
return; |
| 2334 |
} |
} |
| 2335 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 2336 |
|
|
| 2337 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 2338 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_CLOSE, len); |
| 2386 |
// TODO: error check |
// TODO: error check |
| 2387 |
return; |
return; |
| 2388 |
} |
} |
| 2389 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 2390 |
s = "window-change"; |
s = "window-change"; |
| 2391 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 2392 |
buffer_put_char(msg, 0); // wantconfirm |
buffer_put_char(msg, 0); // wantconfirm |
| 2393 |
buffer_put_int(msg, pvar->ssh_state.win_cols); // columns |
buffer_put_int(msg, pvar->ssh_state.win_cols); // columns |
| 2394 |
buffer_put_int(msg, pvar->ssh_state.win_rows); // lines |
buffer_put_int(msg, pvar->ssh_state.win_rows); // lines |
| 2914 |
// TODO: error check |
// TODO: error check |
| 2915 |
return; |
return; |
| 2916 |
} |
} |
| 2917 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 2918 |
buffer_put_int(msg, c->self_id); |
buffer_put_int(msg, c->self_id); |
| 2919 |
buffer_put_int(msg, c->local_window); |
buffer_put_int(msg, c->local_window); |
| 2920 |
buffer_put_int(msg, c->local_maxpacket); |
buffer_put_int(msg, c->local_maxpacket); |
| 2921 |
|
|
| 2922 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 2923 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len); |
| 3021 |
buffer_put_string(msg, s, strlen(s)); // ctype |
buffer_put_string(msg, s, strlen(s)); // ctype |
| 3022 |
buffer_put_char(msg, 1); // want reply |
buffer_put_char(msg, 1); // want reply |
| 3023 |
s = "0.0.0.0"; |
s = "0.0.0.0"; |
| 3024 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 3025 |
|
|
| 3026 |
buffer_put_int(msg, from_server_port); // listening port |
buffer_put_int(msg, from_server_port); // listening port |
| 3027 |
|
|
| 3081 |
} |
} |
| 3082 |
|
|
| 3083 |
c = ssh2_channel_lookup(pvar->shell_id); |
c = ssh2_channel_lookup(pvar->shell_id); |
| 3084 |
if (c == NULL) |
if (c == NULL) |
| 3085 |
return; |
return; |
| 3086 |
|
|
| 3087 |
// making the fake data |
// making the fake data |
| 3094 |
} |
} |
| 3095 |
newdata[newlen - 1] = '\0'; |
newdata[newlen - 1] = '\0'; |
| 3096 |
|
|
| 3097 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 3098 |
s = "x11-req"; |
s = "x11-req"; |
| 3099 |
buffer_put_string(msg, s, strlen(s)); // service name |
buffer_put_string(msg, s, strlen(s)); // service name |
| 3100 |
buffer_put_char(msg, 0); // want confirm (false) |
buffer_put_char(msg, 0); // want confirm (false) |
| 3101 |
buffer_put_char(msg, 0); // XXX bool single connection |
buffer_put_char(msg, 0); // XXX bool single connection |
| 3102 |
|
|
| 3103 |
s = auth_protocol; // MIT-MAGIC-COOKIE-1 |
s = auth_protocol; // MIT-MAGIC-COOKIE-1 |
| 3104 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 3105 |
s = newdata; |
s = newdata; |
| 3106 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 3107 |
|
|
| 3108 |
buffer_put_int(msg, screen_num); |
buffer_put_int(msg, screen_num); |
| 3109 |
|
|
| 3110 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 3111 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
| 3237 |
_snprintf_s(file, sizeof(file), _TRUNCATE, "dump%d.bin", no); |
_snprintf_s(file, sizeof(file), _TRUNCATE, "dump%d.bin", no); |
| 3238 |
|
|
| 3239 |
fp = fopen(file, "wb"); |
fp = fopen(file, "wb"); |
| 3240 |
if (fp == NULL) |
if (fp == NULL) |
| 3241 |
return; |
return; |
| 3242 |
|
|
| 3243 |
fwrite(msg, 1, len, fp); |
fwrite(msg, 1, len, fp); |
| 3319 |
} |
} |
| 3320 |
|
|
| 3321 |
#if 0 |
#if 0 |
| 3322 |
static int get_mac_index(char *name) |
static int get_mac_index(char *name) |
| 3323 |
{ |
{ |
| 3324 |
ssh2_mac_t *ptr = ssh2_macs; |
ssh2_mac_t *ptr = ssh2_macs; |
| 3325 |
int val = -1; |
int val = -1; |
| 3878 |
ssh2_macs[pvar->stoc_hmac]); |
ssh2_macs[pvar->stoc_hmac]); |
| 3879 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3880 |
|
|
| 3881 |
// 圧縮アルゴリズムの決定 |
// 圧縮アルゴリズムの決定 |
| 3882 |
// pvar->ssh_state.compressing = FALSE; として下記メンバを使用する。 |
// pvar->ssh_state.compressing = FALSE; として下記メンバを使用する。 |
| 3883 |
// (2005.7.9 yutaka) |
// (2005.7.9 yutaka) |
| 3884 |
size = get_payload_uint32(pvar, offset); |
size = get_payload_uint32(pvar, offset); |
| 3996 |
|
|
| 3997 |
static DH *dh_new_group14(void) |
static DH *dh_new_group14(void) |
| 3998 |
{ |
{ |
| 3999 |
static char *gen = "2", *group14 = |
static char *gen = "2", *group14 = |
| 4000 |
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
| 4001 |
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" |
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" |
| 4002 |
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" |
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" |
| 4106 |
|
|
| 4107 |
// |
// |
| 4108 |
// KEX_DH_GEX_SHA1 |
// KEX_DH_GEX_SHA1 |
| 4109 |
// |
// |
| 4110 |
// cf. Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol |
// cf. Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol |
| 4111 |
// (draft-ietf-secsh-dh-group-exchange-04.txt) |
// (draft-ietf-secsh-dh-group-exchange-04.txt) |
| 4112 |
// |
// |
| 4115 |
{ |
{ |
| 4116 |
if (bits <= 128) |
if (bits <= 128) |
| 4117 |
return (1024); /* O(2**86) */ |
return (1024); /* O(2**86) */ |
| 4118 |
if (bits <= 192) |
if (bits <= 192) |
| 4119 |
return (2048); /* O(2**116) */ |
return (2048); /* O(2**116) */ |
| 4120 |
return (4096); /* O(2**156) */ |
return (4096); /* O(2**156) */ |
| 4121 |
} |
} |
| 4133 |
} |
} |
| 4134 |
|
|
| 4135 |
// サーバが保証すべき最低限のビット数を求める(we_needはバイト)。 |
// サーバが保証すべき最低限のビット数を求める(we_needはバイト)。 |
| 4136 |
bits = dh_estimate(pvar->we_need * 8); |
bits = dh_estimate(pvar->we_need * 8); |
| 4137 |
min = 1024; |
min = 1024; |
| 4138 |
max = 8192; |
max = 8192; |
| 4139 |
|
|
| 4430 |
////////////////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////////////////// |
| 4431 |
// |
// |
| 4432 |
// Key verify function |
// Key verify function |
| 4433 |
// |
// |
| 4434 |
////////////////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////////////////// |
| 4435 |
|
|
| 4436 |
// |
// |
| 4437 |
// DSS |
// DSS |
| 4438 |
// |
// |
| 4439 |
|
|
| 4440 |
static int ssh_dss_verify(DSA *key, |
static int ssh_dss_verify(DSA *key, |
| 4441 |
u_char *signature, u_int signaturelen, |
u_char *signature, u_int signaturelen, |
| 4507 |
|
|
| 4508 |
// |
// |
| 4509 |
// RSA |
// RSA |
| 4510 |
// |
// |
| 4511 |
|
|
| 4512 |
/* |
/* |
| 4513 |
* See: |
* See: |
| 4698 |
|
|
| 4699 |
// |
// |
| 4700 |
// RSA構造体の複製 |
// RSA構造体の複製 |
| 4701 |
// |
// |
| 4702 |
RSA *duplicate_RSA(RSA *src) |
RSA *duplicate_RSA(RSA *src) |
| 4703 |
{ |
{ |
| 4704 |
RSA *rsa = NULL; |
RSA *rsa = NULL; |
| 4724 |
|
|
| 4725 |
// |
// |
| 4726 |
// DSA構造体の複製 |
// DSA構造体の複製 |
| 4727 |
// |
// |
| 4728 |
DSA *duplicate_DSA(DSA *src) |
DSA *duplicate_DSA(DSA *src) |
| 4729 |
{ |
{ |
| 4730 |
DSA *dsa = NULL; |
DSA *dsa = NULL; |
| 4736 |
dsa->q = BN_new(); |
dsa->q = BN_new(); |
| 4737 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 4738 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 4739 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 4740 |
dsa->q == NULL || |
dsa->q == NULL || |
| 4741 |
dsa->g == NULL || |
dsa->g == NULL || |
| 4742 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 4802 |
if (blob != NULL) { |
if (blob != NULL) { |
| 4803 |
retval = malloc(EVP_MAX_MD_SIZE); |
retval = malloc(EVP_MAX_MD_SIZE); |
| 4804 |
if (retval == NULL) { |
if (retval == NULL) { |
| 4805 |
// TODO: |
// TODO: |
| 4806 |
} |
} |
| 4807 |
EVP_DigestInit(&ctx, md); |
EVP_DigestInit(&ctx, md); |
| 4808 |
EVP_DigestUpdate(&ctx, blob, len); |
EVP_DigestUpdate(&ctx, blob, len); |
| 4850 |
|
|
| 4851 |
|
|
| 4852 |
// |
// |
| 4853 |
// キーのメモリ領域解放 |
// キーのメモリ領域解放 |
| 4854 |
// |
// |
| 4855 |
void key_free(Key *key) |
void key_free(Key *key) |
| 4856 |
{ |
{ |
| 4907 |
|
|
| 4908 |
|
|
| 4909 |
// |
// |
| 4910 |
// キー情報からバッファへ変換する (for SSH2) |
// キー情報からバッファへ変換する (for SSH2) |
| 4911 |
// NOTE: |
// NOTE: |
| 4912 |
// |
// |
| 4913 |
int key_to_blob(Key *key, char **blobp, int *lenp) |
int key_to_blob(Key *key, char **blobp, int *lenp) |
| 4914 |
{ |
{ |
| 4915 |
buffer_t *b; |
buffer_t *b; |
| 4958 |
|
|
| 4959 |
|
|
| 4960 |
// |
// |
| 4961 |
// バッファからキー情報を取り出す(for SSH2) |
// バッファからキー情報を取り出す(for SSH2) |
| 4962 |
// NOTE: 返値はアロケート領域になるので、呼び出し側で解放すること。 |
// NOTE: 返値はアロケート領域になるので、呼び出し側で解放すること。 |
| 4963 |
// |
// |
| 4964 |
Key *key_from_blob(char *data, int blen) |
Key *key_from_blob(char *data, int blen) |
| 4965 |
{ |
{ |
| 4966 |
int keynamelen; |
int keynamelen; |
| 4967 |
char key[128]; |
char key[128]; |
| 4968 |
RSA *rsa = NULL; |
RSA *rsa = NULL; |
| 4969 |
DSA *dsa = NULL; |
DSA *dsa = NULL; |
| 4970 |
Key *hostkey; // hostkey |
Key *hostkey; // hostkey |
| 4971 |
enum hostkey_type type; |
enum hostkey_type type; |
| 4972 |
|
|
| 4973 |
hostkey = malloc(sizeof(Key)); |
hostkey = malloc(sizeof(Key)); |
| 5014 |
dsa->q = BN_new(); |
dsa->q = BN_new(); |
| 5015 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5016 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5017 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5018 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5019 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5020 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5131 |
dsa->q = BN_new(); |
dsa->q = BN_new(); |
| 5132 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5133 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5134 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5135 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5136 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5137 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5458 |
dsa->q = BN_new(); |
dsa->q = BN_new(); |
| 5459 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5460 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5461 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5462 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5463 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5464 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5539 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5540 |
server_host_key_blob, bloblen, |
server_host_key_blob, bloblen, |
| 5541 |
/////// KEXGEX |
/////// KEXGEX |
| 5542 |
pvar->kexgex_min, |
pvar->kexgex_min, |
| 5543 |
pvar->kexgex_bits, |
pvar->kexgex_bits, |
| 5544 |
pvar->kexgex_max, |
pvar->kexgex_max, |
| 5545 |
pvar->kexdh->p, |
pvar->kexdh->p, |
| 5546 |
pvar->kexdh->g, |
pvar->kexdh->g, |
| 5663 |
handle_SSH2_dh_gex_group(pvar); |
handle_SSH2_dh_gex_group(pvar); |
| 5664 |
|
|
| 5665 |
} else { |
} else { |
| 5666 |
// TODO: |
// TODO: |
| 5667 |
|
|
| 5668 |
} |
} |
| 5669 |
|
|
| 5779 |
} |
} |
| 5780 |
s = "ssh-userauth"; |
s = "ssh-userauth"; |
| 5781 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 5782 |
//buffer_put_padding(msg, 32); // XXX: |
//buffer_put_padding(msg, 32); // XXX: |
| 5783 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 5784 |
outmsg = begin_send_packet(pvar, SSH2_MSG_SERVICE_REQUEST, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_SERVICE_REQUEST, len); |
| 5785 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 6054 |
} |
} |
| 6055 |
// セッションID |
// セッションID |
| 6056 |
buffer_append_length(signbuf, pvar->session_id, pvar->session_id_len); |
buffer_append_length(signbuf, pvar->session_id, pvar->session_id_len); |
| 6057 |
buffer_put_char(signbuf, SSH2_MSG_USERAUTH_REQUEST); |
buffer_put_char(signbuf, SSH2_MSG_USERAUTH_REQUEST); |
| 6058 |
s = pvar->auth_state.user; // ユーザ名 |
s = pvar->auth_state.user; // ユーザ名 |
| 6059 |
buffer_put_string(signbuf, s, strlen(s)); |
buffer_put_string(signbuf, s, strlen(s)); |
| 6060 |
s = connect_id; |
s = connect_id; |
| 6109 |
if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
| 6110 |
// keyboard-interactive method |
// keyboard-interactive method |
| 6111 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_INFO_REQUEST); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_INFO_REQUEST); |
| 6112 |
} |
} |
| 6113 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_SUCCESS); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_SUCCESS); |
| 6114 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_FAILURE); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_FAILURE); |
| 6115 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_BANNER); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_BANNER); |
| 6117 |
|
|
| 6118 |
{ |
{ |
| 6119 |
char buf[128]; |
char buf[128]; |
| 6120 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 6121 |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
| 6122 |
pvar->auth_state.cur_cred.method); |
pvar->auth_state.cur_cred.method); |
| 6123 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 6134 |
|
|
| 6135 |
// |
// |
| 6136 |
// SSH2 heartbeat procedure |
// SSH2 heartbeat procedure |
| 6137 |
// |
// |
| 6138 |
// NAT環境において、SSHクライアントとサーバ間で通信が発生しなかった場合、 |
// NAT環境において、SSHクライアントとサーバ間で通信が発生しなかった場合、 |
| 6139 |
// ルータが勝手にNATテーブルをクリアすることがあり、SSHコネクションが |
// ルータが勝手にNATテーブルをクリアすることがあり、SSHコネクションが |
| 6140 |
// 切れてしまうことがある。定期的に、クライアントからダミーパケットを |
// 切れてしまうことがある。定期的に、クライアントからダミーパケットを |
| 6159 |
// 一定時間無通信であれば、サーバへダミーパケットを送る |
// 一定時間無通信であれば、サーバへダミーパケットを送る |
| 6160 |
// 閾値が0であれば何もしない。 |
// 閾値が0であれば何もしない。 |
| 6161 |
tick = time(NULL) - pvar->ssh_heartbeat_tick; |
tick = time(NULL) - pvar->ssh_heartbeat_tick; |
| 6162 |
if (pvar->session_settings.ssh_heartbeat_overtime > 0 && |
if (pvar->session_settings.ssh_heartbeat_overtime > 0 && |
| 6163 |
tick > pvar->session_settings.ssh_heartbeat_overtime) { |
tick > pvar->session_settings.ssh_heartbeat_overtime) { |
| 6164 |
buffer_t *msg; |
buffer_t *msg; |
| 6165 |
char *s; |
char *s; |
| 6166 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 6194 |
|
|
| 6195 |
instance = 0; |
instance = 0; |
| 6196 |
|
|
| 6197 |
return 0; |
return 0; |
| 6198 |
} |
} |
| 6199 |
|
|
| 6200 |
static void start_ssh_heartbeat_thread(PTInstVar pvar) |
static void start_ssh_heartbeat_thread(PTInstVar pvar) |
| 6205 |
thread = (HANDLE)_beginthreadex(NULL, 0, ssh_heartbeat_thread, pvar, 0, &tid); |
thread = (HANDLE)_beginthreadex(NULL, 0, ssh_heartbeat_thread, pvar, 0, &tid); |
| 6206 |
if (thread == (HANDLE)-1) { |
if (thread == (HANDLE)-1) { |
| 6207 |
// TODO: |
// TODO: |
| 6208 |
} |
} |
| 6209 |
pvar->ssh_heartbeat_thread = thread; |
pvar->ssh_heartbeat_thread = thread; |
| 6210 |
} |
} |
| 6211 |
|
|
| 6305 |
// 認証ダイアログのラジオボタンを更新 |
// 認証ダイアログのラジオボタンを更新 |
| 6306 |
if (strstr(cstring, "password")) { |
if (strstr(cstring, "password")) { |
| 6307 |
type |= (1 << SSH_AUTH_PASSWORD); |
type |= (1 << SSH_AUTH_PASSWORD); |
| 6308 |
} |
} |
| 6309 |
if (strstr(cstring, "publickey")) { |
if (strstr(cstring, "publickey")) { |
| 6310 |
type |= (1 << SSH_AUTH_RSA); |
type |= (1 << SSH_AUTH_RSA); |
| 6311 |
} |
} |
| 6465 |
|
|
| 6466 |
// TODO: ここでプロンプトを表示してユーザから入力させるのが正解。 |
// TODO: ここでプロンプトを表示してユーザから入力させるのが正解。 |
| 6467 |
s = pvar->auth_state.cur_cred.password; |
s = pvar->auth_state.cur_cred.password; |
| 6468 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 6469 |
} |
} |
| 6470 |
|
|
| 6471 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 6488 |
int id, remote_id; |
int id, remote_id; |
| 6489 |
Channel_t *c; |
Channel_t *c; |
| 6490 |
#ifdef DONT_WANTCONFIRM |
#ifdef DONT_WANTCONFIRM |
| 6491 |
int wantconfirm = 0; // false |
int wantconfirm = 0; // false |
| 6492 |
#else |
#else |
| 6493 |
int wantconfirm = 1; // true |
int wantconfirm = 1; // true |
| 6494 |
#endif |
#endif |
| 6495 |
|
|
| 6496 |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
| 6512 |
data += 4; |
data += 4; |
| 6513 |
|
|
| 6514 |
c->remote_id = remote_id; |
c->remote_id = remote_id; |
| 6515 |
pvar->session_nego_status = 1; |
pvar->session_nego_status = 1; |
| 6516 |
|
|
| 6517 |
// remote window size |
// remote window size |
| 6518 |
c->remote_window = get_uint32_MSBfirst(data); |
c->remote_window = get_uint32_MSBfirst(data); |
| 6527 |
return TRUE; |
return TRUE; |
| 6528 |
} |
} |
| 6529 |
|
|
| 6530 |
// ポートフォワーディングの準備 (2005.2.26, 2005.6.21 yutaka) |
// ポートフォワーディングの準備 (2005.2.26, 2005.6.21 yutaka) |
| 6531 |
// シェルオープンしたあとに X11 の要求を出さなくてはならない。(2005.7.3 yutaka) |
// シェルオープンしたあとに X11 の要求を出さなくてはならない。(2005.7.3 yutaka) |
| 6532 |
FWD_prep_forwarding(pvar); |
FWD_prep_forwarding(pvar); |
| 6533 |
FWD_enter_interactive_mode(pvar); |
FWD_enter_interactive_mode(pvar); |
| 6534 |
|
|
| 6535 |
//debug_print(100, data, len); |
//debug_print(100, data, len); |
| 6547 |
return FALSE; |
return FALSE; |
| 6548 |
} |
} |
| 6549 |
|
|
| 6550 |
buffer_put_int(msg, remote_id); |
buffer_put_int(msg, remote_id); |
| 6551 |
s = "pty-req"; // pseudo terminalのリクエスト |
s = "pty-req"; // pseudo terminalのリクエスト |
| 6552 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 6553 |
buffer_put_char(msg, wantconfirm); // wantconfirm (disableに変更 2005/3/28 yutaka) |
buffer_put_char(msg, wantconfirm); // wantconfirm (disableに変更 2005/3/28 yutaka) |
| 6554 |
s = pvar->ts->TermType; // TERM |
s = pvar->ts->TermType; // TERM |
| 6555 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 6556 |
buffer_put_int(msg, pvar->ssh_state.win_cols); // columns |
buffer_put_int(msg, pvar->ssh_state.win_cols); // columns |
| 6557 |
buffer_put_int(msg, pvar->ssh_state.win_rows); // lines |
buffer_put_int(msg, pvar->ssh_state.win_rows); // lines |
| 6558 |
buffer_put_int(msg, 480); // XXX: |
buffer_put_int(msg, 480); // XXX: |
| 6561 |
// TTY modeはここで渡す (2005.7.17 yutaka) |
// TTY modeはここで渡す (2005.7.17 yutaka) |
| 6562 |
#if 0 |
#if 0 |
| 6563 |
s = ""; |
s = ""; |
| 6564 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 6565 |
#else |
#else |
| 6566 |
buffer_put_char(ttymsg, 129); // TTY_OP_OSPEED_PROTO2 |
buffer_put_char(ttymsg, 129); // TTY_OP_OSPEED_PROTO2 |
| 6567 |
buffer_put_int(ttymsg, 9600); // baud rate |
buffer_put_int(ttymsg, 9600); // baud rate |
| 6568 |
buffer_put_char(ttymsg, 128); // TTY_OP_ISPEED_PROTO2 |
buffer_put_char(ttymsg, 128); // TTY_OP_ISPEED_PROTO2 |
| 6569 |
buffer_put_int(ttymsg, 9600); // baud rate |
buffer_put_int(ttymsg, 9600); // baud rate |
| 6570 |
// VERASE |
// VERASE |
| 6571 |
buffer_put_char(ttymsg, 3); |
buffer_put_char(ttymsg, 3); |
| 6572 |
if (pvar->ts->BSKey == IdBS) { |
if (pvar->ts->BSKey == IdBS) { |
| 6573 |
buffer_put_int(ttymsg, 0x08); // BS key |
buffer_put_int(ttymsg, 0x08); // BS key |
| 6574 |
} else { |
} else { |
| 6575 |
buffer_put_int(ttymsg, 0x7F); // DEL key |
buffer_put_int(ttymsg, 0x7F); // DEL key |
| 6576 |
} |
} |
| 6577 |
// TTY_OP_END |
// TTY_OP_END |
| 6578 |
buffer_put_char(ttymsg, 0); |
buffer_put_char(ttymsg, 0); |
| 6579 |
|
|
| 6580 |
// SSH2では文字列として書き込む。 |
// SSH2では文字列として書き込む。 |
| 6581 |
buffer_put_string(msg, buffer_ptr(ttymsg), buffer_len(ttymsg)); |
buffer_put_string(msg, buffer_ptr(ttymsg), buffer_len(ttymsg)); |
| 6693 |
|
|
| 6694 |
if (pvar->session_nego_status == 1) { |
if (pvar->session_nego_status == 1) { |
| 6695 |
#ifdef DONT_WANTCONFIRM |
#ifdef DONT_WANTCONFIRM |
| 6696 |
int wantconfirm = 0; // false |
int wantconfirm = 0; // false |
| 6697 |
#else |
#else |
| 6698 |
int wantconfirm = 1; // true |
int wantconfirm = 1; // true |
| 6699 |
#endif |
#endif |
| 6700 |
|
|
| 6701 |
pvar->session_nego_status = 2; |
pvar->session_nego_status = 2; |
| 6702 |
msg = buffer_init(); |
msg = buffer_init(); |
| 6703 |
if (msg == NULL) { |
if (msg == NULL) { |
| 6704 |
// TODO: error check |
// TODO: error check |
| 6710 |
// TODO: error check |
// TODO: error check |
| 6711 |
return FALSE; |
return FALSE; |
| 6712 |
} |
} |
| 6713 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 6714 |
// buffer_put_int(msg, pvar->remote_id); |
// buffer_put_int(msg, pvar->remote_id); |
| 6715 |
|
|
| 6716 |
s = "shell"; |
s = "shell"; |
| 6717 |
buffer_put_string(msg, s, strlen(s)); // ctype |
buffer_put_string(msg, s, strlen(s)); // ctype |
| 6746 |
{ |
{ |
| 6747 |
// window sizeを32KBへ変更し、local windowの判別を修正。 |
// window sizeを32KBへ変更し、local windowの判別を修正。 |
| 6748 |
// これによりSSH2のスループットが向上する。(2006.3.6 yutaka) |
// これによりSSH2のスループットが向上する。(2006.3.6 yutaka) |
|
const unsigned int window_size = CHAN_TCP_PACKET_DEFAULT; |
|
| 6749 |
buffer_t *msg; |
buffer_t *msg; |
| 6750 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 6751 |
int len; |
int len; |
| 6752 |
|
|
| 6753 |
// ローカルのwindow sizeにまだ余裕があるなら、何もしない。 |
// ローカルのwindow sizeにまだ余裕があるなら、何もしない。 |
| 6754 |
// added /2 (2006.3.6 yutaka) |
// added /2 (2006.3.6 yutaka) |
| 6755 |
if (c->local_window > window_size/2) |
if (c->local_window > c->local_window_max/2) |
| 6756 |
return; |
return; |
| 6757 |
|
|
| 6758 |
{ |
{ |
| 6762 |
// TODO: error check |
// TODO: error check |
| 6763 |
return; |
return; |
| 6764 |
} |
} |
| 6765 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 6766 |
buffer_put_int(msg, window_size - c->local_window); |
buffer_put_int(msg, c->local_window_max - c->local_window); |
| 6767 |
|
|
| 6768 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 6769 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, len); |
| 6772 |
buffer_free(msg); |
buffer_free(msg); |
| 6773 |
|
|
| 6774 |
// クライアントのwindow sizeを増やす |
// クライアントのwindow sizeを増やす |
| 6775 |
c->local_window = window_size; |
c->local_window = c->local_window_max; |
| 6776 |
} |
} |
| 6777 |
|
|
| 6778 |
} |
} |
| 6807 |
data += 4; |
data += 4; |
| 6808 |
|
|
| 6809 |
// バッファサイズのチェック |
// バッファサイズのチェック |
| 6810 |
if (strlen > c->local_window_max) { |
if (strlen > c->local_maxpacket) { |
| 6811 |
// TODO: logging |
// TODO: logging |
| 6812 |
} |
} |
| 6813 |
if (strlen > c->local_window) { |
if (strlen > c->local_window) { |
| 6876 |
data += 4; |
data += 4; |
| 6877 |
|
|
| 6878 |
// バッファサイズのチェック |
// バッファサイズのチェック |
| 6879 |
if (strlen > c->local_window_max) { |
if (strlen > c->local_maxpacket) { |
| 6880 |
// TODO: logging |
// TODO: logging |
| 6881 |
} |
} |
| 6882 |
if (strlen > c->local_window) { |
if (strlen > c->local_window) { |
| 7006 |
int orig_port; |
int orig_port; |
| 7007 |
|
|
| 7008 |
orig_str = buffer_get_string(&data, NULL); // "127.0.0.1" |
orig_str = buffer_get_string(&data, NULL); // "127.0.0.1" |
| 7009 |
orig_port = get_uint32_MSBfirst(data); |
orig_port = get_uint32_MSBfirst(data); |
| 7010 |
data += 4; |
data += 4; |
| 7011 |
free(orig_str); |
free(orig_str); |
| 7012 |
|
|
| 7069 |
// TODO: error check |
// TODO: error check |
| 7070 |
return FALSE; |
return FALSE; |
| 7071 |
} |
} |
| 7072 |
buffer_put_int(msg, SSH2_DISCONNECT_PROTOCOL_ERROR); |
buffer_put_int(msg, SSH2_DISCONNECT_PROTOCOL_ERROR); |
| 7073 |
s = "disconnected by server request"; |
s = "disconnected by server request"; |
| 7074 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 7075 |
s = ""; |
s = ""; |
| 7076 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, s, strlen(s)); |
| 7077 |
|
|
| 7078 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 7079 |
outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len); |
| 7084 |
// TCP connection closed |
// TCP connection closed |
| 7085 |
notify_closed_connection(pvar); |
notify_closed_connection(pvar); |
| 7086 |
|
|
| 7087 |
} else if (c->type == TYPE_PORTFWD) { |
} else if (c->type == TYPE_PORTFWD) { |
| 7088 |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
| 7089 |
FWD_free_channel(pvar, c->local_num); |
FWD_free_channel(pvar, c->local_num); |
| 7090 |
|
|
| 7159 |
// TODO: error check |
// TODO: error check |
| 7160 |
return FALSE; |
return FALSE; |
| 7161 |
} |
} |
| 7162 |
buffer_put_int(msg, c->remote_id); |
buffer_put_int(msg, c->remote_id); |
| 7163 |
|
|
| 7164 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 7165 |
outmsg = begin_send_packet(pvar, type, len); |
outmsg = begin_send_packet(pvar, type, len); |