diff options
-rw-r--r-- | channels.c | 40 | ||||
-rw-r--r-- | channels.h | 9 | ||||
-rw-r--r-- | clientloop.c | 6 | ||||
-rw-r--r-- | mux.c | 18 | ||||
-rw-r--r-- | nchan.c | 10 | ||||
-rw-r--r-- | serverloop.c | 6 |
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 | ||
254 | Channel * | 254 | Channel * |
255 | channel_by_remote_id(struct ssh *ssh, int remote_id) | 255 | channel_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 *); | |||
97 | struct Channel { | 97 | struct 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 | ||
224 | Channel *channel_by_id(struct ssh *, int); | 225 | Channel *channel_by_id(struct ssh *, int); |
225 | Channel *channel_by_remote_id(struct ssh *, int); | 226 | Channel *channel_by_remote_id(struct ssh *, u_int); |
226 | Channel *channel_lookup(struct ssh *, int); | 227 | Channel *channel_lookup(struct ssh *, int); |
227 | Channel *channel_new(struct ssh *, char *, int, int, int, int, | 228 | Channel *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); |
@@ -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); |
@@ -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); |