diff options
-rw-r--r-- | clientloop.c | 12 | ||||
-rw-r--r-- | clientloop.h | 4 | ||||
-rw-r--r-- | misc.c | 12 | ||||
-rw-r--r-- | misc.h | 4 | ||||
-rw-r--r-- | openbsd-compat/port-tun.c | 16 | ||||
-rw-r--r-- | openbsd-compat/port-tun.h | 2 | ||||
-rw-r--r-- | serverloop.c | 22 | ||||
-rw-r--r-- | session.c | 5 | ||||
-rw-r--r-- | ssh.1 | 9 | ||||
-rw-r--r-- | ssh.c | 108 | ||||
-rw-r--r-- | ssh_config.5 | 16 |
11 files changed, 133 insertions, 77 deletions
diff --git a/clientloop.c b/clientloop.c index 791d336e3..46ede4f0e 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.305 2017/09/19 04:24:22 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.306 2017/10/23 05:08:00 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 |
@@ -1601,12 +1601,13 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan) | |||
1601 | return c; | 1601 | return c; |
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | int | 1604 | char * |
1605 | client_request_tun_fwd(struct ssh *ssh, int tun_mode, | 1605 | client_request_tun_fwd(struct ssh *ssh, int tun_mode, |
1606 | int local_tun, int remote_tun) | 1606 | int local_tun, int remote_tun) |
1607 | { | 1607 | { |
1608 | Channel *c; | 1608 | Channel *c; |
1609 | int fd; | 1609 | int fd; |
1610 | char *ifname = NULL; | ||
1610 | 1611 | ||
1611 | if (tun_mode == SSH_TUNMODE_NO) | 1612 | if (tun_mode == SSH_TUNMODE_NO) |
1612 | return 0; | 1613 | return 0; |
@@ -1614,10 +1615,11 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode, | |||
1614 | debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); | 1615 | debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); |
1615 | 1616 | ||
1616 | /* Open local tunnel device */ | 1617 | /* Open local tunnel device */ |
1617 | if ((fd = tun_open(local_tun, tun_mode)) == -1) { | 1618 | if ((fd = tun_open(local_tun, tun_mode, &ifname)) == -1) { |
1618 | error("Tunnel device open failed."); | 1619 | error("Tunnel device open failed."); |
1619 | return -1; | 1620 | return NULL; |
1620 | } | 1621 | } |
1622 | debug("Tunnel forwarding using interface %s", ifname); | ||
1621 | 1623 | ||
1622 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, | 1624 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1, |
1623 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); | 1625 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
@@ -1638,7 +1640,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode, | |||
1638 | packet_put_int(remote_tun); | 1640 | packet_put_int(remote_tun); |
1639 | packet_send(); | 1641 | packet_send(); |
1640 | 1642 | ||
1641 | return 0; | 1643 | return ifname; |
1642 | } | 1644 | } |
1643 | 1645 | ||
1644 | /* XXXX move to generic input handler */ | 1646 | /* XXXX move to generic input handler */ |
diff --git a/clientloop.h b/clientloop.h index a1975ccc8..8d1f0bff6 100644 --- a/clientloop.h +++ b/clientloop.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.h,v 1.35 2017/10/23 05:08:00 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -46,7 +46,7 @@ int client_x11_get_proto(struct ssh *, const char *, const char *, | |||
46 | void client_global_request_reply_fwd(int, u_int32_t, void *); | 46 | void client_global_request_reply_fwd(int, u_int32_t, void *); |
47 | void client_session2_setup(struct ssh *, int, int, int, | 47 | void client_session2_setup(struct ssh *, int, int, int, |
48 | const char *, struct termios *, int, Buffer *, char **); | 48 | const char *, struct termios *, int, Buffer *, char **); |
49 | int client_request_tun_fwd(struct ssh *, int, int, int); | 49 | char *client_request_tun_fwd(struct ssh *, int, int, int); |
50 | void client_stop_mux(void); | 50 | void client_stop_mux(void); |
51 | 51 | ||
52 | /* Escape filter for protocol 2 sessions */ | 52 | /* Escape filter for protocol 2 sessions */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.114 2017/10/21 23:06:24 millert Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.115 2017/10/23 05:08:00 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -964,16 +964,19 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, | |||
964 | } | 964 | } |
965 | 965 | ||
966 | int | 966 | int |
967 | tun_open(int tun, int mode) | 967 | tun_open(int tun, int mode, char **ifname) |
968 | { | 968 | { |
969 | #if defined(CUSTOM_SYS_TUN_OPEN) | 969 | #if defined(CUSTOM_SYS_TUN_OPEN) |
970 | return (sys_tun_open(tun, mode)); | 970 | return (sys_tun_open(tun, mode, ifname)); |
971 | #elif defined(SSH_TUN_OPENBSD) | 971 | #elif defined(SSH_TUN_OPENBSD) |
972 | struct ifreq ifr; | 972 | struct ifreq ifr; |
973 | char name[100]; | 973 | char name[100]; |
974 | int fd = -1, sock; | 974 | int fd = -1, sock; |
975 | const char *tunbase = "tun"; | 975 | const char *tunbase = "tun"; |
976 | 976 | ||
977 | if (ifname != NULL) | ||
978 | *ifname = NULL; | ||
979 | |||
977 | if (mode == SSH_TUNMODE_ETHERNET) | 980 | if (mode == SSH_TUNMODE_ETHERNET) |
978 | tunbase = "tap"; | 981 | tunbase = "tap"; |
979 | 982 | ||
@@ -1020,6 +1023,9 @@ tun_open(int tun, int mode) | |||
1020 | } | 1023 | } |
1021 | } | 1024 | } |
1022 | 1025 | ||
1026 | if (ifname != NULL) | ||
1027 | *ifname = xstrdup(ifr.ifr_name); | ||
1028 | |||
1023 | close(sock); | 1029 | close(sock); |
1024 | return fd; | 1030 | return fd; |
1025 | 1031 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.64 2017/10/21 23:06:24 millert Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.65 2017/10/23 05:08:00 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -87,7 +87,7 @@ void replacearg(arglist *, u_int, char *, ...) | |||
87 | __attribute__((format(printf, 3, 4))); | 87 | __attribute__((format(printf, 3, 4))); |
88 | void freeargs(arglist *); | 88 | void freeargs(arglist *); |
89 | 89 | ||
90 | int tun_open(int, int); | 90 | int tun_open(int, int, char **); |
91 | 91 | ||
92 | /* Common definitions for ssh tunnel device forwarding */ | 92 | /* Common definitions for ssh tunnel device forwarding */ |
93 | #define SSH_TUNMODE_NO 0x00 | 93 | #define SSH_TUNMODE_NO 0x00 |
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c index 7579c6084..0e75c911d 100644 --- a/openbsd-compat/port-tun.c +++ b/openbsd-compat/port-tun.c | |||
@@ -56,12 +56,15 @@ | |||
56 | #include <linux/if_tun.h> | 56 | #include <linux/if_tun.h> |
57 | 57 | ||
58 | int | 58 | int |
59 | sys_tun_open(int tun, int mode) | 59 | sys_tun_open(int tun, int mode, char **ifname) |
60 | { | 60 | { |
61 | struct ifreq ifr; | 61 | struct ifreq ifr; |
62 | int fd = -1; | 62 | int fd = -1; |
63 | const char *name = NULL; | 63 | const char *name = NULL; |
64 | 64 | ||
65 | if (ifname != NULL) | ||
66 | *ifname = NULL; | ||
67 | |||
65 | if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { | 68 | if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { |
66 | debug("%s: failed to open tunnel control interface: %s", | 69 | debug("%s: failed to open tunnel control interface: %s", |
67 | __func__, strerror(errno)); | 70 | __func__, strerror(errno)); |
@@ -99,6 +102,9 @@ sys_tun_open(int tun, int mode) | |||
99 | else | 102 | else |
100 | debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); | 103 | debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); |
101 | 104 | ||
105 | if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) | ||
106 | goto failed; | ||
107 | |||
102 | return (fd); | 108 | return (fd); |
103 | 109 | ||
104 | failed: | 110 | failed: |
@@ -116,13 +122,16 @@ sys_tun_open(int tun, int mode) | |||
116 | #endif | 122 | #endif |
117 | 123 | ||
118 | int | 124 | int |
119 | sys_tun_open(int tun, int mode) | 125 | sys_tun_open(int tun, int mode, char **ifname) |
120 | { | 126 | { |
121 | struct ifreq ifr; | 127 | struct ifreq ifr; |
122 | char name[100]; | 128 | char name[100]; |
123 | int fd = -1, sock, flag; | 129 | int fd = -1, sock, flag; |
124 | const char *tunbase = "tun"; | 130 | const char *tunbase = "tun"; |
125 | 131 | ||
132 | if (ifname != NULL) | ||
133 | *ifname = NULL; | ||
134 | |||
126 | if (mode == SSH_TUNMODE_ETHERNET) { | 135 | if (mode == SSH_TUNMODE_ETHERNET) { |
127 | #ifdef SSH_TUN_NO_L2 | 136 | #ifdef SSH_TUN_NO_L2 |
128 | debug("%s: no layer 2 tunnelling support", __func__); | 137 | debug("%s: no layer 2 tunnelling support", __func__); |
@@ -180,6 +189,9 @@ sys_tun_open(int tun, int mode) | |||
180 | goto failed; | 189 | goto failed; |
181 | } | 190 | } |
182 | 191 | ||
192 | if (ifname != NULL && (*ifname = strdup(ifr.ifr_name))) | ||
193 | goto failed; | ||
194 | |||
183 | close(sock); | 195 | close(sock); |
184 | return (fd); | 196 | return (fd); |
185 | 197 | ||
diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-tun.h index 103514370..926bc93e1 100644 --- a/openbsd-compat/port-tun.h +++ b/openbsd-compat/port-tun.h | |||
@@ -22,7 +22,7 @@ struct ssh; | |||
22 | 22 | ||
23 | #if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) | 23 | #if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) |
24 | # define CUSTOM_SYS_TUN_OPEN | 24 | # define CUSTOM_SYS_TUN_OPEN |
25 | int sys_tun_open(int, int); | 25 | int sys_tun_open(int, int, char **); |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) | 28 | #if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) |
diff --git a/serverloop.c b/serverloop.c index 24bbae322..a3cb8e782 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.199 2017/10/23 05:08:00 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 |
@@ -99,6 +99,9 @@ static volatile sig_atomic_t received_sigterm = 0; | |||
99 | /* prototypes */ | 99 | /* prototypes */ |
100 | static void server_init_dispatch(void); | 100 | static void server_init_dispatch(void); |
101 | 101 | ||
102 | /* requested tunnel forwarding interface(s), shared with session.c */ | ||
103 | char *tun_fwd_ifnames = NULL; | ||
104 | |||
102 | /* | 105 | /* |
103 | * we write to this pipe if a SIGCHLD is caught in order to avoid | 106 | * we write to this pipe if a SIGCHLD is caught in order to avoid |
104 | * the race between select() and child_terminated | 107 | * the race between select() and child_terminated |
@@ -519,6 +522,7 @@ server_request_tun(struct ssh *ssh) | |||
519 | Channel *c = NULL; | 522 | Channel *c = NULL; |
520 | int mode, tun; | 523 | int mode, tun; |
521 | int sock; | 524 | int sock; |
525 | char *tmp, *ifname = NULL; | ||
522 | 526 | ||
523 | mode = packet_get_int(); | 527 | mode = packet_get_int(); |
524 | switch (mode) { | 528 | switch (mode) { |
@@ -541,9 +545,10 @@ server_request_tun(struct ssh *ssh) | |||
541 | goto done; | 545 | goto done; |
542 | tun = forced_tun_device; | 546 | tun = forced_tun_device; |
543 | } | 547 | } |
544 | sock = tun_open(tun, mode); | 548 | sock = tun_open(tun, mode, &ifname); |
545 | if (sock < 0) | 549 | if (sock < 0) |
546 | goto done; | 550 | goto done; |
551 | debug("Tunnel forwarding using interface %s", ifname); | ||
547 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, | 552 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, |
548 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); | 553 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
549 | c->datagram = 1; | 554 | c->datagram = 1; |
@@ -553,6 +558,19 @@ server_request_tun(struct ssh *ssh) | |||
553 | sys_tun_outfilter, NULL, NULL); | 558 | sys_tun_outfilter, NULL, NULL); |
554 | #endif | 559 | #endif |
555 | 560 | ||
561 | /* | ||
562 | * Update the list of names exposed to the session | ||
563 | * XXX remove these if the tunnels are closed (won't matter | ||
564 | * much if they are already in the environment though) | ||
565 | */ | ||
566 | tmp = tun_fwd_ifnames; | ||
567 | xasprintf(&tun_fwd_ifnames, "%s%s%s", | ||
568 | tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames, | ||
569 | tun_fwd_ifnames == NULL ? "" : ",", | ||
570 | ifname); | ||
571 | free(tmp); | ||
572 | free(ifname); | ||
573 | |||
556 | done: | 574 | done: |
557 | if (c == NULL) | 575 | if (c == NULL) |
558 | packet_send_debug("Failed to open the tunnel device."); | 576 | packet_send_debug("Failed to open the tunnel device."); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.293 2017/10/23 05:08:00 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -140,6 +140,7 @@ extern u_int utmp_len; | |||
140 | extern int startup_pipe; | 140 | extern int startup_pipe; |
141 | extern void destroy_sensitive_data(void); | 141 | extern void destroy_sensitive_data(void); |
142 | extern Buffer loginmsg; | 142 | extern Buffer loginmsg; |
143 | char *tun_fwd_ifnames; /* serverloop.c */ | ||
143 | 144 | ||
144 | /* original command from peer. */ | 145 | /* original command from peer. */ |
145 | const char *original_command = NULL; | 146 | const char *original_command = NULL; |
@@ -1066,6 +1067,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) | |||
1066 | free(laddr); | 1067 | free(laddr); |
1067 | child_set_env(&env, &envsize, "SSH_CONNECTION", buf); | 1068 | child_set_env(&env, &envsize, "SSH_CONNECTION", buf); |
1068 | 1069 | ||
1070 | if (tun_fwd_ifnames != NULL) | ||
1071 | child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames); | ||
1069 | if (auth_info_file != NULL) | 1072 | if (auth_info_file != NULL) |
1070 | child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file); | 1073 | child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file); |
1071 | if (s->ttyfd != -1) | 1074 | if (s->ttyfd != -1) |
@@ -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.1,v 1.386 2017/10/21 23:06:24 millert Exp $ | 36 | .\" $OpenBSD: ssh.1,v 1.387 2017/10/23 05:08:00 djm Exp $ |
37 | .Dd $Mdocdate: October 21 2017 $ | 37 | .Dd $Mdocdate: October 23 2017 $ |
38 | .Dt SSH 1 | 38 | .Dt SSH 1 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1395,6 +1395,11 @@ This is set to the name of the tty (path to the device) associated | |||
1395 | with the current shell or command. | 1395 | with the current shell or command. |
1396 | If the current session has no tty, | 1396 | If the current session has no tty, |
1397 | this variable is not set. | 1397 | this variable is not set. |
1398 | .It Ev SSH_TUNNEL | ||
1399 | Optionally set by | ||
1400 | .Xr sshd 8 | ||
1401 | to contain the interface names assigned if tunnel forwarding was | ||
1402 | requested by the client. | ||
1398 | .It Ev SSH_USER_AUTH | 1403 | .It Ev SSH_USER_AUTH |
1399 | Optionally set by | 1404 | Optionally set by |
1400 | .Xr sshd 8 , | 1405 | .Xr sshd 8 , |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.465 2017/10/21 23:06:24 millert Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.466 2017/10/23 05:08:00 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,10 @@ char *config = NULL; | |||
168 | */ | 168 | */ |
169 | char *host; | 169 | char *host; |
170 | 170 | ||
171 | /* Various strings used to to percent_expand() arguments */ | ||
172 | static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | ||
173 | static char uidstr[32], *host_arg, *conn_hash_hex; | ||
174 | |||
171 | /* socket address the host resolves to */ | 175 | /* socket address the host resolves to */ |
172 | struct sockaddr_storage hostaddr; | 176 | struct sockaddr_storage hostaddr; |
173 | 177 | ||
@@ -208,8 +212,8 @@ usage(void) | |||
208 | exit(255); | 212 | exit(255); |
209 | } | 213 | } |
210 | 214 | ||
211 | static int ssh_session2(struct ssh *); | 215 | static int ssh_session2(struct ssh *, struct passwd *); |
212 | static void load_public_identity_files(void); | 216 | static void load_public_identity_files(struct passwd *); |
213 | static void main_sigchld_handler(int); | 217 | static void main_sigchld_handler(int); |
214 | 218 | ||
215 | /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ | 219 | /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ |
@@ -456,14 +460,14 @@ resolve_canonicalize(char **hostp, int port) | |||
456 | * file if the user specifies a config file on the command line. | 460 | * file if the user specifies a config file on the command line. |
457 | */ | 461 | */ |
458 | static void | 462 | static void |
459 | process_config_files(const char *host_arg, struct passwd *pw, int post_canon) | 463 | process_config_files(const char *host_name, struct passwd *pw, int post_canon) |
460 | { | 464 | { |
461 | char buf[PATH_MAX]; | 465 | char buf[PATH_MAX]; |
462 | int r; | 466 | int r; |
463 | 467 | ||
464 | if (config != NULL) { | 468 | if (config != NULL) { |
465 | if (strcasecmp(config, "none") != 0 && | 469 | if (strcasecmp(config, "none") != 0 && |
466 | !read_config_file(config, pw, host, host_arg, &options, | 470 | !read_config_file(config, pw, host, host_name, &options, |
467 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) | 471 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) |
468 | fatal("Can't open user config file %.100s: " | 472 | fatal("Can't open user config file %.100s: " |
469 | "%.100s", config, strerror(errno)); | 473 | "%.100s", config, strerror(errno)); |
@@ -471,13 +475,13 @@ process_config_files(const char *host_arg, struct passwd *pw, int post_canon) | |||
471 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | 475 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, |
472 | _PATH_SSH_USER_CONFFILE); | 476 | _PATH_SSH_USER_CONFFILE); |
473 | if (r > 0 && (size_t)r < sizeof(buf)) | 477 | if (r > 0 && (size_t)r < sizeof(buf)) |
474 | (void)read_config_file(buf, pw, host, host_arg, | 478 | (void)read_config_file(buf, pw, host, host_name, |
475 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | | 479 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | |
476 | (post_canon ? SSHCONF_POSTCANON : 0)); | 480 | (post_canon ? SSHCONF_POSTCANON : 0)); |
477 | 481 | ||
478 | /* Read systemwide configuration file after user config. */ | 482 | /* Read systemwide configuration file after user config. */ |
479 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, | 483 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, |
480 | host, host_arg, &options, | 484 | host, host_name, &options, |
481 | post_canon ? SSHCONF_POSTCANON : 0); | 485 | post_canon ? SSHCONF_POSTCANON : 0); |
482 | } | 486 | } |
483 | } | 487 | } |
@@ -511,9 +515,8 @@ main(int ac, char **av) | |||
511 | struct ssh *ssh = NULL; | 515 | struct ssh *ssh = NULL; |
512 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; | 516 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
513 | int config_test = 0, opt_terminated = 0; | 517 | int config_test = 0, opt_terminated = 0; |
514 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; | 518 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
515 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 519 | char cname[NI_MAXHOST]; |
516 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; | ||
517 | struct stat st; | 520 | struct stat st; |
518 | struct passwd *pw; | 521 | struct passwd *pw; |
519 | extern int optind, optreset; | 522 | extern int optind, optreset; |
@@ -1203,6 +1206,7 @@ main(int ac, char **av) | |||
1203 | if (options.user == NULL) | 1206 | if (options.user == NULL) |
1204 | options.user = xstrdup(pw->pw_name); | 1207 | options.user = xstrdup(pw->pw_name); |
1205 | 1208 | ||
1209 | /* Set up strings used to percent_expand() arguments */ | ||
1206 | if (gethostname(thishost, sizeof(thishost)) == -1) | 1210 | if (gethostname(thishost, sizeof(thishost)) == -1) |
1207 | fatal("gethostname: %s", strerror(errno)); | 1211 | fatal("gethostname: %s", strerror(errno)); |
1208 | strlcpy(shorthost, thishost, sizeof(shorthost)); | 1212 | strlcpy(shorthost, thishost, sizeof(shorthost)); |
@@ -1220,24 +1224,11 @@ main(int ac, char **av) | |||
1220 | ssh_digest_free(md); | 1224 | ssh_digest_free(md); |
1221 | conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); | 1225 | conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); |
1222 | 1226 | ||
1223 | if (options.local_command != NULL) { | 1227 | /* |
1224 | debug3("expanding LocalCommand: %s", options.local_command); | 1228 | * Expand tokens in arguments. NB. LocalCommand is expanded later, |
1225 | cp = options.local_command; | 1229 | * after port-forwarding is set up, so it may pick up any local |
1226 | options.local_command = percent_expand(cp, | 1230 | * tunnel interface name allocated. |
1227 | "C", conn_hash_hex, | 1231 | */ |
1228 | "L", shorthost, | ||
1229 | "d", pw->pw_dir, | ||
1230 | "h", host, | ||
1231 | "l", thishost, | ||
1232 | "n", host_arg, | ||
1233 | "p", portstr, | ||
1234 | "r", options.user, | ||
1235 | "u", pw->pw_name, | ||
1236 | (char *)NULL); | ||
1237 | debug3("expanded LocalCommand: %s", options.local_command); | ||
1238 | free(cp); | ||
1239 | } | ||
1240 | |||
1241 | if (options.remote_command != NULL) { | 1232 | if (options.remote_command != NULL) { |
1242 | debug3("expanding RemoteCommand: %s", options.remote_command); | 1233 | debug3("expanding RemoteCommand: %s", options.remote_command); |
1243 | cp = options.remote_command; | 1234 | cp = options.remote_command; |
@@ -1256,7 +1247,6 @@ main(int ac, char **av) | |||
1256 | free(cp); | 1247 | free(cp); |
1257 | buffer_append(&command, options.remote_command, | 1248 | buffer_append(&command, options.remote_command, |
1258 | strlen(options.remote_command)); | 1249 | strlen(options.remote_command)); |
1259 | |||
1260 | } | 1250 | } |
1261 | 1251 | ||
1262 | if (options.control_path != NULL) { | 1252 | if (options.control_path != NULL) { |
@@ -1427,7 +1417,7 @@ main(int ac, char **av) | |||
1427 | } | 1417 | } |
1428 | } | 1418 | } |
1429 | /* load options.identity_files */ | 1419 | /* load options.identity_files */ |
1430 | load_public_identity_files(); | 1420 | load_public_identity_files(pw); |
1431 | 1421 | ||
1432 | /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ | 1422 | /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ |
1433 | if (options.identity_agent && | 1423 | if (options.identity_agent && |
@@ -1491,7 +1481,7 @@ main(int ac, char **av) | |||
1491 | } | 1481 | } |
1492 | 1482 | ||
1493 | skip_connect: | 1483 | skip_connect: |
1494 | exit_status = ssh_session2(ssh); | 1484 | exit_status = ssh_session2(ssh, pw); |
1495 | packet_close(); | 1485 | packet_close(); |
1496 | 1486 | ||
1497 | if (options.control_path != NULL && muxserver_sock != -1) | 1487 | if (options.control_path != NULL && muxserver_sock != -1) |
@@ -1650,7 +1640,7 @@ ssh_init_stdio_forwarding(struct ssh *ssh) | |||
1650 | } | 1640 | } |
1651 | 1641 | ||
1652 | static void | 1642 | static void |
1653 | ssh_init_forwarding(struct ssh *ssh) | 1643 | ssh_init_forwarding(struct ssh *ssh, char **ifname) |
1654 | { | 1644 | { |
1655 | int success = 0; | 1645 | int success = 0; |
1656 | int i; | 1646 | int i; |
@@ -1708,8 +1698,9 @@ ssh_init_forwarding(struct ssh *ssh) | |||
1708 | 1698 | ||
1709 | /* Initiate tunnel forwarding. */ | 1699 | /* Initiate tunnel forwarding. */ |
1710 | if (options.tun_open != SSH_TUNMODE_NO) { | 1700 | if (options.tun_open != SSH_TUNMODE_NO) { |
1711 | if (client_request_tun_fwd(ssh, options.tun_open, | 1701 | if ((*ifname = client_request_tun_fwd(ssh, |
1712 | options.tun_local, options.tun_remote) == -1) { | 1702 | options.tun_open, options.tun_local, |
1703 | options.tun_remote)) == NULL) { | ||
1713 | if (options.exit_on_forward_failure) | 1704 | if (options.exit_on_forward_failure) |
1714 | fatal("Could not request tunnel forwarding."); | 1705 | fatal("Could not request tunnel forwarding."); |
1715 | else | 1706 | else |
@@ -1824,14 +1815,35 @@ ssh_session2_open(struct ssh *ssh) | |||
1824 | } | 1815 | } |
1825 | 1816 | ||
1826 | static int | 1817 | static int |
1827 | ssh_session2(struct ssh *ssh) | 1818 | ssh_session2(struct ssh *ssh, struct passwd *pw) |
1828 | { | 1819 | { |
1829 | int id = -1; | 1820 | int id = -1; |
1821 | char *cp, *tun_fwd_ifname = NULL; | ||
1830 | 1822 | ||
1831 | /* XXX should be pre-session */ | 1823 | /* XXX should be pre-session */ |
1832 | if (!options.control_persist) | 1824 | if (!options.control_persist) |
1833 | ssh_init_stdio_forwarding(ssh); | 1825 | ssh_init_stdio_forwarding(ssh); |
1834 | ssh_init_forwarding(ssh); | 1826 | |
1827 | ssh_init_forwarding(ssh, &tun_fwd_ifname); | ||
1828 | |||
1829 | if (options.local_command != NULL) { | ||
1830 | debug3("expanding LocalCommand: %s", options.local_command); | ||
1831 | cp = options.local_command; | ||
1832 | options.local_command = percent_expand(cp, | ||
1833 | "C", conn_hash_hex, | ||
1834 | "L", shorthost, | ||
1835 | "d", pw->pw_dir, | ||
1836 | "h", host, | ||
1837 | "l", thishost, | ||
1838 | "n", host_arg, | ||
1839 | "p", portstr, | ||
1840 | "r", options.user, | ||
1841 | "u", pw->pw_name, | ||
1842 | "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, | ||
1843 | (char *)NULL); | ||
1844 | debug3("expanded LocalCommand: %s", options.local_command); | ||
1845 | free(cp); | ||
1846 | } | ||
1835 | 1847 | ||
1836 | /* Start listening for multiplex clients */ | 1848 | /* Start listening for multiplex clients */ |
1837 | if (!packet_get_mux()) | 1849 | if (!packet_get_mux()) |
@@ -1907,12 +1919,10 @@ ssh_session2(struct ssh *ssh) | |||
1907 | 1919 | ||
1908 | /* Loads all IdentityFile and CertificateFile keys */ | 1920 | /* Loads all IdentityFile and CertificateFile keys */ |
1909 | static void | 1921 | static void |
1910 | load_public_identity_files(void) | 1922 | load_public_identity_files(struct passwd *pw) |
1911 | { | 1923 | { |
1912 | char *filename, *cp, thishost[NI_MAXHOST]; | 1924 | char *filename, *cp; |
1913 | char *pwdir = NULL, *pwname = NULL; | ||
1914 | struct sshkey *public; | 1925 | struct sshkey *public; |
1915 | struct passwd *pw; | ||
1916 | int i; | 1926 | int i; |
1917 | u_int n_ids, n_certs; | 1927 | u_int n_ids, n_certs; |
1918 | char *identity_files[SSH_MAX_IDENTITY_FILES]; | 1928 | char *identity_files[SSH_MAX_IDENTITY_FILES]; |
@@ -1951,11 +1961,6 @@ load_public_identity_files(void) | |||
1951 | #endif /* ENABLE_PKCS11 */ | 1961 | #endif /* ENABLE_PKCS11 */ |
1952 | if ((pw = getpwuid(original_real_uid)) == NULL) | 1962 | if ((pw = getpwuid(original_real_uid)) == NULL) |
1953 | fatal("load_public_identity_files: getpwuid failed"); | 1963 | fatal("load_public_identity_files: getpwuid failed"); |
1954 | pwname = xstrdup(pw->pw_name); | ||
1955 | pwdir = xstrdup(pw->pw_dir); | ||
1956 | if (gethostname(thishost, sizeof(thishost)) == -1) | ||
1957 | fatal("load_public_identity_files: gethostname: %s", | ||
1958 | strerror(errno)); | ||
1959 | for (i = 0; i < options.num_identity_files; i++) { | 1964 | for (i = 0; i < options.num_identity_files; i++) { |
1960 | if (n_ids >= SSH_MAX_IDENTITY_FILES || | 1965 | if (n_ids >= SSH_MAX_IDENTITY_FILES || |
1961 | strcasecmp(options.identity_files[i], "none") == 0) { | 1966 | strcasecmp(options.identity_files[i], "none") == 0) { |
@@ -1965,8 +1970,8 @@ load_public_identity_files(void) | |||
1965 | } | 1970 | } |
1966 | cp = tilde_expand_filename(options.identity_files[i], | 1971 | cp = tilde_expand_filename(options.identity_files[i], |
1967 | original_real_uid); | 1972 | original_real_uid); |
1968 | filename = percent_expand(cp, "d", pwdir, | 1973 | filename = percent_expand(cp, "d", pw->pw_dir, |
1969 | "u", pwname, "l", thishost, "h", host, | 1974 | "u", pw->pw_name, "l", thishost, "h", host, |
1970 | "r", options.user, (char *)NULL); | 1975 | "r", options.user, (char *)NULL); |
1971 | free(cp); | 1976 | free(cp); |
1972 | public = key_load_public(filename, NULL); | 1977 | public = key_load_public(filename, NULL); |
@@ -2011,8 +2016,8 @@ load_public_identity_files(void) | |||
2011 | for (i = 0; i < options.num_certificate_files; i++) { | 2016 | for (i = 0; i < options.num_certificate_files; i++) { |
2012 | cp = tilde_expand_filename(options.certificate_files[i], | 2017 | cp = tilde_expand_filename(options.certificate_files[i], |
2013 | original_real_uid); | 2018 | original_real_uid); |
2014 | filename = percent_expand(cp, "d", pwdir, | 2019 | filename = percent_expand(cp, "d", pw->pw_dir, |
2015 | "u", pwname, "l", thishost, "h", host, | 2020 | "u", pw->pw_name, "l", thishost, "h", host, |
2016 | "r", options.user, (char *)NULL); | 2021 | "r", options.user, (char *)NULL); |
2017 | free(cp); | 2022 | free(cp); |
2018 | 2023 | ||
@@ -2045,11 +2050,6 @@ load_public_identity_files(void) | |||
2045 | memcpy(options.certificate_files, | 2050 | memcpy(options.certificate_files, |
2046 | certificate_files, sizeof(certificate_files)); | 2051 | certificate_files, sizeof(certificate_files)); |
2047 | memcpy(options.certificates, certificates, sizeof(certificates)); | 2052 | memcpy(options.certificates, certificates, sizeof(certificates)); |
2048 | |||
2049 | explicit_bzero(pwname, strlen(pwname)); | ||
2050 | free(pwname); | ||
2051 | explicit_bzero(pwdir, strlen(pwdir)); | ||
2052 | free(pwdir); | ||
2053 | } | 2053 | } |
2054 | 2054 | ||
2055 | static void | 2055 | static void |
diff --git a/ssh_config.5 b/ssh_config.5 index c04701044..4d3fc3425 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.260 2017/10/21 23:06:24 millert Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.261 2017/10/23 05:08:00 djm Exp $ |
37 | .Dd $Mdocdate: October 21 2017 $ | 37 | .Dd $Mdocdate: October 23 2017 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1713,6 +1713,16 @@ The original remote hostname, as given on the command line. | |||
1713 | The remote port. | 1713 | The remote port. |
1714 | .It %r | 1714 | .It %r |
1715 | The remote username. | 1715 | The remote username. |
1716 | .It \&%T | ||
1717 | The local | ||
1718 | .Xr tun 4 | ||
1719 | or | ||
1720 | .Xr tap 4 | ||
1721 | network interface assigned if | ||
1722 | .Cm Tunnel | ||
1723 | forwarding was requested, or | ||
1724 | .Cm NONE | ||
1725 | otherwise. | ||
1716 | .It %u | 1726 | .It %u |
1717 | The local username. | 1727 | The local username. |
1718 | .El | 1728 | .El |
@@ -1735,7 +1745,7 @@ and | |||
1735 | accept the tokens %%, %d, %h, %l, %r, and %u. | 1745 | accept the tokens %%, %d, %h, %l, %r, and %u. |
1736 | .Pp | 1746 | .Pp |
1737 | .Cm LocalCommand | 1747 | .Cm LocalCommand |
1738 | accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u. | 1748 | accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, %T, and %u. |
1739 | .Pp | 1749 | .Pp |
1740 | .Cm ProxyCommand | 1750 | .Cm ProxyCommand |
1741 | accepts the tokens %%, %h, %p, and %r. | 1751 | accepts the tokens %%, %h, %p, and %r. |