Skip to content

Commit

Permalink
upstream: Allow forwarding a different agent socket to the path
Browse files Browse the repository at this point in the history
specified by $SSH_AUTH_SOCK, by extending the existing ForwardAgent option to
accepting an explicit path or the name of an environment variable in addition
to yes/no.

Patch by Eric Chiang, manpage by me; ok markus@

OpenBSD-Commit-ID: 98f2ed80bf34ea54d8b2ddd19ac14ebbf40e9265
  • Loading branch information
djmdjm committed Dec 21, 2019
1 parent 416f153 commit 40be78f
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 28 deletions.
36 changes: 25 additions & 11 deletions authfd.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -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));
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion authfd.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
Expand All @@ -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);
Expand Down
15 changes: 13 additions & 2 deletions clientloop.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -134,6 +134,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
Expand Down Expand Up @@ -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));
Expand Down
43 changes: 37 additions & 6 deletions readconf.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -919,6 +919,34 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,

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:
Expand All @@ -940,10 +968,6 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
*intptr = value;
break;

case oForwardX11:
intptr = &options->forward_x11;
goto parse_flag;

case oForwardX11Trusted:
intptr = &options->forward_x11_trusted;
goto parse_flag;
Expand Down Expand Up @@ -1736,6 +1760,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
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.",
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down
3 changes: 2 additions & 1 deletion readconf.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
Expand Down Expand Up @@ -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. */
Expand Down
34 changes: 33 additions & 1 deletion ssh.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 9 additions & 6 deletions ssh_config.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 40be78f

Please sign in to comment.