Large diffs are not rendered by default.

@@ -1,4 +1,4 @@
/* $OpenBSD: compat.c,v 1.102 2017/04/30 23:11:45 djm Exp $ */
/* $OpenBSD: compat.c,v 1.103 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -39,24 +39,8 @@
#include "match.h"
#include "kex.h"

int compat13 = 0;
int compat20 = 0;
int datafellows = 0;

void
enable_compat20(void)
{
if (compat20)
return;
debug("Enabling compatibility mode for protocol 2.0");
compat20 = 1;
}
void
enable_compat13(void)
{
debug("Enabling compatibility mode for protocol 1.3");
compat13 = 1;
}
/* datafellows bug compatibility */
u_int
compat_datafellows(const char *version)
@@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker Exp $ */
/* $OpenBSD: compat.h,v 1.49 2017/04/30 23:13:25 djm Exp $ */

/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -63,15 +63,11 @@
#define SSH_BUG_HOSTKEYS 0x20000000
#define SSH_BUG_DHGEX_LARGE 0x40000000

void enable_compat13(void);
void enable_compat20(void);
u_int compat_datafellows(const char *);
int proto_spec(const char *);
char *compat_cipher_proposal(char *);
char *compat_pkalg_proposal(char *);
char *compat_kex_proposal(char *);

extern int compat13;
extern int compat20;
extern int datafellows;
#endif
@@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */
/* $OpenBSD: dispatch.c,v 1.28 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -45,8 +45,6 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
int r;

logit("dispatch_protocol_error: type %d seq %u", type, seq);
if (!compat20)
fatal("protocol error");
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
266 nchan.c
@@ -1,4 +1,4 @@
/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */
/* $OpenBSD: nchan.c,v 1.64 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -74,9 +74,6 @@
/*
* ACTIONS: should never update the channel states
*/
static void chan_send_ieof1(Channel *);
static void chan_send_oclose1(Channel *);
static void chan_send_close2(Channel *);
static void chan_send_eof2(Channel *);
static void chan_send_eow2(Channel *);

@@ -96,6 +93,7 @@ chan_set_istate(Channel *c, u_int next)
istates[next]);
c->istate = next;
}

static void
chan_set_ostate(Channel *c, u_int next)
{
@@ -106,34 +104,6 @@ chan_set_ostate(Channel *c, u_int next)
c->ostate = next;
}

/*
* SSH1 specific implementation of event functions
*/

static void
chan_rcvd_oclose1(Channel *c)
{
debug2("channel %d: rcvd oclose", c->self);
switch (c->istate) {
case CHAN_INPUT_WAIT_OCLOSE:
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_OPEN:
chan_shutdown_read(c);
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
/* both local read_failed and remote write_failed */
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
default:
error("channel %d: protocol error: rcvd_oclose for istate %d",
c->self, c->istate);
return;
}
}
void
chan_read_failed(Channel *c)
{
@@ -149,6 +119,7 @@ chan_read_failed(Channel *c)
break;
}
}

