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 2811 by yutakakn, Fri Apr 8 14:55:03 2005 UTC revision 2823 by yutakakn, Sun Jun 19 09:17:47 2005 UTC
# Line 100  static void start_ssh_heartbeat_thread(P Line 100  static void start_ssh_heartbeat_thread(P
100  // channel data structure  // channel data structure
101  #define CHANNEL_MAX 100  #define CHANNEL_MAX 100
102    
103    enum channel_type {
104            TYPE_SHELL, TYPE_PORTFWD,
105    };
106    
107  typedef struct channel {  typedef struct channel {
108          int used;          int used;
         int type;  
109          int self_id;          int self_id;
110          int remote_id;          int remote_id;
111          unsigned int local_window;          unsigned int local_window;
# Line 111  typedef struct channel { Line 114  typedef struct channel {
114          unsigned int local_maxpacket;          unsigned int local_maxpacket;
115          unsigned int remote_window;          unsigned int remote_window;
116          unsigned int remote_maxpacket;          unsigned int remote_maxpacket;
117            enum channel_type type;
118            int local_num;
119  } Channel_t;  } Channel_t;
120    
121  static Channel_t channels[CHANNEL_MAX];  static Channel_t channels[CHANNEL_MAX];
# Line 118  static Channel_t channels[CHANNEL_MAX]; Line 123  static Channel_t channels[CHANNEL_MAX];
123  //  //
124  // channel function  // channel function
125  //  //
126  static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack)  static Channel_t *ssh2_channel_new(unsigned int window, unsigned int maxpack, enum confirm_type type, int local_num)
127  {  {
128          int i, found;          int i, found;
129          Channel_t *c;          Channel_t *c;
# Line 145  static Channel_t *ssh2_channel_new(unsig Line 150  static Channel_t *ssh2_channel_new(unsig
150          c->local_maxpacket = maxpack;          c->local_maxpacket = maxpack;
151          c->remote_window = 0;          c->remote_window = 0;
152          c->remote_maxpacket = 0;          c->remote_maxpacket = 0;
153            c->type = type;
154            c->local_num = local_num;
155    
156          return (c);          return (c);
157  }  }
# Line 177  static Channel_t *ssh2_channel_lookup(in Line 184  static Channel_t *ssh2_channel_lookup(in
184          return (c);          return (c);
185  }  }
186    
187    // SSH1で管理しているchannel構造体から、SSH2向けのChannel_tへ変換する。
188    // TODO: 将来的にはチャネル構造体は1つに統合する。
189    // (2005.6.12 yutaka)
190    static Channel_t *ssh2_local_channel_lookup(int local_num)
191    {
192            int i;
193            Channel_t *c;
194    
195            for (i = 0 ; i < CHANNEL_MAX ; i++) {
196                    c = &channels[i];
197                    if (c->local_num == local_num)
198                            return (c);
199            }
200            return (NULL);
201    }
202    
203    
204  //  //
# Line 2248  void SSH_send(PTInstVar pvar, unsigned c Line 2270  void SSH_send(PTInstVar pvar, unsigned c
2270                  int len;                  int len;
2271                  Channel_t *c;                  Channel_t *c;
2272    
2273                    // SSH2鍵交換中の場合、パケットを捨てる。(2005.6.19 yutaka)
2274                    if (pvar->rekeying) {
2275                            // TODO: 理想としてはパケット破棄ではなく、パケット読み取り遅延にしたいところだが、
2276                            // 将来直すことにする。
2277                            c = NULL;
2278    
2279                            return;
2280                    }
2281    
2282                  c = ssh2_channel_lookup(pvar->shell_id);                  c = ssh2_channel_lookup(pvar->shell_id);
2283                  if (c == NULL)                  if (c == NULL)
2284                          return;                          return;
# Line 2451  void SSH_end(PTInstVar pvar) Line 2482  void SSH_end(PTInstVar pvar)
2482  }  }
2483    
2484  /* support for port forwarding */  /* support for port forwarding */
2485  void SSH_channel_send(PTInstVar pvar, uint32 remote_channel_num,  void SSH_channel_send(PTInstVar pvar, int channel_num,
2486                                              uint32 remote_channel_num,
2487                                            unsigned char FAR * buf, int len)                                            unsigned char FAR * buf, int len)
2488  {  {
2489          unsigned char FAR *outmsg =          int buflen = len;
                 begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);  
2490    
2491          set_uint32(outmsg, remote_channel_num);          if (SSHv1(pvar)) {
2492          set_uint32(outmsg + 4, len);                  unsigned char FAR *outmsg =
2493                            begin_send_packet(pvar, SSH_MSG_CHANNEL_DATA, 8 + len);
2494    
2495          if (pvar->ssh_state.compressing) {                  set_uint32(outmsg, remote_channel_num);
2496                  buf_ensure_size(&pvar->ssh_state.outbuf,                  set_uint32(outmsg + 4, len);
2497                                                  &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);  
2498                  pvar->ssh_state.compress_stream.next_in =                  if (pvar->ssh_state.compressing) {
2499                          pvar->ssh_state.precompress_outbuf;                          buf_ensure_size(&pvar->ssh_state.outbuf,
2500                  pvar->ssh_state.compress_stream.avail_in = 9;                                                          &pvar->ssh_state.outbuflen, len + (len >> 6) + 50);
2501                  pvar->ssh_state.compress_stream.next_out =                          pvar->ssh_state.compress_stream.next_in =
2502                          pvar->ssh_state.outbuf + 12;                                  pvar->ssh_state.precompress_outbuf;
2503                  pvar->ssh_state.compress_stream.avail_out =                          pvar->ssh_state.compress_stream.avail_in = 9;
2504                          pvar->ssh_state.outbuflen - 12;                          pvar->ssh_state.compress_stream.next_out =
2505                                    pvar->ssh_state.outbuf + 12;
2506                            pvar->ssh_state.compress_stream.avail_out =
2507                                    pvar->ssh_state.outbuflen - 12;
2508    
2509                            if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {
2510                                    notify_fatal_error(pvar, "Error compressing packet data");
2511                                    return;
2512                            }
2513    
2514                            pvar->ssh_state.compress_stream.next_in =
2515                                    (unsigned char FAR *) buf;
2516                            pvar->ssh_state.compress_stream.avail_in = len;
2517    
2518                            if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=
2519                                    Z_OK) {
2520                                    notify_fatal_error(pvar, "Error compressing packet data");
2521                                    return;
2522                            }
2523                    } else {
2524                            memcpy(outmsg + 8, buf, len);
2525                    }
2526    
2527                    finish_send_packet_special(pvar, 1);
2528    
2529            } else {
2530                    // ポートフォワーディングにおいてクライアントからの送信要求を、SSH通信に乗せてサーバまで送り届ける。
2531                    buffer_t *msg;
2532                    unsigned char *outmsg;
2533                    int len;
2534                    Channel_t *c;
2535    
2536                    // SSH2鍵交換中の場合、パケットを捨てる。(2005.6.19 yutaka)
2537                    if (pvar->rekeying) {
2538                            // TODO: 理想としてはパケット破棄ではなく、パケット読み取り遅延にしたいところだが、
2539                            // 将来直すことにする。
2540                            c = NULL;
2541    
                 if (deflate(&pvar->ssh_state.compress_stream, Z_NO_FLUSH) != Z_OK) {  
                         notify_fatal_error(pvar, "Error compressing packet data");  
2542                          return;                          return;
2543                  }                  }
2544    
2545                  pvar->ssh_state.compress_stream.next_in =                  c = ssh2_local_channel_lookup(channel_num);
2546                          (unsigned char FAR *) buf;                  if (c == NULL)
2547                  pvar->ssh_state.compress_stream.avail_in = len;                          return;
2548    
2549                  if (deflate(&pvar->ssh_state.compress_stream, Z_SYNC_FLUSH) !=                  msg = buffer_init();
2550                          Z_OK) {                  if (msg == NULL) {
2551                          notify_fatal_error(pvar, "Error compressing packet data");                          // TODO: error check
2552                          return;                          return;
2553                  }                  }
2554          } else {                  buffer_put_int(msg, c->remote_id);  
2555                  memcpy(outmsg + 8, buf, len);                  buffer_put_string(msg, (char *)buf, buflen);  
2556    
2557                    len = buffer_len(msg);
2558                    outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_DATA, len);
2559                    memcpy(outmsg, buffer_ptr(msg), len);
2560                    finish_send_packet(pvar);
2561                    buffer_free(msg);
2562    
2563                    // remote window sizeの調整
2564                    c->remote_window -= len;
2565          }          }
2566    
         finish_send_packet_special(pvar, 1);  
