| 7372 |
return TRUE; |
return TRUE; |
| 7373 |
} |
} |
| 7374 |
|
|
| 7375 |
|
/* |
| 7376 |
|
* SSH_MSG_CHANNEL_REQUEST 送信関数 |
| 7377 |
|
* type-specific data が string で 0 〜 2 の物に対応。 |
| 7378 |
|
* 使用しないメッセージは NULL にする。 |
| 7379 |
|
* type-specific data が他の形式には対応していないので、自前で送る事。 |
| 7380 |
|
*/ |
| 7381 |
|
static BOOL send_channel_request_gen(PTInstVar pvar, Channel_t *c, unsigned char *req, int want_reply, unsigned char *msg1, unsigned char *msg2) |
| 7382 |
|
{ |
| 7383 |
|
buffer_t *msg; |
| 7384 |
|
unsigned char *outmsg; |
| 7385 |
|
int len; |
| 7386 |
|
|
| 7387 |
|
msg = buffer_init(); |
| 7388 |
|
if (msg == NULL) { |
| 7389 |
|
return FALSE; |
| 7390 |
|
} |
| 7391 |
|
|
| 7392 |
|
buffer_put_int(msg, c->remote_id); |
| 7393 |
|
buffer_put_string(msg, req, strlen(req)); |
| 7394 |
|
|
| 7395 |
|
buffer_put_char(msg, want_reply); |
| 7396 |
|
|
| 7397 |
|
if (msg1) { |
| 7398 |
|
buffer_put_string(msg, msg1, strlen(msg1)); |
| 7399 |
|
} |
| 7400 |
|
if (msg2) { |
| 7401 |
|
buffer_put_string(msg, msg1, strlen(msg1)); |
| 7402 |
|
} |
| 7403 |
|
|
| 7404 |
|
len = buffer_len(msg); |
| 7405 |
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
| 7406 |
|
memcpy(outmsg, buffer_ptr(msg), len); |
| 7407 |
|
finish_send_packet(pvar); |
| 7408 |
|
buffer_free(msg); |
| 7409 |
|
|
| 7410 |
|
logprintf(pvar, LOG_LEVEL_VERBOSE, __FUNCTION__ ": sending SSH2_MSG_CHANNEL_REQUEST. " |
| 7411 |
|
"local: %d, remote: %d, request-type: %s, msg1=%s, msg2=%s", |
| 7412 |
|
c->self_id, c->remote_id, req, msg1 ? msg1 : "none", msg2 ? msg2 : "none"); |
| 7413 |
|
return TRUE; |
| 7414 |
|
} |
| 7415 |
|
|
| 7416 |
BOOL send_pty_request(PTInstVar pvar, Channel_t *c) |
BOOL send_pty_request(PTInstVar pvar, Channel_t *c) |
| 7417 |
{ |
{ |
| 7418 |
buffer_t *msg, *ttymsg; |
buffer_t *msg, *ttymsg; |
| 7500 |
} |
} |
| 7501 |
|
|
| 7502 |
static BOOL handle_SSH2_open_confirm(PTInstVar pvar) |
static BOOL handle_SSH2_open_confirm(PTInstVar pvar) |
| 7503 |
{ |
{ |
|
buffer_t *msg; |
|
|
char *s; |
|
|
unsigned char *outmsg; |
|
| 7504 |
int len; |
int len; |
| 7505 |
char *data; |
char *data; |
| 7506 |
int id, remote_id; |
int id, remote_id; |
| 7507 |
Channel_t *c; |
Channel_t *c; |
| 7508 |
|
char buff[MAX_PATH + 30]; |
| 7509 |
|
|
| 7510 |
#ifdef DONT_WANTCONFIRM |
#ifdef DONT_WANTCONFIRM |
| 7511 |
int wantconfirm = 0; // false |
int want_reply = 0; // false |
| 7512 |
#else |
#else |
| 7513 |
int wantconfirm = 1; // true |
int want_reply = 1; // true |
| 7514 |
#endif |
#endif |
| 7515 |
|
|
| 7516 |
notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN_CONFIRMATION was received.", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN_CONFIRMATION was received.", LOG_LEVEL_VERBOSE); |
| 7545 |
c->remote_maxpacket = get_uint32_MSBfirst(data); |
c->remote_maxpacket = get_uint32_MSBfirst(data); |
| 7546 |
data += 4; |
data += 4; |
| 7547 |
|
|
| 7548 |
if (c->type == TYPE_PORTFWD) { |
switch (c->type) { |
| 7549 |
|
case TYPE_PORTFWD: |
| 7550 |
// port-forwadingの"direct-tcpip"が成功。 |
// port-forwadingの"direct-tcpip"が成功。 |
| 7551 |
FWD_confirmed_open(pvar, c->local_num, -1); |
FWD_confirmed_open(pvar, c->local_num, -1); |
| 7552 |
return TRUE; |
break; |
|
} |
|
| 7553 |
|
|
| 7554 |
if (c->type == TYPE_SHELL) { |
case TYPE_SHELL: |
| 7555 |
// ポートフォワーディングの準備 (2005.2.26, 2005.6.21 yutaka) |
// ポートフォワーディングの準備 (2005.2.26, 2005.6.21 yutaka) |
| 7556 |
// シェルオープンしたあとに X11 の要求を出さなくてはならない。(2005.7.3 yutaka) |
// シェルオープンしたあとに X11 の要求を出さなくてはならない。(2005.7.3 yutaka) |
| 7557 |
FWD_prep_forwarding(pvar); |
FWD_prep_forwarding(pvar); |
| 7558 |
FWD_enter_interactive_mode(pvar); |
FWD_enter_interactive_mode(pvar); |
|
} |
|
|
|
|
|
//debug_print(100, data, len); |
|
| 7559 |
|
|
|
if (c->type == TYPE_SHELL) { |
|
| 7560 |
// エージェント転送 (2008.11.25 maya) |
// エージェント転送 (2008.11.25 maya) |
| 7561 |
if (pvar->session_settings.ForwardAgent) { |
if (pvar->session_settings.ForwardAgent) { |
| 7562 |
// pty-req より前にリクエストしないとエラーになる模様 |
// pty-req より前にリクエストしないとエラーになる模様 |
| 7563 |
|
return send_channel_request_gen(pvar, c, "auth-agent-req@openssh.com", 1, NULL, NULL); |
|
msg = buffer_init(); |
|
|
if (msg == NULL) { |
|
|
// TODO: error check |
|
|
return FALSE; |
|
|
} |
|
|
buffer_put_int(msg, c->remote_id); |
|
|
s = "auth-agent-req@openssh.com"; |
|
|
buffer_put_string(msg, s, strlen(s)); |
|
|
buffer_put_char(msg, 1); // want reply |
|
|
len = buffer_len(msg); |
|
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
|
|
memcpy(outmsg, buffer_ptr(msg), len); |
|
|
finish_send_packet(pvar); |
|
|
buffer_free(msg); |
|
|
|
|
|
notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_channel_success().", LOG_LEVEL_VERBOSE); |
|
|
return TRUE; |
|
| 7564 |
} |
} |
| 7565 |
else { |
else { |
| 7566 |
return send_pty_request(pvar, c); |
return send_pty_request(pvar, c); |
| 7567 |
} |
} |
| 7568 |
} |
break; |
|
|
|
|
msg = buffer_init(); |
|
|
if (msg == NULL) { |
|
|
// TODO: error check |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
buffer_put_int(msg, remote_id); |
|
|
if (c->type == TYPE_SCP) { |
|
|
s = "exec"; |
|
|
} else if (c->type == TYPE_SFTP || c->type == TYPE_SUBSYSTEM_GEN) { |
|
|
s = "subsystem"; |
|
|
} else { |
|
|
s = ""; // NOT REACHED |
|
|
} |
|
|
buffer_put_string(msg, s, strlen(s)); |
|
|
buffer_put_char(msg, wantconfirm); // wantconfirm (disableに変更 2005/3/28 yutaka) |
|
| 7569 |
|
|
| 7570 |
if (c->type == TYPE_SCP) { |
case TYPE_SCP: |
|
char sbuf[MAX_PATH + 30]; |
|
| 7571 |
if (c->scp.dir == TOREMOTE) { |
if (c->scp.dir == TOREMOTE) { |
| 7572 |
_snprintf_s(sbuf, sizeof(sbuf), _TRUNCATE, "scp -t %s", c->scp.remotefile); |
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "scp -t %s", c->scp.remotefile); |
| 7573 |
|
|
| 7574 |
} else { |
} else { |
| 7575 |
// ファイル名に空白を含まれていてもよいように、ファイル名を二重引用符で囲む。 |
// ファイル名に空白を含まれていてもよいように、ファイル名を二重引用符で囲む。 |
| 7576 |
// (2014.7.13 yutaka) |
// (2014.7.13 yutaka) |
| 7577 |
_snprintf_s(sbuf, sizeof(sbuf), _TRUNCATE, "scp -p -f \"%s\"", c->scp.remotefile); |
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "scp -p -f \"%s\"", c->scp.remotefile); |
|
|
|
| 7578 |
} |
} |
|
buffer_put_string(msg, sbuf, strlen(sbuf)); |
|
|
} |
|
|
else if (c->type == TYPE_SFTP) { |
|
|
char *sbuf = "sftp"; |
|
|
buffer_put_string(msg, sbuf, strlen(sbuf)); |
|
|
} |
|
|
else if (c->type == TYPE_SUBSYSTEM_GEN) { |
|
|
buffer_put_string(msg, pvar->subsystem_name, strlen(pvar->subsystem_name)); |
|
|
pvar->session_nego_status = 0; |
|
|
} |
|
|
|
|
|
len = buffer_len(msg); |
|
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
|
|
memcpy(outmsg, buffer_ptr(msg), len); |
|
|
finish_send_packet(pvar); |
|
|
buffer_free(msg); |
|
| 7579 |
|
|
| 7580 |
notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_open_confirm().", LOG_LEVEL_VERBOSE); |
if (!send_channel_request_gen(pvar, c, "exec", want_reply, buff, NULL)) { |
| 7581 |
|
return FALSE;; |
| 7582 |
|
} |
| 7583 |
|
|
|
if (c->type == TYPE_SCP) { |
|
| 7584 |
// SCPで remote-to-local の場合は、サーバからのファイル送信要求を出す。 |
// SCPで remote-to-local の場合は、サーバからのファイル送信要求を出す。 |
| 7585 |
// この時点では remote window size が"0"なので、すぐには送られないが、遅延送信処理で送られる。 |
// この時点では remote window size が"0"なので、すぐには送られないが、遅延送信処理で送られる。 |
| 7586 |
// (2007.12.27 yutaka) |
// (2007.12.27 yutaka) |
| 7588 |
char ch = '\0'; |
char ch = '\0'; |
| 7589 |
SSH2_send_channel_data(pvar, c, &ch, 1, 0); |
SSH2_send_channel_data(pvar, c, &ch, 1, 0); |
| 7590 |
} |
} |
| 7591 |
|
break; |
| 7592 |
|
|
| 7593 |
|
case TYPE_SFTP: |
| 7594 |
|
if (!send_channel_request_gen(pvar, c, "subsystem", want_reply, "sftp", NULL)) { |
| 7595 |
|
return FALSE;; |
| 7596 |
|
} |
| 7597 |
|
|
|
} else if (c->type == TYPE_SFTP) { |
|
| 7598 |
// SFTPセッションを開始するためのネゴシエーションを行う。 |
// SFTPセッションを開始するためのネゴシエーションを行う。 |
| 7599 |
// (2012.5.3 yutaka) |
// (2012.5.3 yutaka) |
| 7600 |
sftp_do_init(pvar, c); |
sftp_do_init(pvar, c); |
| 7601 |
|
break; |
| 7602 |
|
|
| 7603 |
} |
case TYPE_SUBSYSTEM_GEN: |
| 7604 |
|
if (!send_channel_request_gen(pvar, c, "subsystem", want_reply, pvar->subsystem_name, NULL)) { |
| 7605 |
|
return FALSE;; |
| 7606 |
|
} |
| 7607 |
|
pvar->session_nego_status = 0; |
| 7608 |
|
break; |
| 7609 |
|
|
| 7610 |
|
default: // NOT REACHED |
| 7611 |
|
logprintf(pvar, LOG_LEVEL_ERROR, __FUNCTION__ ": Invalid channel-type. (%d)", c->type); |
| 7612 |
|
return FALSE; |
| 7613 |
|
} |
| 7614 |
return TRUE; |
return TRUE; |
| 7615 |
} |
} |
| 7616 |
|
|
|
|
|
| 7617 |
// SSH2 port-forwarding においてセッションがオープンできない場合のサーバからのリプライ(失敗) |
// SSH2 port-forwarding においてセッションがオープンできない場合のサーバからのリプライ(失敗) |
| 7618 |
static BOOL handle_SSH2_open_failure(PTInstVar pvar) |
static BOOL handle_SSH2_open_failure(PTInstVar pvar) |
| 7619 |
{ |
{ |
| 7678 |
return TRUE; |
return TRUE; |
| 7679 |
} |
} |
| 7680 |
|
|
|
|
|
| 7681 |
// SSH2_MSG_GLOBAL_REQUEST for OpenSSH 6.8 |
// SSH2_MSG_GLOBAL_REQUEST for OpenSSH 6.8 |
| 7682 |
static BOOL handle_SSH2_client_global_request(PTInstVar pvar) |
static BOOL handle_SSH2_client_global_request(PTInstVar pvar) |
| 7683 |
{ |
{ |
| 7762 |
|
|
| 7763 |
static BOOL handle_SSH2_channel_success(PTInstVar pvar) |
static BOOL handle_SSH2_channel_success(PTInstVar pvar) |
| 7764 |
{ |
{ |
|
buffer_t *msg; |
|
|
char *s; |
|
|
unsigned char *outmsg; |
|
|
int len; |
|
| 7765 |
Channel_t *c; |
Channel_t *c; |
| 7766 |
#ifdef DONT_WANTCONFIRM |
#ifdef DONT_WANTCONFIRM |
| 7767 |
int wantconfirm = 0; // false |
int want_reply = 0; // false |
| 7768 |
#else |
#else |
| 7769 |
int wantconfirm = 1; // true |
int want_reply = 1; // true |
| 7770 |
#endif |
#endif |
| 7771 |
char buf[128]; |
char buf[128]; |
| 7772 |
|
|
| 7787 |
|
|
| 7788 |
} else if (pvar->session_nego_status == 2) { |
} else if (pvar->session_nego_status == 2) { |
| 7789 |
pvar->session_nego_status = 3; |
pvar->session_nego_status = 3; |
| 7790 |
msg = buffer_init(); |
|
|
if (msg == NULL) { |
|
|
// TODO: error check |
|
|
return FALSE; |
|
|
} |
|
| 7791 |
// find channel by shell id(2005.2.27 yutaka) |
// find channel by shell id(2005.2.27 yutaka) |
| 7792 |
c = ssh2_channel_lookup(pvar->shell_id); |
c = ssh2_channel_lookup(pvar->shell_id); |
| 7793 |
if (c == NULL) { |
if (c == NULL) { |
| 7794 |
// TODO: error check |
// TODO: error check |
| 7795 |
return FALSE; |
return FALSE; |
| 7796 |
} |
} |
|
buffer_put_int(msg, c->remote_id); |
|
|
// buffer_put_int(msg, pvar->remote_id); |
|
|
|
|
|
s = "shell"; |
|
|
buffer_put_string(msg, s, strlen(s)); // ctype |
|
|
buffer_put_char(msg, wantconfirm); // wantconfirm (disableに変更 2005/3/28 yutaka) |
|
|
|
|
|
len = buffer_len(msg); |
|
|
outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len); |
|
|
memcpy(outmsg, buffer_ptr(msg), len); |
|
|
finish_send_packet(pvar); |
|
|
buffer_free(msg); |
|
| 7797 |
|
|
| 7798 |
notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_channel_success().", LOG_LEVEL_VERBOSE); |
if (!send_channel_request_gen(pvar, c, "shell", want_reply, NULL, NULL)) { |
| 7799 |
|
return FALSE;; |
| 7800 |
|
} |
| 7801 |
|
|
| 7802 |
if (wantconfirm == 0) { |
if (want_reply == 0) { |
| 7803 |
handle_SSH2_channel_success(pvar); |
handle_SSH2_channel_success(pvar); |
| 7804 |
} |
} |
| 7805 |
|
|
| 7818 |
Channel_t *c; |
Channel_t *c; |
| 7819 |
char *data; |
char *data; |
| 7820 |
int channel_id; |
int channel_id; |
|
char buf[128]; |
|
| 7821 |
|
|
| 7822 |
data = pvar->ssh_state.payload; |
data = pvar->ssh_state.payload; |
| 7823 |
channel_id = get_uint32_MSBfirst(data); |
channel_id = get_uint32_MSBfirst(data); |
| 7843 |
if (pvar->session_nego_status == 1) { |
if (pvar->session_nego_status == 1) { |
| 7844 |
// リモートで auth-agent-req@openssh.com がサポートされてないので |
// リモートで auth-agent-req@openssh.com がサポートされてないので |
| 7845 |
// エラーは気にせず次へ進む |
// エラーは気にせず次へ進む |
| 7846 |
|
notify_verbose_message(pvar, |
| 7847 |
strncpy_s(buf, sizeof(buf), |
"auth-agent-req@openssh.com is not supported by remote host.", |
| 7848 |
"auth-agent-req@openssh.com is not supported by remote host.", |
LOG_LEVEL_VERBOSE); |
|
_TRUNCATE); |
|
|
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
|
| 7849 |
|
|
| 7850 |
return send_pty_request(pvar, c); |
return send_pty_request(pvar, c); |
| 7851 |
} |
} |