diff options
author | Damien Miller <djm@mindrot.org> | 2010-05-21 14:57:35 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-05-21 14:57:35 +1000 |
commit | 388f6fc48561851dcedd5433aff75f60af573fb2 (patch) | |
tree | 4ac7be863c3ba9be98df80c6d66953608cd77a6c | |
parent | d530f5f471491b6be9edb58a063f2590e4dce48d (diff) |
- markus@cvs.openbsd.org 2010/05/16 12:55:51
[PROTOCOL.mux clientloop.h mux.c readconf.c readconf.h ssh.1 ssh.c]
mux support for remote forwarding with dynamic port allocation,
use with
LPORT=`ssh -S muxsocket -R0:localhost:25 -O forward somehost`
feedback and ok djm@
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | PROTOCOL.mux | 13 | ||||
-rw-r--r-- | clientloop.h | 3 | ||||
-rw-r--r-- | mux.c | 113 | ||||
-rw-r--r-- | readconf.c | 3 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | ssh.1 | 11 | ||||
-rw-r--r-- | ssh.c | 9 |
8 files changed, 141 insertions, 20 deletions
@@ -23,6 +23,12 @@ | |||
23 | the server. | 23 | the server. |
24 | 24 | ||
25 | motivated by and with feedback from markus@ | 25 | motivated by and with feedback from markus@ |
26 | - markus@cvs.openbsd.org 2010/05/16 12:55:51 | ||
27 | [PROTOCOL.mux clientloop.h mux.c readconf.c readconf.h ssh.1 ssh.c] | ||
28 | mux support for remote forwarding with dynamic port allocation, | ||
29 | use with | ||
30 | LPORT=`ssh -S muxsocket -R0:localhost:25 -O forward somehost` | ||
31 | feedback and ok djm@ | ||
26 | 32 | ||
27 | 20100511 | 33 | 20100511 |
28 | - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve | 34 | - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve |
diff --git a/PROTOCOL.mux b/PROTOCOL.mux index d22f7379c..1d8c463a7 100644 --- a/PROTOCOL.mux +++ b/PROTOCOL.mux | |||
@@ -109,8 +109,14 @@ A client may request the master to establish a port forward: | |||
109 | 109 | ||
110 | forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. | 110 | forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. |
111 | 111 | ||
112 | A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a | 112 | A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a |
113 | MUX_S_FAILURE. | 113 | MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. |
114 | |||
115 | For dynamically allocated listen port the server replies with | ||
116 | |||
117 | uint32 MUX_S_REMOTE_PORT | ||
118 | uint32 client request id | ||
119 | uint32 allocated remote listen port | ||
114 | 120 | ||
115 | 5. Requesting closure of port forwards | 121 | 5. Requesting closure of port forwards |
116 | 122 | ||
@@ -178,6 +184,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: | |||
178 | #define MUX_S_EXIT_MESSAGE 0x80000004 | 184 | #define MUX_S_EXIT_MESSAGE 0x80000004 |
179 | #define MUX_S_ALIVE 0x80000005 | 185 | #define MUX_S_ALIVE 0x80000005 |
180 | #define MUX_S_SESSION_OPENED 0x80000006 | 186 | #define MUX_S_SESSION_OPENED 0x80000006 |
187 | #define MUX_S_REMOTE_PORT 0x80000007 | ||
181 | 188 | ||
182 | #define MUX_FWD_LOCAL 1 | 189 | #define MUX_FWD_LOCAL 1 |
183 | #define MUX_FWD_REMOTE 2 | 190 | #define MUX_FWD_REMOTE 2 |
@@ -193,4 +200,4 @@ XXX server->client error/warning notifications | |||
193 | XXX port0 rfwd (need custom response message) | 200 | XXX port0 rfwd (need custom response message) |
194 | XXX send signals via mux | 201 | XXX send signals via mux |
195 | 202 | ||
196 | $OpenBSD: PROTOCOL.mux,v 1.1 2010/01/26 01:28:35 djm Exp $ | 203 | $OpenBSD: PROTOCOL.mux,v 1.2 2010/05/16 12:55:51 markus Exp $ |
diff --git a/clientloop.h b/clientloop.h index 0b8257b99..a5bc246a3 100644 --- a/clientloop.h +++ b/clientloop.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.h,v 1.23 2010/01/26 01:28:35 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.h,v 1.24 2010/05/16 12:55:51 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -63,6 +63,7 @@ void client_register_global_confirm(global_confirm_cb *, void *); | |||
63 | #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ | 63 | #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ |
64 | #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ | 64 | #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ |
65 | #define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */ | 65 | #define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */ |
66 | #define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */ | ||
66 | 67 | ||
67 | void muxserver_listen(void); | 68 | void muxserver_listen(void); |
68 | void muxclient(const char *); | 69 | void muxclient(const char *); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.17 2010/05/14 23:29:23 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.18 2010/05/16 12:55:51 markus 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 | * |
@@ -71,6 +71,7 @@ | |||
71 | #include "xmalloc.h" | 71 | #include "xmalloc.h" |
72 | #include "log.h" | 72 | #include "log.h" |
73 | #include "ssh.h" | 73 | #include "ssh.h" |
74 | #include "ssh2.h" | ||
74 | #include "pathnames.h" | 75 | #include "pathnames.h" |
75 | #include "misc.h" | 76 | #include "misc.h" |
76 | #include "match.h" | 77 | #include "match.h" |
@@ -109,6 +110,13 @@ struct mux_session_confirm_ctx { | |||
109 | u_int rid; | 110 | u_int rid; |
110 | }; | 111 | }; |
111 | 112 | ||
113 | /* Context for global channel callback */ | ||
114 | struct mux_channel_confirm_ctx { | ||
115 | u_int cid; /* channel id */ | ||
116 | u_int rid; /* request id */ | ||
117 | int fid; /* forward id */ | ||
118 | }; | ||
119 | |||
112 | /* fd to control socket */ | 120 | /* fd to control socket */ |
113 | int muxserver_sock = -1; | 121 | int muxserver_sock = -1; |
114 | 122 | ||
@@ -144,6 +152,7 @@ struct mux_master_state { | |||
144 | #define MUX_S_EXIT_MESSAGE 0x80000004 | 152 | #define MUX_S_EXIT_MESSAGE 0x80000004 |
145 | #define MUX_S_ALIVE 0x80000005 | 153 | #define MUX_S_ALIVE 0x80000005 |
146 | #define MUX_S_SESSION_OPENED 0x80000006 | 154 | #define MUX_S_SESSION_OPENED 0x80000006 |
155 | #define MUX_S_REMOTE_PORT 0x80000007 | ||
147 | 156 | ||
148 | /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ | 157 | /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ |
149 | #define MUX_FWD_LOCAL 1 | 158 | #define MUX_FWD_LOCAL 1 |
@@ -557,6 +566,61 @@ compare_forward(Forward *a, Forward *b) | |||
557 | return 1; | 566 | return 1; |
558 | } | 567 | } |
559 | 568 | ||
569 | static void | ||
570 | mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | ||
571 | { | ||
572 | struct mux_channel_confirm_ctx *fctx = ctxt; | ||
573 | char *failmsg = NULL; | ||
574 | Forward *rfwd; | ||
575 | Channel *c; | ||
576 | Buffer out; | ||
577 | |||
578 | if ((c = channel_by_id(fctx->cid)) == NULL) { | ||
579 | /* no channel for reply */ | ||
580 | error("%s: unknown channel", __func__); | ||
581 | return; | ||
582 | } | ||
583 | buffer_init(&out); | ||
584 | if (fctx->fid >= options.num_remote_forwards) { | ||
585 | xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid); | ||
586 | goto fail; | ||
587 | } | ||
588 | rfwd = &options.remote_forwards[fctx->fid]; | ||
589 | debug("%s: %s for: listen %d, connect %s:%d", __func__, | ||
590 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | ||
591 | rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); | ||
592 | if (type == SSH2_MSG_REQUEST_SUCCESS) { | ||
593 | if (rfwd->listen_port == 0) { | ||
594 | rfwd->allocated_port = packet_get_int(); | ||
595 | logit("Allocated port %u for mux remote forward" | ||
596 | " to %s:%d", rfwd->allocated_port, | ||
597 | rfwd->connect_host, rfwd->connect_port); | ||
598 | buffer_put_int(&out, MUX_S_REMOTE_PORT); | ||
599 | buffer_put_int(&out, fctx->rid); | ||
600 | buffer_put_int(&out, rfwd->allocated_port); | ||
601 | } else { | ||
602 | buffer_put_int(&out, MUX_S_OK); | ||
603 | buffer_put_int(&out, fctx->rid); | ||
604 | } | ||
605 | goto out; | ||
606 | } else { | ||
607 | xasprintf(&failmsg, "remote port forwarding failed for " | ||
608 | "listen port %d", rfwd->listen_port); | ||
609 | } | ||
610 | fail: | ||
611 | error("%s: %s", __func__, failmsg); | ||
612 | buffer_put_int(&out, MUX_S_FAILURE); | ||
613 | buffer_put_int(&out, fctx->rid); | ||
614 | buffer_put_cstring(&out, failmsg); | ||
615 | xfree(failmsg); | ||
616 | out: | ||
617 | buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); | ||
618 | buffer_free(&out); | ||
619 | if (c->mux_pause <= 0) | ||
620 | fatal("%s: mux_pause %d", __func__, c->mux_pause); | ||
621 | c->mux_pause = 0; /* start processing messages again */ | ||
622 | } | ||
623 | |||
560 | static int | 624 | static int |
561 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 625 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) |
562 | { | 626 | { |
@@ -592,15 +656,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
592 | ftype != MUX_FWD_DYNAMIC) { | 656 | ftype != MUX_FWD_DYNAMIC) { |
593 | logit("%s: invalid forwarding type %u", __func__, ftype); | 657 | logit("%s: invalid forwarding type %u", __func__, ftype); |
594 | invalid: | 658 | invalid: |
595 | xfree(fwd.listen_host); | 659 | if (fwd.listen_host) |
596 | xfree(fwd.connect_host); | 660 | xfree(fwd.listen_host); |
661 | if (fwd.connect_host) | ||
662 | xfree(fwd.connect_host); | ||
597 | buffer_put_int(r, MUX_S_FAILURE); | 663 | buffer_put_int(r, MUX_S_FAILURE); |
598 | buffer_put_int(r, rid); | 664 | buffer_put_int(r, rid); |
599 | buffer_put_cstring(r, "Invalid forwarding request"); | 665 | buffer_put_cstring(r, "Invalid forwarding request"); |
600 | return 0; | 666 | return 0; |
601 | } | 667 | } |
602 | /* XXX support rport0 forwarding with reply of port assigned */ | 668 | if (fwd.listen_port >= 65536) { |
603 | if (fwd.listen_port == 0 || fwd.listen_port >= 65536) { | ||
604 | logit("%s: invalid listen port %u", __func__, | 669 | logit("%s: invalid listen port %u", __func__, |
605 | fwd.listen_port); | 670 | fwd.listen_port); |
606 | goto invalid; | 671 | goto invalid; |
@@ -635,8 +700,17 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
635 | case MUX_FWD_REMOTE: | 700 | case MUX_FWD_REMOTE: |
636 | for (i = 0; i < options.num_remote_forwards; i++) { | 701 | for (i = 0; i < options.num_remote_forwards; i++) { |
637 | if (compare_forward(&fwd, | 702 | if (compare_forward(&fwd, |
638 | options.remote_forwards + i)) | 703 | options.remote_forwards + i)) { |
639 | goto exists; | 704 | if (fwd.listen_port != 0) |
705 | goto exists; | ||
706 | debug2("%s: found allocated port", | ||
707 | __func__); | ||
708 | buffer_put_int(r, MUX_S_REMOTE_PORT); | ||
709 | buffer_put_int(r, rid); | ||
710 | buffer_put_int(r, | ||
711 | options.remote_forwards[i].allocated_port); | ||
712 | goto out; | ||
713 | } | ||
640 | } | 714 | } |
641 | break; | 715 | break; |
642 | } | 716 | } |
@@ -668,14 +742,24 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
668 | add_local_forward(&options, &fwd); | 742 | add_local_forward(&options, &fwd); |
669 | freefwd = 0; | 743 | freefwd = 0; |
670 | } else { | 744 | } else { |
671 | /* XXX wait for remote to confirm */ | 745 | struct mux_channel_confirm_ctx *fctx; |
746 | |||
672 | if (options.num_remote_forwards + 1 >= | 747 | if (options.num_remote_forwards + 1 >= |
673 | SSH_MAX_FORWARDS_PER_DIRECTION || | 748 | SSH_MAX_FORWARDS_PER_DIRECTION || |
674 | channel_request_remote_forwarding(fwd.listen_host, | 749 | channel_request_remote_forwarding(fwd.listen_host, |
675 | fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) | 750 | fwd.listen_port, fwd.connect_host, fwd.connect_port) < 0) |
676 | goto fail; | 751 | goto fail; |
677 | add_remote_forward(&options, &fwd); | 752 | add_remote_forward(&options, &fwd); |
753 | fctx = xcalloc(1, sizeof(*fctx)); | ||
754 | fctx->cid = c->self; | ||
755 | fctx->rid = rid; | ||
756 | fctx->fid = options.num_remote_forwards-1; | ||
757 | client_register_global_confirm(mux_confirm_remote_forward, | ||
758 | fctx); | ||
678 | freefwd = 0; | 759 | freefwd = 0; |
760 | c->mux_pause = 1; /* wait for mux_confirm_remote_forward */ | ||
761 | /* delayed reply in mux_confirm_remote_forward */ | ||
762 | goto out; | ||
679 | } | 763 | } |
680 | buffer_put_int(r, MUX_S_OK); | 764 | buffer_put_int(r, MUX_S_OK); |
681 | buffer_put_int(r, rid); | 765 | buffer_put_int(r, rid); |
@@ -1392,6 +1476,15 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd) | |||
1392 | switch (type) { | 1476 | switch (type) { |
1393 | case MUX_S_OK: | 1477 | case MUX_S_OK: |
1394 | break; | 1478 | break; |
1479 | case MUX_S_REMOTE_PORT: | ||
1480 | fwd->allocated_port = buffer_get_int(&m); | ||
1481 | logit("Allocated port %u for remote forward to %s:%d", | ||
1482 | fwd->allocated_port, | ||
1483 | fwd->connect_host ? fwd->connect_host : "", | ||
1484 | fwd->connect_port); | ||
1485 | if (muxclient_command == SSHMUX_COMMAND_FORWARD) | ||
1486 | fprintf(stdout, "%u\n", fwd->allocated_port); | ||
1487 | break; | ||
1395 | case MUX_S_PERMISSION_DENIED: | 1488 | case MUX_S_PERMISSION_DENIED: |
1396 | e = buffer_get_string(&m, NULL); | 1489 | e = buffer_get_string(&m, NULL); |
1397 | buffer_free(&m); | 1490 | buffer_free(&m); |
@@ -1758,6 +1851,10 @@ muxclient(const char *path) | |||
1758 | mux_client_request_terminate(sock); | 1851 | mux_client_request_terminate(sock); |
1759 | fprintf(stderr, "Exit request sent.\r\n"); | 1852 | fprintf(stderr, "Exit request sent.\r\n"); |
1760 | exit(0); | 1853 | exit(0); |
1854 | case SSHMUX_COMMAND_FORWARD: | ||
1855 | if (mux_client_request_forwards(sock) != 0) | ||
1856 | fatal("%s: master forward request failed", __func__); | ||
1857 | exit(0); | ||
1761 | case SSHMUX_COMMAND_OPEN: | 1858 | case SSHMUX_COMMAND_OPEN: |
1762 | if (mux_client_request_forwards(sock) != 0) { | 1859 | if (mux_client_request_forwards(sock) != 0) { |
1763 | error("%s: master forward request failed", __func__); | 1860 | error("%s: master forward request failed", __func__); |
diff --git a/readconf.c b/readconf.c index 8bdc8caf1..4bc98b77e 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.184 2010/05/16 12:55:51 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -283,6 +283,7 @@ add_remote_forward(Options *options, const Forward *newfwd) | |||
283 | fwd->listen_port = newfwd->listen_port; | 283 | fwd->listen_port = newfwd->listen_port; |
284 | fwd->connect_host = newfwd->connect_host; | 284 | fwd->connect_host = newfwd->connect_host; |
285 | fwd->connect_port = newfwd->connect_port; | 285 | fwd->connect_port = newfwd->connect_port; |
286 | fwd->allocated_port = 0; | ||
286 | } | 287 | } |
287 | 288 | ||
288 | static void | 289 | static void |
diff --git a/readconf.h b/readconf.h index 4264751c5..4fb29e2fa 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.82 2010/02/08 10:50:20 markus Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.83 2010/05/16 12:55:51 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -23,6 +23,7 @@ typedef struct { | |||
23 | int listen_port; /* Port to forward. */ | 23 | int listen_port; /* Port to forward. */ |
24 | char *connect_host; /* Host to connect. */ | 24 | char *connect_host; /* Host to connect. */ |
25 | int connect_port; /* Port to connect on connect_host. */ | 25 | int connect_port; /* Port to connect on connect_host. */ |
26 | int allocated_port; /* Dynamically allocated listen port */ | ||
26 | } Forward; | 27 | } Forward; |
27 | /* Data structure for representing option data. */ | 28 | /* Data structure for representing option data. */ |
28 | 29 | ||
@@ -34,8 +34,8 @@ | |||
34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 34 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | .\" | 36 | .\" |
37 | .\" $OpenBSD: ssh.1,v 1.304 2010/03/26 06:54:36 jmc Exp $ | 37 | .\" $OpenBSD: ssh.1,v 1.305 2010/05/16 12:55:51 markus Exp $ |
38 | .Dd $Mdocdate: March 26 2010 $ | 38 | .Dd $Mdocdate: May 16 2010 $ |
39 | .Dt SSH 1 | 39 | .Dt SSH 1 |
40 | .Os | 40 | .Os |
41 | .Sh NAME | 41 | .Sh NAME |
@@ -421,7 +421,9 @@ option is specified, the | |||
421 | argument is interpreted and passed to the master process. | 421 | argument is interpreted and passed to the master process. |
422 | Valid commands are: | 422 | Valid commands are: |
423 | .Dq check | 423 | .Dq check |
424 | (check that the master process is running) and | 424 | (check that the master process is running), |
425 | .Dq forward | ||
426 | (request forwardings without command execution) and | ||
425 | .Dq exit | 427 | .Dq exit |
426 | (request the master to exit). | 428 | (request the master to exit). |
427 | .It Fl o Ar option | 429 | .It Fl o Ar option |
@@ -557,6 +559,9 @@ argument is | |||
557 | .Ql 0 , | 559 | .Ql 0 , |
558 | the listen port will be dynamically allocated on the server and reported | 560 | the listen port will be dynamically allocated on the server and reported |
559 | to the client at run time. | 561 | to the client at run time. |
562 | When used together with | ||
563 | .Ic -O forward | ||
564 | the allocated port will be printed to the standard output. | ||
560 | .It Fl S Ar ctl_path | 565 | .It Fl S Ar ctl_path |
561 | Specifies the location of a control socket for connection sharing, | 566 | Specifies the location of a control socket for connection sharing, |
562 | or the string | 567 | or the string |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.337 2010/05/14 23:29:23 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.338 2010/05/16 12:55:51 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -327,6 +327,8 @@ main(int ac, char **av) | |||
327 | fatal("Multiplexing command already specified"); | 327 | fatal("Multiplexing command already specified"); |
328 | if (strcmp(optarg, "check") == 0) | 328 | if (strcmp(optarg, "check") == 0) |
329 | muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; | 329 | muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; |
330 | else if (strcmp(optarg, "forward") == 0) | ||
331 | muxclient_command = SSHMUX_COMMAND_FORWARD; | ||
330 | else if (strcmp(optarg, "exit") == 0) | 332 | else if (strcmp(optarg, "exit") == 0) |
331 | muxclient_command = SSHMUX_COMMAND_TERMINATE; | 333 | muxclient_command = SSHMUX_COMMAND_TERMINATE; |
332 | else | 334 | else |
@@ -877,9 +879,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
877 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | 879 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", |
878 | rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); | 880 | rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); |
879 | if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { | 881 | if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { |
882 | rfwd->allocated_port = packet_get_int(); | ||
880 | logit("Allocated port %u for remote forward to %s:%d", | 883 | logit("Allocated port %u for remote forward to %s:%d", |
881 | packet_get_int(), | 884 | rfwd->allocated_port, |
882 | rfwd->connect_host, rfwd->connect_port); | 885 | rfwd->connect_host, rfwd->connect_port); |
883 | } | 886 | } |
884 | 887 | ||
885 | if (type == SSH2_MSG_REQUEST_FAILURE) { | 888 | if (type == SSH2_MSG_REQUEST_FAILURE) { |