| 78 |
// channel data structure |
// channel data structure |
| 79 |
#define CHANNEL_MAX 100 |
#define CHANNEL_MAX 100 |
| 80 |
|
|
| 81 |
|
// |
| 82 |
|
// msg が NULL では無い事の保証。NULL の場合は "(null)" を返す。 |
| 83 |
|
// |
| 84 |
|
#define NonNull(msg) ((msg)?(msg):"(null)") |
| 85 |
|
|
| 86 |
static struct global_confirm global_confirms; |
static struct global_confirm global_confirms; |
| 87 |
|
|
| 6337 |
|
|
| 6338 |
static BOOL handle_SSH2_service_accept(PTInstVar pvar) |
static BOOL handle_SSH2_service_accept(PTInstVar pvar) |
| 6339 |
{ |
{ |
| 6340 |
char *data, *s; |
char *data, *svc; |
| 6341 |
|
|
| 6342 |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
| 6343 |
data = pvar->ssh_state.payload; |
data = pvar->ssh_state.payload; |
| 6344 |
|
|
| 6345 |
s = buffer_get_string(&data, NULL); |
if ((svc = buffer_get_string(&data, NULL)) == NULL) { |
| 6346 |
logprintf(LOG_LEVEL_VERBOSE, "SSH2_MSG_SERVICE_ACCEPT was received. service name=%s", s); |
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL."); |
| 6347 |
|
} |
| 6348 |
|
logprintf(LOG_LEVEL_VERBOSE, "SSH2_MSG_SERVICE_ACCEPT was received. service-name=%s", NonNull(svc)); |
| 6349 |
|
free(svc); |
| 6350 |
|
|
| 6351 |
SSH2_dispatch_init(5); |
SSH2_dispatch_init(5); |
| 6352 |
SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.5 yutaka) |
SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX: Tru64 UNIX workaround (2005.3.5 yutaka) |
| 6944 |
inst = buffer_get_string(&data, NULL); |
inst = buffer_get_string(&data, NULL); |
| 6945 |
lang = buffer_get_string(&data, NULL); |
lang = buffer_get_string(&data, NULL); |
| 6946 |
lprompt[0] = 0; |
lprompt[0] = 0; |
| 6947 |
if (strlen(inst) > 0) { |
if (inst == NULL) { |
| 6948 |
|
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL. (inst)"); |
| 6949 |
|
} |
| 6950 |
|
else if (strlen(inst) > 0) { |
| 6951 |
strncat_s(lprompt, sizeof(lprompt), inst, _TRUNCATE); |
strncat_s(lprompt, sizeof(lprompt), inst, _TRUNCATE); |
| 6952 |
strncat_s(lprompt, sizeof(lprompt), "\r\n", _TRUNCATE); |
strncat_s(lprompt, sizeof(lprompt), "\r\n", _TRUNCATE); |
| 6953 |
} |
} |
| 6954 |
if (strlen(lang) > 0) { |
if (lang == NULL) { |
| 6955 |
|
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL. (lang)"); |
| 6956 |
|
} |
| 6957 |
|
else if (strlen(lang) > 0) { |
| 6958 |
strncat_s(lprompt, sizeof(lprompt), lang, _TRUNCATE); |
strncat_s(lprompt, sizeof(lprompt), lang, _TRUNCATE); |
| 6959 |
strncat_s(lprompt, sizeof(lprompt), "\r\n", _TRUNCATE); |
strncat_s(lprompt, sizeof(lprompt), "\r\n", _TRUNCATE); |
| 6960 |
} |
} |
| 6961 |
|
|
| 6962 |
|
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": user=%s, inst=%s, lang=%s", |
| 6963 |
|
NonNull(name), NonNull(inst), NonNull(lang)); |
| 6964 |
|
|
| 6965 |
free(name); |
free(name); |
| 6966 |
free(inst); |
free(inst); |
| 6967 |
free(lang); |
free(lang); |
| 7273 |
|
|
| 7274 |
info = buffer_get_string(&data, NULL); |
info = buffer_get_string(&data, NULL); |
| 7275 |
lang = buffer_get_string(&data, NULL); |
lang = buffer_get_string(&data, NULL); |
| 7276 |
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": info %s lang %s\n", info, lang); |
if (info == NULL || lang == NULL) { |
| 7277 |
|
logprintf(LOG_LEVEL_ERROR, |
| 7278 |
|
__FUNCTION__ ": buffer_get_string returns NULL. info=%s, lang=%s", |
| 7279 |
|
NonNull(info), NonNull(lang)); |
| 7280 |
|
} |
| 7281 |
|
else { |
| 7282 |
|
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": info=%s, lang=%s\n", info, lang); |
| 7283 |
|
} |
| 7284 |
free(info); |
free(info); |
| 7285 |
free(lang); |
free(lang); |
| 7286 |
|
|
| 7611 |
|
|
| 7612 |
cstring = buffer_get_string(&data, NULL); |
cstring = buffer_get_string(&data, NULL); |
| 7613 |
|
|
| 7614 |
|
if (cstring == NULL) { |
| 7615 |
|
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL"); |
| 7616 |
|
} |
| 7617 |
UTIL_get_lang_msg("MSG_SSH_CHANNEL_OPEN_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_CHANNEL_OPEN_ERROR", pvar, |
| 7618 |
"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"); |
| 7619 |
_snprintf_s(tmpbuf, sizeof(tmpbuf), _TRUNCATE, pvar->ts->UIMsg, |
_snprintf_s(tmpbuf, sizeof(tmpbuf), _TRUNCATE, pvar->ts->UIMsg, |
| 7620 |
id, rmsg, reason, cstring); |
id, rmsg, reason, NonNull(cstring)); |
| 7621 |
notify_nonfatal_error(pvar, tmpbuf); |
notify_nonfatal_error(pvar, tmpbuf); |
| 7622 |
|
|
| 7623 |
free(cstring); |
free(cstring); |
| 7668 |
data++; |
data++; |
| 7669 |
len--; |
len--; |
| 7670 |
|
|
| 7671 |
// OpenSSH 6.8では、サーバのホスト鍵が更新されると、下記の通知が来る。 |
if (rtype == NULL) { |
| 7672 |
if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) { |
// rtype が NULL で無い事の保証 |
| 7673 |
|
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL."); |
| 7674 |
|
} |
| 7675 |
|
else if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) { |
| 7676 |
|
// OpenSSH 6.8では、サーバのホスト鍵が更新されると、この通知が来る。 |
| 7677 |
// OpenSSH 6.8の実装では、常に成功で返すようになっているため、 |
// OpenSSH 6.8の実装では、常に成功で返すようになっているため、 |
| 7678 |
// それに合わせて Tera Term でも成功と返すことにする。 |
// それに合わせて Tera Term でも成功と返すことにする。 |
| 7679 |
success = update_client_input_hostkeys(pvar, data, len); |
success = update_client_input_hostkeys(pvar, data, len); |
| 8732 |
buffer_t *msg; |
buffer_t *msg; |
| 8733 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 8734 |
|
|
| 8735 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_CHANNEL_OPEN was received."); |
logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_CHANNEL_OPEN was received."); |
| 8736 |
|
|
| 8737 |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
| 8738 |
data = pvar->ssh_state.payload; |
data = pvar->ssh_state.payload; |
| 8750 |
remote_maxpacket = get_uint32_MSBfirst(data); |
remote_maxpacket = get_uint32_MSBfirst(data); |
| 8751 |
data += 4; |
data += 4; |
| 8752 |
|
|
| 8753 |
|
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ |
| 8754 |
|
": type=%s, channel=%d, init_winsize=%d, max_packetsize:%d", |
| 8755 |
|
NonNull(ctype), remote_id, remote_window, remote_maxpacket); |
| 8756 |
|
|
| 8757 |
// check Channel Type(string) |
// check Channel Type(string) |
| 8758 |
if (strcmp(ctype, "forwarded-tcpip") == 0) { // port-forwarding(remote to local) |
if (ctype == NULL) { |
| 8759 |
|
// ctype が NULL で無い事の保証の為、先にチェックする |
| 8760 |
|
logputs(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL. (ctype)"); |
| 8761 |
|
} |
| 8762 |
|
else if (strcmp(ctype, "forwarded-tcpip") == 0) { // port-forwarding(remote to local) |
| 8763 |
char *listen_addr, *orig_addr; |
char *listen_addr, *orig_addr; |
| 8764 |
int listen_port, orig_port; |
int listen_port, orig_port; |
| 8765 |
|
|
| 8771 |
orig_port = get_uint32_MSBfirst(data); // 32776 |
orig_port = get_uint32_MSBfirst(data); // 32776 |
| 8772 |
data += 4; |
data += 4; |
| 8773 |
|
|
| 8774 |
// searching request entry by listen_port & create_local_channel |
if (listen_addr && orig_addr) { |
| 8775 |
FWD_open(pvar, remote_id, listen_addr, listen_port, orig_addr, orig_port, |
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ |
| 8776 |
&chan_num); |
": %s: listen_addr=%s, listen_port=%d, orig_addr=%s, orig_port=%d", |
| 8777 |
|
ctype, listen_addr, listen_port, orig_addr, orig_port); |
| 8778 |
|
// searching request entry by listen_port & create_local_channel |
| 8779 |
|
FWD_open(pvar, remote_id, listen_addr, listen_port, orig_addr, orig_port, &chan_num); |
| 8780 |
|
|
| 8781 |
|
// channelをアロケートし、必要な情報(remote window size)をここで取っておく。 |
| 8782 |
|
// changed window size from 128KB to 32KB. (2006.3.6 yutaka) |
| 8783 |
|
// changed window size from 32KB to 128KB. (2007.10.29 maya) |
| 8784 |
|
c = ssh2_channel_new(CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_PORTFWD, chan_num); |
| 8785 |
|
if (c == NULL) { |
| 8786 |
|
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
| 8787 |
|
FWD_free_channel(pvar, chan_num); |
| 8788 |
|
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
| 8789 |
|
"Could not open new channel. TTSSH is already opening too many channels."); |
| 8790 |
|
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
| 8791 |
|
return FALSE; |
| 8792 |
|
} |
| 8793 |
|
c->remote_id = remote_id; |
| 8794 |
|
c->remote_window = remote_window; |
| 8795 |
|
c->remote_maxpacket = remote_maxpacket; |
| 8796 |
|
} |
| 8797 |
|
else { |
| 8798 |
|
logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": %s: buffer_get_string returns NULL. " |
| 8799 |
|
"linsten_addr=%s, orig_addr=%s", |
| 8800 |
|
ctype, NonNull(listen_addr), NonNull(orig_addr)); |
| 8801 |
|
} |
| 8802 |
free(listen_addr); |
free(listen_addr); |
| 8803 |
free(orig_addr); |
free(orig_addr); |
| 8804 |
|
|
|
// channelをアロケートし、必要な情報(remote window size)をここで取っておく。 |
|
|
// changed window size from 128KB to 32KB. (2006.3.6 yutaka) |
|
|
// changed window size from 32KB to 128KB. (2007.10.29 maya) |
|
|
c = ssh2_channel_new(CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_PORTFWD, chan_num); |
|
|
if (c == NULL) { |
|
|
// 転送チャネル内にあるソケットの解放漏れを修正 (2007.7.26 maya) |
|
|
FWD_free_channel(pvar, chan_num); |
|
|
UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar, |
|
|
"Could not open new channel. TTSSH is already opening too many channels."); |
|
|
notify_nonfatal_error(pvar, pvar->ts->UIMsg); |
|
|
return FALSE; |
|
|
} |
|
|
c->remote_id = remote_id; |
|
|
c->remote_window = remote_window; |
|
|
c->remote_maxpacket = remote_maxpacket; |
|
|
|
|
| 8805 |
} else if (strcmp(ctype, "x11") == 0) { // port-forwarding(X11) |
} else if (strcmp(ctype, "x11") == 0) { // port-forwarding(X11) |
| 8806 |
// X applicationをターミナル上で実行すると、SSH2_MSG_CHANNEL_OPEN が送られてくる。 |
// X applicationをターミナル上で実行すると、SSH2_MSG_CHANNEL_OPEN が送られてくる。 |
| 8807 |
char *orig_str; |
char *orig_str; |
| 8810 |
orig_str = buffer_get_string(&data, NULL); // "127.0.0.1" |
orig_str = buffer_get_string(&data, NULL); // "127.0.0.1" |
| 8811 |
orig_port = get_uint32_MSBfirst(data); |
orig_port = get_uint32_MSBfirst(data); |
| 8812 |
data += 4; |
data += 4; |
| 8813 |
|
|
| 8814 |
|
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": %s: orig_addr=%s, orig_port=%d", |
| 8815 |
|
ctype, orig_str, orig_port); |
| 8816 |
|
|
| 8817 |
free(orig_str); |
free(orig_str); |
| 8818 |
|
|
| 8819 |
// X server(port 6000)へ接続する。接続に失敗するとTera Term自身が切断される。 |
// X server(port 6000)へ接続する。接続に失敗するとTera Term自身が切断される。 |
| 8868 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 8869 |
buffer_free(msg); |
buffer_free(msg); |
| 8870 |
|
|
| 8871 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_CHANNEL_OPEN_FAILURE was sent at handle_SSH2_channel_open()."); |
logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_CHANNEL_OPEN_FAILURE was sent."); |
| 8872 |
} |
} |
| 8873 |
|
|
| 8874 |
} else { |
} else { |
| 8875 |
// unknown type(unsupported) |
// unknown type(unsupported) |
|
|
|
| 8876 |
} |
} |
| 8877 |
|
|
| 8878 |
free(ctype); |
free(ctype); |
| 8950 |
int success = 0; |
int success = 0; |
| 8951 |
Channel_t *c; |
Channel_t *c; |
| 8952 |
|
|
| 8953 |
|
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_CHANNEL_REQUEST was received."); |
| 8954 |
|
|
| 8955 |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
| 8956 |
data = pvar->ssh_state.payload; |
data = pvar->ssh_state.payload; |
| 8957 |
// パケットサイズ - (パディングサイズ+1);真のパケットサイズ |
// パケットサイズ - (パディングサイズ+1);真のパケットサイズ |
| 8971 |
want_reply = data[0]; |
want_reply = data[0]; |
| 8972 |
data += 1; |
data += 1; |
| 8973 |
|
|
| 8974 |
logprintf(LOG_LEVEL_VERBOSE, "SSH2_MSG_CHANNEL_REQUEST was received. " |
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ |
| 8975 |
"local:%d remote:%d request:%s want_reply:%d", |
": local=%d, remote=%d, request=%s, want_reply=%d", |
| 8976 |
c->self_id, c->remote_id, request?request:"(null)", want_reply); |
c->self_id, c->remote_id, NonNull(request), want_reply); |
| 8977 |
|
|
| 8978 |
if (request) { |
if (request == NULL) { |
| 8979 |
if (strcmp(request, "exit-status") == 0) { |
// request が NULL で無い事の保証 |
| 8980 |
// 終了コードが含まれているならば |
logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": buffer_get_string returns NULL. (request)"); |
| 8981 |
int estat = get_uint32_MSBfirst(data); |
} |
| 8982 |
success = 1; |
else if (strcmp(request, "exit-status") == 0) { |
| 8983 |
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": exit-status=%d", estat); |
// 終了コードが含まれているならば |
| 8984 |
} |
int estat = get_uint32_MSBfirst(data); |
| 8985 |
else if (strcmp(request, "keepalive@openssh.com") == 0) { |
success = 1; |
| 8986 |
// OpenSSH client では success = 1 にしていないけれど、 |
logprintf(LOG_LEVEL_VERBOSE, __FUNCTION__ ": exit-status=%d", estat); |
| 8987 |
// server 側は SUCCESS/FAILURE どちらでも OK なので |
} |
| 8988 |
// とりあえず SUCCESS を返す。 |
else if (strcmp(request, "keepalive@openssh.com") == 0) { |
| 8989 |
success = 1; |
// OpenSSH client では success = 1 にしていないけれど、 |
| 8990 |
} |
// server 側は SUCCESS/FAILURE どちらでも OK なので |
| 8991 |
|
// とりあえず SUCCESS を返す。 |
| 8992 |
free(request); |
success = 1; |
| 8993 |
} |
} |
| 8994 |
|
|
| 8995 |
|
free(request); |
| 8996 |
|
|
| 8997 |
if (want_reply) { |
if (want_reply) { |
| 8998 |
buffer_t *msg; |
buffer_t *msg; |
| 8999 |
unsigned char *outmsg; |
unsigned char *outmsg; |