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 2830 by yutakakn, Sun Jul 3 13:32:00 2005 UTC revision 2833 by yutakakn, Sat Jul 9 17:08:47 2005 UTC
# Line 609  static int prep_packet(PTInstVar pvar, c Line 609  static int prep_packet(PTInstVar pvar, c
609    
610          pvar->ssh_state.payload_grabbed = 0;          pvar->ssh_state.payload_grabbed = 0;
611    
612          if (pvar->ssh_state.decompressing) {          if (SSHv1(pvar)) {
613                  if (pvar->ssh_state.decompress_stream.avail_in != 0) {                  if (pvar->ssh_state.decompressing) {
614                          notify_nonfatal_error(pvar,                          if (pvar->ssh_state.decompress_stream.avail_in != 0) {
615                                                                    "Internal error: a packet was not fully decompressed.\n"                                  notify_nonfatal_error(pvar,
616                                                                    "This is a bug, please report it.");                                                                          "Internal error: a packet was not fully decompressed.\n"
617                                                                            "This is a bug, please report it.");
618                            }
619    
620                            pvar->ssh_state.decompress_stream.next_in =
621                                    pvar->ssh_state.payload;
622                            pvar->ssh_state.decompress_stream.avail_in =
623                                    pvar->ssh_state.payloadlen;
624                            pvar->ssh_state.decompress_stream.next_out =
625                                    pvar->ssh_state.postdecompress_inbuf;
626                            pvar->ssh_state.payloadlen = -1;
627                    } else {
628                            pvar->ssh_state.payload++;
629                    }
630    
631                    if (!grab_payload_limited(pvar, 1)) {
632                            return SSH_MSG_NONE;
633                  }                  }
634    
                 pvar->ssh_state.decompress_stream.next_in =  
                         pvar->ssh_state.payload;  
                 pvar->ssh_state.decompress_stream.avail_in =  
                         pvar->ssh_state.payloadlen;  
                 pvar->ssh_state.decompress_stream.next_out =  
                         pvar->ssh_state.postdecompress_inbuf;  
                 pvar->ssh_state.payloadlen = -1;  
635          } else {          } else {
636                  pvar->ssh_state.payload++;                  // support of SSH2 packet compression (2005.7.9 yutaka)
637          }                  if (pvar->stoc_compression && pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled
638                            int ret;
639    
640                            if (pvar->decomp_buffer == NULL) {
641                                    pvar->decomp_buffer = buffer_init();
642                                    if (pvar->decomp_buffer == NULL)
643                                            return SSH_MSG_NONE;
644                            }
645                            // 一度確保したバッファは使い回すので初期化を忘れずに。
646                            buffer_clear(pvar->decomp_buffer);
647    
648                            // packet sizeとpaddingを取り除いたペイロード部分のみを展開する。
649                            ret = buffer_decompress(&pvar->ssh_state.decompress_stream,
650                                    pvar->ssh_state.payload, pvar->ssh_state.payloadlen, pvar->decomp_buffer);
651    
652                            // ポインタの更新。
653                            pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
654                            pvar->ssh_state.payload++;
655                            pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
656    
657                    } else {
658                            pvar->ssh_state.payload++;
659                    }
660    
661                    if (!grab_payload_limited(pvar, 1)) {
662                            return SSH_MSG_NONE;
663                    }
664    
         if (!grab_payload_limited(pvar, 1)) {  
                 return SSH_MSG_NONE;  
665          }          }
666    
667          pvar->ssh_state.receiver_sequence_number++;          pvar->ssh_state.receiver_sequence_number++;
# Line 699  static void finish_send_packet_special(P Line 732  static void finish_send_packet_special(P
732          int len = pvar->ssh_state.outgoing_packet_len;          int len = pvar->ssh_state.outgoing_packet_len;
733          char FAR *data;          char FAR *data;
734          int data_length;          int data_length;
735            buffer_t *msg = NULL; // for SSH2 packet compression
736    
737          if (pvar->ssh_state.compressing) {          if (pvar->ssh_state.compressing) {
738                  if (!skip_compress) {                  if (!skip_compress) {
# Line 749  static void finish_send_packet_special(P Line 783  static void finish_send_packet_special(P
783                  int padding;                  int padding;
784                  BOOL ret;                  BOOL ret;
785    
786                    /*
787                     データ構造
788                     pvar->ssh_state.outbuf:
789                     offset: 0 1 2 3 4 5 6 7 8 9 10 11 12 ...         EOD
790                             <--ignore---> ^^^^^^^^    <---- payload --->  
791                                                   packet length
792    
793                                                                        ^^padding
794    
795                                                               <---------------------------->
796                                                                  SSH2 sending data on TCP
797                    
798                     NOTE:
799                       payload = type(1) + raw-data
800                       len = ssh_state.outgoing_packet_len = payload size
801                     */
802                    // パケット圧縮が有効の場合、パケットを圧縮してから送信パケットを構築する。(2005.7.9 yutaka)
803                    if (pvar->ctos_compression && pvar->ssh2_keys[MODE_OUT].comp.enabled) {
804                            // このバッファは packet-length(4) + padding(1) + payload(any) を示す。
805                            msg = buffer_init();
806                            if (msg == NULL) {
807                                    // TODO: error check
808                                    return;
809                            }
810    
811                            // 圧縮対象はヘッダを除くペイロードのみ。
812                            buffer_append(msg, "\0\0\0\0\0", 5);  // 5 = packet-length(4) + padding(1)
813                            if (buffer_compress(&pvar->ssh_state.compress_stream, pvar->ssh_state.outbuf + 12, len, msg) == -1) {
814                                    notify_fatal_error(pvar,
815                                                                       "An error occurred while compressing packet data.\n"
816                                                                       "The connection will close.");
817                                    return;
818                            }
819                            data = buffer_ptr(msg);
820                            len = buffer_len(msg) - 5;  // 'len' is overwritten.
821    
822                    } else {
823                            // 無圧縮
824                            data = pvar->ssh_state.outbuf + 7;
825    
826                    }
827    
828                    // 送信パケット構築(input parameter: data, len)
829                  if (block_size < 8) {                  if (block_size < 8) {
830                          block_size = 8;                          block_size = 8;
831                  }                  }
832                  encryption_size = ((len + 8) / block_size + 1) * block_size;                  encryption_size = ((len + 8) / block_size + 1) * block_size;
                 data = pvar->ssh_state.outbuf + 7;  
833                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);                  data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
834    
835                  set_uint32(data, encryption_size - 4);                  set_uint32(data, encryption_size - 4);
# Line 774  static void finish_send_packet_special(P Line 850  static void finish_send_packet_special(P
850    
851          send_packet_blocking(pvar, data, data_length);          send_packet_blocking(pvar, data, data_length);
852    
853            buffer_free(msg);
854    
855          pvar->ssh_state.sender_sequence_number++;          pvar->ssh_state.sender_sequence_number++;
856    
857          // 送信時刻を記録          // 送信時刻を記録
# Line 1717  static void enable_compression(PTInstVar Line 1795  static void enable_compression(PTInstVar
1795                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,                  buf_ensure_size(&pvar->ssh_state.postdecompress_inbuf,
1796                                                  &pvar->ssh_state.postdecompress_inbuflen, 1000);                                                  &pvar->ssh_state.postdecompress_inbuflen, 1000);
1797          }          }
1798    
1799            // SSH2では圧縮・展開処理をSSH1とは別に行うので、下記フラグは落としておく。(2005.7.9 yutaka)
1800            if (SSHv2(pvar)) {
1801                    pvar->ssh_state.compressing = FALSE;
1802                    pvar->ssh_state.decompressing = FALSE;
1803            }
1804    
1805  }  }
1806    
1807  static BOOL handle_enable_compression(PTInstVar pvar)  static BOOL handle_enable_compression(PTInstVar pvar)
# Line 1735  static BOOL handle_disable_compression(P Line 1820  static BOOL handle_disable_compression(P
1820  static void prep_compression(PTInstVar pvar)  static void prep_compression(PTInstVar pvar)
1821  {  {
1822          if (pvar->session_settings.CompressionLevel > 0) {          if (pvar->session_settings.CompressionLevel > 0) {
1823                  static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };                  // added if statement (2005.7.10 yutaka)
1824                  static const SSHPacketHandler handlers[]                  if (SSHv1(pvar)) {
1825                  = { handle_enable_compression, handle_disable_compression };                          static const int msgs[] = { SSH_SMSG_SUCCESS, SSH_SMSG_FAILURE };
1826                            static const SSHPacketHandler handlers[]
1827                            = { handle_enable_compression, handle_disable_compression };
1828    
1829                  unsigned char FAR *outmsg =                          unsigned char FAR *outmsg =
1830                          begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);                                  begin_send_packet(pvar, SSH_CMSG_REQUEST_COMPRESSION, 4);
1831    
1832                  set_uint32(outmsg, pvar->session_settings.CompressionLevel);                          set_uint32(outmsg, pvar->session_settings.CompressionLevel);
1833                  finish_send_packet(pvar);                          finish_send_packet(pvar);
1834    
1835                            enque_handlers(pvar, 2, msgs, handlers);
1836                    }
1837    
1838                  pvar->ssh_state.compression_level =                  pvar->ssh_state.compression_level =
1839                          pvar->session_settings.CompressionLevel;                          pvar->session_settings.CompressionLevel;
1840    
                 enque_handlers(pvar, 2, msgs, handlers);  
1841          } else {          } else {
1842                  prep_forwarding(pvar);                  // added if statement (2005.7.10 yutaka)
1843                    if (SSHv1(pvar)) {
1844                            prep_forwarding(pvar);
1845                    }
1846          }          }
1847  }  }
1848    
# Line 2065  void SSH_init(PTInstVar pvar) Line 2157  void SSH_init(PTInstVar pvar)
2157          pvar->key_done = 0;          pvar->key_done = 0;
2158          pvar->ssh2_autologin = 0;  // autologin disabled(default)          pvar->ssh2_autologin = 0;  // autologin disabled(default)
2159          pvar->userauth_retry_count = 0;          pvar->userauth_retry_count = 0;
2160            pvar->decomp_buffer = NULL;
2161    
2162  }  }
2163    
# Line 2348  void SSH_get_compression_info(PTInstVar Line 2441  void SSH_get_compression_info(PTInstVar
2441          char buf[1024];          char buf[1024];
2442          char buf2[1024];          char buf2[1024];
2443    
2444          if (pvar->ssh_state.compressing) {          // added support of SSH2 packet compression (2005.7.10 yutaka)
2445            if (pvar->ssh_state.compressing || pvar->ctos_compression) {
2446                  unsigned long total_in = pvar->ssh_state.compress_stream.total_in;                  unsigned long total_in = pvar->ssh_state.compress_stream.total_in;
2447                  unsigned long total_out =                  unsigned long total_out =
2448                          pvar->ssh_state.compress_stream.total_out;                          pvar->ssh_state.compress_stream.total_out;
# Line 2367  void SSH_get_compression_info(PTInstVar Line 2461  void SSH_get_compression_info(PTInstVar
2461          }          }
2462          buf[sizeof(buf) - 1] = 0;          buf[sizeof(buf) - 1] = 0;
2463    
2464          if (pvar->ssh_state.decompressing) {          if (pvar->ssh_state.decompressing || pvar->stoc_compression) {
2465                  unsigned long total_in =                  unsigned long total_in =
2466                          pvar->ssh_state.decompress_stream.total_in;                          pvar->ssh_state.decompress_stream.total_in;
2467                  unsigned long total_out =                  unsigned long total_out =
# Line 2485  void SSH_end(PTInstVar pvar) Line 2579  void SSH_end(PTInstVar pvar)
2579                  pvar->session_nego_status = 0;                  pvar->session_nego_status = 0;
2580    
2581                  pvar->ssh_heartbeat_tick = 0;                  pvar->ssh_heartbeat_tick = 0;
2582    
2583                    if (pvar->decomp_buffer != NULL) {
2584                            buffer_free(pvar->decomp_buffer);
2585                            pvar->decomp_buffer = NULL;
2586                    }
2587          }          }
2588  #endif  #endif
2589    
# Line 2972  static char *myproposal[PROPOSAL_MAX] = Line 3071  static char *myproposal[PROPOSAL_MAX] =
3071  //      "hmac-sha1,hmac-md5",  //      "hmac-sha1,hmac-md5",
3072  //      "hmac-sha1",  //      "hmac-sha1",
3073  //      "hmac-sha1",  //      "hmac-sha1",
3074          "none",          "none,zlib",
3075          "none",          "none,zlib",
3076          "",          "",
3077          "",          "",
3078  };  };
# Line 2985  static char *myproposal[PROPOSAL_MAX] = Line 3084  static char *myproposal[PROPOSAL_MAX] =
3084          "3des-cbc,aes128-cbc",          "3des-cbc,aes128-cbc",
3085          "hmac-sha1,hmac-md5",          "hmac-sha1,hmac-md5",
3086          "hmac-sha1,hmac-md5",          "hmac-sha1,hmac-md5",
3087          "none",          "none,zlib",
3088          "none",          "none,zlib",
3089          "",          "",
3090          "",          "",
3091  };  };
# Line 3137  void SSH2_update_cipher_myproposal(PTIns Line 3236  void SSH2_update_cipher_myproposal(PTIns
3236  }  }
3237    
3238    
3239    void SSH2_update_compression_myproposal(PTInstVar pvar)
3240    {
3241            static char buf[128]; // TODO: malloc()にすべき
3242    
3243            // 圧縮レベルに応じて、myproposal[]を書き換える。(2005.7.9 yutaka)
3244            buf[0] = '\0';
3245            if (pvar->ts_SSH->CompressionLevel > 0) {
3246                    _snprintf(buf, sizeof(buf), "zlib,none");
3247            }
3248            if (buf[0] != '\0') {
3249                    myproposal[PROPOSAL_COMP_ALGS_CTOS] = buf;  // Client To Server
3250                    myproposal[PROPOSAL_COMP_ALGS_STOC] = buf;  // Server To Client
3251            }
3252    }
3253    
3254    
3255  // クライアントからサーバへのキー交換開始要求  // クライアントからサーバへのキー交換開始要求
3256  void SSH2_send_kexinit(PTInstVar pvar)  void SSH2_send_kexinit(PTInstVar pvar)
3257  {  {
# Line 3230  static enum hmac_type choose_SSH2_hmac_a Line 3345  static enum hmac_type choose_SSH2_hmac_a
3345  }  }
3346    
3347    
3348    static int choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal)
3349    {
3350            char tmp[1024], *ptr;
3351            int ret = -1;
3352    
3353            _snprintf(tmp, sizeof(tmp), my_proposal);
3354            ptr = strtok(tmp, ","); // not thread-safe
3355            while (ptr != NULL) {
3356                    // server_proposalにはサーバのproposalがカンマ文字列で格納されている
3357                    if (strstr(server_proposal, ptr)) { // match
3358                            break;
3359                    }
3360                    ptr = strtok(NULL, ",");
3361            }
3362            if (strstr(ptr, "zlib")) {
3363                    ret = 1; // packet compression enabled
3364            } else if (strstr(ptr, "none")) {
3365                    ret = 0; // packet compression disabled
3366            }
3367    
3368            return (ret);
3369    }
3370    
3371  // 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。  // 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。
3372  static void choose_SSH2_key_maxlength(PTInstVar pvar)  static void choose_SSH2_key_maxlength(PTInstVar pvar)
3373  {  {
# Line 3265  static void choose_SSH2_key_maxlength(PT Line 3403  static void choose_SSH2_key_maxlength(PT
3403                          current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher);                          current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher);
3404                  }                  }
3405                  current_keys[mode].mac.enabled = 0;                  current_keys[mode].mac.enabled = 0;
3406                    current_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka)
3407    
3408                  // 現時点ではMACはdisable                  // 現時点ではMACはdisable
3409                  pvar->ssh2_keys[mode].mac.enabled = 0;                  pvar->ssh2_keys[mode].mac.enabled = 0;
3410                    pvar->ssh2_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka)
3411          }          }
3412          need = 0;          need = 0;
3413          for (mode = 0; mode < MODE_MAX; mode++) {          for (mode = 0; mode < MODE_MAX; mode++) {
# Line 3503  static BOOL handle_SSH2_kexinit(PTInstVa Line 3643  static BOOL handle_SSH2_kexinit(PTInstVa
3643          }          }
3644    
3645    
3646            // 圧縮アルゴリズムの決定
3647            // pvar->ssh_state.compressing = FALSE; として下記メンバを使用する。
3648            // (2005.7.9 yutaka)
3649            size = get_payload_uint32(pvar, offset);
3650            offset += 4;
3651            for (i = 0; i < size; i++) {
3652                    buf[i] = data[offset + i];
3653            }
3654            buf[i] = 0;
3655            offset += size;
3656            pvar->ctos_compression = choose_SSH2_compression_algorithm(buf, myproposal[PROPOSAL_COMP_ALGS_CTOS]);
3657            if (pvar->ctos_compression == -1) { // not match
3658                    strcpy(tmp, "unknown Packet Compression algorithm: ");
3659                    strcat(tmp, buf);
3660                    msg = tmp;
3661                    goto error;
3662            }
3663    
3664            size = get_payload_uint32(pvar, offset);
3665            offset += 4;
3666            for (i = 0; i < size; i++) {
3667                    buf[i] = data[offset + i];
3668            }
3669            buf[i] = 0;
3670            offset += size;
3671            pvar->stoc_compression = choose_SSH2_compression_algorithm(buf, myproposal[PROPOSAL_COMP_ALGS_STOC]);
3672            if (pvar->stoc_compression == -1) { // not match
3673                    strcpy(tmp, "unknown Packet Compression algorithm: ");
3674                    strcat(tmp, buf);
3675                    msg = tmp;
3676                    goto error;
3677            }
3678    
3679    
3680          // we_needの決定 (2004.11.6 yutaka)          // we_needの決定 (2004.11.6 yutaka)
3681          // キー再作成の場合はスキップする。          // キー再作成の場合はスキップする。
3682          if (pvar->rekeying == 0) {          if (pvar->rekeying == 0) {
# Line 4450  static BOOL handle_SSH2_dh_kex_reply(PTI Line 4624  static BOOL handle_SSH2_dh_kex_reply(PTI
4624                  // まず、送信用だけ設定する。                  // まず、送信用だけ設定する。
4625                  ssh2_set_newkeys(pvar, MODE_OUT);                  ssh2_set_newkeys(pvar, MODE_OUT);
4626                  pvar->ssh2_keys[MODE_OUT].mac.enabled = 1;                  pvar->ssh2_keys[MODE_OUT].mac.enabled = 1;
4627                    pvar->ssh2_keys[MODE_OUT].comp.enabled = 1;
4628                  if (!CRYPT_start_encryption(pvar, 1, 0)) {                  if (!CRYPT_start_encryption(pvar, 1, 0)) {
4629                          // TODO: error                          // TODO: error
4630                  }                  }
# Line 4762  static BOOL handle_SSH2_dh_gex_reply(PTI Line 4937  static BOOL handle_SSH2_dh_gex_reply(PTI
4937                  // まず、送信用だけ設定する。                  // まず、送信用だけ設定する。
4938                  ssh2_set_newkeys(pvar, MODE_OUT);                  ssh2_set_newkeys(pvar, MODE_OUT);
4939                  pvar->ssh2_keys[MODE_OUT].mac.enabled = 1;                  pvar->ssh2_keys[MODE_OUT].mac.enabled = 1;
4940                    pvar->ssh2_keys[MODE_OUT].comp.enabled = 1;
4941                  if (!CRYPT_start_encryption(pvar, 1, 0)) {                  if (!CRYPT_start_encryption(pvar, 1, 0)) {
4942                          // TODO: error                          // TODO: error
4943                  }                  }
# Line 4852  static BOOL handle_SSH2_newkeys(PTInstVa Line 5028  static BOOL handle_SSH2_newkeys(PTInstVa
5028                  // かつ、受信用の暗号鍵の再設定をここで行う。                  // かつ、受信用の暗号鍵の再設定をここで行う。
5029                  ssh2_set_newkeys(pvar, MODE_IN);                  ssh2_set_newkeys(pvar, MODE_IN);
5030                  pvar->ssh2_keys[MODE_IN].mac.enabled = 1;                  pvar->ssh2_keys[MODE_IN].mac.enabled = 1;
5031                    pvar->ssh2_keys[MODE_IN].comp.enabled = 1;
5032                  if (!CRYPT_start_encryption(pvar, 0, 1)) {                  if (!CRYPT_start_encryption(pvar, 0, 1)) {
5033                          // TODO: error                          // TODO: error
5034                  }                  }
# Line 4895  BOOL do_SSH2_userauth(PTInstVar pvar) Line 5072  BOOL do_SSH2_userauth(PTInstVar pvar)
5072    
5073          for (mode = 0 ; mode < MODE_MAX ; mode++) {          for (mode = 0 ; mode < MODE_MAX ; mode++) {
5074                  pvar->ssh2_keys[mode].mac.enabled = 1;                  pvar->ssh2_keys[mode].mac.enabled = 1;
5075                    pvar->ssh2_keys[mode].comp.enabled = 1;
5076          }          }
5077            // パケット圧縮が有効なら初期化する。(2005.7.9 yutaka)
5078            prep_compression(pvar);
5079            enable_compression(pvar);
5080    
5081          // start user authentication          // start user authentication
5082          msg = buffer_init();          msg = buffer_init();
# Line 6150  static BOOL handle_SSH2_window_adjust(PT Line 6331  static BOOL handle_SSH2_window_adjust(PT
6331    
6332  /*  /*
6333   * $Log: not supported by cvs2svn $   * $Log: not supported by cvs2svn $
6334     * Revision 1.33  2005/07/03 13:32:00  yutakakn
6335     * SSH2 port-forwardingの初期化タイミングを変更。
6336     *
6337   * Revision 1.32  2005/07/03 12:07:53  yutakakn   * Revision 1.32  2005/07/03 12:07:53  yutakakn
6338   * SSH2 X Window Systemのport forwardingをサポートした。   * SSH2 X Window Systemのport forwardingをサポートした。
6339   *   *

Legend:
Removed from v.2830  
changed lines
  Added in v.2833

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