summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-09-12 06:35:31 +0000
committerDamien Miller <djm@mindrot.org>2017-09-12 17:37:03 +1000
commit9f53229c2ac97dbc6f5a03657de08a1150a9ac7e (patch)
tree4f74dc06676dc6dce2b2bc3aa6beb248a1d8def6
parentdbee4119b502e3f8b6cd3282c69c537fd01d8e16 (diff)
upstream commit
Make remote channel ID a u_int Previously we tracked the remote channel IDs in an int, but this is strictly incorrect: the wire protocol uses uint32 and there is nothing in-principle stopping a SSH implementation from sending, say, 0xffff0000. In practice everyone numbers their channels sequentially, so this has never been a problem. ok markus@ Upstream-ID: b9f4cd3dc53155b4a5c995c0adba7da760d03e73
-rw-r--r--channels.c40
-rw-r--r--channels.h9
-rw-r--r--clientloop.c6
-rw-r--r--mux.c18
-rw-r--r--nchan.c10
-rw-r--r--serverloop.c6
6 files changed, 65 insertions, 24 deletions
diff --git a/channels.c b/channels.c
index 935625c74..3ab4823a9 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.366 2017/08/30 03:59:08 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.368 2017/09/12 06:35:31 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -252,14 +252,14 @@ channel_by_id(struct ssh *ssh, int id)
252} 252}
253 253
254Channel * 254Channel *
255channel_by_remote_id(struct ssh *ssh, int remote_id) 255channel_by_remote_id(struct ssh *ssh, u_int remote_id)
256{ 256{
257 Channel *c; 257 Channel *c;
258 u_int i; 258 u_int i;
259 259
260 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { 260 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
261 c = ssh->chanctxt->channels[i]; 261 c = ssh->chanctxt->channels[i];
262 if (c != NULL && c->remote_id == remote_id) 262 if (c != NULL && c->have_remote_id && c->remote_id == remote_id)
263 return c; 263 return c;
264 } 264 }
265 return NULL; 265 return NULL;
@@ -387,7 +387,6 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
387 c->local_window = window; 387 c->local_window = window;
388 c->local_window_max = window; 388 c->local_window_max = window;
389 c->local_maxpacket = maxpack; 389 c->local_maxpacket = maxpack;
390 c->remote_id = -1;
391 c->remote_name = xstrdup(remote_name); 390 c->remote_name = xstrdup(remote_name);
392 c->ctl_chan = -1; 391 c->ctl_chan = -1;
393 c->delayed = 1; /* prevent call to channel_post handler */ 392 c->delayed = 1; /* prevent call to channel_post handler */
@@ -703,7 +702,7 @@ channel_find_open(struct ssh *ssh)
703 702
704 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { 703 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
705 c = ssh->chanctxt->channels[i]; 704 c = ssh->chanctxt->channels[i];
706 if (c == NULL || c->remote_id < 0) 705 if (c == NULL || !c->have_remote_id)
707 continue; 706 continue;
708 switch (c->type) { 707 switch (c->type) {
709 case SSH_CHANNEL_CLOSED: 708 case SSH_CHANNEL_CLOSED:
@@ -778,9 +777,10 @@ channel_open_message(struct ssh *ssh)
778 case SSH_CHANNEL_MUX_PROXY: 777 case SSH_CHANNEL_MUX_PROXY:
779 case SSH_CHANNEL_MUX_CLIENT: 778 case SSH_CHANNEL_MUX_CLIENT:
780 if ((r = sshbuf_putf(buf, " #%d %.300s " 779 if ((r = sshbuf_putf(buf, " #%d %.300s "
781 "(t%d r%d i%u/%zu o%u/%zu fd %d/%d cc %d)\r\n", 780 "(t%d %s%u i%u/%zu o%u/%zu fd %d/%d cc %d)\r\n",
782 c->self, c->remote_name, 781 c->self, c->remote_name,
783 c->type, c->remote_id, 782 c->type,
783 c->have_remote_id ? "r" : "nr", c->remote_id,
784 c->istate, sshbuf_len(c->input), 784 c->istate, sshbuf_len(c->input),
785 c->ostate, sshbuf_len(c->output), 785 c->ostate, sshbuf_len(c->output),
786 c->rfd, c->wfd, c->ctl_chan)) != 0) 786 c->rfd, c->wfd, c->ctl_chan)) != 0)
@@ -838,6 +838,9 @@ channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm)
838 logit("%s: %d: unknown channel id", __func__, id); 838 logit("%s: %d: unknown channel id", __func__, id);
839 return; 839 return;
840 } 840 }
841 if (!c->have_remote_id)
842 fatal(":%s: channel %d: no remote id", __func__, c->self);
843
841 debug2("channel %d: request %s confirm %d", id, service, wantconfirm); 844 debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
842 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 || 845 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
843 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 846 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
@@ -930,6 +933,9 @@ channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
930 933
931 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) 934 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
932 fatal("channel_activate for non-larval channel %d.", id); 935 fatal("channel_activate for non-larval channel %d.", id);
936 if (!c->have_remote_id)
937 fatal(":%s: channel %d: no remote id", __func__, c->self);
938
933 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty); 939 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
934 c->type = SSH_CHANNEL_OPEN; 940 c->type = SSH_CHANNEL_OPEN;
935 c->local_window = c->local_window_max = window_max; 941 c->local_window = c->local_window_max = window_max;
@@ -1698,6 +1704,8 @@ channel_post_connecting(struct ssh *ssh, Channel *c,
1698 1704
1699 if (!FD_ISSET(c->sock, writeset)) 1705 if (!FD_ISSET(c->sock, writeset))
1700 return; 1706 return;
1707 if (!c->have_remote_id)
1708 fatal(":%s: channel %d: no remote id", __func__, c->self);
1701 1709
1702 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) { 1710 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
1703 err = errno; 1711 err = errno;
@@ -1983,6 +1991,9 @@ channel_check_window(struct ssh *ssh, Channel *c)
1983 c->local_maxpacket*3) || 1991 c->local_maxpacket*3) ||
1984 c->local_window < c->local_window_max/2) && 1992 c->local_window < c->local_window_max/2) &&
1985 c->local_consumed > 0) { 1993 c->local_consumed > 0) {
1994 if (!c->have_remote_id)
1995 fatal(":%s: channel %d: no remote id",
1996 __func__, c->self);
1986 if ((r = sshpkt_start(ssh, 1997 if ((r = sshpkt_start(ssh,
1987 SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 || 1998 SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
1988 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 1999 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
@@ -2338,6 +2349,9 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
2338 return; 2349 return;
2339 } 2350 }
2340 2351
2352 if (!c->have_remote_id)
2353 fatal(":%s: channel %d: no remote id", __func__, c->self);
2354
2341 if (c->datagram) { 2355 if (c->datagram) {
2342 /* Check datagram will fit; drop if not */ 2356 /* Check datagram will fit; drop if not */
2343 if ((r = sshbuf_peek_string_direct(c->input, NULL, &dlen)) != 0) 2357 if ((r = sshbuf_peek_string_direct(c->input, NULL, &dlen)) != 0)
@@ -2404,6 +2418,8 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
2404 len = c->remote_maxpacket; 2418 len = c->remote_maxpacket;
2405 if (len == 0) 2419 if (len == 0)
2406 return; 2420 return;
2421 if (!c->have_remote_id)
2422 fatal(":%s: channel %d: no remote id", __func__, c->self);
2407 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 || 2423 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
2408 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 2424 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2409 (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 || 2425 (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
@@ -2570,6 +2586,7 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
2570 c->mux_ctx = downstream; /* point to mux client */ 2586 c->mux_ctx = downstream; /* point to mux client */
2571 c->mux_downstream_id = id; 2587 c->mux_downstream_id = id;
2572 c->remote_id = remote_id; 2588 c->remote_id = remote_id;
2589 c->have_remote_id = 1;
2573 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 || 2590 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
2574 (r = sshbuf_put_u32(modified, c->self)) != 0 || 2591 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
2575 (r = sshbuf_putb(modified, original)) != 0) { 2592 (r = sshbuf_putb(modified, original)) != 0) {
@@ -2713,8 +2730,10 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
2713 switch (type) { 2730 switch (type) {
2714 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: 2731 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
2715 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */ 2732 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */
2716 if (cp && len > 4) 2733 if (cp && len > 4) {
2717 c->remote_id = PEEK_U32(cp); 2734 c->remote_id = PEEK_U32(cp);
2735 c->have_remote_id = 1;
2736 }
2718 break; 2737 break;
2719 case SSH2_MSG_CHANNEL_CLOSE: 2738 case SSH2_MSG_CHANNEL_CLOSE:
2720 if (c->flags & CHAN_CLOSE_SENT) 2739 if (c->flags & CHAN_CLOSE_SENT)
@@ -2923,14 +2942,15 @@ channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
2923 * Record the remote channel number and mark that the channel 2942 * Record the remote channel number and mark that the channel
2924 * is now open. 2943 * is now open.
2925 */ 2944 */
2926 c->remote_id = channel_parse_id(ssh, __func__, "open confirmation"); 2945 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
2927 if ((r = sshpkt_get_u32(ssh, &remote_window)) != 0 || 2946 (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
2928 (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0) { 2947 (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0) {
2929 error("%s: window/maxpacket: %s", __func__, ssh_err(r)); 2948 error("%s: window/maxpacket: %s", __func__, ssh_err(r));
2930 packet_disconnect("Invalid open confirmation message"); 2949 packet_disconnect("Invalid open confirmation message");
2931 } 2950 }
2932 ssh_packet_check_eom(ssh); 2951 ssh_packet_check_eom(ssh);
2933 2952
2953 c->have_remote_id = 1;
2934 c->remote_window = remote_window; 2954 c->remote_window = remote_window;
2935 c->remote_maxpacket = remote_maxpacket; 2955 c->remote_maxpacket = remote_maxpacket;
2936 c->type = SSH_CHANNEL_OPEN; 2956 c->type = SSH_CHANNEL_OPEN;
diff --git a/channels.h b/channels.h
index f04c43afa..d1cf5dc6a 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.128 2017/09/12 06:32:07 djm Exp $ */ 1/* $OpenBSD: channels.h,v 1.129 2017/09/12 06:35:32 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -97,8 +97,9 @@ typedef int mux_callback_fn(struct ssh *, struct Channel *);
97struct Channel { 97struct Channel {
98 int type; /* channel type/state */ 98 int type; /* channel type/state */
99 int self; /* my own channel identifier */ 99 int self; /* my own channel identifier */
100 int remote_id; /* channel identifier for remote peer */ 100 uint32_t remote_id; /* channel identifier for remote peer */
101 /* XXX should be uint32_t */ 101 int have_remote_id; /* non-zero if remote_id is valid */
102
102 u_int istate; /* input from channel (state of receive half) */ 103 u_int istate; /* input from channel (state of receive half) */
103 u_int ostate; /* output to channel (state of transmit half) */ 104 u_int ostate; /* output to channel (state of transmit half) */
104 int flags; /* close sent/rcvd */ 105 int flags; /* close sent/rcvd */
@@ -222,7 +223,7 @@ void channel_init_channels(struct ssh *ssh);
222/* channel management */ 223/* channel management */
223 224
224Channel *channel_by_id(struct ssh *, int); 225Channel *channel_by_id(struct ssh *, int);
225Channel *channel_by_remote_id(struct ssh *, int); 226Channel *channel_by_remote_id(struct ssh *, u_int);
226Channel *channel_lookup(struct ssh *, int); 227Channel *channel_lookup(struct ssh *, int);
227Channel *channel_new(struct ssh *, char *, int, int, int, int, 228Channel *channel_new(struct ssh *, char *, int, int, int, int,
228 u_int, u_int, int, char *, int); 229 u_int, u_int, int, char *, int);
diff --git a/clientloop.c b/clientloop.c
index 1218b3b71..829eae024 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.303 2017/09/12 06:32:07 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.304 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1682,6 +1682,7 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1682 } else if (c != NULL) { 1682 } else if (c != NULL) {
1683 debug("confirm %s", ctype); 1683 debug("confirm %s", ctype);
1684 c->remote_id = rchan; 1684 c->remote_id = rchan;
1685 c->have_remote_id = 1;
1685 c->remote_window = rwindow; 1686 c->remote_window = rwindow;
1686 c->remote_maxpacket = rmaxpack; 1687 c->remote_maxpacket = rmaxpack;
1687 if (c->type != SSH_CHANNEL_CONNECTING) { 1688 if (c->type != SSH_CHANNEL_CONNECTING) {
@@ -1749,6 +1750,9 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1749 packet_check_eom(); 1750 packet_check_eom();
1750 } 1751 }
1751 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { 1752 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
1753 if (!c->have_remote_id)
1754 fatal("%s: channel %d: no remote_id",
1755 __func__, c->self);
1752 packet_start(success ? 1756 packet_start(success ?
1753 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1757 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1754 packet_put_int(c->remote_id); 1758 packet_put_int(c->remote_id);
diff --git a/mux.c b/mux.c
index 9eee287b9..f8510426d 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.66 2017/09/12 06:32:07 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -215,7 +215,8 @@ mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
215 fatal("%s: channel %d missing control channel %d", 215 fatal("%s: channel %d missing control channel %d",
216 __func__, c->self, c->ctl_chan); 216 __func__, c->self, c->ctl_chan);
217 c->ctl_chan = -1; 217 c->ctl_chan = -1;
218 cc->remote_id = -1; 218 cc->remote_id = 0;
219 cc->have_remote_id = 0;
219 chan_rcvd_oclose(ssh, cc); 220 chan_rcvd_oclose(ssh, cc);
220 } 221 }
221 channel_cancel_cleanup(ssh, c->self); 222 channel_cancel_cleanup(ssh, c->self);
@@ -231,11 +232,12 @@ mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
231 debug3("%s: entering for channel %d", __func__, cid); 232 debug3("%s: entering for channel %d", __func__, cid);
232 if (c == NULL) 233 if (c == NULL)
233 fatal("%s: channel_by_id(%i) == NULL", __func__, cid); 234 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
234 if (c->remote_id != -1) { 235 if (c->have_remote_id) {
235 if ((sc = channel_by_id(ssh, c->remote_id)) == NULL) 236 if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
236 fatal("%s: channel %d missing session channel %d", 237 fatal("%s: channel %d missing session channel %u",
237 __func__, c->self, c->remote_id); 238 __func__, c->self, c->remote_id);
238 c->remote_id = -1; 239 c->remote_id = 0;
240 c->have_remote_id = 0;
239 sc->ctl_chan = -1; 241 sc->ctl_chan = -1;
240 if (sc->type != SSH_CHANNEL_OPEN && 242 if (sc->type != SSH_CHANNEL_OPEN &&
241 sc->type != SSH_CHANNEL_OPENING) { 243 sc->type != SSH_CHANNEL_OPENING) {
@@ -413,7 +415,7 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
413 new_fd[0], new_fd[1], new_fd[2]); 415 new_fd[0], new_fd[1], new_fd[2]);
414 416
415 /* XXX support multiple child sessions in future */ 417 /* XXX support multiple child sessions in future */
416 if (c->remote_id != -1) { 418 if (c->have_remote_id) {
417 debug2("%s: session already open", __func__); 419 debug2("%s: session already open", __func__);
418 /* prepare reply */ 420 /* prepare reply */
419 buffer_put_int(r, MUX_S_FAILURE); 421 buffer_put_int(r, MUX_S_FAILURE);
@@ -471,6 +473,7 @@ process_mux_new_session(struct ssh *ssh, u_int rid,
471 473
472 nc->ctl_chan = c->self; /* link session -> control channel */ 474 nc->ctl_chan = c->self; /* link session -> control channel */
473 c->remote_id = nc->self; /* link control -> session channel */ 475 c->remote_id = nc->self; /* link control -> session channel */
476 c->have_remote_id = 1;
474 477
475 if (cctx->want_tty && escape_char != 0xffffffff) { 478 if (cctx->want_tty && escape_char != 0xffffffff) {
476 channel_register_filter(ssh, nc->self, 479 channel_register_filter(ssh, nc->self,
@@ -1007,7 +1010,7 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
1007 new_fd[0], new_fd[1]); 1010 new_fd[0], new_fd[1]);
1008 1011
1009 /* XXX support multiple child sessions in future */ 1012 /* XXX support multiple child sessions in future */
1010 if (c->remote_id != -1) { 1013 if (c->have_remote_id) {
1011 debug2("%s: session already open", __func__); 1014 debug2("%s: session already open", __func__);
1012 /* prepare reply */ 1015 /* prepare reply */
1013 buffer_put_int(r, MUX_S_FAILURE); 1016 buffer_put_int(r, MUX_S_FAILURE);
@@ -1043,6 +1046,7 @@ process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
1043 1046
1044 nc->ctl_chan = c->self; /* link session -> control channel */ 1047 nc->ctl_chan = c->self; /* link session -> control channel */
1045 c->remote_id = nc->self; /* link control -> session channel */ 1048 c->remote_id = nc->self; /* link control -> session channel */
1049 c->have_remote_id = 1;
1046 1050
1047 debug2("%s: channel_new: %d linked to control channel %d", 1051 debug2("%s: channel_new: %d linked to control channel %d",
1048 __func__, nc->self, nc->ctl_chan); 1052 __func__, nc->self, nc->ctl_chan);
diff --git a/nchan.c b/nchan.c
index 74c855c90..24929556d 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.66 2017/09/12 06:32:07 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -183,6 +183,9 @@ chan_send_eof2(struct ssh *ssh, Channel *c)
183 debug2("channel %d: send eof", c->self); 183 debug2("channel %d: send eof", c->self);
184 switch (c->istate) { 184 switch (c->istate) {
185 case CHAN_INPUT_WAIT_DRAIN: 185 case CHAN_INPUT_WAIT_DRAIN:
186 if (!c->have_remote_id)
187 fatal("%s: channel %d: no remote_id",
188 __func__, c->self);
186 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 || 189 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
187 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 190 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
188 (r = sshpkt_send(ssh)) != 0) 191 (r = sshpkt_send(ssh)) != 0)
@@ -209,6 +212,9 @@ chan_send_close2(struct ssh *ssh, Channel *c)
209 } else if (c->flags & CHAN_CLOSE_SENT) { 212 } else if (c->flags & CHAN_CLOSE_SENT) {
210 error("channel %d: already sent close", c->self); 213 error("channel %d: already sent close", c->self);
211 } else { 214 } else {
215 if (!c->have_remote_id)
216 fatal("%s: channel %d: no remote_id",
217 __func__, c->self);
212 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 || 218 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
213 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 219 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
214 (r = sshpkt_send(ssh)) != 0) 220 (r = sshpkt_send(ssh)) != 0)
@@ -230,6 +236,8 @@ chan_send_eow2(struct ssh *ssh, Channel *c)
230 } 236 }
231 if (!(datafellows & SSH_NEW_OPENSSH)) 237 if (!(datafellows & SSH_NEW_OPENSSH))
232 return; 238 return;
239 if (!c->have_remote_id)
240 fatal("%s: channel %d: no remote_id", __func__, c->self);
233 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 || 241 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
234 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || 242 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
235 (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 || 243 (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
diff --git a/serverloop.c b/serverloop.c
index 567159410..ae75fc2ec 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.197 2017/09/12 06:32:07 djm Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -619,6 +619,7 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
619 if (c != NULL) { 619 if (c != NULL) {
620 debug("server_input_channel_open: confirm %s", ctype); 620 debug("server_input_channel_open: confirm %s", ctype);
621 c->remote_id = rchan; 621 c->remote_id = rchan;
622 c->have_remote_id = 1;
622 c->remote_window = rwindow; 623 c->remote_window = rwindow;
623 c->remote_maxpacket = rmaxpack; 624 c->remote_maxpacket = rmaxpack;
624 if (c->type != SSH_CHANNEL_CONNECTING) { 625 if (c->type != SSH_CHANNEL_CONNECTING) {
@@ -844,6 +845,9 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
844 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 845 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
845 success = session_input_channel_req(ssh, c, rtype); 846 success = session_input_channel_req(ssh, c, rtype);
846 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 847 if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
848 if (!c->have_remote_id)
849 fatal("%s: channel %d: no remote_id",
850 __func__, c->self);
847 packet_start(success ? 851 packet_start(success ?
848 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 852 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
849 packet_put_int(c->remote_id); 853 packet_put_int(c->remote_id);