void
chan_ibuf_empty(Channel *c)
{
@@ -160,59 +131,17 @@ chan_ibuf_empty(Channel *c)
}
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
if (compat20) {
if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
} else {
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
}
if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
default:
error("channel %d: chan_ibuf_empty for istate %d",
c->self, c->istate);
break;
}
}
static void
chan_rcvd_ieof1(Channel *c)
{
debug2("channel %d: rcvd ieof", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
case CHAN_OUTPUT_WAIT_IEOF:
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: protocol error: rcvd_ieof for ostate %d",
c->self, c->ostate);
break;
}
}
static void
chan_write_failed1(Channel *c)
{
debug2("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
chan_shutdown_write(c);
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
break;
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
}

void
chan_obuf_empty(Channel *c)
{
@@ -225,8 +154,6 @@ chan_obuf_empty(Channel *c)
switch (c->ostate) {
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
if (!compat20)
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
@@ -235,82 +162,6 @@ chan_obuf_empty(Channel *c)
break;
}
}
static void
chan_send_ieof1(Channel *c)
{
debug2("channel %d: send ieof", c->self);
switch (c->istate) {
case CHAN_INPUT_OPEN:
case CHAN_INPUT_WAIT_DRAIN:
packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
packet_put_int(c->remote_id);
packet_send();
break;
default:
error("channel %d: cannot send ieof for istate %d",
c->self, c->istate);
break;
}
}
static void
chan_send_oclose1(Channel *c)
{
debug2("channel %d: send oclose", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
case CHAN_OUTPUT_WAIT_DRAIN:
buffer_clear(&c->output);
packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
packet_put_int(c->remote_id);
packet_send();
break;
default:
error("channel %d: cannot send oclose for ostate %d",
c->self, c->ostate);
break;
}
}

/*
* the same for SSH2
*/
static void
chan_rcvd_close2(Channel *c)
{
debug2("channel %d: rcvd close", c->self);
if (!(c->flags & CHAN_LOCAL)) {
if (c->flags & CHAN_CLOSE_RCVD)
error("channel %d: protocol error: close rcvd twice",
c->self);
c->flags |= CHAN_CLOSE_RCVD;
}
if (c->type == SSH_CHANNEL_LARVAL) {
/* tear down larval channels immediately */
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
chan_set_istate(c, CHAN_INPUT_CLOSED);
return;
}
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
/*
* wait until a data from the channel is consumed if a CLOSE
* is received
*/
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
}
switch (c->istate) {
case CHAN_INPUT_OPEN:
chan_shutdown_read(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
if (!(c->flags & CHAN_LOCAL))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}

void
chan_rcvd_eow(Channel *c)
@@ -323,32 +174,7 @@ chan_rcvd_eow(Channel *c)
break;
}
}
static void
chan_rcvd_eof2(Channel *c)
{
debug2("channel %d: rcvd eof", c->self);
c->flags |= CHAN_EOF_RCVD;
if (c->ostate == CHAN_OUTPUT_OPEN)
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
}
static void
chan_write_failed2(Channel *c)
{
debug2("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
if (strcmp(c->ctype, "session") == 0)
chan_send_eow2(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
}

static void
chan_send_eof2(Channel *c)
{
@@ -366,6 +192,7 @@ chan_send_eof2(Channel *c)
break;
}
}

static void
chan_send_close2(Channel *c)
{
@@ -383,6 +210,7 @@ chan_send_close2(Channel *c)
c->flags |= CHAN_CLOSE_SENT;
}
}

