From: jbasney Date: Thu, 15 Feb 2007 17:20:11 +0000 (+0000) Subject: http://www.psc.edu/networking/projects/hpn-ssh/openssh-4.5p1-hpn12v14.diff.gz X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/commitdiff_plain/refs/heads/OPENSSH_4_5P1_SIMON_20061220_HPN12V14 http://www.psc.edu/networking/projects/hpn-ssh/openssh-4.5p1-hpn12v14.diff.gz --- diff --git a/openssh/buffer.c b/openssh/buffer.c index e02e1e3..f7be849 100644 --- a/openssh/buffer.c +++ b/openssh/buffer.c @@ -26,7 +26,9 @@ #define BUFFER_MAX_CHUNK 0x100000 #define BUFFER_MAX_LEN 0xa00000 -#define BUFFER_ALLOCSZ 0x008000 +/* try increasing to 256k in hpnxfers */ +#define BUFFER_ALLOCSZ 0x008000 /* 32k */ +#define BUFFER_ALLOCSZ_HPN 0x040000 /* 256k */ /* Initializes the buffer structure. */ @@ -42,6 +44,7 @@ buffer_init(Buffer *buffer) buffer->end = 0; } + /* Frees any memory used for the buffer. */ void @@ -103,6 +106,8 @@ void * buffer_append_space(Buffer *buffer, u_int len) { u_int newlen; + u_int buf_max; + u_int buf_alloc_sz; void *p; if (len > BUFFER_MAX_CHUNK) @@ -125,9 +130,15 @@ restart: if (buffer_compact(buffer)) goto restart; + // if hpn is disabled use the smaller buffer size + buf_max = BUFFER_MAX_LEN_HPN; + buf_alloc_sz = BUFFER_ALLOCSZ_HPN; + /* Increase the size of the buffer and retry. */ - newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ); - if (newlen > BUFFER_MAX_LEN) + newlen = roundup(buffer->alloc + len, buf_alloc_sz); + + + if (newlen > buf_max) fatal("buffer_append_space: alloc %u not supported", newlen); buffer->buf = xrealloc(buffer->buf, 1, newlen); @@ -143,6 +154,9 @@ restart: int buffer_check_alloc(Buffer *buffer, u_int len) { + u_int buf_max; + u_int buf_alloc_sz; + if (buffer->offset == buffer->end) { buffer->offset = 0; buffer->end = 0; @@ -152,7 +166,12 @@ buffer_check_alloc(Buffer *buffer, u_int len) return (1); if (buffer_compact(buffer)) goto restart; - if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN) + + // if hpn is disabled use the smaller buffer size + buf_max = BUFFER_MAX_LEN_HPN; + buf_alloc_sz = BUFFER_ALLOCSZ_HPN; + + if (roundup(buffer->alloc + len, buf_alloc_sz) <= buf_max) return (1); return (0); } diff --git a/openssh/buffer.h b/openssh/buffer.h index ecc4aea..c062bc0 100644 --- a/openssh/buffer.h +++ b/openssh/buffer.h @@ -15,6 +15,7 @@ #ifndef BUFFER_H #define BUFFER_H +#define BUFFER_MAX_LEN_HPN 0x4000000 /* 64MB */ typedef struct { u_char *buf; /* Buffer for data. */ diff --git a/openssh/channels.c b/openssh/channels.c index 26b63a1..639e69c 100644 --- a/openssh/channels.c +++ b/openssh/channels.c @@ -76,6 +76,7 @@ #include "authfd.h" #include "pathnames.h" + /* -- channel core */ /* @@ -311,6 +312,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->local_window_max = window; c->local_consumed = 0; c->local_maxpacket = maxpack; + c->dynamic_window = 0; c->remote_id = -1; c->remote_name = xstrdup(remote_name); c->remote_window = 0; @@ -765,11 +767,34 @@ channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) FD_SET(c->sock, writeset); } +int channel_tcpwinsz () { + u_int32_t tcpwinsz = 0; + socklen_t optsz = sizeof(tcpwinsz); + int ret = -1; + if(!packet_connection_is_on_socket()) + return(131072); + ret = getsockopt(packet_get_connection_in(), + SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); + if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN) + tcpwinsz = BUFFER_MAX_LEN_HPN; + debug2("tcpwinsz: %d for connection: %d", tcpwinsz, + packet_get_connection_in()); + 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(); + /* check buffer limits */ + if (!c->tcpwinsz) + c->tcpwinsz = channel_tcpwinsz(); + if (c->dynamic_window > 0) + c->tcpwinsz = channel_tcpwinsz(); + + limit = MIN(limit, 2 * c->tcpwinsz); + if (c->istate == CHAN_INPUT_OPEN && limit > 0 && buffer_len(&c->input) < limit && @@ -1658,14 +1683,20 @@ channel_check_window(Channel *c) !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && 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)) { + addition = 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; @@ -2339,7 +2370,8 @@ channel_set_af(int af) static int channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, - const char *host_to_connect, u_short port_to_connect, int gateway_ports) + const char *host_to_connect, u_short port_to_connect, int gateway_ports, + int hpn_disabled, int hpn_buffer_size) { Channel *c; int sock, r, success = 0, wildcard = 0, is_client; @@ -2452,9 +2484,15 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por continue; } /* 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); + /* 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, + hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); strlcpy(c->path, host, sizeof(c->path)); c->host_port = port_to_connect; c->listening_port = listen_port; @@ -2491,20 +2529,22 @@ channel_cancel_rport_listener(const char *host, u_short port) /* protocol local port fwd, used by ssh (and sshd in v1) */ int channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, - const char *host_to_connect, u_short port_to_connect, int gateway_ports) + const char *host_to_connect, u_short port_to_connect, int gateway_ports, + int hpn_disabled, int hpn_buffer_size) { return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, listen_host, listen_port, host_to_connect, port_to_connect, - gateway_ports); + gateway_ports, hpn_disabled, hpn_buffer_size); } /* protocol v2 remote port fwd, used by sshd */ int channel_setup_remote_fwd_listener(const char *listen_address, - u_short listen_port, int gateway_ports) + u_short listen_port, int gateway_ports, int hpn_disabled, int hpn_buffer_size) { return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, - listen_address, listen_port, NULL, 0, gateway_ports); + listen_address, listen_port, NULL, 0, gateway_ports, + hpn_disabled, hpn_buffer_size); } /* @@ -2612,7 +2652,8 @@ channel_request_rforward_cancel(const char *host, u_short port) * message if there was an error). */ int -channel_input_port_forward_request(int is_root, int gateway_ports) +channel_input_port_forward_request(int is_root, int gateway_ports, + int hpn_disabled, int hpn_buffer_size) { u_short port, host_port; int success = 0; @@ -2638,7 +2679,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports) /* Initiate forwarding */ success = channel_setup_local_fwd_listener(NULL, port, hostname, - host_port, gateway_ports); + host_port, gateway_ports, hpn_disabled, hpn_buffer_size); /* Free the argument string. */ xfree(hostname); @@ -2842,7 +2883,8 @@ channel_send_window_changes(void) */ int x11_create_display_inet(int x11_display_offset, int x11_use_localhost, - int single_connection, u_int *display_numberp, int **chanids) + int single_connection, u_int *display_numberp, int **chanids, + int hpn_disabled, int hpn_buffer_size) { Channel *nc = NULL; int display_number, sock; @@ -2939,10 +2981,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, + hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); nc->single_connection = single_connection; (*chanids)[n] = nc->self; } diff --git a/openssh/channels.h b/openssh/channels.h index 2674f09..91bc0ae 100644 --- a/openssh/channels.h +++ b/openssh/channels.h @@ -98,8 +98,10 @@ struct Channel { u_int local_window_max; u_int local_consumed; u_int local_maxpacket; + int dynamic_window; int extended_usage; int single_connection; + u_int tcpwinsz; char *ctype; /* type */ @@ -121,12 +123,17 @@ struct Channel { #define CHAN_EXTENDED_WRITE 2 /* default window/packet sizes for tcp/x11-fwd-channel */ -#define CHAN_SES_PACKET_DEFAULT (32*1024) -#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) -#define CHAN_TCP_PACKET_DEFAULT (32*1024) -#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) -#define CHAN_X11_PACKET_DEFAULT (16*1024) -#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) +#define CHAN_SES_PACKET_DEFAULT (32*1024) +#define CHAN_SES_WINDOW_DEFAULT_HPN (160*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) + +#define CHAN_TCP_PACKET_DEFAULT (32*1024) +#define CHAN_TCP_WINDOW_DEFAULT_HPN (160*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) + +#define CHAN_X11_PACKET_DEFAULT (16*1024) +#define CHAN_X11_WINDOW_DEFAULT_HPN (4*CHAN_X11_PACKET_DEFAULT) +#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) /* possible input states */ #define CHAN_INPUT_OPEN 0 @@ -208,21 +215,21 @@ void channel_add_permitted_opens(char *, int); int channel_add_adm_permitted_opens(char *, int); void channel_clear_permitted_opens(void); void channel_clear_adm_permitted_opens(void); -int channel_input_port_forward_request(int, int); +int channel_input_port_forward_request(int, int, int, int); int channel_connect_to(const char *, u_short); int channel_connect_by_listen_address(u_short); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); int channel_setup_local_fwd_listener(const char *, u_short, - const char *, u_short, int); + const char *, u_short, int, int, int); void channel_request_rforward_cancel(const char *host, u_short port); -int channel_setup_remote_fwd_listener(const char *, u_short, int); +int channel_setup_remote_fwd_listener(const char *, u_short, int, int, int); int channel_cancel_rport_listener(const char *, u_short); /* x11 forwarding */ int x11_connect_display(void); -int x11_create_display_inet(int, int, int, u_int *, int **); +int x11_create_display_inet(int, int, int, u_int *, int **, int, int); void x11_input_open(int, u_int32_t, void *); void x11_request_forwarding_with_spoofing(int, const char *, const char *, const char *); diff --git a/openssh/cipher.c b/openssh/cipher.c index b264063..c484e18 100644 --- a/openssh/cipher.c +++ b/openssh/cipher.c @@ -156,7 +156,8 @@ 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) { + if (c == NULL || (c->number != SSH_CIPHER_SSH2 && +c->number != SSH_CIPHER_NONE)) { debug("bad cipher %s [%s]", p, names); xfree(cipher_list); return 0; @@ -330,6 +331,7 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) int evplen; switch (c->number) { + case SSH_CIPHER_NONE: case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: @@ -364,6 +366,7 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) int evplen = 0; switch (c->number) { + case SSH_CIPHER_NONE: case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: diff --git a/openssh/clientloop.c b/openssh/clientloop.c index 4c51081..2f7ce2b 100644 --- a/openssh/clientloop.c +++ b/openssh/clientloop.c @@ -715,6 +715,10 @@ client_process_control(fd_set *readset) u_int i, len, env_len, command, flags; uid_t euid; gid_t egid; + int listen_port = 0; + int connect_port = 0; + char * listen_host = NULL; + char * connect_host = NULL; /* * Accept connection on control socket @@ -763,6 +767,13 @@ client_process_control(fd_set *readset) command = buffer_get_int(&m); flags = buffer_get_int(&m); + if (SSHMUX_FLAG_PORTFORWARD & flags) + { + listen_host = buffer_get_string(&m,NULL); + listen_port = buffer_get_int(&m); + connect_host = buffer_get_string(&m,NULL); + connect_port = buffer_get_int(&m); + } buffer_clear(&m); switch (command) { @@ -802,6 +813,31 @@ client_process_control(fd_set *readset) return; } + if (allowed && (SSHMUX_FLAG_PORTFORWARD & flags) && listen_host && connect_host) + { + int ret; + Forward * fwd; + + fwd = &options.local_forwards[options.num_local_forwards++]; + fwd->listen_host = xstrdup(listen_host); + fwd->listen_port = listen_port; + fwd->connect_host = xstrdup(connect_host); + fwd->connect_port = connect_port; + ret = channel_setup_local_fwd_listener( + options.local_forwards[options.num_local_forwards-1].listen_host, + options.local_forwards[options.num_local_forwards-1].listen_port, + options.local_forwards[options.num_local_forwards-1].connect_host, + options.local_forwards[options.num_local_forwards-1].connect_port, + options.gateway_ports, options.hpn_disabled, options.hpn_buffer_size); + + } + + + if (listen_host) + xfree(listen_host); + if (connect_host) + xfree(connect_host); + /* Reply for SSHMUX_COMMAND_OPEN */ buffer_clear(&m); buffer_put_int(&m, allowed); @@ -900,11 +936,16 @@ client_process_control(fd_set *readset) set_nonblock(client_fd); - c = channel_new("session", SSH_CHANNEL_OPENING, - new_fd[0], new_fd[1], new_fd[2], - CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, - CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - + if (options.hpn_disabled) + c = channel_new("session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], + CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, + CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); + else + c = channel_new("session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], + options.hpn_buffer_size, CHAN_SES_PACKET_DEFAULT, + CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); /* XXX */ c->ctl_fd = client_fd; @@ -1003,7 +1044,8 @@ process_cmdline(void) if (local) { if (channel_setup_local_fwd_listener(fwd.listen_host, fwd.listen_port, fwd.connect_host, - fwd.connect_port, options.gateway_ports) < 0) { + fwd.connect_port, options.gateway_ports, + options.hpn_disabled, options.hpn_buffer_size) < 0) { logit("Port forwarding failed."); goto out; } @@ -1702,10 +1744,16 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) xfree(listen_address); return NULL; } - c = channel_new("forwarded-tcpip", - SSH_CHANNEL_CONNECTING, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - originator_address, 1); + if (options.hpn_disabled) + c = channel_new("forwarded-tcpip", + SSH_CHANNEL_CONNECTING, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, + originator_address, 1); + else + c = channel_new("forwarded-tcpip", + SSH_CHANNEL_CONNECTING, sock, sock, -1, + options.hpn_buffer_size, options.hpn_buffer_size, 0, + originator_address, 1); xfree(originator_address); xfree(listen_address); return c; @@ -1739,9 +1787,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; } @@ -1760,10 +1813,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_WINDOW_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; } diff --git a/openssh/clientloop.h b/openssh/clientloop.h index beec62f..0be32b4 100644 --- a/openssh/clientloop.h +++ b/openssh/clientloop.h @@ -52,8 +52,10 @@ void client_session2_setup(int, int, int, const char *, struct termios *, #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ +#define SSHMUX_COMMAND_PORTFORWARD 4 /* Ask master to portforward */ #define SSHMUX_FLAG_TTY (1) /* Request tty on open */ #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ #define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ #define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ +#define SSHMUX_FLAG_PORTFORWARD (1<<4) /* Request portforward */ diff --git a/openssh/compat.c b/openssh/compat.c index da67f94..dca641b 100644 --- a/openssh/compat.c +++ b/openssh/compat.c @@ -168,6 +168,15 @@ 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 */ + if(strstr(version,"OpenSSH") != NULL) + { + if (strstr(version,"hpn") == NULL) + { + datafellows |= SSH_BUG_LARGEWINDOW; + debug("Remote is NON-HPN aware"); + } + } return; } } diff --git a/openssh/compat.h b/openssh/compat.h index 83d469d..9123201 100644 --- a/openssh/compat.h +++ b/openssh/compat.h @@ -56,6 +56,7 @@ #define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 +#define SSH_BUG_LARGEWINDOW 0x02000000 void enable_compat13(void); void enable_compat20(void); diff --git a/openssh/kex.c b/openssh/kex.c index b592049..ac74079 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -68,7 +68,7 @@ static void kex_kexinit_finish(Kex *); static void kex_choose_conf(Kex *); /* put algorithm proposal into buffer */ -static void +void kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) { u_int i; diff --git a/openssh/kex.h b/openssh/kex.h index 51d224c..03b623e 100644 --- a/openssh/kex.h +++ b/openssh/kex.h @@ -131,6 +131,8 @@ struct Kex { void (*kex[KEX_MAX])(Kex *); }; +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]); + Kex *kex_setup(char *[PROPOSAL_MAX]); void kex_finish(Kex *); diff --git a/openssh/myproposal.h b/openssh/myproposal.h index e246e0d..f56ec50 100644 --- a/openssh/myproposal.h +++ b/openssh/myproposal.h @@ -46,6 +46,8 @@ "arcfour128,arcfour256,arcfour," \ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ "aes128-ctr,aes192-ctr,aes256-ctr" +#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \ + ",none" #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ diff --git a/openssh/packet.c b/openssh/packet.c index ab5a010..64970e8 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -1576,6 +1576,13 @@ packet_send_ignore(int nbytes) rnd >>= 8; } } +int rekey_requested = 0; + +void +packet_request_rekeying(void) +{ + rekey_requested = 1; +} #define MAX_PACKETS (1U<<31) int @@ -1583,6 +1590,11 @@ packet_need_rekeying(void) { if (datafellows & SSH_BUG_NOREKEY) return 0; + if (rekey_requested == 1) + { + rekey_requested = 0; + return 1; + } return (p_send.packets > MAX_PACKETS) || (p_read.packets > MAX_PACKETS) || diff --git a/openssh/packet.h b/openssh/packet.h index 21ff450..6e5cc07 100644 --- a/openssh/packet.h +++ b/openssh/packet.h @@ -20,6 +20,9 @@ #include +void +packet_request_rekeying(void); + void packet_set_connection(int, int); void packet_set_nonblocking(void); int packet_get_connection_in(void); diff --git a/openssh/readconf.c b/openssh/readconf.c index 0d3c519..53747af 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -132,6 +132,8 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, + oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled, + oHPNBufferSize, oDeprecated, oUnsupported } OpCodes; @@ -232,6 +234,12 @@ static struct { { "tunneldevice", oTunnelDevice }, { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, + { "noneenabled", oNoneEnabled }, + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, + { "noneswitch", oNoneSwitch }, + { "hpndisabled", oHPNDisabled }, + { "hpnbuffersize", oHPNBufferSize }, { NULL, oBadOption } }; @@ -467,10 +475,31 @@ parse_flag: intptr = &options->check_host_ip; goto parse_flag; + case oNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; + + case oNoneSwitch: + intptr = &options->none_switch; + goto parse_flag; + + 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 oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; goto parse_yesnoask; + case oStrictHostKeyChecking: intptr = &options->strict_host_key_checking; parse_yesnoask: @@ -646,6 +675,10 @@ parse_int: intptr = &options->connection_attempts; goto parse_int; + case oTcpRcvBuf: + intptr = &options->tcp_rcv_buf; + goto parse_int; + case oCipher: intptr = &options->cipher; arg = strdelim(&s); @@ -1081,6 +1114,12 @@ initialize_options(Options * options) options->tun_remote = -1; options->local_command = NULL; options->permit_local_command = -1; + options->none_switch = -1; + options->none_enabled = -1; + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; + options->tcp_rcv_buf_poll = -1; + options->tcp_rcv_buf = -1; } /* @@ -1207,6 +1246,27 @@ fill_default_options(Options * options) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; + if (options->none_switch == -1) + options->none_switch = 0; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + if (options->hpn_buffer_size > -1) + { + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1; + /*limit the buffer to 7MB*/ + if (options->hpn_buffer_size > 7168) + { + options->hpn_buffer_size = 7168; + debug("User requested buffer larger than 7MB. Request reverted to 7MB"); + } + options->hpn_buffer_size *=1024; + 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->control_master == -1) options->control_master = 0; if (options->hash_known_hosts == -1) diff --git a/openssh/readconf.h b/openssh/readconf.h index a3d3024..7e1d9f2 100644 --- a/openssh/readconf.h +++ b/openssh/readconf.h @@ -58,6 +58,11 @@ typedef struct { int compression_level; /* Compression level 1 (fast) to 9 * (best). */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ + int tcp_rcv_buf; /* user switch to set tcp recv buffer */ + int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ + int hpn_disabled; /* Switch to disable HPN buffer management */ + int hpn_buffer_size; /* User definable size for HPN buffer window */ + LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ @@ -103,6 +108,8 @@ typedef struct { int enable_ssh_keysign; int rekey_limit; + int none_switch; /* use none cipher */ + int none_enabled; /* Allow none to be used */ int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; diff --git a/openssh/scp.c b/openssh/scp.c index 56a3e79..d6005f8 100644 --- a/openssh/scp.c +++ b/openssh/scp.c @@ -318,8 +318,8 @@ main(int argc, char **argv) case '4': case '6': case 'C': - addargs(&args, "-%c", ch); - break; + addargs(&args, "-%c", ch); + break; case 'o': case 'c': case 'i': @@ -582,7 +582,7 @@ source(int argc, char **argv) off_t i, amt, statbytes; size_t result; int fd = -1, haderr, indx; - char *last, *name, buf[2048]; + char *last, *name, buf[16384]; int len; for (indx = 0; indx < argc; ++indx) { @@ -642,7 +642,7 @@ syserr: run_err("%s: %s", name, strerror(errno)); (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; - if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { + if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; @@ -810,7 +810,7 @@ sink(int argc, char **argv) mode_t mode, omode, mask; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + char ch, *cp, *np, *targ, *why, *vect[1], buf[16384]; struct timeval tv[2]; #define atime tv[0] @@ -971,7 +971,7 @@ bad: run_err("%s: %s", np, strerror(errno)); continue; } (void) atomicio(vwrite, remout, "", 1); - if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) { (void) close(ofd); continue; } @@ -981,8 +981,8 @@ bad: run_err("%s: %s", np, strerror(errno)); statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); - for (count = i = 0; i < size; i += 4096) { - amt = 4096; + for (count = i = 0; i < size; i += sizeof(buf)) { + amt = sizeof(buf); if (i + amt > size) amt = size - i; count += amt; @@ -999,7 +999,7 @@ bad: run_err("%s: %s", np, strerror(errno)); } while (amt > 0); if (limit_rate) - bwlimit(4096); + bwlimit(sizeof(buf)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ diff --git a/openssh/servconf.c b/openssh/servconf.c index 77adea4..74b35e1 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -124,11 +124,19 @@ initialize_server_options(ServerOptions *options) options->permit_tun = -1; options->num_permitted_opens = -1; options->adm_forced_command = NULL; + options->none_enabled = -1; + options->tcp_rcv_buf_poll = -1; + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; } void fill_default_server_options(ServerOptions *options) { + int sock; + int socksize; + int socksizelen = sizeof(int); + /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 0; @@ -256,10 +264,54 @@ fill_default_server_options(ServerOptions *options) if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + + if (options->hpn_buffer_size == -1) + { + /* option not explicitly set. Now we have to figure out */ + /* what value to use */ + if (options->hpn_disabled == 1) + { + options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + } + else + { + /* get the current RCV size and set it to that */ + /*create a socket but don't connect it */ + /* we use that the get the rcv socket size */ + sock = socket(AF_INET, SOCK_STREAM, 0); + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + close(sock); + options->hpn_buffer_size = socksize; + debug ("HPN Buffer Size: %d", options->hpn_buffer_size); + + } + } + else + { + /* we have to do this incase the user sets both values in a contradictory */ + /* manner. hpn_disabled overrrides hpn_buffer_size*/ + if (options->hpn_disabled <= 0) + { + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1; + /* limit the maximum buffer to 64MB */ + if (options->hpn_buffer_size > 64*1024) + options->hpn_buffer_size = 64*1024; + options->hpn_buffer_size *=1024; + } + else + options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + } + /* Turn privilege separation on by default */ if (use_privsep == -1) use_privsep = 1; + + #ifndef HAVE_MMAP if (use_privsep && options->compression == 1) { error("This platform does not support both privilege " @@ -300,7 +352,8 @@ typedef enum { sGssKeyEx, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, - sUsePrivilegeSeparation, + sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, + sHPNDisabled, sHPNBufferSize, sDeprecated, sUnsupported } ServerOpCodes; @@ -415,6 +468,10 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, + { "noneenabled", sNoneEnabled }, + { "hpndisabled", sHPNDisabled }, + { "hpnbuffersize", sHPNBufferSize }, + { "tcprcvbufpoll", sTcpRcvBufPoll }, { NULL, sBadOption, 0 } }; @@ -430,6 +487,7 @@ parse_token(const char *cp, const char *filename, for (i = 0; keywords[i].name; i++) if (strcasecmp(cp, keywords[i].name) == 0) { + debug ("Config token is %s", keywords[i].name); *flags = keywords[i].flags; return keywords[i].opcode; } @@ -840,6 +898,22 @@ parse_flag: *intptr = value; break; + case sNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; + + case sTcpRcvBufPoll: + intptr = &options->tcp_rcv_buf_poll; + goto parse_flag; + + case sHPNDisabled: + intptr = &options->hpn_disabled; + goto parse_flag; + + case sHPNBufferSize: + intptr = &options->hpn_buffer_size; + goto parse_int; + case sIgnoreUserKnownHosts: intptr = &options->ignore_user_known_hosts; goto parse_flag; diff --git a/openssh/servconf.h b/openssh/servconf.h index 7b60292..ccddd2f 100644 --- a/openssh/servconf.h +++ b/openssh/servconf.h @@ -139,6 +139,10 @@ typedef struct { char *adm_forced_command; int use_pam; /* Enable auth via PAM */ + int none_enabled; /* enable NONE cipher switch */ + int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int hpn_buffer_size; /* set the hpn buffer size - default 3MB */ int permit_tun; diff --git a/openssh/serverloop.c b/openssh/serverloop.c index 69304b5..b175471 100644 --- a/openssh/serverloop.c +++ b/openssh/serverloop.c @@ -945,9 +945,14 @@ server_request_direct_tcpip(void) xfree(originator); if (sock < 0) return NULL; - c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING, - sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, - CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); + if (options.hpn_disabled) + c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING, + sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, + CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); + else + c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING, + sock, sock, -1, options.hpn_buffer_size, + CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); return c; } @@ -982,8 +987,12 @@ 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) @@ -1013,6 +1022,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.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) + c->dynamic_window = 1; if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); @@ -1109,7 +1120,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) } else { /* Start listening on the port */ success = channel_setup_remote_fwd_listener( - listen_address, listen_port, options.gateway_ports); + listen_address, listen_port, options.gateway_ports, + options.hpn_disabled, options.hpn_buffer_size); } xfree(listen_address); } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { diff --git a/openssh/session.c b/openssh/session.c index 69153ad..a5a81be 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -211,6 +211,7 @@ auth_input_request_forwarding(struct passwd * pw) packet_disconnect("listen: %.100s", strerror(errno)); /* Allocate a channel for the authentication agent socket. */ + /* this shouldn't matter if its hpn or not - cjr */ nc = channel_new("auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, @@ -348,7 +349,8 @@ do_authenticated1(Authctxt *authctxt) } debug("Received TCP/IP port forwarding request."); if (channel_input_port_forward_request(s->pw->pw_uid == 0, - options.gateway_ports) < 0) { + options.gateway_ports, options.hpn_disabled, + options.hpn_buffer_size) < 0) { debug("Port forwarding failed."); break; } @@ -2058,11 +2060,18 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr) */ if (s->chanid == -1) fatal("no channel for session %d", s->self); - channel_set_fds(s->chanid, - fdout, fdin, fderr, - fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, - 1, - CHAN_SES_WINDOW_DEFAULT); + if(options.hpn_disabled) + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, + 1, + CHAN_SES_WINDOW_DEFAULT); + else + channel_set_fds(s->chanid, + fdout, fdin, fderr, + fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, + 1, + options.hpn_buffer_size); } /* @@ -2407,7 +2416,8 @@ session_setup_x11fwd(Session *s) } if (x11_create_display_inet(options.x11_display_offset, options.x11_use_localhost, s->single_connection, - &s->display_number, &s->x11_chanids) == -1) { + &s->display_number, &s->x11_chanids, + options.hpn_disabled, options.hpn_buffer_size) == -1) { debug("x11_create_display_inet failed."); return 0; } diff --git a/openssh/ssh.c b/openssh/ssh.c index 47297ed..2099325 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -498,9 +498,6 @@ main(int ac, char **av) no_shell_flag = 1; no_tty_flag = 1; break; - case 'T': - no_tty_flag = 1; - break; case 'o': dummy = 1; line = xstrdup(optarg); @@ -509,6 +506,13 @@ main(int ac, char **av) exit(255); xfree(line); break; + case 'T': + no_tty_flag = 1; + /* ensure that the user doesn't try to backdoor a */ + /* null cipher switch on an interactive session */ + /* so explicitly disable it no matter what */ + options.none_switch=0; + break; case 's': subsystem_flag = 1; break; @@ -825,7 +829,8 @@ ssh_init_forwarding(void) options.local_forwards[i].listen_port, options.local_forwards[i].connect_host, options.local_forwards[i].connect_port, - options.gateway_ports); + options.gateway_ports, options.hpn_disabled, + options.hpn_buffer_size); } if (i > 0 && success != i && options.exit_on_forward_failure) fatal("Could not request local forwarding."); @@ -1122,9 +1127,14 @@ ssh_session2_setup(int id, void *arg) debug("Requesting tun."); if ((fd = tun_open(options.tun_local, options.tun_open)) >= 0) { - 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) if (options.tun_open == SSH_TUNMODE_POINTOPOINT) @@ -1154,6 +1164,9 @@ ssh_session2_open(void) { Channel *c; int window, packetmax, in, out, err; + int sock; + int socksize; + int socksizelen = sizeof(int); if (stdin_null_flag) { in = open(_PATH_DEVNULL, O_RDONLY); @@ -1174,9 +1187,70 @@ ssh_session2_open(void) if (!isatty(err)) set_nonblock(err); - window = CHAN_SES_WINDOW_DEFAULT; + /* we need to check to see if what they want to do about buffer */ + /* sizes here. In a hpn to nonhpn connection we want to limit */ + /* the window size to something reasonable in case the far side */ + /* has the large window bug. In hpn to hpn connection we want to */ + /* use the max window size but allow the user to override it */ + /* lastly if they disabled hpn then use the ssh std window size */ + + /* so why don't we just do a getsockopt() here and set the */ + /* ssh window to that? In the case of a autotuning receive */ + /* window 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 hasspecifically set the hpnrcvbufpoll */ + /* to no. In which case we *can* just set the window to the */ + /* minimum of the hpn buffer size and tcp receive buffer size */ + + if(options.hpn_disabled) + { + options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + } + else if (datafellows & SSH_BUG_LARGEWINDOW) + { + debug("HPN to Non-HPN Connection"); + if (options.hpn_buffer_size < 0) + options.hpn_buffer_size = 2*1024*1024; + } + else + { + if (options.hpn_buffer_size < 0) + options.hpn_buffer_size = BUFFER_MAX_LEN_HPN; + + /*create a socket but don't connect it */ + /* we use that the get the rcv socket size */ + sock = socket(AF_INET, SOCK_STREAM, 0); + /* if they are using the tcp_rcv_buf option */ + /* attempt to set the buffer size to that */ + if (options.tcp_rcv_buf) + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, + sizeof(options.tcp_rcv_buf)); + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + close(sock); + debug("socksize %d", socksize); + if (options.tcp_rcv_buf_poll <= 0) + { + options.hpn_buffer_size = MIN(socksize,options.hpn_buffer_size); + debug ("MIN of TCP RWIN and HPNBufferSize: %d", options.hpn_buffer_size); + } + else + { + if (options.tcp_rcv_buf > 0) + options.hpn_buffer_size = MIN(options.tcp_rcv_buf, options.hpn_buffer_size); + debug ("MIN of TCPRcvBuf and HPNBufferSize: %d", options.hpn_buffer_size); + } + + } + + debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); + + window = options.hpn_buffer_size; + packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { + window = 4*CHAN_SES_PACKET_DEFAULT; window >>= 1; packetmax >>= 1; } @@ -1184,7 +1258,10 @@ ssh_session2_open(void) "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - + if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) { + c->dynamic_window = 1; + debug ("Enabled Dynamic Window Scaling\n"); + } debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); @@ -1374,12 +1451,23 @@ control_client(const char *path) flags |= SSHMUX_FLAG_X11_FWD; if (options.forward_agent) flags |= SSHMUX_FLAG_AGENT_FWD; - + if (options.num_local_forwards > 0) + flags |= SSHMUX_FLAG_PORTFORWARD; buffer_init(&m); /* Send our command to server */ buffer_put_int(&m, mux_command); buffer_put_int(&m, flags); + if (options.num_local_forwards > 0) + { + if (options.local_forwards[0].listen_host == NULL) + buffer_put_string(&m,"LOCALHOST",11); + else + buffer_put_string(&m,options.local_forwards[0].listen_host,512); + buffer_put_int(&m,options.local_forwards[0].listen_port); + buffer_put_string(&m,options.local_forwards[0].connect_host,512); + buffer_put_int(&m,options.local_forwards[0].connect_port); + } if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) fatal("%s: msg_send", __func__); buffer_clear(&m); diff --git a/openssh/sshconnect.c b/openssh/sshconnect.c index a222233..e016e19 100644 --- a/openssh/sshconnect.c +++ b/openssh/sshconnect.c @@ -163,6 +163,31 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) return 0; } +/* + * Set TCP receive buffer if requested. + * Note: tuning needs to happen after the socket is + * created but before the connection happens + * so winscale is negotiated properly -cjr + */ +static void +ssh_set_socket_recvbuf(int sock) +{ + void *buf = (void *)&options.tcp_rcv_buf; + int sz = sizeof(options.tcp_rcv_buf); + int socksize; + int socksizelen = 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, &socksizelen); + 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. */ @@ -186,13 +211,19 @@ 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); if (sock < 0) error("socket: %.100s", strerror(errno)); - - /* Bind the socket to an alternative local IP address */ + + 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; @@ -487,7 +518,7 @@ ssh_exchange_identification(void) snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_VERSION); + SSH_RELEASE); if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index 5190b07..a169298 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -72,6 +72,12 @@ extern char *client_version_string; extern char *server_version_string; extern Options options; +extern Kex *xxx_kex; + +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */ +/* if it is set then prevent the switch to the null cipher */ + +extern int tty_flag; /* * SSH2 key exchange @@ -133,7 +139,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); myproposal[PROPOSAL_ENC_ALGS_STOC] = @@ -376,6 +383,28 @@ 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); + /* if the user wants to use the none cipher do it */ + /* post authentication and only if the right conditions are met */ + /* both of the NONE commands must be true and there must be no */ + /* tty allocated */ + if ((options.none_switch == 1) && (options.none_enabled == 1)) + { + if (!tty_flag) /* no null on tty sessions */ + { + debug("Requesting none rekeying..."); + myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; + myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; + kex_prop2buf(&xxx_kex->my,myproposal); + packet_request_rekeying(); + fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n"); + } + else + { + /* requested NONE cipher when in a tty */ + debug("Cannot switch to NONE cipher with tty allocated"); + fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); + } + } debug("Authentication succeeded (%s).", authctxt.method->name); } diff --git a/openssh/sshd.c b/openssh/sshd.c index 912e023..3f519bb 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -422,7 +422,7 @@ sshd_exchange_identification(int sock_in, int sock_out) major = PROTOCOL_MAJOR_1; minor = PROTOCOL_MINOR_1; } - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE); server_version_string = xstrdup(buf); /* Send our protocol version identification. */ @@ -945,6 +945,8 @@ server_listen(void) int ret, listen_sock, on = 1; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + int socksize; + int socksizelen = sizeof(int); for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) @@ -981,6 +983,11 @@ server_listen(void) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); debug("Bind to port %s on %s.", strport, ntop); + + getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + 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) { @@ -2153,6 +2160,10 @@ do_ssh2_kex(void) if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; + } 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; } myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); diff --git a/openssh/sshd_config b/openssh/sshd_config index 68c8752..f49f376 100644 --- a/openssh/sshd_config +++ b/openssh/sshd_config @@ -107,6 +107,20 @@ # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server +# the following are HPN related configuration options +# tcp receive buffer polling. enable in autotuning kernels +#TcpRcvBufPoll no + +# allow the use of the none cipher +#NoneEnabled no + +# disable hpn performance boosts. +#HPNDisabled no + +# buffer size for hpn to non-hn connections +#HPNBufferSize 2048 + + # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no diff --git a/openssh/version.h b/openssh/version.h index d16990a..b29eaad 100644 --- a/openssh/version.h +++ b/openssh/version.h @@ -3,4 +3,5 @@ #define SSH_VERSION "OpenSSH_4.5" #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_HPN "-hpn12v14" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN