diff options
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) |