2567  }  }
2568    
2569  void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)  void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num)
# Line 2514  void SSH_confirm_channel_open(PTInstVar Line 2588  void SSH_confirm_channel_open(PTInstVar
2588    
2589  void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)  void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num)
2590  {  {
2591          unsigned char FAR *outmsg =          if (SSHv1(pvar)){
2592                  begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);                  unsigned char FAR *outmsg =
2593                            begin_send_packet(pvar, SSH_MSG_CHANNEL_OUTPUT_CLOSED, 4);
2594    
2595          set_uint32(outmsg, remote_channel_num);                  set_uint32(outmsg, remote_channel_num);
2596          finish_send_packet(pvar);                  finish_send_packet(pvar);
2597    
2598            } else {
2599                    // SSH2: 特になし。
2600    
2601            }
2602  }  }
2603    
2604  void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num)  void SSH_channel_input_eof(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num)
2605  {  {
2606          unsigned char FAR *outmsg =          if (SSHv1(pvar)){
2607                  begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);                  unsigned char FAR *outmsg =
2608                            begin_send_packet(pvar, SSH_MSG_CHANNEL_INPUT_EOF, 4);
2609    
2610                    set_uint32(outmsg, remote_channel_num);
2611                    finish_send_packet(pvar);
2612    
2613            } else {
2614                    // SSH2: チャネルクローズをサーバへ通知
2615                            buffer_t *msg;
2616                            unsigned char *outmsg;
2617                            int len;
2618                            Channel_t *c;
2619    
2620                            c = ssh2_local_channel_lookup(local_channel_num);
2621                            if (c == NULL)
2622                                    return;
2623    
2624                            msg = buffer_init();
2625                            if (msg == NULL) {
2626                                    // TODO: error check
2627                                    return;
2628                            }
2629                            buffer_put_int(msg, c->remote_id);  // remote ID
2630    
2631                            len = buffer_len(msg);
2632                            outmsg = begin_send_packet(pvar, SSH2_MSG_CHANNEL_EOF, len);
2633                            memcpy(outmsg, buffer_ptr(msg), len);
2634                            finish_send_packet(pvar);
2635                            buffer_free(msg);
2636            }
2637    
         set_uint32(outmsg, remote_channel_num);  
         finish_send_packet(pvar);  
2638  }  }
2639    
2640  void SSH_request_forwarding(PTInstVar pvar, int from_server_port,  void SSH_request_forwarding(PTInstVar pvar, int from_server_port,
# Line 2618  void SSH_open_channel(PTInstVar pvar, ui Line 2725  void SSH_open_channel(PTInstVar pvar, ui
2725                          int len;                          int len;
2726                          Channel_t *c;                          Channel_t *c;
2727    
2728                          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT);                          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_PORTFWD, local_channel_num);
2729    
2730                          msg = buffer_init();                          msg = buffer_init();
2731                          if (msg == NULL) {                          if (msg == NULL) {
# Line 4548  static BOOL handle_SSH2_dh_common_reply( Line 4655  static BOOL handle_SSH2_dh_common_reply(
4655  }  }
4656    
4657    
4658  static void do_SSH2_dispatch_setup_for_transfer(void)  static void do_SSH2_dispatch_setup_for_transfer(PTInstVar pvar)
4659  {  {
4660            // キー再作成情報のクリア (2005.6.19 yutaka)
4661            pvar->rekeying = 0;
4662    
4663          SSH2_dispatch_init(6);          SSH2_dispatch_init(6);
4664          SSH2_dispatch_add_range_message(SSH2_MSG_REQUEST_SUCCESS, SSH2_MSG_CHANNEL_FAILURE);          SSH2_dispatch_add_range_message(SSH2_MSG_REQUEST_SUCCESS, SSH2_MSG_CHANNEL_FAILURE);
4665          SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX          SSH2_dispatch_add_message(SSH2_MSG_IGNORE); // XXX
# Line 4579  static BOOL handle_SSH2_newkeys(PTInstVa Line 4689  static BOOL handle_SSH2_newkeys(PTInstVa
4689                  if (!CRYPT_start_encryption(pvar, 0, 1)) {                  if (!CRYPT_start_encryption(pvar, 0, 1)) {
4690                          // TODO: error                          // TODO: error
4691                  }                  }
4692                  do_SSH2_dispatch_setup_for_transfer();                  do_SSH2_dispatch_setup_for_transfer(pvar);
4693                  return TRUE;                  return TRUE;
4694          }          }
4695    
# Line 5098  static BOOL handle_SSH2_userauth_success Line 5208  static BOOL handle_SSH2_userauth_success
5208          FWD_enter_interactive_mode(pvar);          FWD_enter_interactive_mode(pvar);
5209    
5210          // ディスパッチルーチンの再設定          // ディスパッチルーチンの再設定
5211          do_SSH2_dispatch_setup_for_transfer();          do_SSH2_dispatch_setup_for_transfer(pvar);
5212    
5213    
5214          // チャネル設定          // チャネル設定
5215          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT);          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_SHELL, -1);
5216          if (c == NULL) {          if (c == NULL) {
5217                  // TODO: error check                  // TODO: error check
5218                  return FALSE;                  return FALSE;
# Line 5322  static BOOL handle_SSH2_open_confirm(PTI Line 5432  static BOOL handle_SSH2_open_confirm(PTI
5432          c->remote_maxpacket = get_uint32_MSBfirst(data);          c->remote_maxpacket = get_uint32_MSBfirst(data);
5433          data += 4;          data += 4;
5434    
5435            if (c->type == TYPE_PORTFWD) {
5436                    // port-forwadingの"direct-tcpip"が成功。
5437                    FWD_confirmed_open(pvar, c->local_num, -1);
5438                    notify_verbose_message(pvar, "SSH2_MSG_CHANNEL_REQUEST was received. (port-fowarding)", LOG_LEVEL_VERBOSE);
5439                    return TRUE;
5440            }
5441    
5442          //debug_print(100, data, len);          //debug_print(100, data, len);
5443    
5444          // pty open          // pty open
# Line 5502  static BOOL handle_SSH2_channel_data(PTI Line 5619  static BOOL handle_SSH2_channel_data(PTI
5619          }          }
5620    
5621          // ペイロードとしてクライアント(TeraTerm)へ渡す          // ペイロードとしてクライアント(TeraTerm)へ渡す
5622          pvar->ssh_state.payload_datalen = strlen;          if (c->type == TYPE_SHELL) {
5623          pvar->ssh_state.payload_datastart = 8;                  pvar->ssh_state.payload_datalen = strlen;
5624                    pvar->ssh_state.payload_datastart = 8;
5625    
5626            } else {
5627                    //debug_print(0, data, strlen);
5628                    FWD_received_data(pvar, c->local_num, data, strlen);
5629    
5630            }
5631    
5632          //debug_print(200, data, strlen);          //debug_print(200, data, strlen);
5633    
# Line 5526  static BOOL handle_SSH2_channel_extended Line 5650  static BOOL handle_SSH2_channel_extended
5650    
5651  static BOOL handle_SSH2_channel_eof(PTInstVar pvar)  static BOOL handle_SSH2_channel_eof(PTInstVar pvar)
5652  {        {      
5653          // 切断時に呼ばれてくるが、特に何もしない。          int len;
5654            char *data;
5655            int id;
5656            Channel_t *c;
5657    
5658            // 切断時にサーバが SSH2_MSG_CHANNEL_EOF を送ってくるので、チャネルを解放する。(2005.6.19 yutaka)
5659    
5660            // 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード
5661            data = pvar->ssh_state.payload;
5662            // パケットサイズ - (パディングサイズ+1);真のパケットサイズ
5663            len = pvar->ssh_state.payloadlen;
5664    
5665            // channel number
5666            id = get_uint32_MSBfirst(data);
5667            data += 4;
5668    
5669            c = ssh2_channel_lookup(id);
5670            if (c == NULL) {
5671                    // TODO:
5672                    return FALSE;
5673            }
5674            if (c->type != TYPE_SHELL) {
5675                    FWD_channel_input_eof(pvar, c->local_num);
5676            }
5677    
5678          return TRUE;          return TRUE;
5679  }  }
# Line 5534  static BOOL handle_SSH2_channel_eof(PTIn Line 5681  static BOOL handle_SSH2_channel_eof(PTIn
5681    
5682  static BOOL handle_SSH2_channel_close(PTInstVar pvar)  static BOOL handle_SSH2_channel_close(PTInstVar pvar)
5683  {        {      
5684            int len;
5685            char *data;
5686            int id;
5687            Channel_t *c;
5688          buffer_t *msg;          buffer_t *msg;
5689          char *s;          char *s;
5690          unsigned char *outmsg;          unsigned char *outmsg;
         int len;  
5691    
5692          msg = buffer_init();          // 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード
5693          if (msg == NULL) {          data = pvar->ssh_state.payload;
5694                  // TODO: error check          // パケットサイズ - (パディングサイズ+1);真のパケットサイズ
5695            len = pvar->ssh_state.payloadlen;
5696    
5697            id = get_uint32_MSBfirst(data);
5698            data += 4;
5699            c = ssh2_channel_lookup(id);
5700            if (c == NULL) {
5701                    // TODO:
5702                  return FALSE;                  return FALSE;
5703          }          }
         buffer_put_int(msg, SSH2_DISCONNECT_PROTOCOL_ERROR);    
         s = "disconnected by server request";  
         buffer_put_string(msg, s, strlen(s));    
         s = "";  
         buffer_put_string(msg, s, strlen(s));    
5704    
5705          len = buffer_len(msg);          if (c->type == TYPE_SHELL) {
5706          outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len);                  msg = buffer_init();
5707          memcpy(outmsg, buffer_ptr(msg), len);                  if (msg == NULL) {
5708          finish_send_packet(pvar);                          // TODO: error check
5709          buffer_free(msg);                          return FALSE;
5710                    }
5711                    buffer_put_int(msg, SSH2_DISCONNECT_PROTOCOL_ERROR);  
5712                    s = "disconnected by server request";
5713                    buffer_put_string(msg, s, strlen(s));  
5714                    s = "";
5715                    buffer_put_string(msg, s, strlen(s));  
5716    
5717          // TCP connection closed                  len = buffer_len(msg);
5718          notify_closed_connection(pvar);                  outmsg = begin_send_packet(pvar, SSH2_MSG_DISCONNECT, len);
5719                    memcpy(outmsg, buffer_ptr(msg), len);
5720                    finish_send_packet(pvar);
5721                    buffer_free(msg);
5722    
5723                    // TCP connection closed
5724                    notify_closed_connection(pvar);
5725            }
5726    
5727          return TRUE;          return TRUE;
5728  }  }
# Line 5670  static BOOL handle_SSH2_window_adjust(PT Line 5835  static BOOL handle_SSH2_window_adjust(PT
5835    
5836  /*  /*
5837   * $Log: not supported by cvs2svn $   * $Log: not supported by cvs2svn $
5838     * Revision 1.26  2005/04/08 14:55:03  yutakakn
5839     * "Duplicate session"においてSSH自動ログインを行うようにした。
5840     *
5841   * Revision 1.25  2005/04/03 14:39:48  yutakakn   * Revision 1.25  2005/04/03 14:39:48  yutakakn
5842   * SSH2 channel lookup機構の追加(ポートフォワーディングのため)。   * SSH2 channel lookup機構の追加(ポートフォワーディングのため)。
5843   * TTSSH 2.10で追加したlog dump機構において、DH鍵再作成時にbuffer freeで   * TTSSH 2.10で追加したlog dump機構において、DH鍵再作成時にbuffer freeで

Legend:
Removed from v.2811  
changed lines
  Added in v.2823

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