From 27a8f6b05636648367ea373d77d129327eb515a9 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 29 Aug 2004 16:31:28 +1000 Subject: - dtucker@cvs.openbsd.org 2004/08/23 14:26:38 [ssh-keysign.c ssh.c] Use permanently_set_uid() in ssh and ssh-keysign for consistency, matches change in Portable; ok markus@ (CVS ID sync only) --- ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ssh.c') diff --git a/ssh.c b/ssh.c index 1419f9874..e69d73807 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.224 2004/07/28 09:40:29 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.225 2004/08/23 14:26:38 dtucker Exp $"); #include #include -- cgit v1.2.3 From 2aa6d3cfce738f57c31ae676e11399382bd5660e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 12 Sep 2004 16:53:04 +1000 Subject: - (djm) [ssh.c sshd.c version.h] Don't divulge portable version in protocol banner. Suggested by deraadt@, ok mouring@, dtucker@ --- ChangeLog | 4 +++- ssh.c | 2 +- sshd.c | 4 ++-- version.h | 5 ++++- 4 files changed, 10 insertions(+), 5 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index e1cf4153f..714591df6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ No change in resultant binary - (djm) [loginrec.c] __func__ifiy - (djm) [loginrec.c] xmalloc + - (djm) [ssh.c sshd.c version.h] Don't divulge portable version in protocol + banner. Suggested by deraadt@, ok mouring@, dtucker@ 20040911 - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ @@ -1740,4 +1742,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3550 2004/09/12 05:26:00 djm Exp $ +$Id: ChangeLog,v 1.3551 2004/09/12 06:53:04 djm Exp $ diff --git a/ssh.c b/ssh.c index e69d73807..6f0ba26ad 100644 --- a/ssh.c +++ b/ssh.c @@ -319,7 +319,7 @@ again: /* fallthrough */ case 'V': fprintf(stderr, "%s, %s\n", - SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); + SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); if (opt == 'V') exit(0); break; diff --git a/sshd.c b/sshd.c index 2a28ece03..4b2d10af9 100644 --- a/sshd.c +++ b/sshd.c @@ -774,7 +774,7 @@ static void usage(void) { fprintf(stderr, "%s, %s\n", - SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); + SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); fprintf(stderr, "usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" " [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" @@ -1081,7 +1081,7 @@ main(int ac, char **av) exit(1); } - debug("sshd version %.100s", SSH_VERSION); + debug("sshd version %.100s", SSH_RELEASE); /* load private host keys */ sensitive_data.host_keys = xmalloc(options.num_host_key_files * diff --git a/version.h b/version.h index aae2c3b37..d0c867b87 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,6 @@ /* $OpenBSD: version.h,v 1.42 2004/08/16 08:17:01 markus Exp $ */ -#define SSH_VERSION "OpenSSH_3.9p1" +#define SSH_VERSION "OpenSSH_3.9" + +#define SSH_PORTABLE "p1" +#define SSH_RELEASE SSH_VERSION SSH_PORTABLE -- cgit v1.2.3 From 07336dae9491062f32ca93ec3ccd4b17774bdd00 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 5 Nov 2004 20:02:16 +1100 Subject: - djm@cvs.openbsd.org 2004/09/07 23:41:30 [clientloop.c ssh.c] cleanup multiplex control socket on SIGHUP too, spotted by sturm@ ok markus@ deraadt@ --- ChangeLog | 6 +++++- clientloop.c | 4 +++- ssh.c | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 958724cc7..93a2d62b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ .Xsession -> .xsession; originally from a pr from f at obiit dot org, but missed by myself; ok markus@ matthieu@ + - djm@cvs.openbsd.org 2004/09/07 23:41:30 + [clientloop.c ssh.c] + cleanup multiplex control socket on SIGHUP too, spotted by sturm@ + ok markus@ deraadt@ 20041102 - (dtucker) [configure.ac includes.h] Bug #947: Fix compile error on HP-UX @@ -1787,4 +1791,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3564 2004/11/05 09:01:03 dtucker Exp $ +$Id: ChangeLog,v 1.3565 2004/11/05 09:02:16 dtucker Exp $ diff --git a/clientloop.c b/clientloop.c index 0b9a0fb29..49f9ba1ab 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.130 2004/08/11 21:43:04 avsm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.131 2004/09/07 23:41:30 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -1196,6 +1196,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) * Set signal handlers, (e.g. to restore non-blocking mode) * but don't overwrite SIG_IGN, matches behaviour from rsh(1) */ + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, signal_handler); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, signal_handler); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) diff --git a/ssh.c b/ssh.c index 6f0ba26ad..77f16c0c5 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.225 2004/08/23 14:26:38 dtucker Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.226 2004/09/07 23:41:30 djm Exp $"); #include #include @@ -1325,6 +1325,7 @@ control_client(const char *path) fatal("%s: master returned error", __func__); buffer_free(&m); + signal(SIGHUP, control_client_sighandler); signal(SIGINT, control_client_sighandler); signal(SIGTERM, control_client_sighandler); signal(SIGWINCH, control_client_sigrelay); -- cgit v1.2.3 From e9bf98412e41a9f18beb9c3e842d02259ddd8c67 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 5 Nov 2004 20:05:32 +1100 Subject: - deraadt@cvs.openbsd.org 2004/09/15 00:46:01 [ssh.c] /* fallthrough */ is something a programmer understands. But /* FALLTHROUGH */ is also understood by lint, so that is better. --- ChangeLog | 6 +++++- ssh.c | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 93a2d62b9..1363c37ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,10 @@ [clientloop.c ssh.c] cleanup multiplex control socket on SIGHUP too, spotted by sturm@ ok markus@ deraadt@ + - deraadt@cvs.openbsd.org 2004/09/15 00:46:01 + [ssh.c] + /* fallthrough */ is something a programmer understands. But + /* FALLTHROUGH */ is also understood by lint, so that is better. 20041102 - (dtucker) [configure.ac includes.h] Bug #947: Fix compile error on HP-UX @@ -1791,4 +1795,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3565 2004/11/05 09:02:16 dtucker Exp $ +$Id: ChangeLog,v 1.3566 2004/11/05 09:05:32 dtucker Exp $ diff --git a/ssh.c b/ssh.c index 77f16c0c5..7859b0f78 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.226 2004/09/07 23:41:30 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.227 2004/09/15 00:46:01 deraadt Exp $"); #include #include @@ -316,7 +316,7 @@ again: options.log_level++; break; } - /* fallthrough */ + /* FALLTHROUGH */ case 'V': fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); -- cgit v1.2.3 From 39207a46b4b0d3d9c3ef8d03e9d3c6d5e11df9ec Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 5 Nov 2004 20:19:51 +1100 Subject: - djm@cvs.openbsd.org 2004/09/23 13:00:04 [ssh.c] correctly honour -n in multiplex client mode; spotted by sturm@ ok markus@ --- ChangeLog | 5 ++++- ssh.c | 13 +++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 188869c3d..17750e92c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,9 @@ - deraadt@cvs.openbsd.org 2004/09/15 18:46:04 [scp.c] scratch that do { } while (0) wrapper in this case + - djm@cvs.openbsd.org 2004/09/23 13:00:04 + [ssh.c] + correctly honour -n in multiplex client mode; spotted by sturm@ ok markus@ 20041102 - (dtucker) [configure.ac includes.h] Bug #947: Fix compile error on HP-UX @@ -1808,4 +1811,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3569 2004/11/05 09:10:02 dtucker Exp $ +$Id: ChangeLog,v 1.3570 2004/11/05 09:19:51 dtucker Exp $ diff --git a/ssh.c b/ssh.c index 7859b0f78..c231c5fae 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.227 2004/09/15 00:46:01 deraadt Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.228 2004/09/23 13:00:04 djm Exp $"); #include #include @@ -1249,11 +1249,20 @@ static void control_client(const char *path) { struct sockaddr_un addr; - int i, r, sock, exitval, num_env, addr_len; + int i, r, fd, sock, exitval, num_env, addr_len; Buffer m; char *cp; extern char **environ; + if (stdin_null_flag) { + if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) + fatal("open(/dev/null): %s", strerror(errno)); + if (dup2(fd, STDIN_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (fd > STDERR_FILENO) + close(fd); + } + memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; addr_len = offsetof(struct sockaddr_un, sun_path) + -- cgit v1.2.3 From 7ebfc10884da0e430966cb323f57de17397f64bc Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 7 Nov 2004 20:06:19 +1100 Subject: - djm@cvs.openbsd.org 2004/11/07 00:01:46 [clientloop.c clientloop.h ssh.1 ssh.c] add basic control of a running multiplex master connection; including the ability to check its status and request it to exit; ok markus@ --- ChangeLog | 6 ++++- clientloop.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++----------- clientloop.h | 10 ++++++- ssh.1 | 19 +++++++++++--- ssh.c | 66 ++++++++++++++++++++++++++++++++++++---------- 5 files changed, 153 insertions(+), 34 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 871187478..fe96f8d0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ [sftp.c] command editing and history support via libedit; ok markus@ thanks to hshoexer@ and many testers on tech@ too + - djm@cvs.openbsd.org 2004/11/07 00:01:46 + [clientloop.c clientloop.h ssh.1 ssh.c] + add basic control of a running multiplex master connection; including the + ability to check its status and request it to exit; ok markus@ 20041105 - (dtucker) OpenBSD CVS Sync @@ -1848,4 +1852,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3579 2004/11/07 09:04:10 dtucker Exp $ +$Id: ChangeLog,v 1.3580 2004/11/07 09:06:19 dtucker Exp $ diff --git a/clientloop.c b/clientloop.c index d77337b82..033a98a5b 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.133 2004/10/29 22:53:56 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -561,7 +561,7 @@ client_process_control(fd_set * readset) struct sockaddr_storage addr; struct confirm_ctx *cctx; char *cmd; - u_int len, env_len; + u_int len, env_len, command, flags; uid_t euid; gid_t egid; @@ -591,24 +591,74 @@ client_process_control(fd_set * readset) return; } - allowed = 1; - if (options.control_master == 2) - allowed = ask_permission("Allow shared connection to %s? ", - host); - unset_nonblock(client_fd); + /* Read command */ buffer_init(&m); + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + if ((ver = buffer_get_char(&m)) != 1) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return; + } + + allowed = 1; + command = buffer_get_int(&m); + flags = buffer_get_int(&m); + + buffer_clear(&m); + switch (command) { + case SSHMUX_COMMAND_OPEN: + if (options.control_master == 2) + allowed = ask_permission("Allow shared connection " + "to %s? ", host); + /* continue below */ + break; + case SSHMUX_COMMAND_TERMINATE: + if (options.control_master == 2) + allowed = ask_permission("Terminate shared connection " + "to %s? ", host); + if (allowed) + quit_pending = 1; + /* FALLTHROUGH */ + case SSHMUX_COMMAND_ALIVE_CHECK: + /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ + buffer_clear(&m); + buffer_put_int(&m, allowed); + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + buffer_free(&m); + return; + } + buffer_free(&m); + close(client_fd); + return; + default: + error("Unsupported command %d", command); + buffer_free(&m); + close(client_fd); + return; + } + + /* Reply for SSHMUX_COMMAND_OPEN */ + buffer_clear(&m); buffer_put_int(&m, allowed); buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { error("%s: client msg_send failed", __func__); close(client_fd); buffer_free(&m); return; } - buffer_clear(&m); if (!allowed) { error("Refused control connection"); @@ -617,14 +667,14 @@ client_process_control(fd_set * readset) return; } + buffer_clear(&m); if (ssh_msg_recv(client_fd, &m) == -1) { error("%s: client msg_recv failed", __func__); close(client_fd); buffer_free(&m); return; } - - if ((ver = buffer_get_char(&m)) != 0) { + if ((ver = buffer_get_char(&m)) != 1) { error("%s: wrong client version %d", __func__, ver); buffer_free(&m); close(client_fd); @@ -633,9 +683,8 @@ client_process_control(fd_set * readset) cctx = xmalloc(sizeof(*cctx)); memset(cctx, 0, sizeof(*cctx)); - - cctx->want_tty = buffer_get_int(&m); - cctx->want_subsys = buffer_get_int(&m); + cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; + cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; cctx->term = buffer_get_string(&m, &len); cmd = buffer_get_string(&m, &len); @@ -667,14 +716,21 @@ client_process_control(fd_set * readset) if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) error("%s: tcgetattr: %s", __func__, strerror(errno)); + /* This roundtrip is just for synchronisation of ttymodes */ buffer_clear(&m); - if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + if (ssh_msg_send(client_fd, /* version */1, &m) == -1) { error("%s: client msg_send failed", __func__); close(client_fd); close(new_fd[0]); close(new_fd[1]); close(new_fd[2]); buffer_free(&m); + xfree(cctx->term); + if (env_len != 0) { + for (i = 0; i < env_len; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } return; } buffer_free(&m); diff --git a/clientloop.h b/clientloop.h index 9992d5938..b23c111cb 100644 --- a/clientloop.h +++ b/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.11 2004/07/11 17:48:47 deraadt Exp $ */ +/* $OpenBSD: clientloop.h,v 1.12 2004/11/07 00:01:46 djm Exp $ */ /* * Author: Tatu Ylonen @@ -40,3 +40,11 @@ int client_loop(int, int, int); void client_global_request_reply_fwd(int, u_int32_t, void *); void client_session2_setup(int, int, int, const char *, struct termios *, int, Buffer *, char **, dispatch_fn *); + +/* Multiplexing control protocol flags */ +#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ +#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ +#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ + +#define SSHMUX_FLAG_TTY (1) /* Request tty on open */ +#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ diff --git a/ssh.1 b/ssh.1 index 06cb60cec..ec83319b8 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.197 2004/10/07 10:10:24 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.198 2004/11/07 00:01:46 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -62,6 +62,7 @@ .Ek .Op Fl l Ar login_name .Op Fl m Ar mac_spec +.Op Fl O Ar ctl_cmd .Op Fl o Ar option .Bk -words .Op Fl p Ar port @@ -74,7 +75,7 @@ .Sm on .Xc .Oc -.Op Fl S Ar ctl +.Op Fl S Ar ctl_path .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Sh DESCRIPTION @@ -613,6 +614,18 @@ be specified in order of preference. See the .Cm MACs keyword for more information. +.It Fl O Ar ctl_cmd +Control an active connection multiplexing master process. +When the +.Fl O +option is specified, the +.Ar ctl_cmd +argument is interpreted and passed to the master process. +Valid commands are: +.Dq check +(check that the master process is running) and +.Dq exit +(request the master to exit). .It Fl N Do not execute a remote command. This is useful for just forwarding ports @@ -735,7 +748,7 @@ IPv6 addresses can be specified with an alternative syntax: .Ar hostport . .Xc .Sm on -.It Fl S Ar ctl +.It Fl S Ar ctl_path Specifies the location of a control socket for connection sharing. Refer to the description of .Cm ControlPath diff --git a/ssh.c b/ssh.c index c231c5fae..dfe9b25c1 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.228 2004/09/23 13:00:04 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.229 2004/11/07 00:01:46 djm Exp $"); #include #include @@ -144,6 +144,9 @@ pid_t proxy_command_pid = 0; /* fd to control socket */ int control_fd = -1; +/* Multiplexing control command */ +static u_int mux_command = SSHMUX_COMMAND_OPEN; + /* Only used in control client mode */ volatile sig_atomic_t control_client_terminate = 0; u_int control_server_pid = 0; @@ -236,7 +239,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -270,6 +273,14 @@ again: case 'g': options.gateway_ports = 1; break; + case 'O': + if (strcmp(optarg, "check") == 0) + mux_command = SSHMUX_COMMAND_ALIVE_CHECK; + else if (strcmp(optarg, "exit") == 0) + mux_command = SSHMUX_COMMAND_TERMINATE; + else + fatal("Invalid multiplex command."); + break; case 'P': /* deprecated */ options.use_privileged_port = 0; break; @@ -1251,8 +1262,9 @@ control_client(const char *path) struct sockaddr_un addr; int i, r, fd, sock, exitval, num_env, addr_len; Buffer m; - char *cp; + char *term; extern char **environ; + u_int flags; if (stdin_null_flag) { if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) @@ -1278,26 +1290,52 @@ control_client(const char *path) if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) fatal("Couldn't connect to %s: %s", path, strerror(errno)); - if ((cp = getenv("TERM")) == NULL) - cp = ""; + if ((term = getenv("TERM")) == NULL) + term = ""; + + flags = 0; + if (tty_flag) + flags |= SSHMUX_FLAG_TTY; + if (subsystem_flag) + flags |= SSHMUX_FLAG_SUBSYS; buffer_init(&m); - /* Get PID of controlee */ + /* Send our command to server */ + buffer_put_int(&m, mux_command); + buffer_put_int(&m, flags); + if (ssh_msg_send(sock, /* version */1, &m) == -1) + fatal("%s: msg_send", __func__); + buffer_clear(&m); + + /* Get authorisation status and PID of controlee */ if (ssh_msg_recv(sock, &m) == -1) fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != 0) + if (buffer_get_char(&m) != 1) fatal("%s: wrong version", __func__); - /* Connection allowed? */ if (buffer_get_int(&m) != 1) fatal("Connection to master denied"); control_server_pid = buffer_get_int(&m); buffer_clear(&m); - buffer_put_int(&m, tty_flag); - buffer_put_int(&m, subsystem_flag); - buffer_put_cstring(&m, cp); + switch (mux_command) { + case SSHMUX_COMMAND_ALIVE_CHECK: + fprintf(stderr, "Master running (pid=%d)\r\n", + control_server_pid); + exit(0); + case SSHMUX_COMMAND_TERMINATE: + fprintf(stderr, "Exit request sent.\r\n"); + exit(0); + case SSHMUX_COMMAND_OPEN: + /* continue below */ + break; + default: + fatal("silly mux_command %d", mux_command); + } + + /* SSHMUX_COMMAND_OPEN */ + buffer_put_cstring(&m, term); buffer_append(&command, "\0", 1); buffer_put_cstring(&m, buffer_ptr(&command)); @@ -1319,7 +1357,7 @@ control_client(const char *path) } } - if (ssh_msg_send(sock, /* version */0, &m) == -1) + if (ssh_msg_send(sock, /* version */1, &m) == -1) fatal("%s: msg_send", __func__); mm_send_fd(sock, STDIN_FILENO); @@ -1330,8 +1368,8 @@ control_client(const char *path) buffer_clear(&m); if (ssh_msg_recv(sock, &m) == -1) fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != 0) - fatal("%s: master returned error", __func__); + if (buffer_get_char(&m) != 1) + fatal("%s: wrong version", __func__); buffer_free(&m); signal(SIGHUP, control_client_sighandler); -- cgit v1.2.3 From 9c6bf325c0cf03fc40e87e51d165189dce07c594 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 3 Dec 2004 14:10:19 +1100 Subject: - jmc@cvs.openbsd.org 2004/11/07 17:57:30 [ssh.c] usage(): - add -O - sync -S w/ manpage - remove -h --- ChangeLog | 8 +++++++- ssh.c | 9 +++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 4b3024429..35a7d07ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ - jmc@cvs.openbsd.org 2004/11/07 17:42:36 [ssh.1] options sort, and whitespace; + - jmc@cvs.openbsd.org 2004/11/07 17:57:30 + [ssh.c] + usage(): + - add -O + - sync -S w/ manpage + - remove -h 20041107 - (dtucker) OpenBSD CVS Sync @@ -1860,4 +1866,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3582 2004/12/03 03:08:45 dtucker Exp $ +$Id: ChangeLog,v 1.3583 2004/12/03 03:10:19 dtucker Exp $ diff --git a/ssh.c b/ssh.c index dfe9b25c1..ac537338c 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.229 2004/11/07 00:01:46 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.230 2004/11/07 17:57:30 jmc Exp $"); #include #include @@ -157,10 +157,11 @@ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" " [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" -" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-o option]\n" -" [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\n" +" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n" +" [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n" +" [user@]hostname [command]\n" ); exit(1); } -- cgit v1.2.3 From 3eb48b62457b78a9308d10e5b968e85c2bc18525 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 1 Mar 2005 21:15:46 +1100 Subject: - otto@cvs.openbsd.org 2005/02/16 09:56:44 [ssh.c] Better diagnostic if an identity file is not accesible. ok markus@ djm@ --- ChangeLog | 8 +++++++- ssh.c | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 3fd376c3b..7faf0e6af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20050301 + - (djm) OpenBSD CVS sync: + - otto@cvs.openbsd.org 2005/02/16 09:56:44 + [ssh.c] + Better diagnostic if an identity file is not accesible. ok markus@ djm@ + 20050226 - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c] Remove two obsolete Cygwin #ifdefs. Patch from vinschen at redhat.com. @@ -2173,4 +2179,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3666 2005/02/25 23:12:38 dtucker Exp $ +$Id: ChangeLog,v 1.3667 2005/03/01 10:15:46 djm Exp $ diff --git a/ssh.c b/ssh.c index ac537338c..1f50727e9 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.230 2004/11/07 17:57:30 jmc Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $"); #include #include @@ -297,7 +297,8 @@ again: case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " - "does not exist.\n", optarg); + "not accessible: %s.\n", optarg, + strerror(errno)); break; } if (options.num_identity_files >= -- cgit v1.2.3 From f91ee4c3def4de8b4b9409f07ab26a61e535e1e6 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 1 Mar 2005 21:24:33 +1100 Subject: - djm@cvs.openbsd.org 2005/03/01 10:09:52 [auth-options.c channels.c channels.h clientloop.c compat.c compat.h] [misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5] [sshd_config.5] bz#413: allow optional specification of bind address for port forwardings. Patch originally by Dan Astorian, but worked on by several people Adds GatewayPorts=clientspecified option on server to allow remote forwards to bind to client-specified ports. --- ChangeLog | 10 +++- auth-options.c | 28 +++++----- channels.c | 82 ++++++++++++++++++++++++------ channels.h | 10 ++-- clientloop.c | 49 +++++++++--------- compat.c | 20 +++++--- compat.h | 3 +- misc.c | 44 +++++++++++++++- misc.h | 3 +- readconf.c | 157 +++++++++++++++++++++++++++++++++++++++++++-------------- readconf.h | 14 ++--- servconf.c | 65 ++++++++++++------------ ssh.1 | 59 ++++++++++++++++++---- ssh.c | 110 +++++++++++++++++++++++----------------- ssh_config.5 | 70 +++++++++++++++++++++---- sshd_config.5 | 15 +++--- 16 files changed, 525 insertions(+), 214 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index e4ec748f0..f31a52665 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,14 @@ [ssh_config.5] bz#849: document timeout on untrusted x11 forwarding sessions. Reported by orion AT cora.nwra.com; ok markus@ + - djm@cvs.openbsd.org 2005/03/01 10:09:52 + [auth-options.c channels.c channels.h clientloop.c compat.c compat.h] + [misc.c misc.h readconf.c readconf.h servconf.c ssh.1 ssh.c ssh_config.5] + [sshd_config.5] + bz#413: allow optional specification of bind address for port forwardings. + Patch originally by Dan Astorian, but worked on by several people + Adds GatewayPorts=clientspecified option on server to allow remote + forwards to bind to client-specified ports. 20050226 - (dtucker) [openbsd-compat/bsd-openpty.c openbsd-compat/inet_ntop.c] @@ -2195,4 +2203,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3671 2005/03/01 10:17:31 djm Exp $ +$Id: ChangeLog,v 1.3672 2005/03/01 10:24:33 djm Exp $ diff --git a/auth-options.c b/auth-options.c index 0e146ab15..04d12d66e 100644 --- a/auth-options.c +++ b/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.28 2003/06/02 09:17:34 markus Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.29 2005/03/01 10:09:52 djm Exp $"); #include "xmalloc.h" #include "match.h" @@ -217,7 +217,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) } cp = "permitopen=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { - char host[256], sport[6]; + char *host, *p; u_short port; char *patterns = xmalloc(strlen(opts) + 1); @@ -236,25 +236,29 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) if (!*opts) { debug("%.100s, line %lu: missing end quote", file, linenum); - auth_debug_add("%.100s, line %lu: missing end quote", - file, linenum); + auth_debug_add("%.100s, line %lu: missing " + "end quote", file, linenum); xfree(patterns); goto bad_option; } patterns[i] = 0; opts++; - if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 && - sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) { - debug("%.100s, line %lu: Bad permitopen specification " - "<%.100s>", file, linenum, patterns); + p = patterns; + host = hpdelim(&p); + if (host == NULL || strlen(host) >= NI_MAXHOST) { + debug("%.100s, line %lu: Bad permitopen " + "specification <%.100s>", file, linenum, + patterns); auth_debug_add("%.100s, line %lu: " - "Bad permitopen specification", file, linenum); + "Bad permitopen specification", file, + linenum); xfree(patterns); goto bad_option; } - if ((port = a2port(sport)) == 0) { - debug("%.100s, line %lu: Bad permitopen port <%.100s>", - file, linenum, sport); + host = cleanhostname(host); + if (p == NULL || (port = a2port(p)) == 0) { + debug("%.100s, line %lu: Bad permitopen port " + "<%.100s>", file, linenum, p ? p : ""); auth_debug_add("%.100s, line %lu: " "Bad permitopen port", file, linenum); xfree(patterns); diff --git a/channels.c b/channels.c index 8550e51ca..1be213bce 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.211 2004/10/29 21:47:15 djm Exp $"); +RCSID("$OpenBSD: channels.c,v 1.212 2005/03/01 10:09:52 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2179,14 +2179,14 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por const char *host_to_connect, u_short port_to_connect, int gateway_ports) { Channel *c; - int success, sock, on = 1; + int sock, r, success = 0, on = 1, wildcard = 0, is_client; struct addrinfo hints, *ai, *aitop; - const char *host; + const char *host, *addr; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - success = 0; host = (type == SSH_CHANNEL_RPORT_LISTENER) ? listen_addr : host_to_connect; + is_client = (type == SSH_CHANNEL_PORT_LISTENER); if (host == NULL) { error("No forward host name."); @@ -2197,17 +2197,61 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por return success; } + /* + * Determine whether or not a port forward listens to loopback, + * specified address or wildcard. On the client, a specified bind + * address will always override gateway_ports. On the server, a + * gateway_ports of 1 (``yes'') will override the client's + * specification and force a wildcard bind, whereas a value of 2 + * (``clientspecified'') will bind to whatever address the client + * asked for. + * + * Special-case listen_addrs are: + * + * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR + * "" (empty string), "*" -> wildcard v4/v6 + * "localhost" -> loopback v4/v6 + */ + addr = NULL; + if (listen_addr == NULL) { + /* No address specified: default to gateway_ports setting */ + if (gateway_ports) + wildcard = 1; + } else if (gateway_ports || is_client) { + if (((datafellows & SSH_OLD_FORWARD_ADDR) && + strcmp(listen_addr, "0.0.0.0") == 0) || + *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || + (!is_client && gateway_ports == 1)) + wildcard = 1; + else if (strcmp(listen_addr, "localhost") != 0) + addr = listen_addr; + } + + debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", + type, wildcard, (addr == NULL) ? "NULL" : addr); + /* * getaddrinfo returns a loopback address if the hostname is * set to NULL and hints.ai_flags is not AI_PASSIVE */ memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; - hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; + hints.ai_flags = wildcard ? AI_PASSIVE : 0; hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", listen_port); - if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) - packet_disconnect("getaddrinfo: fatal error"); + if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { + if (addr == NULL) { + /* This really shouldn't happen */ + packet_disconnect("getaddrinfo: fatal error: %s", + gai_strerror(r)); + } else { + verbose("channel_setup_fwd_listener: " + "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); + packet_send_debug("channel_setup_fwd_listener: " + "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); + } + aitop = NULL; + } for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) @@ -2290,11 +2334,12 @@ channel_cancel_rport_listener(const char *host, u_short port) /* protocol local port fwd, used by ssh (and sshd in v1) */ int -channel_setup_local_fwd_listener(u_short listen_port, +channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports) { return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, - NULL, listen_port, host_to_connect, port_to_connect, gateway_ports); + listen_host, listen_port, host_to_connect, port_to_connect, + gateway_ports); } /* protocol v2 remote port fwd, used by sshd */ @@ -2312,7 +2357,7 @@ channel_setup_remote_fwd_listener(const char *listen_address, */ void -channel_request_remote_forwarding(u_short listen_port, +channel_request_remote_forwarding(const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect) { int type, success = 0; @@ -2323,7 +2368,14 @@ channel_request_remote_forwarding(u_short listen_port, /* Send the forward request to the remote side. */ if (compat20) { - const char *address_to_bind = "0.0.0.0"; + const char *address_to_bind; + if (listen_host == NULL) + address_to_bind = "localhost"; + else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) + address_to_bind = ""; + else + address_to_bind = listen_host; + packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("tcpip-forward"); packet_put_char(1); /* boolean: want reply */ @@ -2369,10 +2421,9 @@ channel_request_remote_forwarding(u_short listen_port, * local side. */ void -channel_request_rforward_cancel(u_short port) +channel_request_rforward_cancel(const char *host, u_short port) { int i; - const char *address_to_bind = "0.0.0.0"; if (!compat20) return; @@ -2389,7 +2440,7 @@ channel_request_rforward_cancel(u_short port) packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("cancel-tcpip-forward"); packet_put_char(0); - packet_put_cstring(address_to_bind); + packet_put_cstring(host == NULL ? "" : host); packet_put_int(port); packet_send(); @@ -2430,7 +2481,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports) #endif /* Initiate forwarding */ - channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); + channel_setup_local_fwd_listener(NULL, port, hostname, + host_port, gateway_ports); /* Free the argument string. */ xfree(hostname); diff --git a/channels.h b/channels.h index c47de55c0..fc20fb2c3 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.75 2004/10/29 21:47:15 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */ /* * Author: Tatu Ylonen @@ -203,9 +203,11 @@ void channel_clear_permitted_opens(void); void channel_input_port_forward_request(int, int); int channel_connect_to(const char *, u_short); int channel_connect_by_listen_address(u_short); -void channel_request_remote_forwarding(u_short, const char *, u_short); -void channel_request_rforward_cancel(u_short port); -int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); +void channel_request_remote_forwarding(const char *, u_short, + const char *, u_short); +int channel_setup_local_fwd_listener(const char *, u_short, + const char *, u_short, int); +void channel_request_rforward_cancel(const char *host, u_short port); int channel_setup_remote_fwd_listener(const char *, u_short, int); int channel_cancel_rport_listener(const char *, u_short); diff --git a/clientloop.c b/clientloop.c index 033a98a5b..1e250883f 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.134 2004/11/07 00:01:46 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.135 2005/03/01 10:09:52 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -763,11 +763,11 @@ static void process_cmdline(void) { void (*handler)(int); - char *s, *cmd; - u_short fwd_port, fwd_host_port; - char buf[1024], sfwd_port[6], sfwd_host_port[6]; + char *s, *cmd, *cancel_host; int delete = 0; int local = 0; + u_short cancel_port; + Forward fwd; leave_raw_mode(); handler = signal(SIGINT, SIG_IGN); @@ -813,37 +813,38 @@ process_cmdline(void) s++; if (delete) { - if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) { - logit("Bad forwarding specification."); - goto out; + cancel_port = 0; + cancel_host = hpdelim(&s); /* may be NULL */ + if (s != NULL) { + cancel_port = a2port(s); + cancel_host = cleanhostname(cancel_host); + } else { + cancel_port = a2port(cancel_host); + cancel_host = NULL; } - if ((fwd_host_port = a2port(sfwd_host_port)) == 0) { - logit("Bad forwarding port(s)."); + if (cancel_port == 0) { + logit("Bad forwarding close port"); goto out; } - channel_request_rforward_cancel(fwd_host_port); + channel_request_rforward_cancel(cancel_host, cancel_port); } else { - if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", - sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", - sfwd_port, buf, sfwd_host_port) != 3) { + if (!parse_forward(&fwd, s)) { logit("Bad forwarding specification."); goto out; } - if ((fwd_port = a2port(sfwd_port)) == 0 || - (fwd_host_port = a2port(sfwd_host_port)) == 0) { - logit("Bad forwarding port(s)."); - goto out; - } if (local) { - if (channel_setup_local_fwd_listener(fwd_port, buf, - fwd_host_port, options.gateway_ports) < 0) { + if (channel_setup_local_fwd_listener(fwd.listen_host, + fwd.listen_port, fwd.connect_host, + fwd.connect_port, options.gateway_ports) < 0) { logit("Port forwarding failed."); goto out; } - } else - channel_request_remote_forwarding(fwd_port, buf, - fwd_host_port); + } else { + channel_request_remote_forwarding(fwd.listen_host, + fwd.listen_port, fwd.connect_host, + fwd.connect_port); + } + logit("Forwarding port."); } diff --git a/compat.c b/compat.c index 2fdebe7fa..4086e853e 100644 --- a/compat.c +++ b/compat.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $"); +RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $"); #include "buffer.h" #include "packet.h" @@ -62,24 +62,28 @@ compat_datafellows(const char *version) "OpenSSH_2.1*," "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF}, + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF}, + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| - SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, + SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, { "OpenSSH_2.5.0p1*," "OpenSSH_2.5.1p1*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| - SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, + SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, { "OpenSSH_2.5.0*," "OpenSSH_2.5.1*," "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| - SSH_BUG_EXTEOF}, - { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, { "OpenSSH_2.*," "OpenSSH_3.0*," - "OpenSSH_3.1*", SSH_BUG_EXTEOF}, + "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH*", 0 }, { "*MindTerm*", 0 }, diff --git a/compat.h b/compat.h index 5efb5c29e..cf92dbdee 100644 --- a/compat.h +++ b/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */ +/* $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -55,6 +55,7 @@ #define SSH_BUG_EXTEOF 0x00200000 #define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_FIRSTKEX 0x00800000 +#define SSH_OLD_FORWARD_ADDR 0x01000000 void enable_compat13(void); void enable_compat20(void); diff --git a/misc.c b/misc.c index a90125505..2e366f81b 100644 --- a/misc.c +++ b/misc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.27 2004/12/11 01:48:56 dtucker Exp $"); +RCSID("$OpenBSD: misc.c,v 1.28 2005/03/01 10:09:52 djm Exp $"); #include "misc.h" #include "log.h" @@ -275,6 +275,48 @@ convtime(const char *s) return total; } +/* + * Search for next delimiter between hostnames/addresses and ports. + * Argument may be modified (for termination). + * Returns *cp if parsing succeeds. + * *cp is set to the start of the next delimiter, if one was found. + * If this is the last field, *cp is set to NULL. + */ +char * +hpdelim(char **cp) +{ + char *s, *old; + + if (cp == NULL || *cp == NULL) + return NULL; + + old = s = *cp; + if (*s == '[') { + if ((s = strchr(s, ']')) == NULL) + return NULL; + else + s++; + } else if ((s = strpbrk(s, ":/")) == NULL) + s = *cp + strlen(*cp); /* skip to end (see first case below) */ + + switch (*s) { + case '\0': + *cp = NULL; /* no more fields*/ + break; + + case ':': + case '/': + *s = '\0'; /* terminate */ + *cp = s + 1; + break; + + default: + return NULL; + } + + return old; +} + char * cleanhostname(char *host) { diff --git a/misc.h b/misc.h index 193216fa9..8bbc87f0d 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.20 2004/12/11 01:48:56 dtucker Exp $ */ +/* $OpenBSD: misc.h,v 1.21 2005/03/01 10:09:52 djm Exp $ */ /* * Author: Tatu Ylonen @@ -20,6 +20,7 @@ int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); int a2port(const char *); +char *hpdelim(char **); char *cleanhostname(char *); char *colon(char *); long convtime(const char *); diff --git a/readconf.c b/readconf.c index a4fe1fe02..c3dc71e66 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.135 2005/03/01 10:09:52 djm Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -206,21 +206,23 @@ static struct { */ void -add_local_forward(Options *options, u_short port, const char *host, - u_short host_port) +add_local_forward(Options *options, const Forward *newfwd) { Forward *fwd; #ifndef NO_IPPORT_RESERVED_CONCEPT extern uid_t original_real_uid; - if (port < IPPORT_RESERVED && original_real_uid != 0) + if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) fatal("Privileged ports can only be forwarded by root."); #endif if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->local_forwards[options->num_local_forwards++]; - fwd->port = port; - fwd->host = xstrdup(host); - fwd->host_port = host_port; + + fwd->listen_host = (newfwd->listen_host == NULL) ? + NULL : xstrdup(newfwd->listen_host); + fwd->listen_port = newfwd->listen_port; + fwd->connect_host = xstrdup(newfwd->connect_host); + fwd->connect_port = newfwd->connect_port; } /* @@ -229,17 +231,19 @@ add_local_forward(Options *options, u_short port, const char *host, */ void -add_remote_forward(Options *options, u_short port, const char *host, - u_short host_port) +add_remote_forward(Options *options, const Forward *newfwd) { Forward *fwd; if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) fatal("Too many remote forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->remote_forwards[options->num_remote_forwards++]; - fwd->port = port; - fwd->host = xstrdup(host); - fwd->host_port = host_port; + + fwd->listen_host = (newfwd->listen_host == NULL) ? + NULL : xstrdup(newfwd->listen_host); + fwd->listen_port = newfwd->listen_port; + fwd->connect_host = xstrdup(newfwd->connect_host); + fwd->connect_port = newfwd->connect_port; } static void @@ -247,11 +251,15 @@ clear_forwardings(Options *options) { int i; - for (i = 0; i < options->num_local_forwards; i++) - xfree(options->local_forwards[i].host); + for (i = 0; i < options->num_local_forwards; i++) { + xfree(options->local_forwards[i].listen_host); + xfree(options->local_forwards[i].connect_host); + } options->num_local_forwards = 0; - for (i = 0; i < options->num_remote_forwards; i++) - xfree(options->remote_forwards[i].host); + for (i = 0; i < options->num_remote_forwards; i++) { + xfree(options->remote_forwards[i].listen_host); + xfree(options->remote_forwards[i].connect_host); + } options->num_remote_forwards = 0; } @@ -284,11 +292,10 @@ process_config_line(Options *options, const char *host, char *line, const char *filename, int linenum, int *activep) { - char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; + char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; int opcode, *intptr, value; size_t len; - u_short fwd_port, fwd_host_port; - char sfwd_host_port[6]; + Forward fwd; /* Strip trailing whitespace */ for(len = strlen(line) - 1; len > 0; len--) { @@ -645,30 +652,26 @@ parse_int: case oLocalForward: case oRemoteForward: arg = strdelim(&s); - if (!arg || *arg == '\0') + if (arg == NULL || *arg == '\0') fatal("%.200s line %d: Missing port argument.", filename, linenum); - if ((fwd_port = a2port(arg)) == 0) - fatal("%.200s line %d: Bad listen port.", + arg2 = strdelim(&s); + if (arg2 == NULL || *arg2 == '\0') + fatal("%.200s line %d: Missing target argument.", filename, linenum); - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing second argument.", - filename, linenum); - if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && - sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) + + /* construct a string for parse_forward */ + snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); + + if (parse_forward(&fwd, fwdarg) == 0) fatal("%.200s line %d: Bad forwarding specification.", filename, linenum); - if ((fwd_host_port = a2port(sfwd_host_port)) == 0) - fatal("%.200s line %d: Bad forwarding port.", - filename, linenum); + if (*activep) { if (opcode == oLocalForward) - add_local_forward(options, fwd_port, buf, - fwd_host_port); + add_local_forward(options, &fwd); else if (opcode == oRemoteForward) - add_remote_forward(options, fwd_port, buf, - fwd_host_port); + add_remote_forward(options, &fwd); } break; @@ -677,12 +680,25 @@ parse_int: if (!arg || *arg == '\0') fatal("%.200s line %d: Missing port argument.", filename, linenum); - fwd_port = a2port(arg); - if (fwd_port == 0) + memset(&fwd, '\0', sizeof(fwd)); + fwd.connect_host = "socks"; + fwd.listen_host = hpdelim(&arg); + if (fwd.listen_host == NULL || + strlen(fwd.listen_host) >= NI_MAXHOST) + fatal("%.200s line %d: Bad forwarding specification.", + filename, linenum); + if (arg) { + fwd.listen_port = a2port(arg); + fwd.listen_host = cleanhostname(fwd.listen_host); + } else { + fwd.listen_port = a2port(fwd.listen_host); + fwd.listen_host = ""; + } + if (fwd.listen_port == 0) fatal("%.200s line %d: Badly formatted port number.", filename, linenum); if (*activep) - add_local_forward(options, fwd_port, "socks", 0); + add_local_forward(options, &fwd); break; case oClearAllForwardings: @@ -1045,3 +1061,68 @@ fill_default_options(Options * options) /* options->host_key_alias should not be set by default */ /* options->preferred_authentications will be set in ssh */ } + +/* + * parse_forward + * parses a string containing a port forwarding specification of the form: + * [listenhost:]listenport:connecthost:connectport + * returns number of arguments parsed or zero on error + */ +int +parse_forward(Forward *fwd, const char *fwdspec) +{ + int i; + char *p, *cp, *fwdarg[4]; + + memset(fwd, '\0', sizeof(*fwd)); + + cp = p = xstrdup(fwdspec); + + /* skip leading spaces */ + while (*cp && isspace(*cp)) + cp++; + + for (i = 0; i < 4; ++i) + if ((fwdarg[i] = hpdelim(&cp)) == NULL) + break; + + /* Check for trailing garbage in 4-arg case*/ + if (cp != NULL) + i = 0; /* failure */ + + switch (i) { + case 3: + fwd->listen_host = NULL; + fwd->listen_port = a2port(fwdarg[0]); + fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); + fwd->connect_port = a2port(fwdarg[2]); + break; + + case 4: + fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); + fwd->listen_port = a2port(fwdarg[1]); + fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); + fwd->connect_port = a2port(fwdarg[3]); + break; + default: + i = 0; /* failure */ + } + + xfree(p); + + if (fwd->listen_port == 0 && fwd->connect_port == 0) + goto fail_free; + + if (fwd->connect_host != NULL && + strlen(fwd->connect_host) >= NI_MAXHOST) + goto fail_free; + + return (i); + + fail_free: + if (fwd->connect_host != NULL) + xfree(fwd->connect_host); + if (fwd->listen_host != NULL) + xfree(fwd->listen_host); + return (0); +} diff --git a/readconf.h b/readconf.h index ded422585..03b772a2d 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.64 2004/07/11 17:48:47 deraadt Exp $ */ +/* $OpenBSD: readconf.h,v 1.65 2005/03/01 10:09:52 djm Exp $ */ /* * Author: Tatu Ylonen @@ -21,9 +21,10 @@ /* Data structure for representing a forwarding request. */ typedef struct { - u_short port; /* Port to forward. */ - char *host; /* Host to connect. */ - u_short host_port; /* Port to connect on host. */ + char *listen_host; /* Host (address) to listen on. */ + u_short listen_port; /* Port to forward. */ + char *connect_host; /* Host to connect. */ + u_short connect_port; /* Port to connect on connect_host. */ } Forward; /* Data structure for representing option data. */ @@ -117,11 +118,12 @@ typedef struct { void initialize_options(Options *); void fill_default_options(Options *); int read_config_file(const char *, const char *, Options *, int); +int parse_forward(Forward *, const char *); int process_config_line(Options *, const char *, char *, const char *, int, int *); -void add_local_forward(Options *, u_short, const char *, u_short); -void add_remote_forward(Options *, u_short, const char *, u_short); +void add_local_forward(Options *, const Forward *); +void add_remote_forward(Options *, const Forward *); #endif /* READCONF_H */ diff --git a/servconf.c b/servconf.c index 541a9c85b..2d1a0c362 100644 --- a/servconf.c +++ b/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.138 2004/12/23 23:11:00 djm Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.139 2005/03/01 10:09:52 djm Exp $"); #include "ssh.h" #include "log.h" @@ -440,6 +440,7 @@ process_server_config_line(ServerOptions *options, char *line, char *cp, **charptr, *arg, *p; int *intptr, value, i, n; ServerOpCodes opcode; + u_short port; cp = line; arg = strdelim(&cp); @@ -512,39 +513,21 @@ parse_time: case sListenAddress: arg = strdelim(&cp); - if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) - fatal("%s line %d: missing inet addr.", + if (arg == NULL || *arg == '\0') + fatal("%s line %d: missing address", filename, linenum); - if (*arg == '[') { - if ((p = strchr(arg, ']')) == NULL) - fatal("%s line %d: bad ipv6 inet addr usage.", - filename, linenum); - arg++; - memmove(p, p+1, strlen(p+1)+1); - } else if (((p = strchr(arg, ':')) == NULL) || - (strchr(p+1, ':') != NULL)) { - add_listen_addr(options, arg, 0); - break; - } - if (*p == ':') { - u_short port; - - p++; - if (*p == '\0') - fatal("%s line %d: bad inet addr:port usage.", - filename, linenum); - else { - *(p-1) = '\0'; - if ((port = a2port(p)) == 0) - fatal("%s line %d: bad port number.", - filename, linenum); - add_listen_addr(options, arg, port); - } - } else if (*p == '\0') - add_listen_addr(options, arg, 0); - else - fatal("%s line %d: bad inet addr usage.", + p = hpdelim(&arg); + if (p == NULL) + fatal("%s line %d: bad address:port usage", filename, linenum); + p = cleanhostname(p); + if (arg == NULL) + port = 0; + else if ((port = a2port(arg)) == 0) + fatal("%s line %d: bad port number", filename, linenum); + + add_listen_addr(options, p, port); + break; case sAddressFamily: @@ -742,7 +725,23 @@ parse_flag: case sGatewayPorts: intptr = &options->gateway_ports; - goto parse_flag; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing yes/no/clientspecified " + "argument.", filename, linenum); + value = 0; /* silence compiler */ + if (strcmp(arg, "clientspecified") == 0) + value = 2; + else if (strcmp(arg, "yes") == 0) + value = 1; + else if (strcmp(arg, "no") == 0) + value = 0; + else + fatal("%s line %d: Bad yes/no/clientspecified " + "argument: %s", filename, linenum, arg); + if (*intptr == -1) + *intptr = value; + break; case sUseDNS: intptr = &options->use_dns; diff --git a/ssh.1 b/ssh.1 index b8a91a160..27da08c69 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.199 2004/11/07 17:42:36 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.200 2005/03/01 10:09:52 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -53,13 +53,13 @@ .Op Fl i Ar identity_file .Oo Fl L Xo .Sm off +.Oo Ar bind_address : Oc .Ar port : .Ar host : .Ar hostport .Sm on .Xc .Oc -.Ek .Op Fl l Ar login_name .Op Fl m Ar mac_spec .Op Fl O Ar ctl_cmd @@ -69,6 +69,7 @@ .Ek .Oo Fl R Xo .Sm off +.Oo Ar bind_address : Oc .Ar port : .Ar host : .Ar hostport @@ -570,6 +571,7 @@ configuration files). Disables forwarding (delegation) of GSSAPI credentials to the server. .It Fl L Xo .Sm off +.Oo Ar bind_address : Oc .Ar port : host : hostport .Sm on .Xc @@ -577,7 +579,9 @@ Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side. This works by allocating a socket to listen to .Ar port -on the local side, and whenever a connection is made to this port, the +on the local side, optionally bound to the specified +.Ar bind_address . +Whenever a connection is made to this port, the connection is forwarded over the secure channel, and a connection is made to .Ar host @@ -585,14 +589,30 @@ port .Ar hostport from the remote machine. Port forwardings can also be specified in the configuration file. -Only root can forward privileged ports. IPv6 addresses can be specified with an alternative syntax: .Sm off .Xo +.Oo Ar bind_address / Oc .Ar port No / Ar host No / -.Ar hostport . +.Ar hostport .Xc .Sm on +or by enclosing the address in square brackets. +Only the superuser can forward privileged ports. +By default, the local port is bound in accordance with the +.Cm GatewayPorts +setting. +However, an explicit +.Ar bind_address +may be used to bind the connection to a specific address. +The +.Ar bind_address +of +.Dq localhost +indicates that the listening port be bound for local use only, while an +empty address or +.Dq * +indicates that the port should be available from all interfaces. .It Fl l Ar login_name Specifies the user to log in as on the remote machine. This also may be specified on a per-host basis in the configuration file. @@ -724,6 +744,7 @@ Quiet mode. Causes all warning and diagnostic messages to be suppressed. .It Fl R Xo .Sm off +.Oo Ar bind_address : Oc .Ar port : host : hostport .Sm on .Xc @@ -738,16 +759,34 @@ made to port .Ar hostport from the local machine. +.Pp Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. -IPv6 addresses can be specified with an alternative syntax: -.Sm off +IPv6 addresses can be specified by enclosing the address in square braces or +using an alternative syntax: .Xo -.Ar port No / Ar host No / -.Ar hostport . -.Xc +.Sm off +.Oo Ar bind_address / Oc +.Ar host/port/hostport .Sm on +.Xc . +.Pp +By default, the listening socket on the server will be bound to the loopback +interface only. +This may be overriden by specifying a +.Ar bind_address . +An empty +.Ar bind_address , +or the address +.Ql * +indicates that the remote socket should listen on all interfaces. +Specifying a remote +.Ar bind_address +will only succeed if the server's +.Cm GatewayPorts +option is enabled (see +.Xr sshd_config 5 ). .It Fl S Ar ctl_path Specifies the location of a control socket for connection sharing. Refer to the description of diff --git a/ssh.c b/ssh.c index 1f50727e9..99b25afcc 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.231 2005/02/16 09:56:44 otto Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.232 2005/03/01 10:09:52 djm Exp $"); #include #include @@ -158,9 +158,10 @@ usage(void) { fprintf(stderr, "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" -" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd]\n" -" [-o option] [-p port] [-R port:host:hostport] [-S ctl_path]\n" +" [-D [listen-host:]port] [-e escape_char] [-F configfile]\n" +" [-i identity_file] [-L [listen-host:]port:host:hostport]\n" +" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" +" [-R [listen-host:]port:host:hostport] [-S ctl_path]\n" " [user@]hostname [command]\n" ); exit(1); @@ -178,14 +179,13 @@ int main(int ac, char **av) { int i, opt, exit_status; - u_short fwd_port, fwd_host_port; - char sfwd_port[6], sfwd_host_port[6]; char *p, *cp, *line, buf[256]; struct stat st; struct passwd *pw; int dummy; extern int optind, optreset; extern char *optarg; + Forward fwd; __progname = ssh_get_progname(av[0]); init_rng(); @@ -401,39 +401,51 @@ again: break; case 'L': - case 'R': - if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", - sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]", - sfwd_port, buf, sfwd_host_port) != 3) { + if (parse_forward(&fwd, optarg)) + add_local_forward(&options, &fwd); + else { fprintf(stderr, - "Bad forwarding specification '%s'\n", + "Bad local forwarding specification '%s'\n", optarg); - usage(); - /* NOTREACHED */ + exit(1); } - if ((fwd_port = a2port(sfwd_port)) == 0 || - (fwd_host_port = a2port(sfwd_host_port)) == 0) { + break; + + case 'R': + if (parse_forward(&fwd, optarg)) { + add_remote_forward(&options, &fwd); + } else { fprintf(stderr, - "Bad forwarding port(s) '%s'\n", optarg); + "Bad remote forwarding specification " + "'%s'\n", optarg); exit(1); } - if (opt == 'L') - add_local_forward(&options, fwd_port, buf, - fwd_host_port); - else if (opt == 'R') - add_remote_forward(&options, fwd_port, buf, - fwd_host_port); break; case 'D': - fwd_port = a2port(optarg); - if (fwd_port == 0) { + cp = p = xstrdup(optarg); + memset(&fwd, '\0', sizeof(fwd)); + fwd.connect_host = "socks"; + if ((fwd.listen_host = hpdelim(&cp)) == NULL) { + fprintf(stderr, "Bad dynamic forwarding " + "specification '%.100s'\n", optarg); + exit(1); + } + if (cp != NULL) { + fwd.listen_port = a2port(cp); + fwd.listen_host = cleanhostname(fwd.listen_host); + } else { + fwd.listen_port = a2port(fwd.listen_host); + fwd.listen_host = ""; + } + + if (fwd.listen_port == 0) { fprintf(stderr, "Bad dynamic port '%s'\n", optarg); exit(1); } - add_local_forward(&options, fwd_port, "socks", 0); + add_local_forward(&options, &fwd); + xfree(p); break; case 'C': @@ -842,14 +854,19 @@ ssh_init_forwarding(void) /* Initiate local TCP/IP port forwardings. */ for (i = 0; i < options.num_local_forwards; i++) { - debug("Connections to local port %d forwarded to remote address %.200s:%d", - options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port); + debug("Local connections to %.200s:%d forwarded to remote " + "address %.200s:%d", + (options.local_forwards[i].listen_host == NULL) ? + (options.gateway_ports ? "*" : "LOCALHOST") : + options.local_forwards[i].listen_host, + options.local_forwards[i].listen_port, + options.local_forwards[i].connect_host, + options.local_forwards[i].connect_port); success += channel_setup_local_fwd_listener( - options.local_forwards[i].port, - options.local_forwards[i].host, - options.local_forwards[i].host_port, + options.local_forwards[i].listen_host, + options.local_forwards[i].listen_port, + options.local_forwards[i].connect_host, + options.local_forwards[i].connect_port, options.gateway_ports); } if (i > 0 && success == 0) @@ -857,14 +874,17 @@ ssh_init_forwarding(void) /* Initiate remote TCP/IP port forwardings. */ for (i = 0; i < options.num_remote_forwards; i++) { - debug("Connections to remote port %d forwarded to local address %.200s:%d", - options.remote_forwards[i].port, - options.remote_forwards[i].host, - options.remote_forwards[i].host_port); + debug("Remote connections from %.200s:%d forwarded to " + "local address %.200s:%d", + options.remote_forwards[i].listen_host, + options.remote_forwards[i].listen_port, + options.remote_forwards[i].connect_host, + options.remote_forwards[i].connect_port); channel_request_remote_forwarding( - options.remote_forwards[i].port, - options.remote_forwards[i].host, - options.remote_forwards[i].host_port); + options.remote_forwards[i].listen_host, + options.remote_forwards[i].listen_port, + options.remote_forwards[i].connect_host, + options.remote_forwards[i].connect_port); } } @@ -1040,12 +1060,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) return; debug("remote forward %s for: listen %d, connect %s:%d", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", - options.remote_forwards[i].port, - options.remote_forwards[i].host, - options.remote_forwards[i].host_port); + options.remote_forwards[i].listen_port, + options.remote_forwards[i].connect_host, + options.remote_forwards[i].connect_port); if (type == SSH2_MSG_REQUEST_FAILURE) - logit("Warning: remote port forwarding failed for listen port %d", - options.remote_forwards[i].port); + logit("Warning: remote port forwarding failed for listen " + "port %d", options.remote_forwards[i].listen_port); } static void diff --git a/ssh_config.5 b/ssh_config.5 index 8f6d851b4..6b6cfc5e9 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.42 2005/02/28 00:54:10 djm Exp $ +.\" $OpenBSD: ssh_config.5,v 1.43 2005/03/01 10:09:52 djm Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -480,12 +480,37 @@ The default is to use the server specified list. Specifies that a TCP/IP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. The first argument must be a port number, and the second must be -.Ar host:port . -IPv6 addresses can be specified with an alternative syntax: -.Ar host/port . -Multiple forwardings may be specified, and additional -forwardings can be given on the command line. +.Xo +.Sm off +.Oo Ar bind_address : Oc +.Ar host:port +.Sm on +.Xc . +IPv6 addresses can be specified by enclosing addresses in square brackets or +by using an alternative syntax: +.Xo +.Sm off +.Oo Ar bind_address / Oc +.Ar host/port +.Sm on +.Xc . +Multiple forwardings may be specified, and additional forwardings can be +given on the command line. Only the superuser can forward privileged ports. +By default, the local port is bound in accordance with the +.Cm GatewayPorts +setting. +However, an explicit +.Ar bind_address +may be used to bind the connection to a specific address. +The +.Ar bind_address +of +.Dq localhost +indicates that the listening port be bound for local use only, while an +empty address or +.Dq * +indicates that the port should be available from all interfaces. .It Cm LogLevel Gives the verbosity level that is used when logging messages from .Nm ssh . @@ -592,12 +617,39 @@ This option applies to protocol version 2 only. Specifies that a TCP/IP port on the remote machine be forwarded over the secure channel to the specified host and port from the local machine. The first argument must be a port number, and the second must be -.Ar host:port . -IPv6 addresses can be specified with an alternative syntax: -.Ar host/port . +.Xo +.Sm off +.Oo Ar bind_address : Oc +.Ar host:port +.Sm on +.Xc . +IPv6 addresses can be specified by enclosing any addresses in square brackets +or by using the alternative syntax: +.Xo +.Sm off +.Oo Ar bind_address / Oc +.Ar host/port +.Sm on +.Xc . Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. +.Pp +If the +.Ar bind_address +is not specified, the default is to only bind to loopback addresses. +If the +.Ar bind_address +is +.Ql * +or an empty string, then the forwarding is requested to listen on all +interfaces. +Specifying a remote +.Ar bind_address +will only succeed if the server's +.Cm GatewayPorts +option is enabled (see +.Xr sshd_config 5 ). .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. diff --git a/sshd_config.5 b/sshd_config.5 index da6d97c68..8d291e61d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.38 2005/01/08 00:41:19 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.39 2005/03/01 10:09:52 djm Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -256,12 +256,15 @@ This prevents other remote hosts from connecting to forwarded ports. .Cm GatewayPorts can be used to specify that .Nm sshd -should bind remote port forwardings to the wildcard address, -thus allowing remote hosts to connect to forwarded ports. -The argument must be +should allow remote port forwardings to bind to non-loopback addresses, thus +allowing other hosts to connect. +The argument may be +.Dq no +to force remote port forwardings to be available to the local host only, .Dq yes -or -.Dq no . +to force remote port forwardings to bind to the wildcard address, or +.Dq clientspecified +to allow the client to select the address to which the forwarding is bound. The default is .Dq no . .It Cm GSSAPIAuthentication -- cgit v1.2.3 From 02faeceb5632393de553ef2b4b7d31d6f7b022c4 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 2 Mar 2005 12:04:32 +1100 Subject: - jmc@cvs.openbsd.org 2005/03/01 17:22:06 [ssh.c] sync usage() w/ man SYNOPSIS; ok markus@ --- ChangeLog | 6 +++++- ssh.c | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'ssh.c') diff --git a/ChangeLog b/ChangeLog index 538e2e3b3..e306a8324 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,10 @@ [scp.1 sftp.1] add HashKnownHosts to -o list; ok markus@ + - jmc@cvs.openbsd.org 2005/03/01 17:22:06 + [ssh.c] + sync usage() w/ man SYNOPSIS; + ok markus@ 20050301 - (djm) OpenBSD CVS sync: @@ -2241,4 +2245,4 @@ - (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu -$Id: ChangeLog,v 1.3681 2005/03/02 01:04:16 djm Exp $ +$Id: ChangeLog,v 1.3682 2005/03/02 01:04:32 djm Exp $ diff --git a/ssh.c b/ssh.c index 99b25afcc..9acec3082 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.232 2005/03/01 10:09:52 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.233 2005/03/01 17:22:06 jmc Exp $"); #include #include @@ -158,10 +158,10 @@ usage(void) { fprintf(stderr, "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D [listen-host:]port] [-e escape_char] [-F configfile]\n" -" [-i identity_file] [-L [listen-host:]port:host:hostport]\n" +" [-D port] [-e escape_char] [-F configfile]\n" +" [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" -" [-R [listen-host:]port:host:hostport] [-S ctl_path]\n" +" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" " [user@]hostname [command]\n" ); exit(1); -- cgit v1.2.3