diff options
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 239 |
1 files changed, 139 insertions, 100 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.64 2017/01/21 11:32:04 guenther Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.69 2017/09/20 05:19:00 dtucker 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,52 +203,54 @@ 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 = 0; |
209 | chan_rcvd_oclose(cc); | 219 | cc->have_remote_id = 0; |
220 | chan_rcvd_oclose(ssh, cc); | ||
210 | } | 221 | } |
211 | channel_cancel_cleanup(c->self); | 222 | channel_cancel_cleanup(ssh, c->self); |
212 | } | 223 | } |
213 | 224 | ||
214 | /* Cleanup callback fired on closure of mux slave _control_ channel */ | 225 | /* Cleanup callback fired on closure of mux slave _control_ channel */ |
215 | /* ARGSUSED */ | 226 | /* ARGSUSED */ |
216 | static void | 227 | static void |
217 | mux_master_control_cleanup_cb(int cid, void *unused) | 228 | mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused) |
218 | { | 229 | { |
219 | Channel *sc, *c = channel_by_id(cid); | 230 | Channel *sc, *c = channel_by_id(ssh, cid); |
220 | 231 | ||
221 | debug3("%s: entering for channel %d", __func__, cid); | 232 | debug3("%s: entering for channel %d", __func__, cid); |
222 | if (c == NULL) | 233 | if (c == NULL) |
223 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); | 234 | fatal("%s: channel_by_id(%i) == NULL", __func__, cid); |
224 | if (c->remote_id != -1) { | 235 | if (c->have_remote_id) { |
225 | if ((sc = channel_by_id(c->remote_id)) == NULL) | 236 | if ((sc = channel_by_id(ssh, c->remote_id)) == NULL) |
226 | fatal("%s: channel %d missing session channel %d", | 237 | fatal("%s: channel %d missing session channel %u", |
227 | __func__, c->self, c->remote_id); | 238 | __func__, c->self, c->remote_id); |
228 | c->remote_id = -1; | 239 | c->remote_id = 0; |
240 | c->have_remote_id = 0; | ||
229 | sc->ctl_chan = -1; | 241 | sc->ctl_chan = -1; |
230 | if (sc->type != SSH_CHANNEL_OPEN && | 242 | if (sc->type != SSH_CHANNEL_OPEN && |
231 | sc->type != SSH_CHANNEL_OPENING) { | 243 | sc->type != SSH_CHANNEL_OPENING) { |
232 | debug2("%s: channel %d: not open", __func__, sc->self); | 244 | debug2("%s: channel %d: not open", __func__, sc->self); |
233 | chan_mark_dead(sc); | 245 | chan_mark_dead(ssh, sc); |
234 | } else { | 246 | } else { |
235 | if (sc->istate == CHAN_INPUT_OPEN) | 247 | if (sc->istate == CHAN_INPUT_OPEN) |
236 | chan_read_failed(sc); | 248 | chan_read_failed(ssh, sc); |
237 | if (sc->ostate == CHAN_OUTPUT_OPEN) | 249 | if (sc->ostate == CHAN_OUTPUT_OPEN) |
238 | chan_write_failed(sc); | 250 | chan_write_failed(ssh, sc); |
239 | } | 251 | } |
240 | } | 252 | } |
241 | channel_cancel_cleanup(c->self); | 253 | channel_cancel_cleanup(ssh, c->self); |
242 | } | 254 | } |
243 | 255 | ||
244 | /* Check mux client environment variables before passing them to mux master. */ | 256 | /* Check mux client environment variables before passing them to mux master. */ |
@@ -266,7 +278,8 @@ env_permitted(char *env) | |||
266 | /* Mux master protocol message handlers */ | 278 | /* Mux master protocol message handlers */ |
267 | 279 | ||
268 | static int | 280 | static int |
269 | process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) | 281 | process_mux_master_hello(struct ssh *ssh, u_int rid, |
282 | Channel *c, Buffer *m, Buffer *r) | ||
270 | { | 283 | { |
271 | u_int ver; | 284 | u_int ver; |
272 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; | 285 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; |
@@ -308,7 +321,8 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
308 | } | 321 | } |
309 | 322 | ||
310 | static int | 323 | static int |
311 | process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | 324 | process_mux_new_session(struct ssh *ssh, u_int rid, |
325 | Channel *c, Buffer *m, Buffer *r) | ||
312 | { | 326 | { |
313 | Channel *nc; | 327 | Channel *nc; |
314 | struct mux_session_confirm_ctx *cctx; | 328 | struct mux_session_confirm_ctx *cctx; |
@@ -401,7 +415,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
401 | new_fd[0], new_fd[1], new_fd[2]); | 415 | new_fd[0], new_fd[1], new_fd[2]); |
402 | 416 | ||
403 | /* XXX support multiple child sessions in future */ | 417 | /* XXX support multiple child sessions in future */ |
404 | if (c->remote_id != -1) { | 418 | if (c->have_remote_id) { |
405 | debug2("%s: session already open", __func__); | 419 | debug2("%s: session already open", __func__); |
406 | /* prepare reply */ | 420 | /* prepare reply */ |
407 | buffer_put_int(r, MUX_S_FAILURE); | 421 | buffer_put_int(r, MUX_S_FAILURE); |
@@ -453,15 +467,16 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
453 | packetmax >>= 1; | 467 | packetmax >>= 1; |
454 | } | 468 | } |
455 | 469 | ||
456 | nc = channel_new("session", SSH_CHANNEL_OPENING, | 470 | nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, |
457 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, | 471 | new_fd[0], new_fd[1], new_fd[2], window, packetmax, |
458 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); | 472 | CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); |
459 | 473 | ||
460 | nc->ctl_chan = c->self; /* link session -> control channel */ | 474 | nc->ctl_chan = c->self; /* link session -> control channel */ |
461 | 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; | ||
462 | 477 | ||
463 | if (cctx->want_tty && escape_char != 0xffffffff) { | 478 | if (cctx->want_tty && escape_char != 0xffffffff) { |
464 | channel_register_filter(nc->self, | 479 | channel_register_filter(ssh, nc->self, |
465 | client_simple_escape_filter, NULL, | 480 | client_simple_escape_filter, NULL, |
466 | client_filter_cleanup, | 481 | client_filter_cleanup, |
467 | client_new_escape_filter_ctx((int)escape_char)); | 482 | client_new_escape_filter_ctx((int)escape_char)); |
@@ -470,17 +485,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", | 485 | debug2("%s: channel_new: %d linked to control channel %d", |
471 | __func__, nc->self, nc->ctl_chan); | 486 | __func__, nc->self, nc->ctl_chan); |
472 | 487 | ||
473 | channel_send_open(nc->self); | 488 | channel_send_open(ssh, nc->self); |
474 | channel_register_open_confirm(nc->self, mux_session_confirm, cctx); | 489 | channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx); |
475 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ | 490 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ |
476 | channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); | 491 | channel_register_cleanup(ssh, nc->self, |
492 | mux_master_session_cleanup_cb, 1); | ||
477 | 493 | ||
478 | /* reply is deferred, sent by mux_session_confirm */ | 494 | /* reply is deferred, sent by mux_session_confirm */ |
479 | return 0; | 495 | return 0; |
480 | } | 496 | } |
481 | 497 | ||
482 | static int | 498 | static int |
483 | process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) | 499 | process_mux_alive_check(struct ssh *ssh, u_int rid, |
500 | Channel *c, Buffer *m, Buffer *r) | ||
484 | { | 501 | { |
485 | debug2("%s: channel %d: alive check", __func__, c->self); | 502 | debug2("%s: channel %d: alive check", __func__, c->self); |
486 | 503 | ||
@@ -493,7 +510,8 @@ process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
493 | } | 510 | } |
494 | 511 | ||
495 | static int | 512 | static int |
496 | process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) | 513 | process_mux_terminate(struct ssh *ssh, u_int rid, |
514 | Channel *c, Buffer *m, Buffer *r) | ||
497 | { | 515 | { |
498 | debug2("%s: channel %d: terminate request", __func__, c->self); | 516 | debug2("%s: channel %d: terminate request", __func__, c->self); |
499 | 517 | ||
@@ -582,7 +600,7 @@ compare_forward(struct Forward *a, struct Forward *b) | |||
582 | } | 600 | } |
583 | 601 | ||
584 | static void | 602 | static void |
585 | mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 603 | mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
586 | { | 604 | { |
587 | struct mux_channel_confirm_ctx *fctx = ctxt; | 605 | struct mux_channel_confirm_ctx *fctx = ctxt; |
588 | char *failmsg = NULL; | 606 | char *failmsg = NULL; |
@@ -590,7 +608,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
590 | Channel *c; | 608 | Channel *c; |
591 | Buffer out; | 609 | Buffer out; |
592 | 610 | ||
593 | if ((c = channel_by_id(fctx->cid)) == NULL) { | 611 | if ((c = channel_by_id(ssh, fctx->cid)) == NULL) { |
594 | /* no channel for reply */ | 612 | /* no channel for reply */ |
595 | error("%s: unknown channel", __func__); | 613 | error("%s: unknown channel", __func__); |
596 | return; | 614 | return; |
@@ -616,7 +634,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
616 | buffer_put_int(&out, MUX_S_REMOTE_PORT); | 634 | buffer_put_int(&out, MUX_S_REMOTE_PORT); |
617 | buffer_put_int(&out, fctx->rid); | 635 | buffer_put_int(&out, fctx->rid); |
618 | buffer_put_int(&out, rfwd->allocated_port); | 636 | buffer_put_int(&out, rfwd->allocated_port); |
619 | channel_update_permitted_opens(rfwd->handle, | 637 | channel_update_permitted_opens(ssh, rfwd->handle, |
620 | rfwd->allocated_port); | 638 | rfwd->allocated_port); |
621 | } else { | 639 | } else { |
622 | buffer_put_int(&out, MUX_S_OK); | 640 | buffer_put_int(&out, MUX_S_OK); |
@@ -625,7 +643,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
625 | goto out; | 643 | goto out; |
626 | } else { | 644 | } else { |
627 | if (rfwd->listen_port == 0) | 645 | if (rfwd->listen_port == 0) |
628 | channel_update_permitted_opens(rfwd->handle, -1); | 646 | channel_update_permitted_opens(ssh, rfwd->handle, -1); |
629 | if (rfwd->listen_path != NULL) | 647 | if (rfwd->listen_path != NULL) |
630 | xasprintf(&failmsg, "remote port forwarding failed for " | 648 | xasprintf(&failmsg, "remote port forwarding failed for " |
631 | "listen path %s", rfwd->listen_path); | 649 | "listen path %s", rfwd->listen_path); |
@@ -651,7 +669,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
651 | buffer_put_cstring(&out, failmsg); | 669 | buffer_put_cstring(&out, failmsg); |
652 | free(failmsg); | 670 | free(failmsg); |
653 | out: | 671 | out: |
654 | buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); | 672 | buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out)); |
655 | buffer_free(&out); | 673 | buffer_free(&out); |
656 | if (c->mux_pause <= 0) | 674 | if (c->mux_pause <= 0) |
657 | fatal("%s: mux_pause %d", __func__, c->mux_pause); | 675 | fatal("%s: mux_pause %d", __func__, c->mux_pause); |
@@ -659,7 +677,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
659 | } | 677 | } |
660 | 678 | ||
661 | static int | 679 | static int |
662 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 680 | process_mux_open_fwd(struct ssh *ssh, u_int rid, |
681 | Channel *c, Buffer *m, Buffer *r) | ||
663 | { | 682 | { |
664 | struct Forward fwd; | 683 | struct Forward fwd; |
665 | char *fwd_desc = NULL; | 684 | char *fwd_desc = NULL; |
@@ -727,13 +746,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
727 | fwd.listen_port); | 746 | fwd.listen_port); |
728 | goto invalid; | 747 | goto invalid; |
729 | } | 748 | } |
730 | if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) | 749 | if ((fwd.connect_port != PORT_STREAMLOCAL && |
731 | || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { | 750 | fwd.connect_port >= 65536) || |
751 | (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && | ||
752 | fwd.connect_port == 0)) { | ||
732 | logit("%s: invalid connect port %u", __func__, | 753 | logit("%s: invalid connect port %u", __func__, |
733 | fwd.connect_port); | 754 | fwd.connect_port); |
734 | goto invalid; | 755 | goto invalid; |
735 | } | 756 | } |
736 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { | 757 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && |
758 | fwd.connect_path == NULL) { | ||
737 | logit("%s: missing connect host", __func__); | 759 | logit("%s: missing connect host", __func__); |
738 | goto invalid; | 760 | goto invalid; |
739 | } | 761 | } |
@@ -784,7 +806,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
784 | } | 806 | } |
785 | 807 | ||
786 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { | 808 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { |
787 | if (!channel_setup_local_fwd_listener(&fwd, | 809 | if (!channel_setup_local_fwd_listener(ssh, &fwd, |
788 | &options.fwd_opts)) { | 810 | &options.fwd_opts)) { |
789 | fail: | 811 | fail: |
790 | logit("slave-requested %s failed", fwd_desc); | 812 | logit("slave-requested %s failed", fwd_desc); |
@@ -798,7 +820,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
798 | } else { | 820 | } else { |
799 | struct mux_channel_confirm_ctx *fctx; | 821 | struct mux_channel_confirm_ctx *fctx; |
800 | 822 | ||
801 | fwd.handle = channel_request_remote_forwarding(&fwd); | 823 | fwd.handle = channel_request_remote_forwarding(ssh, &fwd); |
802 | if (fwd.handle < 0) | 824 | if (fwd.handle < 0) |
803 | goto fail; | 825 | goto fail; |
804 | add_remote_forward(&options, &fwd); | 826 | add_remote_forward(&options, &fwd); |
@@ -827,7 +849,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
827 | } | 849 | } |
828 | 850 | ||
829 | static int | 851 | static int |
830 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 852 | process_mux_close_fwd(struct ssh *ssh, u_int rid, |
853 | Channel *c, Buffer *m, Buffer *r) | ||
831 | { | 854 | { |
832 | struct Forward fwd, *found_fwd; | 855 | struct Forward fwd, *found_fwd; |
833 | char *fwd_desc = NULL; | 856 | char *fwd_desc = NULL; |
@@ -908,11 +931,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
908 | * However, for dynamic allocated listen ports we need | 931 | * However, for dynamic allocated listen ports we need |
909 | * to use the actual listen port. | 932 | * to use the actual listen port. |
910 | */ | 933 | */ |
911 | if (channel_request_rforward_cancel(found_fwd) == -1) | 934 | if (channel_request_rforward_cancel(ssh, found_fwd) == -1) |
912 | error_reason = "port not in permitted opens"; | 935 | error_reason = "port not in permitted opens"; |
913 | } else { /* local and dynamic forwards */ | 936 | } else { /* local and dynamic forwards */ |
914 | /* Ditto */ | 937 | /* Ditto */ |
915 | if (channel_cancel_lport_listener(&fwd, fwd.connect_port, | 938 | if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port, |
916 | &options.fwd_opts) == -1) | 939 | &options.fwd_opts) == -1) |
917 | error_reason = "port not found"; | 940 | error_reason = "port not found"; |
918 | } | 941 | } |
@@ -942,7 +965,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
942 | } | 965 | } |
943 | 966 | ||
944 | static int | 967 | static int |
945 | process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 968 | process_mux_stdio_fwd(struct ssh *ssh, u_int rid, |
969 | Channel *c, Buffer *m, Buffer *r) | ||
946 | { | 970 | { |
947 | Channel *nc; | 971 | Channel *nc; |
948 | char *reserved, *chost; | 972 | char *reserved, *chost; |
@@ -986,7 +1010,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
986 | new_fd[0], new_fd[1]); | 1010 | new_fd[0], new_fd[1]); |
987 | 1011 | ||
988 | /* XXX support multiple child sessions in future */ | 1012 | /* XXX support multiple child sessions in future */ |
989 | if (c->remote_id != -1) { | 1013 | if (c->have_remote_id) { |
990 | debug2("%s: session already open", __func__); | 1014 | debug2("%s: session already open", __func__); |
991 | /* prepare reply */ | 1015 | /* prepare reply */ |
992 | buffer_put_int(r, MUX_S_FAILURE); | 1016 | buffer_put_int(r, MUX_S_FAILURE); |
@@ -1018,19 +1042,21 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1018 | if (!isatty(new_fd[1])) | 1042 | if (!isatty(new_fd[1])) |
1019 | set_nonblock(new_fd[1]); | 1043 | set_nonblock(new_fd[1]); |
1020 | 1044 | ||
1021 | nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); | 1045 | nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]); |
1022 | 1046 | ||
1023 | nc->ctl_chan = c->self; /* link session -> control channel */ | 1047 | nc->ctl_chan = c->self; /* link session -> control channel */ |
1024 | 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; | ||
1025 | 1050 | ||
1026 | debug2("%s: channel_new: %d linked to control channel %d", | 1051 | debug2("%s: channel_new: %d linked to control channel %d", |
1027 | __func__, nc->self, nc->ctl_chan); | 1052 | __func__, nc->self, nc->ctl_chan); |
1028 | 1053 | ||
1029 | channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); | 1054 | channel_register_cleanup(ssh, nc->self, |
1055 | mux_master_session_cleanup_cb, 1); | ||
1030 | 1056 | ||
1031 | cctx = xcalloc(1, sizeof(*cctx)); | 1057 | cctx = xcalloc(1, sizeof(*cctx)); |
1032 | cctx->rid = rid; | 1058 | cctx->rid = rid; |
1033 | channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx); | 1059 | channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx); |
1034 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ | 1060 | c->mux_pause = 1; /* stop handling messages until open_confirm done */ |
1035 | 1061 | ||
1036 | /* reply is deferred, sent by mux_session_confirm */ | 1062 | /* reply is deferred, sent by mux_session_confirm */ |
@@ -1039,7 +1065,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1039 | 1065 | ||
1040 | /* Callback on open confirmation in mux master for a mux stdio fwd session. */ | 1066 | /* Callback on open confirmation in mux master for a mux stdio fwd session. */ |
1041 | static void | 1067 | static void |
1042 | mux_stdio_confirm(int id, int success, void *arg) | 1068 | mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg) |
1043 | { | 1069 | { |
1044 | struct mux_stdio_confirm_ctx *cctx = arg; | 1070 | struct mux_stdio_confirm_ctx *cctx = arg; |
1045 | Channel *c, *cc; | 1071 | Channel *c, *cc; |
@@ -1047,9 +1073,9 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1047 | 1073 | ||
1048 | if (cctx == NULL) | 1074 | if (cctx == NULL) |
1049 | fatal("%s: cctx == NULL", __func__); | 1075 | fatal("%s: cctx == NULL", __func__); |
1050 | if ((c = channel_by_id(id)) == NULL) | 1076 | if ((c = channel_by_id(ssh, id)) == NULL) |
1051 | fatal("%s: no channel for id %d", __func__, id); | 1077 | fatal("%s: no channel for id %d", __func__, id); |
1052 | if ((cc = channel_by_id(c->ctl_chan)) == NULL) | 1078 | if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1053 | fatal("%s: channel %d lacks control channel %d", __func__, | 1079 | fatal("%s: channel %d lacks control channel %d", __func__, |
1054 | id, c->ctl_chan); | 1080 | id, c->ctl_chan); |
1055 | 1081 | ||
@@ -1072,7 +1098,7 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1072 | 1098 | ||
1073 | done: | 1099 | done: |
1074 | /* Send reply */ | 1100 | /* Send reply */ |
1075 | buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); | 1101 | buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); |
1076 | buffer_free(&reply); | 1102 | buffer_free(&reply); |
1077 | 1103 | ||
1078 | if (cc->mux_pause <= 0) | 1104 | if (cc->mux_pause <= 0) |
@@ -1083,7 +1109,8 @@ mux_stdio_confirm(int id, int success, void *arg) | |||
1083 | } | 1109 | } |
1084 | 1110 | ||
1085 | static int | 1111 | static int |
1086 | process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1112 | process_mux_stop_listening(struct ssh *ssh, u_int rid, |
1113 | Channel *c, Buffer *m, Buffer *r) | ||
1087 | { | 1114 | { |
1088 | debug("%s: channel %d: stop listening", __func__, c->self); | 1115 | debug("%s: channel %d: stop listening", __func__, c->self); |
1089 | 1116 | ||
@@ -1100,7 +1127,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1100 | } | 1127 | } |
1101 | 1128 | ||
1102 | if (mux_listener_channel != NULL) { | 1129 | if (mux_listener_channel != NULL) { |
1103 | channel_free(mux_listener_channel); | 1130 | channel_free(ssh, mux_listener_channel); |
1104 | client_stop_mux(); | 1131 | client_stop_mux(); |
1105 | free(options.control_path); | 1132 | free(options.control_path); |
1106 | options.control_path = NULL; | 1133 | options.control_path = NULL; |
@@ -1116,7 +1143,8 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1116 | } | 1143 | } |
1117 | 1144 | ||
1118 | static int | 1145 | static int |
1119 | process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1146 | process_mux_proxy(struct ssh *ssh, u_int rid, |
1147 | Channel *c, Buffer *m, Buffer *r) | ||
1120 | { | 1148 | { |
1121 | debug("%s: channel %d: proxy request", __func__, c->self); | 1149 | debug("%s: channel %d: proxy request", __func__, c->self); |
1122 | 1150 | ||
@@ -1129,7 +1157,7 @@ process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
1129 | 1157 | ||
1130 | /* Channel callbacks fired on read/write from mux slave fd */ | 1158 | /* Channel callbacks fired on read/write from mux slave fd */ |
1131 | static int | 1159 | static int |
1132 | mux_master_read_cb(Channel *c) | 1160 | mux_master_read_cb(struct ssh *ssh, Channel *c) |
1133 | { | 1161 | { |
1134 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; | 1162 | struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; |
1135 | Buffer in, out; | 1163 | Buffer in, out; |
@@ -1141,7 +1169,7 @@ mux_master_read_cb(Channel *c) | |||
1141 | if (c->mux_ctx == NULL) { | 1169 | if (c->mux_ctx == NULL) { |
1142 | state = xcalloc(1, sizeof(*state)); | 1170 | state = xcalloc(1, sizeof(*state)); |
1143 | c->mux_ctx = state; | 1171 | c->mux_ctx = state; |
1144 | channel_register_cleanup(c->self, | 1172 | channel_register_cleanup(ssh, c->self, |
1145 | mux_master_control_cleanup_cb, 0); | 1173 | mux_master_control_cleanup_cb, 0); |
1146 | 1174 | ||
1147 | /* Send hello */ | 1175 | /* Send hello */ |
@@ -1149,7 +1177,7 @@ mux_master_read_cb(Channel *c) | |||
1149 | buffer_put_int(&out, MUX_MSG_HELLO); | 1177 | buffer_put_int(&out, MUX_MSG_HELLO); |
1150 | buffer_put_int(&out, SSHMUX_VER); | 1178 | buffer_put_int(&out, SSHMUX_VER); |
1151 | /* no extensions */ | 1179 | /* no extensions */ |
1152 | buffer_put_string(&c->output, buffer_ptr(&out), | 1180 | buffer_put_string(c->output, buffer_ptr(&out), |
1153 | buffer_len(&out)); | 1181 | buffer_len(&out)); |
1154 | buffer_free(&out); | 1182 | buffer_free(&out); |
1155 | debug3("%s: channel %d: hello sent", __func__, c->self); | 1183 | debug3("%s: channel %d: hello sent", __func__, c->self); |
@@ -1160,7 +1188,7 @@ mux_master_read_cb(Channel *c) | |||
1160 | buffer_init(&out); | 1188 | buffer_init(&out); |
1161 | 1189 | ||
1162 | /* Channel code ensures that we receive whole packets */ | 1190 | /* Channel code ensures that we receive whole packets */ |
1163 | if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { | 1191 | if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) { |
1164 | malf: | 1192 | malf: |
1165 | error("%s: malformed message", __func__); | 1193 | error("%s: malformed message", __func__); |
1166 | goto out; | 1194 | goto out; |
@@ -1186,7 +1214,8 @@ mux_master_read_cb(Channel *c) | |||
1186 | 1214 | ||
1187 | for (i = 0; mux_master_handlers[i].handler != NULL; i++) { | 1215 | for (i = 0; mux_master_handlers[i].handler != NULL; i++) { |
1188 | if (type == mux_master_handlers[i].type) { | 1216 | if (type == mux_master_handlers[i].type) { |
1189 | ret = mux_master_handlers[i].handler(rid, c, &in, &out); | 1217 | ret = mux_master_handlers[i].handler(ssh, rid, |
1218 | c, &in, &out); | ||
1190 | break; | 1219 | break; |
1191 | } | 1220 | } |
1192 | } | 1221 | } |
@@ -1199,7 +1228,7 @@ mux_master_read_cb(Channel *c) | |||
1199 | } | 1228 | } |
1200 | /* Enqueue reply packet */ | 1229 | /* Enqueue reply packet */ |
1201 | if (buffer_len(&out) != 0) { | 1230 | if (buffer_len(&out) != 0) { |
1202 | buffer_put_string(&c->output, buffer_ptr(&out), | 1231 | buffer_put_string(c->output, buffer_ptr(&out), |
1203 | buffer_len(&out)); | 1232 | buffer_len(&out)); |
1204 | } | 1233 | } |
1205 | out: | 1234 | out: |
@@ -1209,7 +1238,7 @@ mux_master_read_cb(Channel *c) | |||
1209 | } | 1238 | } |
1210 | 1239 | ||
1211 | void | 1240 | void |
1212 | mux_exit_message(Channel *c, int exitval) | 1241 | mux_exit_message(struct ssh *ssh, Channel *c, int exitval) |
1213 | { | 1242 | { |
1214 | Buffer m; | 1243 | Buffer m; |
1215 | Channel *mux_chan; | 1244 | Channel *mux_chan; |
@@ -1217,7 +1246,7 @@ mux_exit_message(Channel *c, int exitval) | |||
1217 | debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, | 1246 | debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, |
1218 | exitval); | 1247 | exitval); |
1219 | 1248 | ||
1220 | if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) | 1249 | if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1221 | fatal("%s: channel %d missing mux channel %d", | 1250 | fatal("%s: channel %d missing mux channel %d", |
1222 | __func__, c->self, c->ctl_chan); | 1251 | __func__, c->self, c->ctl_chan); |
1223 | 1252 | ||
@@ -1227,19 +1256,19 @@ mux_exit_message(Channel *c, int exitval) | |||
1227 | buffer_put_int(&m, c->self); | 1256 | buffer_put_int(&m, c->self); |
1228 | buffer_put_int(&m, exitval); | 1257 | buffer_put_int(&m, exitval); |
1229 | 1258 | ||
1230 | buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); | 1259 | buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); |
1231 | buffer_free(&m); | 1260 | buffer_free(&m); |
1232 | } | 1261 | } |
1233 | 1262 | ||
1234 | void | 1263 | void |
1235 | mux_tty_alloc_failed(Channel *c) | 1264 | mux_tty_alloc_failed(struct ssh *ssh, Channel *c) |
1236 | { | 1265 | { |
1237 | Buffer m; | 1266 | Buffer m; |
1238 | Channel *mux_chan; | 1267 | Channel *mux_chan; |
1239 | 1268 | ||
1240 | debug3("%s: channel %d: TTY alloc failed", __func__, c->self); | 1269 | debug3("%s: channel %d: TTY alloc failed", __func__, c->self); |
1241 | 1270 | ||
1242 | if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) | 1271 | if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1243 | fatal("%s: channel %d missing mux channel %d", | 1272 | fatal("%s: channel %d missing mux channel %d", |
1244 | __func__, c->self, c->ctl_chan); | 1273 | __func__, c->self, c->ctl_chan); |
1245 | 1274 | ||
@@ -1248,13 +1277,13 @@ mux_tty_alloc_failed(Channel *c) | |||
1248 | buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); | 1277 | buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); |
1249 | buffer_put_int(&m, c->self); | 1278 | buffer_put_int(&m, c->self); |
1250 | 1279 | ||
1251 | buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); | 1280 | buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m)); |
1252 | buffer_free(&m); | 1281 | buffer_free(&m); |
1253 | } | 1282 | } |
1254 | 1283 | ||
1255 | /* Prepare a mux master to listen on a Unix domain socket. */ | 1284 | /* Prepare a mux master to listen on a Unix domain socket. */ |
1256 | void | 1285 | void |
1257 | muxserver_listen(void) | 1286 | muxserver_listen(struct ssh *ssh) |
1258 | { | 1287 | { |
1259 | mode_t old_umask; | 1288 | mode_t old_umask; |
1260 | char *orig_control_path = options.control_path; | 1289 | char *orig_control_path = options.control_path; |
@@ -1327,7 +1356,7 @@ muxserver_listen(void) | |||
1327 | 1356 | ||
1328 | set_nonblock(muxserver_sock); | 1357 | set_nonblock(muxserver_sock); |
1329 | 1358 | ||
1330 | mux_listener_channel = channel_new("mux listener", | 1359 | mux_listener_channel = channel_new(ssh, "mux listener", |
1331 | SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, | 1360 | SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, |
1332 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, | 1361 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
1333 | 0, options.control_path, 1); | 1362 | 0, options.control_path, 1); |
@@ -1338,7 +1367,7 @@ muxserver_listen(void) | |||
1338 | 1367 | ||
1339 | /* Callback on open confirmation in mux master for a mux client session. */ | 1368 | /* Callback on open confirmation in mux master for a mux client session. */ |
1340 | static void | 1369 | static void |
1341 | mux_session_confirm(int id, int success, void *arg) | 1370 | mux_session_confirm(struct ssh *ssh, int id, int success, void *arg) |
1342 | { | 1371 | { |
1343 | struct mux_session_confirm_ctx *cctx = arg; | 1372 | struct mux_session_confirm_ctx *cctx = arg; |
1344 | const char *display; | 1373 | const char *display; |
@@ -1348,9 +1377,9 @@ mux_session_confirm(int id, int success, void *arg) | |||
1348 | 1377 | ||
1349 | if (cctx == NULL) | 1378 | if (cctx == NULL) |
1350 | fatal("%s: cctx == NULL", __func__); | 1379 | fatal("%s: cctx == NULL", __func__); |
1351 | if ((c = channel_by_id(id)) == NULL) | 1380 | if ((c = channel_by_id(ssh, id)) == NULL) |
1352 | fatal("%s: no channel for id %d", __func__, id); | 1381 | fatal("%s: no channel for id %d", __func__, id); |
1353 | if ((cc = channel_by_id(c->ctl_chan)) == NULL) | 1382 | if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL) |
1354 | fatal("%s: channel %d lacks control channel %d", __func__, | 1383 | fatal("%s: channel %d lacks control channel %d", __func__, |
1355 | id, c->ctl_chan); | 1384 | id, c->ctl_chan); |
1356 | 1385 | ||
@@ -1369,27 +1398,27 @@ mux_session_confirm(int id, int success, void *arg) | |||
1369 | char *proto, *data; | 1398 | char *proto, *data; |
1370 | 1399 | ||
1371 | /* Get reasonable local authentication information. */ | 1400 | /* Get reasonable local authentication information. */ |
1372 | if (client_x11_get_proto(display, options.xauth_location, | 1401 | if (client_x11_get_proto(ssh, display, options.xauth_location, |
1373 | options.forward_x11_trusted, options.forward_x11_timeout, | 1402 | options.forward_x11_trusted, options.forward_x11_timeout, |
1374 | &proto, &data) == 0) { | 1403 | &proto, &data) == 0) { |
1375 | /* Request forwarding with authentication spoofing. */ | 1404 | /* Request forwarding with authentication spoofing. */ |
1376 | debug("Requesting X11 forwarding with authentication " | 1405 | debug("Requesting X11 forwarding with authentication " |
1377 | "spoofing."); | 1406 | "spoofing."); |
1378 | x11_request_forwarding_with_spoofing(id, display, proto, | 1407 | x11_request_forwarding_with_spoofing(ssh, id, |
1379 | data, 1); | 1408 | display, proto, data, 1); |
1380 | /* XXX exit_on_forward_failure */ | 1409 | /* XXX exit_on_forward_failure */ |
1381 | client_expect_confirm(id, "X11 forwarding", | 1410 | client_expect_confirm(ssh, id, "X11 forwarding", |
1382 | CONFIRM_WARN); | 1411 | CONFIRM_WARN); |
1383 | } | 1412 | } |
1384 | } | 1413 | } |
1385 | 1414 | ||
1386 | if (cctx->want_agent_fwd && options.forward_agent) { | 1415 | if (cctx->want_agent_fwd && options.forward_agent) { |
1387 | debug("Requesting authentication agent forwarding."); | 1416 | debug("Requesting authentication agent forwarding."); |
1388 | channel_request_start(id, "auth-agent-req@openssh.com", 0); | 1417 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); |
1389 | packet_send(); | 1418 | packet_send(); |
1390 | } | 1419 | } |
1391 | 1420 | ||
1392 | client_session2_setup(id, cctx->want_tty, cctx->want_subsys, | 1421 | client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, |
1393 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); | 1422 | cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); |
1394 | 1423 | ||
1395 | debug3("%s: sending success reply", __func__); | 1424 | debug3("%s: sending success reply", __func__); |
@@ -1401,7 +1430,7 @@ mux_session_confirm(int id, int success, void *arg) | |||
1401 | 1430 | ||
1402 | done: | 1431 | done: |
1403 | /* Send reply */ | 1432 | /* Send reply */ |
1404 | buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); | 1433 | buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply)); |
1405 | buffer_free(&reply); | 1434 | buffer_free(&reply); |
1406 | 1435 | ||
1407 | if (cc->mux_pause <= 0) | 1436 | if (cc->mux_pause <= 0) |
@@ -1570,31 +1599,38 @@ mux_client_hello_exchange(int fd) | |||
1570 | { | 1599 | { |
1571 | Buffer m; | 1600 | Buffer m; |
1572 | u_int type, ver; | 1601 | u_int type, ver; |
1602 | int ret = -1; | ||
1573 | 1603 | ||
1574 | buffer_init(&m); | 1604 | buffer_init(&m); |
1575 | buffer_put_int(&m, MUX_MSG_HELLO); | 1605 | buffer_put_int(&m, MUX_MSG_HELLO); |
1576 | buffer_put_int(&m, SSHMUX_VER); | 1606 | buffer_put_int(&m, SSHMUX_VER); |
1577 | /* no extensions */ | 1607 | /* no extensions */ |
1578 | 1608 | ||
1579 | if (mux_client_write_packet(fd, &m) != 0) | 1609 | if (mux_client_write_packet(fd, &m) != 0) { |
1580 | fatal("%s: write packet: %s", __func__, strerror(errno)); | 1610 | debug("%s: write packet: %s", __func__, strerror(errno)); |
1611 | goto out; | ||
1612 | } | ||
1581 | 1613 | ||
1582 | buffer_clear(&m); | 1614 | buffer_clear(&m); |
1583 | 1615 | ||
1584 | /* Read their HELLO */ | 1616 | /* Read their HELLO */ |
1585 | if (mux_client_read_packet(fd, &m) != 0) { | 1617 | if (mux_client_read_packet(fd, &m) != 0) { |
1586 | buffer_free(&m); | 1618 | debug("%s: read packet failed", __func__); |
1587 | return -1; | 1619 | goto out; |
1588 | } | 1620 | } |
1589 | 1621 | ||
1590 | type = buffer_get_int(&m); | 1622 | type = buffer_get_int(&m); |
1591 | if (type != MUX_MSG_HELLO) | 1623 | if (type != MUX_MSG_HELLO) { |
1592 | fatal("%s: expected HELLO (%u) received %u", | 1624 | error("%s: expected HELLO (%u) received %u", |
1593 | __func__, MUX_MSG_HELLO, type); | 1625 | __func__, MUX_MSG_HELLO, type); |
1626 | goto out; | ||
1627 | } | ||
1594 | ver = buffer_get_int(&m); | 1628 | ver = buffer_get_int(&m); |
1595 | if (ver != SSHMUX_VER) | 1629 | if (ver != SSHMUX_VER) { |
1596 | fatal("Unsupported multiplexing protocol version %d " | 1630 | error("Unsupported multiplexing protocol version %d " |
1597 | "(expected %d)", ver, SSHMUX_VER); | 1631 | "(expected %d)", ver, SSHMUX_VER); |
1632 | goto out; | ||
1633 | } | ||
1598 | debug2("%s: master version %u", __func__, ver); | 1634 | debug2("%s: master version %u", __func__, ver); |
1599 | /* No extensions are presently defined */ | 1635 | /* No extensions are presently defined */ |
1600 | while (buffer_len(&m) > 0) { | 1636 | while (buffer_len(&m) > 0) { |
@@ -1605,8 +1641,11 @@ mux_client_hello_exchange(int fd) | |||
1605 | free(name); | 1641 | free(name); |
1606 | free(value); | 1642 | free(value); |
1607 | } | 1643 | } |
1644 | /* success */ | ||
1645 | ret = 0; | ||
1646 | out: | ||
1608 | buffer_free(&m); | 1647 | buffer_free(&m); |
1609 | return 0; | 1648 | return ret; |
1610 | } | 1649 | } |
1611 | 1650 | ||
1612 | static u_int | 1651 | static u_int |
@@ -1962,7 +2001,7 @@ mux_client_request_session(int fd) | |||
1962 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 2001 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1963 | 2002 | ||
1964 | if (muxclient_terminate) { | 2003 | if (muxclient_terminate) { |
1965 | debug2("Exiting on signal %d", muxclient_terminate); | 2004 | debug2("Exiting on signal: %s", strsignal(muxclient_terminate)); |
1966 | exitval = 255; | 2005 | exitval = 255; |
1967 | } else if (!exitval_seen) { | 2006 | } else if (!exitval_seen) { |
1968 | debug2("Control master terminated unexpectedly"); | 2007 | debug2("Control master terminated unexpectedly"); |