static void
chan_send_eow2(Channel *c)
{
@@ -406,30 +234,71 @@ chan_send_eow2(Channel *c)
void
chan_rcvd_ieof(Channel *c)
{
if (compat20)
chan_rcvd_eof2(c);
else
chan_rcvd_ieof1(c);
debug2("channel %d: rcvd eof", c->self);
c->flags |= CHAN_EOF_RCVD;
if (c->ostate == CHAN_OUTPUT_OPEN)
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
buffer_len(&c->output) == 0 &&
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
chan_obuf_empty(c);
}

void
chan_rcvd_oclose(Channel *c)
{
if (compat20)
chan_rcvd_close2(c);
else
chan_rcvd_oclose1(c);
debug2("channel %d: rcvd close", c->self);
if (!(c->flags & CHAN_LOCAL)) {
if (c->flags & CHAN_CLOSE_RCVD)
error("channel %d: protocol error: close rcvd twice",
c->self);
c->flags |= CHAN_CLOSE_RCVD;
}
if (c->type == SSH_CHANNEL_LARVAL) {
/* tear down larval channels immediately */
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
chan_set_istate(c, CHAN_INPUT_CLOSED);
return;
}
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
/*
* wait until a data from the channel is consumed if a CLOSE
* is received
*/
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
}
switch (c->istate) {
case CHAN_INPUT_OPEN:
chan_shutdown_read(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
if (!(c->flags & CHAN_LOCAL))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}

void
chan_write_failed(Channel *c)
{
if (compat20)
chan_write_failed2(c);
else
chan_write_failed1(c);
debug2("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
if (strcmp(c->ctype, "session") == 0)
chan_send_eow2(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
}

void
@@ -447,10 +316,6 @@ chan_is_dead(Channel *c, int do_send)
}
if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
return 0;
if (!compat20) {
debug2("channel %d: is dead", c->self);
return 1;
}
if ((datafellows & SSH_BUG_EXTEOF) &&
c->extended_usage == CHAN_EXTENDED_WRITE &&
c->efd != -1 &&
@@ -488,7 +353,7 @@ static void
chan_shutdown_write(Channel *c)
{
buffer_clear(&c->output);
if (compat20 && c->type == SSH_CHANNEL_LARVAL)
if (c->type == SSH_CHANNEL_LARVAL)
return;
/* shutdown failure is allowed if write failed already */
debug2("channel %d: close_write", c->self);
@@ -504,10 +369,11 @@ chan_shutdown_write(Channel *c)
c->self, c->wfd, strerror(errno));
}
}

static void
chan_shutdown_read(Channel *c)
{
if (compat20 && c->type == SSH_CHANNEL_LARVAL)
if (c->type == SSH_CHANNEL_LARVAL)
return;
debug2("channel %d: close_read", c->self);
if (c->sock != -1) {
395 packet.c

Large diffs are not rendered by default.

@@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.76 2017/02/03 23:03:33 djm Exp $ */
/* $OpenBSD: packet.h,v 1.77 2017/04/30 23:13:25 djm Exp $ */

/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -112,7 +112,6 @@ int ssh_packet_set_log_preamble(struct ssh *, const char *, ...)

int ssh_packet_log_type(u_char);

int ssh_packet_send1(struct ssh *);
int ssh_packet_send2_wrapped(struct ssh *);
int ssh_packet_send2(struct ssh *);

@@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.110 2017/04/30 23:10:43 djm Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.111 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@@ -221,7 +221,6 @@ keygrab_ssh2(con *c)
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
int r;

enable_compat20();
switch (c->c_keytype) {
case KT_DSA:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
174 ssh.c
@@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.454 2017/04/30 23:11:45 djm Exp $ */
/* $OpenBSD: ssh.c,v 1.455 2017/04/30 23:13:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -209,7 +209,6 @@ usage(void)
exit(255);
}

static int ssh_session(void);
static int ssh_session2(void);
static void load_public_identity_files(void);
static void main_sigchld_handler(int);
@@ -1243,7 +1242,6 @@ main(int ac, char **av)
if ((sock = muxclient(options.control_path)) >= 0) {
packet_set_connection(sock, sock);
ssh = active_state; /* XXX */
enable_compat20(); /* XXX */
packet_set_mux();
goto skip_connect;
}
@@ -1447,7 +1445,7 @@ main(int ac, char **av)
}

skip_connect:
exit_status = compat20 ? ssh_session2() : ssh_session();
exit_status = ssh_session2();
packet_close();

if (options.control_path != NULL && muxserver_sock != -1)
@@ -1591,8 +1589,6 @@ ssh_init_stdio_forwarding(void)

if (options.stdio_forward_host == NULL)
return;
if (!compat20)
fatal("stdio forwarding require Protocol 2");

debug3("%s: %s:%d", __func__, options.stdio_forward_host,
options.stdio_forward_port);
@@ -1691,172 +1687,6 @@ check_agent_present(void)
}
}

static int
ssh_session(void)
{
int type;
int interactive = 0;
int have_tty = 0;
struct winsize ws;
char *cp;
const char *display;
char *proto = NULL, *data = NULL;

/* Enable compression if requested. */
if (options.compression) {
debug("Requesting compression at level %d.",
options.compression_level);

if (options.compression_level < 1 ||
options.compression_level > 9)
fatal("Compression level must be from 1 (fast) to "
"9 (slow, best).");

/* Send the request. */
packet_start(SSH_CMSG_REQUEST_COMPRESSION);
packet_put_int(options.compression_level);
packet_send();
packet_write_wait();
type = packet_read();
if (type == SSH_SMSG_SUCCESS)
packet_start_compression(options.compression_level);
else if (type == SSH_SMSG_FAILURE)
logit("Warning: Remote host refused compression.");
else
packet_disconnect("Protocol error waiting for "
"compression response.");
}
/* Allocate a pseudo tty if appropriate. */
if (tty_flag) {
debug("Requesting pty.");

/* Start the packet. */
packet_start(SSH_CMSG_REQUEST_PTY);

/* Store TERM in the packet. There is no limit on the
length of the string. */
cp = getenv("TERM");
if (!cp)
cp = "";
packet_put_cstring(cp);

/* Store window size in the packet. */
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
memset(&ws, 0, sizeof(ws));
packet_put_int((u_int)ws.ws_row);
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_xpixel);
packet_put_int((u_int)ws.ws_ypixel);

/* Store tty modes in the packet. */
tty_make_modes(fileno(stdin), NULL);

/* Send the packet, and wait for it to leave. */
packet_send();
packet_write_wait();

/* Read response from the server. */
type = packet_read();
if (type == SSH_SMSG_SUCCESS) {
interactive = 1;
have_tty = 1;
} else if (type == SSH_SMSG_FAILURE)
logit("Warning: Remote host failed or refused to "
"allocate a pseudo tty.");
else
packet_disconnect("Protocol error waiting for pty "
"request response.");
}
/* Request X11 forwarding if enabled and DISPLAY is set. */
display = getenv("DISPLAY");
if (display == NULL && options.forward_x11)
debug("X11 forwarding requested but DISPLAY not set");
if (options.forward_x11 && client_x11_get_proto(display,
options.xauth_location, options.forward_x11_trusted,
options.forward_x11_timeout, &proto, &data) == 0) {
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(0, display, proto,
data, 0);
/* Read response from the server. */
type = packet_read();
if (type == SSH_SMSG_SUCCESS) {
interactive = 1;
} else if (type == SSH_SMSG_FAILURE) {
logit("Warning: Remote host denied X11 forwarding.");
} else {
packet_disconnect("Protocol error waiting for X11 "
"forwarding");
}
}
/* Tell the packet module whether this is an interactive session. */
packet_set_interactive(interactive,
options.ip_qos_interactive, options.ip_qos_bulk);

/* Request authentication agent forwarding if appropriate. */
check_agent_present();

if (options.forward_agent) {
debug("Requesting authentication agent forwarding.");
auth_request_forwarding();

/* Read response from the server. */
type = packet_read();
packet_check_eom();
if (type != SSH_SMSG_SUCCESS)
logit("Warning: Remote host denied authentication agent forwarding.");
}

/* Initiate port forwardings. */
ssh_init_stdio_forwarding();
ssh_init_forwarding();

/* Execute a local command */
if (options.local_command != NULL &&
options.permit_local_command)
ssh_local_cmd(options.local_command);

/*
* If requested and we are not interested in replies to remote
* forwarding requests, then let ssh continue in the background.
*/
if (fork_after_authentication_flag) {
if (options.exit_on_forward_failure &&
options.num_remote_forwards > 0) {
debug("deferring postauth fork until remote forward "
"confirmation received");
} else
fork_postauth();
}

/*
* If a command was specified on the command line, execute the
* command now. Otherwise request the server to start a shell.
*/
if (buffer_len(&command) > 0) {
int len = buffer_len(&command);
if (len > 900)
len = 900;
debug("Sending command: %.*s", len,
(u_char *)buffer_ptr(&command));
packet_start(SSH_CMSG_EXEC_CMD);
packet_put_string(buffer_ptr(&command), buffer_len(&command));
packet_send();
packet_write_wait();
} else {
debug("Requesting shell.");
packet_start(SSH_CMSG_EXEC_SHELL);
packet_send();
packet_write_wait();
}

/* Enter the interactive session. */
return client_loop(have_tty, tty_flag ?
options.escape_char : SSH_ESCAPECHAR_NONE, 0);
}

