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 6967 by doda, Thu Nov 2 11:37:33 2017 UTC revision 6968 by doda, Thu Nov 2 11:37:37 2017 UTC
# Line 726  static BOOL grab_payload_limited(PTInstV Line 726  static BOOL grab_payload_limited(PTInstV
726   * 'len' is the length of the * payload + padding (+ length of CRC for SSHv1).   * 'len' is the length of the * payload + padding (+ length of CRC for SSHv1).
727   * 'padding' is the length of the padding alone.   * 'padding' is the length of the padding alone.
728   */   */
729  static int prep_packet(PTInstVar pvar, char *data, int len, int padding)  static int prep_packet_ssh1(PTInstVar pvar, char *data, int len, int padding)
730  {  {
731          pvar->ssh_state.payload = data + 4;          pvar->ssh_state.payload = data + 4;
732          pvar->ssh_state.payloadlen = len;          pvar->ssh_state.payloadlen = len;
733    
734          if (SSHv1(pvar)) {          if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {
735                  if (CRYPT_detect_attack(pvar, pvar->ssh_state.payload, len)) {                  UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, "'CORE insertion attack' detected.  Aborting connection.");
736                          UTIL_get_lang_msg("MSG_SSH_COREINS_ERROR", pvar, "'CORE insertion attack' detected.  Aborting connection.");                  notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
737                          notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);          }
                 }  
738    
739                  CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);          CRYPT_decrypt(pvar, pvar->ssh_state.payload, len);
740                  /* PKT guarantees that the data is always 4-byte aligned */          /* PKT guarantees that the data is always 4-byte aligned */
741                  if (do_crc(pvar->ssh_state.payload, len - 4) != get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {          if (do_crc(pvar->ssh_state.payload, len - 4) != get_uint32_MSBfirst(pvar->ssh_state.payload + len - 4)) {
742                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");                  UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
743                          notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);                  notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
744                          return SSH_MSG_NONE;                  return SSH_MSG_NONE;
745                  }          }
746    
747                  pvar->ssh_state.payload += padding;          pvar->ssh_state.payload += padding;
748                  pvar->ssh_state.payloadlen -= padding + 4;          pvar->ssh_state.payloadlen -= padding + 4;
         } else {  
                 int already_decrypted = get_predecryption_amount(pvar);  
749    
750                  CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);          pvar->ssh_state.payload_grabbed = 0;
751    
752                  if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {          if (pvar->ssh_state.decompressing) {
753                          UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar,                  if (pvar->ssh_state.decompress_stream.avail_in != 0) {
754                                            "Detected corrupted data; connection terminating.");                          UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,
755                          notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);                                            "Internal error: a packet was not fully decompressed.\n"
756                          return SSH_MSG_NONE;                                            "This is a bug, please report it.");
757                            notify_nonfatal_error(pvar, pvar->ts->UIMsg);
758                  }                  }
759    
760                    pvar->ssh_state.decompress_stream.next_in = pvar->ssh_state.payload;
761                    pvar->ssh_state.decompress_stream.avail_in = pvar->ssh_state.payloadlen;
762                    pvar->ssh_state.decompress_stream.next_out = pvar->ssh_state.postdecompress_inbuf;
763                    pvar->ssh_state.payloadlen = -1;
764            } else {
765                  pvar->ssh_state.payload++;                  pvar->ssh_state.payload++;
                 pvar->ssh_state.payloadlen -= padding + 1;  
766          }          }
767    
768          pvar->ssh_state.payload_grabbed = 0;          if (!grab_payload_limited(pvar, 1)) {
769                    return SSH_MSG_NONE;
770            }
771    
772          if (SSHv1(pvar)) {          pvar->ssh_state.receiver_sequence_number++;
                 if (pvar->ssh_state.decompressing) {  
                         if (pvar->ssh_state.decompress_stream.avail_in != 0) {  
                                 UTIL_get_lang_msg("MSG_SSH_DECOMPRESS_ERROR", pvar,  
                                                   "Internal error: a packet was not fully decompressed.\n"  
                                                   "This is a bug, please report it.");  
                                 notify_nonfatal_error(pvar, pvar->ts->UIMsg);  
                         }  
773    
774                          pvar->ssh_state.decompress_stream.next_in = pvar->ssh_state.payload;          return pvar->ssh_state.payload[-1];
775                          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;  
                 } else {  
                         pvar->ssh_state.payload++;  
                 }  
776    
777                  if (!grab_payload_limited(pvar, 1)) {  static int prep_packet_ssh2(PTInstVar pvar, char *data, int len, int padding)
778                          return SSH_MSG_NONE;  {
779                  }          int already_decrypted = get_predecryption_amount(pvar);
780    
781          } else {          pvar->ssh_state.payload = data + 4;
782                  // support of SSH2 packet compression (2005.7.9 yutaka)          pvar->ssh_state.payloadlen = len;
                 // support of "Compression delayed" (2006.6.23 maya)  
                 if ((pvar->stoc_compression == COMP_ZLIB ||  
                      pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success) &&  
                     pvar->ssh2_keys[MODE_IN].comp.enabled) { // compression enabled  
                         int ret;  
   
                         if (pvar->decomp_buffer == NULL) {  
                                 pvar->decomp_buffer = buffer_init();  
                                 if (pvar->decomp_buffer == NULL)  
                                         return SSH_MSG_NONE;  
                         }  
                         // 一度確保したバッファは使い回すので初期化を忘れずに。  
                         buffer_clear(pvar->decomp_buffer);  
783    
784                          // packet sizeとpaddingを取り除いたペイロード部分のみを展開する。          CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
                         ret = buffer_decompress(&pvar->ssh_state.decompress_stream,  
                                                 pvar->ssh_state.payload,  
                                                 pvar->ssh_state.payloadlen,  
                                                 pvar->decomp_buffer);  
   
                         // ポインタの更新。  
                         pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);  
                         pvar->ssh_state.payload++;  
                         pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);  
785    
786                  } else {          if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
787                          pvar->ssh_state.payload++;                  UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
788                  }                  notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
789                    return SSH_MSG_NONE;
790            }
791    
792                  if (!grab_payload_limited(pvar, 1)) {          pvar->ssh_state.payload++;
793                          return SSH_MSG_NONE;          pvar->ssh_state.payloadlen -= padding + 1;
                 }  
