| 131 |
// |
// |
| 132 |
// channel function |
// channel function |
| 133 |
// |
// |
| 134 |
static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack, enum confirm_type type, int local_num) |
static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack, |
| 135 |
|
enum confirm_type type, int local_num) |
| 136 |
{ |
{ |
| 137 |
int i, found; |
int i, found; |
| 138 |
Channel_t *c; |
Channel_t *c; |
| 374 |
|
|
| 375 |
fprintf(fp, "<<< TeraTerm SSH2 log dump >>>\n"); |
fprintf(fp, "<<< TeraTerm SSH2 log dump >>>\n"); |
| 376 |
fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n", |
fprintf(fp, "saved time: %04d/%02d/%02d %02d:%02d:%02d\n", |
| 377 |
tm->tm_year + 1900, |
tm->tm_year + 1900, |
| 378 |
tm->tm_mon + 1, |
tm->tm_mon + 1, |
| 379 |
tm->tm_mday, |
tm->tm_mday, |
| 380 |
tm->tm_hour, |
tm->tm_hour, |
| 381 |
tm->tm_min, |
tm->tm_min, |
| 382 |
tm->tm_sec); |
tm->tm_sec); |
| 383 |
fprintf(fp, "\n"); |
fprintf(fp, "\n"); |
| 384 |
|
|
| 385 |
for (i = 0 ; i < memtag_count ; i++) { |
for (i = 0 ; i < memtag_count ; i++) { |
| 474 |
|
|
| 475 |
pvar->ssh_state.payload = |
pvar->ssh_state.payload = |
| 476 |
pvar->ssh_state.postdecompress_inbuf + 1; |
pvar->ssh_state.postdecompress_inbuf + 1; |
| 477 |
if (pvar->ssh_state.postdecompress_inbuflen == |
if (pvar->ssh_state.postdecompress_inbuflen == cur_decompressed_bytes) { |
|
cur_decompressed_bytes) { |
|
| 478 |
buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, |
buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, |
| 479 |
&pvar->ssh_state.postdecompress_inbuflen, |
&pvar->ssh_state.postdecompress_inbuflen, |
| 480 |
min(limit, cur_decompressed_bytes * 2)); |
min(limit, cur_decompressed_bytes * 2)); |
| 481 |
} |
} |
| 482 |
|
|
| 483 |
pvar->ssh_state.decompress_stream.next_out |
pvar->ssh_state.decompress_stream.next_out = |
|
= |
|
| 484 |
pvar->ssh_state.postdecompress_inbuf + |
pvar->ssh_state.postdecompress_inbuf + |
| 485 |
cur_decompressed_bytes; |
cur_decompressed_bytes; |
| 486 |
pvar->ssh_state.decompress_stream.avail_out = |
pvar->ssh_state.decompress_stream.avail_out = |
| 501 |
return cur_decompressed_bytes; |
return cur_decompressed_bytes; |
| 502 |
default: |
default: |
| 503 |
UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar, |
| 504 |
"Invalid compressed data in received packet"); |
"Invalid compressed data in received packet"); |
| 505 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 506 |
return -1; |
return -1; |
| 507 |
} |
} |
| 531 |
if (pvar->ssh_state.payload_grabbed > in_buffer) { |
if (pvar->ssh_state.payload_grabbed > in_buffer) { |
| 532 |
char buf[128]; |
char buf[128]; |
| 533 |
UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_ERROR", pvar, |
| 534 |
"Received truncated packet (%ld > %d) @ grab_payload()"); |
"Received truncated packet (%ld > %d) @ grab_payload()"); |
| 535 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
| 536 |
pvar->ssh_state.payload_grabbed, in_buffer); |
pvar->ssh_state.payload_grabbed, in_buffer); |
| 537 |
notify_fatal_error(pvar, buf); |
notify_fatal_error(pvar, buf); |
| 538 |
return FALSE; |
return FALSE; |
| 539 |
} else { |
} else { |
| 555 |
if (pvar->ssh_state.payload_grabbed > in_buffer) { |
if (pvar->ssh_state.payload_grabbed > in_buffer) { |
| 556 |
char buf[128]; |
char buf[128]; |
| 557 |
UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_TRUNCATED_PKT_LIM_ERROR", pvar, |
| 558 |
"Received truncated packet (%ld > %d) @ grab_payload_limited()"); |
"Received truncated packet (%ld > %d) @ grab_payload_limited()"); |
| 559 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
| 560 |
pvar->ssh_state.payload_grabbed, in_buffer); |
pvar->ssh_state.payload_grabbed, in_buffer); |
| 561 |
notify_fatal_error(pvar, buf); |
notify_fatal_error(pvar, buf); |
| 562 |
return FALSE; |
return FALSE; |
| 563 |
} else { |
} else { |
| 589 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 590 |
if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) { |
if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) { |
| 591 |
UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, |
| 592 |
"'CORE insertion attack' detected. Aborting connection."); |
"'CORE insertion attack' detected. Aborting connection."); |
| 593 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 594 |
} |
} |
| 595 |
|
|
| 598 |
if (do_crc(pvar->ssh_state.payload, len - 4) != |
if (do_crc(pvar->ssh_state.payload, len - 4) != |
| 599 |
get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) { |
get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) { |
| 600 |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, |
| 601 |
"Detected corrupted data; connection terminating."); |
"Detected corrupted data; connection terminating."); |
| 602 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 603 |
return SSH_MSG_NONE; |
return SSH_MSG_NONE; |
| 604 |
} |
} |
| 610 |
|
|
| 611 |
#if 0 |
#if 0 |
| 612 |
CRYPT_decrypt(pvar, data + already_decrypted, |
CRYPT_decrypt(pvar, data + already_decrypted, |
| 613 |
len - already_decrypted); |
len - already_decrypted); |
| 614 |
#else |
#else |
| 615 |
CRYPT_decrypt(pvar, data + already_decrypted, |
CRYPT_decrypt(pvar, data + already_decrypted, |
| 616 |
(4 + len) - already_decrypted); |
(4 + len) - already_decrypted); |
| 617 |
#endif |
#endif |
| 618 |
|
|
| 619 |
if (!CRYPT_verify_receiver_MAC |
if (!CRYPT_verify_receiver_MAC |
| 620 |
(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, |
(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, |
| 621 |
data + len + 4)) { |
data + len + 4)) { |
| 622 |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, |
| 623 |
"Detected corrupted data; connection terminating."); |
"Detected corrupted data; connection terminating."); |
| 624 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 625 |
return SSH_MSG_NONE; |
return SSH_MSG_NONE; |
| 626 |
} |
} |
| 635 |
if (pvar->ssh_state.decompressing) { |
if (pvar->ssh_state.decompressing) { |
| 636 |
if (pvar->ssh_state.decompress_stream.avail_in != 0) { |
if (pvar->ssh_state.decompress_stream.avail_in != 0) { |
| 637 |
UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar, |
| 638 |
"Internal error: a packet was not fully decompressed.\n" |
"Internal error: a packet was not fully decompressed.\n" |
| 639 |
"This is a bug, please report it."); |
"This is a bug, please report it."); |
| 640 |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 641 |
} |
} |
| 642 |
|
|
| 659 |
// support of SSH2 packet compression (2005.7.9 yutaka) |
// support of SSH2 packet compression (2005.7.9 yutaka) |
| 660 |
// support of "Compression delayed" (2006.6.23 maya) |
// support of "Compression delayed" (2006.6.23 maya) |
| 661 |
if ((pvar->stoc_compression == COMP_ZLIB || |
if ((pvar->stoc_compression == COMP_ZLIB || |
| 662 |
pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) && |
pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) && |
| 663 |
pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled |
pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled |
| 664 |
int ret; |
int ret; |
| 665 |
|
|
| 666 |
if (pvar->decomp_buffer == NULL) { |
if (pvar->decomp_buffer == NULL) { |
| 672 |
buffer_clear(pvar->decomp_buffer); |
buffer_clear(pvar->decomp_buffer); |
| 673 |
|
|
| 674 |
// packet sizeとpaddingを取り除いたペイロード部分のみを展開する。 |
// packet sizeとpaddingを取り除いたペイロード部分のみを展開する。 |
| 675 |
ret = buffer_decompress(&pvar->ssh_state.decompress_stream, |
ret = buffer_decompress(&pvar->ssh_state.decompress_stream, |
| 676 |
pvar->ssh_state.payload, pvar->ssh_state.payloadlen, pvar->decomp_buffer); |
pvar->ssh_state.payload, |
| 677 |
|
pvar->ssh_state.payloadlen, |
| 678 |
|
pvar->decomp_buffer); |
| 679 |
|
|
| 680 |
// ポインタの更新。 |
// ポインタの更新。 |
| 681 |
pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer); |
pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer); |
| 703 |
or for the packet type byte). |
or for the packet type byte). |
| 704 |
Returns a pointer to the payload data area, a region of length 'len', |
Returns a pointer to the payload data area, a region of length 'len', |
| 705 |
to be filled by the caller. */ |
to be filled by the caller. */ |
| 706 |
static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, |
static unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len) |
|
int len) |
|
| 707 |
{ |
{ |
| 708 |
unsigned char FAR *buf; |
unsigned char FAR *buf; |
| 709 |
|
|
| 711 |
|
|
| 712 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 713 |
buf_ensure_size(&pvar->ssh_state.precompress_outbuf, |
buf_ensure_size(&pvar->ssh_state.precompress_outbuf, |
| 714 |
&pvar->ssh_state.precompress_outbuflen, 1 + len); |
&pvar->ssh_state.precompress_outbuflen, 1 + len); |
| 715 |
buf = pvar->ssh_state.precompress_outbuf; |
buf = pvar->ssh_state.precompress_outbuf; |
| 716 |
} else { |
} else { |
| 717 |
/* For SSHv2, |
/* For SSHv2, |
| 719 |
+ len(payload) + 4(minpadding), rounded up to nearest block_size |
+ len(payload) + 4(minpadding), rounded up to nearest block_size |
| 720 |
We only need a reasonable upper bound for the buffer size */ |
We only need a reasonable upper bound for the buffer size */ |
| 721 |
buf_ensure_size(&pvar->ssh_state.outbuf, |
buf_ensure_size(&pvar->ssh_state.outbuf, |
| 722 |
&pvar->ssh_state.outbuflen, |
&pvar->ssh_state.outbuflen, |
| 723 |
len + 30 + CRYPT_get_sender_MAC_size(pvar) + |
len + 30 + CRYPT_get_sender_MAC_size(pvar) + |
| 724 |
CRYPT_get_encryption_block_size(pvar)); |
CRYPT_get_encryption_block_size(pvar)); |
| 725 |
buf = pvar->ssh_state.outbuf + 12; |
buf = pvar->ssh_state.outbuf + 12; |
| 726 |
} |
} |
| 727 |
|
|
| 769 |
u_long do_block = 0; |
u_long do_block = 0; |
| 770 |
|
|
| 771 |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 772 |
0, 0) == SOCKET_ERROR |
0, 0) == SOCKET_ERROR |
| 773 |
|| ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR |
|| ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR |
| 774 |
|| retry_send_packet(pvar, data, len) |
|| retry_send_packet(pvar, data, len) |
| 775 |
|| (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
|| (pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 776 |
pvar->notification_msg, |
pvar->notification_msg, |
| 777 |
pvar->notification_events) == |
pvar->notification_events) == |
| 778 |
SOCKET_ERROR) { |
SOCKET_ERROR) { |
| 779 |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
| 780 |
"A communications error occurred while sending an SSH packet.\n" |
"A communications error occurred while sending an SSH packet.\n" |
| 781 |
"The connection will close."); |
"The connection will close."); |
| 782 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 783 |
return FALSE; |
return FALSE; |
| 784 |
} else { |
} else { |
| 798 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 799 |
if (!skip_compress) { |
if (!skip_compress) { |
| 800 |
buf_ensure_size(&pvar->ssh_state.outbuf, |
buf_ensure_size(&pvar->ssh_state.outbuf, |
| 801 |
&pvar->ssh_state.outbuflen, |
&pvar->ssh_state.outbuflen, |
| 802 |
len + (len >> 6) + 50 + |
len + (len >> 6) + 50 + |
| 803 |
CRYPT_get_sender_MAC_size(pvar)); |
CRYPT_get_sender_MAC_size(pvar)); |
| 804 |
pvar->ssh_state.compress_stream.next_in = |
pvar->ssh_state.compress_stream.next_in = |
| 805 |
pvar->ssh_state.precompress_outbuf; |
pvar->ssh_state.precompress_outbuf; |
| 806 |
pvar->ssh_state.compress_stream.avail_in = len; |
pvar->ssh_state.compress_stream.avail_in = len; |
| 809 |
pvar->ssh_state.compress_stream.avail_out = |
pvar->ssh_state.compress_stream.avail_out = |
| 810 |
pvar->ssh_state.outbuflen - 12; |
pvar->ssh_state.outbuflen - 12; |
| 811 |
|
|
| 812 |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) { |
|
Z_OK) { |
|
| 813 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 814 |
"An error occurred while compressing packet data.\n" |
"An error occurred while compressing packet data.\n" |
| 815 |
"The connection will close."); |
"The connection will close."); |
| 816 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 817 |
return; |
return; |
| 818 |
} |
} |
| 836 |
memset(data + 4, 0, padding); |
memset(data + 4, 0, padding); |
| 837 |
} |
} |
| 838 |
set_uint32(data + data_length - 4, |
set_uint32(data + data_length - 4, |
| 839 |
do_crc(data + 4, data_length - 8)); |
do_crc(data + 4, data_length - 8)); |
| 840 |
CRYPT_encrypt(pvar, data + 4, data_length - 4); |
CRYPT_encrypt(pvar, data + 4, data_length - 4); |
| 841 |
} else { //for SSH2(yutaka) |
} else { //for SSH2(yutaka) |
| 842 |
int block_size = CRYPT_get_encryption_block_size(pvar); |
int block_size = CRYPT_get_encryption_block_size(pvar); |
| 863 |
// パケット圧縮が有効の場合、パケットを圧縮してから送信パケットを構築する。(2005.7.9 yutaka) |
// パケット圧縮が有効の場合、パケットを圧縮してから送信パケットを構築する。(2005.7.9 yutaka) |
| 864 |
// support of "Compression delayed" (2006.6.23 maya) |
// support of "Compression delayed" (2006.6.23 maya) |
| 865 |
if ((pvar->ctos_compression == COMP_ZLIB || |
if ((pvar->ctos_compression == COMP_ZLIB || |
| 866 |
pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) && |
pvar->ctos_compression == COMP_DELAYED && pvar->userauth_success) && |
| 867 |
pvar->ssh2_keys[MODE_OUT].comp.enabled) { |
pvar->ssh2_keys[MODE_OUT].comp.enabled) { |
| 868 |
// このバッファは packet-length(4) + padding(1) + payload(any) を示す。 |
// このバッファは packet-length(4) + padding(1) + payload(any) を示す。 |
| 869 |
msg = buffer_init(); |
msg = buffer_init(); |
| 870 |
if (msg == NULL) { |
if (msg == NULL) { |
| 876 |
buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1) |
buffer_append(msg, "\0\0\0\0\0", 5); // 5 = packet-length(4) + padding(1) |
| 877 |
if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) { |
if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) { |
| 878 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 879 |
"An error occurred while compressing packet data.\n" |
"An error occurred while compressing packet data.\n" |
| 880 |
"The connection will close."); |
"The connection will close."); |
| 881 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 882 |
return; |
return; |
| 883 |
} |
} |
| 902 |
data[4] = (unsigned char) padding; |
data[4] = (unsigned char) padding; |
| 903 |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
| 904 |
ret = CRYPT_build_sender_MAC(pvar, |
ret = CRYPT_build_sender_MAC(pvar, |
| 905 |
pvar->ssh_state.sender_sequence_number, |
pvar->ssh_state.sender_sequence_number, |
| 906 |
data, encryption_size, |
data, encryption_size, |
| 907 |
data + encryption_size); |
data + encryption_size); |
| 908 |
if (ret == FALSE) { // HMACがまだ設定されていない場合 |
if (ret == FALSE) { // HMACがまだ設定されていない場合 |
| 909 |
data_length = encryption_size; |
data_length = encryption_size; |
| 910 |
} |
} |
| 928 |
memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen); |
memset(pvar->ssh_state.outbuf, 0, pvar->ssh_state.outbuflen); |
| 929 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 930 |
memset(pvar->ssh_state.precompress_outbuf, 0, |
memset(pvar->ssh_state.precompress_outbuf, 0, |
| 931 |
pvar->ssh_state.precompress_outbuflen); |
pvar->ssh_state.precompress_outbuflen); |
| 932 |
} |
} |
| 933 |
} |
} |
| 934 |
|
|
| 936 |
handlers fires, if it returns FALSE, then all handlers in the set are |
handlers fires, if it returns FALSE, then all handlers in the set are |
| 937 |
removed from their queues. */ |
removed from their queues. */ |
| 938 |
static void enque_handlers(PTInstVar pvar, int num_msgs, |
static void enque_handlers(PTInstVar pvar, int num_msgs, |
| 939 |
const int FAR * messages, |
const int FAR * messages, |
| 940 |
const SSHPacketHandler FAR * handlers) |
const SSHPacketHandler FAR * handlers) |
| 941 |
{ |
{ |
| 942 |
SSHPacketHandlerItem FAR *first_item; |
SSHPacketHandlerItem FAR *first_item; |
| 943 |
SSHPacketHandlerItem FAR *last_item = NULL; |
SSHPacketHandlerItem FAR *last_item = NULL; |
| 1024 |
} |
} |
| 1025 |
|
|
| 1026 |
static void enque_handler(PTInstVar pvar, int message, |
static void enque_handler(PTInstVar pvar, int message, |
| 1027 |
SSHPacketHandler handler) |
SSHPacketHandler handler) |
| 1028 |
{ |
{ |
| 1029 |
enque_handlers(pvar, 1, &message, &handler); |
enque_handlers(pvar, 1, &message, &handler); |
| 1030 |
} |
} |
| 1065 |
static BOOL handle_auth_failure(PTInstVar pvar) |
static BOOL handle_auth_failure(PTInstVar pvar) |
| 1066 |
{ |
{ |
| 1067 |
notify_verbose_message(pvar, "Authentication failed", |
notify_verbose_message(pvar, "Authentication failed", |
| 1068 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1069 |
|
|
| 1070 |
// retry countの追加 (2005.7.15 yutaka) |
// retry countの追加 (2005.7.15 yutaka) |
| 1071 |
pvar->userauth_retry_count++; |
pvar->userauth_retry_count++; |
| 1090 |
|
|
| 1091 |
if (grab_payload(pvar, len)) { |
if (grab_payload(pvar, len)) { |
| 1092 |
notify_verbose_message(pvar, "Received TIS challenge", |
notify_verbose_message(pvar, "Received TIS challenge", |
| 1093 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1094 |
|
|
| 1095 |
AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len); |
AUTH_set_TIS_mode(pvar, pvar->ssh_state.payload + 4, len); |
| 1096 |
AUTH_advance_to_next_cred(pvar); |
AUTH_advance_to_next_cred(pvar); |
| 1104 |
static BOOL handle_auth_required(PTInstVar pvar) |
static BOOL handle_auth_required(PTInstVar pvar) |
| 1105 |
{ |
{ |
| 1106 |
notify_verbose_message(pvar, "Server requires authentication", |
notify_verbose_message(pvar, "Server requires authentication", |
| 1107 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1108 |
|
|
| 1109 |
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
| 1110 |
try_send_credentials(pvar); |
try_send_credentials(pvar); |
| 1117 |
{ |
{ |
| 1118 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 1119 |
if (grab_payload(pvar, 4) |
if (grab_payload(pvar, 4) |
| 1120 |
&& grab_payload(pvar, get_payload_uint32(pvar, 0))) { |
&& grab_payload(pvar, get_payload_uint32(pvar, 0))) { |
| 1121 |
/* ignore it! but it must be decompressed */ |
/* ignore it! but it must be decompressed */ |
| 1122 |
} |
} |
| 1123 |
} |
} |
| 1139 |
|
|
| 1140 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 1141 |
if (grab_payload(pvar, 4) |
if (grab_payload(pvar, 4) |
| 1142 |
&& grab_payload(pvar, description_len = |
&& grab_payload(pvar, description_len = |
| 1143 |
get_payload_uint32(pvar, 0))) { |
get_payload_uint32(pvar, 0))) { |
| 1144 |
always_display = FALSE; |
always_display = FALSE; |
| 1145 |
description = pvar->ssh_state.payload + 4; |
description = pvar->ssh_state.payload + 4; |
| 1146 |
description[description_len] = 0; |
description[description_len] = 0; |
| 1149 |
} |
} |
| 1150 |
} else { |
} else { |
| 1151 |
if (grab_payload(pvar, 5) |
if (grab_payload(pvar, 5) |
| 1152 |
&& grab_payload(pvar, |
&& grab_payload(pvar, |
| 1153 |
(description_len = |
(description_len = get_payload_uint32(pvar, 1)) + 4) |
| 1154 |
get_payload_uint32(pvar, 1)) + 4) |
&& grab_payload(pvar, |
| 1155 |
&& grab_payload(pvar, |
get_payload_uint32(pvar, 5 + description_len))) { |
|
get_payload_uint32(pvar, |
|
|
5 + description_len))) { |
|
| 1156 |
always_display = pvar->ssh_state.payload[0] != 0; |
always_display = pvar->ssh_state.payload[0] != 0; |
| 1157 |
description = pvar->ssh_state.payload + 5; |
description = pvar->ssh_state.payload + 5; |
| 1158 |
description[description_len] = 0; |
description[description_len] = 0; |
| 1163 |
|
|
| 1164 |
chop_newlines(description); |
chop_newlines(description); |
| 1165 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s", |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "DEBUG message from server: %s", |
| 1166 |
description); |
description); |
|
buf[sizeof(buf) - 1] = 0; |
|
| 1167 |
if (always_display) { |
if (always_display) { |
| 1168 |
notify_nonfatal_error(pvar, buf); |
notify_nonfatal_error(pvar, buf); |
| 1169 |
} else { |
} else { |
| 1183 |
|
|
| 1184 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 1185 |
if (grab_payload(pvar, 4) |
if (grab_payload(pvar, 4) |
| 1186 |
&& grab_payload(pvar, description_len = |
&& grab_payload(pvar, description_len = get_payload_uint32(pvar, 0))) { |
|
get_payload_uint32(pvar, 0))) { |
|
| 1187 |
reason_code = -1; |
reason_code = -1; |
| 1188 |
description = pvar->ssh_state.payload + 4; |
description = pvar->ssh_state.payload + 4; |
| 1189 |
description[description_len] = 0; |
description[description_len] = 0; |
| 1192 |
} |
} |
| 1193 |
} else { |
} else { |
| 1194 |
if (grab_payload(pvar, 8) |
if (grab_payload(pvar, 8) |
| 1195 |
&& grab_payload(pvar, |
&& grab_payload(pvar, |
| 1196 |
(description_len = |
(description_len = get_payload_uint32(pvar, 4)) + 4) |
| 1197 |
get_payload_uint32(pvar, 4)) + 4) |
&& grab_payload(pvar, |
| 1198 |
&& grab_payload(pvar, |
get_payload_uint32(pvar, 8 + description_len))) { |
|
get_payload_uint32(pvar, |
|
|
8 + description_len))) { |
|
| 1199 |
reason_code = get_payload_uint32(pvar, 0); |
reason_code = get_payload_uint32(pvar, 0); |
| 1200 |
description = pvar->ssh_state.payload + 8; |
description = pvar->ssh_state.payload + 8; |
| 1201 |
description[description_len] = 0; |
description[description_len] = 0; |
| 1211 |
|
|
| 1212 |
if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) { |
if (get_handler(pvar, SSH_SMSG_FAILURE) == handle_forwarding_failure) { |
| 1213 |
UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_UNABLE_FWD_ERROR", pvar, |
| 1214 |
"\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n" |
"\nIt may have disconnected because it was unable to forward a port you requested to be forwarded from the server.\n" |
| 1215 |
"This often happens when someone is already forwarding that port from the server."); |
"This often happens when someone is already forwarding that port from the server."); |
| 1216 |
strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE); |
strncpy_s(uimsg, sizeof(uimsg), pvar->ts->UIMsg, _TRUNCATE); |
| 1217 |
explanation = uimsg; |
explanation = uimsg; |
| 1218 |
} |
} |
| 1219 |
|
|
| 1220 |
if (description != NULL) { |
if (description != NULL) { |
| 1221 |
UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_ERROR", pvar, |
| 1222 |
"Server disconnected with message '%s'.%s"); |
"Server disconnected with message '%s'.%s"); |
| 1223 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 1224 |
pvar->ts->UIMsg, description, |
pvar->ts->UIMsg, description, |
| 1225 |
explanation); |
explanation); |
| 1226 |
} else { |
} else { |
| 1227 |
UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SERVER_DISCON_NORES_ERROR", pvar, |
| 1228 |
"Server disconnected (no reason given).%s"); |
"Server disconnected (no reason given).%s"); |
| 1229 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 1230 |
pvar->ts->UIMsg, explanation); |
pvar->ts->UIMsg, explanation); |
| 1231 |
} |
} |
| 1232 |
notify_fatal_error(pvar, buf); |
notify_fatal_error(pvar, buf); |
| 1233 |
|
|
| 1244 |
static BOOL handle_crypt_success(PTInstVar pvar) |
static BOOL handle_crypt_success(PTInstVar pvar) |
| 1245 |
{ |
{ |
| 1246 |
notify_verbose_message(pvar, "Secure mode successfully achieved", |
notify_verbose_message(pvar, "Secure mode successfully achieved", |
| 1247 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1248 |
return FALSE; |
return FALSE; |
| 1249 |
} |
} |
| 1250 |
|
|
| 1251 |
static BOOL handle_noauth_success(PTInstVar pvar) |
static BOOL handle_noauth_success(PTInstVar pvar) |
| 1252 |
{ |
{ |
| 1253 |
notify_verbose_message(pvar, "Server does not require authentication", |
notify_verbose_message(pvar, "Server does not require authentication", |
| 1254 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1255 |
prep_compression(pvar); |
prep_compression(pvar); |
| 1256 |
return FALSE; |
return FALSE; |
| 1257 |
} |
} |
| 1259 |
static BOOL handle_auth_success(PTInstVar pvar) |
static BOOL handle_auth_success(PTInstVar pvar) |
| 1260 |
{ |
{ |
| 1261 |
notify_verbose_message(pvar, "Authentication accepted", |
notify_verbose_message(pvar, "Authentication accepted", |
| 1262 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 1263 |
prep_compression(pvar); |
prep_compression(pvar); |
| 1264 |
|
|
| 1265 |
// ハートビート・スレッドの開始 (2004.12.11 yutaka) |
// ハートビート・スレッドの開始 (2004.12.11 yutaka) |
| 1314 |
inmsg = pvar->ssh_state.payload; |
inmsg = pvar->ssh_state.payload; |
| 1315 |
|
|
| 1316 |
CRYPT_set_server_cookie(pvar, inmsg); |
CRYPT_set_server_cookie(pvar, inmsg); |
| 1317 |
if (!CRYPT_set_server_RSA_key |
if (!CRYPT_set_server_RSA_key(pvar, |
| 1318 |
(pvar, get_uint32(inmsg + 8), pvar->ssh_state.payload + 12, |
get_uint32(inmsg + 8), |
| 1319 |
inmsg + server_key_public_modulus_pos)) |
pvar->ssh_state.payload + 12, |
| 1320 |
|
inmsg + server_key_public_modulus_pos)) |
| 1321 |
return FALSE; |
return FALSE; |
| 1322 |
if (!CRYPT_set_host_RSA_key |
if (!CRYPT_set_host_RSA_key(pvar, |
| 1323 |
(pvar, get_uint32(inmsg + host_key_bits_pos), |
get_uint32(inmsg + host_key_bits_pos), |
| 1324 |
inmsg + host_key_bits_pos + 4, |
inmsg + host_key_bits_pos + 4, |
| 1325 |
inmsg + host_key_public_modulus_pos)) |
inmsg + host_key_public_modulus_pos)) |
| 1326 |
return FALSE; |
return FALSE; |
| 1327 |
pvar->ssh_state.server_protocol_flags = |
pvar->ssh_state.server_protocol_flags = |
| 1328 |
get_uint32(inmsg + protocol_flags_pos); |
get_uint32(inmsg + protocol_flags_pos); |
| 1329 |
|
|
| 1330 |
supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4); |
supported_ciphers = get_uint32(inmsg + protocol_flags_pos + 4); |
| 1331 |
if (!CRYPT_set_supported_ciphers |
if (!CRYPT_set_supported_ciphers(pvar, |
| 1332 |
(pvar, supported_ciphers, supported_ciphers)) |
supported_ciphers, |
| 1333 |
|
supported_ciphers)) |
| 1334 |
return FALSE; |
return FALSE; |
| 1335 |
if (!AUTH_set_supported_auth_types |
if (!AUTH_set_supported_auth_types(pvar, |
| 1336 |
(pvar, get_uint32(inmsg + protocol_flags_pos + 8))) |
get_uint32(inmsg + protocol_flags_pos + 8))) |
| 1337 |
return FALSE; |
return FALSE; |
| 1338 |
|
|
| 1339 |
/* this must be the LAST THING in this function, since it can cause |
/* this must be the LAST THING in this function, since it can cause |
| 1492 |
if (ID[ID_len - 1] != '\n') { |
if (ID[ID_len - 1] != '\n') { |
| 1493 |
pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING; |
pvar->ssh_state.status_flags |= STATUS_IN_PARTIAL_ID_STRING; |
| 1494 |
return FALSE; |
return FALSE; |
| 1495 |
} else |
} else if ((pvar->ssh_state.status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) { |
|
if ((pvar->ssh_state. |
|
|
status_flags & STATUS_IN_PARTIAL_ID_STRING) != 0) { |
|
| 1496 |
pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING; |
pvar->ssh_state.status_flags &= ~STATUS_IN_PARTIAL_ID_STRING; |
| 1497 |
return FALSE; |
return FALSE; |
| 1498 |
} else if (strncmp(ID, "SSH-", 4) != 0) { |
} else if (strncmp(ID, "SSH-", 4) != 0) { |
| 1508 |
|
|
| 1509 |
if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) { |
if (!parse_protocol_ID(pvar, ID) || !negotiate_protocol(pvar)) { |
| 1510 |
UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_VERSION_ERROR", pvar, |
| 1511 |
"This program does not understand the server's version of the protocol."); |
"This program does not understand the server's version of the protocol."); |
| 1512 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 1513 |
} else { |
} else { |
| 1514 |
char TTSSH_ID[1024]; |
char TTSSH_ID[1024]; |
| 1519 |
get_file_version("ttxssh.dll", &a, &b, &c, &d); |
get_file_version("ttxssh.dll", &a, &b, &c, &d); |
| 1520 |
|
|
| 1521 |
_snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE, |
_snprintf_s(TTSSH_ID, sizeof(TTSSH_ID), _TRUNCATE, |
| 1522 |
"SSH-%d.%d-TTSSH/%d.%d Win32\n", |
"SSH-%d.%d-TTSSH/%d.%d Win32\n", |
| 1523 |
pvar->protocol_major, pvar->protocol_minor, a, b); |
pvar->protocol_major, pvar->protocol_minor, a, b); |
| 1524 |
TTSSH_ID_len = strlen(TTSSH_ID); |
TTSSH_ID_len = strlen(TTSSH_ID); |
| 1525 |
|
|
| 1526 |
// for SSH2(yutaka) |
// for SSH2(yutaka) |
| 1527 |
// クライアントバージョンの保存(改行は取り除くこと) |
// クライアントバージョンの保存(改行は取り除くこと) |
| 1528 |
strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string), |
strncpy_s(pvar->client_version_string, sizeof(pvar->client_version_string), |
| 1529 |
TTSSH_ID, _TRUNCATE); |
TTSSH_ID, _TRUNCATE); |
| 1530 |
|
|
| 1531 |
// サーババージョンの保存(改行は取り除くこと)(2005.3.9 yutaka) |
// サーババージョンの保存(改行は取り除くこと)(2005.3.9 yutaka) |
| 1532 |
_snprintf_s(pvar->server_version_string, |
_snprintf_s(pvar->server_version_string, |
| 1533 |
sizeof(pvar->server_version_string), _TRUNCATE, |
sizeof(pvar->server_version_string), _TRUNCATE, |
| 1534 |
"%s", pvar->ssh_state.server_ID); |
"%s", pvar->ssh_state.server_ID); |
| 1535 |
|
|
| 1536 |
if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, |
if ((pvar->Psend) (pvar->socket, TTSSH_ID, TTSSH_ID_len, |
| 1537 |
0) != TTSSH_ID_len) { |
0) != TTSSH_ID_len) { |
| 1538 |
UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SEND_ID_ERROR", pvar, |
| 1539 |
"An error occurred while sending the SSH ID string.\n" |
"An error occurred while sending the SSH ID string.\n" |
| 1540 |
"The connection will close."); |
"The connection will close."); |
| 1541 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 1542 |
} else { |
} else { |
| 1543 |
// 改行コードの除去 (2004.8.4 yutaka) |
// 改行コードの除去 (2004.8.4 yutaka) |
| 1587 |
if ((pvar->ssh_state. |
if ((pvar->ssh_state. |
| 1588 |
server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) { |
server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) { |
| 1589 |
if (grab_payload(pvar, 8) |
if (grab_payload(pvar, 8) |
| 1590 |
&& grab_payload(pvar, |
&& grab_payload(pvar, |
| 1591 |
8 + (host_len = get_payload_uint32(pvar, 4))) |
8 + (host_len = get_payload_uint32(pvar, 4))) |
| 1592 |
&& grab_payload(pvar, originator_len = |
&& grab_payload(pvar, originator_len = |
| 1593 |
get_payload_uint32(pvar, host_len + 12))) { |
get_payload_uint32(pvar, host_len + 12))) { |
| 1594 |
int local_port = get_payload_uint32(pvar, 8 + host_len); |
int local_port = get_payload_uint32(pvar, 8 + host_len); |
| 1595 |
|
|
| 1596 |
pvar->ssh_state.payload[8 + host_len] = 0; |
pvar->ssh_state.payload[8 + host_len] = 0; |
| 1597 |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
| 1598 |
pvar->ssh_state.payload + 8, local_port, |
pvar->ssh_state.payload + 8, local_port, |
| 1599 |
pvar->ssh_state.payload + 16 + host_len, |
pvar->ssh_state.payload + 16 + host_len, |
| 1600 |
originator_len, |
originator_len, |
| 1601 |
NULL); |
NULL); |
| 1602 |
} |
} |
| 1603 |
} else { |
} else { |
| 1604 |
if (grab_payload(pvar, 8) |
if (grab_payload(pvar, 8) |
| 1605 |
&& grab_payload(pvar, |
&& grab_payload(pvar, |
| 1606 |
4 + (host_len = |
4 + (host_len = get_payload_uint32(pvar, 4)))) { |
|
get_payload_uint32(pvar, 4)))) { |
|
| 1607 |
int local_port = get_payload_uint32(pvar, 8 + host_len); |
int local_port = get_payload_uint32(pvar, 8 + host_len); |
| 1608 |
|
|
| 1609 |
pvar->ssh_state.payload[8 + host_len] = 0; |
pvar->ssh_state.payload[8 + host_len] = 0; |
| 1610 |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
FWD_open(pvar, get_payload_uint32(pvar, 0), |
| 1611 |
pvar->ssh_state.payload + 8, local_port, NULL, 0, |
pvar->ssh_state.payload + 8, local_port, NULL, 0, |
| 1612 |
NULL); |
NULL); |
| 1613 |
} |
} |
| 1614 |
} |
} |
| 1615 |
|
|
| 1620 |
{ |
{ |
| 1621 |
int originator_len; |
int originator_len; |
| 1622 |
|
|
| 1623 |
if ((pvar->ssh_state. |
if ((pvar->ssh_state.server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) { |
|
server_protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0) { |
|
| 1624 |
if (grab_payload(pvar, 8) |
if (grab_payload(pvar, 8) |
| 1625 |
&& grab_payload(pvar, originator_len = |
&& grab_payload(pvar, originator_len = get_payload_uint32(pvar, 4))) { |
|
get_payload_uint32(pvar, 4))) { |
|
| 1626 |
FWD_X11_open(pvar, get_payload_uint32(pvar, 0), |
FWD_X11_open(pvar, get_payload_uint32(pvar, 0), |
| 1627 |
pvar->ssh_state.payload + 8, originator_len, NULL); |
pvar->ssh_state.payload + 8, originator_len, NULL); |
| 1628 |
} |
} |
| 1629 |
} else { |
} else { |
| 1630 |
if (grab_payload(pvar, 4)) { |
if (grab_payload(pvar, 4)) { |
| 1639 |
{ |
{ |
| 1640 |
if (grab_payload(pvar, 8)) { |
if (grab_payload(pvar, 8)) { |
| 1641 |
FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0), |
FWD_confirmed_open(pvar, get_payload_uint32(pvar, 0), |
| 1642 |
get_payload_uint32(pvar, 4)); |
get_payload_uint32(pvar, 4)); |
| 1643 |
} |
} |
| 1644 |
return FALSE; |
return FALSE; |
| 1645 |
} |
} |
| 1657 |
int len; |
int len; |
| 1658 |
|
|
| 1659 |
if (grab_payload(pvar, 8) |
if (grab_payload(pvar, 8) |
| 1660 |
&& grab_payload(pvar, len = get_payload_uint32(pvar, 4))) { |
&& grab_payload(pvar, len = get_payload_uint32(pvar, 4))) { |
| 1661 |
FWD_received_data(pvar, get_payload_uint32(pvar, 0), |
FWD_received_data(pvar, get_payload_uint32(pvar, 0), |
| 1662 |
pvar->ssh_state.payload + 8, len); |
pvar->ssh_state.payload + 8, len); |
| 1663 |
} |
} |
| 1664 |
return TRUE; |
return TRUE; |
| 1665 |
} |
} |
| 1775 |
char buf[1024]; |
char buf[1024]; |
| 1776 |
|
|
| 1777 |
UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, |
| 1778 |
"Unexpected packet type received: %d"); |
"Unexpected packet type received: %d"); |
| 1779 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 1780 |
pvar->ts->UIMsg, message, handle_message_stage); |
pvar->ts->UIMsg, message, handle_message_stage); |
| 1781 |
notify_fatal_error(pvar, buf); |
notify_fatal_error(pvar, buf); |
| 1784 |
begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4); |
begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4); |
| 1785 |
|
|
| 1786 |
set_uint32(outmsg, |
set_uint32(outmsg, |
| 1787 |
pvar->ssh_state.receiver_sequence_number - 1); |
pvar->ssh_state.receiver_sequence_number - 1); |
| 1788 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 1789 |
/* XXX need to decompress incoming packet, but how? */ |
/* XXX need to decompress incoming packet, but how? */ |
| 1790 |
} |
} |
| 1804 |
enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data); |
enque_handler(pvar, SSH_SMSG_STDERR_DATA, handle_data); |
| 1805 |
enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data); |
enque_handler(pvar, SSH_MSG_CHANNEL_DATA, handle_channel_data); |
| 1806 |
enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, |
enque_handler(pvar, SSH_MSG_CHANNEL_INPUT_EOF, |
| 1807 |
handle_channel_input_eof); |
handle_channel_input_eof); |
| 1808 |
enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, |
enque_handler(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, |
| 1809 |
handle_channel_output_eof); |
handle_channel_output_eof); |
| 1810 |
enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open); |
enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open); |
| 1811 |
enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open); |
enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open); |
| 1812 |
return FALSE; |
return FALSE; |
| 1815 |
static BOOL handle_pty_failure(PTInstVar pvar) |
static BOOL handle_pty_failure(PTInstVar pvar) |
| 1816 |
{ |
{ |
| 1817 |
UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_ALLOC_TERMINAL_ERROR", pvar, |
| 1818 |
"The server cannot allocate a pseudo-terminal. " |
"The server cannot allocate a pseudo-terminal. " |
| 1819 |
"You may encounter some problems with the terminal."); |
"You may encounter some problems with the terminal."); |
| 1820 |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 1821 |
return handle_pty_success(pvar); |
return handle_pty_success(pvar); |
| 1822 |
} |
} |
| 1826 |
int len = strlen(pvar->ts->TermType); |
int len = strlen(pvar->ts->TermType); |
| 1827 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 1828 |
begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, |
begin_send_packet(pvar, SSH_CMSG_REQUEST_PTY, |
| 1829 |
4 + len + 16 + sizeof(ssh_ttymodes)); |
4 + len + 16 + sizeof(ssh_ttymodes)); |
| 1830 |
static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE }; |
static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE }; |
| 1831 |
static const SSHPacketHandler handlers[] |
static const SSHPacketHandler handlers[] |
| 1832 |
= { handle_pty_success, handle_pty_failure }; |
= { handle_pty_success, handle_pty_failure }; |
| 1869 |
pvar->ssh_state.compress_stream.zfree = NULL; |
pvar->ssh_state.compress_stream.zfree = NULL; |
| 1870 |
pvar->ssh_state.compress_stream.opaque = NULL; |
pvar->ssh_state.compress_stream.opaque = NULL; |
| 1871 |
if (deflateInit |
if (deflateInit |
| 1872 |
(&pvar->ssh_state.compress_stream, |
(&pvar->ssh_state.compress_stream, |
| 1873 |
pvar->ssh_state.compression_level) != Z_OK) { |
pvar->ssh_state.compression_level) != Z_OK) { |
| 1874 |
UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar, |
| 1875 |
"An error occurred while setting up compression.\n" |
"An error occurred while setting up compression.\n" |
| 1876 |
"The connection will close."); |
"The connection will close."); |
| 1877 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 1878 |
return; |
return; |
| 1879 |
} else { |
} else { |
| 1901 |
if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) { |
if (inflateInit(&pvar->ssh_state.decompress_stream) != Z_OK) { |
| 1902 |
deflateEnd(&pvar->ssh_state.compress_stream); |
deflateEnd(&pvar->ssh_state.compress_stream); |
| 1903 |
UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SETUP_COMP_ERROR", pvar, |
| 1904 |
"An error occurred while setting up compression.\n" |
"An error occurred while setting up compression.\n" |
| 1905 |
"The connection will close."); |
"The connection will close."); |
| 1906 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 1907 |
return; |
return; |
| 1908 |
} else { |
} else { |
| 1914 |
} |
} |
| 1915 |
|
|
| 1916 |
buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, |
buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf, |
| 1917 |
&pvar->ssh_state.postdecompress_inbuflen, 1000); |
&pvar->ssh_state.postdecompress_inbuflen, 1000); |
| 1918 |
} |
} |
| 1919 |
} |
} |
| 1920 |
|
|
| 2010 |
enque_simple_auth_handlers(pvar); |
enque_simple_auth_handlers(pvar); |
| 2011 |
} else { |
} else { |
| 2012 |
UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar, |
| 2013 |
"An error occurred while decrypting the RSA challenge.\n" |
"An error occurred while decrypting the RSA challenge.\n" |
| 2014 |
"Perhaps the key file is corrupted."); |
"Perhaps the key file is corrupted."); |
| 2015 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2016 |
} |
} |
| 2017 |
} |
} |
| 2052 |
int obfuscated_len = obfuscating_round_up(pvar, len); |
int obfuscated_len = obfuscating_round_up(pvar, len); |
| 2053 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2054 |
begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD, |
begin_send_packet(pvar, SSH_CMSG_AUTH_PASSWORD, |
| 2055 |
4 + obfuscated_len); |
4 + obfuscated_len); |
| 2056 |
|
|
| 2057 |
notify_verbose_message(pvar, |
notify_verbose_message(pvar, |
| 2058 |
"Trying PASSWORD authentication...", |
"Trying PASSWORD authentication...", |
| 2059 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2060 |
|
|
| 2061 |
set_uint32(outmsg, obfuscated_len); |
set_uint32(outmsg, obfuscated_len); |
| 2062 |
memcpy(outmsg + 4, cred->password, len); |
memcpy(outmsg + 4, cred->password, len); |
| 2077 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len); |
begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS, 4 + len); |
| 2078 |
|
|
| 2079 |
notify_verbose_message(pvar, |
notify_verbose_message(pvar, |
| 2080 |
"Trying RHOSTS authentication...", |
"Trying RHOSTS authentication...", |
| 2081 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2082 |
|
|
| 2083 |
set_uint32(outmsg, len); |
set_uint32(outmsg, len); |
| 2084 |
memcpy(outmsg + 4, cred->rhosts_client_user, len); |
memcpy(outmsg + 4, cred->rhosts_client_user, len); |
| 2092 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len); |
begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len); |
| 2093 |
|
|
| 2094 |
notify_verbose_message(pvar, |
notify_verbose_message(pvar, |
| 2095 |
"Trying RSA authentication...", |
"Trying RSA authentication...", |
| 2096 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2097 |
|
|
| 2098 |
set_ushort16_MSBfirst(outmsg, len * 8); |
set_ushort16_MSBfirst(outmsg, len * 8); |
| 2099 |
BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2); |
BN_bn2bin(cred->key_pair->RSA_key->n, outmsg + 2); |
| 2108 |
int index; |
int index; |
| 2109 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2110 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA, |
begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA, |
| 2111 |
12 + mod_len + name_len + exp_len); |
12 + mod_len + name_len + exp_len); |
| 2112 |
|
|
| 2113 |
notify_verbose_message(pvar, |
notify_verbose_message(pvar, |
| 2114 |
"Trying RHOSTS+RSA authentication...", |
"Trying RHOSTS+RSA authentication...", |
| 2115 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2116 |
|
|
| 2117 |
set_uint32(outmsg, name_len); |
set_uint32(outmsg, name_len); |
| 2118 |
memcpy(outmsg + 4, cred->rhosts_client_user, name_len); |
memcpy(outmsg + 4, cred->rhosts_client_user, name_len); |
| 2135 |
begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0); |
begin_send_packet(pvar, SSH_CMSG_AUTH_TIS, 0); |
| 2136 |
|
|
| 2137 |
notify_verbose_message(pvar, |
notify_verbose_message(pvar, |
| 2138 |
"Trying TIS authentication...", |
"Trying TIS authentication...", |
| 2139 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2140 |
enque_handlers(pvar, 2, TIS_msgs, TIS_handlers); |
enque_handlers(pvar, 2, TIS_msgs, TIS_handlers); |
| 2141 |
} else { |
} else { |
| 2142 |
int len = strlen(cred->password); |
int len = strlen(cred->password); |
| 2143 |
int obfuscated_len = obfuscating_round_up(pvar, len); |
int obfuscated_len = obfuscating_round_up(pvar, len); |
| 2144 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2145 |
begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE, |
begin_send_packet(pvar, SSH_CMSG_AUTH_TIS_RESPONSE, |
| 2146 |
4 + obfuscated_len); |
4 + obfuscated_len); |
| 2147 |
|
|
| 2148 |
notify_verbose_message(pvar, "Sending TIS response", |
notify_verbose_message(pvar, "Sending TIS response", |
| 2149 |
LOG_LEVEL_VERBOSE); |
LOG_LEVEL_VERBOSE); |
| 2150 |
|
|
| 2151 |
set_uint32(outmsg, obfuscated_len); |
set_uint32(outmsg, obfuscated_len); |
| 2152 |
memcpy(outmsg + 4, cred->password, len); |
memcpy(outmsg + 4, cred->password, len); |
| 2159 |
} |
} |
| 2160 |
default: |
default: |
| 2161 |
UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_UNSUPPORT_AUTH_METHOD_ERROR", pvar, |
| 2162 |
"Internal error: unsupported authentication method"); |
"Internal error: unsupported authentication method"); |
| 2163 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2164 |
return; |
return; |
| 2165 |
} |
} |
| 2220 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 2221 |
outmsg = |
outmsg = |
| 2222 |
begin_send_packet(pvar, SSH_CMSG_SESSION_KEY, |
begin_send_packet(pvar, SSH_CMSG_SESSION_KEY, |
| 2223 |
15 + encrypted_session_key_len); |
15 + encrypted_session_key_len); |
| 2224 |
outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar); |
outmsg[0] = (unsigned char) CRYPT_get_sender_cipher(pvar); |
| 2225 |
memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */ |
memcpy(outmsg + 1, CRYPT_get_server_cookie(pvar), 8); /* antispoofing cookie */ |
| 2226 |
outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5); |
outmsg[9] = (unsigned char) (encrypted_session_key_len >> 5); |
| 2228 |
if (!CRYPT_choose_session_key(pvar, outmsg + 11)) |
if (!CRYPT_choose_session_key(pvar, outmsg + 11)) |
| 2229 |
return; |
return; |
| 2230 |
set_uint32(outmsg + 11 + encrypted_session_key_len, |
set_uint32(outmsg + 11 + encrypted_session_key_len, |
| 2231 |
SSH_PROTOFLAG_SCREEN_NUMBER | |
SSH_PROTOFLAG_SCREEN_NUMBER | |
| 2232 |
SSH_PROTOFLAG_HOST_IN_FWD_OPEN); |
SSH_PROTOFLAG_HOST_IN_FWD_OPEN); |
| 2233 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 2234 |
} |
} |
| 2235 |
|
|
| 2258 |
|
|
| 2259 |
buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen); |
buf_create(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen); |
| 2260 |
buf_create(&pvar->ssh_state.precompress_outbuf, |
buf_create(&pvar->ssh_state.precompress_outbuf, |
| 2261 |
&pvar->ssh_state.precompress_outbuflen); |
&pvar->ssh_state.precompress_outbuflen); |
| 2262 |
buf_create(&pvar->ssh_state.postdecompress_inbuf, |
buf_create(&pvar->ssh_state.postdecompress_inbuf, |
| 2263 |
&pvar->ssh_state.postdecompress_inbuflen); |
&pvar->ssh_state.postdecompress_inbuflen); |
| 2264 |
pvar->ssh_state.payload = NULL; |
pvar->ssh_state.payload = NULL; |
| 2265 |
pvar->ssh_state.compressing = FALSE; |
pvar->ssh_state.compressing = FALSE; |
| 2266 |
pvar->ssh_state.decompressing = FALSE; |
pvar->ssh_state.decompressing = FALSE; |
| 2460 |
|
|
| 2461 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 2462 |
buf_ensure_size(&pvar->ssh_state.outbuf, |
buf_ensure_size(&pvar->ssh_state.outbuf, |
| 2463 |
&pvar->ssh_state.outbuflen, |
&pvar->ssh_state.outbuflen, |
| 2464 |
len + (len >> 6) + 50); |
len + (len >> 6) + 50); |
| 2465 |
pvar->ssh_state.compress_stream.next_in = |
pvar->ssh_state.compress_stream.next_in = |
| 2466 |
pvar->ssh_state.precompress_outbuf; |
pvar->ssh_state.precompress_outbuf; |
| 2467 |
pvar->ssh_state.compress_stream.avail_in = 5; |
pvar->ssh_state.compress_stream.avail_in = 5; |
| 2470 |
pvar->ssh_state.compress_stream.avail_out = |
pvar->ssh_state.compress_stream.avail_out = |
| 2471 |
pvar->ssh_state.outbuflen - 12; |
pvar->ssh_state.outbuflen - 12; |
| 2472 |
|
|
| 2473 |
if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != |
if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) { |
|
Z_OK) { |
|
| 2474 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 2475 |
"Error compressing packet data"); |
"Error compressing packet data"); |
| 2476 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2481 |
(unsigned char FAR *) buf; |
(unsigned char FAR *) buf; |
| 2482 |
pvar->ssh_state.compress_stream.avail_in = len; |
pvar->ssh_state.compress_stream.avail_in = len; |
| 2483 |
|
|
| 2484 |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != Z_OK) { |
|
Z_OK) { |
|
| 2485 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 2486 |
"Error compressing packet data"); |
"Error compressing packet data"); |
| 2487 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2488 |
return; |
return; |
| 2489 |
} |
} |
| 2547 |
|
|
| 2548 |
if (!pvar->ssh_state.decompressing) { |
if (!pvar->ssh_state.decompressing) { |
| 2549 |
memcpy(dest, |
memcpy(dest, |
| 2550 |
pvar->ssh_state.payload + pvar->ssh_state.payload_datastart, |
pvar->ssh_state.payload + pvar->ssh_state.payload_datastart, |
| 2551 |
num_bytes); |
num_bytes); |
| 2552 |
pvar->ssh_state.payload_datastart += num_bytes; |
pvar->ssh_state.payload_datastart += num_bytes; |
| 2553 |
} else if (num_bytes > 0) { |
} else if (num_bytes > 0) { |
| 2554 |
pvar->ssh_state.decompress_stream.next_out = dest; |
pvar->ssh_state.decompress_stream.next_out = dest; |
| 2555 |
pvar->ssh_state.decompress_stream.avail_out = num_bytes; |
pvar->ssh_state.decompress_stream.avail_out = num_bytes; |
| 2556 |
|
|
| 2557 |
if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != |
if (inflate(&pvar->ssh_state.decompress_stream, Z_SYNC_FLUSH) != Z_OK) { |
|
Z_OK) { |
|
| 2558 |
UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_INVALID_COMPDATA_ERROR", pvar, |
| 2559 |
"Invalid compressed data in received packet"); |
"Invalid compressed data in received packet"); |
| 2560 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2561 |
return 0; |
return 0; |
| 2562 |
} |
} |
| 2583 |
|
|
| 2584 |
if (total_out > 0) { |
if (total_out > 0) { |
| 2585 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar, |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar, |
| 2586 |
"level %d; ratio %.1f (%ld:%ld)"); |
"level %d; ratio %.1f (%ld:%ld)"); |
| 2587 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
| 2588 |
pvar->ssh_state.compression_level, |
pvar->ssh_state.compression_level, |
| 2589 |
((double) total_in) / total_out, total_in, |
((double) total_in) / total_out, total_in, |
| 2590 |
total_out); |
total_out); |
| 2591 |
} else { |
} else { |
| 2592 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d"); |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d"); |
| 2593 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
| 2594 |
pvar->ssh_state.compression_level); |
pvar->ssh_state.compression_level); |
| 2595 |
} |
} |
| 2596 |
} else { |
} else { |
| 2597 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none"); |
UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none"); |
| 2609 |
|
|
| 2610 |
if (total_in > 0) { |
if (total_in > 0) { |
| 2611 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar, |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO", pvar, |
| 2612 |
"level %d; ratio %.1f (%ld:%ld)"); |
"level %d; ratio %.1f (%ld:%ld)"); |
| 2613 |
_snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg, |
| 2614 |
pvar->ssh_state.compression_level, |
pvar->ssh_state.compression_level, |
| 2615 |
((double) total_out) / total_in, total_out, |
((double) total_out) / total_in, total_out, |
| 2616 |
total_in); |
total_in); |
| 2617 |
} else { |
} else { |
| 2618 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d"); |
UTIL_get_lang_msg("DLG_ABOUT_COMP_INFO2", pvar, "level %d"); |
| 2619 |
_snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(buf2, sizeof(buf2), _TRUNCATE, pvar->ts->UIMsg, |
| 2620 |
pvar->ssh_state.compression_level); |
pvar->ssh_state.compression_level); |
| 2621 |
} |
} |
| 2622 |
} else { |
} else { |
| 2623 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none"); |
UTIL_get_lang_msg("DLG_ABOUT_COMP_NONE", pvar, "none"); |
| 2625 |
} |
} |
| 2626 |
|
|
| 2627 |
UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar, |
UTIL_get_lang_msg("DLG_ABOUT_COMP_UPDOWN", pvar, |
| 2628 |
"Upstream %s; Downstream %s"); |
"Upstream %s; Downstream %s"); |
| 2629 |
_snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2); |
_snprintf_s(dest, len, _TRUNCATE, pvar->ts->UIMsg, buf, buf2); |
| 2630 |
} |
} |
| 2631 |
|
|
| 2632 |
void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len) |
void SSH_get_server_ID_info(PTInstVar pvar, char FAR * dest, int len) |
| 2633 |
{ |
{ |
| 2634 |
strncpy_s(dest, len, |
strncpy_s(dest, len, |
| 2635 |
pvar->ssh_state.server_ID == NULL ? "Unknown" |
pvar->ssh_state.server_ID == NULL ? "Unknown" |
| 2636 |
: pvar->ssh_state.server_ID, |
: pvar->ssh_state.server_ID, |
| 2637 |
_TRUNCATE); |
_TRUNCATE); |
| 2638 |
} |
} |
| 2639 |
|
|
| 2640 |
void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest, |
void SSH_get_protocol_version_info(PTInstVar pvar, char FAR * dest, |
| 2641 |
int len) |
int len) |
| 2642 |
{ |
{ |
| 2643 |
if (pvar->protocol_major == 0) { |
if (pvar->protocol_major == 0) { |
| 2644 |
strncpy_s(dest, len, "Unknown", _TRUNCATE); |
strncpy_s(dest, len, "Unknown", _TRUNCATE); |
| 2645 |
} else { |
} else { |
| 2646 |
_snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major, |
_snprintf_s(dest, len, _TRUNCATE, "%d.%d", pvar->protocol_major, |
| 2647 |
pvar->protocol_minor); |
pvar->protocol_minor); |
| 2648 |
} |
} |
| 2649 |
} |
} |
| 2650 |
|
|
| 2675 |
pvar->ssh_state.server_ID = NULL; |
pvar->ssh_state.server_ID = NULL; |
| 2676 |
buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen); |
buf_destroy(&pvar->ssh_state.outbuf, &pvar->ssh_state.outbuflen); |
| 2677 |
buf_destroy(&pvar->ssh_state.precompress_outbuf, |
buf_destroy(&pvar->ssh_state.precompress_outbuf, |
| 2678 |
&pvar->ssh_state.precompress_outbuflen); |
&pvar->ssh_state.precompress_outbuflen); |
| 2679 |
buf_destroy(&pvar->ssh_state.postdecompress_inbuf, |
buf_destroy(&pvar->ssh_state.postdecompress_inbuf, |
| 2680 |
&pvar->ssh_state.postdecompress_inbuflen); |
&pvar->ssh_state.postdecompress_inbuflen); |
| 2681 |
|
|
| 2682 |
// support of "Compression delayed" (2006.6.23 maya) |
// support of "Compression delayed" (2006.6.23 maya) |
| 2683 |
if (pvar->ssh_state.compressing || |
if (pvar->ssh_state.compressing || |
| 2746 |
|
|
| 2747 |
/* support for port forwarding */ |
/* support for port forwarding */ |
| 2748 |
void SSH_channel_send(PTInstVar pvar, int channel_num, |
void SSH_channel_send(PTInstVar pvar, int channel_num, |
| 2749 |
uint32 remote_channel_num, |
uint32 remote_channel_num, |
| 2750 |
unsigned char FAR * buf, int len) |
unsigned char FAR * buf, int len) |
| 2751 |
{ |
{ |
| 2752 |
int buflen = len; |
int buflen = len; |
| 2753 |
|
|
| 2760 |
|
|
| 2761 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 2762 |
buf_ensure_size(&pvar->ssh_state.outbuf, |
buf_ensure_size(&pvar->ssh_state.outbuf, |
| 2763 |
&pvar->ssh_state.outbuflen, len + (len >> 6) + 50); |
&pvar->ssh_state.outbuflen, len + (len >> 6) + 50); |
| 2764 |
pvar->ssh_state.compress_stream.next_in = |
pvar->ssh_state.compress_stream.next_in = |
| 2765 |
pvar->ssh_state.precompress_outbuf; |
pvar->ssh_state.precompress_outbuf; |
| 2766 |
pvar->ssh_state.compress_stream.avail_in = 9; |
pvar->ssh_state.compress_stream.avail_in = 9; |
| 2771 |
|
|
| 2772 |
if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) { |
if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) { |
| 2773 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 2774 |
"Error compressing packet data"); |
"Error compressing packet data"); |
| 2775 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2776 |
return; |
return; |
| 2777 |
} |
} |
| 2783 |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != |
if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) != |
| 2784 |
Z_OK) { |
Z_OK) { |
| 2785 |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_COMP_ERROR", pvar, |
| 2786 |
"Error compressing packet data"); |
"Error compressing packet data"); |
| 2787 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2788 |
return; |
return; |
| 2789 |
} |
} |
| 2971 |
} |
} |
| 2972 |
|
|
| 2973 |
void SSH_request_forwarding(PTInstVar pvar, int from_server_port, |
void SSH_request_forwarding(PTInstVar pvar, int from_server_port, |
| 2974 |
char FAR * to_local_host, int to_local_port) |
char FAR * to_local_host, int to_local_port) |
| 2975 |
{ |
{ |
| 2976 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 2977 |
int host_len = strlen(to_local_host); |
int host_len = strlen(to_local_host); |
| 2978 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2979 |
begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST, |
begin_send_packet(pvar, SSH_CMSG_PORT_FORWARD_REQUEST, |
| 2980 |
12 + host_len); |
12 + host_len); |
| 2981 |
|
|
| 2982 |
set_uint32(outmsg, from_server_port); |
set_uint32(outmsg, from_server_port); |
| 2983 |
set_uint32(outmsg + 4, host_len); |
set_uint32(outmsg + 4, host_len); |
| 3017 |
} |
} |
| 3018 |
|
|
| 3019 |
void SSH_request_X11_forwarding(PTInstVar pvar, |
void SSH_request_X11_forwarding(PTInstVar pvar, |
| 3020 |
char FAR * auth_protocol, |
char FAR * auth_protocol, |
| 3021 |
unsigned char FAR * auth_data, |
unsigned char FAR * auth_data, |
| 3022 |
int auth_data_len, int screen_num) |
int auth_data_len, int screen_num) |
| 3023 |
{ |
{ |
| 3024 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 3025 |
int protocol_len = strlen(auth_protocol); |
int protocol_len = strlen(auth_protocol); |
| 3035 |
set_uint32(outmsg + 4 + protocol_len, data_len); |
set_uint32(outmsg + 4 + protocol_len, data_len); |
| 3036 |
auth_data_ptr = outmsg + 8 + protocol_len; |
auth_data_ptr = outmsg + 8 + protocol_len; |
| 3037 |
for (i = 0; i < auth_data_len; i++) { |
for (i = 0; i < auth_data_len; i++) { |
| 3038 |
_snprintf_s(auth_data_ptr + i * 2, outmsg_len - (auth_data_ptr - outmsg) - i * 2, |
_snprintf_s(auth_data_ptr + i * 2, |
| 3039 |
_TRUNCATE, "%.2x", auth_data[i]); |
outmsg_len - (auth_data_ptr - outmsg) - i * 2, |
| 3040 |
|
_TRUNCATE, "%.2x", auth_data[i]); |
| 3041 |
} |
} |
| 3042 |
set_uint32(outmsg + 8 + protocol_len + data_len, screen_num); |
set_uint32(outmsg + 8 + protocol_len + data_len, screen_num); |
| 3043 |
|
|
| 3101 |
} |
} |
| 3102 |
|
|
| 3103 |
void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num, |
void SSH_open_channel(PTInstVar pvar, uint32 local_channel_num, |
| 3104 |
char FAR * to_remote_host, int to_remote_port, |
char FAR * to_remote_host, int to_remote_port, |
| 3105 |
char FAR * originator, unsigned short originator_port) |
char FAR * originator, unsigned short originator_port) |
| 3106 |
{ |
{ |
| 3107 |
static const int msgs[] |
static const int msgs[] |
| 3108 |
= { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE }; |
= { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE }; |
| 3116 |
int originator_len = strlen(originator); |
int originator_len = strlen(originator); |
| 3117 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 3118 |
begin_send_packet(pvar, SSH_MSG_PORT_OPEN, |
begin_send_packet(pvar, SSH_MSG_PORT_OPEN, |
| 3119 |
16 + host_len + originator_len); |
16 + host_len + originator_len); |
| 3120 |
|
|
| 3121 |
set_uint32(outmsg, local_channel_num); |
set_uint32(outmsg, local_channel_num); |
| 3122 |
set_uint32(outmsg + 4, host_len); |
set_uint32(outmsg + 4, host_len); |
| 3129 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 3130 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 3131 |
begin_send_packet(pvar, SSH_MSG_PORT_OPEN, |
begin_send_packet(pvar, SSH_MSG_PORT_OPEN, |
| 3132 |
12 + host_len); |
12 + host_len); |
| 3133 |
|
|
| 3134 |
set_uint32(outmsg, local_channel_num); |
set_uint32(outmsg, local_channel_num); |
| 3135 |
set_uint32(outmsg + 4, host_len); |
set_uint32(outmsg + 4, host_len); |
| 3159 |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
| 3160 |
FWD_free_channel(pvar, local_channel_num); |
FWD_free_channel(pvar, local_channel_num); |
| 3161 |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
| 3162 |
"Could not open new channel. TTSSH is already opening too many channels."); |
"Could not open new channel. TTSSH is already opening too many channels."); |
| 3163 |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 3164 |
return; |
return; |
| 3165 |
} |
} |
| 3769 |
offset += size; |
offset += size; |
| 3770 |
pvar->hostkey_type = -1; |
pvar->hostkey_type = -1; |
| 3771 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, |
| 3772 |
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]); |
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]); |
| 3773 |
ptr = strtok(tmp, ","); // not thread-safe |
ptr = strtok(tmp, ","); // not thread-safe |
| 3774 |
while (ptr != NULL) { |
while (ptr != NULL) { |
| 3775 |
// buf[]にはサーバのproposalがカンマ文字列で格納されている |
// buf[]にはサーバのproposalがカンマ文字列で格納されている |
| 3806 |
#endif |
#endif |
| 3807 |
|
|
| 3808 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3809 |
"server host key algorithm: %s", ptr); |
"server host key algorithm: %s", ptr); |
| 3810 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3811 |
|
|
| 3812 |
// クライアント -> サーバ暗号アルゴリズムチェック |
// クライアント -> サーバ暗号アルゴリズムチェック |
| 3826 |
} |
} |
| 3827 |
|
|
| 3828 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3829 |
"encryption algorithm client to server: %s", |
"encryption algorithm client to server: %s", |
| 3830 |
get_cipher_string(pvar->ctos_cipher)); |
get_cipher_string(pvar->ctos_cipher)); |
| 3831 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3832 |
|
|
| 3833 |
// サーバ -> クライアント暗号アルゴリズムチェック |
// サーバ -> クライアント暗号アルゴリズムチェック |
| 3847 |
} |
} |
| 3848 |
|
|
| 3849 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3850 |
"encryption algorithm server to client: %s", |
"encryption algorithm server to client: %s", |
| 3851 |
get_cipher_string(pvar->stoc_cipher)); |
get_cipher_string(pvar->stoc_cipher)); |
| 3852 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3853 |
|
|
| 3854 |
// HMAC(Hash Message Authentication Code)アルゴリズムの決定 (2004.12.17 yutaka) |
// HMAC(Hash Message Authentication Code)アルゴリズムの決定 (2004.12.17 yutaka) |
| 3868 |
} |
} |
| 3869 |
|
|
| 3870 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3871 |
"MAC algorithm client to server: %s", |
"MAC algorithm client to server: %s", |
| 3872 |
ssh2_macs[pvar->ctos_hmac]); |
ssh2_macs[pvar->ctos_hmac]); |
| 3873 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3874 |
|
|
| 3875 |
size = get_payload_uint32(pvar, offset); |
size = get_payload_uint32(pvar, offset); |
| 3888 |
} |
} |
| 3889 |
|
|
| 3890 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3891 |
"MAC algorithm server to client: %s", |
"MAC algorithm server to client: %s", |
| 3892 |
ssh2_macs[pvar->stoc_hmac]); |
ssh2_macs[pvar->stoc_hmac]); |
| 3893 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3894 |
|
|
| 3895 |
// 圧縮アルゴリズムの決定 |
// 圧縮アルゴリズムの決定 |
| 3911 |
} |
} |
| 3912 |
|
|
| 3913 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3914 |
"compression algorithm client to server: %s", |
"compression algorithm client to server: %s", |
| 3915 |
ssh_comp[pvar->ctos_compression]); |
ssh_comp[pvar->ctos_compression]); |
| 3916 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3917 |
|
|
| 3918 |
size = get_payload_uint32(pvar, offset); |
size = get_payload_uint32(pvar, offset); |
| 3931 |
} |
} |
| 3932 |
|
|
| 3933 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 3934 |
"compression algorithm server to client: %s", |
"compression algorithm server to client: %s", |
| 3935 |
ssh_comp[pvar->stoc_compression]); |
ssh_comp[pvar->stoc_compression]); |
| 3936 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 3937 |
|
|
| 3938 |
// we_needの決定 (2004.11.6 yutaka) |
// we_needの決定 (2004.11.6 yutaka) |
| 4010 |
static DH *dh_new_group14(void) |
static DH *dh_new_group14(void) |
| 4011 |
{ |
{ |
| 4012 |
static char *gen = "2", *group14 = |
static char *gen = "2", *group14 = |
| 4013 |
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
| 4014 |
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" |
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" |
| 4015 |
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" |
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" |
| 4016 |
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" |
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" |
| 4017 |
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" |
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" |
| 4018 |
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" |
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" |
| 4093 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 4094 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 4095 |
|
|
| 4096 |
if (pvar->kexdh != NULL) { |
if (pvar->kexdh != NULL) { |
| 4097 |
DH_free(pvar->kexdh); |
DH_free(pvar->kexdh); |
| 4098 |
} |
} |
| 4099 |
pvar->kexdh = dh; |
pvar->kexdh = dh; |
| 4100 |
|
|
| 4101 |
SSH2_dispatch_init(2); |
SSH2_dispatch_init(2); |
| 4126 |
|
|
| 4127 |
static int dh_estimate(int bits) |
static int dh_estimate(int bits) |
| 4128 |
{ |
{ |
| 4129 |
if (bits <= 128) |
if (bits <= 128) |
| 4130 |
return (1024); /* O(2**86) */ |
return (1024); /* O(2**86) */ |
| 4131 |
if (bits <= 192) |
if (bits <= 192) |
| 4132 |
return (2048); /* O(2**116) */ |
return (2048); /* O(2**116) */ |
| 4133 |
return (4096); /* O(2**156) */ |
return (4096); /* O(2**156) */ |
| 4134 |
} |
} |
| 4135 |
|
|
| 4136 |
static void SSH2_dh_gex_kex_init(PTInstVar pvar) |
static void SSH2_dh_gex_kex_init(PTInstVar pvar) |
| 4137 |
{ |
{ |
| 4167 |
{ |
{ |
| 4168 |
char tmp[128]; |
char tmp[128]; |
| 4169 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, |
| 4170 |
"we_need %d min %d bits %d max %d", |
"we_need %d min %d bits %d max %d", |
| 4171 |
pvar->we_need, min, bits, max); |
pvar->we_need, min, bits, max); |
| 4172 |
push_memdump("DH_GEX_REQUEST", "requested key bits", tmp, strlen(tmp)); |
push_memdump("DH_GEX_REQUEST", "requested key bits", tmp, strlen(tmp)); |
| 4173 |
} |
} |
| 4174 |
|
|
| 4264 |
|
|
| 4265 |
|
|
| 4266 |
// SHA-1(160bit)を求める |
// SHA-1(160bit)を求める |
| 4267 |
unsigned char *kex_dh_hash( |
unsigned char *kex_dh_hash(char *client_version_string, |
| 4268 |
char *client_version_string, |
char *server_version_string, |
| 4269 |
char *server_version_string, |
char *ckexinit, int ckexinitlen, |
| 4270 |
char *ckexinit, int ckexinitlen, |
char *skexinit, int skexinitlen, |
| 4271 |
char *skexinit, int skexinitlen, |
u_char *serverhostkeyblob, int sbloblen, |
| 4272 |
u_char *serverhostkeyblob, int sbloblen, |
BIGNUM *client_dh_pub, |
| 4273 |
BIGNUM *client_dh_pub, |
BIGNUM *server_dh_pub, |
| 4274 |
BIGNUM *server_dh_pub, |
BIGNUM *shared_secret) |
|
BIGNUM *shared_secret) |
|
| 4275 |
{ |
{ |
| 4276 |
buffer_t *b; |
buffer_t *b; |
| 4277 |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
| 4333 |
} |
} |
| 4334 |
|
|
| 4335 |
|
|
| 4336 |
static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len) |
static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, |
| 4337 |
|
char *session_id, int session_id_len) |
| 4338 |
{ |
{ |
| 4339 |
buffer_t *b; |
buffer_t *b; |
| 4340 |
const EVP_MD *evp_md = EVP_sha1(); |
const EVP_MD *evp_md = EVP_sha1(); |
| 4399 |
} |
} |
| 4400 |
|
|
| 4401 |
|
|
| 4402 |
void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len) |
void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret, |
| 4403 |
|
char *session_id, int session_id_len) |
| 4404 |
{ |
{ |
| 4405 |
#define NKEYS 6 |
#define NKEYS 6 |
| 4406 |
u_char *keys[NKEYS]; |
u_char *keys[NKEYS]; |
| 4450 |
// DSS |
// DSS |
| 4451 |
// |
// |
| 4452 |
|
|
| 4453 |
static int ssh_dss_verify( |
static int ssh_dss_verify(DSA *key, |
| 4454 |
DSA *key, u_char *signature, u_int signaturelen, |
u_char *signature, u_int signaturelen, |
| 4455 |
u_char *data, u_int datalen) |
u_char *data, u_int datalen) |
| 4456 |
{ |
{ |
| 4457 |
DSA_SIG *sig; |
DSA_SIG *sig; |
| 4458 |
const EVP_MD *evp_md = EVP_sha1(); |
const EVP_MD *evp_md = EVP_sha1(); |
| 4553 |
}; |
}; |
| 4554 |
|
|
| 4555 |
static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen, |
static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen, |
| 4556 |
u_char *sigbuf, u_int siglen, RSA *rsa) |
u_char *sigbuf, u_int siglen, RSA *rsa) |
| 4557 |
{ |
{ |
| 4558 |
u_int ret, rsasize, oidlen = 0, hlen = 0; |
u_int ret, rsasize, oidlen = 0, hlen = 0; |
| 4559 |
int len; |
int len; |
| 4590 |
return 1; // error |
return 1; // error |
| 4591 |
|
|
| 4592 |
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, |
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, |
| 4593 |
RSA_PKCS1_PADDING)) < 0) { |
RSA_PKCS1_PADDING)) < 0) { |
| 4594 |
//error("RSA_public_decrypt failed: %s", |
//error("RSA_public_decrypt failed: %s", |
| 4595 |
// ERR_error_string(ERR_get_error(), NULL)); |
// ERR_error_string(ERR_get_error(), NULL)); |
| 4596 |
goto done; |
goto done; |
| 4614 |
return ret; |
return ret; |
| 4615 |
} |
} |
| 4616 |
|
|
| 4617 |
static int ssh_rsa_verify(RSA *key, u_char *signature, u_int signaturelen, |
static int ssh_rsa_verify(RSA *key, |
| 4618 |
u_char *data, u_int datalen) |
u_char *signature, u_int signaturelen, |
| 4619 |
|
u_char *data, u_int datalen) |
| 4620 |
{ |
{ |
| 4621 |
const EVP_MD *evp_md; |
const EVP_MD *evp_md; |
| 4622 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 4690 |
return ret; |
return ret; |
| 4691 |
} |
} |
| 4692 |
|
|
| 4693 |
static int key_verify( |
static int key_verify(RSA *rsa_key, DSA *dsa_key, |
| 4694 |
RSA *rsa_key, |
unsigned char *signature, unsigned int signaturelen, |
| 4695 |
DSA *dsa_key, |
unsigned char *data, unsigned int datalen) |
|
unsigned char *signature, unsigned int signaturelen, |
|
|
unsigned char *data, unsigned int datalen) |
|
| 4696 |
{ |
{ |
| 4697 |
int ret = 0; |
int ret = 0; |
| 4698 |
|
|
| 4750 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 4751 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 4752 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 4753 |
dsa->q == NULL || |
dsa->q == NULL || |
| 4754 |
dsa->g == NULL || |
dsa->g == NULL || |
| 4755 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 4756 |
DSA_free(dsa); |
DSA_free(dsa); |
| 4757 |
goto error; |
goto error; |
| 4758 |
} |
} |
| 5028 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5029 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5030 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5031 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5032 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5033 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5034 |
goto error; |
goto error; |
| 5035 |
} |
} |
| 5036 |
|
|
| 5145 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5146 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5147 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5148 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5149 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5150 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5151 |
emsg = "Out of memory4 @ handle_SSH2_dh_kex_reply()"; |
emsg = "Out of memory4 @ handle_SSH2_dh_kex_reply()"; |
| 5152 |
goto error; |
goto error; |
| 5153 |
} |
} |
| 5163 |
} else { |
} else { |
| 5164 |
// unknown key |
// unknown key |
| 5165 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5166 |
"Unknown key type(%s) @ handle_SSH2_dh_kex_reply()", key); |
"Unknown key type(%s) @ handle_SSH2_dh_kex_reply()", key); |
| 5167 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5168 |
goto error; |
goto error; |
| 5169 |
|
|
| 5172 |
// known_hosts対応 (2006.3.20 yutaka) |
// known_hosts対応 (2006.3.20 yutaka) |
| 5173 |
if (hostkey.type != pvar->hostkey_type) { // ホストキーの種別比較 |
if (hostkey.type != pvar->hostkey_type) { // ホストキーの種別比較 |
| 5174 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5175 |
"type mismatch for decoded server_host_key_blob @ %s", __FUNCTION__); |
"type mismatch for decoded server_host_key_blob @ %s", __FUNCTION__); |
| 5176 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5177 |
goto error; |
goto error; |
| 5178 |
} |
} |
| 5216 |
//debug_print(40, dh_buf, share_len); |
//debug_print(40, dh_buf, share_len); |
| 5217 |
|
|
| 5218 |
// ハッシュの計算 |
// ハッシュの計算 |
| 5219 |
/* calc and verify H */ |
/* calc and verify H */ |
| 5220 |
hash = kex_dh_hash( |
hash = kex_dh_hash(pvar->client_version_string, |
| 5221 |
pvar->client_version_string, |
pvar->server_version_string, |
| 5222 |
pvar->server_version_string, |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 5223 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5224 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
server_host_key_blob, bloblen, |
| 5225 |
server_host_key_blob, bloblen, |
pvar->kexdh->pub_key, |
| 5226 |
pvar->kexdh->pub_key, |
dh_server_pub, |
| 5227 |
dh_server_pub, |
share_key); |
|
share_key |
|
|
); |
|
| 5228 |
//debug_print(30, hash, 20); |
//debug_print(30, hash, 20); |
| 5229 |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
| 5230 |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
| 5245 |
|
|
| 5246 |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, 20)) != 1) { |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, 20)) != 1) { |
| 5247 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5248 |
"key verify error(%d) @ handle_SSH2_dh_kex_reply()", ret); |
"key verify error(%d) @ handle_SSH2_dh_kex_reply()", ret); |
| 5249 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5250 |
save_memdump(LOGDUMP); |
save_memdump(LOGDUMP); |
| 5251 |
goto error; |
goto error; |
| 5320 |
|
|
| 5321 |
|
|
| 5322 |
// SHA-1(160bit)を求める |
// SHA-1(160bit)を求める |
| 5323 |
static unsigned char *kex_dh_gex_hash( |
static unsigned char *kex_dh_gex_hash(char *client_version_string, |
| 5324 |
char *client_version_string, |
char *server_version_string, |
| 5325 |
char *server_version_string, |
char *ckexinit, int ckexinitlen, |
| 5326 |
char *ckexinit, int ckexinitlen, |
char *skexinit, int skexinitlen, |
| 5327 |
char *skexinit, int skexinitlen, |
u_char *serverhostkeyblob, int sbloblen, |
| 5328 |
u_char *serverhostkeyblob, int sbloblen, |
int kexgex_min, |
| 5329 |
int kexgex_min, |
int kexgex_bits, |
| 5330 |
int kexgex_bits, |
int kexgex_max, |
| 5331 |
int kexgex_max, |
BIGNUM *kexgex_p, |
| 5332 |
BIGNUM *kexgex_p, |
BIGNUM *kexgex_g, |
| 5333 |
BIGNUM *kexgex_g, |
BIGNUM *client_dh_pub, |
| 5334 |
BIGNUM *client_dh_pub, |
BIGNUM *server_dh_pub, |
| 5335 |
BIGNUM *server_dh_pub, |
BIGNUM *shared_secret) |
|
BIGNUM *shared_secret) |
|
| 5336 |
{ |
{ |
| 5337 |
buffer_t *b; |
buffer_t *b; |
| 5338 |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
| 5472 |
dsa->g = BN_new(); |
dsa->g = BN_new(); |
| 5473 |
dsa->pub_key = BN_new(); |
dsa->pub_key = BN_new(); |
| 5474 |
if (dsa->p == NULL || |
if (dsa->p == NULL || |
| 5475 |
dsa->q == NULL || |
dsa->q == NULL || |
| 5476 |
dsa->g == NULL || |
dsa->g == NULL || |
| 5477 |
dsa->pub_key == NULL) { |
dsa->pub_key == NULL) { |
| 5478 |
emsg = "Out of memory4 @ handle_SSH2_dh_kex_reply()"; |
emsg = "Out of memory4 @ handle_SSH2_dh_kex_reply()"; |
| 5479 |
goto error; |
goto error; |
| 5480 |
} |
} |
| 5490 |
} else { |
} else { |
| 5491 |
// unknown key |
// unknown key |
| 5492 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5493 |
"Unknown key type(%s) @ handle_SSH2_dh_kex_reply()", key); |
"Unknown key type(%s) @ handle_SSH2_dh_kex_reply()", key); |
| 5494 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5495 |
goto error; |
goto error; |
| 5496 |
|
|
| 5499 |
// known_hosts対応 (2006.3.20 yutaka) |
// known_hosts対応 (2006.3.20 yutaka) |
| 5500 |
if (hostkey.type != pvar->hostkey_type) { // ホストキーの種別比較 |
if (hostkey.type != pvar->hostkey_type) { // ホストキーの種別比較 |
| 5501 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5502 |
"type mismatch for decoded server_host_key_blob @ %s", __FUNCTION__); |
"type mismatch for decoded server_host_key_blob @ %s", __FUNCTION__); |
| 5503 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5504 |
goto error; |
goto error; |
| 5505 |
} |
} |
| 5544 |
//debug_print(40, dh_buf, share_len); |
//debug_print(40, dh_buf, share_len); |
| 5545 |
|
|
| 5546 |
// ハッシュの計算 |
// ハッシュの計算 |
| 5547 |
/* calc and verify H */ |
/* calc and verify H */ |
| 5548 |
hash = kex_dh_gex_hash( |
hash = kex_dh_gex_hash( |
| 5549 |
pvar->client_version_string, |
pvar->client_version_string, |
| 5550 |
pvar->server_version_string, |
pvar->server_version_string, |
| 5551 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 5552 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5553 |
server_host_key_blob, bloblen, |
server_host_key_blob, bloblen, |
| 5554 |
/////// KEXGEX |
/////// KEXGEX |
| 5555 |
pvar->kexgex_min, |
pvar->kexgex_min, |
| 5556 |
pvar->kexgex_bits, |
pvar->kexgex_bits, |
| 5557 |
pvar->kexgex_max, |
pvar->kexgex_max, |
| 5558 |
pvar->kexdh->p, |
pvar->kexdh->p, |
| 5559 |
pvar->kexdh->g, |
pvar->kexdh->g, |
| 5560 |
pvar->kexdh->pub_key, |
pvar->kexdh->pub_key, |
| 5561 |
/////// KEXGEX |
/////// KEXGEX |
| 5562 |
dh_server_pub, |
dh_server_pub, |
| 5563 |
share_key |
share_key); |
|
); |
|
| 5564 |
|
|
| 5565 |
|
|
| 5566 |
{ |
{ |
| 5593 |
|
|
| 5594 |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, 20)) != 1) { |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, 20)) != 1) { |
| 5595 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5596 |
"key verify error(%d) @ SSH2_DH_GEX\r\n%s", ret, SENDTOME); |
"key verify error(%d) @ SSH2_DH_GEX\r\n%s", ret, SENDTOME); |
| 5597 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5598 |
save_memdump(LOGDUMP); |
save_memdump(LOGDUMP); |
| 5599 |
goto error; |
goto error; |
| 6155 |
{ |
{ |
| 6156 |
char buf[128]; |
char buf[128]; |
| 6157 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 6158 |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
| 6159 |
pvar->auth_state.cur_cred.method); |
pvar->auth_state.cur_cred.method); |
| 6160 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 6161 |
} |
} |
| 6162 |
|
|
| 6279 |
c = ssh2_channel_new(CHAN_SES_PACKET_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_SHELL, -1); |
c = ssh2_channel_new(CHAN_SES_PACKET_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_SHELL, -1); |
| 6280 |
if (c == NULL) { |
if (c == NULL) { |
| 6281 |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
| 6282 |
"Could not open new channel. TTSSH is already opening too many channels."); |
"Could not open new channel. TTSSH is already opening too many channels."); |
| 6283 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 6284 |
return FALSE; |
return FALSE; |
| 6285 |
} |
} |
| 6380 |
if (pvar->ssh2_autologin == 1) { |
if (pvar->ssh2_autologin == 1) { |
| 6381 |
// SSH2自動ログインが有効の場合は、リトライは行わない。(2004.12.4 yutaka) |
// SSH2自動ログインが有効の場合は、リトライは行わない。(2004.12.4 yutaka) |
| 6382 |
UTIL_get_lang_msg("MSG_SSH_AUTH_FAILURE_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_AUTH_FAILURE_ERROR", pvar, |
| 6383 |
"SSH2 autologin error: user authentication failed"); |
"SSH2 autologin error: user authentication failed"); |
| 6384 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 6385 |
return TRUE; |
return TRUE; |
| 6386 |
} |
} |
| 6480 |
|
|
| 6481 |
// keyboard-interactive method (2005.3.12 yutaka) |
// keyboard-interactive method (2005.3.12 yutaka) |
| 6482 |
if (pvar->keyboard_interactive_password_input == 0 && |
if (pvar->keyboard_interactive_password_input == 0 && |
| 6483 |
pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
| 6484 |
AUTH_set_TIS_mode(pvar, prompt, slen); |
AUTH_set_TIS_mode(pvar, prompt, slen); |
| 6485 |
AUTH_advance_to_next_cred(pvar); |
AUTH_advance_to_next_cred(pvar); |
| 6486 |
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
| 6668 |
cstring = buffer_get_string(&data, NULL); |
cstring = buffer_get_string(&data, NULL); |
| 6669 |
|
|
| 6670 |
UTIL_get_lang_msg("MSG_SSH_CHANNEL_OPEN_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_CHANNEL_OPEN_ERROR", pvar, |
| 6671 |
"SSH2_MSG_CHANNEL_OPEN_FAILURE was received.\r\nchannel [%d]: reason: %s(%d) message: %s"); |
"SSH2_MSG_CHANNEL_OPEN_FAILURE was received.\r\nchannel [%d]: reason: %s(%d) message: %s"); |
| 6672 |
_snprintf_s(tmpbuf, sizeof(tmpbuf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(tmpbuf, sizeof(tmpbuf), _TRUNCATE, pvar->ts->UIMsg, |
| 6673 |
id, rmsg, reason, cstring); |
id, rmsg, reason, cstring); |
| 6674 |
notify_nonfatal_error(pvar, tmpbuf); |
notify_nonfatal_error(pvar, tmpbuf); |
| 6675 |
|
|
| 6676 |
free(cstring); |
free(cstring); |
| 6712 |
{ |
{ |
| 6713 |
char buf[128]; |
char buf[128]; |
| 6714 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 6715 |
"SSH2_MSG_CHANNEL_SUCCESS is received(nego_status %d).", |
"SSH2_MSG_CHANNEL_SUCCESS is received(nego_status %d).", |
| 6716 |
pvar->session_nego_status); |
pvar->session_nego_status); |
| 6717 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 6718 |
} |
} |
| 6719 |
|
|
| 7019 |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
| 7020 |
FWD_free_channel(pvar, chan_num); |
FWD_free_channel(pvar, chan_num); |
| 7021 |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
| 7022 |
"Could not open new channel. TTSSH is already opening too many channels."); |
"Could not open new channel. TTSSH is already opening too many channels."); |
| 7023 |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 7024 |
return FALSE; |
return FALSE; |
| 7025 |
} |
} |
| 7048 |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
| 7049 |
FWD_free_channel(pvar, chan_num); |
FWD_free_channel(pvar, chan_num); |
| 7050 |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
| 7051 |
"Could not open new channel. TTSSH is already opening too many channels."); |
"Could not open new channel. TTSSH is already opening too many channels."); |
| 7052 |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 7053 |
return FALSE; |
return FALSE; |
| 7054 |
} |
} |
| 7127 |
|
|
| 7128 |
|
|
| 7129 |
static BOOL handle_SSH2_channel_request(PTInstVar pvar) |
static BOOL handle_SSH2_channel_request(PTInstVar pvar) |
| 7130 |
{ |
{ |
| 7131 |
int len; |
int len; |
| 7132 |
char *data; |
char *data; |
| 7133 |
int id; |
int id; |