diff options
-rw-r--r-- | authfd.c | 36 | ||||
-rw-r--r-- | authfd.h | 3 | ||||
-rw-r--r-- | clientloop.c | 15 | ||||
-rw-r--r-- | readconf.c | 43 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | ssh.c | 34 | ||||
-rw-r--r-- | ssh_config.5 | 15 |
7 files changed, 121 insertions, 28 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.120 2019/11/13 04:47:52 deraadt Exp $ */ +/* $OpenBSD: authfd.c,v 1.121 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -82,21 +82,16 @@ decode_reply(u_char type) return SSH_ERR_INVALID_FORMAT; } -/* Returns the number of the authentication fd, or -1 if there is none. */ +/* + * Opens an authentication socket at the provided path and stores the file + * descriptor in fdp. Returns 0 on success and an error on failure. + */ int -ssh_get_authentication_socket(int *fdp) +ssh_get_authentication_socket_path(const char *authsocket, int *fdp) { - const char *authsocket; int sock, oerrno; struct sockaddr_un sunaddr; - if (fdp != NULL) - *fdp = -1; - - authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); - if (authsocket == NULL || *authsocket == '\0') - return SSH_ERR_AGENT_NOT_PRESENT; - memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); @@ -119,6 +114,25 @@ ssh_get_authentication_socket(int *fdp) return 0; } +/* + * Opens the default authentication socket and stores the file descriptor in + * fdp. Returns 0 on success and an error on failure. + */ +int +ssh_get_authentication_socket(int *fdp) +{ + const char *authsocket; + + if (fdp != NULL) + *fdp = -1; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + if (authsocket == NULL || *authsocket == '\0') + return SSH_ERR_AGENT_NOT_PRESENT; + + return ssh_get_authentication_socket_path(authsocket, fdp); +} + /* Communicate with agent: send request and read reply */ static int ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.47 2019/10/31 21:19:15 djm Exp $ */ +/* $OpenBSD: authfd.h,v 1.48 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -24,6 +24,7 @@ struct ssh_identitylist { }; int ssh_get_authentication_socket(int *fdp); +int ssh_get_authentication_socket_path(const char *authsocket, int *fdp); void ssh_close_authentication_socket(int sock); int ssh_lock_agent(int sock, int lock, const char *password); diff --git a/clientloop.c b/clientloop.c index 880abfda2..8f0332df4 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.329 2019/11/25 00:51:37 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.330 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -135,6 +135,12 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ extern char *host; /* + * If this field is not NULL, the ForwardAgent socket is this path and different + * instead of SSH_AUTH_SOCK. + */ +extern char *forward_agent_sock_path; + +/* * Flag to indicate that we have received a window change signal which has * not yet been processed. This will cause a message indicating the new * window size to be sent to the server a little later. This is volatile @@ -1618,7 +1624,12 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan) "malicious server."); return NULL; } - if ((r = ssh_get_authentication_socket(&sock)) != 0) { + if (forward_agent_sock_path == NULL) { + r = ssh_get_authentication_socket(&sock); + } else { + r = ssh_get_authentication_socket_path(forward_agent_sock_path, &sock); + } + if (r != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); diff --git a/readconf.c b/readconf.c index 282afede6..cb3ae6dc7 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.318 2019/12/20 02:42:42 dtucker Exp $ */ +/* $OpenBSD: readconf.c,v 1.319 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -919,6 +919,34 @@ parse_time: case oForwardAgent: intptr = &options->forward_agent; + + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%s line %d: missing argument.", + filename, linenum); + + value = -1; + multistate_ptr = multistate_flag; + for (i = 0; multistate_ptr[i].key != NULL; i++) { + if (strcasecmp(arg, multistate_ptr[i].key) == 0) { + value = multistate_ptr[i].value; + break; + } + } + if (value != -1) { + if (*activep && *intptr == -1) + *intptr = value; + break; + } + /* ForwardAgent wasn't 'yes' or 'no', assume a path */ + if (*activep && *intptr == -1) + *intptr = 1; + + charptr = &options->forward_agent_sock_path; + goto parse_agent_path; + + case oForwardX11: + intptr = &options->forward_x11; parse_flag: multistate_ptr = multistate_flag; parse_multistate: @@ -940,10 +968,6 @@ parse_time: *intptr = value; break; - case oForwardX11: - intptr = &options->forward_x11; - goto parse_flag; - case oForwardX11Trusted: intptr = &options->forward_x11_trusted; goto parse_flag; @@ -1736,6 +1760,7 @@ parse_keytypes: if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); + parse_agent_path: /* Extra validation if the string represents an env var. */ if (arg[0] == '$' && !valid_env_name(arg + 1)) { fatal("%.200s line %d: Invalid environment name %s.", @@ -1853,6 +1878,7 @@ initialize_options(Options * options) { memset(options, 'X', sizeof(*options)); options->forward_agent = -1; + options->forward_agent_sock_path = NULL; options->forward_x11 = -1; options->forward_x11_trusted = -1; options->forward_x11_timeout = -1; @@ -2636,7 +2662,6 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); - dump_cfg_fmtint(oForwardAgent, o->forward_agent); dump_cfg_fmtint(oForwardX11, o->forward_x11); dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); @@ -2712,6 +2737,12 @@ dump_client_config(Options *o, const char *host) /* Special cases */ + /* oForwardAgent */ + if (o->forward_agent_sock_path == NULL) + dump_cfg_fmtint(oForwardAgent, o->forward_agent); + else + dump_cfg_string(oForwardAgent, o->forward_agent_sock_path); + /* oConnectTimeout */ if (o->connection_timeout == -1) printf("connecttimeout none\n"); diff --git a/readconf.h b/readconf.h index 51d540b88..dcecfc54a 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.130 2019/10/31 21:18:28 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.131 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -29,6 +29,7 @@ struct allowed_cname { typedef struct { int forward_agent; /* Forward authentication agent. */ + char *forward_agent_sock_path; /* Optional path of the agent. */ int forward_x11; /* Forward X11 display. */ int forward_x11_timeout; /* Expiration for Cookies */ int forward_x11_trusted; /* Trust Forward X11 display. */ @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.509 2019/11/18 16:10:05 naddy Exp $ */ +/* $OpenBSD: ssh.c,v 1.510 2019/12/21 02:19:13 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -168,6 +168,12 @@ char *config = NULL; */ char *host; +/* + * A config can specify a path to forward, overriding SSH_AUTH_SOCK. If this is + * not NULL, forward the socket at this path instead. + */ +char *forward_agent_sock_path = NULL; + /* Various strings used to to percent_expand() arguments */ static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; static char uidstr[32], *host_arg, *conn_hash_hex; @@ -1498,6 +1504,32 @@ main(int ac, char **av) } } + if (options.forward_agent && (options.forward_agent_sock_path != NULL)) { + p = tilde_expand_filename(options.forward_agent_sock_path, getuid()); + cp = percent_expand(p, + "d", pw->pw_dir, + "h", host, + "i", uidstr, + "l", thishost, + "r", options.user, + "u", pw->pw_name, + (char *)NULL); + free(p); + + if (cp[0] == '$') { + if (!valid_env_name(cp + 1)) { + fatal("Invalid ForwardAgent environment variable name %s", cp); + } + if ((p = getenv(cp + 1)) != NULL) + forward_agent_sock_path = p; + else + options.forward_agent = 0; + free(cp); + } else { + forward_agent_sock_path = cp; + } + } + /* Expand ~ in known host file names. */ tilde_expand_paths(options.system_hostfiles, options.num_system_hostfiles); diff --git a/ssh_config.5 b/ssh_config.5 index dc7a2143d..186e07617 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (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.311 2019/12/19 15:09:30 naddy Exp $ -.Dd $Mdocdate: December 19 2019 $ +.\" $OpenBSD: ssh_config.5,v 1.312 2019/12/21 02:19:13 djm Exp $ +.Dd $Mdocdate: December 21 2019 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -669,11 +669,14 @@ and .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. -The argument must be -.Cm yes -or +The argument may be +.Cm yes , .Cm no -(the default). +(the default), +an explicit path to an agent socket or the name of an environment variable +(beginning with +.Sq $ ) +in which to find the path. .Pp Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host |