summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--authfd.c36
-rw-r--r--authfd.h3
-rw-r--r--clientloop.c15
-rw-r--r--readconf.c43
-rw-r--r--readconf.h3
-rw-r--r--ssh.c34
-rw-r--r--ssh_config.515
7 files changed, 121 insertions, 28 deletions
diff --git a/authfd.c b/authfd.c
index ab6305944..05fd45401 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.c,v 1.120 2019/11/13 04:47:52 deraadt Exp $ */ 1/* $OpenBSD: authfd.c,v 1.121 2019/12/21 02:19:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -82,21 +82,16 @@ decode_reply(u_char type)
82 return SSH_ERR_INVALID_FORMAT; 82 return SSH_ERR_INVALID_FORMAT;
83} 83}
84 84
85/* Returns the number of the authentication fd, or -1 if there is none. */ 85/*
86 * Opens an authentication socket at the provided path and stores the file
87 * descriptor in fdp. Returns 0 on success and an error on failure.
88 */
86int 89int
87ssh_get_authentication_socket(int *fdp) 90ssh_get_authentication_socket_path(const char *authsocket, int *fdp)
88{ 91{
89 const char *authsocket;
90 int sock, oerrno; 92 int sock, oerrno;
91 struct sockaddr_un sunaddr; 93 struct sockaddr_un sunaddr;
92 94
93 if (fdp != NULL)
94 *fdp = -1;
95
96 authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
97 if (authsocket == NULL || *authsocket == '\0')
98 return SSH_ERR_AGENT_NOT_PRESENT;
99
100 memset(&sunaddr, 0, sizeof(sunaddr)); 95 memset(&sunaddr, 0, sizeof(sunaddr));
101 sunaddr.sun_family = AF_UNIX; 96 sunaddr.sun_family = AF_UNIX;
102 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); 97 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
@@ -119,6 +114,25 @@ ssh_get_authentication_socket(int *fdp)
119 return 0; 114 return 0;
120} 115}
121 116
117/*
118 * Opens the default authentication socket and stores the file descriptor in
119 * fdp. Returns 0 on success and an error on failure.
120 */
121int
122ssh_get_authentication_socket(int *fdp)
123{
124 const char *authsocket;
125
126 if (fdp != NULL)
127 *fdp = -1;
128
129 authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
130 if (authsocket == NULL || *authsocket == '\0')
131 return SSH_ERR_AGENT_NOT_PRESENT;
132
133 return ssh_get_authentication_socket_path(authsocket, fdp);
134}
135
122/* Communicate with agent: send request and read reply */ 136/* Communicate with agent: send request and read reply */
123static int 137static int
124ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) 138ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
diff --git a/authfd.h b/authfd.h
index 443771a00..c3bf6259a 100644
--- a/authfd.h
+++ b/authfd.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.h,v 1.47 2019/10/31 21:19:15 djm Exp $ */ 1/* $OpenBSD: authfd.h,v 1.48 2019/12/21 02:19:13 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -24,6 +24,7 @@ struct ssh_identitylist {
24}; 24};
25 25
26int ssh_get_authentication_socket(int *fdp); 26int ssh_get_authentication_socket(int *fdp);
27int ssh_get_authentication_socket_path(const char *authsocket, int *fdp);
27void ssh_close_authentication_socket(int sock); 28void ssh_close_authentication_socket(int sock);
28 29
29int ssh_lock_agent(int sock, int lock, const char *password); 30int 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 @@
1/* $OpenBSD: clientloop.c,v 1.329 2019/11/25 00:51:37 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.330 2019/12/21 02:19:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * 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 */
135extern char *host; 135extern char *host;
136 136
137/* 137/*
138 * If this field is not NULL, the ForwardAgent socket is this path and different
139 * instead of SSH_AUTH_SOCK.
140 */
141extern char *forward_agent_sock_path;
142
143/*
138 * Flag to indicate that we have received a window change signal which has 144 * Flag to indicate that we have received a window change signal which has
139 * not yet been processed. This will cause a message indicating the new 145 * not yet been processed. This will cause a message indicating the new
140 * window size to be sent to the server a little later. This is volatile 146 * 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)
1618 "malicious server."); 1624 "malicious server.");
1619 return NULL; 1625 return NULL;
1620 } 1626 }
1621 if ((r = ssh_get_authentication_socket(&sock)) != 0) { 1627 if (forward_agent_sock_path == NULL) {
1628 r = ssh_get_authentication_socket(&sock);
1629 } else {
1630 r = ssh_get_authentication_socket_path(forward_agent_sock_path, &sock);
1631 }
1632 if (r != 0) {
1622 if (r != SSH_ERR_AGENT_NOT_PRESENT) 1633 if (r != SSH_ERR_AGENT_NOT_PRESENT)
1623 debug("%s: ssh_get_authentication_socket: %s", 1634 debug("%s: ssh_get_authentication_socket: %s",
1624 __func__, ssh_err(r)); 1635 __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 @@
1/* $OpenBSD: readconf.c,v 1.318 2019/12/20 02:42:42 dtucker Exp $ */ 1/* $OpenBSD: readconf.c,v 1.319 2019/12/21 02:19:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -919,6 +919,34 @@ parse_time:
919 919
920 case oForwardAgent: 920 case oForwardAgent:
921 intptr = &options->forward_agent; 921 intptr = &options->forward_agent;
922
923 arg = strdelim(&s);
924 if (!arg || *arg == '\0')
925 fatal("%s line %d: missing argument.",
926 filename, linenum);
927
928 value = -1;
929 multistate_ptr = multistate_flag;
930 for (i = 0; multistate_ptr[i].key != NULL; i++) {
931 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
932 value = multistate_ptr[i].value;
933 break;
934 }
935 }
936 if (value != -1) {
937 if (*activep && *intptr == -1)
938 *intptr = value;
939 break;
940 }
941 /* ForwardAgent wasn't 'yes' or 'no', assume a path */
942 if (*activep && *intptr == -1)
943 *intptr = 1;
944
945 charptr = &options->forward_agent_sock_path;
946 goto parse_agent_path;
947
948 case oForwardX11:
949 intptr = &options->forward_x11;
922 parse_flag: 950 parse_flag:
923 multistate_ptr = multistate_flag; 951 multistate_ptr = multistate_flag;
924 parse_multistate: 952 parse_multistate:
@@ -940,10 +968,6 @@ parse_time:
940 *intptr = value; 968 *intptr = value;
941 break; 969 break;
942 970
943 case oForwardX11:
944 intptr = &options->forward_x11;
945 goto parse_flag;
946
947 case oForwardX11Trusted: 971 case oForwardX11Trusted:
948 intptr = &options->forward_x11_trusted; 972 intptr = &options->forward_x11_trusted;
949 goto parse_flag; 973 goto parse_flag;
@@ -1736,6 +1760,7 @@ parse_keytypes:
1736 if (!arg || *arg == '\0') 1760 if (!arg || *arg == '\0')
1737 fatal("%.200s line %d: Missing argument.", 1761 fatal("%.200s line %d: Missing argument.",
1738 filename, linenum); 1762 filename, linenum);
1763 parse_agent_path:
1739 /* Extra validation if the string represents an env var. */ 1764 /* Extra validation if the string represents an env var. */
1740 if (arg[0] == '$' && !valid_env_name(arg + 1)) { 1765 if (arg[0] == '$' && !valid_env_name(arg + 1)) {
1741 fatal("%.200s line %d: Invalid environment name %s.", 1766 fatal("%.200s line %d: Invalid environment name %s.",
@@ -1853,6 +1878,7 @@ initialize_options(Options * options)
1853{ 1878{
1854 memset(options, 'X', sizeof(*options)); 1879 memset(options, 'X', sizeof(*options));
1855 options->forward_agent = -1; 1880 options->forward_agent = -1;
1881 options->forward_agent_sock_path = NULL;
1856 options->forward_x11 = -1; 1882 options->forward_x11 = -1;
1857 options->forward_x11_trusted = -1; 1883 options->forward_x11_trusted = -1;
1858 options->forward_x11_timeout = -1; 1884 options->forward_x11_timeout = -1;
@@ -2636,7 +2662,6 @@ dump_client_config(Options *o, const char *host)
2636 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings); 2662 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2637 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); 2663 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2638 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); 2664 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2639 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2640 dump_cfg_fmtint(oForwardX11, o->forward_x11); 2665 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2641 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); 2666 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2642 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2667 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
@@ -2712,6 +2737,12 @@ dump_client_config(Options *o, const char *host)
2712 2737
2713 /* Special cases */ 2738 /* Special cases */
2714 2739
2740 /* oForwardAgent */
2741 if (o->forward_agent_sock_path == NULL)
2742 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2743 else
2744 dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
2745
2715 /* oConnectTimeout */ 2746 /* oConnectTimeout */
2716 if (o->connection_timeout == -1) 2747 if (o->connection_timeout == -1)
2717 printf("connecttimeout none\n"); 2748 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 @@
1/* $OpenBSD: readconf.h,v 1.130 2019/10/31 21:18:28 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.131 2019/12/21 02:19:13 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -29,6 +29,7 @@ struct allowed_cname {
29 29
30typedef struct { 30typedef struct {
31 int forward_agent; /* Forward authentication agent. */ 31 int forward_agent; /* Forward authentication agent. */
32 char *forward_agent_sock_path; /* Optional path of the agent. */
32 int forward_x11; /* Forward X11 display. */ 33 int forward_x11; /* Forward X11 display. */
33 int forward_x11_timeout; /* Expiration for Cookies */ 34 int forward_x11_timeout; /* Expiration for Cookies */
34 int forward_x11_trusted; /* Trust Forward X11 display. */ 35 int forward_x11_trusted; /* Trust Forward X11 display. */
diff --git a/ssh.c b/ssh.c
index 13299f7d1..12760af29 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.509 2019/11/18 16:10:05 naddy Exp $ */ 1/* $OpenBSD: ssh.c,v 1.510 2019/12/21 02:19:13 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -168,6 +168,12 @@ char *config = NULL;
168 */ 168 */
169char *host; 169char *host;
170 170
171/*
172 * A config can specify a path to forward, overriding SSH_AUTH_SOCK. If this is
173 * not NULL, forward the socket at this path instead.
174 */
175char *forward_agent_sock_path = NULL;
176
171/* Various strings used to to percent_expand() arguments */ 177/* Various strings used to to percent_expand() arguments */
172static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 178static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
173static char uidstr[32], *host_arg, *conn_hash_hex; 179static char uidstr[32], *host_arg, *conn_hash_hex;
@@ -1498,6 +1504,32 @@ main(int ac, char **av)
1498 } 1504 }
1499 } 1505 }
1500 1506
1507 if (options.forward_agent && (options.forward_agent_sock_path != NULL)) {
1508 p = tilde_expand_filename(options.forward_agent_sock_path, getuid());
1509 cp = percent_expand(p,
1510 "d", pw->pw_dir,
1511 "h", host,
1512 "i", uidstr,
1513 "l", thishost,
1514 "r", options.user,
1515 "u", pw->pw_name,
1516 (char *)NULL);
1517 free(p);
1518
1519 if (cp[0] == '$') {
1520 if (!valid_env_name(cp + 1)) {
1521 fatal("Invalid ForwardAgent environment variable name %s", cp);
1522 }
1523 if ((p = getenv(cp + 1)) != NULL)
1524 forward_agent_sock_path = p;
1525 else
1526 options.forward_agent = 0;
1527 free(cp);
1528 } else {
1529 forward_agent_sock_path = cp;
1530 }
1531 }
1532
1501 /* Expand ~ in known host file names. */ 1533 /* Expand ~ in known host file names. */
1502 tilde_expand_paths(options.system_hostfiles, 1534 tilde_expand_paths(options.system_hostfiles,
1503 options.num_system_hostfiles); 1535 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 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.311 2019/12/19 15:09:30 naddy Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.312 2019/12/21 02:19:13 djm Exp $
37.Dd $Mdocdate: December 19 2019 $ 37.Dd $Mdocdate: December 21 2019 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -669,11 +669,14 @@ and
669.It Cm ForwardAgent 669.It Cm ForwardAgent
670Specifies whether the connection to the authentication agent (if any) 670Specifies whether the connection to the authentication agent (if any)
671will be forwarded to the remote machine. 671will be forwarded to the remote machine.
672The argument must be 672The argument may be
673.Cm yes 673.Cm yes ,
674or
675.Cm no 674.Cm no
676(the default). 675(the default),
676an explicit path to an agent socket or the name of an environment variable
677(beginning with
678.Sq $ )
679in which to find the path.
677.Pp 680.Pp
678Agent forwarding should be enabled with caution. 681Agent forwarding should be enabled with caution.
679Users with the ability to bypass file permissions on the remote host 682Users with the ability to bypass file permissions on the remote host