| 179 |
free(p); |
free(p); |
| 180 |
return; |
return; |
| 181 |
} |
} |
| 182 |
buffer_put_string(p->msg, buf, buflen); |
buffer_put_raw(p->msg, buf, buflen); |
| 183 |
p->next = NULL; |
p->next = NULL; |
| 184 |
|
|
| 185 |
if (c->bufchain == NULL) { |
if (c->bufchain == NULL) { |
| 205 |
if (size >= c->remote_window) |
if (size >= c->remote_window) |
| 206 |
break; |
break; |
| 207 |
|
|
| 208 |
SSH_channel_send(pvar, c->local_num, 0, buffer_ptr(ch->msg), size); |
SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size); |
| 209 |
|
|
| 210 |
c->bufchain = ch->next; |
c->bufchain = ch->next; |
| 211 |
|
|
| 311 |
// |
// |
| 312 |
// (2005.3.7 yutaka) |
// (2005.3.7 yutaka) |
| 313 |
// |
// |
| 314 |
#define MEMTAG_MAX 100 |
#define MEMTAG_MAX 300 |
| 315 |
#define LOGDUMP "ssh2dump.log" |
#define LOGDUMP "ssh2dump.log" |
| 316 |
#define SENDTOME "Please send '"LOGDUMP"' file to TeraTerm developer team." |
#define SENDTOME "Please send '"LOGDUMP"' file to TeraTerm developer team." |
| 317 |
|
|
| 827 |
|
|
| 828 |
static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len) |
static BOOL send_packet_blocking(PTInstVar pvar, char FAR * data, int len) |
| 829 |
{ |
{ |
| 830 |
#if 0 |
// パケット送信後にバッファを使いまわすため、ブロッキングで送信してしまう必要がある。 |
| 831 |
|
// ノンブロッキングで送信してWSAEWOULDBLOCKが返ってきた場合、そのバッファは送信完了する |
| 832 |
|
// まで保持しておかなくてはならない。(2007.10.30 yutaka) |
| 833 |
u_long do_block = 0; |
u_long do_block = 0; |
| 834 |
|
|
| 835 |
|
#if 0 |
| 836 |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 837 |
0, 0) == SOCKET_ERROR |
0, 0) == SOCKET_ERROR |
| 838 |
|| ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR |
|| ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR |
| 841 |
pvar->notification_msg, |
pvar->notification_msg, |
| 842 |
pvar->notification_events) == |
pvar->notification_events) == |
| 843 |
SOCKET_ERROR) { |
SOCKET_ERROR) { |
|
#else |
|
|
// ソケットをノンブロッキングのままでパケット送信を行う。(2007.9.26 yutaka) |
|
|
if (retry_send_packet(pvar, data, len)) { |
|
|
#endif |
|
| 844 |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
| 845 |
"A communications error occurred while sending an SSH packet.\n" |
"A communications error occurred while sending an SSH packet.\n" |
| 846 |
"The connection will close."); |
"The connection will close."); |
| 849 |
} else { |
} else { |
| 850 |
return TRUE; |
return TRUE; |
| 851 |
} |
} |
| 852 |
|
#else |
| 853 |
|
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 854 |
|
0, 0) == SOCKET_ERROR) { |
| 855 |
|
code = WSAGetLastError(); |
| 856 |
|
kind = "WSAAsyncSelect1"; |
| 857 |
|
goto error; |
| 858 |
|
} |
| 859 |
|
if (ioctlsocket(pvar->socket, FIONBIO, &do_block) == SOCKET_ERROR) { |
| 860 |
|
code = WSAGetLastError(); |
| 861 |
|
kind = "ioctlsocket"; |
| 862 |
|
goto error; |
| 863 |
|
} |
| 864 |
|
if (retry_send_packet(pvar, data, len) != 0) { |
| 865 |
|
code = WSAGetLastError(); |
| 866 |
|
kind = "retry_send_packet"; |
| 867 |
|
goto error; |
| 868 |
|
} |
| 869 |
|
if ((pvar->PWSAAsyncSelect) (pvar->socket, pvar->NotificationWindow, |
| 870 |
|
pvar->notification_msg, |
| 871 |
|
pvar->notification_events) == |
| 872 |
|
SOCKET_ERROR) { |
| 873 |
|
code = WSAGetLastError(); |
| 874 |
|
kind = "WSAAsyncSelect2"; |
| 875 |
|
goto error; |
| 876 |
|
} |
| 877 |
|
|
| 878 |
|
return TRUE; |
| 879 |
|
|
| 880 |
|
error: |
| 881 |
|
UTIL_get_lang_msg("MSG_SSH_SEND_PKT_ERROR", pvar, |
| 882 |
|
"A communications error occurred while sending an SSH packet.\n" |
| 883 |
|
"The connection will close. (%s:%d)"); |
| 884 |
|
_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, |
| 885 |
|
kind, code); |
| 886 |
|
notify_fatal_error(pvar, buf); |
| 887 |
|
return FALSE; |
| 888 |
|
#endif |
| 889 |
} |
} |
| 890 |
|
|
| 891 |
/* if skip_compress is true, then the data has already been compressed |
/* if skip_compress is true, then the data has already been compressed |
| 892 |
into outbuf + 12 */ |
into outbuf + 12 */ |
| 893 |
static void finish_send_packet_special(PTInstVar pvar, int skip_compress) |
static void finish_send_packet_special(PTInstVar pvar, int skip_compress) |
| 894 |
{ |
{ |
| 895 |
int len = pvar->ssh_state.outgoing_packet_len; |
unsigned int len = pvar->ssh_state.outgoing_packet_len; |
| 896 |
char FAR *data; |
unsigned char FAR *data; |
| 897 |
int data_length; |
unsigned int data_length; |
| 898 |
buffer_t *msg = NULL; // for SSH2 packet compression |
buffer_t *msg = NULL; // for SSH2 packet compression |
| 899 |
|
|
| 900 |
if (pvar->ssh_state.compressing) { |
if (pvar->ssh_state.compressing) { |
| 901 |
if (!skip_compress) { |
if (!skip_compress) { |
| 902 |
buf_ensure_size(&pvar->ssh_state.outbuf, |
buf_ensure_size(&pvar->ssh_state.outbuf, |
| 903 |
&pvar->ssh_state.outbuflen, |
&pvar->ssh_state.outbuflen, |
| 904 |
len + (len >> 6) + 50 + |
(int)(len + (len >> 6) + 50 + |
| 905 |
CRYPT_get_sender_MAC_size(pvar)); |
CRYPT_get_sender_MAC_size(pvar))); |
| 906 |
pvar->ssh_state.compress_stream.next_in = |
pvar->ssh_state.compress_stream.next_in = |
| 907 |
pvar->ssh_state.precompress_outbuf; |
pvar->ssh_state.precompress_outbuf; |
| 908 |
pvar->ssh_state.compress_stream.avail_in = len; |
pvar->ssh_state.compress_stream.avail_in = len; |
| 1015 |
data[4] = (unsigned char) padding; |
data[4] = (unsigned char) padding; |
| 1016 |
data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar); |
data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar); |
| 1017 |
#endif |
#endif |
| 1018 |
|
//if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0; |
| 1019 |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
| 1020 |
ret = CRYPT_build_sender_MAC(pvar, |
ret = CRYPT_build_sender_MAC(pvar, |
| 1021 |
pvar->ssh_state.sender_sequence_number, |
pvar->ssh_state.sender_sequence_number, |
| 2559 |
try_send_credentials(pvar); |
try_send_credentials(pvar); |
| 2560 |
} |
} |
| 2561 |
|
|
| 2562 |
void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, int buflen) |
void SSH_send(PTInstVar pvar, unsigned char const FAR * buf, unsigned int buflen) |
| 2563 |
{ |
{ |
| 2564 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 2565 |
if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) { |
if (get_handler(pvar, SSH_SMSG_STDOUT_DATA) != handle_data) { |
| 2633 |
if (c == NULL) |
if (c == NULL) |
| 2634 |
return; |
return; |
| 2635 |
|
|
| 2636 |
msg = buffer_init(); |
if (buflen > c->remote_window) { |
| 2637 |
if (msg == NULL) { |
buflen = c->remote_window; |
|
// TODO: error check |
|
|
return; |
|
| 2638 |
} |
} |
| 2639 |
buffer_put_int(msg, c->remote_id); |
if (buflen > 0) { |
| 2640 |
buffer_put_string(msg, (char *)buf, buflen); |
msg = buffer_init(); |
| 2641 |
|
if (msg == NULL) { |
| 2642 |
|
// TODO: error check |
| 2643 |
|
return; |
| 2644 |
|
} |
| 2645 |
|
buffer_put_int(msg, c->remote_id); |
| 2646 |
|
buffer_put_string(msg, (char *)buf, buflen); |
| 2647 |
|
|
| 2648 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 2649 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
| 2650 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 2651 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 2652 |
buffer_free(msg); |
buffer_free(msg); |
| 2653 |
|
|
| 2654 |
// remote window sizeの調整 |
// remote window sizeの調整 |
| 2655 |
if (len <= c->remote_window) { |
if (buflen <= c->remote_window) { |
| 2656 |
c->remote_window -= buflen; |
c->remote_window -= buflen; |
| 2657 |
} |
} |
| 2658 |
else { |
else { |
| 2659 |
c->remote_window = 0; |
c->remote_window = 0; |
| 2660 |
|
} |
| 2661 |
} |
} |
|
|
|
| 2662 |
} |
} |
| 2663 |
|
|
| 2664 |
} |
} |
| 2877 |
uint32 remote_channel_num, |
uint32 remote_channel_num, |
| 2878 |
unsigned char FAR * buf, int len) |
unsigned char FAR * buf, int len) |
| 2879 |
{ |
{ |
| 2880 |
int buflen = len; |
unsigned int buflen = len; |
| 2881 |
|
|
| 2882 |
if (SSHv1(pvar)) { |
if (SSHv1(pvar)) { |
| 2883 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2941 |
if (c == NULL) |
if (c == NULL) |
| 2942 |
return; |
return; |
| 2943 |
|
|
| 2944 |
#if 0 |
if ((unsigned int)buflen > c->remote_window) { |
| 2945 |
if (c->bufchain) { // chainに残っている場合はそのままつなぐ |
unsigned int offset = c->remote_window; |
| 2946 |
ssh2_channel_add_bufchain(c, buf, buflen); |
// 送れないデータはいったん保存しておく |
| 2947 |
return; |
ssh2_channel_add_bufchain(c, buf + offset, buflen - offset); |
| 2948 |
|
buflen = offset; |
| 2949 |
} |
} |
| 2950 |
#endif |
if (buflen > 0) { |
|
|
|
|
if ((unsigned int)buflen > c->remote_window) { |
|
|
unsigned int offset = c->remote_window; |
|
|
// 送れないデータはいったん保存しておく |
|
|
ssh2_channel_add_bufchain(c, buf + offset, buflen - offset); |
|
|
buflen = offset; |
|
|
} |
|
|
if (buflen > 0) { |
|
| 2951 |
msg = buffer_init(); |
msg = buffer_init(); |
| 2952 |
if (msg == NULL) { |
if (msg == NULL) { |
| 2953 |
// TODO: error check |
// TODO: error check |
| 2958 |
|
|
| 2959 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 2960 |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len); |
| 2961 |
|
//if (len + 12 >= pvar->ssh_state.outbuflen) *(int *)0 = 0; |
| 2962 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 2963 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 2964 |
buffer_free(msg); |
buffer_free(msg); |
| 2965 |
|
//debug_print(1, pvar->ssh_state.outbuf, 7 + 4 + 1 + 1 + len); |
| 2966 |
|
|
| 2967 |
// remote window sizeの調整 |
// remote window sizeの調整 |
| 2968 |
if (len <= c->remote_window) { |
if (buflen <= c->remote_window) { |
| 2969 |
c->remote_window -= buflen; |
c->remote_window -= buflen; |
| 2970 |
} |
} |
| 2971 |
else { |
else { |