diff options
author | Colin Watson <cjwatson@debian.org> | 2007-06-12 16:16:35 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2007-06-12 16:16:35 +0000 |
commit | b7e40fa9da0b5491534a429dadb321eab5a77558 (patch) | |
tree | bed1da11e9f829925797aa093e379fc0b5868ecd /packet.c | |
parent | 4f84beedf1005e44ff33c854abd6b711ffc0adb7 (diff) | |
parent | 086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff) |
* New upstream release (closes: #395507, #397961, #420035). Important
changes not previously backported to 4.3p2:
- 4.4/4.4p1 (http://www.openssh.org/txt/release-4.4):
+ On portable OpenSSH, fix a GSSAPI authentication abort that could be
used to determine the validity of usernames on some platforms.
+ Implemented conditional configuration in sshd_config(5) using the
"Match" directive. This allows some configuration options to be
selectively overridden if specific criteria (based on user, group,
hostname and/or address) are met. So far a useful subset of
post-authentication options are supported and more are expected to
be added in future releases.
+ Add support for Diffie-Hellman group exchange key agreement with a
final hash of SHA256.
+ Added a "ForceCommand" directive to sshd_config(5). Similar to the
command="..." option accepted in ~/.ssh/authorized_keys, this forces
the execution of the specified command regardless of what the user
requested. This is very useful in conjunction with the new "Match"
option.
+ Add a "PermitOpen" directive to sshd_config(5). This mirrors the
permitopen="..." authorized_keys option, allowing fine-grained
control over the port-forwardings that a user is allowed to
establish.
+ Add optional logging of transactions to sftp-server(8).
+ ssh(1) will now record port numbers for hosts stored in
~/.ssh/known_hosts when a non-standard port has been requested
(closes: #50612).
+ Add an "ExitOnForwardFailure" option to cause ssh(1) to exit (with a
non-zero exit code) when requested port forwardings could not be
established.
+ Extend sshd_config(5) "SubSystem" declarations to allow the
specification of command-line arguments.
+ Replacement of all integer overflow susceptible invocations of
malloc(3) and realloc(3) with overflow-checking equivalents.
+ Many manpage fixes and improvements.
+ Add optional support for OpenSSL hardware accelerators (engines),
enabled using the --with-ssl-engine configure option.
+ Tokens in configuration files may be double-quoted in order to
contain spaces (closes: #319639).
+ Move a debug() call out of a SIGCHLD handler, fixing a hang when the
session exits very quickly (closes: #307890).
+ Fix some incorrect buffer allocation calculations (closes: #410599).
+ ssh-add doesn't ask for a passphrase if key file permissions are too
liberal (closes: #103677).
+ Likewise, ssh doesn't ask either (closes: #99675).
- 4.6/4.6p1 (http://www.openssh.org/txt/release-4.6):
+ sshd now allows the enabling and disabling of authentication methods
on a per user, group, host and network basis via the Match directive
in sshd_config.
+ Fixed an inconsistent check for a terminal when displaying scp
progress meter (closes: #257524).
+ Fix "hang on exit" when background processes are running at the time
of exit on a ttyful/login session (closes: #88337).
* Update to current GSSAPI patch from
http://www.sxw.org.uk/computing/patches/openssh-4.6p1-gsskex-20070312.patch;
install ChangeLog.gssapi.
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 78 |
1 files changed, 50 insertions, 28 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" |
@@ -261,6 +275,7 @@ packet_get_keyiv_len(int mode) | |||
261 | 275 | ||
262 | return (cipher_get_keyiv_len(cc)); | 276 | return (cipher_get_keyiv_len(cc)); |
263 | } | 277 | } |
278 | |||
264 | void | 279 | void |
265 | packet_set_iv(int mode, u_char *dat) | 280 | packet_set_iv(int mode, u_char *dat) |
266 | { | 281 | { |
@@ -273,6 +288,7 @@ packet_set_iv(int mode, u_char *dat) | |||
273 | 288 | ||
274 | cipher_set_keyiv(cc, dat); | 289 | cipher_set_keyiv(cc, dat); |
275 | } | 290 | } |
291 | |||
276 | int | 292 | int |
277 | packet_get_ssh1_cipher(void) | 293 | packet_get_ssh1_cipher(void) |
278 | { | 294 | { |
@@ -474,31 +490,37 @@ packet_put_char(int value) | |||
474 | 490 | ||
475 | buffer_append(&outgoing_packet, &ch, 1); | 491 | buffer_append(&outgoing_packet, &ch, 1); |
476 | } | 492 | } |
493 | |||
477 | void | 494 | void |
478 | packet_put_int(u_int value) | 495 | packet_put_int(u_int value) |
479 | { | 496 | { |
480 | buffer_put_int(&outgoing_packet, value); | 497 | buffer_put_int(&outgoing_packet, value); |
481 | } | 498 | } |
499 | |||
482 | void | 500 | void |
483 | packet_put_string(const void *buf, u_int len) | 501 | packet_put_string(const void *buf, u_int len) |
484 | { | 502 | { |
485 | buffer_put_string(&outgoing_packet, buf, len); | 503 | buffer_put_string(&outgoing_packet, buf, len); |
486 | } | 504 | } |
505 | |||
487 | void | 506 | void |
488 | packet_put_cstring(const char *str) | 507 | packet_put_cstring(const char *str) |
489 | { | 508 | { |
490 | buffer_put_cstring(&outgoing_packet, str); | 509 | buffer_put_cstring(&outgoing_packet, str); |
491 | } | 510 | } |
511 | |||
492 | void | 512 | void |
493 | packet_put_raw(const void *buf, u_int len) | 513 | packet_put_raw(const void *buf, u_int len) |
494 | { | 514 | { |
495 | buffer_append(&outgoing_packet, buf, len); | 515 | buffer_append(&outgoing_packet, buf, len); |
496 | } | 516 | } |
517 | |||
497 | void | 518 | void |
498 | packet_put_bignum(BIGNUM * value) | 519 | packet_put_bignum(BIGNUM * value) |
499 | { | 520 | { |
500 | buffer_put_bignum(&outgoing_packet, value); | 521 | buffer_put_bignum(&outgoing_packet, value); |
501 | } | 522 | } |
523 | |||
502 | void | 524 | void |
503 | packet_put_bignum2(BIGNUM * value) | 525 | packet_put_bignum2(BIGNUM * value) |
504 | { | 526 | { |
@@ -552,7 +574,7 @@ packet_send1(void) | |||
552 | /* Add check bytes. */ | 574 | /* Add check bytes. */ |
553 | checksum = ssh_crc32(buffer_ptr(&outgoing_packet), | 575 | checksum = ssh_crc32(buffer_ptr(&outgoing_packet), |
554 | buffer_len(&outgoing_packet)); | 576 | buffer_len(&outgoing_packet)); |
555 | PUT_32BIT(buf, checksum); | 577 | put_u32(buf, checksum); |
556 | buffer_append(&outgoing_packet, buf, 4); | 578 | buffer_append(&outgoing_packet, buf, 4); |
557 | 579 | ||
558 | #ifdef PACKET_DEBUG | 580 | #ifdef PACKET_DEBUG |
@@ -561,7 +583,7 @@ packet_send1(void) | |||
561 | #endif | 583 | #endif |
562 | 584 | ||
563 | /* Append to output. */ | 585 | /* Append to output. */ |
564 | PUT_32BIT(buf, len); | 586 | put_u32(buf, len); |
565 | buffer_append(&output, buf, 4); | 587 | buffer_append(&output, buf, 4); |
566 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); | 588 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
567 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), | 589 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
@@ -657,7 +679,7 @@ set_newkeys(int mode) | |||
657 | 679 | ||
658 | /* | 680 | /* |
659 | * Delayed compression for SSH2 is enabled after authentication: | 681 | * Delayed compression for SSH2 is enabled after authentication: |
660 | * This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, | 682 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, |
661 | * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. | 683 | * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. |
662 | */ | 684 | */ |
663 | static void | 685 | static void |
@@ -672,6 +694,9 @@ packet_enable_delayed_compress(void) | |||
672 | */ | 694 | */ |
673 | after_authentication = 1; | 695 | after_authentication = 1; |
674 | for (mode = 0; mode < MODE_MAX; mode++) { | 696 | for (mode = 0; mode < MODE_MAX; mode++) { |
697 | /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ | ||
698 | if (newkeys[mode] == NULL) | ||
699 | continue; | ||
675 | comp = &newkeys[mode]->comp; | 700 | comp = &newkeys[mode]->comp; |
676 | if (comp && !comp->enabled && comp->type == COMP_DELAYED) { | 701 | if (comp && !comp->enabled && comp->type == COMP_DELAYED) { |
677 | packet_init_compression(); | 702 | packet_init_compression(); |
@@ -764,7 +789,7 @@ packet_send2_wrapped(void) | |||
764 | /* packet_length includes payload, padding and padding length field */ | 789 | /* packet_length includes payload, padding and padding length field */ |
765 | packet_length = buffer_len(&outgoing_packet) - 4; | 790 | packet_length = buffer_len(&outgoing_packet) - 4; |
766 | cp = buffer_ptr(&outgoing_packet); | 791 | cp = buffer_ptr(&outgoing_packet); |
767 | PUT_32BIT(cp, packet_length); | 792 | put_u32(cp, packet_length); |
768 | cp[4] = padlen; | 793 | cp[4] = padlen; |
769 | DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); | 794 | DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); |
770 | 795 | ||
@@ -781,7 +806,7 @@ packet_send2_wrapped(void) | |||
781 | buffer_len(&outgoing_packet)); | 806 | buffer_len(&outgoing_packet)); |
782 | /* append unencrypted MAC */ | 807 | /* append unencrypted MAC */ |
783 | if (mac && mac->enabled) | 808 | if (mac && mac->enabled) |
784 | buffer_append(&output, (char *)macbuf, mac->mac_len); | 809 | buffer_append(&output, macbuf, mac->mac_len); |
785 | #ifdef PACKET_DEBUG | 810 | #ifdef PACKET_DEBUG |
786 | fprintf(stderr, "encrypted: "); | 811 | fprintf(stderr, "encrypted: "); |
787 | buffer_dump(&output); | 812 | buffer_dump(&output); |
@@ -872,7 +897,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) | |||
872 | struct timeval tv, *tvp; | 897 | struct timeval tv, *tvp; |
873 | DBG(debug("packet_read()")); | 898 | DBG(debug("packet_read()")); |
874 | 899 | ||
875 | setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) * | 900 | setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), |
876 | sizeof(fd_mask)); | 901 | sizeof(fd_mask)); |
877 | 902 | ||
878 | /* Since we are blocking, ensure that all written packets have been sent. */ | 903 | /* Since we are blocking, ensure that all written packets have been sent. */ |
@@ -902,11 +927,11 @@ packet_read_seqnr(u_int32_t *seqnr_p) | |||
902 | FD_SET(connection_in, setp); | 927 | FD_SET(connection_in, setp); |
903 | 928 | ||
904 | if (setup_timeout > 0) { | 929 | if (setup_timeout > 0) { |
905 | tvp = &tv; | 930 | tvp = &tv; |
906 | tv.tv_sec = setup_timeout; | 931 | tv.tv_sec = setup_timeout; |
907 | tv.tv_usec = 0; | 932 | tv.tv_usec = 0; |
908 | } else | 933 | } else |
909 | tvp = 0; | 934 | tvp = NULL; |
910 | 935 | ||
911 | /* Wait for some data to arrive. */ | 936 | /* Wait for some data to arrive. */ |
912 | while (select(connection_in + 1, setp, NULL, NULL, tvp) == -1 && | 937 | while (select(connection_in + 1, setp, NULL, NULL, tvp) == -1 && |
@@ -914,7 +939,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) | |||
914 | ; | 939 | ; |
915 | 940 | ||
916 | if (!FD_ISSET(connection_in, setp)) | 941 | if (!FD_ISSET(connection_in, setp)) |
917 | fatal("packet_read: Setup timeout expired, giving up"); | 942 | fatal("packet_read: Setup timeout expired, giving up"); |
918 | 943 | ||
919 | /* Read data from the socket. */ | 944 | /* Read data from the socket. */ |
920 | len = read(connection_in, buf, sizeof(buf)); | 945 | len = read(connection_in, buf, sizeof(buf)); |
@@ -973,7 +998,7 @@ packet_read_poll1(void) | |||
973 | return SSH_MSG_NONE; | 998 | return SSH_MSG_NONE; |
974 | /* Get length of incoming packet. */ | 999 | /* Get length of incoming packet. */ |
975 | cp = buffer_ptr(&input); | 1000 | cp = buffer_ptr(&input); |
976 | len = GET_32BIT(cp); | 1001 | len = get_u32(cp); |
977 | if (len < 1 + 2 + 2 || len > 256 * 1024) | 1002 | if (len < 1 + 2 + 2 || len > 256 * 1024) |
978 | packet_disconnect("Bad packet length %u.", len); | 1003 | packet_disconnect("Bad packet length %u.", len); |
979 | padded_len = (len + 8) & ~7; | 1004 | padded_len = (len + 8) & ~7; |
@@ -993,7 +1018,7 @@ packet_read_poll1(void) | |||
993 | * Ariel Futoransky(futo@core-sdi.com) | 1018 | * Ariel Futoransky(futo@core-sdi.com) |
994 | */ | 1019 | */ |
995 | if (!receive_context.plaintext) { | 1020 | if (!receive_context.plaintext) { |
996 | switch (detect_attack(buffer_ptr(&input), padded_len, NULL)) { | 1021 | switch (detect_attack(buffer_ptr(&input), padded_len)) { |
997 | case DEATTACK_DETECTED: | 1022 | case DEATTACK_DETECTED: |
998 | packet_disconnect("crc32 compensation attack: " | 1023 | packet_disconnect("crc32 compensation attack: " |
999 | "network attack detected"); | 1024 | "network attack detected"); |
@@ -1028,7 +1053,7 @@ packet_read_poll1(void) | |||
1028 | len, buffer_len(&incoming_packet)); | 1053 | len, buffer_len(&incoming_packet)); |
1029 | 1054 | ||
1030 | cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; | 1055 | cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; |
1031 | stored_checksum = GET_32BIT(cp); | 1056 | stored_checksum = get_u32(cp); |
1032 | if (checksum != stored_checksum) | 1057 | if (checksum != stored_checksum) |
1033 | packet_disconnect("Corrupted check bytes on input."); | 1058 | packet_disconnect("Corrupted check bytes on input."); |
1034 | buffer_consume_end(&incoming_packet, 4); | 1059 | buffer_consume_end(&incoming_packet, 4); |
@@ -1077,7 +1102,7 @@ packet_read_poll2(u_int32_t *seqnr_p) | |||
1077 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), | 1102 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), |
1078 | block_size); | 1103 | block_size); |
1079 | cp = buffer_ptr(&incoming_packet); | 1104 | cp = buffer_ptr(&incoming_packet); |
1080 | packet_length = GET_32BIT(cp); | 1105 | packet_length = get_u32(cp); |
1081 | if (packet_length < 1 + 4 || packet_length > 256 * 1024) { | 1106 | if (packet_length < 1 + 4 || packet_length > 256 * 1024) { |
1082 | #ifdef PACKET_DEBUG | 1107 | #ifdef PACKET_DEBUG |
1083 | buffer_dump(&incoming_packet); | 1108 | buffer_dump(&incoming_packet); |
@@ -1208,7 +1233,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) | |||
1208 | break; | 1233 | break; |
1209 | default: | 1234 | default: |
1210 | return type; | 1235 | return type; |
1211 | break; | ||
1212 | } | 1236 | } |
1213 | } else { | 1237 | } else { |
1214 | type = packet_read_poll1(); | 1238 | type = packet_read_poll1(); |
@@ -1231,7 +1255,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) | |||
1231 | if (type) | 1255 | if (type) |
1232 | DBG(debug("received packet type %d", type)); | 1256 | DBG(debug("received packet type %d", type)); |
1233 | return type; | 1257 | return type; |
1234 | break; | ||
1235 | } | 1258 | } |
1236 | } | 1259 | } |
1237 | } | 1260 | } |
@@ -1433,7 +1456,7 @@ packet_write_wait(void) | |||
1433 | { | 1456 | { |
1434 | fd_set *setp; | 1457 | fd_set *setp; |
1435 | 1458 | ||
1436 | setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) * | 1459 | setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), |
1437 | sizeof(fd_mask)); | 1460 | sizeof(fd_mask)); |
1438 | packet_write_poll(); | 1461 | packet_write_poll(); |
1439 | while (packet_have_data_to_write()) { | 1462 | while (packet_have_data_to_write()) { |
@@ -1501,8 +1524,7 @@ packet_set_interactive(int interactive) | |||
1501 | /* Only set socket options if using a socket. */ | 1524 | /* Only set socket options if using a socket. */ |
1502 | if (!packet_connection_is_on_socket()) | 1525 | if (!packet_connection_is_on_socket()) |
1503 | return; | 1526 | return; |
1504 | if (interactive) | 1527 | set_nodelay(connection_in); |
1505 | set_nodelay(connection_in); | ||
1506 | packet_set_tos(interactive); | 1528 | packet_set_tos(interactive); |
1507 | } | 1529 | } |
1508 | 1530 | ||
@@ -1563,7 +1585,7 @@ packet_send_ignore(int nbytes) | |||
1563 | for (i = 0; i < nbytes; i++) { | 1585 | for (i = 0; i < nbytes; i++) { |
1564 | if (i % 4 == 0) | 1586 | if (i % 4 == 0) |
1565 | rnd = arc4random(); | 1587 | rnd = arc4random(); |
1566 | packet_put_char(rnd & 0xff); | 1588 | packet_put_char((u_char)rnd & 0xff); |
1567 | rnd >>= 8; | 1589 | rnd >>= 8; |
1568 | } | 1590 | } |
1569 | } | 1591 | } |