summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/openssh/README.hpn120
-rw-r--r--crypto/openssh/buffer.c10
-rw-r--r--crypto/openssh/buffer.h3
-rw-r--r--crypto/openssh/channels.c98
-rw-r--r--crypto/openssh/channels.h10
-rw-r--r--crypto/openssh/cipher.c14
-rw-r--r--crypto/openssh/clientloop.c36
-rw-r--r--crypto/openssh/compat.c11
-rw-r--r--crypto/openssh/compat.h2
-rw-r--r--crypto/openssh/kex.c26
-rw-r--r--crypto/openssh/kex.h5
-rw-r--r--crypto/openssh/misc.c32
-rw-r--r--crypto/openssh/misc.h2
-rw-r--r--crypto/openssh/myproposal.h5
-rw-r--r--crypto/openssh/packet.c26
-rw-r--r--crypto/openssh/packet.h7
-rw-r--r--crypto/openssh/readconf.c92
-rw-r--r--crypto/openssh/readconf.h12
-rw-r--r--crypto/openssh/servconf.c66
-rw-r--r--crypto/openssh/servconf.h10
-rw-r--r--crypto/openssh/serverloop.c15
-rw-r--r--crypto/openssh/session.c18
-rw-r--r--crypto/openssh/sftp.13
-rw-r--r--crypto/openssh/sftp.c3
-rw-r--r--crypto/openssh/ssh.c54
-rw-r--r--crypto/openssh/sshconnect.c30
-rw-r--r--crypto/openssh/sshconnect2.c34
-rw-r--r--crypto/openssh/sshd.c19
-rw-r--r--crypto/openssh/sshd_config12
-rw-r--r--crypto/openssh/version.c10
-rw-r--r--crypto/openssh/version.h5
31 files changed, 747 insertions, 43 deletions
diff --git a/crypto/openssh/README.hpn b/crypto/openssh/README.hpn
new file mode 100644
index 0000000..674827f
--- /dev/null
+++ b/crypto/openssh/README.hpn
@@ -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.
diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c
index ae97003..a3202c6 100644
--- a/crypto/openssh/buffer.c
+++ b/crypto/openssh/buffer.c
@@ -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
diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h
index e2a9dd1..c35f53f 100644
--- a/crypto/openssh/buffer.h
+++ b/crypto/openssh/buffer.h
@@ -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);
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 *);
diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
index 6abe2d0..bf7072a 100644
--- a/crypto/openssh/channels.c
+++ b/crypto/openssh/channels.c
@@ -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, char *rtype);
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 rfd, int wfd, int efd,
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 *readset, fd_set *writeset)
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, const char *listen_addr,
*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_offset, int x11_use_localhost,
*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;
}
diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
index 0680ed0..a967a7e 100644
--- a/crypto/openssh/channels.h
+++ b/crypto/openssh/channels.h
@@ -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
diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c
index bb5c0ac..28afa45 100644
--- a/crypto/openssh/cipher.c
+++ b/crypto/openssh/cipher.c
@@ -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_char *iv, u_int len)
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_char *iv)
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:
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index f6c1444..05487f2 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -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_type, int rchan)
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_type, int rchan)
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 local_tun, int remote_tun)
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)
diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c
index df3541d..d685f6d 100644
--- a/crypto/openssh/compat.c
+++ b/crypto/openssh/compat.c
@@ -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;
}
}
diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h
index 16cf282..b840526 100644
--- a/crypto/openssh/compat.h
+++ b/crypto/openssh/compat.h
@@ -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);
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index c65e28f..ca3c420 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -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,
diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
index 7373d3c..fc5bdf6 100644
--- a/crypto/openssh/kex.h
+++ b/crypto/openssh/kex.h
@@ -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 *);
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index 919b04e..1fc3ae7 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -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);
+}
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index 65cf4a6..19149ed 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -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);
diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h
index 2c43607..30948c2 100644
--- a/crypto/openssh/myproposal.h
+++ b/crypto/openssh/myproposal.h
@@ -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," \
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
index b4e01f7..6f2bdc3 100644
--- a/crypto/openssh/packet.c
+++ b/crypto/openssh/packet.c
@@ -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
diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h
index d516aae..16e33cd 100644
--- a/crypto/openssh/packet.h
+++ b/crypto/openssh/packet.h
@@ -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);
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);
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index 43779af..17a93a6 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -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
}
/*
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index ee160df..195f6e7 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -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
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index c742e130..96761e7 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -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)
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(ServerOptions *options)
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 },
{ "ipqos", sIPQoS, SSHCFG_ALL },
+ { "hpndisabled", sHPNDisabled, SSHCFG_ALL },
+ { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
+ { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
+#ifdef NONE_CIPHER_ENABLED
+ { "noneenabled", sNoneEnabled, SSHCFG_ALL },
+#endif
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
@@ -1409,6 +1457,24 @@ process_server_config_line(ServerOptions *options, char *line,
} while (arg != NULL && *arg != '\0');
break;
+ case sHPNDisabled:
+ intptr = &options->hpn_disabled;
+ goto parse_flag;
+
+ case sHPNBufferSize:
+ intptr = &options->hpn_buffer_size;
+ goto parse_int;
+
+ case sTcpRcvBufPoll:
+ intptr = &options->tcp_rcv_buf_poll;
+ goto parse_flag;
+
+#ifdef NONE_CIPHER_ENABLED
+ case sNoneEnabled:
+ intptr = &options->none_enabled;
+ goto parse_flag;
+#endif
+
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index 5a058a4..f6aadac 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -1,4 +1,5 @@
/* $OpenBSD: servconf.h,v 1.95 2010/11/13 23:27:50 djm Exp $ */
+/* $OpenBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -160,6 +161,15 @@ typedef struct {
char *revoked_keys_file;
char *trusted_user_ca_keys;
char *authorized_principals_file;
+
+ int hpn_disabled; /* Disable HPN functionality. */
+ int hpn_buffer_size; /* Set HPN buffer size - default 2MB.*/
+ int tcp_rcv_buf_poll; /* Poll TCP rcv window in autotuning
+ * kernels. */
+
+#ifdef NONE_CIPHER_ENABLED
+ int none_enabled; /* Enable NONE cipher switch. */
+#endif
} ServerOptions;
void initialize_server_options(ServerOptions *);
diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c
index 8be01c5..7606937 100644
--- a/crypto/openssh/serverloop.c
+++ b/crypto/openssh/serverloop.c
@@ -1,4 +1,5 @@
/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */
+/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -726,7 +727,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
/* Wait until all output has been sent to the client. */
drain_output();
- debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
+ debug("End of interactive session; stdin %ld, stdout (read %ld, " "sent %ld), stderr %ld bytes.",
stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
/* Free and clear the buffers. */
@@ -998,8 +999,14 @@ server_request_tun(void)
sock = tun_open(tun, mode);
if (sock < 0)
goto done;
- c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
+ if (options.hpn_disabled)
+ c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
+ CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
+ "tun", 1);
+ else
+ c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
+ options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0,
+ "tun", 1);
c->datagram = 1;
#if defined(SSH_TUN_FILTER)
if (mode == SSH_TUNMODE_POINTOPOINT)
@@ -1035,6 +1042,8 @@ server_request_session(void)
c = channel_new("session", SSH_CHANNEL_LARVAL,
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
0, "server-session", 1);
+ if (!options.hpn_disabled && options.tcp_rcv_buf_poll)
+ 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 --git a/crypto/openssh/session.c b/crypto/openssh/session.c
index 242a861..b04e629 100644
--- a/crypto/openssh/session.c
+++ b/crypto/openssh/session.c
@@ -1,4 +1,5 @@
/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -232,7 +233,10 @@ auth_input_request_forwarding(struct passwd * pw)
goto authsock_err;
}
- /* Allocate a channel for the authentication agent socket. */
+ /*
+ * Allocate a channel for the authentication agent socket.
+ * Ignore HPN on that one given no improvement expected.
+ */
nc = channel_new("auth socket",
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
@@ -2283,10 +2287,14 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
*/
if (s->chanid == -1)
fatal("no channel for session %d", s->self);
- channel_set_fds(s->chanid,
- fdout, fdin, fderr,
- ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
- 1, is_tty, CHAN_SES_WINDOW_DEFAULT);
+ if (options.hpn_disabled)
+ channel_set_fds(s->chanid, fdout, fdin, fderr,
+ ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ 1, is_tty, CHAN_SES_WINDOW_DEFAULT);
+ else
+ channel_set_fds(s->chanid, fdout, fdin, fderr,
+ ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ 1, is_tty, options.hpn_buffer_size);
}
/*
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index 6b506fe..4169482 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -242,7 +242,8 @@ diagnostic messages from
Specify how many requests may be outstanding at any one time.
Increasing this may slightly improve file transfer speed
but will increase memory usage.
-The default is 64 outstanding requests.
+The default is 256 outstanding requests providing for 8MB
+of outstanding data with a 32KB buffer.
.It Fl r
Recursively copy entire directories when uploading and downloading.
Note that
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index ab667f5..0fb420a 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -1,4 +1,5 @@
/* $OpenBSD: sftp.c,v 1.132 2010/12/04 00:18:01 djm Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -69,7 +70,7 @@ typedef void EditLine;
#include "sftp-client.h"
#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */
-#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */
+#define DEFAULT_NUM_REQUESTS 256 /* # concurrent outstanding requests */
/* File to read commands from */
FILE* infile;
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index c9b29fb..1d21f93 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,4 +1,5 @@
/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */
+/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -546,6 +547,15 @@ main(int ac, char **av)
break;
case 'T':
no_tty_flag = 1;
+#ifdef NONE_CIPHER_ENABLED
+ /*
+ * Ensure that the user does not try to backdoor a
+ * NONE cipher switch on an interactive session by
+ * explicitly disabling it if the user asks for a
+ * session without a tty.
+ */
+ options.none_switch = 0;
+#endif
break;
case 'o':
dummy = 1;
@@ -1368,9 +1378,46 @@ ssh_session2_open(void)
if (!isatty(err))
set_nonblock(err);
- window = CHAN_SES_WINDOW_DEFAULT;
+ /*
+ * We need to check to see what to do about buffer sizes here.
+ * - In an HPN to non-HPN connection we want to limit the window size to
+ * something reasonable in case the far side has the large window bug.
+ * - In an HPN to HPN connection we want to use the max window size but
+ * allow the user to override it.
+ * - Lastly if HPN is disabled then use the ssh standard window size.
+ *
+ * We cannot just do a getsockopt() here and set the ssh window to that
+ * as in case of autotuning of socket buffers the window would get stuck
+ * at the initial buffer size, generally less than 96k. Therefore we
+ * need to set the maximum ssh window size to the maximum HPN buffer
+ * size unless the user has set TcpRcvBufPoll to no. In that case we
+ * can just set the window to the minimum of HPN buffer size and TCP
+ * receive buffer size.
+ */
+ if (tty_flag)
+ options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
+ else
+ options.hpn_buffer_size = CHAN_HPN_MIN_WINDOW_DEFAULT;
+
+ if (datafellows & SSH_BUG_LARGEWINDOW) {
+ debug("HPN to Non-HPN Connection");
+ } else if (options.tcp_rcv_buf_poll <= 0) {
+ sock_get_rcvbuf(&options.hpn_buffer_size, 0);
+ debug("HPNBufferSize set to TCP RWIN: %d",
+ options.hpn_buffer_size);
+ } else if (options.tcp_rcv_buf > 0) {
+ sock_get_rcvbuf(&options.hpn_buffer_size,
+ options.tcp_rcv_buf);
+ debug("HPNBufferSize set to user TCPRcvBuf: %d",
+ options.hpn_buffer_size);
+ }
+ debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
+ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
+ window = options.hpn_buffer_size;
+
packetmax = CHAN_SES_PACKET_DEFAULT;
if (tty_flag) {
+ window = CHAN_SES_WINDOW_DEFAULT;
window >>= 1;
packetmax >>= 1;
}
@@ -1378,7 +1425,10 @@ ssh_session2_open(void)
"session", SSH_CHANNEL_OPENING, in, out, err,
window, packetmax, CHAN_EXTENDED_WRITE,
"client-session", /*nonblock*/0);
-
+ if (!options.hpn_disabled && options.tcp_rcv_buf_poll > 0) {
+ c->dynamic_window = 1;
+ debug("Enabled Dynamic Window Scaling\n");
+ }
debug3("ssh_session2_open: channel_new: %d", c->self);
channel_send_open(c->self);
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index 3e55b5d..0615b44 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -183,6 +183,29 @@ ssh_kill_proxy_command(void)
}
/*
+ * 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.
+ */
+static void
+ssh_set_socket_recvbuf(int sock)
+{
+ void *buf = (void *)&options.tcp_rcv_buf;
+ int socksize, sz = sizeof(options.tcp_rcv_buf);
+ socklen_t len = sizeof(int);
+
+ debug("setsockopt attempting to set SO_RCVBUF to %d",
+ options.tcp_rcv_buf);
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &len);
+ debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno),
+ socksize);
+ } 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
@@ -205,6 +228,8 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
strerror(errno));
else
debug("Allocated local port %d.", p);
+ if (options.tcp_rcv_buf > 0)
+ ssh_set_socket_recvbuf(sock);
return sock;
}
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
@@ -214,6 +239,9 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
}
fcntl(sock, F_SETFD, FD_CLOEXEC);
+ if (options.tcp_rcv_buf > 0)
+ ssh_set_socket_recvbuf(sock);
+
/* Bind the socket to an alternative local IP address */
if (options.bind_address == NULL)
return sock;
@@ -557,7 +585,7 @@ ssh_exchange_identification(int timeout_ms)
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
compat20 ? PROTOCOL_MINOR_2 : minor1,
- SSH_VERSION, compat20 ? "\r\n" : "\n");
+ SSH_RELEASE, compat20 ? "\r\n" : "\n");
if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
!= strlen(buf))
fatal("write: %.100s", strerror(errno));
diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
index 3cb9b10..7352276 100644
--- a/crypto/openssh/sshconnect2.c
+++ b/crypto/openssh/sshconnect2.c
@@ -1,4 +1,5 @@
/* $OpenBSD: sshconnect2.c,v 1.186 2010/11/29 23:45:51 djm Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -81,6 +82,16 @@
extern char *client_version_string;
extern char *server_version_string;
extern Options options;
+#ifdef NONE_CIPHER_ENABLED
+extern Kex *xxx_kex;
+
+/*
+ * tty_flag is set in ssh.c so we can use it here. If set then prevent
+ * the switch to the null cipher.
+ */
+
+extern int tty_flag;
+#endif
/*
* SSH2 key exchange
@@ -419,6 +430,29 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
pubkey_cleanup(&authctxt);
dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
+#ifdef NONE_CIPHER_ENABLED
+ /*
+ * If the user explicitly requests to use the none cipher enable it
+ * post authentication and only if the right conditions are met: both
+ * of the NONE switches must be true and there must be no tty allocated.
+ */
+ if (options.none_switch == 1 && options.none_enabled == 1) {
+ if (!tty_flag) {
+ debug("Requesting none cipher re-keying...");
+ 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 NONE cipher\n");
+ } else {
+ /* Requested NONE cipher on an interactive session. */
+ debug("Cannot switch to NONE cipher with tty "
+ "allocated");
+ fprintf(stderr, "NONE cipher switch disabled given "
+ "a TTY is allocated\n");
+ }
+ }
+#endif
debug("Authentication succeeded (%s).", authctxt.method->name);
}
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 18d2d8e8..a6c9943 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -1,4 +1,5 @@
/* $OpenBSD: sshd.c,v 1.381 2011/01/11 06:13:10 djm Exp $ */
+/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -429,7 +430,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
minor = PROTOCOL_MINOR_1;
}
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
- SSH_VERSION, newline);
+ SSH_RELEASE, newline);
server_version_string = xstrdup(buf);
/* Send our protocol version identification. */
@@ -1011,6 +1012,8 @@ server_listen(void)
int ret, listen_sock, on = 1;
struct addrinfo *ai;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+ int socksize;
+ socklen_t len;
for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
@@ -1051,6 +1054,11 @@ server_listen(void)
debug("Bind to port %s on %s.", strport, ntop);
+ len = sizeof(socksize);
+ getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &socksize, &len);
+ debug("Server TCP RWIN socket size: %d", socksize);
+ debug("HPN Buffer Size: %d", options.hpn_buffer_size);
+
/* Bind the socket to the desired port. */
if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
error("Bind to port %s on %s failed: %.200s.",
@@ -1960,6 +1968,9 @@ main(int ac, char **av)
/* Log the connection. */
verbose("Connection from %.500s port %d", remote_ip, remote_port);
+ /* Set HPN options for the child. */
+ channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
+
/*
* We don't want to listen forever unless the other side
* successfully authenticates itself. So we set up an alarm which is
@@ -2319,6 +2330,12 @@ do_ssh2_kex(void)
if (options.ciphers != NULL) {
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
+#ifdef NONE_CIPHER_ENABLED
+ } else if (options.none_enabled == 1) {
+ debug ("WARNING: None cipher enabled");
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
+#endif
}
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index 7858e78..f507951 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -117,6 +117,18 @@
# override default of no subsystems
Subsystem sftp /usr/libexec/sftp-server
+# Disable HPN tuning improvements.
+#HPNDisabled no
+
+# Buffer size for HPN to non-HPN connections.
+#HPNBufferSize 2048
+
+# TCP receive socket buffer polling for HPN. Disable on non autotuning kernels.
+#TcpRcvBufPoll yes
+
+# Allow the use of the NONE cipher.
+#NoneEnabled no
+
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
diff --git a/crypto/openssh/version.c b/crypto/openssh/version.c
index 88361ae..3cb4b7a 100644
--- a/crypto/openssh/version.c
+++ b/crypto/openssh/version.c
@@ -40,7 +40,7 @@ const char *
ssh_version_get(void) {
if (version == NULL)
- version = xstrdup(SSH_VERSION_BASE " " SSH_VERSION_ADDENDUM);
+ version = xstrdup(SSH_VERSION);
return (version);
}
@@ -50,11 +50,13 @@ ssh_version_set_addendum(const char *add) {
size_t size;
if (add != NULL) {
- size = strlen(SSH_VERSION_BASE) + 1 + strlen(add) + 1;
+ size = strlen(SSH_VERSION_BASE) + strlen(SSH_VERSION_HPN) + 1 +
+ strlen(add) + 1;
newvers = xmalloc(size);
- snprintf(newvers, size, "%s %s", SSH_VERSION_BASE, add);
+ snprintf(newvers, size, "%s %s", SSH_VERSION_BASE,
+ SSH_VERSION_HPN, add);
} else {
- newvers = xstrdup(SSH_VERSION_BASE);
+ newvers = xstrdup(SSH_VERSION_BASE SSH_VERSION_HPN);
}
if (version != NULL)
xfree(version);
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index 00dbdf3..a154892 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -3,10 +3,11 @@
#ifndef SSH_VERSION
-#define SSH_VERSION (ssh_version_get())
-#define SSH_RELEASE (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_5.8p2"
#define SSH_VERSION_ADDENDUM "FreeBSD-20110503"
+#define SSH_VERSION_HPN "_hpn13v11"
+#define SSH_VERSION SSH_VERSION_BASE SSH_VERSION_HPN " " SSH_VERSION_ADDENDUM
+#define SSH_RELEASE (ssh_version_get())
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *);
OpenPOWER on IntegriCloud