From c970cb9052f85a7570f8003f598cc95fccf70601 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 20 Apr 2004 20:12:53 +1000 Subject: - djm@cvs.openbsd.org 2004/04/19 13:02:40 [ssh.1 ssh_config.5] document strict permission checks on ~/.ssh/config; prompted by, with & ok jmc@ --- ssh.1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ssh.1') diff --git a/ssh.1 b/ssh.1 index 31eb66c97..053fedd28 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.182 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.183 2004/04/19 13:02:40 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -885,6 +885,8 @@ the convenience of the user. This is the per-user configuration file. The file format and configuration options are described in .Xr ssh_config 5 . +Because of the potential for abuse, this file must have strict permissions: +read/write for the user, and not accessible by others. .It Pa $HOME/.ssh/authorized_keys Lists the public keys (RSA/DSA) that can be used for logging in as this user. The format of this file is described in the -- cgit v1.2.3 From 7a6c06620e0a39f22fdff277bcbbb9ebe9861dd8 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 2 May 2004 22:14:03 +1000 Subject: - jmc@cvs.openbsd.org 2004/04/28 07:13:42 [sftp.1 ssh.1] add SendEnv to -o list; --- ChangeLog | 5 ++++- sftp.1 | 3 ++- ssh.1 | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index c8e416ca2..8132bb0ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,9 @@ - jmc@cvs.openbsd.org 2004/04/28 07:02:56 [sshd_config.5] remove unnecessary .Pp; + - jmc@cvs.openbsd.org 2004/04/28 07:13:42 + [sftp.1 ssh.1] + add SendEnv to -o list; 20040423 - (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Declare h_errno @@ -1056,4 +1059,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.3336 2004/05/02 12:13:20 dtucker Exp $ +$Id: ChangeLog,v 1.3337 2004/05/02 12:14:03 dtucker Exp $ diff --git a/sftp.1 b/sftp.1 index b2cab0cda..c8ba85751 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.52 2004/03/05 10:53:58 markus Exp $ +.\" $OpenBSD: sftp.1,v 1.53 2004/04/28 07:13:42 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -176,6 +176,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RhostsRSAAuthentication .It RSAAuthentication +.It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It SmartcardDevice diff --git a/ssh.1 b/ssh.1 index 053fedd28..d387cc884 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.183 2004/04/19 13:02:40 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.184 2004/04/28 07:13:42 jmc Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -649,6 +649,7 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RhostsRSAAuthentication .It RSAAuthentication +.It SendEnv .It ServerAliveInterval .It ServerAliveCountMax .It SmartcardDevice -- cgit v1.2.3 From edae0ec12a11c872b4fb5571c243be272e6065d6 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 2 May 2004 22:15:52 +1000 Subject: - dtucker@cvs.openbsd.org 2004/05/02 11:57:52 [ssh.1] ConnectionTimeout -> ConnectTimeout, from m.a.ellis at ncl.ac.uk via Debian. ok djm@ --- ChangeLog | 6 +++++- ssh.1 | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 6ebc93b69..a34ec1813 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,10 @@ [sshd.8] Man page grammar fix (bz #858), from damerell at chiark.greenend.org.uk via Debian; ok djm@ + - dtucker@cvs.openbsd.org 2004/05/02 11:57:52 + [ssh.1] + ConnectionTimeout -> ConnectTimeout, from m.a.ellis at ncl.ac.uk via + Debian. ok djm@ 20040423 - (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Declare h_errno @@ -1063,4 +1067,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.3338 2004/05/02 12:15:08 dtucker Exp $ +$Id: ChangeLog,v 1.3339 2004/05/02 12:15:52 dtucker Exp $ diff --git a/ssh.1 b/ssh.1 index d387cc884..b7b126440 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.184 2004/04/28 07:13:42 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.185 2004/05/02 11:57:52 dtucker Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -618,7 +618,7 @@ For full details of the options listed below, and their possible values, see .It Compression .It CompressionLevel .It ConnectionAttempts -.It ConnectionTimeout +.It ConnectTimeout .It DynamicForward .It EscapeChar .It ForwardAgent -- cgit v1.2.3 From e7066dfde3d4ac36038050b6027a742356f7b1f1 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 24 May 2004 10:18:05 +1000 Subject: - djm@cvs.openbsd.org 2004/05/21 11:33:11 [channels.c channels.h clientloop.c serverloop.c ssh.1] bz #756: add support for the cancel-tcpip-forward request for the server and the client (through the ~C commandline). reported by z3p AT twistedmatrix.com; ok markus@ --- ChangeLog | 7 ++++- channels.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--- channels.h | 4 ++- clientloop.c | 84 ++++++++++++++++++++++++++++++++++++++++++------------------ serverloop.c | 13 +++++++++- ssh.1 | 13 +++++++--- 6 files changed, 153 insertions(+), 35 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 91c9ce5ec..0e8f4a556 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,11 @@ - markus@cvs.openbsd.org 2004/05/21 08:43:03 [kex.h moduli.c tildexpand.c] add prototypes for -Wall; ok djm + - djm@cvs.openbsd.org 2004/05/21 11:33:11 + [channels.c channels.h clientloop.c serverloop.c ssh.1] + bz #756: add support for the cancel-tcpip-forward request for the server and + the client (through the ~C commandline). reported by z3p AT twistedmatrix.com; + ok markus@ 20040523 - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in @@ -1139,4 +1144,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.3361 2004/05/24 00:14:24 dtucker Exp $ +$Id: ChangeLog,v 1.3362 2004/05/24 00:18:05 dtucker Exp $ diff --git a/channels.c b/channels.c index 55dc67342..2b1ce0e5c 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.201 2004/05/11 19:01:43 deraadt Exp $"); +RCSID("$OpenBSD: channels.c,v 1.202 2004/05/21 11:33:11 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -2228,6 +2228,26 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por return success; } +int +channel_cancel_rport_listener(const char *host, u_short port) +{ + int i, found = 0; + + for(i = 0; i < channels_alloc; i++) { + Channel *c = channels[i]; + + if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && + strncmp(c->path, host, sizeof(c->path)) == 0 && + c->listening_port == port) { + debug2("%s: close clannel %d", __func__, i); + channel_free(c); + found = 1; + } + } + + return (found); +} + /* protocol local port fwd, used by ssh (and sshd in v1) */ int channel_setup_local_fwd_listener(u_short listen_port, @@ -2304,6 +2324,42 @@ channel_request_remote_forwarding(u_short listen_port, } } +/* + * Request cancellation of remote forwarding of connection host:port from + * local side. + */ + +void +channel_request_rforward_cancel(u_short port) +{ + int i; + const char *address_to_bind = "0.0.0.0"; + + if (!compat20) + return; + + for (i = 0; i < num_permitted_opens; i++) { + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].listen_port == port) + break; + } + if (i >= num_permitted_opens) { + debug("%s: requested forward not found", __func__); + return; + } + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("cancel-tcpip-forward"); + packet_put_char(0); + packet_put_cstring(address_to_bind); + packet_put_int(port); + packet_send(); + + permitted_opens[i].listen_port = 0; + permitted_opens[i].port_to_connect = 0; + free(permitted_opens[i].host_to_connect); + permitted_opens[i].host_to_connect = NULL; +} + /* * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates * listening for the port, and sends back a success reply (or disconnect @@ -2373,7 +2429,8 @@ channel_clear_permitted_opens(void) int i; for (i = 0; i < num_permitted_opens; i++) - xfree(permitted_opens[i].host_to_connect); + if (permitted_opens[i].host_to_connect != NULL) + xfree(permitted_opens[i].host_to_connect); num_permitted_opens = 0; } @@ -2441,7 +2498,8 @@ channel_connect_by_listen_address(u_short listen_port) int i; for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].listen_port == listen_port) + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].listen_port == listen_port) return connect_to( permitted_opens[i].host_to_connect, permitted_opens[i].port_to_connect); @@ -2459,7 +2517,8 @@ channel_connect_to(const char *host, u_short port) permit = all_opens_permitted; if (!permit) { for (i = 0; i < num_permitted_opens; i++) - if (permitted_opens[i].port_to_connect == port && + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].port_to_connect == port && strcmp(permitted_opens[i].host_to_connect, host) == 0) permit = 1; diff --git a/channels.h b/channels.h index 7d981479b..0a49c55ea 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.71 2003/09/23 20:41:11 markus Exp $ */ +/* $OpenBSD: channels.h,v 1.72 2004/05/21 11:33:11 djm Exp $ */ /* * Author: Tatu Ylonen @@ -200,8 +200,10 @@ 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); int channel_setup_remote_fwd_listener(const char *, u_short, int); +int channel_cancel_rport_listener(const char *, u_short); /* x11 forwarding */ diff --git a/clientloop.c b/clientloop.c index 9cbc1b0ce..ce627e8b8 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.120 2004/05/20 10:58:05 dtucker Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.121 2004/05/21 11:33:11 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -506,6 +506,7 @@ process_cmdline(void) char *s, *cmd; u_short fwd_port, fwd_host_port; char buf[1024], sfwd_port[6], sfwd_host_port[6]; + int delete = 0; int local = 0; leave_raw_mode(); @@ -515,44 +516,77 @@ process_cmdline(void) goto out; while (*s && isspace(*s)) s++; + if (*s == '-') + s++; /* Skip cmdline '-', if any */ if (*s == '\0') goto out; - if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) { + + if (*s == '?') { + logit("Commands:"); + logit(" -Lport:host:hostport Request local forward"); + logit(" -Rport:host:hostport Request remote forward"); + logit(" -KRhostport Cancel remote forward"); + goto out; + } + + if (*s == 'K') { + delete = 1; + s++; + } + if (*s != 'L' && *s != 'R') { logit("Invalid command."); goto out; } - if (s[1] == 'L') + if (*s == 'L') local = 1; - if (!local && !compat20) { + if (local && delete) { + logit("Not supported."); + goto out; + } + if ((!local || delete) && !compat20) { logit("Not supported for SSH protocol version 1."); goto out; } - s += 2; + + s++; while (*s && isspace(*s)) s++; - 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) { - 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) { - logit("Port forwarding failed."); + if (delete) { + if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) { + logit("Bad forwarding specification."); + goto out; + } + if ((fwd_host_port = a2port(sfwd_host_port)) == 0) { + logit("Bad forwarding port(s)."); + goto out; + } + channel_request_rforward_cancel(fwd_host_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) { + logit("Bad forwarding specification."); goto out; } - } else - channel_request_remote_forwarding(fwd_port, buf, - fwd_host_port); - logit("Forwarding port."); + 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) { + logit("Port forwarding failed."); + goto out; + } + } else + channel_request_remote_forwarding(fwd_port, buf, + fwd_host_port); + logit("Forwarding port."); + } + out: signal(SIGINT, handler); enter_raw_mode(); diff --git a/serverloop.c b/serverloop.c index a777a048d..8d2642d5b 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.116 2004/05/21 11:33:11 djm Exp $"); #include "xmalloc.h" #include "packet.h" @@ -991,6 +991,17 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) listen_address, listen_port, options.gateway_ports); } xfree(listen_address); + } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { + char *cancel_address; + u_short cancel_port; + + cancel_address = packet_get_string(NULL); + cancel_port = (u_short)packet_get_int(); + debug("%s: cancel-tcpip-forward addr %s port %d", __func__, + cancel_address, cancel_port); + + success = channel_cancel_rport_listener(cancel_address, + cancel_port); } if (want_reply) { packet_start(success ? diff --git a/ssh.1 b/ssh.1 index b7b126440..7da143b19 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.185 2004/05/02 11:57:52 dtucker Exp $ +.\" $OpenBSD: ssh.1,v 1.186 2004/05/21 11:33:11 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -302,11 +302,18 @@ Display a list of escape characters. Send a BREAK to the remote system (only useful for SSH protocol version 2 and if the peer supports it). .It Cm ~C -Open command line (only useful for adding port forwardings using the +Open command line. +Currently this allows the addition of port forwardings using the .Fl L and .Fl R -options). +options (see below). +It also allows the cancellation of existing remote port-forwardings +using +.Fl KR Ar hostport . +Basic help is available, using the +.Fl ? +option. .It Cm ~R Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it). -- cgit v1.2.3 From 1973c8889875042977ded9774b4363509f4aa79a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 24 May 2004 10:34:36 +1000 Subject: - djm@cvs.openbsd.org 2004/05/22 06:32:12 [clientloop.c ssh.1] use '-h' for help in ~C commandline instead of '-?'; inspired by jmc@ --- ChangeLog | 5 ++++- clientloop.c | 4 ++-- ssh.1 | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 0e8f4a556..486d4c2ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,9 @@ bz #756: add support for the cancel-tcpip-forward request for the server and the client (through the ~C commandline). reported by z3p AT twistedmatrix.com; ok markus@ + - djm@cvs.openbsd.org 2004/05/22 06:32:12 + [clientloop.c ssh.1] + use '-h' for help in ~C commandline instead of '-?'; inspired by jmc@ 20040523 - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in @@ -1144,4 +1147,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.3362 2004/05/24 00:18:05 dtucker Exp $ +$Id: ChangeLog,v 1.3363 2004/05/24 00:34:36 dtucker Exp $ diff --git a/clientloop.c b/clientloop.c index ce627e8b8..31e604180 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.121 2004/05/21 11:33:11 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.122 2004/05/22 06:32:12 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -521,7 +521,7 @@ process_cmdline(void) if (*s == '\0') goto out; - if (*s == '?') { + if (*s == 'h' || *s == 'H' || *s == '?') { logit("Commands:"); logit(" -Lport:host:hostport Request local forward"); logit(" -Rport:host:hostport Request remote forward"); diff --git a/ssh.1 b/ssh.1 index 7da143b19..008fdde34 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.186 2004/05/21 11:33:11 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.187 2004/05/22 06:32:12 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -311,8 +311,8 @@ options (see below). It also allows the cancellation of existing remote port-forwardings using .Fl KR Ar hostport . -Basic help is available, using the -.Fl ? +Basic help is available, using the +.Fl h option. .It Cm ~R Request rekeying of the connection -- cgit v1.2.3 From e534e1212703c04906d3ab00ba768f3a45bd2370 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 24 May 2004 10:35:14 +1000 Subject: - jmc@cvs.openbsd.org 2004/05/22 16:01:05 [ssh.1] kill whitespace at eol; --- ChangeLog | 5 ++++- ssh.1 | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 486d4c2ac..ff05bc462 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,9 @@ - djm@cvs.openbsd.org 2004/05/22 06:32:12 [clientloop.c ssh.1] use '-h' for help in ~C commandline instead of '-?'; inspired by jmc@ + - jmc@cvs.openbsd.org 2004/05/22 16:01:05 + [ssh.1] + kill whitespace at eol; 20040523 - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in @@ -1147,4 +1150,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.3363 2004/05/24 00:34:36 dtucker Exp $ +$Id: ChangeLog,v 1.3364 2004/05/24 00:35:14 dtucker Exp $ diff --git a/ssh.1 b/ssh.1 index 008fdde34..203e8f288 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.187 2004/05/22 06:32:12 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.188 2004/05/22 16:01:05 jmc Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -308,7 +308,7 @@ Currently this allows the addition of port forwardings using the and .Fl R options (see below). -It also allows the cancellation of existing remote port-forwardings +It also allows the cancellation of existing remote port-forwardings using .Fl KR Ar hostport . Basic help is available, using the -- cgit v1.2.3 From 05202ffe214115afa24bf6e7a6d8c8457e6759bb Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 15 Jun 2004 10:30:39 +1000 Subject: - dtucker@cvs.openbsd.org 2004/06/13 14:01:42 [ssh.1 ssh_config.5 sshd_config.5] List supported ciphers in man pages, tidy up ssh -c; "looks fine" jmc@, ok markus@ --- ChangeLog | 6 +++++- ssh.1 | 51 +++++++++++++++++++++++++++++++++++++-------------- ssh_config.5 | 14 +++++++++++++- sshd_config.5 | 14 +++++++++++++- 4 files changed, 68 insertions(+), 17 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 1d2563ba8..3edf2d19b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,10 @@ [ssh-keyscan.c sshconnect2.c sshd.c] implement diffie-hellman-group14-sha1 kex method (trivial extension to existing diffie-hellman-group1-sha1); ok markus@ + - dtucker@cvs.openbsd.org 2004/06/13 14:01:42 + [ssh.1 ssh_config.5 sshd_config.5] + List supported ciphers in man pages, tidy up ssh -c; + "looks fine" jmc@, ok markus@ 20040603 - (dtucker) [auth-pam.c] Don't use pam_* namespace for sshd's PAM functions. @@ -1204,4 +1208,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.3380 2004/06/15 00:30:09 djm Exp $ +$Id: ChangeLog,v 1.3381 2004/06/15 00:30:39 djm Exp $ diff --git a/ssh.1 b/ssh.1 index 203e8f288..6cef0851d 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.188 2004/05/22 16:01:05 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.189 2004/06/13 14:01:42 dtucker Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -241,8 +241,8 @@ Additionally, supports hostbased or challenge response authentication. .Pp Protocol 2 provides additional mechanisms for confidentiality -(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour) -and integrity (hmac-md5, hmac-sha1). +(the traffic is encrypted using AES, 3DES, Blowfish, CAST128 or Arcfour) +and integrity (hmac-md5, hmac-sha1, hmac-ripemd160). Note that protocol 1 lacks a strong mechanism for ensuring the integrity of the connection. .Ss Login session and remote execution @@ -449,13 +449,18 @@ The default value can be set on a host-by-host basis in the configuration files; see the .Cm Compression option. -.It Fl c Ar blowfish | 3des | des -Selects the cipher to use for encrypting the session. -.Ar 3des -is used by default. -It is believed to be secure. +.It Fl c Ar cipher_spec +Selects the cipher specification for encrypting the session. +.Pp +Protocol version 1 allows specification of a single cipher. +The suported values are +.Dq 3des , +.Dq blowfish +and +.Dq des . .Ar 3des (triple-des) is an encrypt-decrypt-encrypt triple with three different keys. +It is believed to be secure. .Ar blowfish is a fast block cipher; it appears very secure and is much faster than .Ar 3des . @@ -467,12 +472,30 @@ that do not support the .Ar 3des cipher. Its use is strongly discouraged due to cryptographic weaknesses. -.It Fl c Ar cipher_spec -Additionally, for protocol version 2 a comma-separated list of ciphers can -be specified in order of preference. -See -.Cm Ciphers -for more information. +The default is +.Dq 3des . +.Pp +For protocol version 2 +.Ar cipher_spec +is a comma-separated list of ciphers +listed in order of preference. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . +The default is +.Bd -literal + ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, + aes192-cbc,aes256-cbc'' +.Ed .It Fl D Ar port Specifies a local .Dq dynamic diff --git a/ssh_config.5 b/ssh_config.5 index 97fcdd80e..46d3012c8 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.34 2004/05/06 11:24:23 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.35 2004/06/13 14:01:42 dtucker Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -185,6 +185,18 @@ The default is Specifies the ciphers allowed for protocol version 2 in order of preference. Multiple ciphers must be comma-separated. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . The default is .Bd -literal ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, diff --git a/sshd_config.5 b/sshd_config.5 index 8edaf030c..3a377ca74 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.33 2004/05/23 23:59:53 dtucker Exp $ +.\" $OpenBSD: sshd_config.5,v 1.34 2004/06/13 14:01:42 dtucker Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -149,6 +149,18 @@ The default is .It Cm Ciphers Specifies the ciphers allowed for protocol version 2. Multiple ciphers must be comma-separated. +The supported ciphers are +.Dq 3des-cbc , +.Dq aes128-cbc , +.Dq aes192-cbc , +.Dq aes256-cbc , +.Dq aes128-ctr , +.Dq aes192-ctr , +.Dq aes256-ctr , +.Dq arcfour , +.Dq blowfish-cbc , +and +.Dq cast128-cbc . The default is .Bd -literal ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, -- cgit v1.2.3 From 0e220dbfbcc9fe252e8f1f4890dbfa415aad35db Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 15 Jun 2004 10:34:08 +1000 Subject: - djm@cvs.openbsd.org 2004/06/13 15:03:02 [channels.c channels.h clientloop.c clientloop.h includes.h readconf.c] [readconf.h scp.1 sftp.1 ssh.1 ssh.c ssh_config.5] implement session multiplexing in the client (the server has supported this since 2.0); ok markus@ --- ChangeLog | 7 +- channels.c | 76 +++++++++++-- channels.h | 7 +- clientloop.c | 327 ++++++++++++++++++++++++++++++++++++++++++++++++++---- clientloop.h | 4 +- defines.h | 5 +- includes.h | 3 +- readconf.c | 18 ++- readconf.h | 5 +- scp.1 | 4 +- sftp.1 | 4 +- ssh-rand-helper.c | 6 +- ssh.1 | 26 ++++- ssh.c | 276 ++++++++++++++++++++++++++++++--------------- ssh_config.5 | 24 +++- 15 files changed, 650 insertions(+), 142 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 3edf2d19b..36aeb85bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,11 @@ [ssh.1 ssh_config.5 sshd_config.5] List supported ciphers in man pages, tidy up ssh -c; "looks fine" jmc@, ok markus@ + - djm@cvs.openbsd.org 2004/06/13 15:03:02 + [channels.c channels.h clientloop.c clientloop.h includes.h readconf.c] + [readconf.h scp.1 sftp.1 ssh.1 ssh.c ssh_config.5] + implement session multiplexing in the client (the server has supported + this since 2.0); ok markus@ 20040603 - (dtucker) [auth-pam.c] Don't use pam_* namespace for sshd's PAM functions. @@ -1208,4 +1213,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.3381 2004/06/15 00:30:39 djm Exp $ +$Id: ChangeLog,v 1.3382 2004/06/15 00:34:08 djm Exp $ diff --git a/channels.c b/channels.c index 437befa34..1fb1092c8 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.203 2004/05/26 23:02:39 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.204 2004/06/13 15:03:02 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -172,6 +172,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, c->rfd = rfd; c->wfd = wfd; c->sock = (rfd == wfd) ? rfd : -1; + c->ctl_fd = -1; /* XXX: set elsewhere */ c->efd = efd; c->extended_usage = extusage; @@ -263,6 +264,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->single_connection = 0; c->detach_user = NULL; c->confirm = NULL; + c->confirm_ctx = NULL; c->input_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return c; @@ -304,10 +306,11 @@ channel_close_fd(int *fdp) static void channel_close_fds(Channel *c) { - debug3("channel %d: close_fds r %d w %d e %d", - c->self, c->rfd, c->wfd, c->efd); + debug3("channel %d: close_fds r %d w %d e %d c %d", + c->self, c->rfd, c->wfd, c->efd, c->ctl_fd); channel_close_fd(&c->sock); + channel_close_fd(&c->ctl_fd); channel_close_fd(&c->rfd); channel_close_fd(&c->wfd); channel_close_fd(&c->efd); @@ -333,6 +336,8 @@ channel_free(Channel *c) if (c->sock != -1) shutdown(c->sock, SHUT_RDWR); + if (c->ctl_fd != -1) + shutdown(c->ctl_fd, SHUT_RDWR); channel_close_fds(c); buffer_free(&c->input); buffer_free(&c->output); @@ -550,12 +555,13 @@ channel_open_message(void) case SSH_CHANNEL_X11_OPEN: case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: - snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n", + snprintf(buf, sizeof buf, + " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cfd %d)\r\n", c->self, c->remote_name, c->type, c->remote_id, c->istate, buffer_len(&c->input), c->ostate, buffer_len(&c->output), - c->rfd, c->wfd); + c->rfd, c->wfd, c->ctl_fd); buffer_append(&buffer, buf, strlen(buf)); continue; default: @@ -596,14 +602,14 @@ channel_request_start(int id, char *service, int wantconfirm) logit("channel_request_start: %d: unknown channel id", id); return; } - debug2("channel %d: request %s", id, service) ; + debug2("channel %d: request %s confirm %d", id, service, wantconfirm); packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring(service); packet_put_char(wantconfirm); } void -channel_register_confirm(int id, channel_callback_fn *fn) +channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) { Channel *c = channel_lookup(id); @@ -612,6 +618,7 @@ channel_register_confirm(int id, channel_callback_fn *fn) return; } c->confirm = fn; + c->confirm_ctx = ctx; } void channel_register_cleanup(int id, channel_callback_fn *fn) @@ -729,6 +736,10 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) buffer_len(&c->extended) < c->remote_window) FD_SET(c->efd, readset); } + /* XXX: What about efd? races? */ + if (compat20 && c->ctl_fd != -1 && + c->istate == CHAN_INPUT_OPEN && c->ostate == CHAN_OUTPUT_OPEN) + FD_SET(c->ctl_fd, readset); } static void @@ -1482,6 +1493,33 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) return 1; } static int +channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset) +{ + char buf[16]; + int len; + + /* Monitor control fd to detect if the slave client exits */ + if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) { + len = read(c->ctl_fd, buf, sizeof(buf)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + debug2("channel %d: ctl read<=0", c->self); + if (c->type != SSH_CHANNEL_OPEN) { + debug2("channel %d: not open", c->self); + chan_mark_dead(c); + return -1; + } else { + chan_read_failed(c); + chan_write_failed(c); + } + return -1; + } else + fatal("%s: unexpected data on ctl fd", __func__); + } + return 1; +} +static int channel_check_window(Channel *c) { if (c->type == SSH_CHANNEL_OPEN && @@ -1511,6 +1549,7 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset) if (!compat20) return; channel_handle_efd(c, readset, writeset); + channel_handle_ctl(c, readset, writeset); channel_check_window(c); } @@ -2011,7 +2050,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) c->remote_maxpacket = packet_get_int(); if (c->confirm) { debug2("callback start"); - c->confirm(c->self, NULL); + c->confirm(c->self, c->confirm_ctx); debug2("callback done"); } debug2("channel %d: open confirm rwindow %u rmax %u", c->self, @@ -2531,6 +2570,27 @@ channel_connect_to(const char *host, u_short port) return connect_to(host, port); } +void +channel_send_window_changes(void) +{ + int i; + struct winsize ws; + + for (i = 0; i < channels_alloc; i++) { + if (channels[i] == NULL || + channels[i]->type != SSH_CHANNEL_OPEN) + continue; + if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) + continue; + channel_request_start(i, "window-change", 0); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + packet_send(); + } +} + /* -- X11 forwarding */ /* diff --git a/channels.h b/channels.h index 0a49c55ea..41f3cedd3 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.72 2004/05/21 11:33:11 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.73 2004/06/13 15:03:02 djm Exp $ */ /* * Author: Tatu Ylonen @@ -76,6 +76,7 @@ struct Channel { int wfd; /* write fd */ int efd; /* extended fd */ int sock; /* sock fd */ + int ctl_fd; /* control fd (client sharing) */ int isatty; /* rfd is a tty */ int wfd_isatty; /* wfd is a tty */ int force_drain; /* force close on iEOF */ @@ -105,6 +106,7 @@ struct Channel { /* callback */ channel_callback_fn *confirm; channel_callback_fn *detach_user; + void *confirm_ctx; /* filter */ channel_filter_fn *input_filter; @@ -161,10 +163,11 @@ void channel_stop_listening(void); void channel_send_open(int); void channel_request_start(int, char *, int); void channel_register_cleanup(int, channel_callback_fn *); -void channel_register_confirm(int, channel_callback_fn *); +void channel_register_confirm(int, channel_callback_fn *, void *); void channel_register_filter(int, channel_filter_fn *); void channel_cancel_cleanup(int); int channel_close_fd(int *); +void channel_send_window_changes(void); /* protocol handler */ diff --git a/clientloop.c b/clientloop.c index 31e604180..6401588a9 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.122 2004/05/22 06:32:12 djm Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.123 2004/06/13 15:03:02 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -81,6 +81,9 @@ RCSID("$OpenBSD: clientloop.c,v 1.122 2004/05/22 06:32:12 djm Exp $"); #include "atomicio.h" #include "sshpty.h" #include "misc.h" +#include "monitor_fdpass.h" +#include "match.h" +#include "msg.h" /* import options */ extern Options options; @@ -91,6 +94,9 @@ extern int stdin_null_flag; /* Flag indicating that no shell has been requested */ extern int no_shell_flag; +/* Control socket */ +extern int control_fd; + /* * Name of the host we are connecting to. This is the name given on the * command line, or the HostName specified for the user-supplied name in a @@ -131,9 +137,19 @@ static int server_alive_timeouts = 0; static void client_init_dispatch(void); int session_ident = -1; +struct confirm_ctx { + int want_tty; + int want_subsys; + Buffer cmd; + char *term; + struct termios tio; +}; + /*XXX*/ extern Kex *xxx_kex; +void ssh_process_session2_setup(int, int, int, Buffer *); + /* Restores stdin to blocking mode. */ static void @@ -291,19 +307,13 @@ client_check_window_change(void) /** XXX race */ received_window_change_signal = 0; - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - return; - debug2("client_check_window_change: changed"); if (compat20) { - channel_request_start(session_ident, "window-change", 0); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - packet_send(); + channel_send_window_changes(); } else { + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) + return; packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int(ws.ws_row); packet_put_int(ws.ws_col); @@ -335,7 +345,6 @@ server_alive_check(void) * Waits until the client can do something (some data becomes available on * one of the file descriptors). */ - static void client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, int *nallocp, int rekeying) @@ -381,6 +390,9 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); + if (control_fd != -1) + FD_SET(control_fd, *readsetp); + /* * Wait for something to happen. This will suspend the process until * some selected descriptor can be read, written, or has some other @@ -499,6 +511,176 @@ client_process_net_input(fd_set * readset) } } +static void +client_subsystem_reply(int type, u_int32_t seq, void *ctxt) +{ + int id; + Channel *c; + + id = packet_get_int(); + packet_check_eom(); + + if ((c = channel_lookup(id)) == NULL) { + error("%s: no channel for id %d", __func__, id); + return; + } + + if (type == SSH2_MSG_CHANNEL_SUCCESS) + debug2("Request suceeded on channel %d", id); + else if (type == SSH2_MSG_CHANNEL_FAILURE) { + error("Request failed on channel %d", id); + channel_free(c); + } +} + +static void +client_extra_session2_setup(int id, void *arg) +{ + struct confirm_ctx *cctx = arg; + Channel *c; + + if (cctx == NULL) + fatal("%s: cctx == NULL", __func__); + if ((c = channel_lookup(id)) == NULL) + fatal("%s: no channel for id %d", __func__, id); + + client_session2_setup(id, cctx->want_tty, cctx->want_subsys, + cctx->term, &cctx->tio, c->rfd, &cctx->cmd, + client_subsystem_reply); + + c->confirm_ctx = NULL; + buffer_free(&cctx->cmd); + free(cctx->term); + free(cctx); +} + +static void +client_process_control(fd_set * readset) +{ + Buffer m; + Channel *c; + int client_fd, new_fd[3], ver; + socklen_t addrlen; + struct sockaddr_storage addr; + struct confirm_ctx *cctx; + char *cmd; + u_int len; + uid_t euid; + gid_t egid; + + /* + * Accept connection on control socket + */ + if (control_fd == -1 || !FD_ISSET(control_fd, readset)) + return; + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + if ((client_fd = accept(control_fd, + (struct sockaddr*)&addr, &addrlen)) == -1) { + error("%s accept: %s", __func__, strerror(errno)); + return; + } + + if (getpeereid(client_fd, &euid, &egid) < 0) { + error("%s getpeereid failed: %s", __func__, strerror(errno)); + close(client_fd); + return; + } + if ((euid != 0) && (getuid() != euid)) { + error("control mode uid mismatch: peer euid %u != uid %u", + (u_int) euid, (u_int) getuid()); + close(client_fd); + return; + } + /* XXX: implement use of ssh-askpass to confirm additional channels */ + + unset_nonblock(client_fd); + + buffer_init(&m); + + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + return; + } + buffer_clear(&m); + + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + return; + } + + if ((ver = buffer_get_char(&m)) != 0) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return; + } + + cctx = xmalloc(sizeof(*cctx)); + memset(cctx, 0, sizeof(*cctx)); + + cctx->want_tty = buffer_get_int(&m); + cctx->want_subsys = buffer_get_int(&m); + cctx->term = buffer_get_string(&m, &len); + + cmd = buffer_get_string(&m, &len); + buffer_init(&cctx->cmd); + buffer_append(&cctx->cmd, cmd, strlen(cmd)); + + debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, + cctx->want_tty, cctx->want_subsys, cmd); + + /* Gather fds from client */ + new_fd[0] = mm_receive_fd(client_fd); + new_fd[1] = mm_receive_fd(client_fd); + new_fd[2] = mm_receive_fd(client_fd); + + debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, + new_fd[0], new_fd[1], new_fd[2]); + + /* Try to pick up ttymodes from client before it goes raw */ + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error("%s: tcgetattr: %s", __func__, strerror(errno)); + + buffer_clear(&m); + if (ssh_msg_send(client_fd, /* version */0, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + close(new_fd[0]); + close(new_fd[1]); + close(new_fd[2]); + return; + } + buffer_free(&m); + + /* enable nonblocking unless tty */ + if (!isatty(new_fd[0])) + set_nonblock(new_fd[0]); + if (!isatty(new_fd[1])) + set_nonblock(new_fd[1]); + if (!isatty(new_fd[2])) + set_nonblock(new_fd[2]); + + set_nonblock(client_fd); + + c = channel_new("session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], + CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, + CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); + + /* XXX */ + c->ctl_fd = client_fd; + + debug3("%s: channel_new: %d", __func__, c->self); + + channel_send_open(c->self); + channel_register_confirm(c->self, client_extra_session2_setup, cctx); +} + static void process_cmdline(void) { @@ -901,9 +1083,6 @@ simple_escape_filter(Channel *c, char *buf, int len) static void client_channel_closed(int id, void *arg) { - if (id != session_ident) - error("client_channel_closed: id %d != session_ident %d", - id, session_ident); channel_cancel_cleanup(id); session_closed = 1; leave_raw_mode(); @@ -937,6 +1116,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); max_fd = MAX(connection_in, connection_out); + if (control_fd != -1) + max_fd = MAX(max_fd, control_fd); if (!compat20) { /* enable nonblocking unless tty */ @@ -1054,6 +1235,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Buffer input from the connection. */ client_process_net_input(readset); + /* Accept control connections. */ + client_process_control(readset); + if (quit_pending) break; @@ -1385,7 +1569,7 @@ static void client_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; - int id, reply, success = 0; + int exitval, id, reply, success = 0; char *rtype; id = packet_get_int(); @@ -1395,18 +1579,21 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) debug("client_input_channel_req: channel %d rtype %s reply %d", id, rtype, reply); - if (session_ident == -1) { - error("client_input_channel_req: no channel %d", session_ident); - } else if (id != session_ident) { - error("client_input_channel_req: channel %d: wrong channel: %d", - session_ident, id); - } c = channel_lookup(id); if (c == NULL) { error("client_input_channel_req: channel %d: unknown channel", id); } else if (strcmp(rtype, "exit-status") == 0) { - success = 1; - exit_status = packet_get_int(); + exitval = packet_get_int(); + if (id == session_ident) { + success = 1; + exit_status = exitval; + } else if (c->ctl_fd == -1) { + error("client_input_channel_req: unexpected channel %d", + session_ident); + } else { + atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval)); + success = 1; + } packet_check_eom(); } if (reply) { @@ -1437,6 +1624,98 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) xfree(rtype); } +void +client_session2_setup(int id, int want_tty, int want_subsystem, + const char *term, struct termios *tiop, int in_fd, Buffer *cmd, + dispatch_fn *subsys_repl) +{ + int len; + + debug2("%s: id %d", __func__, id); + + if (want_tty) { + struct winsize ws; + struct termios tio; + + /* Store window size in the packet. */ + if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) + memset(&ws, 0, sizeof(ws)); + + channel_request_start(id, "pty-req", 0); + packet_put_cstring(term != NULL ? term : ""); + packet_put_int(ws.ws_col); + packet_put_int(ws.ws_row); + packet_put_int(ws.ws_xpixel); + packet_put_int(ws.ws_ypixel); + tio = get_saved_tio(); + tty_make_modes(-1, tiop != NULL ? tiop : &tio); + packet_send(); + /* XXX wait for reply */ + } + + /* Transfer any environment variables from client to server */ + if (options.num_send_env != 0) { + int i, j, matched; + extern char **environ; + char *name, *val; + + debug("Sending environment."); + for (i = 0; environ && environ[i] != NULL; i++) { + /* Split */ + name = xstrdup(environ[i]); + if ((val = strchr(name, '=')) == NULL) { + free(name); + continue; + } + *val++ = '\0'; + + matched = 0; + for (j = 0; j < options.num_send_env; j++) { + if (match_pattern(name, options.send_env[j])) { + matched = 1; + break; + } + } + if (!matched) { + debug3("Ignored env %s", name); + free(name); + continue; + } + + debug("Sending env %s = %s", name, val); + channel_request_start(id, "env", 0); + packet_put_cstring(name); + packet_put_cstring(val); + packet_send(); + free(name); + } + } + + len = buffer_len(cmd); + if (len > 0) { + if (len > 900) + len = 900; + if (want_subsystem) { + debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "subsystem", subsys_repl != NULL); + if (subsys_repl != NULL) { + /* register callback for reply */ + /* XXX we assume that client_loop has already been called */ + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl); + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl); + } + } else { + debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "exec", 0); + } + packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); + packet_send(); + } else { + channel_request_start(id, "shell", 0); + packet_send(); + } +} + static void client_init_dispatch_20(void) { @@ -1503,5 +1782,7 @@ cleanup_exit(int i) { leave_raw_mode(); leave_non_blocking(); + if (options.control_path != NULL && control_fd != -1) + unlink(options.control_path); _exit(i); } diff --git a/clientloop.h b/clientloop.h index 56af06bc1..f1e13ac3a 100644 --- a/clientloop.h +++ b/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.8 2003/12/16 15:49:51 markus Exp $ */ +/* $OpenBSD: clientloop.h,v 1.9 2004/06/13 15:03:02 djm Exp $ */ /* * Author: Tatu Ylonen @@ -38,3 +38,5 @@ /* Client side main loop for the interactive session. */ 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 *, dispatch_fn *); diff --git a/defines.h b/defines.h index 9b72afecb..73a45fe44 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.115 2004/04/14 07:24:30 dtucker Exp $ */ +/* $Id: defines.h,v 1.116 2004/06/15 00:34:08 djm Exp $ */ /* Constants */ @@ -462,6 +462,9 @@ struct winsize { (struct cmsghdr *)NULL) #endif /* CMSG_FIRSTHDR */ +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif /* Function replacement / compatibility hacks */ diff --git a/includes.h b/includes.h index ca943c7e6..99b70502c 100644 --- a/includes.h +++ b/includes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: includes.h,v 1.17 2002/01/26 16:44:22 stevesk Exp $ */ +/* $OpenBSD: includes.h,v 1.18 2004/06/13 15:03:02 djm Exp $ */ /* * Author: Tatu Ylonen @@ -33,6 +33,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include #include #include +#include #ifdef HAVE_LIMITS_H # include /* For PATH_MAX */ diff --git a/readconf.c b/readconf.c index 5aa371ed9..2b1d7cc46 100644 --- a/readconf.c +++ b/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.131 2004/05/27 00:50:13 dtucker Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.132 2004/06/13 15:03:02 djm Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -106,7 +106,7 @@ typedef enum { oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, - oSendEnv, + oSendEnv, oControlPath, oControlMaster, oDeprecated, oUnsupported } OpCodes; @@ -195,6 +195,8 @@ static struct { { "serveraliveinterval", oServerAliveInterval }, { "serveralivecountmax", oServerAliveCountMax }, { "sendenv", oSendEnv }, + { "controlpath", oControlPath }, + { "controlmaster", oControlMaster }, { NULL, oBadOption } }; @@ -764,6 +766,14 @@ parse_int: } break; + case oControlPath: + charptr = &options->control_path; + goto parse_string; + + case oControlMaster: + intptr = &options->control_master; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -905,6 +915,8 @@ initialize_options(Options * options) options->server_alive_interval = -1; options->server_alive_count_max = -1; options->num_send_env = 0; + options->control_path = NULL; + options->control_master = -1; } /* @@ -1025,6 +1037,8 @@ fill_default_options(Options * options) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; + if (options->control_master == -1) + options->control_master = 0; /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ diff --git a/readconf.h b/readconf.h index 668055943..5e504bece 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.62 2004/04/27 09:46:37 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.63 2004/06/13 15:03:02 djm Exp $ */ /* * Author: Tatu Ylonen @@ -108,6 +108,9 @@ typedef struct { int num_send_env; char *send_env[MAX_SEND_ENV]; + + char *control_path; + int control_master; } Options; diff --git a/scp.1 b/scp.1 index 202ebaadb..f346b2ae9 100644 --- a/scp.1 +++ b/scp.1 @@ -9,7 +9,7 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.35 2004/05/04 18:36:07 jmc Exp $ +.\" $OpenBSD: scp.1,v 1.36 2004/06/13 15:03:02 djm Exp $ .\" .Dd September 25, 1999 .Dt SCP 1 @@ -128,6 +128,8 @@ For full details of the options listed below, and their possible values, see .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout +.It ControlMaster +.It ControlPath .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials diff --git a/sftp.1 b/sftp.1 index 795a0342f..7f0ef1121 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.54 2004/05/02 23:02:17 dtucker Exp $ +.\" $OpenBSD: sftp.1,v 1.55 2004/06/13 15:03:02 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -154,6 +154,8 @@ For full details of the options listed below, and their possible values, see .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout +.It ControlMaster +.It ControlPath .It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials diff --git a/ssh-rand-helper.c b/ssh-rand-helper.c index 8a320a71e..471e7295b 100644 --- a/ssh-rand-helper.c +++ b/ssh-rand-helper.c @@ -39,7 +39,7 @@ #include "pathnames.h" #include "log.h" -RCSID("$Id: ssh-rand-helper.c,v 1.16 2003/11/21 12:56:47 djm Exp $"); +RCSID("$Id: ssh-rand-helper.c,v 1.17 2004/06/15 00:34:08 djm Exp $"); /* Number of bytes we write out */ #define OUTPUT_SEED_SIZE 48 @@ -69,10 +69,6 @@ extern char *__progname; char *__progname; #endif -#ifndef offsetof -# define offsetof(type, member) ((size_t) &((type *)0)->member) -#endif - #define WHITESPACE " \t\n" #ifndef RUSAGE_SELF diff --git a/ssh.1 b/ssh.1 index 6cef0851d..b70102be5 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.189 2004/06/13 14:01:42 dtucker Exp $ +.\" $OpenBSD: ssh.1,v 1.190 2004/06/13 15:03:02 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -43,7 +43,7 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Op Fl 1246AaCfgkNnqsTtVvXxY +.Op Fl 1246AaCfgkMNnqSsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl D Ar port @@ -605,6 +605,17 @@ be specified in order of preference. See the .Cm MACs keyword for more information. +.It Fl M +Places the +.Nm +client into +.Dq master +mode for connection sharing. +Refer to the description of +.Cm ControlMaster +in +.Xr ssh_config 5 +for details. .It Fl N Do not execute a remote command. This is useful for just forwarding ports @@ -649,6 +660,8 @@ For full details of the options listed below, and their possible values, see .It CompressionLevel .It ConnectionAttempts .It ConnectTimeout +.It ControlMaster +.It ControlPath .It DynamicForward .It EscapeChar .It ForwardAgent @@ -724,6 +737,15 @@ IPv6 addresses can be specified with an alternative syntax: .Ar hostport . .Xc .Sm on +.It Fl S +Places the +.Nm +client into slave mode for connection sharing. +Refer to the description of +.Cm ControlMaster +in +.Xr ssh_config 5 +for details. .It Fl s May be used to request invocation of a subsystem on the remote system. Subsystems are a feature of the SSH2 protocol which facilitate the use diff --git a/ssh.c b/ssh.c index 3c21fa37d..1c6ec8b6a 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.213 2004/05/08 00:01:37 deraadt Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.214 2004/06/13 15:03:02 djm Exp $"); #include #include @@ -53,21 +53,24 @@ RCSID("$OpenBSD: ssh.c,v 1.213 2004/05/08 00:01:37 deraadt Exp $"); #include "xmalloc.h" #include "packet.h" #include "buffer.h" +#include "bufaux.h" #include "channels.h" #include "key.h" #include "authfd.h" #include "authfile.h" #include "pathnames.h" +#include "dispatch.h" #include "clientloop.h" #include "log.h" #include "readconf.h" #include "sshconnect.h" -#include "dispatch.h" #include "misc.h" #include "kex.h" #include "mac.h" #include "sshpty.h" #include "match.h" +#include "msg.h" +#include "monitor_fdpass.h" #ifdef SMARTCARD #include "scard.h" @@ -141,6 +144,13 @@ static int client_global_request_id = 0; /* pid of proxycommand child process */ pid_t proxy_command_pid = 0; +/* fd to control socket */ +int control_fd = -1; + +/* Only used in control client mode */ +volatile sig_atomic_t control_client_terminate = 0; +u_int control_server_pid = 0; + /* Prints a help message to the user. This function never returns. */ static void @@ -158,6 +168,7 @@ usage(void) static int ssh_session(void); static int ssh_session2(void); static void load_public_identity_files(void); +static void control_client(const char *path); /* * Main program for the ssh client. @@ -228,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:NPR:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -364,6 +375,9 @@ again: exit(1); } break; + case 'M': + options.control_master = 1; + break; case 'p': options.port = a2port(optarg); if (options.port == 0) { @@ -432,6 +446,13 @@ again: case 's': subsystem_flag = 1; break; + case 'S': + if (options.control_path != NULL) + free(options.control_path); + options.control_path = xstrdup(optarg); + if (options.control_master == -1) + options.control_master = 0; + break; case 'b': options.bind_address = optarg; break; @@ -566,6 +587,13 @@ again: strcmp(options.proxy_command, "none") == 0) options.proxy_command = NULL; + if (options.control_path != NULL) { + options.control_path = tilde_expand_filename( + options.control_path, original_real_uid); + } + if (options.control_path != NULL && options.control_master == 0) + control_client(options.control_path); /* This doesn't return */ + /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, options.address_family, options.connection_attempts, @@ -678,6 +706,9 @@ again: exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); + if (options.control_path != NULL && control_fd != -1) + unlink(options.control_path); + /* * Send SIGHUP to proxy command if used. We don't wait() in * case it hangs and instead rely on init to reap the child @@ -974,7 +1005,7 @@ ssh_session(void) } static void -client_subsystem_reply(int type, u_int32_t seq, void *ctxt) +ssh_subsystem_reply(int type, u_int32_t seq, void *ctxt) { int id, len; @@ -1006,40 +1037,50 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) options.remote_forwards[i].port); } -/* request pty/x11/agent/tcpfwd/shell for channel */ static void -ssh_session2_setup(int id, void *arg) +ssh_control_listener(void) { - int len; - int interactive = 0; - struct termios tio; + struct sockaddr_un addr; + mode_t old_umask; + + if (options.control_path == NULL || options.control_master != 1) + return; - debug2("ssh_session2_setup: id %d", id); + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr.sun_len = offsetof(struct sockaddr_un, sun_path) + + strlen(options.control_path) + 1; - if (tty_flag) { - struct winsize ws; - char *cp; - cp = getenv("TERM"); - if (!cp) - cp = ""; - /* Store window size in the packet. */ - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) - memset(&ws, 0, sizeof(ws)); + if (strlcpy(addr.sun_path, options.control_path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); - channel_request_start(id, "pty-req", 0); - packet_put_cstring(cp); - packet_put_int(ws.ws_col); - packet_put_int(ws.ws_row); - packet_put_int(ws.ws_xpixel); - packet_put_int(ws.ws_ypixel); - tio = get_saved_tio(); - tty_make_modes(/*ignored*/ 0, &tio); - packet_send(); - interactive = 1; - /* XXX wait for reply */ + if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s\n", __func__, strerror(errno)); + + old_umask = umask(0177); + if (bind(control_fd, (struct sockaddr*)&addr, addr.sun_len) == -1) { + control_fd = -1; + if (errno == EINVAL) + fatal("ControlSocket %s already exists", + options.control_path); + else + fatal("%s bind(): %s\n", __func__, strerror(errno)); } - if (options.forward_x11 && - getenv("DISPLAY") != NULL) { + umask(old_umask); + + if (listen(control_fd, 64) == -1) + fatal("%s listen(): %s\n", __func__, strerror(errno)); + + set_nonblock(control_fd); +} + +/* request pty/x11/agent/tcpfwd/shell for channel */ +static void +ssh_session2_setup(int id, void *arg) +{ + int interactive = tty_flag; + if (options.forward_x11 && getenv("DISPLAY") != NULL) { char *proto, *data; /* Get reasonable local authentication information. */ x11_get_proto(&proto, &data); @@ -1057,65 +1098,8 @@ ssh_session2_setup(int id, void *arg) packet_send(); } - /* Transfer any environment variables from client to server */ - if (options.num_send_env != 0) { - int i, j, matched; - extern char **environ; - char *name, *val; - - debug("Sending environment."); - for (i = 0; environ && environ[i] != NULL; i++) { - /* Split */ - name = xstrdup(environ[i]); - if ((val = strchr(name, '=')) == NULL) { - free(name); - continue; - } - *val++ = '\0'; - - matched = 0; - for (j = 0; j < options.num_send_env; j++) { - if (match_pattern(name, options.send_env[j])) { - matched = 1; - break; - } - } - if (!matched) { - debug3("Ignored env %s", name); - free(name); - continue; - } - - debug("Sending env %s = %s", name, val); - channel_request_start(id, "env", 0); - packet_put_cstring(name); - packet_put_cstring(val); - packet_send(); - free(name); - } - } - - len = buffer_len(&command); - if (len > 0) { - if (len > 900) - len = 900; - if (subsystem_flag) { - debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "subsystem", /*want reply*/ 1); - /* register callback for reply */ - /* XXX we assume that client_loop has already been called */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply); - dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply); - } else { - debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); - channel_request_start(id, "exec", 0); - } - packet_put_string(buffer_ptr(&command), buffer_len(&command)); - packet_send(); - } else { - channel_request_start(id, "shell", 0); - packet_send(); - } + client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), + NULL, fileno(stdin), &command, &ssh_subsystem_reply); packet_set_interactive(interactive); } @@ -1161,7 +1145,7 @@ ssh_session2_open(void) channel_send_open(c->self); if (!no_shell_flag) - channel_register_confirm(c->self, ssh_session2_setup); + channel_register_confirm(c->self, ssh_session2_setup, NULL); return c->self; } @@ -1173,6 +1157,7 @@ ssh_session2(void) /* XXX should be pre-session */ ssh_init_forwarding(); + ssh_control_listener(); if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); @@ -1226,3 +1211,110 @@ load_public_identity_files(void) options.identity_keys[i] = public; } } + +static void +control_client_sighandler(int signo) +{ + control_client_terminate = signo; +} + +static void +control_client_sigrelay(int signo) +{ + if (control_server_pid > 1) + kill(control_server_pid, signo); +} + +static void +control_client(const char *path) +{ + struct sockaddr_un addr; + int r, sock, exitval; + Buffer m; + char *cp; + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr.sun_len = offsetof(struct sockaddr_un, sun_path) + + strlen(path) + 1; + + if (strlcpy(addr.sun_path, path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + if (connect(sock, (struct sockaddr*)&addr, addr.sun_len) == -1) + fatal("Couldn't connect to %s: %s", path, strerror(errno)); + + if ((cp = getenv("TERM")) == NULL) + cp = ""; + + signal(SIGINT, control_client_sighandler); + signal(SIGTERM, control_client_sighandler); + signal(SIGWINCH, control_client_sigrelay); + + buffer_init(&m); + + /* Get PID of controlee */ + if (ssh_msg_recv(sock, &m) == -1) + fatal("%s: msg_recv", __func__); + if (buffer_get_char(&m) != 0) + fatal("%s: wrong version", __func__); + control_server_pid = buffer_get_int(&m); + + /* XXX: env passing */ + + buffer_clear(&m); + buffer_put_int(&m, tty_flag); + buffer_put_int(&m, subsystem_flag); + buffer_put_cstring(&m, cp); + + buffer_append(&command, "\0", 1); + buffer_put_cstring(&m, buffer_ptr(&command)); + + if (ssh_msg_send(sock, /* version */0, &m) == -1) + fatal("%s: msg_send", __func__); + + mm_send_fd(sock, STDIN_FILENO); + mm_send_fd(sock, STDOUT_FILENO); + mm_send_fd(sock, STDERR_FILENO); + + /* Wait for reply, so master has a chance to gather ttymodes */ + 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__); + buffer_free(&m); + + if (tty_flag) + enter_raw_mode(); + + /* Stick around until the controlee closes the client_fd */ + exitval = 0; + for (;!control_client_terminate;) { + r = read(sock, &exitval, sizeof(exitval)); + if (r == 0) { + debug2("Received EOF from master"); + break; + } + if (r > 0) + debug2("Received exit status from master %d", exitval); + if (r == -1 && errno != EINTR) + fatal("%s: read %s", __func__, strerror(errno)); + } + + if (control_client_terminate) + debug2("Exiting on signal %d", control_client_terminate); + + close(sock); + + leave_raw_mode(); + + if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) + fprintf(stderr, "Connection to master closed.\r\n"); + + exit(exitval); +} diff --git a/ssh_config.5 b/ssh_config.5 index 46d3012c8..bab11d313 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.35 2004/06/13 14:01:42 dtucker Exp $ +.\" $OpenBSD: ssh_config.5,v 1.36 2004/06/13 15:03:02 djm Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -256,6 +256,28 @@ will act as a SOCKS server. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. +.It Cm ControlMaster +Enables the sharing of multiple sessions over a single network connection. +When set to +.Dq yes +.Nm ssh +will listen for connections on a control socket specified using the +.Cm ControlPath +argument. +Additional sessions can connect to this socket using the same +.Cm ControlPath +with +.Cm ControlMaster +set to +.Dq no +(the default.) +These sessions will reuse the master instance's network connection rather +than initiating new ones. +.It Cm ControlPath +Specify a the path to the control socket used for connection sharing. +See +.Cm ControlMaster +above. .It Cm EnableSSHKeysign Setting this option to .Dq yes -- cgit v1.2.3 From ba5c592126c70587b6fb6887494f1e29a8a05e09 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 18 Jun 2004 16:22:39 +1000 Subject: - djm@cvs.openbsd.org 2004/06/17 23:56:57 [ssh.1 ssh.c] sync usage() and SYNPOSIS with connection sharing changes --- ChangeLog | 6 +++++- ssh.1 | 13 +++++++------ ssh.c | 7 ++++--- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 96701bfef..2a24d8812 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,10 @@ shared connection env passing regress test - (dtucker) [regress/README.regress] Add detail on how to run a single test from the top-level Makefile. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2004/06/17 23:56:57 + [ssh.1 ssh.c] + sync usage() and SYNPOSIS with connection sharing changes 20040617 - (dtucker) [regress/scp.sh] diff -N is not portable (but needed for some @@ -1285,4 +1289,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.3408 2004/06/18 04:14:43 dtucker Exp $ +$Id: ChangeLog,v 1.3409 2004/06/18 06:22:39 dtucker Exp $ diff --git a/ssh.1 b/ssh.1 index b70102be5..dcd02c28f 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.190 2004/06/13 15:03:02 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.191 2004/06/17 23:56:57 djm Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -43,7 +43,7 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Op Fl 1246AaCfgkMNnqSsTtVvXxY +.Op Fl 1246AaCfgkMNnqsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl D Ar port @@ -74,6 +74,7 @@ .Sm on .Xc .Oc +.Op Fl S Ar ctl_path .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Sh DESCRIPTION @@ -737,11 +738,11 @@ IPv6 addresses can be specified with an alternative syntax: .Ar hostport . .Xc .Sm on -.It Fl S -Places the -.Nm -client into slave mode for connection sharing. +.It Fl S Ar ctl_path +Specifies the location of a control socket for for connection sharing. Refer to the description of +.Cm ControlPath +and .Cm ControlMaster in .Xr ssh_config 5 diff --git a/ssh.c b/ssh.c index 6f8114d53..16284f824 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.216 2004/06/17 15:10:14 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.217 2004/06/17 23:56:57 djm Exp $"); #include #include @@ -157,10 +157,11 @@ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfghkNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-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] [user@]hostname [command]\n" +" [-p port] [-R port:host:hostport] [-S ctl_path]\n" +" [user@]hostname [command]\n" ); exit(1); } -- cgit v1.2.3 From b8ea24868f0347ea6d5116cbd93197c1ab0e942b Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 18 Jun 2004 22:21:55 +1000 Subject: - markus@cvs.openbsd.org 2004/06/18 10:55:43 [ssh.1 ssh.c] trim synopsis for -S, allow -S and -oControlMaster, -MM means 'ask'; ok djm --- ChangeLog | 6 +++++- ssh.1 | 6 +++--- ssh.c | 10 ++++------ 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 56237e3de..adbb925ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,10 @@ [ssh.c] delay signal handler setup until we have finished talking to the master. allow interrupting of setup (e.g. if master is stuck); ok markus@ + - markus@cvs.openbsd.org 2004/06/18 10:55:43 + [ssh.1 ssh.c] + trim synopsis for -S, allow -S and -oControlMaster, -MM means 'ask'; + ok djm 20040617 - (dtucker) [regress/scp.sh] diff -N is not portable (but needed for some @@ -1301,4 +1305,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.3412 2004/06/18 12:20:57 djm Exp $ +$Id: ChangeLog,v 1.3413 2004/06/18 12:21:55 djm Exp $ diff --git a/ssh.1 b/ssh.1 index dcd02c28f..5cdeee2da 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.191 2004/06/17 23:56:57 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.192 2004/06/18 10:55:43 markus Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -74,7 +74,7 @@ .Sm on .Xc .Oc -.Op Fl S Ar ctl_path +.Op Fl S Ar ctl .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Sh DESCRIPTION @@ -738,7 +738,7 @@ IPv6 addresses can be specified with an alternative syntax: .Ar hostport . .Xc .Sm on -.It Fl S Ar ctl_path +.It Fl S Ar ctl Specifies the location of a control socket for for connection sharing. Refer to the description of .Cm ControlPath diff --git a/ssh.c b/ssh.c index 89b038198..59f4f41bd 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.218 2004/06/18 10:40:19 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.219 2004/06/18 10:55:43 markus Exp $"); #include #include @@ -160,8 +160,7 @@ usage(void) "usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-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_path]\n" -" [user@]hostname [command]\n" +" [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\n" ); exit(1); } @@ -377,7 +376,8 @@ again: } break; case 'M': - options.control_master = 1; + options.control_master = + (options.control_master >= 1) ? 2 : 1; break; case 'p': options.port = a2port(optarg); @@ -451,8 +451,6 @@ again: if (options.control_path != NULL) free(options.control_path); options.control_path = xstrdup(optarg); - if (options.control_master == -1) - options.control_master = 0; break; case 'b': options.bind_address = optarg; -- cgit v1.2.3 From 5d1ecebcb5c3e7d59bc9a77941556e6ebc0153d8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 30 Jun 2004 22:37:57 +1000 Subject: - OpenBSD CVS Sync - jmc@cvs.openbsd.org 2004/06/26 09:03:21 [ssh.1] - remove double word - rearrange .Bk to keep SYNOPSIS nice - -M before -m in options description --- ChangeLog | 8 +++++++- ssh.1 | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 3e33e2f22..511aeb2bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ 20040630 - (dtucker) [auth-pam.c] Check for buggy PAM modules that return a NULL appdata_ptr to the conversation function. ok djm@ + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2004/06/26 09:03:21 + [ssh.1] + - remove double word + - rearrange .Bk to keep SYNOPSIS nice + - -M before -m in options description 20040627 - (tim) update README files. @@ -1447,4 +1453,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.3458 2004/06/30 10:34:31 dtucker Exp $ +$Id: ChangeLog,v 1.3459 2004/06/30 12:37:57 djm Exp $ diff --git a/ssh.1 b/ssh.1 index 5cdeee2da..faaf20587 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.192 2004/06/18 10:55:43 markus Exp $ +.\" $OpenBSD: ssh.1,v 1.193 2004/06/26 09:03:21 jmc Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -46,11 +46,11 @@ .Op Fl 1246AaCfgkMNnqsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec +.Bk -words .Op Fl D Ar port .Op Fl e Ar escape_char .Op Fl F Ar configfile .Op Fl i Ar identity_file -.Bk -words .Oo Fl L Xo .Sm off .Ar port : @@ -599,13 +599,6 @@ IPv6 addresses can be specified with an alternative syntax: .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. -.It Fl m Ar mac_spec -Additionally, for protocol version 2 a comma-separated list of MAC -(message authentication code) algorithms can -be specified in order of preference. -See the -.Cm MACs -keyword for more information. .It Fl M Places the .Nm @@ -617,6 +610,13 @@ Refer to the description of in .Xr ssh_config 5 for details. +.It Fl m Ar mac_spec +Additionally, for protocol version 2 a comma-separated list of MAC +(message authentication code) algorithms can +be specified in order of preference. +See the +.Cm MACs +keyword for more information. .It Fl N Do not execute a remote command. This is useful for just forwarding ports @@ -739,7 +739,7 @@ IPv6 addresses can be specified with an alternative syntax: .Xc .Sm on .It Fl S Ar ctl -Specifies the location of a control socket for for connection sharing. +Specifies the location of a control socket for connection sharing. Refer to the description of .Cm ControlPath and -- cgit v1.2.3 From 0b42e6d95b915309187281e968049cb61b750c69 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 13 Aug 2004 21:22:40 +1000 Subject: - jakob@cvs.openbsd.org 2004/08/12 21:41:13 [ssh-keygen.1 ssh.1] improve SSHFP documentation; ok deraadt@ --- ChangeLog | 5 ++++- ssh-keygen.1 | 11 +++++++---- ssh.1 | 11 ++++++++++- 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'ssh.1') diff --git a/ChangeLog b/ChangeLog index 01bcf22e6..53506beb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,9 @@ - djm@cvs.openbsd.org 2004/08/12 09:18:24 [sshlogin.c] typo in error message, spotted by moritz AT jodeit.org (Id sync only) + - jakob@cvs.openbsd.org 2004/08/12 21:41:13 + [ssh-keygen.1 ssh.1] + improve SSHFP documentation; ok deraadt@ 20040812 - (dtucker) [sshd.c] Remove duplicate variable imported during sync. @@ -1609,4 +1612,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.3501 2004/08/13 11:21:47 dtucker Exp $ +$Id: ChangeLog,v 1.3502 2004/08/13 11:22:40 dtucker Exp $ diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 6dd615428..824b6e09c 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.61 2003/12/22 09:16:58 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.62 2004/08/12 21:41:13 jakob Exp $ .\" .\" -*- nroff -*- .\" @@ -192,7 +192,9 @@ to stdout. This option allows exporting keys for use by several commercial SSH implementations. .It Fl g -Use generic DNS resource record format. +Use generic DNS format when printing fingerprint resource records using the +.Fl r +command. .It Fl f Ar filename Specifies the filename of the key file. .It Fl i @@ -276,8 +278,9 @@ Multiple options increase the verbosity. The maximum is 3. .It Fl r Ar hostname -Print DNS resource record with the specified -.Ar hostname . +Print the SSHFP fingerprint resource record named +.Ar hostname +for the specified public key file. .El .Sh MODULI GENERATION .Nm diff --git a/ssh.1 b/ssh.1 index faaf20587..0ff77ea29 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.193 2004/06/26 09:03:21 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.194 2004/08/12 21:41:13 jakob Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -400,6 +400,15 @@ The option can be used to prevent logins to machines whose host key is not known or has changed. .Pp +.Nm +can be configured to verify host identification using fingerprint resource +records (SSHFP) published in DNS. +The +.Cm VerifyHostKeyDNS +option can be used to control how DNS lookups are performed. +SSHFP resource records can be generated using +.Xr ssh-keygen 1 . +.Pp The options are as follows: .Bl -tag -width Ds .It Fl 1 -- cgit v1.2.3