diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 79 |
1 files changed, 54 insertions, 25 deletions
@@ -1,3 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.145 2006/09/19 21:14:08 markus Exp $ */ | ||
1 | /* | 2 | /* |
2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -37,26 +38,39 @@ | |||
37 | */ | 38 | */ |
38 | 39 | ||
39 | #include "includes.h" | 40 | #include "includes.h" |
40 | RCSID("$OpenBSD: packet.c,v 1.120 2005/10/30 08:52:17 djm Exp $"); | 41 | |
41 | 42 | #include <sys/types.h> | |
42 | #include "openbsd-compat/sys-queue.h" | 43 | #include "openbsd-compat/sys-queue.h" |
44 | #include <sys/param.h> | ||
45 | #include <sys/socket.h> | ||
46 | #ifdef HAVE_SYS_TIME_H | ||
47 | # include <sys/time.h> | ||
48 | #endif | ||
49 | |||
50 | #include <netinet/in.h> | ||
51 | #include <netinet/ip.h> | ||
52 | #include <arpa/inet.h> | ||
53 | |||
54 | #include <errno.h> | ||
55 | #include <stdarg.h> | ||
56 | #include <stdio.h> | ||
57 | #include <stdlib.h> | ||
58 | #include <string.h> | ||
59 | #include <unistd.h> | ||
60 | #include <signal.h> | ||
43 | 61 | ||
44 | #include "xmalloc.h" | 62 | #include "xmalloc.h" |
45 | #include "buffer.h" | 63 | #include "buffer.h" |
46 | #include "packet.h" | 64 | #include "packet.h" |
47 | #include "bufaux.h" | ||
48 | #include "crc32.h" | 65 | #include "crc32.h" |
49 | #include "getput.h" | ||
50 | |||
51 | #include "compress.h" | 66 | #include "compress.h" |
52 | #include "deattack.h" | 67 | #include "deattack.h" |
53 | #include "channels.h" | 68 | #include "channels.h" |
54 | |||
55 | #include "compat.h" | 69 | #include "compat.h" |
56 | #include "ssh1.h" | 70 | #include "ssh1.h" |
57 | #include "ssh2.h" | 71 | #include "ssh2.h" |
58 | |||
59 | #include "cipher.h" | 72 | #include "cipher.h" |
73 | #include "key.h" | ||
60 | #include "kex.h" | 74 | #include "kex.h" |
61 | #include "mac.h" | 75 | #include "mac.h" |
62 | #include "log.h" | 76 | #include "log.h" |
@@ -258,6 +272,7 @@ packet_get_keyiv_len(int mode) | |||
258 | 272 | ||
259 | return (cipher_get_keyiv_len(cc)); | 273 | return (cipher_get_keyiv_len(cc)); |
260 | } | 274 | } |
275 | |||
261 | void | 276 | void |
262 | packet_set_iv(int mode, u_char *dat) | 277 | packet_set_iv(int mode, u_char *dat) |
263 | { | 278 | { |
@@ -270,6 +285,7 @@ packet_set_iv(int mode, u_char *dat) | |||
270 | 285 | ||
271 | cipher_set_keyiv(cc, dat); | 286 | cipher_set_keyiv(cc, dat); |
272 | } | 287 | } |
288 | |||
273 | int | 289 | int |
274 | packet_get_ssh1_cipher(void) | 290 | packet_get_ssh1_cipher(void) |
275 | { | 291 | { |
@@ -471,31 +487,37 @@ packet_put_char(int value) | |||
471 | 487 | ||
472 | buffer_append(&outgoing_packet, &ch, 1); | 488 | buffer_append(&outgoing_packet, &ch, 1); |
473 | } | 489 | } |
490 | |||
474 | void | 491 | void |
475 | packet_put_int(u_int value) | 492 | packet_put_int(u_int value) |
476 | { | 493 | { |
477 | buffer_put_int(&outgoing_packet, value); | 494 | buffer_put_int(&outgoing_packet, value); |
478 | } | 495 | } |
496 | |||
479 | void | 497 | void |
480 | packet_put_string(const void *buf, u_int len) | 498 | packet_put_string(const void *buf, u_int len) |
481 | { | 499 | { |
482 | buffer_put_string(&outgoing_packet, buf, len); | 500 | buffer_put_string(&outgoing_packet, buf, len); |
483 | } | 501 | } |
502 | |||
484 | void | 503 | void |
485 | packet_put_cstring(const char *str) | 504 | packet_put_cstring(const char *str) |
486 | { | 505 | { |
487 | buffer_put_cstring(&outgoing_packet, str); | 506 | buffer_put_cstring(&outgoing_packet, str); |
488 | } | 507 | } |
508 | |||
489 | void | 509 | void |
490 | packet_put_raw(const void *buf, u_int len) | 510 | packet_put_raw(const void *buf, u_int len) |
491 | { | 511 | { |
492 | buffer_append(&outgoing_packet, buf, len); | 512 | buffer_append(&outgoing_packet, buf, len); |
493 | } | 513 | } |
514 | |||
494 | void | 515 | void |
495 | packet_put_bignum(BIGNUM * value) | 516 | packet_put_bignum(BIGNUM * value) |
496 | { | 517 | { |
497 | buffer_put_bignum(&outgoing_packet, value); | 518 | buffer_put_bignum(&outgoing_packet, value); |
498 | } | 519 | } |
520 | |||
499 | void | 521 | void |
500 | packet_put_bignum2(BIGNUM * value) | 522 | packet_put_bignum2(BIGNUM * value) |
501 | { | 523 | { |
@@ -549,7 +571,7 @@ packet_send1(void) | |||
549 | /* Add check bytes. */ | 571 | /* Add check bytes. */ |
550 | checksum = ssh_crc32(buffer_ptr(&outgoing_packet), | 572 | checksum = ssh_crc32(buffer_ptr(&outgoing_packet), |
551 | buffer_len(&outgoing_packet)); | 573 | buffer_len(&outgoing_packet)); |
552 | PUT_32BIT(buf, checksum); | 574 | put_u32(buf, checksum); |
553 | buffer_append(&outgoing_packet, buf, 4); | 575 | buffer_append(&outgoing_packet, buf, 4); |
554 | 576 | ||
555 | #ifdef PACKET_DEBUG | 577 | #ifdef PACKET_DEBUG |
@@ -558,7 +580,7 @@ packet_send1(void) | |||
558 | #endif | 580 | #endif |
559 | 581 | ||
560 | /* Append to output. */ | 582 | /* Append to output. */ |
561 | PUT_32BIT(buf, len); | 583 | put_u32(buf, len); |
562 | buffer_append(&output, buf, 4); | 584 | buffer_append(&output, buf, 4); |
563 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); | 585 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
564 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), | 586 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
@@ -654,7 +676,7 @@ set_newkeys(int mode) | |||
654 | 676 | ||
655 | /* | 677 | /* |
656 | * Delayed compression for SSH2 is enabled after authentication: | 678 | * Delayed compression for SSH2 is enabled after authentication: |
657 | * This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, | 679 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, |
658 | * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. | 680 | * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. |
659 | */ | 681 | */ |
660 | static void | 682 | static void |
@@ -669,6 +691,9 @@ packet_enable_delayed_compress(void) | |||
669 | */ | 691 | */ |
670 | after_authentication = 1; | 692 | after_authentication = 1; |
671 | for (mode = 0; mode < MODE_MAX; mode++) { | 693 | for (mode = 0; mode < MODE_MAX; mode++) { |
694 | /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ | ||
695 | if (newkeys[mode] == NULL) | ||
696 | continue; | ||
672 | comp = &newkeys[mode]->comp; | 697 | comp = &newkeys[mode]->comp; |
673 | if (comp && !comp->enabled && comp->type == COMP_DELAYED) { | 698 | if (comp && !comp->enabled && comp->type == COMP_DELAYED) { |
674 | packet_init_compression(); | 699 | packet_init_compression(); |
@@ -761,7 +786,7 @@ packet_send2_wrapped(void) | |||
761 | /* packet_length includes payload, padding and padding length field */ | 786 | /* packet_length includes payload, padding and padding length field */ |
762 | packet_length = buffer_len(&outgoing_packet) - 4; | 787 | packet_length = buffer_len(&outgoing_packet) - 4; |
763 | cp = buffer_ptr(&outgoing_packet); | 788 | cp = buffer_ptr(&outgoing_packet); |
764 | PUT_32BIT(cp, packet_length); | 789 | put_u32(cp, packet_length); |
765 | cp[4] = padlen; | 790 | cp[4] = padlen; |
766 | DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); | 791 | DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); |
767 | 792 | ||
@@ -778,7 +803,7 @@ packet_send2_wrapped(void) | |||
778 | buffer_len(&outgoing_packet)); | 803 | buffer_len(&outgoing_packet)); |
779 | /* append unencrypted MAC */ | 804 | /* append unencrypted MAC */ |
780 | if (mac && mac->enabled) | 805 | if (mac && mac->enabled) |
781 | buffer_append(&output, (char *)macbuf, mac->mac_len); | 806 | buffer_append(&output, macbuf, mac->mac_len); |
782 | #ifdef PACKET_DEBUG | 807 | #ifdef PACKET_DEBUG |
783 | fprintf(stderr, "encrypted: "); | 808 | fprintf(stderr, "encrypted: "); |
784 | buffer_dump(&output); | 809 | buffer_dump(&output); |
@@ -868,7 +893,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) | |||
868 | char buf[8192]; | 893 | char buf[8192]; |
869 | DBG(debug("packet_read()")); | 894 | DBG(debug("packet_read()")); |
870 | 895 | ||
871 | setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) * | 896 | setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), |
872 | sizeof(fd_mask)); | 897 | sizeof(fd_mask)); |
873 | 898 | ||
874 | /* Since we are blocking, ensure that all written packets have been sent. */ | 899 | /* Since we are blocking, ensure that all written packets have been sent. */ |
@@ -959,7 +984,7 @@ packet_read_poll1(void) | |||
959 | return SSH_MSG_NONE; | 984 | return SSH_MSG_NONE; |
960 | /* Get length of incoming packet. */ | 985 | /* Get length of incoming packet. */ |
961 | cp = buffer_ptr(&input); | 986 | cp = buffer_ptr(&input); |
962 | len = GET_32BIT(cp); | 987 | len = get_u32(cp); |
963 | if (len < 1 + 2 + 2 || len > 256 * 1024) | 988 | if (len < 1 + 2 + 2 || len > 256 * 1024) |
964 | packet_disconnect("Bad packet length %u.", len); | 989 | packet_disconnect("Bad packet length %u.", len); |
965 | padded_len = (len + 8) & ~7; | 990 | padded_len = (len + 8) & ~7; |
@@ -978,9 +1003,16 @@ packet_read_poll1(void) | |||
978 | * (C)1998 CORE-SDI, Buenos Aires Argentina | 1003 | * (C)1998 CORE-SDI, Buenos Aires Argentina |
979 | * Ariel Futoransky(futo@core-sdi.com) | 1004 | * Ariel Futoransky(futo@core-sdi.com) |
980 | */ | 1005 | */ |
981 | if (!receive_context.plaintext && | 1006 | if (!receive_context.plaintext) { |
982 | detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) | 1007 | switch (detect_attack(buffer_ptr(&input), padded_len)) { |
983 | packet_disconnect("crc32 compensation attack: network attack detected"); | 1008 | case DEATTACK_DETECTED: |
1009 | packet_disconnect("crc32 compensation attack: " | ||
1010 | "network attack detected"); | ||
1011 | case DEATTACK_DOS_DETECTED: | ||
1012 | packet_disconnect("deattack denial of " | ||
1013 | "service detected"); | ||
1014 | } | ||
1015 | } | ||
984 | 1016 | ||
985 | /* Decrypt data to incoming_packet. */ | 1017 | /* Decrypt data to incoming_packet. */ |
986 | buffer_clear(&incoming_packet); | 1018 | buffer_clear(&incoming_packet); |
@@ -1007,7 +1039,7 @@ packet_read_poll1(void) | |||
1007 | len, buffer_len(&incoming_packet)); | 1039 | len, buffer_len(&incoming_packet)); |
1008 | 1040 | ||
1009 | cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; | 1041 | cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; |
1010 | stored_checksum = GET_32BIT(cp); | 1042 | stored_checksum = get_u32(cp); |
1011 | if (checksum != stored_checksum) | 1043 | if (checksum != stored_checksum) |
1012 | packet_disconnect("Corrupted check bytes on input."); | 1044 | packet_disconnect("Corrupted check bytes on input."); |
1013 | buffer_consume_end(&incoming_packet, 4); | 1045 | buffer_consume_end(&incoming_packet, 4); |
@@ -1056,7 +1088,7 @@ packet_read_poll2(u_int32_t *seqnr_p) | |||
1056 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), | 1088 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), |
1057 | block_size); | 1089 | block_size); |
1058 | cp = buffer_ptr(&incoming_packet); | 1090 | cp = buffer_ptr(&incoming_packet); |
1059 | packet_length = GET_32BIT(cp); | 1091 | packet_length = get_u32(cp); |
1060 | if (packet_length < 1 + 4 || packet_length > 256 * 1024) { | 1092 | if (packet_length < 1 + 4 || packet_length > 256 * 1024) { |
1061 | #ifdef PACKET_DEBUG | 1093 | #ifdef PACKET_DEBUG |
1062 | buffer_dump(&incoming_packet); | 1094 | buffer_dump(&incoming_packet); |
@@ -1187,7 +1219,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) | |||
1187 | break; | 1219 | break; |
1188 | default: | 1220 | default: |
1189 | return type; | 1221 | return type; |
1190 | break; | ||
1191 | } | 1222 | } |
1192 | } else { | 1223 | } else { |
1193 | type = packet_read_poll1(); | 1224 | type = packet_read_poll1(); |
@@ -1210,7 +1241,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) | |||
1210 | if (type) | 1241 | if (type) |
1211 | DBG(debug("received packet type %d", type)); | 1242 | DBG(debug("received packet type %d", type)); |
1212 | return type; | 1243 | return type; |
1213 | break; | ||
1214 | } | 1244 | } |
1215 | } | 1245 | } |
1216 | } | 1246 | } |
@@ -1412,7 +1442,7 @@ packet_write_wait(void) | |||
1412 | { | 1442 | { |
1413 | fd_set *setp; | 1443 | fd_set *setp; |
1414 | 1444 | ||
1415 | setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) * | 1445 | setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), |
1416 | sizeof(fd_mask)); | 1446 | sizeof(fd_mask)); |
1417 | packet_write_poll(); | 1447 | packet_write_poll(); |
1418 | while (packet_have_data_to_write()) { | 1448 | while (packet_have_data_to_write()) { |
@@ -1480,8 +1510,7 @@ packet_set_interactive(int interactive) | |||
1480 | /* Only set socket options if using a socket. */ | 1510 | /* Only set socket options if using a socket. */ |
1481 | if (!packet_connection_is_on_socket()) | 1511 | if (!packet_connection_is_on_socket()) |
1482 | return; | 1512 | return; |
1483 | if (interactive) | 1513 | set_nodelay(connection_in); |
1484 | set_nodelay(connection_in); | ||
1485 | packet_set_tos(interactive); | 1514 | packet_set_tos(interactive); |
1486 | } | 1515 | } |
1487 | 1516 | ||
@@ -1542,7 +1571,7 @@ packet_send_ignore(int nbytes) | |||
1542 | for (i = 0; i < nbytes; i++) { | 1571 | for (i = 0; i < nbytes; i++) { |
1543 | if (i % 4 == 0) | 1572 | if (i % 4 == 0) |
1544 | rnd = arc4random(); | 1573 | rnd = arc4random(); |
1545 | packet_put_char(rnd & 0xff); | 1574 | packet_put_char((u_char)rnd & 0xff); |
1546 | rnd >>= 8; | 1575 | rnd >>= 8; |
1547 | } | 1576 | } |
1548 | } | 1577 | } |