/* Increase the size of the buffer and retry. */
newlen = buffer->alloc + len + 32768;
- if (newlen > BUFFER_MAX_LEN)
+ if (newlen > BUFFER_MAX_HPN_LEN)
fatal("buffer_append_space: alloc %u not supported",
newlen);
buffer->buf = xrealloc(buffer->buf, newlen);
#define BUFFER_MAX_CHUNK 0x100000
#define BUFFER_MAX_LEN 0xa00000
+#define BUFFER_MAX_HPN_LEN (2<<29)-1
void buffer_init(Buffer *);
void buffer_clear(Buffer *);
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;
channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
{
u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
-
+
/* check buffer limits */
- limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
+ limit = MIN(limit, (BUFFER_MAX_HPN_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 &&
!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
c->local_window < c->local_window_max/2 &&
c->local_consumed > 0) {
+ u_int32_t tcpwinsz = 0;
+ socklen_t optsz = sizeof(tcpwinsz);
+ int ret = -1;
+ u_int32_t addition = 0;
+ if (c->dynamic_window) {
+ ret = getsockopt(packet_get_connection_in(),
+ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
+ if ((ret == 0) && tcpwinsz > BUFFER_MAX_HPN_LEN)
+ tcpwinsz = BUFFER_MAX_HPN_LEN;
+ }
+ if (c->dynamic_window && (ret == 0) &&
+ (tcpwinsz > c->local_window_max)) {
+ addition = tcpwinsz - c->local_window_max;
+ c->local_window_max += addition;
+ }
packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
packet_put_int(c->remote_id);
- packet_put_int(c->local_consumed);
+ packet_put_int(c->local_consumed + addition);
packet_send();
debug2("channel %d: window %d sent adjust %d",
c->self, c->local_window,
c->local_consumed);
- c->local_window += c->local_consumed;
+ c->local_window += c->local_consumed + addition;
c->local_consumed = 0;
}
return 1;
u_int local_window_max;
u_int local_consumed;
u_int local_maxpacket;
+ int dynamic_window;
int extended_usage;
int single_connection;
/* default window/packet sizes for tcp/x11-fwd-channel */
#define CHAN_SES_PACKET_DEFAULT (32*1024)
-#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT)
+#define CHAN_SES_WINDOW_DEFAULT (0xa00000/2)
#define CHAN_TCP_PACKET_DEFAULT (32*1024)
-#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
+#define CHAN_TCP_WINDOW_DEFAULT (0xa00000/2)
#define CHAN_X11_PACKET_DEFAULT (16*1024)
-#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
+#define CHAN_X11_WINDOW_DEFAULT (0xa00000/2)
/* possible input states */
#define CHAN_INPUT_OPEN 0
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;
int evplen;
switch (c->number) {
+ case SSH_CIPHER_NONE:
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
int evplen = 0;
switch (c->number) {
+ case SSH_CIPHER_NONE:
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
strlen(check[i].pat), 0) == 1) {
debug("match: %s pat %s", version, check[i].pat);
datafellows = check[i].bugs;
+ /* Check to see if the remote side is OpenSSH and not HPN */
+ if(strstr(version,"OpenSSH") != NULL)
+ {
+ if (strstr(version,"hpn") == NULL)
+ {
+ datafellows |= SSH_BUG_LARGEWINDOW;
+ }
+ }
return;
}
}
#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);
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;
void (*kex[KEX_MAX])(Kex *);
};
+void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
+
Kex *kex_setup(char *[PROPOSAL_MAX]);
void kex_finish(Kex *);
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
"arcfour128,arcfour256,arcfour," \
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
- "aes128-ctr,aes192-ctr,aes256-ctr"
+ "aes128-ctr,aes192-ctr,aes256-ctr,none"
#define KEX_DEFAULT_MAC \
"hmac-md5,hmac-sha1,hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \
rnd >>= 8;
}
}
+int rekey_requested = 0;
+
+void
+packet_request_rekeying(void)
+{
+ rekey_requested = 1;
+}
#define MAX_PACKETS (1U<<31)
int
{
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) ||
#include <openssl/bn.h>
+void
+packet_request_rekeying(void);
+
void packet_set_connection(int, int);
void packet_set_nonblocking(void);
int packet_get_connection_in(void);
options->verify_host_key_dns = -1;
options->server_alive_interval = -1;
options->server_alive_count_max = -1;
+ options->none_switch = -1;
options->num_send_env = 0;
options->control_path = NULL;
options->control_master = -1;
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->control_master == -1)
options->control_master = 0;
if (options->hash_known_hosts == -1)
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 */
LogLevel log_level; /* Level for logging. */
int port; /* Port to connect. */
int enable_ssh_keysign;
int rekey_limit;
+ int none_switch;
int no_host_authentication_for_localhost;
int identities_only;
int server_alive_interval;
addargs(&args, "-oClearAllForwardings yes");
fflag = tflag = 0;
- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
+ while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246zS:o:F:R:")) != -1)
switch (ch) {
/* User-visible flags. */
case '1':
case '4':
case '6':
case 'C':
+ case 'z':
addargs(&args, "-%c", ch);
break;
case 'o':
setmode(0, O_BINARY);
#endif
break;
+ case 'R':
+ addargs(&args, "-r%s", optarg);
+ break;
default:
usage();
}
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) {
int amt, exists, first, mask, mode, ofd, omode;
off_t size, statbytes;
int setimes, targisdir, wrerrno = 0;
- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
+ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
struct timeval tv[2];
#define atime tv[0]
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;
}
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;
} while (amt > 0);
if (limit_rate)
- bwlimit(4096);
+ bwlimit(sizeof(buf));
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
{
(void) fprintf(stderr,
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
- " [-l limit] [-o ssh_option] [-P port] [-S program]\n"
+ " [-l limit] [-o ssh_option] [-P port] [-R Receive buffer size (Kb)] [-S program]\n"
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
exit(1);
}
c = channel_new("session", SSH_CHANNEL_LARVAL,
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
0, "server-session", 1);
+ if (!(datafellows & SSH_BUG_LARGEWINDOW))
+ c->dynamic_window = 1;
if (session_open(the_authctxt, c->self) != 1) {
debug("session open failed, free channel %d", c->self);
channel_free(c);
ll = SYSLOG_LEVEL_INFO;
infile = stdin;
- while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:z")) != -1) {
switch (ch) {
case 'C':
addargs(&args, "-C");
optarg);
break;
case 'h':
+ case 'z':
+ addargs(&args, "-%c", ch);
+ break;
default:
usage();
}
usage(void)
{
fprintf(stderr,
-"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
+"usage: ssh [-1246AaCfgkMNnqrsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
" [-w tunnel:tunnel] [user@]hostname [command]\n"
+" [-r Receive Buffer Size in K]\n"
);
exit(255);
}
/* Parse command-line arguments. */
host = NULL;
+ /* need to set options.tcp_rcv_buf to 0 */
+ options.tcp_rcv_buf = 0;
again:
while ((opt = getopt(ac, av,
- "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
+ "1246ab:c:e:fgi:kl:m:no:p:qrstvxACD:F:I:L:MNO:PR:S:TVw:XYz")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
break;
case 'T':
no_tty_flag = 1;
+ options.none_switch = 0;
break;
case 'o':
dummy = 1;
case 'F':
config = optarg;
break;
+ case 'r':
+ options.tcp_rcv_buf = atoi(optarg) * 1024;
+ break;
+ case 'z':
+ /* make sure we can't turn on the none_switch */
+ /* if they try to force a no tty flag on a tty session */
+ if (!no_tty_flag) {
+ options.none_switch = 1;
+ }
+ break;
+
default:
usage();
}
window = CHAN_SES_WINDOW_DEFAULT;
packetmax = CHAN_SES_PACKET_DEFAULT;
if (tty_flag) {
+ window = 4*CHAN_SES_PACKET_DEFAULT;
window >>= 1;
packetmax >>= 1;
}
"session", SSH_CHANNEL_OPENING, in, out, err,
window, packetmax, CHAN_EXTENDED_WRITE,
"client-session", /*nonblock*/0);
-
+ if (!tty_flag && (!(datafellows & SSH_BUG_LARGEWINDOW))) {
+ c->dynamic_window = 1;
+ }
debug3("ssh_session2_open: channel_new: %d", c->self);
channel_send_open(c->self);
strerror(errno));
else
debug("Allocated local port %d.", p);
+
+
+ /* tuning needs to happen after the socket is */
+ /* created but before the connection happens */
+ /* so winscale is negotiated properly -cjr */
+
+ /* Set tcp receive buffer if requested */
+ if (options.tcp_rcv_buf)
+ {
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ (void *)&options.tcp_rcv_buf,
+ sizeof(options.tcp_rcv_buf)) >= 0)
+ {
+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
+ }
+ else
+ {
+ /* coudln't set the socket size to use spec. */
+ /* should default to system param and continue */
+ /* warn the user though - cjr */
+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
+ }
+ }
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 */
+
+ /* tuning needs to happen after the socket is */
+ /* created but before the connection happens */
+ /* so winscale is negotiated properly -cjr */
+
+ /* Set tcp receive buffer if requested */
+ if (options.tcp_rcv_buf)
+ {
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ (void *)&options.tcp_rcv_buf,
+ sizeof(options.tcp_rcv_buf)) >= 0)
+ {
+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
+ }
+ else
+ {
+ /* coudln't set the socket size to use spec. */
+ /* should default to system param and continue */
+ /* warn the user though - cjr */
+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
+ }
+ }
+
+ /* Bind the socket to an alternative local IP address */
if (options.bind_address == NULL)
return sock;
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);
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
pubkey_cleanup(&authctxt);
dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
-
+ if ((options.none_switch == 1) && !tty_flag) /* no null on tty sessions */
+ {
+ debug("Requesting none rekeying...");
+ myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
+ kex_prop2buf(&xxx_kex->my,myproposal);
+ packet_request_rekeying();
+ fprintf(stderr, "WARNING: ENABLED NULL CIPHER\n");
+ }
debug("Authentication succeeded (%s).", authctxt.method->name);
}
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. */
#define SSH_VERSION "OpenSSH_4.3"
#define SSH_PORTABLE "p2"
-#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
+#define SSH_HPN "-hpn"
+#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN