Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3175 by maya, Mon Nov 24 18:47:25 2008 UTC revision 3176 by maya, Sun Nov 30 16:14:41 2008 UTC
# Line 63  SOFTWARE, EVEN IF ADVISED OF THE POSSIBI Line 63  SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
63  #define SSH2_DEBUG  #define SSH2_DEBUG
64  #endif  #endif
65    
66  #define DONT_WANTCONFIRM 1  // (2005.3.28 yutaka)  //#define DONT_WANTCONFIRM 1  // (2005.3.28 yutaka)
67    #undef DONT_WANTCONFIRM // (2008.11.25 maya)
68  #define INTBLOB_LEN 20  #define INTBLOB_LEN 20
69  #define SIGBLOB_LEN (2*INTBLOB_LEN)  #define SIGBLOB_LEN (2*INTBLOB_LEN)
70    
# Line 75  SOFTWARE, EVEN IF ADVISED OF THE POSSIBI Line 76  SOFTWARE, EVEN IF ADVISED OF THE POSSIBI
76  #define CHANNEL_MAX 100  #define CHANNEL_MAX 100
77    
78  enum channel_type {  enum channel_type {
79          TYPE_SHELL, TYPE_PORTFWD, TYPE_SCP, TYPE_SFTP,          TYPE_SHELL, TYPE_PORTFWD, TYPE_SCP, TYPE_SFTP, TYPE_AGENT,
80  };  };
81    
82  enum scp_state {  enum scp_state {
# Line 118  typedef struct channel { Line 119  typedef struct channel {
119          int local_num;          int local_num;
120          bufchain_t *bufchain;          bufchain_t *bufchain;
121          scp_t scp;          scp_t scp;
122            buffer_t *agent_msg;
123            int agent_request_len;
124  } Channel_t;  } Channel_t;
125    
126  static Channel_t channels[CHANNEL_MAX];  static Channel_t channels[CHANNEL_MAX];
# Line 144  static BOOL handle_SSH2_open_failure(PTI Line 147  static BOOL handle_SSH2_open_failure(PTI
147  static BOOL handle_SSH2_request_success(PTInstVar pvar);  static BOOL handle_SSH2_request_success(PTInstVar pvar);
148  static BOOL handle_SSH2_request_failure(PTInstVar pvar);  static BOOL handle_SSH2_request_failure(PTInstVar pvar);
149  static BOOL handle_SSH2_channel_success(PTInstVar pvar);  static BOOL handle_SSH2_channel_success(PTInstVar pvar);
150    static BOOL handle_SSH2_channel_failure(PTInstVar pvar);
151  static BOOL handle_SSH2_channel_data(PTInstVar pvar);  static BOOL handle_SSH2_channel_data(PTInstVar pvar);
152  static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);  static BOOL handle_SSH2_channel_extended_data(PTInstVar pvar);
153  static BOOL handle_SSH2_channel_eof(PTInstVar pvar);  static BOOL handle_SSH2_channel_eof(PTInstVar pvar);
# Line 158  void SSH2_dispatch_add_range_message(uns Line 162  void SSH2_dispatch_add_range_message(uns
162  int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);  int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
163  static void start_ssh_heartbeat_thread(PTInstVar pvar);  static void start_ssh_heartbeat_thread(PTInstVar pvar);
164  static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);  static void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
165    void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c);
166    static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen);
167    
168  //  //
169  // channel function  // channel function
# Line 200  static Channel_t *ssh2_channel_new(unsig Line 206  static Channel_t *ssh2_channel_new(unsig
206                  c->scp.thread = (HANDLE)-1;                  c->scp.thread = (HANDLE)-1;
207                  c->scp.localfp = NULL;                  c->scp.localfp = NULL;
208          }          }
209            if (type == TYPE_AGENT) {
210                    c->agent_msg = buffer_init();
211                    c->agent_request_len = 0;
212            }
213    
214          return (c);          return (c);
215  }  }
# Line 288  static void ssh2_channel_delete(Channel_ Line 298  static void ssh2_channel_delete(Channel_
298                          c->scp.thread = (HANDLE)-1L;                          c->scp.thread = (HANDLE)-1L;
299                  }                  }
300          }          }
301            if (c->type == TYPE_AGENT) {
302                    buffer_free(c->agent_msg);
303            }
304    
305          memset(c, 0, sizeof(Channel_t));          memset(c, 0, sizeof(Channel_t));
306          c->used = 0;          c->used = 0;
# Line 1673  static void init_protocol(PTInstVar pvar Line 1686  static void init_protocol(PTInstVar pvar
1686                  enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);                  enque_handler(pvar, SSH2_MSG_CHANNEL_REQUEST, handle_SSH2_channel_request);
1687                  enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);                  enque_handler(pvar, SSH2_MSG_CHANNEL_WINDOW_ADJUST, handle_SSH2_window_adjust);
1688                  enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);                  enque_handler(pvar, SSH2_MSG_CHANNEL_SUCCESS, handle_SSH2_channel_success);
1689                    enque_handler(pvar, SSH2_MSG_CHANNEL_FAILURE, handle_SSH2_channel_failure);
1690  //              enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);  //              enque_handler(pvar, SSH2_MSG_GLOBAL_REQUEST, handle_unimplemented);
1691                  enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);                  enque_handler(pvar, SSH2_MSG_REQUEST_FAILURE, handle_SSH2_request_failure);
1692                  enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);                  enque_handler(pvar, SSH2_MSG_REQUEST_SUCCESS, handle_SSH2_request_success);
# Line 1878  static BOOL handle_channel_open_failure( Line 1892  static BOOL handle_channel_open_failure(
1892    
1893  static BOOL handle_channel_data(PTInstVar pvar)  static BOOL handle_channel_data(PTInstVar pvar)
1894  {  {
1895          int len;          int len, local_channel;
1896    
1897          if (grab_payload(pvar, 8)          if (grab_payload(pvar, 8)
1898           && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {           && grab_payload(pvar, len = get_payload_uint32(pvar, 4))) {
1899                  FWD_received_data(pvar, get_payload_uint32(pvar, 0),                  local_channel = get_payload_uint32(pvar, 0);
1900                                    pvar->ssh_state.payload + 8, len);                  if (local_channel == pvar->agent_channel.local_id) {
1901                            SSH_agent_response(pvar, NULL,
1902                                               pvar->ssh_state.payload + 8, len);
1903                    }
1904                    else {
1905                            FWD_received_data(pvar, local_channel,
1906                                              pvar->ssh_state.payload + 8, len);
1907                    }
1908          }          }
1909          return TRUE;          return TRUE;
1910  }  }
# Line 1891  static BOOL handle_channel_data(PTInstVa Line 1912  static BOOL handle_channel_data(PTInstVa
1912  static BOOL handle_channel_input_eof(PTInstVar pvar)  static BOOL handle_channel_input_eof(PTInstVar pvar)
1913  {  {
1914          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1915                  FWD_channel_input_eof(pvar, get_payload_uint32(pvar, 0));                  int local_id = get_payload_uint32(pvar, 0);
1916                    if (local_id == pvar->agent_channel.local_id) {
1917                            SSH_channel_input_eof(pvar, pvar->agent_channel.remote_id,
1918                                                        pvar->agent_channel.local_id);
1919                    }
1920                    else {
1921                            FWD_channel_input_eof(pvar, local_id);
1922                    }
1923          }          }
1924          return TRUE;          return TRUE;
1925  }  }
# Line 1899  static BOOL handle_channel_input_eof(PTI Line 1927  static BOOL handle_channel_input_eof(PTI
1927  static BOOL handle_channel_output_eof(PTInstVar pvar)  static BOOL handle_channel_output_eof(PTInstVar pvar)
1928  {  {
1929          if (grab_payload(pvar, 4)) {          if (grab_payload(pvar, 4)) {
1930                  FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));                  int local_id = get_payload_uint32(pvar, 0);
1931                    if (local_id == pvar->agent_channel.local_id) {
1932                            SSH_channel_output_eof(pvar, pvar->agent_channel.remote_id);
1933                            buffer_free(pvar->agent_channel.agent_msg);
1934                    }
1935                    else {
1936                            FWD_channel_output_eof(pvar, get_payload_uint32(pvar, 0));
1937                    }
1938            }
1939            return TRUE;
1940    }
1941    
1942    static BOOL handle_agent_open(PTInstVar pvar)
1943    {
1944            if (grab_payload(pvar, 4)) {
1945                    pvar->agent_channel.remote_id = get_payload_uint32(pvar, 0);
1946                    if (pvar->agentfwd_enable) {
1947                            // SSH1 の channel 実装が port forward しか想定していなかったので、
1948                            // agent forward では固定値を使う
1949                            pvar->agent_channel.local_id = SSH1_AGENT_CHANNEL_ID;
1950                            pvar->agent_channel.agent_msg = buffer_init();
1951                            pvar->agent_channel.agent_request_len = 0;
1952                            SSH_confirm_channel_open(pvar,
1953                                                     pvar->agent_channel.remote_id,
1954                                                     pvar->agent_channel.local_id);
1955                    }
1956                    else {
1957                            SSH_fail_channel_open(pvar, pvar->agent_channel.remote_id);
1958                    }
1959            }
1960            /*
1961            else {
1962                    // 通知する相手channelが分からないので何もできない
1963          }          }
1964            */
1965    
1966          return TRUE;          return TRUE;
1967  }  }
1968    
# Line 2043  static BOOL handle_pty_success(PTInstVar Line 2105  static BOOL handle_pty_success(PTInstVar
2105                        handle_channel_output_eof);                        handle_channel_output_eof);
2106          enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);          enque_handler(pvar, SSH_MSG_PORT_OPEN, handle_channel_open);
2107          enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);          enque_handler(pvar, SSH_SMSG_X11_OPEN, handle_X11_channel_open);
2108            enque_handler(pvar, SSH_SMSG_AGENT_OPEN, handle_agent_open);
2109          return FALSE;          return FALSE;
2110  }  }
2111    
# Line 2080  static void prep_pty(PTInstVar pvar) Line 2143  static void prep_pty(PTInstVar pvar)
2143          finish_send_packet(pvar);          finish_send_packet(pvar);
2144  }  }
2145    
2146    static BOOL handle_agent_request_success(PTInstVar pvar)
2147    {
2148            pvar->agentfwd_enable = TRUE;
2149            prep_pty(pvar);
2150            return FALSE;
2151    }
2152    
2153    static BOOL handle_agent_request_failure(PTInstVar pvar)
2154    {
2155            prep_pty(pvar);
2156            return FALSE;
2157    }
2158    
2159    static void prep_agent_request(PTInstVar pvar)
2160    {
2161            static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
2162            static const SSHPacketHandler handlers[]
2163            = { handle_agent_request_success, handle_agent_request_failure };
2164    
2165            enque_handlers(pvar, 2, msgs, handlers);
2166    
2167            begin_send_packet(pvar, SSH_CMSG_AGENT_REQUEST_FORWARDING, 0);
2168            finish_send_packet(pvar);
2169    }
2170    
2171  static void prep_forwarding(PTInstVar pvar)  static void prep_forwarding(PTInstVar pvar)
2172  {  {
2173          FWD_prep_forwarding(pvar);          FWD_prep_forwarding(pvar);
2174          prep_pty(pvar);  
2175            if (pvar->session_settings.ForwardAgent) {
2176                    prep_agent_request(pvar);
2177            }
2178            else {
2179                    prep_pty(pvar);
2180            }
2181  }  }
2182    
2183    
# Line 2604  void SSH_init(PTInstVar pvar) Line 2698  void SSH_init(PTInstVar pvar)
2698          pvar->decomp_buffer = NULL;          pvar->decomp_buffer = NULL;
2699          pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)          pvar->ssh2_authlist = NULL; // (2007.4.27 yutaka)
2700          pvar->tryed_ssh2_authlist = FALSE;          pvar->tryed_ssh2_authlist = FALSE;
2701            pvar->agentfwd_enable = FALSE;
2702    
2703  }  }
2704    
# Line 2971  void SSH_end(PTInstVar pvar) Line 3066  void SSH_end(PTInstVar pvar)
3066                      &pvar->ssh_state.precompress_outbuflen);                      &pvar->ssh_state.precompress_outbuflen);
3067          buf_destroy(&pvar->ssh_state.postdecompress_inbuf,          buf_destroy(&pvar->ssh_state.postdecompress_inbuf,
3068                      &pvar->ssh_state.postdecompress_inbuflen);                      &pvar->ssh_state.postdecompress_inbuflen);
3069            pvar->agentfwd_enable = FALSE;
3070    
3071          // support of "Compression delayed" (2006.6.23 maya)          // support of "Compression delayed" (2006.6.23 maya)
3072          if (pvar->ssh_state.compressing ||          if (pvar->ssh_state.compressing ||
# Line 7464  BOOL handle_SSH2_userauth_inforeq(PTInst Line 7560  BOOL handle_SSH2_userauth_inforeq(PTInst
7560          return TRUE;          return TRUE;
7561  }  }
7562    
7563    BOOL send_pty_request(PTInstVar pvar, Channel_t *c)
7564    {
7565            buffer_t *msg, *ttymsg;
7566            char *s = "pty-req";  // pseudo terminalのリクエスト
7567            unsigned char *outmsg;
7568            int len;
7569    #ifdef DONT_WANTCONFIRM
7570            int wantconfirm = 0; // false
7571    #else
7572            int wantconfirm = 1; // true
7573    #endif
7574    
7575            // pty open
7576            msg = buffer_init();
7577            if (msg == NULL) {
7578                    // TODO: error check
7579                    return FALSE;
7580            }
7581            ttymsg = buffer_init();
7582            if (ttymsg == NULL) {
7583                    // TODO: error check
7584                    buffer_free(msg);
7585                    return FALSE;
7586            }
7587    
7588            buffer_put_int(msg, c->remote_id);
7589            buffer_put_string(msg, s, strlen(s));
7590            buffer_put_char(msg, wantconfirm);  // wantconfirm (disableに変更 2005/3/28 yutaka)
7591    
7592            s = pvar->ts->TermType; // TERM
7593            buffer_put_string(msg, s, strlen(s));
7594            buffer_put_int(msg, pvar->ssh_state.win_cols);  // columns
7595            buffer_put_int(msg, pvar->ssh_state.win_rows);  // lines
7596            buffer_put_int(msg, 480);  // XXX:
7597            buffer_put_int(msg, 640);  // XXX:
7598    
7599            // TTY modeはここで渡す (2005.7.17 yutaka)
7600    #if 0
7601            s = "";
7602            buffer_put_string(msg, s, strlen(s));
7603    #else
7604            buffer_put_char(ttymsg, 129);  // TTY_OP_OSPEED_PROTO2
7605            buffer_put_int(ttymsg, 9600);  // baud rate
7606            buffer_put_char(ttymsg, 128);  // TTY_OP_ISPEED_PROTO2
7607            buffer_put_int(ttymsg, 9600);  // baud rate
7608            // VERASE
7609            buffer_put_char(ttymsg, 3);
7610            if (pvar->ts->BSKey == IdBS) {
7611                    buffer_put_int(ttymsg, 0x08); // BS key
7612            } else {
7613                    buffer_put_int(ttymsg, 0x7F); // DEL key
7614            }
7615            // TTY_OP_END
7616            buffer_put_char(ttymsg, 0);
7617    
7618            // SSH2では文字列として書き込む。
7619            buffer_put_string(msg, buffer_ptr(ttymsg), buffer_len(ttymsg));
7620    #endif
7621    
7622            len = buffer_len(msg);
7623            outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
7624            memcpy(outmsg, buffer_ptr(msg), len);
7625            finish_send_packet(pvar);
7626            buffer_free(msg);
7627            buffer_free(ttymsg);
7628    
7629            notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at send_pty_request().", LOG_LEVEL_VERBOSE);
7630            pvar->session_nego_status = 2;
7631    
7632            if (wantconfirm == 0) {
7633                    handle_SSH2_channel_success(pvar);
7634            }
7635    
7636            return TRUE;
7637    }
7638    
7639  static BOOL handle_SSH2_open_confirm(PTInstVar pvar)  static BOOL handle_SSH2_open_confirm(PTInstVar pvar)
7640  {        {      
7641          buffer_t *msg, *ttymsg;          buffer_t *msg;
7642          char *s;          char *s;
7643          unsigned char *outmsg;          unsigned char *outmsg;
7644          int len;          int len;
# Line 7524  static BOOL handle_SSH2_open_confirm(PTI Line 7695  static BOOL handle_SSH2_open_confirm(PTI
7695    
7696          //debug_print(100, data, len);          //debug_print(100, data, len);
7697    
7698          // pty open          if (c->type == TYPE_SHELL) {
7699                    // エージェント転送 (2008.11.25 maya)
7700                    if (pvar->session_settings.ForwardAgent) {
7701                            // pty-req より前にリクエストしないとエラーになる模様
7702    
7703                            msg = buffer_init();
7704                            if (msg == NULL) {
7705                                    // TODO: error check
7706                                    return FALSE;
7707                            }
7708                            buffer_put_int(msg, c->remote_id);
7709                            s = "auth-agent-req@openssh.com";
7710                            buffer_put_string(msg, s, strlen(s));
7711                            buffer_put_char(msg, 1); // want reply
7712                            len = buffer_len(msg);
7713                            outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
7714                            memcpy(outmsg, buffer_ptr(msg), len);
7715                            finish_send_packet(pvar);
7716                            buffer_free(msg);
7717    
7718                            notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_channel_success().", LOG_LEVEL_VERBOSE);
7719                            return TRUE;
7720                    }
7721                    else {
7722                            return send_pty_request(pvar, c);
7723                    }
7724            }
7725    
7726          msg = buffer_init();          msg = buffer_init();
7727          if (msg == NULL) {          if (msg == NULL) {
7728                  // TODO: error check                  // TODO: error check
7729                  return FALSE;                  return FALSE;
7730          }          }
         ttymsg = buffer_init();  
         if (ttymsg == NULL) {  
                 // TODO: error check  
                 buffer_free(msg);  
                 return FALSE;  
         }  
7731    
7732          buffer_put_int(msg, remote_id);          buffer_put_int(msg, remote_id);
7733          if (c->type == TYPE_SCP) {          if (c->type == TYPE_SCP) {
7734                  s = "exec";                  s = "exec";
7735          } else if (c->type == TYPE_SFTP) {          } else if (c->type == TYPE_SFTP) {
7736                  s = "subsystem";                  s = "subsystem";
         } else if (c->type == TYPE_SHELL) {  
                 s = "pty-req";  // pseudo terminalのリクエスト  
7737          } else {          } else {
7738                  s = "";  // NOT REACHED                  s = "";  // NOT REACHED
7739          }          }
# Line 7560  static BOOL handle_SSH2_open_confirm(PTI Line 7750  static BOOL handle_SSH2_open_confirm(PTI
7750    
7751                  }                  }
7752                  buffer_put_string(msg, sbuf, strlen(sbuf));                  buffer_put_string(msg, sbuf, strlen(sbuf));
                 goto done;  
