diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-09-12 06:32:07 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-09-12 17:37:02 +1000 |
commit | dbee4119b502e3f8b6cd3282c69c537fd01d8e16 (patch) | |
tree | b8a3263a79e0920e8d08f188654f1ccb7c254406 /mux.c | |
parent | abd59663df37a42152e37980113ccaa405b9a282 (diff) |
upstream commit
refactor channels.c
Move static state to a "struct ssh_channels" that is allocated at
runtime and tracked as a member of struct ssh.
Explicitly pass "struct ssh" to all channels functions.
Replace use of the legacy packet APIs in channels.c.
Rework sshd_config PermitOpen handling: previously the configuration
parser would call directly into the channels layer. After the refactor
this is not possible, as the channels structures are allocated at
connection time and aren't available when the configuration is parsed.
The server config parser now tracks PermitOpen itself and explicitly
configures the channels code later.
ok markus@
Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 193 |
1 files changed, 109 insertions, 84 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.65 2017/06/09 06:47:13 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.66 2017/09/12 06:32:07 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 | * |
@@ -161,22 +161,32 @@ struct mux_master_state { | |||
161 | #define MUX_FWD_REMOTE 2 | 161 | #define MUX_FWD_REMOTE 2 |
162 | #define MUX_FWD_DYNAMIC 3 | 162 | #define MUX_FWD_DYNAMIC 3 |
163 | 163 | ||
164 | static void mux_session_confirm(int, int, void *); | 164 | static void mux_session_confirm(struct ssh *, int, int, void *); |
165 | static void mux_stdio_confirm(int, int, void *); | 165 | static void mux_stdio_confirm(struct ssh *, int, int, void *); |
166 | 166 | ||
167 | static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); | 167 | static int process_mux_master_hello(struct ssh *, u_int, |
168 | static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); | 168 | Channel *, struct sshbuf *, struct sshbuf *); |
169 | static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); | 169 | static int process_mux_new_session(struct ssh *, u_int, |
170 | static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); | 170 | Channel *, struct sshbuf *, struct sshbuf *); |
171 | static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); | 171 | static int process_mux_alive_check(struct ssh *, u_int, |
172 | static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); | 172 | Channel *, struct sshbuf *, struct sshbuf *); |
173 | static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); | 173 | static int process_mux_terminate(struct ssh *, u_int, |
174 | static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); | 174 | Channel *, struct sshbuf *, struct sshbuf *); |
175 | static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); | 175 | static int process_mux_open_fwd(struct ssh *, u_int, |
176 | Channel *, struct sshbuf *, struct sshbuf *); | ||
177 | static int process_mux_close_fwd(struct ssh *, u_int, | ||
178 | Channel *, struct sshbuf *, struct sshbuf *); | ||
179 | static int process_mux_stdio_fwd(struct ssh *, u_int, | ||
180 | Channel *, struct sshbuf *, struct sshbuf *); | ||
181 | static int process_mux_stop_listening(struct ssh *, u_int, | ||
182 | Channel *, struct sshbuf *, struct sshbuf *); | ||
183 | static int process_mux_proxy(struct ssh *, u_int, | ||
184 | Channel *, struct sshbuf *, struct sshbuf *); | ||
176 | 185 | ||
177 | static const struct { | 186 | static const struct { |
178 | u_int type; | 187 | u_int type; |
179 | int (*handler)(u_int, Channel *, Buffer *, Buffer *); | 188 | int (*handler)(struct ssh *, u_int, Channel *, |
189 | struct sshbuf *, struct sshbuf *); | ||
180 | } mux_master_handlers[] = { | 190 | } mux_master_handlers[] = { |
181 | { MUX_MSG_HELLO, process_mux_master_hello }, | 191 | { MUX_MSG_HELLO, process_mux_master_hello }, |
182 | { MUX_C_NEW_SESSION, process_mux_new_session }, | 192 | { MUX_C_NEW_SESSION, process_mux_new_session }, |
@@ -193,36 +203,36 @@ static const struct { | |||
193 | /* Cleanup callback fired on closure of mux slave _session_ channel */ | 203 | /* Cleanup callback fired on closure of mux slave _session_ channel */ |
194 | /* ARGSUSED */ | 204 | /* ARGSUSED */ |
195 | static void | 205 | static void |
196 | mux_master_session_cleanup_cb(int cid, void *unused) | 206 | mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused) |
197 | { | 207 | { |
198 | Channel *cc, *c = channel_by_id(cid); | 208 | Channel *cc, *c = channel_by_id(ssh, cid); |
199 | 209 | ||
200 | debug3("%s: entering for channel %d", __func__, cid); | 210 | debug3("%s: entering for channel %d", __func__, cid); |
201 | if (c == NULL) | 211 | if (c == NULL) |
202 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); | 212 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); |
203 | if (c->ctl_chan != -1) { | 213 | if (c->ctl_chan != -1) { |
204 | if ((cc = channel_by_id(c->ctl_chan)) == NULL) | 214 | if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) |
205 | fatal("%s: channel %d missing control channel %d", | 215 | fatal("%s: channel %d missing control channel %d", |
206 | __func__, c->self, c->ctl_chan); | 216 | __func__, c->self, c->ctl_chan); |
207 | c->ctl_chan = -1; | 217 | c->ctl_chan = -1; |
208 | cc->remote_id = -1; | 218 | cc->remote_id = -1; |
209 | chan_rcvd_oclose(cc); | 219 | chan_rcvd_oclose(ssh, cc); |
210 | } | 220 | } |
211 | channel_cancel_cleanup(c->self); | 221 | channel_cancel_cleanup(ssh, c->self); |
212 | } | 222 | } |
213 | 223 | ||
214 | /* Cleanup callback fired on closure of mux slave _control_ channel */ | 224 | /* Cleanup callback fired on closure of mux slave _control_ channel */ |
215 | /* ARGSUSED */ | 225 | /* ARGSUSED */ |
216 | static void | 226 | static void |
217 | mux_master_control_cleanup_cb(int cid, void *unused) | 227 | mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused) |
218 | { | 228 | { |
219 | Channel *sc, *c = channel_by_id(cid); | 229 | Channel *sc, *c = channel_by_id(ssh, cid); |
220 | 230 | ||
221 | debug3("%s: entering for channel %d", __func__, cid); | 231 | debug3("%s: entering for channel %d", __func__, cid); |
222 | if (c == NULL) | 232 | if (c == NULL) |
223 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); | 233 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); |
224 | if (c->remote_id != -1) { | 234 | if (c->remote_id != -1) { |
225 | if ((sc = channel_by_id(c->remote_id)) == NULL) | 235 | if ((sc = channel_by_id(ssh, c->remote_id)) == NULL) |
226 | fatal("%s: channel %d missing session channel %d", | 236 | fatal("%s: channel %d missing session channel %d", |
227 | __func__, c->self, c->remote_id); | 237 | __func__, c->self, c->remote_id); |
228 | c->remote_id = -1; | 238 | c->remote_id = -1; |
@@ -230,15 +240,15 @@ mux_master_control_cleanup_cb(int cid, void *unused) | |||
230 | if (sc->type != SSH_CHANNEL_OPEN && | 240 | if (sc->type != SSH_CHANNEL_OPEN && |
231 | sc->type != SSH_CHANNEL_OPENING) { | 241 | sc->type != SSH_CHANNEL_OPENING) { |
232 | debug2("%s: channel %d: not open", __func__, sc->self); | 242 | debug2("%s: channel %d: not open", __func__, sc->self); |
233 | chan_mark_dead(sc); | 243 | chan_mark_dead(ssh, sc); |
234 | } else { | 244 | } else { |
235 | if (sc->istate == CHAN_INPUT_OPEN) | 245 | if (sc->istate == CHAN_INPUT_OPEN) |
236 | chan_read_failed(sc); | 246 | chan_read_failed(ssh, sc); |
237 | if (sc->ostate == CHAN_OUTPUT_OPEN) | 247 | if (sc->ostate == CHAN_OUTPUT_OPEN) |
238 | chan_write_failed(sc); | 248 | chan_write_failed(ssh, sc); |
239 | } | 249 | } |
240 | } | 250 | } |
241 | channel_cancel_cleanup(c->self); | 251 | channel_cancel_cleanup(ssh, c->self); |
242 | } | 252 | } |
243 | 253 | ||
244 | /* Check mux client environment variables before passing them to mux master. */ | 254 | /* Check mux client environment variables before passing them to mux master. */ |
@@ -266,7 +276,8 @@ env_permitted(char *env) | |||
266 | /* Mux master protocol message handlers */ | 276 | /* Mux master protocol message handlers */ |
267 | 277 | ||
268 | static int | 278 | static int |
269 | process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) | 279 | process_mux_master_hello(struct ssh *ssh, u_int rid, |
280 | Channel *c, Buffer *m, Buffer *r) | ||
270 | { | 281 | { |
271 | u_int ver; | 282 | u_int ver; |
272 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; | 283 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; |
@@ -308,7 +319,8 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
308 | } | 319 | } |
309 | 320 | ||
310 | static int | 321 | static int |
311 | process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | 322 | process_mux_new_session(struct ssh *ssh, u_int rid, |
323 | Channel *c, Buffer *m, Buffer *r) | ||
312 | { | 324 | { |
313 | Channel *nc; | 325 | Channel *nc; |
314 | struct mux_session_confirm_ctx *cctx; | 326 | struct mux_session_confirm_ctx *cctx; |
@@ -453,7 +465,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
453 | packetmax >>= 1; | 465 | packetmax >>= 1; |
454 | } | 466 | } |
455 | 467 | ||
456 | nc = channel_new("session", SSH_CHANNEL_OPENING, | 468 | nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, |
457 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, | 469 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, |
458 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); | 470 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
459 | 471 | ||
@@ -461,7 +473,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
461 | c->remote_id = nc->self; /* link control -> session channel */ | 473 | c->remote_id = nc->self; /* link control -> session channel */ |
462 | 474 | ||
463 | if (cctx->want_tty && escape_char != 0xffffffff) { | 475 | if (cctx->want_tty && escape_char != 0xffffffff) { |
464 | channel_register_filter(nc->self, | 476 | channel_register_filter(ssh, nc->self, |
465 | client_simple_escape_filter, NULL, | 477 | client_simple_escape_filter, NULL, |
466 | client_filter_cleanup, | 478 | client_filter_cleanup, |
467 | client_new_escape_filter_ctx((int)escape_char)); | 479 | client_new_escape_filter_ctx((int)escape_char)); |
@@ -470,17 +482,19 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
470 | debug2("%s: channel_new: %d linked to control channel %d", | 482 | debug2("%s: channel_new: %d linked to control channel %d", |
471 | __func__, nc->self, nc->ctl_chan); | 483 | __func__, nc->self, nc->ctl_chan); |
472 | 484 | ||
473 | channel_send_open(nc->self); | 485 | channel_send_open(ssh, nc->self); |
474 | channel_register_open_confirm(nc->self, mux_session_confirm, cctx); | 486 | channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx); |
475 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ | 487 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ |
476 | channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); | 488 | channel_register_cleanup(ssh, nc->self, |
489 | mux_master_session_cleanup_cb, 1); | ||
477 | 490 | ||
478 | /* reply is deferred, sent by mux_session_confirm */ | 491 | /* reply is deferred, sent by mux_session_confirm */ |
479 | return 0; | 492 | return 0; |
480 | } | 493 | } |
481 | 494 | ||
482 | static int | 495 | static int |
483 | process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) | 496 | process_mux_alive_check(struct ssh *ssh, u_int rid, |
497 | Channel *c, Buffer *m, Buffer *r) | ||
484 | { | 498 | { |
485 | debug2("%s: channel %d: alive check", __func__, c->self); | 499 | debug2("%s: channel %d: alive check", __func__, c->self); |
486 | 500 | ||
@@ -493,7 +507,8 @@ process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
493 | } | 507 | } |
494 | 508 | ||
495 | static int | 509 | static int |
496 | process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) | 510 | process_mux_terminate(struct ssh *ssh, u_int rid, |
511 | Channel *c, Buffer *m, Buffer *r) | ||
497 | { | 512 | { |
498 | debug2("%s: channel %d: terminate request", __func__, c->self); | 513 | debug2("%s: channel %d: terminate request", __func__, c->self); |
499 | 514 | ||
@@ -582,7 +597,7 @@ compare_forward(struct Forward *a, struct Forward *b) | |||
582 | } | 597 | } |
583 | 598 | ||
584 | static void | 599 | static void |
585 | mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 600 | mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
586 | { | 601 | { |
587 | struct mux_channel_confirm_ctx *fctx = ctxt; | 602 | struct mux_channel_confirm_ctx *fctx = ctxt; |
588 | char *failmsg = NULL; | 603 | char *failmsg = NULL; |
@@ -590,7 +605,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
590 | Channel *c; | 605 | Channel *c; |
591 | Buffer out; | 606 | Buffer out; |
592 | 607 | ||
593 | if ((c = channel_by_id(fctx->cid)) == NULL) { | 608 | if ((c = channel_by_id(ssh, fctx->cid)) == NULL) { |
594 | /* no channel for reply */ | 609 | /* no channel for reply */ |
595 | error("%s: unknown channel", __func__); | 610 | error("%s: unknown channel", __func__); |
596 | return; | 611 | return; |
@@ -616,7 +631,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
616 | buffer_put_int(&out, MUX_S_REMOTE_PORT); | 631 | buffer_put_int(&out, MUX_S_REMOTE_PORT); |
617 | buffer_put_int(&out, fctx->rid); | 632 | buffer_put_int(&out, fctx->rid); |
618 | buffer_put_int(&out, rfwd->allocated_port); | 633 | buffer_put_int(&out, rfwd->allocated_port); |
619 | channel_update_permitted_opens(rfwd->handle, | 634 | channel_update_permitted_opens(ssh, rfwd->handle, |
620 | rfwd->allocated_port); | 635 | rfwd->allocated_port); |
621 | } else { | 636 | } else { |
622 | buffer_put_int(&out, MUX_S_OK); | 637 | buffer_put_int(&out, MUX_S_OK); |
@@ -625,7 +640,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
625 | goto out; | 640 | goto out; |
626 | } else { | 641 | } else { |
627 | if (rfwd->listen_port == 0) | 642 | if (rfwd->listen_port == 0) |
628 | channel_update_permitted_opens(rfwd->handle, -1); | 643 | channel_update_permitted_opens(ssh, rfwd->handle, -1); |
629 | if (rfwd->listen_path != NULL) | 644 | if (rfwd->listen_path != NULL) |
630 | xasprintf(&failmsg, "remote port forwarding failed for " | 645 | xasprintf(&failmsg, "remote port forwarding failed for " |
631 | "listen path %s", rfwd->listen_path); | 646 | "listen path %s", rfwd->listen_path); |
@@ -651,7 +666,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
651 | buffer_put_cstring(&out, failmsg); | 666 | buffer_put_cstring(&out, failmsg); |
652 | free(failmsg); | 667 | free(failmsg); |
653 | out: | 668 | out: |
654 | buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); | 669 | buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out)); |
655 | buffer_free(&out); | 670 | buffer_free(&out); |
656 | if (c->mux_pause <= 0) | 671 | if (c->mux_pause <= 0) |
657 | fatal("%s: mux_pause %d", __func__, c->mux_pause); | 672 | fatal("%s: mux_pause %d", __func__, c->mux_pause); |
@@ -659,7 +674,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
659 | } | 674 | } |
660 | 675 | ||
661 | static int | 676 | static int |
662 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 677 | process_mux_open_fwd(struct ssh *ssh, u_int rid, |
678 | Channel *c, Buffer *m, Buffer *r) | ||
663 | { | 679 | { |
664 | struct Forward fwd; | 680 | struct Forward fwd; |
665 | char *fwd_desc = NULL; | 681 | char *fwd_desc = NULL; |
@@ -727,13 +743,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
727 | fwd.listen_port); | 743 | fwd.listen_port); |
728 | goto invalid; | 744 | goto invalid; |
729 | } | 745 | } |
730 | if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) | 746 | if ((fwd.connect_port != PORT_STREAMLOCAL && |
731 | || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { | 747 | fwd.connect_port >= 65536) || |
748 | (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && | ||
749 | fwd.connect_port == 0)) { | ||
732 | logit("%s: invalid connect port %u", __func__, | 750 | logit("%s: invalid connect port %u", __func__, |
733 | fwd.connect_port); | 751 | fwd.connect_port); |
734 | goto invalid; | 752 | goto invalid; |
735 | } | 753 | } |
736 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { | 754 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && |
755 | fwd.connect_path == NULL) { | ||
737 | logit("%s: missing connect host", __func__); | 756 | logit("%s: missing connect host", __func__); |
738 | goto invalid; | 757 | goto invalid; |
739 | } | 758 | } |
@@ -784,7 +803,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
784 | } | 803 | } |
785 | 804 | ||
786 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { | 805 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { |
787 | if (!channel_setup_local_fwd_listener(&fwd, | 806 | if (!channel_setup_local_fwd_listener(ssh, &fwd, |
788 | &options.fwd_opts)) { | 807 | &options.fwd_opts)) { |
789 | fail: | 808 | fail: |
790 | logit("slave-requested %s failed", fwd_desc); | 809 | logit("slave-requested %s failed", fwd_desc); |
@@ -798,7 +817,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
798 | } else { | 817 | } else { |
799 | struct mux_channel_confirm_ctx *fctx; | 818 | struct mux_channel_confirm_ctx *fctx; |
800 | 819 | ||
801 | fwd.handle = channel_request_remote_forwarding(&fwd); | 820 | fwd.handle = channel_request_remote_forwarding(ssh, &fwd); |
802 | if (fwd.handle < 0) | 821 | if (fwd.handle < 0) |
803 | goto fail; | 822 | goto fail; |
804 | add_remote_forward(&options, &fwd); | 823 | add_remote_forward(&options, &fwd); |
@@ -827,7 +846,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
827 | } | 846 | } |
828 | 847 | ||
829 | static int | 848 | static int |
830 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 849 | process_mux_close_fwd(struct ssh *ssh, u_int rid, |
850 | Channel *c, Buffer *m, Buffer *r) | ||
831 | { | 851 | { |
832 | struct Forward fwd, *found_fwd; | 852 | struct Forward fwd, *found_fwd; |
833 | char *fwd_desc = NULL; | 853 | char *fwd_desc = NULL; |
@@ -908,11 +928,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
908 | * However, for dynamic allocated listen ports we need | 928 | * However, for dynamic allocated listen ports we need |
909 | * to use the actual listen port. | 929 | * to use the actual listen port. |
910 | */ | 930 | */ |
911 | if (channel_request_rforward_cancel(found_fwd) == -1) | 931 | if (channel_request_rforward_cancel(ssh, found_fwd) == -1) |
912 | error_reason = "port not in permitted opens"; | 932 | error_reason = "port not in permitted opens"; |
913 | } else { /* local and dynamic forwards */ | 933 | } else { /* local and dynamic forwards */ |
914 | /* Ditto */ | 934 | /* Ditto */ |
915 | if (channel_cancel_lport_listener(&fwd, fwd.connect_port, | 935 | if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port, |
916 | &options.fwd_opts) == -1) | 936 | &options.fwd_opts) == -1) |
917 | error_reason = "port not found"; | 937 | error_reason = "port not found"; |
918 | } | 938 | } |
@@ -942,7 +962,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
942 | } | 962 | } |
943 | 963 | ||
944 | static int | 964 | static int |
945 | process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 965 | process_mux_stdio_fwd(struct ssh *ssh, u_int rid, |
966 | Channel *c, Buffer *m, Buffer *r) | ||
946 | { | 967 | { |
947 | Channel *nc; | 968 | Channel *nc; |
948 | char *reserved, *chost; | 969 | char *reserved, *chost; |
@@ -1018,7 +1039,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1018 | if (!isatty(new_fd[1])) | 1039 | if (!isatty(new_fd[1])) |
1019 | set_nonblock(new_fd[1]); | 1040 | set_nonblock(new_fd[1]); |
1020 | 1041 | ||
1021 | nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); | 1042 | nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); |
1022 | 1043 | ||
1023 | nc->ctl_chan = c->self; /* link session -> control channel */ | 1044 | nc->ctl_chan = c->self; /* link session -> control channel */ |
1024 | c->remote_id = nc->self; /* link control -> session channel */ | 1045 | c->remote_id = nc->self; /* link control -> session channel */ |
@@ -1026,11 +1047,12 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1026 | debug2("%s: channel_new: %d linked to control channel %d", | 1047 | debug2("%s: channel_new: %d linked to control channel %d", |
1027 | __func__, nc->self, nc->ctl_chan); | 1048 | __func__, nc->self, nc->ctl_chan); |
1028 | 1049 | ||
1029 | channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); | 1050 | channel_register_cleanup(ssh, nc->self, |
1051 | mux_master_session_cleanup_cb, 1); | ||
1030 | 1052 | ||
1031 | cctx = xcalloc(1, sizeof(*cctx)); | 1053 | cctx = xcalloc(1, sizeof(*cctx)); |
1032 | cctx->rid = rid; | 1054 | cctx->rid = rid; |
1033 | channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx); | 1055 | channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx); |
1034 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ | 1056 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ |
1035 | 1057 | ||
1036 | /* reply is deferred, sent by mux_session_confirm */ | 1058 | /* reply is deferred, sent by mux_session_confirm */ |
@@ -1039,7 +1061,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1039 | 1061 | ||
1040 | /* Callback on open confirmation in mux master for a mux stdio fwd session. */ | 1062 | /* Callback on open confirmation in mux master for a mux stdio fwd session. */ |
1041 | static void | 1063 | static void |
1042 | mux_stdio_confirm(int id, int success, void *arg) | 1064 | mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg) |
1043 | { | 1065 | { |
1044 | struct mux_stdio_confirm_ctx *cctx = arg; | 1066 | struct mux_stdio_confirm_ctx *cctx = arg; |
1045 | Channel *c, *cc; | 1067 | Channel *c, *cc; |
@@ -1047,9 +1069,9 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1047 | 1069 | ||
1048 | if (cctx == NULL) | 1070 | if (cctx == NULL) |
1049 | fatal("%s: cctx == NULL", __func__); | 1071 | fatal("%s: cctx == NULL", __func__); |
1050 | if ((c = channel_by_id(id)) == NULL) | 1072 | if ((c = channel_by_id(ssh, id)) == NULL) |
1051 | fatal("%s: no channel for id %d", __func__, id); | 1073 | fatal("%s: no channel for id %d", __func__, id); |
1052 | if ((cc = channel_by_id(c->ctl_chan)) == NULL) | 1074 | if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1053 | fatal("%s: channel %d lacks control channel %d", __func__, | 1075 | fatal("%s: channel %d lacks control channel %d", __func__, |
1054 | id, c->ctl_chan); | 1076 | id, c->ctl_chan); |
1055 | 1077 | ||
@@ -1072,7 +1094,7 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1072 | 1094 | ||
1073 | done: | 1095 | done: |
1074 | /* Send reply */ | 1096 | /* Send reply */ |
1075 | buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); | 1097 | buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); |
1076 | buffer_free(&reply); | 1098 | buffer_free(&reply); |
1077 | 1099 | ||
1078 | if (cc->mux_pause <= 0) | 1100 | if (cc->mux_pause <= 0) |
@@ -1083,7 +1105,8 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1083 | } | 1105 | } |
1084 | 1106 | ||
1085 | static int | 1107 | static int |
1086 | process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1108 | process_mux_stop_listening(struct ssh *ssh, u_int rid, |
1109 | Channel *c, Buffer *m, Buffer *r) | ||
1087 | { | 1110 | { |
1088 | debug("%s: channel %d: stop listening", __func__, c->self); | 1111 | debug("%s: channel %d: stop listening", __func__, c->self); |
1089 | 1112 | ||
@@ -1100,7 +1123,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1100 | } | 1123 | } |
1101 | 1124 | ||
1102 | if (mux_listener_channel != NULL) { | 1125 | if (mux_listener_channel != NULL) { |
1103 | channel_free(mux_listener_channel); | 1126 | channel_free(ssh, mux_listener_channel); |
1104 | client_stop_mux(); | 1127 | client_stop_mux(); |
1105 | free(options.control_path); | 1128 | free(options.control_path); |
1106 | options.control_path = NULL; | 1129 | options.control_path = NULL; |
@@ -1116,7 +1139,8 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1116 | } | 1139 | } |
1117 | 1140 | ||
1118 | static int | 1141 | static int |
1119 | process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1142 | process_mux_proxy(struct ssh *ssh, u_int rid, |
1143 | Channel *c, Buffer *m, Buffer *r) | ||
1120 | { | 1144 | { |
1121 | debug("%s: channel %d: proxy request", __func__, c->self); | 1145 | debug("%s: channel %d: proxy request", __func__, c->self); |
1122 | 1146 | ||
@@ -1129,7 +1153,7 @@ process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1129 | 1153 | ||
1130 | /* Channel callbacks fired on read/write from mux slave fd */ | 1154 | /* Channel callbacks fired on read/write from mux slave fd */ |
1131 | static int | 1155 | static int |
1132 | mux_master_read_cb(Channel *c) | 1156 | mux_master_read_cb(struct ssh *ssh, Channel *c) |
1133 | { | 1157 | { |
1134 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; | 1158 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; |
1135 | Buffer in, out; | 1159 | Buffer in, out; |
@@ -1141,7 +1165,7 @@ mux_master_read_cb(Channel *c) | |||
1141 | if (c->mux_ctx == NULL) { | 1165 | if (c->mux_ctx == NULL) { |
1142 | state = xcalloc(1, sizeof(*state)); | 1166 | state = xcalloc(1, sizeof(*state)); |
1143 | c->mux_ctx = state; | 1167 | c->mux_ctx = state; |
1144 | channel_register_cleanup(c->self, | 1168 | channel_register_cleanup(ssh, c->self, |
1145 | mux_master_control_cleanup_cb, 0); | 1169 | mux_master_control_cleanup_cb, 0); |
1146 | 1170 | ||
1147 | /* Send hello */ | 1171 | /* Send hello */ |
@@ -1149,7 +1173,7 @@ mux_master_read_cb(Channel *c) | |||
1149 | buffer_put_int(&out, MUX_MSG_HELLO); | 1173 | buffer_put_int(&out, MUX_MSG_HELLO); |
1150 | buffer_put_int(&out, SSHMUX_VER); | 1174 | buffer_put_int(&out, SSHMUX_VER); |
1151 | /* no extensions */ | 1175 | /* no extensions */ |
1152 | buffer_put_string(&c->output, buffer_ptr(&out), | 1176 | buffer_put_string(c->output, buffer_ptr(&out), |
1153 | buffer_len(&out)); | 1177 | buffer_len(&out)); |
1154 | buffer_free(&out); | 1178 | buffer_free(&out); |
1155 | debug3("%s: channel %d: hello sent", __func__, c->self); | 1179 | debug3("%s: channel %d: hello sent", __func__, c->self); |
@@ -1160,7 +1184,7 @@ mux_master_read_cb(Channel *c) | |||
1160 | buffer_init(&out); | 1184 | buffer_init(&out); |
1161 | 1185 | ||
1162 | /* Channel code ensures that we receive whole packets */ | 1186 | /* Channel code ensures that we receive whole packets */ |
1163 | if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { | 1187 | if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) { |
1164 | malf: | 1188 | malf: |
1165 | error("%s: malformed message", __func__); | 1189 | error("%s: malformed message", __func__); |
1166 | goto out; | 1190 | goto out; |
@@ -1186,7 +1210,8 @@ mux_master_read_cb(Channel *c) | |||
1186 | 1210 | ||
1187 | for (i = 0; mux_master_handlers[i].handler != NULL; i++) { | 1211 | for (i = 0; mux_master_handlers[i].handler != NULL; i++) { |
1188 | if (type == mux_master_handlers[i].type) { | 1212 | if (type == mux_master_handlers[i].type) { |
1189 | ret = mux_master_handlers[i].handler(rid, c, &in, &out); | 1213 | ret = mux_master_handlers[i].handler(ssh, rid, |
1214 | c, &in, &out); | ||
1190 | break; | 1215 | break; |
1191 | } | 1216 | } |
1192 | } | 1217 | } |
@@ -1199,7 +1224,7 @@ mux_master_read_cb(Channel *c) | |||
1199 | } | 1224 | } |
1200 | /* Enqueue reply packet */ | 1225 | /* Enqueue reply packet */ |
1201 | if (buffer_len(&out) != 0) { | 1226 | if (buffer_len(&out) != 0) { |
1202 | buffer_put_string(&c->output, buffer_ptr(&out), | 1227 | buffer_put_string(c->output, buffer_ptr(&out), |
1203 | buffer_len(&out)); | 1228 | buffer_len(&out)); |
1204 | } | 1229 | } |
1205 | out: | 1230 | out: |
@@ -1209,7 +1234,7 @@ mux_master_read_cb(Channel *c) | |||
1209 | } | 1234 | } |
1210 | 1235 | ||
1211 | void | 1236 | void |
1212 | mux_exit_message(Channel *c, int exitval) | 1237 | mux_exit_message(struct ssh *ssh, Channel *c, int exitval) |
1213 | { | 1238 | { |
1214 | Buffer m; | 1239 | Buffer m; |
1215 | Channel *mux_chan; | 1240 | Channel *mux_chan; |
@@ -1217,7 +1242,7 @@ mux_exit_message(Channel *c, int exitval) | |||
1217 | debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, | 1242 | debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, |
1218 | exitval); | 1243 | exitval); |
1219 | 1244 | ||
1220 | if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) | 1245 | if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1221 | fatal("%s: channel %d missing mux channel %d", | 1246 | fatal("%s: channel %d missing mux channel %d", |
1222 | __func__, c->self, c->ctl_chan); | 1247 | __func__, c->self, c->ctl_chan); |
1223 | 1248 | ||
@@ -1227,19 +1252,19 @@ mux_exit_message(Channel *c, int exitval) | |||
1227 | buffer_put_int(&m, c->self); | 1252 | buffer_put_int(&m, c->self); |
1228 | buffer_put_int(&m, exitval); | 1253 | buffer_put_int(&m, exitval); |
1229 | 1254 | ||
1230 | buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); | 1255 | buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); |
1231 | buffer_free(&m); | 1256 | buffer_free(&m); |
1232 | } | 1257 | } |
1233 | 1258 | ||
1234 | void | 1259 | void |
1235 | mux_tty_alloc_failed(Channel *c) | 1260 | mux_tty_alloc_failed(struct ssh *ssh, Channel *c) |
1236 | { | 1261 | { |
1237 | Buffer m; | 1262 | Buffer m; |
1238 | Channel *mux_chan; | 1263 | Channel *mux_chan; |
1239 | 1264 | ||
1240 | debug3("%s: channel %d: TTY alloc failed", __func__, c->self); | 1265 | debug3("%s: channel %d: TTY alloc failed", __func__, c->self); |
1241 | 1266 | ||
1242 | if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) | 1267 | if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1243 | fatal("%s: channel %d missing mux channel %d", | 1268 | fatal("%s: channel %d missing mux channel %d", |
1244 | __func__, c->self, c->ctl_chan); | 1269 | __func__, c->self, c->ctl_chan); |
1245 | 1270 | ||
@@ -1248,13 +1273,13 @@ mux_tty_alloc_failed(Channel *c) | |||
1248 | buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); | 1273 | buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); |
1249 | buffer_put_int(&m, c->self); | 1274 | buffer_put_int(&m, c->self); |
1250 | 1275 | ||
1251 | buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); | 1276 | buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); |
1252 | buffer_free(&m); | 1277 | buffer_free(&m); |
1253 | } | 1278 | } |
1254 | 1279 | ||
1255 | /* Prepare a mux master to listen on a Unix domain socket. */ | 1280 | /* Prepare a mux master to listen on a Unix domain socket. */ |
1256 | void | 1281 | void |
1257 | muxserver_listen(void) | 1282 | muxserver_listen(struct ssh *ssh) |
1258 | { | 1283 | { |
1259 | mode_t old_umask; | 1284 | mode_t old_umask; |
1260 | char *orig_control_path = options.control_path; | 1285 | char *orig_control_path = options.control_path; |
@@ -1327,7 +1352,7 @@ muxserver_listen(void) | |||
1327 | 1352 | ||
1328 | set_nonblock(muxserver_sock); | 1353 | set_nonblock(muxserver_sock); |
1329 | 1354 | ||
1330 | mux_listener_channel = channel_new("mux listener", | 1355 | mux_listener_channel = channel_new(ssh, "mux listener", |
1331 | SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, | 1356 | SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, |
1332 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, | 1357 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
1333 | 0, options.control_path, 1); | 1358 | 0, options.control_path, 1); |
@@ -1338,7 +1363,7 @@ muxserver_listen(void) | |||
1338 | 1363 | ||
1339 | /* Callback on open confirmation in mux master for a mux client session. */ | 1364 | /* Callback on open confirmation in mux master for a mux client session. */ |
1340 | static void | 1365 | static void |
1341 | mux_session_confirm(int id, int success, void *arg) | 1366 | mux_session_confirm(struct ssh *ssh, int id, int success, void *arg) |
1342 | { | 1367 | { |
1343 | struct mux_session_confirm_ctx *cctx = arg; | 1368 | struct mux_session_confirm_ctx *cctx = arg; |
1344 | const char *display; | 1369 | const char *display; |
@@ -1348,9 +1373,9 @@ mux_session_confirm(int id, int success, void *arg) | |||
1348 | 1373 | ||
1349 | if (cctx == NULL) | 1374 | if (cctx == NULL) |
1350 | fatal("%s: cctx == NULL", __func__); | 1375 | fatal("%s: cctx == NULL", __func__); |
1351 | if ((c = channel_by_id(id)) == NULL) | 1376 | if ((c = channel_by_id(ssh, id)) == NULL) |
1352 | fatal("%s: no channel for id %d", __func__, id); | 1377 | fatal("%s: no channel for id %d", __func__, id); |
1353 | if ((cc = channel_by_id(c->ctl_chan)) == NULL) | 1378 | if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1354 | fatal("%s: channel %d lacks control channel %d", __func__, | 1379 | fatal("%s: channel %d lacks control channel %d", __func__, |
1355 | id, c->ctl_chan); | 1380 | id, c->ctl_chan); |
1356 | 1381 | ||
@@ -1369,27 +1394,27 @@ mux_session_confirm(int id, int success, void *arg) | |||
1369 | char *proto, *data; | 1394 | char *proto, *data; |
1370 | 1395 | ||
1371 | /* Get reasonable local authentication information. */ | 1396 | /* Get reasonable local authentication information. */ |
1372 | if (client_x11_get_proto(display, options.xauth_location, | 1397 | if (client_x11_get_proto(ssh, display, options.xauth_location, |
1373 | options.forward_x11_trusted, options.forward_x11_timeout, | 1398 | options.forward_x11_trusted, options.forward_x11_timeout, |
1374 | &proto, &data) == 0) { | 1399 | &proto, &data) == 0) { |
1375 | /* Request forwarding with authentication spoofing. */ | 1400 | /* Request forwarding with authentication spoofing. */ |
1376 | debug("Requesting X11 forwarding with authentication " | 1401 | debug("Requesting X11 forwarding with authentication " |
1377 | "spoofing."); | 1402 | "spoofing."); |
1378 | x11_request_forwarding_with_spoofing(id, display, proto, | 1403 | x11_request_forwarding_with_spoofing(ssh, id, |
1379 | data, 1); | 1404 | display, proto, data, 1); |
1380 | /* XXX exit_on_forward_failure */ | 1405 | /* XXX exit_on_forward_failure */ |
1381 | client_expect_confirm(id, "X11 forwarding", | 1406 | client_expect_confirm(ssh, id, "X11 forwarding", |
1382 | CONFIRM_WARN); | 1407 | CONFIRM_WARN); |
1383 | } | 1408 | } |
1384 | } | 1409 | } |
1385 | 1410 | ||
1386 | if (cctx->want_agent_fwd && options.forward_agent) { | 1411 | if (cctx->want_agent_fwd && options.forward_agent) { |
1387 | debug("Requesting authentication agent forwarding."); | 1412 | debug("Requesting authentication agent forwarding."); |
1388 | channel_request_start(id, "auth-agent-req@openssh.com", 0); | 1413 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); |
1389 | packet_send(); | 1414 | packet_send(); |
1390 | } | 1415 | } |
1391 | 1416 | ||
1392 | client_session2_setup(id, cctx->want_tty, cctx->want_subsys, | 1417 | client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, |
1393 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); | 1418 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); |
1394 | 1419 | ||
1395 | debug3("%s: sending success reply", __func__); | 1420 | debug3("%s: sending success reply", __func__); |
@@ -1401,7 +1426,7 @@ mux_session_confirm(int id, int success, void *arg) | |||
1401 | 1426 | ||
1402 | done: | 1427 | done: |
1403 | /* Send reply */ | 1428 | /* Send reply */ |
1404 | buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); | 1429 | buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); |
1405 | buffer_free(&reply); | 1430 | buffer_free(&reply); |
1406 | 1431 | ||
1407 | if (cc->mux_pause <= 0) | 1432 | if (cc->mux_pause <= 0) |