/* request pty/x11/agent/tcpfwd/shell for channel */
static void
ssh_session2_setup(int id, int success, void *arg)
{
@@ -1,4 +1,4 @@
/* $OpenBSD: ssh_api.c,v 1.7 2016/05/04 14:22:33 markus Exp $ */
/* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
@@ -371,7 +371,6 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp)
}
if (remote_major != 2)
return SSH_ERR_PROTOCOL_MISMATCH;
enable_compat20();
chop(buf);
debug("Remote version string %.100s", buf);
if ((*bannerp = strdup(buf)) == NULL)
@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.275 2017/04/30 23:11:45 djm Exp $ */
/* $OpenBSD: sshconnect.c,v 1.276 2017/04/30 23:13:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -524,13 +524,8 @@ static void
send_client_banner(int connection_out, int minor1)
{
/* Send our own protocol version identification. */
if (compat20) {
xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
} else {
xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
}
xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
if (atomicio(vwrite, connection_out, client_version_string,
strlen(client_version_string)) != strlen(client_version_string))
fatal("write: %.100s", strerror(errno));
@@ -559,7 +554,6 @@ ssh_exchange_identification(int timeout_ms)
fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
fdset = xcalloc(1, fdsetsz);

enable_compat20();
send_client_banner(connection_out, 0);
client_banner_sent = 1;

@@ -628,15 +622,12 @@ ssh_exchange_identification(int timeout_ms)
mismatch = 0;

switch (remote_major) {
case 2:
break;
case 1:
if (remote_minor == 99)
enable_compat20();
else
if (remote_minor != 99)
mismatch = 1;
break;
case 2:
enable_compat20();
break;
default:
mismatch = 1;
break;
@@ -1243,8 +1234,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
host_key->cert->principals[i]);
}
} else {
debug("Server host key: %s %s", compat20 ?
sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);
debug("Server host key: %s %s", sshkey_ssh_name(host_key), fp);
}

if (sshkey_equal(previous_host_key, host_key)) {
@@ -1349,12 +1339,8 @@ ssh_login(Sensitive *sensitive, const char *orighost,
/* key exchange */
/* authenticate user */
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
if (compat20) {
ssh_kex2(host, hostaddr, port);
ssh_userauth2(local_user, server_user, host, sensitive);
} else {
fatal("ssh1 is not supported");
}
ssh_kex2(host, hostaddr, port);
ssh_userauth2(local_user, server_user, host, sensitive);
free(local_user);
}

8 sshd.c
@@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */
/* $OpenBSD: sshd.c,v 1.486 2017/04/30 23:13:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -450,10 +450,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
chop(server_version_string);
debug("Local version string %.200s", server_version_string);

if (remote_major == 2 ||
(remote_major == 1 && remote_minor == 99)) {
enable_compat20();
} else {
if (remote_major != 2 ||
(remote_major == 1 && remote_minor != 99)) {
s = "Protocol major versions differ.\n";
(void) atomicio(vwrite, sock_out, s, strlen(s));
close(sock_in);
@@ -1,4 +1,4 @@
/* $OpenBSD: ttymodes.c,v 1.30 2016/05/04 14:22:33 markus Exp $ */
/* $OpenBSD: ttymodes.c,v 1.31 2017/04/30 23:13:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -283,18 +283,10 @@ tty_make_modes(int fd, struct termios *tiop)
int baud;
Buffer buf;
int tty_op_ospeed, tty_op_ispeed;
void (*put_arg)(Buffer *, u_int);

buffer_init(&buf);
if (compat20) {
tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
put_arg = buffer_put_int;
} else {
tty_op_ospeed = TTY_OP_OSPEED_PROTO1;
tty_op_ispeed = TTY_OP_ISPEED_PROTO1;
put_arg = (void (*)(Buffer *, u_int)) buffer_put_char;
}
tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
tty_op_ispeed = TTY_OP_ISPEED_PROTO2;

if (tiop == NULL) {
if (fd == -1) {
@@ -319,11 +311,11 @@ tty_make_modes(int fd, struct termios *tiop)
/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
buffer_put_char(&buf, OP); \
put_arg(&buf, special_char_encode(tio.c_cc[NAME]));
buffer_put_int(&buf, special_char_encode(tio.c_cc[NAME]));

#define TTYMODE(NAME, FIELD, OP) \
buffer_put_char(&buf, OP); \
put_arg(&buf, ((tio.FIELD & NAME) != 0));
buffer_put_int(&buf, ((tio.FIELD & NAME) != 0));

#include "ttymodes.h"

@@ -333,10 +325,7 @@ tty_make_modes(int fd, struct termios *tiop)
end:
/* Mark end of mode data. */
buffer_put_char(&buf, TTY_OP_END);
if (compat20)
packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
else
packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
buffer_free(&buf);
}

@@ -351,19 +340,10 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
int opcode, baud;
int n_bytes = 0;
int failure = 0;
u_int (*get_arg)(void);
int arg_size;

if (compat20) {
*n_bytes_ptr = packet_get_int();
if (*n_bytes_ptr == 0)
return;
get_arg = packet_get_int;
arg_size = 4;
} else {
get_arg = packet_get_char;
arg_size = 1;
}

*n_bytes_ptr = packet_get_int();
if (*n_bytes_ptr == 0)
return;

/*
* Get old attributes for the terminal. We will modify these
@@ -404,13 +384,13 @@ tty_parse_modes(int fd, int *n_bytes_ptr)

#define TTYCHAR(NAME, OP) \
case OP: \
n_bytes += arg_size; \
tio.c_cc[NAME] = special_char_decode(get_arg()); \
n_bytes += 4; \
tio.c_cc[NAME] = special_char_decode(packet_get_int()); \
break;
#define TTYMODE(NAME, FIELD, OP) \
case OP: \
n_bytes += arg_size; \
if (get_arg()) \
n_bytes += 4; \
if (packet_get_int()) \
tio.FIELD |= NAME; \
else \
tio.FIELD &= ~NAME; \
@@ -424,51 +404,21 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
default:
debug("Ignoring unsupported tty mode opcode %d (0x%x)",
opcode, opcode);
if (!compat20) {
/*
* SSH1:
* Opcodes 1 to 127 are defined to have
* a one-byte argument.
* Opcodes 128 to 159 are defined to have
* an integer argument.
*/
if (opcode > 0 && opcode < 128) {
n_bytes += 1;
(void) packet_get_char();
break;
} else if (opcode >= 128 && opcode < 160) {
n_bytes += 4;
(void) packet_get_int();
break;
} else {
/*
* It is a truly undefined opcode (160 to 255).
* We have no idea about its arguments. So we
* must stop parsing. Note that some data
* may be left in the packet; hopefully there
* is nothing more coming after the mode data.
*/
logit("parse_tty_modes: unknown opcode %d",
opcode);
goto set;
}
/*
* SSH2:
* Opcodes 1 to 159 are defined to have a uint32
* argument.
* Opcodes 160 to 255 are undefined and cause parsing
* to stop.
*/
if (opcode > 0 && opcode < 160) {
n_bytes += 4;
(void) packet_get_int();
break;
} else {
/*
* SSH2:
* Opcodes 1 to 159 are defined to have
* a uint32 argument.
* Opcodes 160 to 255 are undefined and
* cause parsing to stop.
*/
if (opcode > 0 && opcode < 160) {
n_bytes += 4;
(void) packet_get_int();
break;
} else {
logit("parse_tty_modes: unknown opcode %d",
opcode);
goto set;
}
logit("parse_tty_modes: unknown opcode %d",
opcode);
goto set;
}
}
}