7753          }          }
7754            else if (c->type == TYPE_SFTP) {
         if (c->type == TYPE_SFTP) {  
7755                  char *sbuf = "sftp";                  char *sbuf = "sftp";
7756                  buffer_put_string(msg, sbuf, strlen(sbuf));                  buffer_put_string(msg, sbuf, strlen(sbuf));
                 goto done;  
7757          }          }
7758    
         s = pvar->ts->TermType; // TERM  
         buffer_put_string(msg, s, strlen(s));  
         buffer_put_int(msg, pvar->ssh_state.win_cols);  // columns  
         buffer_put_int(msg, pvar->ssh_state.win_rows);  // lines  
         buffer_put_int(msg, 480);  // XXX:  
         buffer_put_int(msg, 640);  // XXX:  
   
         // TTY modeはここで渡す (2005.7.17 yutaka)  
 #if 0  
         s = "";  
         buffer_put_string(msg, s, strlen(s));  
 #else  
         buffer_put_char(ttymsg, 129);  // TTY_OP_OSPEED_PROTO2  
         buffer_put_int(ttymsg, 9600);  // baud rate  
         buffer_put_char(ttymsg, 128);  // TTY_OP_ISPEED_PROTO2  
         buffer_put_int(ttymsg, 9600);  // baud rate  
         // VERASE  
         buffer_put_char(ttymsg, 3);  
         if (pvar->ts->BSKey == IdBS) {  
                 buffer_put_int(ttymsg, 0x08); // BS key  
         } else {  
                 buffer_put_int(ttymsg, 0x7F); // DEL key  
         }  
         // TTY_OP_END  
         buffer_put_char(ttymsg, 0);  
   
         // SSH2では文字列として書き込む。  
         buffer_put_string(msg, buffer_ptr(ttymsg), buffer_len(ttymsg));  
 #endif  
   
 done:  
7759          len = buffer_len(msg);          len = buffer_len(msg);
7760          outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);          outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_REQUEST, len);
7761          memcpy(outmsg, buffer_ptr(msg), len);          memcpy(outmsg, buffer_ptr(msg), len);
7762          finish_send_packet(pvar);          finish_send_packet(pvar);
7763          buffer_free(msg);          buffer_free(msg);
         buffer_free(ttymsg);  
7764    
7765          notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_open_confirm().", LOG_LEVEL_VERBOSE);          notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was sent at handle_SSH2_open_confirm().", LOG_LEVEL_VERBOSE);
7766    
7767          if (c->type == TYPE_SHELL) {          if (c->type == TYPE_SCP) {
                 if (wantconfirm == 0) {  
                         handle_SSH2_channel_success(pvar);  
                 }  
   
         } else if (c->type == TYPE_SCP) {  
7768                  // SCPで remote-to-local の場合は、サーバからのファイル送信要求を出す。                  // SCPで remote-to-local の場合は、サーバからのファイル送信要求を出す。
7769                  // この時点では remote window size が"0"なので、すぐには送られないが、遅延送信処理で送られる。                  // この時点では remote window size が"0"なので、すぐには送られないが、遅延送信処理で送られる。
7770                  // (2007.12.27 yutaka)                  // (2007.12.27 yutaka)
# Line 7716  static BOOL handle_SSH2_channel_success( Line 7866  static BOOL handle_SSH2_channel_success(
7866          unsigned char *outmsg;          unsigned char *outmsg;
7867          int len;          int len;
7868          Channel_t *c;          Channel_t *c;
7869    #ifdef DONT_WANTCONFIRM
7870            int wantconfirm = 0; // false
7871    #else
7872            int wantconfirm = 1; // true
7873    #endif
7874    
7875          {          {
7876                  char buf[128];                  char buf[128];
# Line 7726  static BOOL handle_SSH2_channel_success( Line 7881  static BOOL handle_SSH2_channel_success(
7881          }          }
7882    
7883          if (pvar->session_nego_status == 1) {          if (pvar->session_nego_status == 1) {
7884  #ifdef DONT_WANTCONFIRM                  // find channel by shell id(2005.2.27 yutaka)
7885                  int wantconfirm = 0; // false                  c = ssh2_channel_lookup(pvar->shell_id);
7886  #else                  if (c == NULL) {
7887                  int wantconfirm = 1; // true                          // TODO: error check
7888  #endif                          return FALSE;
7889                    }
7890                    pvar->agentfwd_enable = TRUE;
7891                    return send_pty_request(pvar, c);
7892    
7893                  pvar->session_nego_status = 2;          } else if (pvar->session_nego_status == 2) {
7894                    pvar->session_nego_status = 3;
7895                  msg = buffer_init();                  msg = buffer_init();
7896                  if (msg == NULL) {                  if (msg == NULL) {
7897                          // TODO: error check                          // TODO: error check
# Line 7763  static BOOL handle_SSH2_channel_success( Line 7922  static BOOL handle_SSH2_channel_success(
7922                          handle_SSH2_channel_success(pvar);                          handle_SSH2_channel_success(pvar);
7923                  }                  }
7924    
7925          } else if (pvar->session_nego_status == 2) {          } else if (pvar->session_nego_status == 3) {
7926                  pvar->session_nego_status = 3;                  pvar->session_nego_status = 4;
7927    
7928          } else {          } else {
7929    
# Line 7773  static BOOL handle_SSH2_channel_success( Line 7932  static BOOL handle_SSH2_channel_success(
7932          return TRUE;          return TRUE;
7933  }  }
7934    
7935    static BOOL handle_SSH2_channel_failure(PTInstVar pvar)
7936    {
7937            Channel_t *c;
7938    
7939            notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_FAILURE was received.", LOG_LEVEL_VERBOSE);
7940    
7941            if (pvar->session_nego_status == 1) {
7942                    // リモートで auth-agent-req@openssh.com がサポートされてないので
7943                    // エラーは気にせず次へ進む
7944    
7945                    // find channel by shell id(2005.2.27 yutaka)
7946                    c = ssh2_channel_lookup(pvar->shell_id);
7947                    if (c == NULL) {
7948                            // TODO: error check
7949                            return FALSE;
7950                    }
7951                    return send_pty_request(pvar, c);
7952            }
7953            else {
7954                    return FALSE;
7955            }
7956    
7957            return TRUE;
7958    }
7959    
7960    
7961    
7962  // クライアントのwindow sizeをサーバへ知らせる  // クライアントのwindow sizeをサーバへ知らせる
# Line 8264  static BOOL handle_SSH2_channel_data(PTI Line 8448  static BOOL handle_SSH2_channel_data(PTI
8448    
8449          } else if (c->type == TYPE_SFTP) {  // SFTP          } else if (c->type == TYPE_SFTP) {  // SFTP
8450    
8451            } else if (c->type == TYPE_AGENT) {  // agent forward
8452                    if (!SSH_agent_response(pvar, c, data, str_len)) {
8453                            return FALSE;
8454                    }
8455          }          }
8456    
8457          //debug_print(200, data, strlen);          //debug_print(200, data, strlen);
# Line 8376  static BOOL handle_SSH2_channel_eof(PTIn Line 8563  static BOOL handle_SSH2_channel_eof(PTIn
8563          if (c->type == TYPE_PORTFWD) {          if (c->type == TYPE_PORTFWD) {
8564                  FWD_channel_input_eof(pvar, c->local_num);                  FWD_channel_input_eof(pvar, c->local_num);
8565          }          }
8566            else if (c->type == TYPE_AGENT) {
8567                    ssh2_channel_send_close(pvar, c);
8568            }
8569    
8570          return TRUE;          return TRUE;
8571  }  }
# Line 8391  static BOOL handle_SSH2_channel_open(PTI Line 8581  static BOOL handle_SSH2_channel_open(PTI
8581          int remote_window;          int remote_window;
8582          int remote_maxpacket;          int remote_maxpacket;
8583          int chan_num = -1;          int chan_num = -1;
8584            buffer_t *msg;
8585            unsigned char *outmsg;
8586    
8587          notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN was received.", LOG_LEVEL_VERBOSE);          notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN was received.", LOG_LEVEL_VERBOSE);
8588    
# Line 8476  static BOOL handle_SSH2_channel_open(PTI Line 8668  static BOOL handle_SSH2_channel_open(PTI
8668                  c->remote_window = remote_window;                  c->remote_window = remote_window;
8669                  c->remote_maxpacket = remote_maxpacket;                  c->remote_maxpacket = remote_maxpacket;
8670    
8671            } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { // agent forwarding
8672                    if (pvar->agentfwd_enable) {
8673                            c = ssh2_channel_new(CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, TYPE_AGENT, chan_num);
8674                            if (c == NULL) {
8675                                    UTIL_get_lang_msg("MSG_SSH_NO_FREE_CHANNEL", pvar,
8676                                                      "Could not open new channel. TTSSH is already opening too many channels.");
8677                                    notify_nonfatal_error(pvar, pvar->ts->UIMsg);
8678                                    return FALSE;
8679                            }
8680                            c->remote_id = remote_id;
8681                            c->remote_window = remote_window;
8682                            c->remote_maxpacket = remote_maxpacket;
8683                            
8684                            msg = buffer_init();
8685                            if (msg == NULL) {
8686                                    // TODO: error check
8687                                    return FALSE;
8688                            }
8689                            buffer_put_int(msg, c->remote_id);
8690                            buffer_put_int(msg, c->self_id);
8691                            buffer_put_int(msg, c->local_window);
8692                            buffer_put_int(msg, c->local_maxpacket);
8693    
8694                            len = buffer_len(msg);
8695                            outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, len);
8696                            memcpy(outmsg, buffer_ptr(msg), len);
8697                            finish_send_packet(pvar);
8698                            buffer_free(msg);
8699    
8700                            notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN_CONFIRMATION was sent at handle_SSH2_channel_open().", LOG_LEVEL_VERBOSE);
8701                    }
8702                    else {
8703                            msg = buffer_init();
8704                            if (msg == NULL) {
8705                                    // TODO: error check
8706                                    return FALSE;
8707                            }
8708                            buffer_put_int(msg, remote_id);
8709                            buffer_put_int(msg, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
8710                            buffer_put_string(msg, "", 0); // description
8711                            buffer_put_string(msg, "", 0); // language tag
8712    
8713                            len = buffer_len(msg);
8714                            outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_OPEN_FAILURE, len);
8715                            memcpy(outmsg, buffer_ptr(msg), len);
8716                            finish_send_packet(pvar);
8717                            buffer_free(msg);
8718    
8719                            notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_OPEN_FAILURE was sent at handle_SSH2_channel_open().", LOG_LEVEL_VERBOSE);
8720                    }
8721    
8722          } else {          } else {
8723                  // unknown type(unsupported)                  // unknown type(unsupported)
8724    
# Line 8680  static BOOL handle_SSH2_window_adjust(PT Line 8923  static BOOL handle_SSH2_window_adjust(PT
8923    
8924          return TRUE;          return TRUE;
8925  }  }
8926    
8927    static BOOL SSH_agent_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen)
8928    {
8929            int req_len, len;
8930            unsigned char *keylist;
8931            buffer_t *msg;
8932            unsigned char cmd, res_cmd;
8933    
8934            req_len = get_uint32_MSBfirst(data);
8935    
8936            // 分割された CHANNEL_DATA の受信に対応 (2008.11.30 maya)
8937            if (SSHv2(pvar)) {
8938                    if (c->agent_msg->len > 0 || req_len + 4 != buflen) {
8939                            if (c->agent_msg->len == 0) {
8940                                    c->agent_request_len = req_len;
8941                            }
8942                            buffer_put_raw(c->agent_msg, data, buflen);
8943                            if (c->agent_request_len > c->agent_msg->len) {
8944                                    return TRUE;
8945                            }
8946                            else {
8947                                    data = c->agent_msg->buf;
8948                            }
8949                    }
8950            }
8951            else {
8952                    if (pvar->agent_channel.agent_msg->len > 0 || req_len + 4 != buflen) {
8953                            if (pvar->agent_channel.agent_msg->len == 0) {
8954                                    pvar->agent_channel.agent_request_len = req_len;
8955                            }
8956                            buffer_put_raw(pvar->agent_channel.agent_msg, data, buflen);
8957                            if (pvar->agent_channel.agent_request_len > pvar->agent_channel.agent_msg->len) {
8958                                    return TRUE;
8959                            }
8960                            else {
8961                                    data = pvar->agent_channel.agent_msg->buf;
8962                            }
8963                    }
8964            }
8965    
8966            data += 4;
8967            cmd = *data;
8968    
8969            if (cmd == 11 || cmd == 1) {
8970                    // Pageant に鍵一覧を要求し、リモートに渡す
8971                    msg = buffer_init();
8972                    if (msg == NULL) {
8973                            return TRUE;
8974                    }
8975    
8976                    if (cmd == 11) { // SSH2_AGENTC_REQUEST_IDENTITIES
8977                            len = putty_get_ssh2_keylist(&keylist);
8978                            res_cmd = 12; // SSH2_AGENT_IDENTITIES_ANSWER
8979                    }
8980                    else { // SSH1_AGENTC_REQUEST_RSA_IDENTITIES 1
8981                            len = putty_get_ssh1_keylist(&keylist);
8982                            res_cmd = 2; // SSH1_AGENT_RSA_IDENTITIES_ANSWER
8983                    }
8984    
8985                    if (len < 5) {
8986                            // Pageant が起動していないか、鍵がない
8987                            buffer_put_int(msg, 4 + 1);
8988                            buffer_put_char(msg, res_cmd);
8989                            buffer_put_int(msg, 0); // 鍵の数 0 をセット
8990                    }
8991                    else {
8992                            buffer_put_int(msg, len + 1);
8993                            buffer_put_char(msg, res_cmd);
8994                            buffer_put_raw(msg, keylist, len);
8995                    }
8996    
8997                    if (SSHv2(pvar)) {
8998                            SSH2_send_channel_data(pvar, c, msg->buf, msg->len);
8999                    }
9000                    else {
9001                            SSH_channel_send(pvar, pvar->agent_channel.local_id,
9002                                                   pvar->agent_channel.remote_id,
9003                                             msg->buf, msg->len);
9004                    }
9005                    buffer_free(msg);
9006            }
9007            else if (cmd == 13 || cmd == 3) {
9008                    // Pageant に署名/ハッシュを要求し、リモートに渡す
9009                    msg = buffer_init();
9010                    if (msg == NULL) {
9011                            return TRUE;
9012                    }
9013    
9014                    if (cmd == 13) { // SSH2_AGENTC_SIGN_REQUEST
9015                            unsigned char *signedmsg;
9016                            int signedlen;
9017    
9018                            data += 1;
9019                            len = get_uint32_MSBfirst(data);
9020                            signedmsg = putty_sign_ssh2_key(data, data + 4 + len, &signedlen);
9021                            if (signedmsg == NULL) {
9022                                    // この channel を閉じる
9023                                    if (SSHv2(pvar)) {
9024                                            ssh2_channel_send_close(pvar, c);
9025                                    }
9026                                    else {
9027                                            SSH_channel_input_eof(pvar, pvar->agent_channel.remote_id,
9028                                                                        pvar->agent_channel.local_id);
9029                                    }
9030                                    return TRUE;
9031                            }
9032    
9033                            buffer_put_int(msg, 1 + signedlen);
9034                            buffer_put_char(msg, 14); // SSH2_AGENT_SIGN_RESPONSE
9035                            buffer_put_raw(msg, signedmsg, signedlen);
9036    
9037                            safefree(signedmsg);
9038                    }
9039                    else { // SSH1_AGENTC_RSA_CHALLENGE
9040                            unsigned char *hash;
9041                            int keylen, challengelen, hashlen;
9042                            data += 1;
9043                            keylen = putty_get_ssh1_keylen(data, req_len);
9044                            challengelen = req_len - keylen - 1 - 16 - 4;
9045                            hash = putty_hash_ssh1_challenge(data, keylen,
9046                                                             data + keylen, challengelen,
9047                                                             data + keylen + challengelen,
9048                                                             &hashlen);
9049                            if (hash == NULL) {
9050                                    // この channel を閉じる
9051                                    if (SSHv2(pvar)) {
9052                                            ssh2_channel_send_close(pvar, c);
9053                                    }
9054                                    else {
9055                                            SSH_channel_input_eof(pvar, pvar->agent_channel.remote_id,
9056                                                                        pvar->agent_channel.local_id);
9057                                    }
9058                                    return TRUE;
9059                            }
9060    
9061                            buffer_put_int(msg, 1 + hashlen);
9062                            buffer_put_char(msg, 4); // SSH1_AGENT_RSA_RESPONSE
9063                            buffer_put_raw(msg, hash, hashlen);
9064    
9065                            safefree(hash);
9066                    }
9067    
9068                    if (SSHv2(pvar)) {
9069                            SSH2_send_channel_data(pvar, c, msg->buf, msg->len);
9070                    }
9071                    else {
9072                            SSH_channel_send(pvar, pvar->agent_channel.local_id,
9073                                                   pvar->agent_channel.remote_id,
9074                                                   msg->buf, msg->len);
9075                    }
9076                    buffer_free(msg);
9077            }
9078            else {
9079                    // この channel を閉じる
9080                    if (SSHv2(pvar)) {
9081                            ssh2_channel_send_close(pvar, c);
9082                    }
9083                    else {
9084                            SSH_channel_input_eof(pvar, pvar->agent_channel.remote_id,
9085                                                        pvar->agent_channel.local_id);
9086                    }
9087                    return TRUE;
9088            }
9089    
9090            return TRUE;
9091    }

Legend:
Removed from v.3175  
changed lines
  Added in v.3176

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26