Date: Wed, 3 Aug 2011 19:14:22 +0000 (UTC) From: Brooks Davis <brooks@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r224638 - head/crypto/openssh Message-ID: <201108031914.p73JEMeh026068@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: brooks Date: Wed Aug 3 19:14:22 2011 New Revision: 224638 URL: http://svn.freebsd.org/changeset/base/224638 Log: Add support for dynamically adjusted buffers to allow the full use of the bandwidth of long fat pipes (i.e. 100Mbps+ trans-oceanic or trans-continental links). Bandwidth-delay products up to 64MB are supported. Also add support (not compiled by default) for the None cypher. The None cypher can only be enabled on non-interactive sessions (those without a pty where -T was not used) and must be enabled in both the client and server configuration files and on the client command line. Additionally, the None cypher will only be activated after authentication is complete. To enable the None cypher you must add -DNONE_CIPHER_ENABLED to CFLAGS via the make command line or in /etc/make.conf. This code is a style(9) compliant version of these features extracted from the patches published at: http://www.psc.edu/networking/projects/hpn-ssh/ Merging this patch has been a collaboration between me and Bjoern. Reviewed by: bz Approved by: re (kib), des (maintainer) Added: head/crypto/openssh/README.hpn Modified: head/crypto/openssh/buffer.c head/crypto/openssh/buffer.h head/crypto/openssh/channels.c head/crypto/openssh/channels.h head/crypto/openssh/cipher.c head/crypto/openssh/clientloop.c head/crypto/openssh/compat.c head/crypto/openssh/compat.h head/crypto/openssh/kex.c head/crypto/openssh/kex.h head/crypto/openssh/misc.c head/crypto/openssh/misc.h head/crypto/openssh/myproposal.h head/crypto/openssh/packet.c head/crypto/openssh/packet.h head/crypto/openssh/readconf.c head/crypto/openssh/readconf.h head/crypto/openssh/servconf.c head/crypto/openssh/servconf.h head/crypto/openssh/serverloop.c head/crypto/openssh/session.c head/crypto/openssh/sftp.1 head/crypto/openssh/sftp.c head/crypto/openssh/ssh.c head/crypto/openssh/sshconnect.c head/crypto/openssh/sshconnect2.c head/crypto/openssh/sshd.c head/crypto/openssh/sshd_config head/crypto/openssh/version.c head/crypto/openssh/version.h Added: head/crypto/openssh/README.hpn ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/crypto/openssh/README.hpn Wed Aug 3 19:14:22 2011 (r224638) @@ -0,0 +1,120 @@ +Notes: + +NONE CIPHER: + To use the NONE option you must have the NoneEnabled switch set on the server + and you MUST have *both* NoneEnabled and NoneSwitch set to yes on the client. + The NONE feature works with ALL ssh subsystems (as far as we can tell) + as long as there is no tty allocated. + If a user uses the -T switch to prevent a tty being created the NONE cipher + will be disabled. + + +PERFORMANCE: + The performance increase will only be as good as the network and TCP stack + tuning on the reciever side of the connection allows. As a rule of thumb a + user will need at least 10Mb/s connection with a 100ms RTT to see a doubling + of performance. + The HPN-SSH home page http://www.psc.edu/networking/projects/hpn-ssh + describes this in greater detail. + + +BUFFER SIZES: +- if HPN is disabled the receive buffer size will be set to the OpenSSH default + of 64K. + +- if a HPN system connects to a non-HPN system the receive buffer will + be set to the HPNBufferSize value. The default is 2MB but user adjustable. + +- If a HPN to HPN connection is established a number of different things might + happen based on the user options and conditions. + + Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set + Result: HPN Buffer Size = up to 64MB + This is the default state. The HPN buffer size will grow to a maximum of + 64MB as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB + is geared towards 10GigE transcontinental connections. + + Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set + Result: HPN Buffer Size = TCP receive buffer value. + Users on non-autotuning systesm should disable TCPRcvBufPoll in the + ssh_cofig and sshd_config + + Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set + Result: HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. + This would be the system defined TCP receive buffer (RWIN). + + Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET + Result: HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. + Generally there is no need to set both. + + Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set + Result: HPN Buffer Size = grows to HPNBufferSize + The buffer will grow up to the maximum size specified here. + + Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET + Result: HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. + Generally there is no need to set both of these, especially on autotuning + systems. However, if the users wishes to override the autotuning this would + be one way to do it. + + Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET + Result: HPN Buffer Size = TCPRcvBuf. + This will override autotuning and set the TCP recieve buffer to the user + defined value. + + +HPN SPECIFIC CONFIGURATION OPTIONS: + +- HPNDisabled=[yes/no] client/server + In some situations, such as transfers on a local area network, the impact + of the HPN code produces a net decrease in performance. In these cases it is + helpful to disable the HPN functionality. By default HPNDisabled is set to no. + +- HPNBufferSize=[int]KB client/server + This is the default buffer size the HPN functionality uses when interacting + with non-HPN SSH installations. Conceptually this is similar to the TcpRcvBuf + option as applied to the internal SSH flow control. This value can range from + 1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause + performance problems depending on the roud trip time of the network path. + The default size of this buffer is 2MB. + +- TcpRcvBufPoll=[yes/no] client/server + Enable or disable the polling of the TCP receive buffer through the life + of the connection. You would want to make sure that this option is enabled + for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista, + FreeBSD 7.x and later). Default is yes. + +- TcpRcvBuf=[int]KB client + Set the TCP socket receive buffer to n Kilobytes. It can be set up to the + maximum socket size allowed by the system. This is useful in situations where + the TCP receive window is set low but the maximum buffer size is set higher + (as is typical). This works on a per TCP connection basis. You can also use + this to artifically limit the transfer rate of the connection. In these cases + the throughput will be no more than n/RTT. The minimum buffer size is 1KB. + Default is the current system wide TCP receive buffer size. + +- NoneEnabled=[yes/no] client/server + Enable or disable the use of the None cipher. Care must always be used when + enabling this as it will allow users to send data in the clear. However, it + is important to note that authentication information remains encrypted even + if this option is enabled. Set to no by default. + +- NoneSwitch=[yes/no] client + Switch the encryption cipher being used to the None cipher after + authentication takes place. NoneEnabled must be enabled on both the client + and server side of the connection. When the connection switches to the NONE + cipher a warning is sent to STDERR. The connection attempt will fail with an + error if a client requests a NoneSwitch from the server that does not + explicitly have NoneEnabled set to yes. + Note: The NONE cipher cannot be used in interactive (shell) sessions and it + will fail silently. Set to no by default. + + +CREDITS: + + This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu) + The majority of the actual coding for versions up to HPN12v1 was performed + by Michael Stevens (mstevens@andrew.cmu.edu). + The MT-AES-CTR cipher was implemented by Ben Bennet (ben@psc.edu). + This work was financed, in part, by Cisco System, Inc., the National Library + of Medicine, and the National Science Foundation. Modified: head/crypto/openssh/buffer.c ============================================================================== --- head/crypto/openssh/buffer.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/buffer.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: buffer.c,v 1.32 2010/02/09 03:56:28 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -25,7 +26,7 @@ #include "log.h" #define BUFFER_MAX_CHUNK 0x100000 -#define BUFFER_MAX_LEN 0xa00000 +#define BUFFER_MAX_LEN 0x4000000 /* 64MB */ #define BUFFER_ALLOCSZ 0x008000 /* Initializes the buffer structure. */ @@ -165,6 +166,13 @@ buffer_len(const Buffer *buffer) return buffer->end - buffer->offset; } +/* Returns the maximum number of bytes of data that may be in the buffer. */ +u_int +buffer_get_max_len(void) +{ + return (BUFFER_MAX_LEN); +} + /* Gets data from the beginning of the buffer. */ int Modified: head/crypto/openssh/buffer.h ============================================================================== --- head/crypto/openssh/buffer.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/buffer.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: buffer.h,v 1.21 2010/08/31 11:54:45 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -46,6 +47,8 @@ int buffer_get_ret(Buffer *, void *, u_ int buffer_consume_ret(Buffer *, u_int); int buffer_consume_end_ret(Buffer *, u_int); +u_int buffer_get_max_len(void); + #include <openssl/bn.h> void buffer_put_bignum(Buffer *, const BIGNUM *); Modified: head/crypto/openssh/channels.c ============================================================================== --- head/crypto/openssh/channels.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/channels.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -170,6 +171,11 @@ static void port_open_helper(Channel *c, static int connect_next(struct channel_connect *); static void channel_connect_ctx_free(struct channel_connect *); +/* -- HPN */ + +static int hpn_disabled = 0; +static u_int buffer_size = CHAN_HPN_MIN_WINDOW_DEFAULT; + /* -- channel core */ Channel * @@ -309,6 +315,7 @@ channel_new(char *ctype, int type, int r c->self = found; c->type = type; c->ctype = ctype; + c->dynamic_window = 0; c->local_window = window; c->local_window_max = window; c->local_consumed = 0; @@ -808,11 +815,46 @@ channel_pre_open_13(Channel *c, fd_set * FD_SET(c->sock, writeset); } +static u_int +channel_tcpwinsz(void) +{ + u_int32_t tcpwinsz; + socklen_t optsz; + int ret, sd; + u_int maxlen; + + /* If we are not on a socket return 128KB. */ + if (!packet_connection_is_on_socket()) + return (128 * 1024); + + tcpwinsz = 0; + optsz = sizeof(tcpwinsz); + sd = packet_get_connection_in(); + ret = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); + + /* Return no more than the maximum buffer size. */ + maxlen = buffer_get_max_len(); + if ((ret == 0) && tcpwinsz > maxlen) + tcpwinsz = maxlen; + /* In case getsockopt() failed return a minimum. */ + if (tcpwinsz == 0) + tcpwinsz = CHAN_TCP_WINDOW_DEFAULT; + debug2("tcpwinsz: %d for connection: %d", tcpwinsz, sd); + return (tcpwinsz); +} + static void channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) { - u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); + u_int limit; + /* Check buffer limits. */ + if (!c->tcpwinsz || c->dynamic_window > 0) + c->tcpwinsz = channel_tcpwinsz(); + + limit = MIN(compat20 ? c->remote_window : packet_get_maxsize(), + 2 * c->tcpwinsz); + if (c->istate == CHAN_INPUT_OPEN && limit > 0 && buffer_len(&c->input) < limit && @@ -1789,14 +1831,25 @@ channel_check_window(Channel *c) c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { + u_int addition = 0; + + /* Adjust max window size if we are in a dynamic environment. */ + if (c->dynamic_window && c->tcpwinsz > c->local_window_max) { + /* + * Grow the window somewhat aggressively to maintain + * pressure. + */ + addition = 1.5 * (c->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; @@ -2634,6 +2687,15 @@ channel_set_af(int af) IPv4or6 = af; } +void +channel_set_hpn(int disabled, u_int buf_size) +{ + hpn_disabled = disabled; + buffer_size = buf_size; + debug("HPN Disabled: %d, HPN Buffer Size: %d", + hpn_disabled, buffer_size); +} + static int channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, int *allocated_listen_port, @@ -2786,10 +2848,18 @@ channel_setup_fwd_listener(int type, con *allocated_listen_port); } - /* Allocate a channel number for the socket. */ - c = channel_new("port listener", type, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, "port listener", 1); + /* + * Allocate a channel number for the socket. Explicitly test + * for hpn disabled option. If true use smaller window size. + */ + if (hpn_disabled) + c = channel_new("port listener", type, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); + else + c = channel_new("port listener", type, sock, sock, -1, + buffer_size, CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); c->path = xstrdup(host); c->host_port = port_to_connect; c->listening_port = listen_port; @@ -3334,10 +3404,16 @@ x11_create_display_inet(int x11_display_ *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); for (n = 0; n < num_socks; n++) { sock = socks[n]; - nc = channel_new("x11 listener", - SSH_CHANNEL_X11_LISTENER, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, - 0, "X11 inet listener", 1); + if (hpn_disabled) + nc = channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); + else + nc = channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + buffer_size, CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; } Modified: head/crypto/openssh/channels.h ============================================================================== --- head/crypto/openssh/channels.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/channels.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: channels.h,v 1.104 2010/05/14 23:29:23 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -125,6 +126,8 @@ struct Channel { u_int local_window_max; u_int local_consumed; u_int local_maxpacket; + u_int tcpwinsz; + int dynamic_window; int extended_usage; int single_connection; @@ -162,11 +165,15 @@ struct Channel { /* default window/packet sizes for tcp/x11-fwd-channel */ #define CHAN_SES_PACKET_DEFAULT (32*1024) #define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT) + #define CHAN_TCP_PACKET_DEFAULT (32*1024) #define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT) + #define CHAN_X11_PACKET_DEFAULT (16*1024) #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) +#define CHAN_HPN_MIN_WINDOW_DEFAULT (2*1024*1024) + /* possible input states */ #define CHAN_INPUT_OPEN 0 #define CHAN_INPUT_WAIT_DRAIN 1 @@ -294,4 +301,7 @@ void chan_rcvd_ieof(Channel *); void chan_write_failed(Channel *); void chan_obuf_empty(Channel *); +/* hpn handler */ +void channel_set_hpn(int, u_int); + #endif Modified: head/crypto/openssh/cipher.c ============================================================================== --- head/crypto/openssh/cipher.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/cipher.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -163,7 +164,12 @@ ciphers_valid(const char *names) 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) { +#ifdef NONE_CIPHER_ENABLED + if (c == NULL || (c->number != SSH_CIPHER_SSH2 && + c->number != SSH_CIPHER_NONE)) { +#else + if (c == NULL || (c->number != SSH_CIPHER_SSH2)) { +#endif debug("bad cipher %s [%s]", p, names); xfree(cipher_list); return 0; @@ -337,6 +343,9 @@ cipher_get_keyiv(CipherContext *cc, u_ch int evplen; switch (c->number) { +#ifdef NONE_CIPHER_ENABLED + case SSH_CIPHER_NONE: +#endif case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: @@ -371,6 +380,9 @@ cipher_set_keyiv(CipherContext *cc, u_ch int evplen = 0; switch (c->number) { +#ifdef NONE_CIPHER_ENABLED + case SSH_CIPHER_NONE: +#endif case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: Modified: head/crypto/openssh/clientloop.c ============================================================================== --- head/crypto/openssh/clientloop.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/clientloop.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1768,9 +1769,14 @@ client_request_x11(const char *request_t sock = x11_connect_display(); if (sock < 0) return NULL; - c = channel_new("x11", - SSH_CHANNEL_X11_OPEN, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); + if (options.hpn_disabled) + c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, "x11", 1); + else + c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, + options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, + 0, "x11", 1); c->force_drain = 1; return c; } @@ -1790,10 +1796,16 @@ client_request_agent(const char *request sock = ssh_get_authentication_socket(); if (sock < 0) return NULL; - c = channel_new("authentication agent connection", - SSH_CHANNEL_OPEN, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, - "authentication agent connection", 1); + if (options.hpn_disabled) + c = channel_new("authentication agent connection", + SSH_CHANNEL_OPEN, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, + "authentication agent connection", 1); + else + c = channel_new("authentication agent connection", + SSH_CHANNEL_OPEN, sock, sock, -1, + options.hpn_buffer_size, options.hpn_buffer_size, 0, + "authentication agent connection", 1); c->force_drain = 1; return c; } @@ -1820,8 +1832,14 @@ client_request_tun_fwd(int tun_mode, int return -1; } - c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + if (options.hpn_disabled) + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "tun", 1); + else + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, + 0, "tun", 1); c->datagram = 1; #if defined(SSH_TUN_FILTER) Modified: head/crypto/openssh/compat.c ============================================================================== --- head/crypto/openssh/compat.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/compat.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -170,6 +171,16 @@ compat_datafellows(const char *version) 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. It is utterly strange to check it from the + * version string and expose the option that way. + */ + if (strstr(version,"OpenSSH") != NULL && + strstr(version,"hpn") == NULL) { + datafellows |= SSH_BUG_LARGEWINDOW; + debug("Remote is not HPN-aware"); + } return; } } Modified: head/crypto/openssh/compat.h ============================================================================== --- head/crypto/openssh/compat.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/compat.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */ +/* $FReeBSD$ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -58,6 +59,7 @@ #define SSH_OLD_FORWARD_ADDR 0x01000000 #define SSH_BUG_RFWD_ADDR 0x02000000 #define SSH_NEW_OPENSSH 0x04000000 +#define SSH_BUG_LARGEWINDOW 0x08000000 void enable_compat13(void); void enable_compat20(void); Modified: head/crypto/openssh/kex.c ============================================================================== --- head/crypto/openssh/kex.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/kex.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -90,8 +91,13 @@ kex_names_valid(const char *names) return 1; } -/* put algorithm proposal into buffer */ +/* Put algorithm proposal into buffer. */ +#ifndef NONE_CIPHER_ENABLED static void +#else +/* Also used in sshconnect2.c. */ +void +#endif kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) { u_int i; @@ -407,6 +413,9 @@ kex_choose_conf(Kex *kex) int nenc, nmac, ncomp; u_int mode, ctos, need; int first_kex_follows, type; +#ifdef NONE_CIPHER_ENABLED + int auth_flag; +#endif my = kex_buf2prop(&kex->my, NULL); peer = kex_buf2prop(&kex->peer, &first_kex_follows); @@ -430,6 +439,10 @@ kex_choose_conf(Kex *kex) } /* Algorithm Negotiation */ +#ifdef NONE_CIPHER_ENABLED + auth_flag = packet_get_authentication_state(); + debug ("AUTH STATE is %d", auth_flag); +#endif for (mode = 0; mode < MODE_MAX; mode++) { newkeys = xcalloc(1, sizeof(*newkeys)); kex->newkeys[mode] = newkeys; @@ -441,6 +454,17 @@ kex_choose_conf(Kex *kex) choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]); choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]); choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); +#ifdef NONE_CIPHER_ENABLED + debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); + if (strcmp(newkeys->enc.name, "none") == 0) { + debug("Requesting NONE. Authflag is %d", auth_flag); + if (auth_flag == 1) + debug("None requested post authentication."); + else + fatal("Pre-authentication none cipher requests " + "are not allowed."); + } +#endif debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, Modified: head/crypto/openssh/kex.h ============================================================================== --- head/crypto/openssh/kex.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/kex.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -140,6 +141,10 @@ struct Kex { int kex_names_valid(const char *); +#ifdef NONE_CIPHER_ENABLED +void kex_prop2buf(Buffer *, char *[PROPOSAL_MAX]); +#endif + Kex *kex_setup(char *[PROPOSAL_MAX]); void kex_finish(Kex *); Modified: head/crypto/openssh/misc.c ============================================================================== --- head/crypto/openssh/misc.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/misc.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -996,3 +997,34 @@ sock_set_v6only(int s) error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); #endif } + +void +sock_get_rcvbuf(int *size, int rcvbuf) +{ + int sock, socksize; + socklen_t socksizelen = sizeof(socksize); + + /* + * Create a socket but do not connect it. We use it + * only to get the rcv socket size. + */ + sock = socket(AF_INET6, SOCK_STREAM, 0); + if (sock < 0) + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + return; + + /* + * If the tcp_rcv_buf option is set and passed in, attempt to set the + * buffer size to its value. + */ + if (rcvbuf) + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, + sizeof(rcvbuf)); + + if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen) == 0) + if (size != NULL) + *size = socksize; + close(sock); +} Modified: head/crypto/openssh/misc.h ============================================================================== --- head/crypto/openssh/misc.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/misc.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: misc.h,v 1.47 2010/11/21 01:01:13 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -36,6 +37,7 @@ void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); void sock_set_v6only(int); +void sock_get_rcvbuf(int *, int); struct passwd *pwcopy(struct passwd *); const char *ssh_gai_strerror(int); Modified: head/crypto/openssh/myproposal.h ============================================================================== --- head/crypto/openssh/myproposal.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/myproposal.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: myproposal.h,v 1.27 2010/09/01 22:42:13 djm Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -75,6 +76,10 @@ "arcfour256,arcfour128," \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" +#ifdef NONE_CIPHER_ENABLED +#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \ + ",none" +#endif #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ Modified: head/crypto/openssh/packet.c ============================================================================== --- head/crypto/openssh/packet.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/packet.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -195,6 +196,9 @@ struct session_state { }; static struct session_state *active_state, *backup_state; +#ifdef NONE_CIPHER_ENABLED +static int rekey_requested = 0; +#endif static struct session_state * alloc_session_state(void) @@ -1861,12 +1865,26 @@ packet_send_ignore(int nbytes) } } +#ifdef NONE_CIPHER_ENABLED +void +packet_request_rekeying(void) +{ + rekey_requested = 1; +} +#endif + #define MAX_PACKETS (1U<<31) int packet_need_rekeying(void) { if (datafellows & SSH_BUG_NOREKEY) return 0; +#ifdef NONE_CIPHER_ENABLED + if (rekey_requested == 1) { + rekey_requested = 0; + return 1; + } +#endif return (active_state->p_send.packets > MAX_PACKETS) || (active_state->p_read.packets > MAX_PACKETS) || @@ -1958,3 +1976,11 @@ packet_restore_state(void) add_recv_bytes(len); } } + +#ifdef NONE_CIPHER_ENABLED +int +packet_get_authentication_state(void) +{ + return (active_state->after_authentication); +} +#endif Modified: head/crypto/openssh/packet.h ============================================================================== --- head/crypto/openssh/packet.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/packet.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: packet.h,v 1.55 2010/11/13 23:27:50 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -38,6 +39,9 @@ void packet_set_interactive(int, int int packet_is_interactive(void); void packet_set_server(void); void packet_set_authenticated(void); +#ifdef NONE_CIPHER_ENABLED +int packet_get_authentication_state(void); +#endif void packet_start(u_char); void packet_put_char(int ch); @@ -117,6 +121,9 @@ do { \ } while (0) int packet_need_rekeying(void); +#ifdef NONE_CIPHER_ENABLED +void packet_request_rekeying(void); +#endif void packet_set_rekey_limit(u_int32_t); void packet_backup_state(void); Modified: head/crypto/openssh/readconf.c ============================================================================== --- head/crypto/openssh/readconf.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/readconf.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -138,6 +139,10 @@ typedef enum { oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, oKexAlgorithms, oIPQoS, + oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf, +#ifdef NONE_CIPHER_ENABLED + oNoneEnabled, oNoneSwitch, +#endif oVersionAddendum, oDeprecated, oUnsupported } OpCodes; @@ -249,6 +254,14 @@ static struct { #endif { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, + { "hpndisabled", oHPNDisabled }, + { "hpnbuffersize", oHPNBufferSize }, + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, +#ifdef NONE_CIPHER_ENABLED + { "noneenabled", oNoneEnabled }, + { "noneswitch", oNoneSwitch }, +#endif { "versionaddendum", oVersionAddendum }, { NULL, oBadOption } @@ -1021,6 +1034,47 @@ parse_int: } while (arg != NULL && *arg != '\0'); break; + case oHPNDisabled: + intptr = &options->hpn_disabled; + goto parse_flag; + + case oHPNBufferSize: + intptr = &options->hpn_buffer_size; + goto parse_int; + + case oTcpRcvBufPoll: + intptr = &options->tcp_rcv_buf_poll; + goto parse_flag; + + case oTcpRcvBuf: + intptr = &options->tcp_rcv_buf; + goto parse_int; + +#ifdef NONE_CIPHER_ENABLED + case oNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; + + /* + * We check to see if the command comes from the command line or not. + * If it does then enable it otherwise fail. NONE must never be a + * default configuration. + */ + case oNoneSwitch: + if (strcmp(filename,"command-line") == 0) { + intptr = &options->none_switch; + goto parse_flag; + } else { + debug("NoneSwitch directive found in %.200s.", + filename); + error("NoneSwitch is found in %.200s.\n" + "You may only use this configuration option " + "from the command line", filename); + error("Continuing..."); + return 0; + } +#endif + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1181,6 +1235,14 @@ initialize_options(Options * options) options->zero_knowledge_password_authentication = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; + options->tcp_rcv_buf_poll = -1; + options->tcp_rcv_buf = -1; +#ifdef NONE_CIPHER_ENABLED + options->none_enabled = -1; + options->none_switch = -1; +#endif } /* @@ -1345,6 +1407,36 @@ fill_default_options(Options * options) /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + if (options->hpn_buffer_size > -1) + { + u_int maxlen; + + /* If a user tries to set the size to 0 set it to 1KB. */ + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1024; + /* Limit the buffer to BUFFER_MAX_LEN. */ + maxlen = buffer_get_max_len(); + if (options->hpn_buffer_size > (maxlen / 1024)) { + debug("User requested buffer larger than %ub: %ub. " + "Request reverted to %ub", maxlen, + options->hpn_buffer_size * 1024, maxlen); + options->hpn_buffer_size = maxlen; + } + debug("hpn_buffer_size set to %d", options->hpn_buffer_size); + } + if (options->tcp_rcv_buf == 0) + options->tcp_rcv_buf = 1; + if (options->tcp_rcv_buf > -1) + options->tcp_rcv_buf *= 1024; + if (options->tcp_rcv_buf_poll == -1) + options->tcp_rcv_buf_poll = 1; +#ifdef NONE_CIPHER_ENABLED + /* options->none_enabled must not be set by default */ + if (options->none_switch == -1) + options->none_switch = 0; +#endif } /* Modified: head/crypto/openssh/readconf.h ============================================================================== --- head/crypto/openssh/readconf.h Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/readconf.h Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -132,6 +133,17 @@ typedef struct { int use_roaming; + int hpn_disabled; /* Switch to disable HPN buffer management. */ + int hpn_buffer_size; /* User definable size for HPN buffer + * window. */ + int tcp_rcv_buf_poll; /* Option to poll recv buf every window + * transfer. */ + int tcp_rcv_buf; /* User switch to set tcp recv buffer. */ + +#ifdef NONE_CIPHER_ENABLED + int none_enabled; /* Allow none to be used */ + int none_switch; /* Use none cipher */ +#endif } Options; #define SSHCTL_MASTER_NO 0 Modified: head/crypto/openssh/servconf.c ============================================================================== --- head/crypto/openssh/servconf.c Wed Aug 3 18:50:19 2011 (r224637) +++ head/crypto/openssh/servconf.c Wed Aug 3 19:14:22 2011 (r224638) @@ -1,4 +1,5 @@ /* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */ +/* $FreeBSD$ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -141,6 +142,12 @@ initialize_server_options(ServerOptions options->authorized_principals_file = NULL; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; + options->tcp_rcv_buf_poll = -1; +#ifdef NONE_CIPHER_ENABLED + options->none_enabled = -1; +#endif } void @@ -283,6 +290,37 @@ fill_default_server_options(ServerOption options->ip_qos_interactive = IPTOS_LOWDELAY; if (options->ip_qos_bulk == -1) options->ip_qos_bulk = IPTOS_THROUGHPUT; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + if (options->hpn_buffer_size == -1) { + /* + * HPN buffer size option not explicitly set. Try to figure + * out what value to use or resort to default. + */ + options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + if (!options->hpn_disabled) { + sock_get_rcvbuf(&options->hpn_buffer_size, 0); + debug ("HPN Buffer Size: %d", options->hpn_buffer_size); + } + } else { + /* + * In the case that the user sets both values in a + * contradictory manner hpn_disabled overrrides hpn_buffer_size. + */ + if (options->hpn_disabled <= 0) { + u_int maxlen; + + maxlen = buffer_get_max_len(); + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1; + /* Limit the maximum buffer to BUFFER_MAX_LEN. */ + if (options->hpn_buffer_size > maxlen / 1024) + options->hpn_buffer_size = maxlen; + else + options->hpn_buffer_size *= 1024; + } else + options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT; + } /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -330,6 +368,10 @@ typedef enum { sZeroKnowledgePasswordAuthentication, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, sKexAlgorithms, sIPQoS, + sHPNDisabled, sHPNBufferSize, sTcpRcvBufPoll, +#ifdef NONE_CIPHER_ENABLED + sNoneEnabled, +#endif sVersionAddendum, sDeprecated, sUnsupported } ServerOpCodes; @@ -455,6 +497,12 @@ static struct { { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108031914.p73JEMeh026068>