794    
795            pvar->ssh_state.payload_grabbed = 0;
796    
797            // data compression
798            if (pvar->ssh2_keys[MODE_IN].comp.enabled &&
799               (pvar->stoc_compression == COMP_ZLIB ||
800                pvar->stoc_compression == COMP_DELAYED && pvar->userauth_success)) {
801    
802                    if (pvar->decomp_buffer == NULL) {
803                            pvar->decomp_buffer = buffer_init();
804                            if (pvar->decomp_buffer == NULL)
805                                    return SSH_MSG_NONE;
806                    }
807                    // 一度確保したバッファは使い回すので初期化を忘れずに。
808                    buffer_clear(pvar->decomp_buffer);
809    
810                    // packet sizeとpaddingを取り除いたペイロード部分のみを展開する。
811                    buffer_decompress(&pvar->ssh_state.decompress_stream,
812                                      pvar->ssh_state.payload,
813                                      pvar->ssh_state.payloadlen,
814                                      pvar->decomp_buffer);
815    
816                    // ポインタの更新。
817                    pvar->ssh_state.payload = buffer_ptr(pvar->decomp_buffer);
818                    pvar->ssh_state.payload++;
819                    pvar->ssh_state.payloadlen = buffer_len(pvar->decomp_buffer);
820            } else {
821                    pvar->ssh_state.payload++;
822            }
823    
824            if (!grab_payload_limited(pvar, 1)) {
825                    return SSH_MSG_NONE;
826          }          }
827    
828          pvar->ssh_state.receiver_sequence_number++;          pvar->ssh_state.receiver_sequence_number++;
# Line 2034  void SSH2_dispatch_add_range_message(uns Line 2036  void SSH2_dispatch_add_range_message(uns
2036  }  }
2037    
2038    
2039  void SSH_handle_packet(PTInstVar pvar, char *data, int len, int padding)  void SSH_handle_packet1(PTInstVar pvar, char *data, int len, int padding)
2040  {  {
2041          unsigned char message = prep_packet(pvar, data, len, padding);          unsigned char message = prep_packet_ssh1(pvar, data, len, padding);
2042    
2043          // SSHのメッセージタイプをチェック          // SSHのメッセージタイプをチェック
2044          if (message != SSH_MSG_NONE) {          if (message != SSH_MSG_NONE) {
2045                  // メッセージタイプに応じたハンドラを起動                  // メッセージタイプに応じたハンドラを起動
2046                  SSHPacketHandler handler = get_handler(pvar, message);                  SSHPacketHandler handler = get_handler(pvar, message);
2047    
2048                  // for SSH2(yutaka)                  if (handler == NULL) {
2049                  if (SSHv2(pvar)) {                          char buf[1024];
2050                          // 想定外のメッセージタイプが到着したらアボートさせる。  
2051                          if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {                          UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");
2052                                  char buf[1024];                          _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2053                            notify_fatal_error(pvar, buf, TRUE);
2054                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");                  } else {
2055                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);                          if (!handler(pvar)) {
2056                                  notify_fatal_error(pvar, buf, TRUE);                                  deque_handlers(pvar, message);
                                 return;  
2057                          }                          }
2058                  }                  }
2059            }
2060    }
2061    
2062    void SSH_handle_packet2(PTInstVar pvar, char *data, int len, int padding)
2063    {
2064            unsigned char message = prep_packet_ssh2(pvar, data, len, padding);
2065    
2066            // SSHのメッセージタイプをチェック
2067            if (message != SSH_MSG_NONE) {
2068                    // メッセージタイプに応じたハンドラを起動
2069                    SSHPacketHandler handler = get_handler(pvar, message);
2070    
2071                    // 想定外のメッセージタイプが到着したらアボートさせる。
2072                    if (!SSH2_dispatch_enabled_check(message) || handler == NULL) {
2073                            char buf[1024];
2074    
2075                            UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG2_ERROR", pvar, "Unexpected SSH2 message(%d) on current stage(%d)");
2076                            _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);
2077                            notify_fatal_error(pvar, buf, TRUE);
2078                            return;
2079                    }
2080    
2081                  if (handler == NULL) {                  if (handler == NULL) {
2082                          if (SSHv1(pvar)) {                          unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);
                                 char buf[1024];  
2083    
2084                                  UTIL_get_lang_msg("MSG_SSH_UNEXP_MSG_ERROR", pvar, "Unexpected packet type received: %d");                          set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);
2085                                  _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, message, handle_message_stage);                          finish_send_packet(pvar);
                                 notify_fatal_error(pvar, buf, TRUE);  
                         } else {  
                                 unsigned char *outmsg = begin_send_packet(pvar, SSH2_MSG_UNIMPLEMENTED, 4);  
   
                                 set_uint32(outmsg, pvar->ssh_state.receiver_sequence_number - 1);  
                                 finish_send_packet(pvar);  
2086    
2087                                  logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_UNIMPLEMENTED was sent at SSH_handle_packet().");                          logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_UNIMPLEMENTED was sent.");
2088                                  /* XXX need to decompress incoming packet, but how? */                          /* XXX need to decompress incoming packet, but how? */
                         }  
2089                  } else {                  } else {
2090                          if (!handler(pvar)) {                          if (!handler(pvar)) {
2091                                  deque_handlers(pvar, message);                                  deque_handlers(pvar, message);

Legend:
Removed from v.6967  
changed lines
  Added in v.6968

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