mirror of
git://anongit.mindrot.org/openssh.git
synced 2025-05-04 09:08:35 +00:00
upstream: Allow forwarding a different agent socket to the path
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
This commit is contained in:
parent
416f15372b
commit
40be78f503
36
authfd.c
36
authfd.c
@ -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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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;
|
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
|
int
|
||||||
ssh_get_authentication_socket(int *fdp)
|
ssh_get_authentication_socket_path(const char *authsocket, int *fdp)
|
||||||
{
|
{
|
||||||
const char *authsocket;
|
|
||||||
int sock, oerrno;
|
int sock, oerrno;
|
||||||
struct sockaddr_un sunaddr;
|
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));
|
memset(&sunaddr, 0, sizeof(sunaddr));
|
||||||
sunaddr.sun_family = AF_UNIX;
|
sunaddr.sun_family = AF_UNIX;
|
||||||
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
|
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
|
||||||
@ -119,6 +114,25 @@ ssh_get_authentication_socket(int *fdp)
|
|||||||
return 0;
|
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 */
|
/* Communicate with agent: send request and read reply */
|
||||||
static int
|
static int
|
||||||
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
|
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
|
||||||
|
3
authfd.h
3
authfd.h
@ -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>
|
* 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(int *fdp);
|
||||||
|
int ssh_get_authentication_socket_path(const char *authsocket, int *fdp);
|
||||||
void ssh_close_authentication_socket(int sock);
|
void ssh_close_authentication_socket(int sock);
|
||||||
|
|
||||||
int ssh_lock_agent(int sock, int lock, const char *password);
|
int ssh_lock_agent(int sock, int lock, const char *password);
|
||||||
|
15
clientloop.c
15
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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -134,6 +134,12 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
|
|||||||
*/
|
*/
|
||||||
extern char *host;
|
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
|
* 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
|
* not yet been processed. This will cause a message indicating the new
|
||||||
@ -1618,7 +1624,12 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
|
|||||||
"malicious server.");
|
"malicious server.");
|
||||||
return NULL;
|
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)
|
if (r != SSH_ERR_AGENT_NOT_PRESENT)
|
||||||
debug("%s: ssh_get_authentication_socket: %s",
|
debug("%s: ssh_get_authentication_socket: %s",
|
||||||
__func__, ssh_err(r));
|
__func__, ssh_err(r));
|
||||||
|
43
readconf.c
43
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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -919,6 +919,34 @@ parse_time:
|
|||||||
|
|
||||||
case oForwardAgent:
|
case oForwardAgent:
|
||||||
intptr = &options->forward_agent;
|
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:
|
parse_flag:
|
||||||
multistate_ptr = multistate_flag;
|
multistate_ptr = multistate_flag;
|
||||||
parse_multistate:
|
parse_multistate:
|
||||||
@ -940,10 +968,6 @@ parse_time:
|
|||||||
*intptr = value;
|
*intptr = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case oForwardX11:
|
|
||||||
intptr = &options->forward_x11;
|
|
||||||
goto parse_flag;
|
|
||||||
|
|
||||||
case oForwardX11Trusted:
|
case oForwardX11Trusted:
|
||||||
intptr = &options->forward_x11_trusted;
|
intptr = &options->forward_x11_trusted;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
@ -1736,6 +1760,7 @@ parse_keytypes:
|
|||||||
if (!arg || *arg == '\0')
|
if (!arg || *arg == '\0')
|
||||||
fatal("%.200s line %d: Missing argument.",
|
fatal("%.200s line %d: Missing argument.",
|
||||||
filename, linenum);
|
filename, linenum);
|
||||||
|
parse_agent_path:
|
||||||
/* Extra validation if the string represents an env var. */
|
/* Extra validation if the string represents an env var. */
|
||||||
if (arg[0] == '$' && !valid_env_name(arg + 1)) {
|
if (arg[0] == '$' && !valid_env_name(arg + 1)) {
|
||||||
fatal("%.200s line %d: Invalid environment name %s.",
|
fatal("%.200s line %d: Invalid environment name %s.",
|
||||||
@ -1853,6 +1878,7 @@ initialize_options(Options * options)
|
|||||||
{
|
{
|
||||||
memset(options, 'X', sizeof(*options));
|
memset(options, 'X', sizeof(*options));
|
||||||
options->forward_agent = -1;
|
options->forward_agent = -1;
|
||||||
|
options->forward_agent_sock_path = NULL;
|
||||||
options->forward_x11 = -1;
|
options->forward_x11 = -1;
|
||||||
options->forward_x11_trusted = -1;
|
options->forward_x11_trusted = -1;
|
||||||
options->forward_x11_timeout = -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(oClearAllForwardings, o->clear_forwardings);
|
||||||
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
|
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
|
||||||
dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
|
dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
|
||||||
dump_cfg_fmtint(oForwardAgent, o->forward_agent);
|
|
||||||
dump_cfg_fmtint(oForwardX11, o->forward_x11);
|
dump_cfg_fmtint(oForwardX11, o->forward_x11);
|
||||||
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
|
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
|
||||||
dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
|
dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
|
||||||
@ -2712,6 +2737,12 @@ dump_client_config(Options *o, const char *host)
|
|||||||
|
|
||||||
/* Special cases */
|
/* 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 */
|
/* oConnectTimeout */
|
||||||
if (o->connection_timeout == -1)
|
if (o->connection_timeout == -1)
|
||||||
printf("connecttimeout none\n");
|
printf("connecttimeout none\n");
|
||||||
|
@ -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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -29,6 +29,7 @@ struct allowed_cname {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int forward_agent; /* Forward authentication agent. */
|
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; /* Forward X11 display. */
|
||||||
int forward_x11_timeout; /* Expiration for Cookies */
|
int forward_x11_timeout; /* Expiration for Cookies */
|
||||||
int forward_x11_trusted; /* Trust Forward X11 display. */
|
int forward_x11_trusted; /* Trust Forward X11 display. */
|
||||||
|
34
ssh.c
34
ssh.c
@ -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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -168,6 +168,12 @@ char *config = NULL;
|
|||||||
*/
|
*/
|
||||||
char *host;
|
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 */
|
/* Various strings used to to percent_expand() arguments */
|
||||||
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
|
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
|
||||||
static char uidstr[32], *host_arg, *conn_hash_hex;
|
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. */
|
/* Expand ~ in known host file names. */
|
||||||
tilde_expand_paths(options.system_hostfiles,
|
tilde_expand_paths(options.system_hostfiles,
|
||||||
options.num_system_hostfiles);
|
options.num_system_hostfiles);
|
||||||
|
15
ssh_config.5
15
ssh_config.5
@ -33,8 +33,8 @@
|
|||||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" 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 $
|
.\" $OpenBSD: ssh_config.5,v 1.312 2019/12/21 02:19:13 djm Exp $
|
||||||
.Dd $Mdocdate: December 19 2019 $
|
.Dd $Mdocdate: December 21 2019 $
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -669,11 +669,14 @@ and
|
|||||||
.It Cm ForwardAgent
|
.It Cm ForwardAgent
|
||||||
Specifies whether the connection to the authentication agent (if any)
|
Specifies whether the connection to the authentication agent (if any)
|
||||||
will be forwarded to the remote machine.
|
will be forwarded to the remote machine.
|
||||||
The argument must be
|
The argument may be
|
||||||
.Cm yes
|
.Cm yes ,
|
||||||
or
|
|
||||||
.Cm no
|
.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
|
.Pp
|
||||||
Agent forwarding should be enabled with caution.
|
Agent forwarding should be enabled with caution.
|
||||||
Users with the ability to bypass file permissions on the remote host
|
Users with the ability to bypass file permissions on the remote host
|
||||||
|
Loading…
Reference in New Issue
Block a user