Package: openssh-server Version: 1:4.1p1-6 Followup-For: Bug #292932 This patch is to replace my previous. It reverts one of Darren's suggested changes which was causing disconnects on large transfers and reverses the order in which I had added the -hpn string to the version string.
-- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (500, 'stable'), (1, 'experimental') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.12.4 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages openssh-server depends on: ii adduser 3.67 Add and remove users and groups ii debconf [debconf-2.0] 1.4.57 Debian configuration management sy ii dpkg 1.13.10 Package maintenance system for Deb ii libc6 2.3.5-3 GNU C Library: Shared libraries an ii libpam-modules 0.76-23 Pluggable Authentication Modules f ii libpam-runtime 0.76-23 Runtime support for the PAM librar ii libpam0g 0.76-23 Pluggable Authentication Modules l ii libselinux1 1.24-4 SELinux shared libraries ii libssl0.9.7 0.9.7g-1 SSL shared libraries ii libwrap0 7.6.dbs-8 Wietse Venema's TCP wrappers libra ii openssh-client 1:4.1p1-6 Secure shell client, an rlogin/rsh ii zlib1g 1:1.2.3-3 compression library - runtime openssh-server recommends no packages. -- debconf information excluded
diff -urN openssh-4.1p1/buffer.c openssh-4.1p1-hpn11-none/buffer.c --- openssh-4.1p1/buffer.c 2005-03-14 06:22:26.000000000 -0600 +++ openssh-4.1p1-hpn11-none/buffer.c 2005-08-13 07:01:57.000000000 -0500 @@ -107,7 +107,7 @@ /* Increase the size of the buffer and retry. */ newlen = buffer->alloc + len + 32768; - if (newlen > BUFFER_MAX_LEN) + if (newlen > BUFFER_MAX_HPN_LEN) fatal("buffer_append_space: alloc %u not supported", newlen); buffer->buf = xrealloc(buffer->buf, newlen); diff -urN openssh-4.1p1/buffer.h openssh-4.1p1-hpn11-none/buffer.h --- openssh-4.1p1/buffer.h 2005-03-14 06:22:26.000000000 -0600 +++ openssh-4.1p1-hpn11-none/buffer.h 2005-08-13 07:55:44.000000000 -0500 @@ -25,6 +25,7 @@ #define BUFFER_MAX_CHUNK 0x100000 #define BUFFER_MAX_LEN 0xa00000 +#define BUFFER_MAX_HPN_LEN ((2U>>29)-1) void buffer_init(Buffer *); void buffer_clear(Buffer *); diff -urN openssh-4.1p1/channels.c openssh-4.1p1-hpn11-none/channels.c --- openssh-4.1p1/channels.c 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/channels.c 2005-08-13 07:06:16.000000000 -0500 @@ -259,6 +259,7 @@ c->local_window_max = window; c->local_consumed = 0; c->local_maxpacket = maxpack; + c->dynamic_window = 0; c->remote_id = -1; c->remote_name = xstrdup(remote_name); c->remote_window = 0; @@ -715,7 +716,7 @@ u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); /* check buffer limits */ - limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF)); + limit = MIN(limit, (BUFFER_MAX_HPN_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF)); if (c->istate == CHAN_INPUT_OPEN && limit > 0 && @@ -1533,14 +1534,29 @@ !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && c->local_window < c->local_window_max/2 && c->local_consumed > 0) { + u_int32_t tcpwinsz = 0; + socklen_t optsz = sizeof(tcpwinsz); + int ret = -1; + u_int32_t addition = 0; + if (c->dynamic_window) { + ret = getsockopt(packet_get_connection_in(), + SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); + if ((ret == 0) && tcpwinsz > BUFFER_MAX_HPN_LEN) + tcpwinsz = BUFFER_MAX_HPN_LEN; + } + if (c->dynamic_window && (ret == 0) && + (tcpwinsz > c->local_window_max)) { + addition = tcpwinsz - c->local_window_max; + c->local_window_max += addition; + } packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); - packet_put_int(c->local_consumed); + packet_put_int(c->local_consumed + addition); packet_send(); debug2("channel %d: window %d sent adjust %d", c->self, c->local_window, c->local_consumed); - c->local_window += c->local_consumed; + c->local_window += c->local_consumed + addition; c->local_consumed = 0; } return 1; diff -urN openssh-4.1p1/channels.h openssh-4.1p1-hpn11-none/channels.h --- openssh-4.1p1/channels.h 2005-03-01 04:24:33.000000000 -0600 +++ openssh-4.1p1-hpn11-none/channels.h 2005-08-13 07:58:08.000000000 -0500 @@ -99,6 +99,7 @@ u_int local_window_max; u_int local_consumed; u_int local_maxpacket; + int dynamic_window; int extended_usage; int single_connection; @@ -119,11 +120,11 @@ /* default window/packet sizes for tcp/x11-fwd-channel */ #define CHAN_SES_PACKET_DEFAULT (32*1024) -#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) +#define CHAN_SES_WINDOW_DEFAULT (BUFFER_MAX_LEN/2) #define CHAN_TCP_PACKET_DEFAULT (32*1024) -#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_TCP_WINDOW_DEFAULT (BUFFER_MAX_LEN/2) #define CHAN_X11_PACKET_DEFAULT (16*1024) -#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) +#define CHAN_X11_WINDOW_DEFAULT (BUFFER_MAX_LEN/2) /* possible input states */ #define CHAN_INPUT_OPEN 0 diff -urN openssh-4.1p1/cipher.c openssh-4.1p1-hpn11-none/cipher.c --- openssh-4.1p1/cipher.c 2005-01-24 04:57:11.000000000 -0600 +++ openssh-4.1p1-hpn11-none/cipher.c 2005-08-13 07:31:14.000000000 -0500 @@ -175,7 +175,8 @@ for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); - if (c == NULL || c->number != SSH_CIPHER_SSH2) { + if (c == NULL || (c->number != SSH_CIPHER_SSH2 && + c->number != SSH_CIPHER_NONE)) { debug("bad cipher %s [%s]", p, names); xfree(cipher_list); return 0; @@ -345,6 +346,7 @@ int evplen; switch (c->number) { + case SSH_CIPHER_NONE: case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: @@ -379,6 +381,7 @@ int evplen = 0; switch (c->number) { + case SSH_CIPHER_NONE: case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: diff -urN openssh-4.1p1/compat.c openssh-4.1p1-hpn11-none/compat.c --- openssh-4.1p1/compat.c 2005-03-01 04:24:33.000000000 -0600 +++ openssh-4.1p1-hpn11-none/compat.c 2005-08-13 07:08:54.000000000 -0500 @@ -162,6 +162,14 @@ strlen(check[i].pat), 0) == 1) { debug("match: %s pat %s", version, check[i].pat); datafellows = check[i].bugs; + /* Check to see if the remote side is OpenSSH and not HPN */ + if(strstr(version,"OpenSSH") != NULL) + { + if (strstr(version,"hpn") == NULL) + { + datafellows |= SSH_BUG_LARGEWINDOW; + } + } return; } } diff -urN openssh-4.1p1/compat.h openssh-4.1p1-hpn11-none/compat.h --- openssh-4.1p1/compat.h 2005-03-01 04:24:33.000000000 -0600 +++ openssh-4.1p1-hpn11-none/compat.h 2005-08-13 07:09:23.000000000 -0500 @@ -56,6 +56,7 @@ #define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 +#define SSH_BUG_LARGEWINDOW 0x02000000 void enable_compat13(void); void enable_compat20(void); diff -urN openssh-4.1p1/kex.c openssh-4.1p1-hpn11-none/kex.c --- openssh-4.1p1/kex.c 2004-06-21 21:56:02.000000000 -0500 +++ openssh-4.1p1-hpn11-none/kex.c 2005-08-13 07:31:58.000000000 -0500 @@ -49,7 +49,7 @@ static void kex_choose_conf(Kex *); /* put algorithm proposal into buffer */ -static void +void kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) { int i; diff -urN openssh-4.1p1/kex.h openssh-4.1p1-hpn11-none/kex.h --- openssh-4.1p1/kex.h 2004-06-14 19:30:09.000000000 -0500 +++ openssh-4.1p1-hpn11-none/kex.h 2005-08-13 07:32:35.000000000 -0500 @@ -118,6 +118,8 @@ void (*kex[KEX_MAX])(Kex *); }; +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]); + Kex *kex_setup(char *[PROPOSAL_MAX]); void kex_finish(Kex *); diff -urN openssh-4.1p1/myproposal.h openssh-4.1p1-hpn11-none/myproposal.h --- openssh-4.1p1/myproposal.h 2004-06-14 19:30:09.000000000 -0500 +++ openssh-4.1p1-hpn11-none/myproposal.h 2005-08-13 07:32:56.000000000 -0500 @@ -30,7 +30,7 @@ #define KEX_DEFAULT_ENCRYPT \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \ "aes192-cbc,aes256-cbc,[EMAIL PROTECTED]," \ - "aes128-ctr,aes192-ctr,aes256-ctr" + "aes128-ctr,aes192-ctr,aes256-ctr,none" #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,hmac-ripemd160," \ "[EMAIL PROTECTED]," \ diff -urN openssh-4.1p1/packet.c openssh-4.1p1-hpn11-none/packet.c --- openssh-4.1p1/packet.c 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/packet.c 2005-08-13 07:35:30.000000000 -0500 @@ -1519,6 +1519,13 @@ rnd >>= 8; } } +int rekey_requested = 0; + +void +packet_request_rekeying(void) +{ + rekey_requested = 1; +} #define MAX_PACKETS (1U<<31) int @@ -1526,6 +1533,11 @@ { if (datafellows & SSH_BUG_NOREKEY) return 0; + if (rekey_requested == 1) + { + rekey_requested = 0; + return 1; + } return (p_send.packets > MAX_PACKETS) || (p_read.packets > MAX_PACKETS) || diff -urN openssh-4.1p1/packet.h openssh-4.1p1-hpn11-none/packet.h --- openssh-4.1p1/packet.h 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/packet.h 2005-08-13 07:36:34.000000000 -0500 @@ -18,6 +18,9 @@ #include <openssl/bn.h> +void +packet_request_rekeying(void); + void packet_set_connection(int, int, int); void packet_set_nonblocking(void); int packet_get_connection_in(void); diff -urN openssh-4.1p1/readconf.c openssh-4.1p1-hpn11-none/readconf.c --- openssh-4.1p1/readconf.c 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/readconf.c 2005-08-13 07:38:14.000000000 -0500 @@ -967,6 +967,7 @@ options->verify_host_key_dns = -1; options->server_alive_interval = -1; options->server_alive_count_max = -1; + options->none_switch = -1; options->num_send_env = 0; options->control_path = NULL; options->control_master = -1; @@ -1096,6 +1097,8 @@ } if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; + if (options->none_switch == -1) + options->none_switch = 0; if (options->control_master == -1) options->control_master = 0; if (options->hash_known_hosts == -1) diff -urN openssh-4.1p1/readconf.h openssh-4.1p1-hpn11-none/readconf.h --- openssh-4.1p1/readconf.h 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/readconf.h 2005-08-13 07:38:37.000000000 -0500 @@ -58,6 +58,7 @@ * (best). */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ int setuptimeout; /* timeout in the protocol banner exchange */ + int tcp_rcv_buf; /* user switch to set tcp recv buffer */ LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ @@ -103,6 +104,7 @@ int enable_ssh_keysign; int rekey_limit; + int none_switch; int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; diff -urN openssh-4.1p1/scp.c openssh-4.1p1-hpn11-none/scp.c --- openssh-4.1p1/scp.c 2005-04-02 18:16:40.000000000 -0600 +++ openssh-4.1p1-hpn11-none/scp.c 2005-08-13 07:43:03.000000000 -0500 @@ -229,7 +229,7 @@ addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246zS:o:F:w:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -237,6 +237,7 @@ case '4': case '6': case 'C': + case 'z': addargs(&args, "-%c", ch); break; case 'o': @@ -290,6 +291,9 @@ setmode(0, O_BINARY); #endif break; + case 'w': + addargs(&args, "-w%s", optarg); + break; default: usage(); } @@ -504,7 +508,7 @@ BUF *bp; off_t i, amt, result, statbytes; int fd, haderr, indx; - char *last, *name, buf[2048]; + char *last, *name, buf[16384]; int len; for (indx = 0; indx < argc; ++indx) { @@ -564,7 +568,11 @@ (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; - if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { + /* this change decreases the number of read/write syscalls*/ + /* when scp acts as data source. this is the critical change*/ + /* buf can actually remain at 2k but increasing both to 16k*/ + /* seemed to make sense*/ + if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) { next: (void) close(fd); continue; } @@ -724,7 +732,7 @@ int amt, count, exists, first, mask, mode, ofd, omode; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + char ch, *cp, *np, *targ, *why, *vect[1], buf[16384]; struct timeval tv[2]; #define atime tv[0] @@ -885,7 +893,7 @@ continue; } (void) atomicio(vwrite, remout, "", 1); - if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) { (void) close(ofd); continue; } @@ -895,8 +903,8 @@ statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); - for (count = i = 0; i < size; i += 4096) { - amt = 4096; + for (count = i = 0; i < size; i += sizeof(buf)) { + amt = sizeof(buf); if (i + amt > size) amt = size - i; count += amt; @@ -913,7 +921,7 @@ } while (amt > 0); if (limit_rate) - bwlimit(4096); + bwlimit(sizeof(buf)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ @@ -1029,7 +1037,7 @@ { (void) fprintf(stderr, "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" - " [-l limit] [-o ssh_option] [-P port] [-S program]\n" + " [-l limit] [-o ssh_option] [-P port] [-w buffer size] [-S program]\n" " [EMAIL PROTECTED]:]file1 [...] [EMAIL PROTECTED]:]file2\n"); exit(1); } diff -urN openssh-4.1p1/serverloop.c openssh-4.1p1-hpn11-none/serverloop.c --- openssh-4.1p1/serverloop.c 2005-08-13 08:09:32.000000000 -0500 +++ openssh-4.1p1-hpn11-none/serverloop.c 2005-08-13 07:17:30.000000000 -0500 @@ -895,6 +895,8 @@ c = channel_new("session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); + if (!(datafellows & SSH_BUG_LARGEWINDOW)) + c->dynamic_window = 1; if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); diff -urN openssh-4.1p1/ssh.c openssh-4.1p1-hpn11-none/ssh.c --- openssh-4.1p1/ssh.c 2005-08-13 08:09:32.000000000 -0500 +++ openssh-4.1p1-hpn11-none/ssh.c 2005-08-13 07:45:41.000000000 -0500 @@ -158,7 +158,7 @@ { fprintf(stderr, "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D port] [-e escape_char] [-F configfile]\n" +" [-D port] [-e escape_char] [-F configfile] [-w receive buffer size]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" @@ -238,9 +238,12 @@ /* Parse command-line arguments. */ host = NULL; + /* need to set options.tcp_rcv_buf to 0 */ + options.tcp_rcv_buf = 0; + again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvw:xzACD:F:I:L:MNO:PR:S:TVXY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -462,6 +465,7 @@ break; case 'T': no_tty_flag = 1; + options.none_switch = 0; break; case 'o': dummy = 1; @@ -485,6 +489,16 @@ case 'F': config = optarg; break; + case 'w': + options.tcp_rcv_buf = atoi(optarg); + break; + case 'z': + /* make sure we can't turn on the none_switch */ + /* if they try to force a no tty flag on a tty session */ + if (!no_tty_flag) { + options.none_switch = 1; + } + break; default: usage(); } @@ -1174,6 +1188,7 @@ window = CHAN_SES_WINDOW_DEFAULT; packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { + window = 4*CHAN_SES_PACKET_DEFAULT; window >>= 1; packetmax >>= 1; } @@ -1181,7 +1196,9 @@ "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - + if (!tty_flag && (!(datafellows & SSH_BUG_LARGEWINDOW))) { + c->dynamic_window = 1; + } debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); diff -urN openssh-4.1p1/sshconnect.c openssh-4.1p1-hpn11-none/sshconnect.c --- openssh-4.1p1/sshconnect.c 2005-08-13 08:09:31.000000000 -0500 +++ openssh-4.1p1-hpn11-none/sshconnect.c 2005-08-13 07:55:02.000000000 -0500 @@ -171,6 +171,26 @@ } /* + * Set TCP receive buffer if requested. + * Note: tuning needs to happen after the socket is + * created but before the connection happens + * so winscale is negotiated properly -cjr + */ +static void +ssh_set_socket_recvbuf(int sock) +{ + void *buf = (void *)&options.tcp_rcv_buf; + int sz = sizeof(options.tcp_rcv_buf); + + if (options.tcp_rcv_buf == 0) + return; + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) + debug("setsockopt SO_RCVBUF set to %d", options.tcp_rcv_buf); + else + error("Couldn't set socket receive buffer to %d: %.100s", + options.tcp_rcv_buf, strerror(errno)); +} +/* * Creates a (possibly privileged) socket for use as the ssh connection. */ static int @@ -193,12 +213,15 @@ strerror(errno)); else debug("Allocated local port %d.", p); + ssh_set_socket_recvbuf(sock); return sock; } sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) error("socket: %.100s", strerror(errno)); + ssh_set_socket_recvbuf(sock); + /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL) return sock; diff -urN openssh-4.1p1/sshconnect2.c openssh-4.1p1-hpn11-none/sshconnect2.c --- openssh-4.1p1/sshconnect2.c 2004-06-14 19:30:09.000000000 -0500 +++ openssh-4.1p1-hpn11-none/sshconnect2.c 2005-08-13 07:47:25.000000000 -0500 @@ -58,6 +58,12 @@ extern char *client_version_string; extern char *server_version_string; extern Options options; +extern Kex *xxx_kex; + +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */ +/* if it is set then prevent the switch to the null cipher */ + +extern int tty_flag; /* * SSH2 key exchange @@ -309,7 +315,15 @@ pubkey_cleanup(&authctxt); dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); - + if ((options.none_switch == 1) && !tty_flag) /* no null on tty sessions */ + { + debug("Requesting none rekeying..."); + myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; + myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; + kex_prop2buf(&xxx_kex->my,myproposal); + packet_request_rekeying(); + fprintf(stderr, "WARNING: ENABLED NULL CIPHER\n"); + } debug("Authentication succeeded (%s).", authctxt.method->name); } diff -urN openssh-4.1p1/version.h openssh-4.1p1-hpn11-none/version.h --- openssh-4.1p1/version.h 2005-08-13 08:09:32.000000000 -0500 +++ openssh-4.1p1-hpn11-none/version.h 2005-08-13 07:27:29.000000000 -0500 @@ -6,4 +6,5 @@ #ifndef SSH_EXTRAVERSION #define SSH_EXTRAVERSION #endif -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_EXTRAVERSION +#define SSH_HPN "-hpn" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN SSH_EXTRAVERSION