Upgrade to OpenSSH 7.2p2.

This commit is contained in:
Dag-Erling Smørgrav
2016-03-11 00:15:29 +00:00
153 changed files with 5781 additions and 3345 deletions
+116 -79
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.275 2015/07/10 06:21:53 markus Exp $ */
/* $OpenBSD: clientloop.c,v 1.284 2016/02/08 10:57:07 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -111,7 +111,6 @@
#include "sshpty.h"
#include "match.h"
#include "msg.h"
#include "roaming.h"
#include "ssherr.h"
#include "hostfile.h"
@@ -169,8 +168,6 @@ static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static void client_init_dispatch(void);
int session_ident = -1;
int session_resumed = 0;
/* Track escape per proto2 channel */
struct escape_filter_ctx {
int escape_pending;
@@ -288,6 +285,9 @@ client_x11_display_valid(const char *display)
{
size_t i, dlen;
if (display == NULL)
return 0;
dlen = strlen(display);
for (i = 0; i < dlen; i++) {
if (!isalnum((u_char)display[i]) &&
@@ -301,35 +301,34 @@ client_x11_display_valid(const char *display)
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
#define X11_TIMEOUT_SLACK 60
void
int
client_x11_get_proto(const char *display, const char *xauth_path,
u_int trusted, u_int timeout, char **_proto, char **_data)
{
char cmd[1024];
char line[512];
char xdisplay[512];
char cmd[1024], line[512], xdisplay[512];
char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
static char proto[512], data[512];
FILE *f;
int got_data = 0, generated = 0, do_unlink = 0, i;
char *xauthdir, *xauthfile;
int got_data = 0, generated = 0, do_unlink = 0, i, r;
struct stat st;
u_int now, x11_timeout_real;
xauthdir = xauthfile = NULL;
*_proto = proto;
*_data = data;
proto[0] = data[0] = '\0';
proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0';
if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) {
if (!client_x11_display_valid(display)) {
if (display != NULL)
logit("DISPLAY \"%s\" invalid; disabling X11 forwarding",
display);
return -1;
}
if (xauth_path != NULL && stat(xauth_path, &st) == -1) {
debug("No xauth program.");
} else if (!client_x11_display_valid(display)) {
logit("DISPLAY '%s' invalid, falling back to fake xauth data",
display);
} else {
if (display == NULL) {
debug("x11_get_proto: DISPLAY not set");
return;
}
xauth_path = NULL;
}
if (xauth_path != NULL) {
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
@@ -338,45 +337,60 @@ client_x11_get_proto(const char *display, const char *xauth_path,
* is not perfect.
*/
if (strncmp(display, "localhost:", 10) == 0) {
snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10);
if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10)) < 0 ||
(size_t)r >= sizeof(xdisplay)) {
error("%s: display name too long", __func__);
return -1;
}
display = xdisplay;
}
if (trusted == 0) {
xauthdir = xmalloc(PATH_MAX);
xauthfile = xmalloc(PATH_MAX);
mktemp_proto(xauthdir, PATH_MAX);
/*
* Generate an untrusted X11 auth cookie.
*
* The authentication cookie should briefly outlive
* ssh's willingness to forward X11 connections to
* avoid nasty fail-open behaviour in the X server.
*/
mktemp_proto(xauthdir, sizeof(xauthdir));
if (mkdtemp(xauthdir) == NULL) {
error("%s: mkdtemp: %s",
__func__, strerror(errno));
return -1;
}
do_unlink = 1;
if ((r = snprintf(xauthfile, sizeof(xauthfile),
"%s/xauthfile", xauthdir)) < 0 ||
(size_t)r >= sizeof(xauthfile)) {
error("%s: xauthfile path too long", __func__);
unlink(xauthfile);
rmdir(xauthdir);
return -1;
}
if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK)
x11_timeout_real = UINT_MAX;
else
x11_timeout_real = timeout + X11_TIMEOUT_SLACK;
if (mkdtemp(xauthdir) != NULL) {
do_unlink = 1;
snprintf(xauthfile, PATH_MAX, "%s/xauthfile",
xauthdir);
snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout %u 2>" _PATH_DEVNULL,
xauth_path, xauthfile, display,
x11_timeout_real);
debug2("x11_get_proto: %s", cmd);
if (x11_refuse_time == 0) {
now = monotime() + 1;
if (UINT_MAX - timeout < now)
x11_refuse_time = UINT_MAX;
else
x11_refuse_time = now + timeout;
channel_set_x11_refuse_time(
x11_refuse_time);
}
if (system(cmd) == 0)
generated = 1;
if ((r = snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout %u 2>" _PATH_DEVNULL,
xauth_path, xauthfile, display,
x11_timeout_real)) < 0 ||
(size_t)r >= sizeof(cmd))
fatal("%s: cmd too long", __func__);
debug2("%s: %s", __func__, cmd);
if (x11_refuse_time == 0) {
now = monotime() + 1;
if (UINT_MAX - timeout < now)
x11_refuse_time = UINT_MAX;
else
x11_refuse_time = now + timeout;
channel_set_x11_refuse_time(x11_refuse_time);
}
if (system(cmd) == 0)
generated = 1;
}
/*
@@ -398,17 +412,20 @@ client_x11_get_proto(const char *display, const char *xauth_path,
got_data = 1;
if (f)
pclose(f);
} else
error("Warning: untrusted X11 forwarding setup failed: "
"xauth key data not generated");
}
}
if (do_unlink) {
unlink(xauthfile);
rmdir(xauthdir);
}
free(xauthdir);
free(xauthfile);
/* Don't fall back to fake X11 data for untrusted forwarding */
if (!trusted && !got_data) {
error("Warning: untrusted X11 forwarding setup failed: "
"xauth key data not generated");
return -1;
}
/*
* If we didn't get authentication data, just make up some
@@ -432,6 +449,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
rnd >>= 8;
}
}
return 0;
}
/*
@@ -735,7 +754,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
static void
client_process_net_input(fd_set *readset)
{
int len, cont = 0;
int len;
char buf[SSH_IOBUFSZ];
/*
@@ -744,8 +763,8 @@ client_process_net_input(fd_set *readset)
*/
if (FD_ISSET(connection_in, readset)) {
/* Read as much as possible. */
len = roaming_read(connection_in, buf, sizeof(buf), &cont);
if (len == 0 && cont == 0) {
len = read(connection_in, buf, sizeof(buf));
if (len == 0) {
/*
* Received EOF. The remote host has closed the
* connection.
@@ -1483,13 +1502,43 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
{
fd_set *readset = NULL, *writeset = NULL;
double start_time, total_time;
int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0;
int r, max_fd = 0, max_fd2 = 0, len;
u_int64_t ibytes, obytes;
u_int nalloc = 0;
char buf[100];
debug("Entering interactive session.");
if (options.control_master &&
! option_clear_or_none(options.control_path)) {
debug("pledge: id");
if (pledge("stdio rpath wpath cpath unix inet dns proc exec id tty",
NULL) == -1)
fatal("%s pledge(): %s", __func__, strerror(errno));
} else if (options.forward_x11 || options.permit_local_command) {
debug("pledge: exec");
if (pledge("stdio rpath wpath cpath unix inet dns proc exec tty",
NULL) == -1)
fatal("%s pledge(): %s", __func__, strerror(errno));
} else if (options.update_hostkeys) {
debug("pledge: filesystem full");
if (pledge("stdio rpath wpath cpath unix inet dns proc tty",
NULL) == -1)
fatal("%s pledge(): %s", __func__, strerror(errno));
} else if (! option_clear_or_none(options.proxy_command)) {
debug("pledge: proc");
if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1)
fatal("%s pledge(): %s", __func__, strerror(errno));
} else {
debug("pledge: network");
if (pledge("stdio unix inet dns tty", NULL) == -1)
fatal("%s pledge(): %s", __func__, strerror(errno));
}
start_time = get_current_time();
/* Initialize variables. */
@@ -1568,10 +1617,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (compat20 && session_closed && !channel_still_open())
break;
rekeying = (active_state->kex != NULL && !active_state->kex->done);
if (rekeying) {
if (ssh_packet_is_rekeying(active_state)) {
debug("rekeying in progress");
} else if (need_rekeying) {
/* manual rekey request */
debug("need rekeying");
if ((r = kex_start_rekex(active_state)) != 0)
fatal("%s: kex_start_rekex: %s", __func__,
ssh_err(r));
need_rekeying = 0;
} else {
/*
* Make packets of buffered stdin data, and buffer
@@ -1602,23 +1656,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
*/
max_fd2 = max_fd;
client_wait_until_can_do_something(&readset, &writeset,
&max_fd2, &nalloc, rekeying);
&max_fd2, &nalloc, ssh_packet_is_rekeying(active_state));
if (quit_pending)
break;
/* Do channel operations unless rekeying in progress. */
if (!rekeying) {
if (!ssh_packet_is_rekeying(active_state))
channel_after_select(readset, writeset);
if (need_rekeying || packet_need_rekeying()) {
debug("need rekeying");
active_state->kex->done = 0;
if ((r = kex_send_kexinit(active_state)) != 0)
fatal("%s: kex_send_kexinit: %s",
__func__, ssh_err(r));
need_rekeying = 0;
}
}
/* Buffer input from the connection. */
client_process_net_input(readset);
@@ -1636,14 +1681,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
client_process_output(writeset);
}
if (session_resumed) {
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
max_fd = MAX(max_fd, connection_out);
max_fd = MAX(max_fd, connection_in);
session_resumed = 0;
}
/*
* Send as much buffered packet data as possible to the
* sender.
@@ -1737,7 +1774,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
}
/* Clear and free any buffers. */
memset(buf, 0, sizeof(buf));
explicit_bzero(buf, sizeof(buf));
buffer_free(&stdin_buffer);
buffer_free(&stdout_buffer);
buffer_free(&stderr_buffer);