-/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */
+/* $OpenBSD: channels.c,v 1.358 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
for (i = 0; i < channels_alloc; i++) {
c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
-#if 0
- if (!compat20 &&
- buffer_len(&c->input) > packet_get_maxsize()) {
- debug2("channel %d: big input buffer %d",
- c->self, buffer_len(&c->input));
- return 0;
- }
-#endif
if (buffer_len(&c->output) > packet_get_maxsize()) {
debug2("channel %d: big output buffer %u > %u",
c->self, buffer_len(&c->output),
case SSH_CHANNEL_RUNIX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
- if (!compat20)
- fatal("cannot happen: SSH_CHANNEL_LARVAL");
continue;
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
return 1;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
- if (!compat13)
- fatal("cannot happen: OUT_DRAIN");
- return 1;
+ fatal("cannot happen: OUT_DRAIN");
default:
- fatal("channel_still_open: bad channel type %d", c->type);
+ fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
}
}
return i;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
- if (!compat13)
- fatal("cannot happen: OUT_DRAIN");
- return i;
+ fatal("cannot happen: OUT_DRAIN");
default:
- fatal("channel_find_open: bad channel type %d", c->type);
+ fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
}
}
FD_SET(c->sock, writeset);
}
-static void
-channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
-{
- if (buffer_len(&c->input) < packet_get_maxsize())
- FD_SET(c->sock, readset);
- if (buffer_len(&c->output) > 0)
- FD_SET(c->sock, writeset);
-}
-
static void
channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
{
- u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
-
if (c->istate == CHAN_INPUT_OPEN &&
- limit > 0 &&
- buffer_len(&c->input) < limit &&
+ c->remote_window > 0 &&
+ buffer_len(&c->input) < c->remote_window &&
buffer_check_alloc(&c->input, CHAN_RBUF))
FD_SET(c->rfd, readset);
if (c->ostate == CHAN_OUTPUT_OPEN ||
}
}
/** XXX check close conditions, too */
- if (compat20 && c->efd != -1 &&
- !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) {
+ if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
+ c->ostate == CHAN_OUTPUT_CLOSED)) {
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
buffer_len(&c->extended) > 0)
FD_SET(c->efd, writeset);
/* XXX: What about efd? races? */
}
-/* ARGSUSED */
-static void
-channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
-{
- if (buffer_len(&c->input) == 0) {
- packet_start(SSH_MSG_CHANNEL_CLOSE);
- packet_put_int(c->remote_id);
- packet_send();
- c->type = SSH_CHANNEL_CLOSED;
- debug2("channel %d: closing after input drain.", c->self);
- }
-}
-
-/* ARGSUSED */
-static void
-channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
-{
- if (buffer_len(&c->output) == 0)
- chan_mark_dead(c);
- else
- FD_SET(c->sock, writeset);
-}
-
/*
* This is a special state for X11 authentication spoofing. An opened X11
* connection (when authentication spoofing is being done) remains in this
return 1;
}
-static void
-channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
-{
- int ret = x11_open_helper(&c->output);
-
- if (ret == 1) {
- /* Start normal processing for the channel. */
- c->type = SSH_CHANNEL_OPEN;
- channel_pre_open_13(c, readset, writeset);
- } else if (ret == -1) {
- /*
- * We have received an X11 connection that has bad
- * authentication information.
- */
- logit("X11 connection rejected because of wrong authentication.");
- buffer_clear(&c->input);
- buffer_clear(&c->output);
- channel_close_fd(&c->sock);
- c->sock = -1;
- c->type = SSH_CHANNEL_CLOSED;
- packet_start(SSH_MSG_CHANNEL_CLOSE);
- packet_put_int(c->remote_id);
- packet_send();
- }
-}
-
static void
channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
{
buffer_clear(&c->input);
chan_ibuf_empty(c);
buffer_clear(&c->output);
- /* for proto v1, the peer will send an IEOF */
- if (compat20)
- chan_write_failed(c);
- else
- c->type = SSH_CHANNEL_OPEN;
+ chan_write_failed(c);
debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
}
}
nc = channel_new("accepted x11 socket",
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, 0, buf, 1);
- if (compat20) {
- packet_start(SSH2_MSG_CHANNEL_OPEN);
- packet_put_cstring("x11");
- packet_put_int(nc->self);
- packet_put_int(nc->local_window_max);
- packet_put_int(nc->local_maxpacket);
- /* originator ipaddr and port */
- packet_put_cstring(remote_ipaddr);
- if (datafellows & SSH_BUG_X11FWD) {
- debug2("ssh2 x11 bug compat mode");
- } else {
- packet_put_int(remote_port);
- }
- packet_send();
+ packet_start(SSH2_MSG_CHANNEL_OPEN);
+ packet_put_cstring("x11");
+ packet_put_int(nc->self);
+ packet_put_int(nc->local_window_max);
+ packet_put_int(nc->local_maxpacket);
+ /* originator ipaddr and port */
+ packet_put_cstring(remote_ipaddr);
+ if (datafellows & SSH_BUG_X11FWD) {
+ debug2("ssh2 x11 bug compat mode");
} else {
- packet_start(SSH_SMSG_X11_OPEN);
- packet_put_int(nc->self);
- if (packet_get_protocol_flags() &
- SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
- packet_put_cstring(buf);
- packet_send();
+ packet_put_int(remote_port);
}
+ packet_send();
free(remote_ipaddr);
}
}
free(c->remote_name);
c->remote_name = xstrdup(buf);
- if (compat20) {
- packet_start(SSH2_MSG_CHANNEL_OPEN);
- packet_put_cstring(rtype);
- packet_put_int(c->self);
- packet_put_int(c->local_window_max);
- packet_put_int(c->local_maxpacket);
- if (strcmp(rtype, "direct-tcpip") == 0) {
- /* target host, port */
- packet_put_cstring(c->path);
- packet_put_int(c->host_port);
- } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
- /* target path */
- packet_put_cstring(c->path);
- } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
- /* listen path */
- packet_put_cstring(c->path);
- } else {
- /* listen address, port */
- packet_put_cstring(c->path);
- packet_put_int(local_port);
- }
- if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
- /* reserved for future owner/mode info */
- packet_put_cstring("");
- } else {
- /* originator host and port */
- packet_put_cstring(remote_ipaddr);
- packet_put_int((u_int)remote_port);
- }
- packet_send();
- } else {
- packet_start(SSH_MSG_PORT_OPEN);
- packet_put_int(c->self);
+ packet_start(SSH2_MSG_CHANNEL_OPEN);
+ packet_put_cstring(rtype);
+ packet_put_int(c->self);
+ packet_put_int(c->local_window_max);
+ packet_put_int(c->local_maxpacket);
+ if (strcmp(rtype, "direct-tcpip") == 0) {
+ /* target host, port */
packet_put_cstring(c->path);
packet_put_int(c->host_port);
- if (packet_get_protocol_flags() &
- SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
- packet_put_cstring(c->remote_name);
- packet_send();
+ } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
+ /* target path */
+ packet_put_cstring(c->path);
+ } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
+ /* listen path */
+ packet_put_cstring(c->path);
+ } else {
+ /* listen address, port */
+ packet_put_cstring(c->path);
+ packet_put_int(local_port);
+ }
+ if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
+ /* reserved for future owner/mode info */
+ packet_put_cstring("");
+ } else {
+ /* originator host and port */
+ packet_put_cstring(remote_ipaddr);
+ packet_put_int((u_int)remote_port);
}
+ packet_send();
free(remote_ipaddr);
free(local_ipaddr);
}
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket,
0, "accepted auth socket", 1);
- if (compat20) {
- packet_start(SSH2_MSG_CHANNEL_OPEN);
- packet_put_cstring("auth-agent@openssh.com");
- packet_put_int(nc->self);
- packet_put_int(c->local_window_max);
- packet_put_int(c->local_maxpacket);
- } else {
- packet_start(SSH_SMSG_AGENT_OPEN);
- packet_put_int(nc->self);
- }
+ packet_start(SSH2_MSG_CHANNEL_OPEN);
+ packet_put_cstring("auth-agent@openssh.com");
+ packet_put_int(nc->self);
+ packet_put_int(c->local_window_max);
+ packet_put_int(c->local_maxpacket);
packet_send();
}
}
c->self, c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
c->type = SSH_CHANNEL_OPEN;
- if (compat20) {
- packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(c->remote_id);
- packet_put_int(c->self);
- packet_put_int(c->local_window);
- packet_put_int(c->local_maxpacket);
- } else {
- packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(c->remote_id);
- packet_put_int(c->self);
- }
+ packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
+ packet_put_int(c->remote_id);
+ packet_put_int(c->self);
+ packet_put_int(c->local_window);
+ packet_put_int(c->local_maxpacket);
} else {
debug("channel %d: connection failed: %s",
c->self, strerror(err));
error("connect_to %.100s port %d: failed.",
c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
- if (compat20) {
- packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
- packet_put_int(c->remote_id);
- packet_put_int(SSH2_OPEN_CONNECT_FAILED);
- if (!(datafellows & SSH_BUG_OPENFAILURE)) {
- packet_put_cstring(strerror(err));
- packet_put_cstring("");
- }
- } else {
- packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
- packet_put_int(c->remote_id);
+ packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
+ packet_put_int(c->remote_id);
+ packet_put_int(SSH2_OPEN_CONNECT_FAILED);
+ if (!(datafellows & SSH_BUG_OPENFAILURE)) {
+ packet_put_cstring(strerror(err));
+ packet_put_cstring("");
}
chan_mark_dead(c);
}
debug2("channel %d: not open", c->self);
chan_mark_dead(c);
return -1;
- } else if (compat13) {
- buffer_clear(&c->output);
- c->type = SSH_CHANNEL_INPUT_DRAINING;
- debug2("channel %d: input draining.", c->self);
} else {
chan_read_failed(c);
}
debug2("channel %d: not open", c->self);
chan_mark_dead(c);
return -1;
- } else if (compat13) {
- buffer_clear(&c->output);
- debug2("channel %d: input draining.", c->self);
- c->type = SSH_CHANNEL_INPUT_DRAINING;
} else {
chan_write_failed(c);
}
return -1;
}
- if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
+ if (c->isatty && dlen >= 1 && buf[0] != '\r') {
if (tcgetattr(c->wfd, &tio) == 0 &&
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
/*
buffer_consume(&c->output, len);
}
out:
- if (compat20 && olen > 0)
+ if (olen > 0)
c->local_consumed += olen - buffer_len(&c->output);
return 1;
}
{
channel_handle_rfd(c, readset, writeset);
channel_handle_wfd(c, readset, writeset);
- if (!compat20)
- return;
channel_handle_efd(c, readset, writeset);
channel_check_window(c);
}
u_int need;
ssize_t len;
- if (!compat20)
- fatal("%s: entered with !compat20", __func__);
-
if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&
(c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)) {
nc->flags |= CHAN_LOCAL;
}
-/* ARGSUSED */
static void
-channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
+channel_handler_init(void)
{
- int len;
+ int i;
- /* Send buffered output data to the socket. */
- if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
- len = write(c->sock, buffer_ptr(&c->output),
- buffer_len(&c->output));
- if (len <= 0)
- buffer_clear(&c->output);
- else
- buffer_consume(&c->output, len);
+ for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
+ channel_pre[i] = NULL;
+ channel_post[i] = NULL;
}
-}
-
-static void
-channel_handler_init_20(void)
-{
channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
}
-static void
-channel_handler_init_13(void)
-{
- channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
- channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
- channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
- channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
- channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
- channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
-
- channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
- channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
- channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
- channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
- channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
- channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
- channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
-}
-
-static void
-channel_handler_init_15(void)
-{
- channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
- channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
- channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
- channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
- channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
-
- channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
- channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
- channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
- channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
- channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
- channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
-}
-
-static void
-channel_handler_init(void)
-{
- int i;
-
- for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
- channel_pre[i] = NULL;
- channel_post[i] = NULL;
- }
- if (compat20)
- channel_handler_init_20();
- else if (compat13)
- channel_handler_init_13();
- else
- channel_handler_init_15();
-}
-
/* gc dead channels */
static void
channel_garbage_collect(Channel *c)
* We are only interested in channels that can have buffered
* incoming data.
*/
- if (compat13) {
- if (c->type != SSH_CHANNEL_OPEN &&
- c->type != SSH_CHANNEL_INPUT_DRAINING)
- continue;
- } else {
- if (c->type != SSH_CHANNEL_OPEN)
- continue;
- }
- if (compat20 &&
- (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
+ if (c->type != SSH_CHANNEL_OPEN)
+ continue;
+ if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
/* XXX is this true? */
debug3("channel %d: will not send data after close", c->self);
continue;
* Send some data for the other side over the secure
* connection.
*/
- if (compat20) {
- if (len > c->remote_window)
- len = c->remote_window;
- if (len > c->remote_maxpacket)
- len = c->remote_maxpacket;
- } else {
- if (packet_is_interactive()) {
- if (len > 1024)
- len = 512;
- } else {
- /* Keep the packets at reasonable size. */
- if (len > packet_get_maxsize()/2)
- len = packet_get_maxsize()/2;
- }
- }
+ if (len > c->remote_window)
+ len = c->remote_window;
+ if (len > c->remote_maxpacket)
+ len = c->remote_maxpacket;
if (len > 0) {
- packet_start(compat20 ?
- SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
+ packet_start(SSH2_MSG_CHANNEL_DATA);
packet_put_int(c->remote_id);
packet_put_string(buffer_ptr(&c->input), len);
packet_send();
c->remote_window -= len;
}
} else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
- if (compat13)
- fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
/*
* input-buffer is empty and read-socket shutdown:
* tell peer, that we will not send more data: send IEOF.
chan_ibuf_empty(c);
}
/* Send extended data, i.e. stderr */
- if (compat20 &&
- !(c->flags & CHAN_EOF_SENT) &&
+ if (!(c->flags & CHAN_EOF_SENT) &&
c->remote_window > 0 &&
(len = buffer_len(&c->extended)) > 0 &&
c->extended_usage == CHAN_EXTENDED_READ) {
* that window updates are sent back. Otherwise the connection might
* deadlock.
*/
- if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {
- if (compat20) {
- c->local_window -= win_len;
- c->local_consumed += win_len;
- }
+ if (c->ostate != CHAN_OUTPUT_OPEN) {
+ c->local_window -= win_len;
+ c->local_consumed += win_len;
return 0;
}
- if (compat20) {
- if (win_len > c->local_maxpacket) {
- logit("channel %d: rcvd big packet %d, maxpack %d",
- c->self, win_len, c->local_maxpacket);
- }
- if (win_len > c->local_window) {
- logit("channel %d: rcvd too much data %d, win %d",
- c->self, win_len, c->local_window);
- return 0;
- }
- c->local_window -= win_len;
+ if (win_len > c->local_maxpacket) {
+ logit("channel %d: rcvd big packet %d, maxpack %d",
+ c->self, win_len, c->local_maxpacket);
+ }
+ if (win_len > c->local_window) {
+ logit("channel %d: rcvd too much data %d, win %d",
+ c->self, win_len, c->local_window);
+ return 0;
}
+ c->local_window -= win_len;
+
if (c->datagram)
buffer_put_string(&c->output, data, data_len);
else
c->remote_id = remote_id;
c->type = SSH_CHANNEL_OPEN;
- if (compat20) {
- c->remote_window = packet_get_int();
- c->remote_maxpacket = packet_get_int();
- if (c->open_confirm) {
- debug2("callback start");
- c->open_confirm(c->self, 1, c->open_confirm_ctx);
- debug2("callback done");
- }
- debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
- c->remote_window, c->remote_maxpacket);
+ c->remote_window = packet_get_int();
+ c->remote_maxpacket = packet_get_int();
+ if (c->open_confirm) {
+ debug2("callback start");
+ c->open_confirm(c->self, 1, c->open_confirm_ctx);
+ debug2("callback done");
}
+ debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
+ c->remote_window, c->remote_maxpacket);
packet_check_eom();
return 0;
}
if (c->type != SSH_CHANNEL_OPENING)
packet_disconnect("Received open failure for "
"non-opening channel %d.", id);
- if (compat20) {
- reason = packet_get_int();
- if (!(datafellows & SSH_BUG_OPENFAILURE)) {
- msg = packet_get_string(NULL);
- lang = packet_get_string(NULL);
- }
- logit("channel %d: open failed: %s%s%s", id,
- reason2txt(reason), msg ? ": ": "", msg ? msg : "");
- free(msg);
- free(lang);
- if (c->open_confirm) {
- debug2("callback start");
- c->open_confirm(c->self, 0, c->open_confirm_ctx);
- debug2("callback done");
- }
+ reason = packet_get_int();
+ if (!(datafellows & SSH_BUG_OPENFAILURE)) {
+ msg = packet_get_string(NULL);
+ lang = packet_get_string(NULL);
+ }
+ logit("channel %d: open failed: %s%s%s", id,
+ reason2txt(reason), msg ? ": ": "", msg ? msg : "");
+ free(msg);
+ free(lang);
+ if (c->open_confirm) {
+ debug2("callback start");
+ c->open_confirm(c->self, 0, c->open_confirm_ctx);
+ debug2("callback done");
}
packet_check_eom();
/* Schedule the channel for cleanup/deletion. */
int id;
u_int adjust, tmp;
- if (!compat20)
- return 0;
-
/* Get the channel number and verify it. */
id = packet_get_int();
c = channel_lookup(id);
int
channel_request_remote_forwarding(struct Forward *fwd)
{
- int type, success = 0, idx = -1;
+ int success = 0, idx = -1;
/* Send the forward request to the remote side. */
- if (compat20) {
- packet_start(SSH2_MSG_GLOBAL_REQUEST);
- if (fwd->listen_path != NULL) {
- packet_put_cstring("streamlocal-forward@openssh.com");
- packet_put_char(1); /* boolean: want reply */
- packet_put_cstring(fwd->listen_path);
- } else {
- packet_put_cstring("tcpip-forward");
- packet_put_char(1); /* boolean: want reply */
- packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
- packet_put_int(fwd->listen_port);
- }
- packet_send();
- packet_write_wait();
- /* Assume that server accepts the request */
- success = 1;
- } else if (fwd->listen_path == NULL) {
- packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
- packet_put_int(fwd->listen_port);
- packet_put_cstring(fwd->connect_host);
- packet_put_int(fwd->connect_port);
- packet_send();
- packet_write_wait();
-
- /* Wait for response from the remote side. */
- type = packet_read();
- switch (type) {
- case SSH_SMSG_SUCCESS:
- success = 1;
- break;
- case SSH_SMSG_FAILURE:
- break;
- default:
- /* Unknown packet */
- packet_disconnect("Protocol error for port forward request:"
- "received packet type %d.", type);
- }
+ packet_start(SSH2_MSG_GLOBAL_REQUEST);
+ if (fwd->listen_path != NULL) {
+ packet_put_cstring("streamlocal-forward@openssh.com");
+ packet_put_char(1); /* boolean: want reply */
+ packet_put_cstring(fwd->listen_path);
} else {
- logit("Warning: Server does not support remote stream local forwarding.");
+ packet_put_cstring("tcpip-forward");
+ packet_put_char(1); /* boolean: want reply */
+ packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
+ packet_put_int(fwd->listen_port);
}
+ packet_send();
+ packet_write_wait();
+ /* Assume that server accepts the request */
+ success = 1;
if (success) {
/* Record that connection to this host/port is permitted. */
permitted_opens = xreallocarray(permitted_opens,
{
int i;
- if (!compat20)
- return -1;
-
for (i = 0; i < num_permitted_opens; i++) {
if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0))
break;
{
int i;
- if (!compat20)
- return -1;
-
for (i = 0; i < num_permitted_opens; i++) {
if (open_listen_match_streamlocal(&permitted_opens[i], path))
break;
new_data = tohex(x11_fake_data, data_len);
/* Send the request packet. */
- if (compat20) {
- channel_request_start(client_session_id, "x11-req", want_reply);
- packet_put_char(0); /* XXX bool single connection */
- } else {
- packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
- }
+ channel_request_start(client_session_id, "x11-req", want_reply);
+ packet_put_char(0); /* XXX bool single connection */
packet_put_cstring(proto);
packet_put_cstring(new_data);
packet_put_int(screen_number);
-/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 dtucker Exp $ */
+/* $OpenBSD: channels.h,v 1.122 2017/04/30 23:13:25 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
/* check whether 'efd' is still in use */
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
- (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
+ (c->extended_usage == CHAN_EXTENDED_READ && \
(c->efd != -1 || \
buffer_len(&c->extended) > 0))
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
- (compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \
+ (c->extended_usage == CHAN_EXTENDED_WRITE && \
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
buffer_len(&c->extended) > 0))
-/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.292 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
}
}
-/* Puts stdin terminal in non-blocking mode. */
-
-static void
-enter_non_blocking(void)
-{
- in_non_blocking_mode = 1;
- set_nonblock(fileno(stdin));
-}
-
/*
* Signal handler for the window change signal (SIGWINCH). This just sets a
* flag indicating that the window has changed.
return 0;
}
-/*
- * This is called when the interactive is entered. This checks if there is
- * an EOF coming on stdin. We must check this explicitly, as select() does
- * not appear to wake up when redirecting from /dev/null.
- */
-
-static void
-client_check_initial_eof_on_stdin(void)
-{
- int len;
- char buf[1];
-
- /*
- * If standard input is to be "redirected from /dev/null", we simply
- * mark that we have seen an EOF and send an EOF message to the
- * server. Otherwise, we try to read a single character; it appears
- * that for some files, such /dev/null, select() never wakes up for
- * read for this descriptor, which means that we never get EOF. This
- * way we will get the EOF if stdin comes from /dev/null or similar.
- */
- if (stdin_null_flag) {
- /* Fake EOF on stdin. */
- debug("Sending eof.");
- stdin_eof = 1;
- packet_start(SSH_CMSG_EOF);
- packet_send();
- } else {
- enter_non_blocking();
-
- /* Check for immediate EOF on stdin. */
- len = read(fileno(stdin), buf, 1);
- if (len == 0) {
- /*
- * EOF. Record that we have seen it and send
- * EOF to server.
- */
- debug("Sending eof.");
- stdin_eof = 1;
- packet_start(SSH_CMSG_EOF);
- packet_send();
- } else if (len > 0) {
- /*
- * Got data. We must store the data in the buffer,
- * and also process it as an escape character if
- * appropriate.
- */
- if ((u_char) buf[0] == escape_char1)
- escape_pending1 = 1;
- else
- buffer_append(&stdin_buffer, buf, 1);
- }
- leave_non_blocking();
- }
-}
-
-
-/*
- * Make packets from buffered stdin data, and buffer them for sending to the
- * connection.
- */
-
-static void
-client_make_packets_from_stdin_data(void)
-{
- u_int len;
-
- /* Send buffered stdin data to the server. */
- while (buffer_len(&stdin_buffer) > 0 &&
- packet_not_very_much_data_to_write()) {
- len = buffer_len(&stdin_buffer);
- /* Keep the packets at reasonable size. */
- if (len > packet_get_maxsize())
- len = packet_get_maxsize();
- packet_start(SSH_CMSG_STDIN_DATA);
- packet_put_string(buffer_ptr(&stdin_buffer), len);
- packet_send();
- buffer_consume(&stdin_buffer, len);
- /* If we have a pending EOF, send it now. */
- if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
- packet_start(SSH_CMSG_EOF);
- packet_send();
- }
- }
-}
-
/*
* Checks if the client window has changed, and sends a packet about it to
* the server if so. The actual change is detected elsewhere (by a software
static void
client_check_window_change(void)
{
- struct winsize ws;
-
- if (! received_window_change_signal)
+ if (!received_window_change_signal)
return;
/** XXX race */
received_window_change_signal = 0;
- debug2("client_check_window_change: changed");
+ debug2("%s: changed", __func__);
- if (compat20) {
- channel_send_window_changes();
- } else {
- if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
- return;
- packet_start(SSH_CMSG_WINDOW_SIZE);
- 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);
- packet_send();
- }
+ channel_send_window_changes();
}
static int
channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
&minwait_secs, rekeying);
- if (!compat20) {
- /* Read from the connection, unless our buffers are full. */
- if (buffer_len(&stdout_buffer) < buffer_high &&
- buffer_len(&stderr_buffer) < buffer_high &&
- channel_not_very_much_buffered_data())
- FD_SET(connection_in, *readsetp);
- /*
- * Read from stdin, unless we have seen EOF or have very much
- * buffered data to send to the server.
- */
- if (!stdin_eof && packet_not_very_much_data_to_write())
- FD_SET(fileno(stdin), *readsetp);
-
- /* Select stdout/stderr if have data in buffer. */
- if (buffer_len(&stdout_buffer) > 0)
- FD_SET(fileno(stdout), *writesetp);
- if (buffer_len(&stderr_buffer) > 0)
- FD_SET(fileno(stderr), *writesetp);
+ /* channel_prepare_select could have closed the last channel */
+ if (session_closed && !channel_still_open() &&
+ !packet_have_data_to_write()) {
+ /* clear mask since we did not call select() */
+ memset(*readsetp, 0, *nallocp);
+ memset(*writesetp, 0, *nallocp);
+ return;
} else {
- /* channel_prepare_select could have closed the last channel */
- if (session_closed && !channel_still_open() &&
- !packet_have_data_to_write()) {
- /* clear mask since we did not call select() */
- memset(*readsetp, 0, *nallocp);
- memset(*writesetp, 0, *nallocp);
- return;
- } else {
- FD_SET(connection_in, *readsetp);
- }
+ FD_SET(connection_in, *readsetp);
}
/* Select server connection if have data to write to the server. */
*/
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
- if (options.server_alive_interval > 0 && compat20) {
+ if (options.server_alive_interval > 0) {
timeout_secs = options.server_alive_interval;
server_alive_time = now + options.server_alive_interval;
}
- if (options.rekey_interval > 0 && compat20 && !rekeying)
+ if (options.rekey_interval > 0 && !rekeying)
timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
set_control_persist_exit_time();
if (control_persist_exit_time > 0) {
goto out;
}
- if (delete && !compat20) {
- logit("Not supported for SSH protocol version 1.");
- goto out;
- }
-
while (isspace((u_char)*++s))
;
/* reasons to suppress output of an escape command in help output */
#define SUPPRESS_NEVER 0 /* never suppress, always show */
-#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */
-#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */
-#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */
-#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
+#define SUPPRESS_MUXCLIENT 1 /* don't show in mux client sessions */
+#define SUPPRESS_MUXMASTER 2 /* don't show in mux master sessions */
+#define SUPPRESS_SYSLOG 4 /* don't show when logging to syslog */
struct escape_help_text {
const char *cmd;
const char *text;
{".", "terminate session", SUPPRESS_MUXMASTER},
{".", "terminate connection (and any multiplexed sessions)",
SUPPRESS_MUXCLIENT},
- {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1},
+ {"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
{"C", "open a command line", SUPPRESS_MUXCLIENT},
- {"R", "request rekey", SUPPRESS_PROTO1},
+ {"R", "request rekey", SUPPRESS_NEVER},
{"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
{"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
{"#", "list forwarded connections", SUPPRESS_NEVER},
};
static void
-print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
- int using_stderr)
+print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
{
unsigned int i, suppress_flags;
char string[1024];
"Supported escape sequences:\r\n", escape_char);
buffer_append(b, string, strlen(string));
- suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |
+ suppress_flags =
(mux_client ? SUPPRESS_MUXCLIENT : 0) |
(mux_client ? 0 : SUPPRESS_MUXMASTER) |
(using_stderr ? 0 : SUPPRESS_SYSLOG);
continue;
case 'B':
- if (compat20) {
- snprintf(string, sizeof string,
- "%cB\r\n", escape_char);
- buffer_append(berr, string,
- strlen(string));
- channel_request_start(c->self,
- "break", 0);
- packet_put_int(1000);
- packet_send();
- }
+ snprintf(string, sizeof string,
+ "%cB\r\n", escape_char);
+ buffer_append(berr, string, strlen(string));
+ channel_request_start(c->self, "break", 0);
+ packet_put_int(1000);
+ packet_send();
continue;
case 'R':
- if (compat20) {
- if (datafellows & SSH_BUG_NOREKEY)
- logit("Server does not "
- "support re-keying");
- else
- need_rekeying = 1;
- }
+ if (datafellows & SSH_BUG_NOREKEY)
+ logit("Server does not "
+ "support re-keying");
+ else
+ need_rekeying = 1;
continue;
case 'V':
exit(0);
}
/* The child continues serving connections. */
- if (compat20) {
- buffer_append(bin, "\004", 1);
- /* fake EOF on stdin */
- return -1;
- } else if (!stdin_eof) {
- /*
- * Sending SSH_CMSG_EOF alone does not
- * always appear to be enough. So we
- * try to send an EOF character first.
- */
- packet_start(SSH_CMSG_STDIN_DATA);
- packet_put_string("\004", 1);
- packet_send();
- /* Close stdin. */
- stdin_eof = 1;
- if (buffer_len(bin) == 0) {
- packet_start(SSH_CMSG_EOF);
- packet_send();
- }
- }
- continue;
-
+ buffer_append(bin, "\004", 1);
+ /* fake EOF on stdin */
+ return -1;
case '?':
- print_escape_help(berr, escape_char, compat20,
+ print_escape_help(berr, escape_char,
(c && c->ctl_chan != -1),
log_is_on_stderr());
continue;
return bytes;
}
-static void
-client_process_input(fd_set *readset)
-{
- int len;
- char buf[8192];
-
- /* Read input from stdin. */
- if (FD_ISSET(fileno(stdin), readset)) {
- /* Read as much as possible. */
- len = read(fileno(stdin), buf, sizeof(buf));
- if (len < 0 && (errno == EAGAIN || errno == EINTR))
- return; /* we'll try again later */
- if (len <= 0) {
- /*
- * Received EOF or error. They are treated
- * similarly, except that an error message is printed
- * if it was an error condition.
- */
- if (len < 0) {
- snprintf(buf, sizeof buf, "read: %.100s\r\n",
- strerror(errno));
- buffer_append(&stderr_buffer, buf, strlen(buf));
- }
- /* Mark that we have seen EOF. */
- stdin_eof = 1;
- /*
- * Send an EOF message to the server unless there is
- * data in the buffer. If there is data in the
- * buffer, no message will be sent now. Code
- * elsewhere will send the EOF when the buffer
- * becomes empty if stdin_eof is set.
- */
- if (buffer_len(&stdin_buffer) == 0) {
- packet_start(SSH_CMSG_EOF);
- packet_send();
- }
- } else if (escape_char1 == SSH_ESCAPECHAR_NONE) {
- /*
- * Normal successful read, and no escape character.
- * Just append the data to buffer.
- */
- buffer_append(&stdin_buffer, buf, len);
- } else {
- /*
- * Normal, successful read. But we have an escape
- * character and have to process the characters one
- * by one.
- */
- if (process_escapes(NULL, &stdin_buffer,
- &stdout_buffer, &stderr_buffer, buf, len) == -1)
- return;
- }
- }
-}
-
-static void
-client_process_output(fd_set *writeset)
-{
- int len;
- char buf[100];
-
- /* Write buffered output to stdout. */
- if (FD_ISSET(fileno(stdout), writeset)) {
- /* Write as much data as possible. */
- len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
- buffer_len(&stdout_buffer));
- if (len <= 0) {
- if (errno == EINTR || errno == EAGAIN)
- len = 0;
- else {
- /*
- * An error or EOF was encountered. Put an
- * error message to stderr buffer.
- */
- snprintf(buf, sizeof buf,
- "write stdout: %.50s\r\n", strerror(errno));
- buffer_append(&stderr_buffer, buf, strlen(buf));
- quit_pending = 1;
- return;
- }
- }
- /* Consume printed data from the buffer. */
- buffer_consume(&stdout_buffer, len);
- }
- /* Write buffered output to stderr. */
- if (FD_ISSET(fileno(stderr), writeset)) {
- /* Write as much data as possible. */
- len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
- buffer_len(&stderr_buffer));
- if (len <= 0) {
- if (errno == EINTR || errno == EAGAIN)
- len = 0;
- else {
- /*
- * EOF or error, but can't even print
- * error message.
- */
- quit_pending = 1;
- return;
- }
- }
- /* Consume printed characters from the buffer. */
- buffer_consume(&stderr_buffer, len);
- }
-}
-
/*
* Get packets from the connection input buffer, and process them as long as
* there are packets available.
connection_out = packet_get_connection_out();
max_fd = MAXIMUM(connection_in, connection_out);
- if (!compat20) {
- /* enable nonblocking unless tty */
- if (!isatty(fileno(stdin)))
- set_nonblock(fileno(stdin));
- if (!isatty(fileno(stdout)))
- set_nonblock(fileno(stdout));
- if (!isatty(fileno(stderr)))
- set_nonblock(fileno(stderr));
- max_fd = MAXIMUM(max_fd, fileno(stdin));
- max_fd = MAXIMUM(max_fd, fileno(stdout));
- max_fd = MAXIMUM(max_fd, fileno(stderr));
- }
quit_pending = 0;
escape_char1 = escape_char_arg;
if (have_pty)
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
- if (compat20) {
- session_ident = ssh2_chan_id;
- if (session_ident != -1) {
- if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
- channel_register_filter(session_ident,
- client_simple_escape_filter, NULL,
- client_filter_cleanup,
- client_new_escape_filter_ctx(
- escape_char_arg));
- }
- channel_register_cleanup(session_ident,
- client_channel_closed, 0);
+ session_ident = ssh2_chan_id;
+ if (session_ident != -1) {
+ if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
+ channel_register_filter(session_ident,
+ client_simple_escape_filter, NULL,
+ client_filter_cleanup,
+ client_new_escape_filter_ctx(
+ escape_char_arg));
}
- } else {
- /* Check if we should immediately send eof on stdin. */
- client_check_initial_eof_on_stdin();
+ channel_register_cleanup(session_ident,
+ client_channel_closed, 0);
}
/* Main loop of the client for the interactive session mode. */
/* Process buffered packets sent by the server. */
client_process_buffered_input_packets();
- if (compat20 && session_closed && !channel_still_open())
+ if (session_closed && !channel_still_open())
break;
if (ssh_packet_is_rekeying(active_state)) {
ssh_err(r));
need_rekeying = 0;
} else {
- /*
- * Make packets of buffered stdin data, and buffer
- * them for sending to the server.
- */
- if (!compat20)
- client_make_packets_from_stdin_data();
-
/*
* Make packets from buffered channel data, and
* enqueue them for sending to the server.
if (quit_pending)
break;
- if (!compat20) {
- /* Buffer data from stdin */
- client_process_input(readset);
- /*
- * Process output to stdout and stderr. Output to
- * the connection is processed elsewhere (above).
- */
- client_process_output(writeset);
- }
-
/*
* Send as much buffered packet data as possible to the
* sender.
/* Stop watching for window change. */
signal(SIGWINCH, SIG_DFL);
- if (compat20) {
- packet_start(SSH2_MSG_DISCONNECT);
- packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
- packet_put_cstring("disconnected by user");
- packet_put_cstring(""); /* language tag */
- packet_send();
- packet_write_wait();
- }
+ packet_start(SSH2_MSG_DISCONNECT);
+ packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
+ packet_put_cstring("disconnected by user");
+ packet_put_cstring(""); /* language tag */
+ packet_send();
+ packet_write_wait();
channel_free_all();
/*********/
-static int
-client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
-{
- u_int data_len;
- char *data = packet_get_string(&data_len);
- packet_check_eom();
- buffer_append(&stdout_buffer, data, data_len);
- explicit_bzero(data, data_len);
- free(data);
- return 0;
-}
-static int
-client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
-{
- u_int data_len;
- char *data = packet_get_string(&data_len);
- packet_check_eom();
- buffer_append(&stderr_buffer, data, data_len);
- explicit_bzero(data, data_len);
- free(data);
- return 0;
-}
-static int
-client_input_exit_status(int type, u_int32_t seq, void *ctxt)
-{
- exit_status = packet_get_int();
- packet_check_eom();
- /* Acknowledge the exit. */
- packet_start(SSH_CMSG_EXIT_CONFIRMATION);
- packet_send();
- /*
- * Must wait for packet to be sent since we are
- * exiting the loop.
- */
- packet_write_wait();
- /* Flag that we want to exit. */
- quit_pending = 1;
- return 0;
-}
-
-static int
-client_input_agent_open(int type, u_int32_t seq, void *ctxt)
-{
- Channel *c = NULL;
- int r, remote_id, sock;
-
- /* Read the remote channel number from the message. */
- remote_id = packet_get_int();
- packet_check_eom();
-
- /*
- * Get a connection to the local authentication agent (this may again
- * get forwarded).
- */
- if ((r = ssh_get_authentication_socket(&sock)) != 0 &&
- r != SSH_ERR_AGENT_NOT_PRESENT)
- debug("%s: ssh_get_authentication_socket: %s",
- __func__, ssh_err(r));
-
-
- /*
- * If we could not connect the agent, send an error message back to
- * the server. This should never happen unless the agent dies,
- * because authentication forwarding is only enabled if we have an
- * agent.
- */
- if (sock >= 0) {
- c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
- -1, 0, 0, 0, "authentication agent connection", 1);
- c->remote_id = remote_id;
- c->force_drain = 1;
- }
- if (c == NULL) {
- packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
- packet_put_int(remote_id);
- } else {
- /* Send a confirmation to the remote host. */
- debug("Forwarding authentication connection.");
- packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(remote_id);
- packet_put_int(c->self);
- }
- packet_send();
- return 0;
-}
-
static Channel *
client_request_forwarded_tcpip(const char *request_type, int rchan,
u_int rwindow, u_int rmaxpack)
if (tun_mode == SSH_TUNMODE_NO)
return 0;
- if (!compat20) {
- error("Tunnel forwarding is not supported for protocol 1");
- return -1;
- }
-
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
/* Open local tunnel device */
}
static void
-client_init_dispatch_20(void)
+client_init_dispatch(void)
{
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
}
-static void
-client_init_dispatch_13(void)
-{
- dispatch_init(NULL);
- dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
- dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
- dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
- dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
- dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
- dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
- dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
- dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
- dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
-
- dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
- &client_input_agent_open : &deny_input_open);
- dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
- &x11_input_open : &deny_input_open);
-}
-
-static void
-client_init_dispatch_15(void)
-{
- client_init_dispatch_13();
- dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
- dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
-}
-
-static void
-client_init_dispatch(void)
-{
- if (compat20)
- client_init_dispatch_20();
- else if (compat13)
- client_init_dispatch_13();
- else
- client_init_dispatch_15();
-}
-
void
client_stop_mux(void)
{
-/* $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.
*
#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)
-/* $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.
#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
-/* $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.
*
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 ||
-/* $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.
*
/*
* 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 *);
istates[next]);
c->istate = next;
}
+
static void
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)
{
break;
}
}
+
void
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",
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)
{
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:
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)
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)
{
break;
}
}
+
static void
chan_send_close2(Channel *c)
{
c->flags |= CHAN_CLOSE_SENT;
}
}
+
static void
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
}
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 &&
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);
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) {
-/* $OpenBSD: packet.c,v 1.248 2017/04/30 23:10:43 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.249 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
int
ssh_packet_is_rekeying(struct ssh *ssh)
{
- return compat20 &&
- (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0));
+ return ssh->state->rekeying ||
+ (ssh->kex != NULL && ssh->kex->done == 0);
}
/*
{
int r;
- if (ssh->state->packet_compression && !compat20)
+ if (ssh->state->packet_compression)
return SSH_ERR_INTERNAL_ERROR;
ssh->state->packet_compression = 1;
if ((r = ssh_packet_init_compression(ssh)) != 0 ||
fatal("no SSH protocol 1 support");
}
-/*
- * Finalizes and sends the packet. If the encryption key has been set,
- * encrypts the packet before sending.
- */
-
-int
-ssh_packet_send1(struct ssh *ssh)
-{
- struct session_state *state = ssh->state;
- u_char buf[8], *cp;
- int r, padding, len;
- u_int checksum;
-
- /*
- * If using packet compression, compress the payload of the outgoing
- * packet.
- */
- if (state->packet_compression) {
- sshbuf_reset(state->compression_buffer);
- /* Skip padding. */
- if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0)
- goto out;
- /* padding */
- if ((r = sshbuf_put(state->compression_buffer,
- "\0\0\0\0\0\0\0\0", 8)) != 0)
- goto out;
- if ((r = compress_buffer(ssh, state->outgoing_packet,
- state->compression_buffer)) != 0)
- goto out;
- sshbuf_reset(state->outgoing_packet);
- if ((r = sshbuf_putb(state->outgoing_packet,
- state->compression_buffer)) != 0)
- goto out;
- }
- /* Compute packet length without padding (add checksum, remove padding). */
- len = sshbuf_len(state->outgoing_packet) + 4 - 8;
-
- /* Insert padding. Initialized to zero in packet_start1() */
- padding = 8 - len % 8;
- if (!cipher_ctx_is_plaintext(state->send_context)) {
- cp = sshbuf_mutable_ptr(state->outgoing_packet);
- if (cp == NULL) {
- r = SSH_ERR_INTERNAL_ERROR;
- goto out;
- }
- arc4random_buf(cp + 8 - padding, padding);
- }
- if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0)
- goto out;
-
- /* Add check bytes. */
- checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet),
- sshbuf_len(state->outgoing_packet));
- POKE_U32(buf, checksum);
- if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0)
- goto out;
-
-#ifdef PACKET_DEBUG
- fprintf(stderr, "packet_send plain: ");
- sshbuf_dump(state->outgoing_packet, stderr);
-#endif
-
- /* Append to output. */
- POKE_U32(buf, len);
- if ((r = sshbuf_put(state->output, buf, 4)) != 0)
- goto out;
- if ((r = sshbuf_reserve(state->output,
- sshbuf_len(state->outgoing_packet), &cp)) != 0)
- goto out;
- if ((r = cipher_crypt(state->send_context, 0, cp,
- sshbuf_ptr(state->outgoing_packet),
- sshbuf_len(state->outgoing_packet), 0, 0)) != 0)
- goto out;
-
-#ifdef PACKET_DEBUG
- fprintf(stderr, "encrypted: ");
- sshbuf_dump(state->output, stderr);
-#endif
- state->p_send.packets++;
- state->p_send.bytes += len +
- sshbuf_len(state->outgoing_packet);
- sshbuf_reset(state->outgoing_packet);
-
- /*
- * Note that the packet is now only buffered in output. It won't be
- * actually sent until ssh_packet_write_wait or ssh_packet_write_poll
- * is called.
- */
- r = 0;
- out:
- return r;
-}
-
int
ssh_set_newkeys(struct ssh *ssh, int mode)
{
r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
if (r != 0)
break;
- if (!compat20 && (
- *typep == SSH_SMSG_SUCCESS
- || *typep == SSH_SMSG_FAILURE
- || *typep == SSH_CMSG_EOF
- || *typep == SSH_CMSG_EXIT_CONFIRMATION))
- if ((r = sshpkt_get_end(ssh)) != 0)
- break;
/* If we got a packet, return it. */
if (*typep != SSH_MSG_NONE)
break;
for (;;) {
msg = NULL;
- if (compat20) {
- r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
- if (r != 0)
- return r;
- if (*typep) {
- state->keep_alive_timeouts = 0;
- DBG(debug("received packet type %d", *typep));
- }
- switch (*typep) {
- case SSH2_MSG_IGNORE:
- debug3("Received SSH2_MSG_IGNORE");
- break;
- case SSH2_MSG_DEBUG:
- if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
- (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
- free(msg);
- return r;
- }
- debug("Remote: %.900s", msg);
- free(msg);
- break;
- case SSH2_MSG_DISCONNECT:
- if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
- return r;
- /* Ignore normal client exit notifications */
- do_log2(ssh->state->server_side &&
- reason == SSH2_DISCONNECT_BY_APPLICATION ?
- SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
- "Received disconnect from %s port %d:"
- "%u: %.400s", ssh_remote_ipaddr(ssh),
- ssh_remote_port(ssh), reason, msg);
- free(msg);
- return SSH_ERR_DISCONNECTED;
- case SSH2_MSG_UNIMPLEMENTED:
- if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
- return r;
- debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
- seqnr);
- break;
- default:
- return 0;
- }
- } else {
- r = ssh_packet_read_poll1(ssh, typep);
- switch (*typep) {
- case SSH_MSG_NONE:
- return SSH_MSG_NONE;
- case SSH_MSG_IGNORE:
- break;
- case SSH_MSG_DEBUG:
- if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
- return r;
- debug("Remote: %.900s", msg);
- free(msg);
- break;
- case SSH_MSG_DISCONNECT:
- if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
- return r;
- error("Received disconnect from %s port %d: "
- "%.400s", ssh_remote_ipaddr(ssh),
- ssh_remote_port(ssh), msg);
+ r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
+ if (r != 0)
+ return r;
+ if (*typep) {
+ state->keep_alive_timeouts = 0;
+ DBG(debug("received packet type %d", *typep));
+ }
+ switch (*typep) {
+ case SSH2_MSG_IGNORE:
+ debug3("Received SSH2_MSG_IGNORE");
+ break;
+ case SSH2_MSG_DEBUG:
+ if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
+ (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
free(msg);
- return SSH_ERR_DISCONNECTED;
- default:
- DBG(debug("received packet type %d", *typep));
- return 0;
+ return r;
}
+ debug("Remote: %.900s", msg);
+ free(msg);
+ break;
+ case SSH2_MSG_DISCONNECT:
+ if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
+ return r;
+ /* Ignore normal client exit notifications */
+ do_log2(ssh->state->server_side &&
+ reason == SSH2_DISCONNECT_BY_APPLICATION ?
+ SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
+ "Received disconnect from %s port %d:"
+ "%u: %.400s", ssh_remote_ipaddr(ssh),
+ ssh_remote_port(ssh), reason, msg);
+ free(msg);
+ return SSH_ERR_DISCONNECTED;
+ case SSH2_MSG_UNIMPLEMENTED:
+ if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
+ return r;
+ debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
+ seqnr);
+ break;
+ default:
+ return 0;
}
}
}
va_list args;
int r;
- if (compat20 && (ssh->compat & SSH_BUG_DEBUG))
+ if ((ssh->compat & SSH_BUG_DEBUG))
return;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
- if (compat20) {
- if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
- (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
- (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
- (r = sshpkt_put_cstring(ssh, "")) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- } else {
- if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 ||
- (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- fatal("%s: %s", __func__, ssh_err(r));
- }
- if ((r = ssh_packet_write_wait(ssh)) != 0)
+ if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
+ (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
+ (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0 ||
+ (r = ssh_packet_write_wait(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
u_int32_t rnd = 0;
int r, i;
- if ((r = sshpkt_start(ssh, compat20 ?
- SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 ||
+ if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
(r = sshpkt_put_u32(ssh, nbytes)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
for (i = 0; i < nbytes; i++) {
struct session_state *state = ssh->state;
u_char *p;
size_t slen, rlen;
- int r, ssh1cipher;
-
- if (!compat20) {
- ssh1cipher = cipher_ctx_get_number(state->receive_context);
- slen = cipher_get_keyiv_len(state->send_context);
- rlen = cipher_get_keyiv_len(state->receive_context);
- if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 ||
- (r = sshbuf_put_u32(m, ssh1cipher)) != 0 ||
- (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 ||
- (r = sshbuf_put_u32(m, slen)) != 0 ||
- (r = sshbuf_reserve(m, slen, &p)) != 0 ||
- (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 ||
- (r = sshbuf_put_u32(m, rlen)) != 0 ||
- (r = sshbuf_reserve(m, rlen, &p)) != 0 ||
- (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0)
- return r;
- } else {
- if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
- (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
- (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
- (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
- (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
- (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
- (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
- (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
- (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
- (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
- (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
- (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
- (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
- return r;
- }
+ int r;
+
+ if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
+ (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
+ (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
+ (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
+ (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
+ (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
+ (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
+ (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
+ (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
+ (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
+ (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
+ (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
+ (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
+ return r;
slen = cipher_get_keycontext(state->send_context, NULL);
rlen = cipher_get_keycontext(state->receive_context, NULL);
ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
{
struct session_state *state = ssh->state;
- const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output;
- size_t ssh1keylen, rlen, slen, ilen, olen;
+ const u_char *keyin, *keyout, *input, *output;
+ size_t rlen, slen, ilen, olen;
int r;
- u_int ssh1cipher = 0;
-
- if (!compat20) {
- if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 ||
- (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 ||
- (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 ||
- (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 ||
- (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0)
- return r;
- if (ssh1cipher > INT_MAX)
- return SSH_ERR_KEY_UNKNOWN_CIPHER;
- ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen,
- (int)ssh1cipher);
- if (cipher_get_keyiv_len(state->send_context) != (int)slen ||
- cipher_get_keyiv_len(state->receive_context) != (int)rlen)
- return SSH_ERR_INVALID_FORMAT;
- if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 ||
- (r = cipher_set_keyiv(state->receive_context, ivin)) != 0)
- return r;
- } else {
- if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
- (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
- (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
- (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
- (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
- (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
- (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
- (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
- (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
- (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
- (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
- (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
- (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
- return r;
- /*
- * We set the time here so that in post-auth privsep slave we
- * count from the completion of the authentication.
- */
- state->rekey_time = monotime();
- /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
- if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
- (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
- return r;
- }
+
+ if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
+ (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
+ (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
+ (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
+ (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
+ (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
+ (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
+ (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
+ (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
+ (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
+ (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
+ (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
+ (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
+ return r;
+ /*
+ * We set the time here so that in post-auth privsep slave we
+ * count from the completion of the authentication.
+ */
+ state->rekey_time = monotime();
+ /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
+ if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
+ (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
+ return r;
+
if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||
(r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
return r;
int
sshpkt_start(struct ssh *ssh, u_char type)
{
- u_char buf[9];
- int len;
+ u_char buf[6]; /* u32 packet length, u8 pad len, u8 type */
DBG(debug("packet_start[%d]", type));
- len = compat20 ? 6 : 9;
- memset(buf, 0, len - 1);
- buf[len - 1] = type;
+ memset(buf, 0, sizeof(buf));
+ buf[sizeof(buf) - 1] = type;
sshbuf_reset(ssh->state->outgoing_packet);
- return sshbuf_put(ssh->state->outgoing_packet, buf, len);
+ return sshbuf_put(ssh->state->outgoing_packet, buf, sizeof(buf));
}
static int
{
if (ssh->state && ssh->state->mux)
return ssh_packet_send_mux(ssh);
- if (compat20)
- return ssh_packet_send2(ssh);
- else
- return ssh_packet_send1(ssh);
+ return ssh_packet_send2(ssh);
}
int
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
- if (compat20) {
- if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
- (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
- (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
- (r = sshpkt_put_cstring(ssh, "")) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- return r;
- } else {
- if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 ||
- (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
- (r = sshpkt_send(ssh)) != 0)
- return r;
- }
+ if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
+ (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ return r;
return 0;
}
-/* $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>
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 *);
-/* $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>.
*
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 ?
-/* $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
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);
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;
}
}
skip_connect:
- exit_status = compat20 ? ssh_session2() : ssh_session();
+ exit_status = ssh_session2();
packet_close();
if (options.control_path != NULL && muxserver_sock != -1)
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);
}
}
-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)
{
-/* $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.
*
}
if (remote_major != 2)
return SSH_ERR_PROTOCOL_MISMATCH;
- enable_compat20();
chop(buf);
debug("Remote version string %.100s", buf);
if ((*bannerp = strdup(buf)) == NULL)
-/* $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
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));
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;
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;
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)) {
/* 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);
}
-/* $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
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);
-/* $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
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) {
/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
buffer_put_char(&buf, OP); \
- put_arg(&buf, tio.c_cc[NAME]);
+ buffer_put_int(&buf, 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"
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);
}
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
#define TTYCHAR(NAME, OP) \
case OP: \
- n_bytes += arg_size; \
- tio.c_cc[NAME] = get_arg(); \
+ n_bytes += 4; \
+ tio.c_cc[NAME] = 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; \
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;
}
}
}