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)
This commit is contained in:
Brooks Davis 2011-08-03 19:14:22 +00:00
parent 06521fbb49
commit 8998619212
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=224638
31 changed files with 747 additions and 43 deletions

120
crypto/openssh/README.hpn Normal file
View File

@ -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.

View File

@ -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

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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);

View File

@ -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," \

View File

@ -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

View File

@ -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);

View File

@ -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 @@ process_config_line(Options *options, const char *host,
} 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
}
/*

View File

@ -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

View File

@ -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);

View File

@ -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 *);

View File

@ -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);

View File

@ -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);
}
/*

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -182,6 +182,29 @@ ssh_kill_proxy_command(void)
kill(proxy_command_pid, SIGHUP);
}
/*
* 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.
*/
@ -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));

View File

@ -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);
}

View File

@ -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]);

View File

@ -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

View File

@ -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);

View File

@ -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 *);