mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
upstream commit
Expose devices allocated for tun/tap forwarding. At the client, the device may be obtained from a new %T expansion for LocalCommand. At the server, the allocated devices will be listed in a SSH_TUNNEL variable exposed to the environment of any user sessions started after the tunnel forwarding was established. ok markus Upstream-ID: e61e53f8ae80566e9ddc0d67a5df5bdf2f3c9f9e
This commit is contained in:
parent
887669ef03
commit
b7548b12a6
12
clientloop.c
12
clientloop.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.c,v 1.305 2017/09/19 04:24:22 djm Exp $ */
|
/* $OpenBSD: clientloop.c,v 1.306 2017/10/23 05:08:00 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
|
||||||
@ -1601,12 +1601,13 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
char *
|
||||||
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
||||||
int local_tun, int remote_tun)
|
int local_tun, int remote_tun)
|
||||||
{
|
{
|
||||||
Channel *c;
|
Channel *c;
|
||||||
int fd;
|
int fd;
|
||||||
|
char *ifname = NULL;
|
||||||
|
|
||||||
if (tun_mode == SSH_TUNMODE_NO)
|
if (tun_mode == SSH_TUNMODE_NO)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1614,10 +1615,11 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
|||||||
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
|
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
|
||||||
|
|
||||||
/* Open local tunnel device */
|
/* Open local tunnel device */
|
||||||
if ((fd = tun_open(local_tun, tun_mode)) == -1) {
|
if ((fd = tun_open(local_tun, tun_mode, &ifname)) == -1) {
|
||||||
error("Tunnel device open failed.");
|
error("Tunnel device open failed.");
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
debug("Tunnel forwarding using interface %s", ifname);
|
||||||
|
|
||||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
|
c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
|
||||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
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,
|
|||||||
packet_put_int(remote_tun);
|
packet_put_int(remote_tun);
|
||||||
packet_send();
|
packet_send();
|
||||||
|
|
||||||
return 0;
|
return ifname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXXX move to generic input handler */
|
/* XXXX move to generic input handler */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */
|
/* $OpenBSD: clientloop.h,v 1.35 2017/10/23 05:08:00 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -46,7 +46,7 @@ int client_x11_get_proto(struct ssh *, const char *, const char *,
|
|||||||
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
||||||
void client_session2_setup(struct ssh *, int, int, int,
|
void client_session2_setup(struct ssh *, int, int, int,
|
||||||
const char *, struct termios *, int, Buffer *, char **);
|
const char *, struct termios *, int, Buffer *, char **);
|
||||||
int client_request_tun_fwd(struct ssh *, int, int, int);
|
char *client_request_tun_fwd(struct ssh *, int, int, int);
|
||||||
void client_stop_mux(void);
|
void client_stop_mux(void);
|
||||||
|
|
||||||
/* Escape filter for protocol 2 sessions */
|
/* Escape filter for protocol 2 sessions */
|
||||||
|
12
misc.c
12
misc.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: misc.c,v 1.114 2017/10/21 23:06:24 millert Exp $ */
|
/* $OpenBSD: misc.c,v 1.115 2017/10/23 05:08:00 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
* 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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
tun_open(int tun, int mode)
|
tun_open(int tun, int mode, char **ifname)
|
||||||
{
|
{
|
||||||
#if defined(CUSTOM_SYS_TUN_OPEN)
|
#if defined(CUSTOM_SYS_TUN_OPEN)
|
||||||
return (sys_tun_open(tun, mode));
|
return (sys_tun_open(tun, mode, ifname));
|
||||||
#elif defined(SSH_TUN_OPENBSD)
|
#elif defined(SSH_TUN_OPENBSD)
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
char name[100];
|
char name[100];
|
||||||
int fd = -1, sock;
|
int fd = -1, sock;
|
||||||
const char *tunbase = "tun";
|
const char *tunbase = "tun";
|
||||||
|
|
||||||
|
if (ifname != NULL)
|
||||||
|
*ifname = NULL;
|
||||||
|
|
||||||
if (mode == SSH_TUNMODE_ETHERNET)
|
if (mode == SSH_TUNMODE_ETHERNET)
|
||||||
tunbase = "tap";
|
tunbase = "tap";
|
||||||
|
|
||||||
@ -1020,6 +1023,9 @@ tun_open(int tun, int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifname != NULL)
|
||||||
|
*ifname = xstrdup(ifr.ifr_name);
|
||||||
|
|
||||||
close(sock);
|
close(sock);
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
|
4
misc.h
4
misc.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: misc.h,v 1.64 2017/10/21 23:06:24 millert Exp $ */
|
/* $OpenBSD: misc.h,v 1.65 2017/10/23 05:08:00 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -87,7 +87,7 @@ void replacearg(arglist *, u_int, char *, ...)
|
|||||||
__attribute__((format(printf, 3, 4)));
|
__attribute__((format(printf, 3, 4)));
|
||||||
void freeargs(arglist *);
|
void freeargs(arglist *);
|
||||||
|
|
||||||
int tun_open(int, int);
|
int tun_open(int, int, char **);
|
||||||
|
|
||||||
/* Common definitions for ssh tunnel device forwarding */
|
/* Common definitions for ssh tunnel device forwarding */
|
||||||
#define SSH_TUNMODE_NO 0x00
|
#define SSH_TUNMODE_NO 0x00
|
||||||
|
@ -56,12 +56,15 @@
|
|||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_tun_open(int tun, int mode)
|
sys_tun_open(int tun, int mode, char **ifname)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
|
||||||
|
if (ifname != NULL)
|
||||||
|
*ifname = NULL;
|
||||||
|
|
||||||
if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
|
if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
|
||||||
debug("%s: failed to open tunnel control interface: %s",
|
debug("%s: failed to open tunnel control interface: %s",
|
||||||
__func__, strerror(errno));
|
__func__, strerror(errno));
|
||||||
@ -99,6 +102,9 @@ sys_tun_open(int tun, int mode)
|
|||||||
else
|
else
|
||||||
debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
|
debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
|
||||||
|
|
||||||
|
if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
return (fd);
|
return (fd);
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
@ -116,13 +122,16 @@ sys_tun_open(int tun, int mode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_tun_open(int tun, int mode)
|
sys_tun_open(int tun, int mode, char **ifname)
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
char name[100];
|
char name[100];
|
||||||
int fd = -1, sock, flag;
|
int fd = -1, sock, flag;
|
||||||
const char *tunbase = "tun";
|
const char *tunbase = "tun";
|
||||||
|
|
||||||
|
if (ifname != NULL)
|
||||||
|
*ifname = NULL;
|
||||||
|
|
||||||
if (mode == SSH_TUNMODE_ETHERNET) {
|
if (mode == SSH_TUNMODE_ETHERNET) {
|
||||||
#ifdef SSH_TUN_NO_L2
|
#ifdef SSH_TUN_NO_L2
|
||||||
debug("%s: no layer 2 tunnelling support", __func__);
|
debug("%s: no layer 2 tunnelling support", __func__);
|
||||||
@ -180,6 +189,9 @@ sys_tun_open(int tun, int mode)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
close(sock);
|
close(sock);
|
||||||
return (fd);
|
return (fd);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ struct ssh;
|
|||||||
|
|
||||||
#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
|
#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
|
||||||
# define CUSTOM_SYS_TUN_OPEN
|
# define CUSTOM_SYS_TUN_OPEN
|
||||||
int sys_tun_open(int, int);
|
int sys_tun_open(int, int, char **);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
|
#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
|
||||||
|
22
serverloop.c
22
serverloop.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */
|
/* $OpenBSD: serverloop.c,v 1.199 2017/10/23 05:08:00 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
|
||||||
@ -99,6 +99,9 @@ static volatile sig_atomic_t received_sigterm = 0;
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
static void server_init_dispatch(void);
|
static void server_init_dispatch(void);
|
||||||
|
|
||||||
|
/* requested tunnel forwarding interface(s), shared with session.c */
|
||||||
|
char *tun_fwd_ifnames = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we write to this pipe if a SIGCHLD is caught in order to avoid
|
* we write to this pipe if a SIGCHLD is caught in order to avoid
|
||||||
* the race between select() and child_terminated
|
* the race between select() and child_terminated
|
||||||
@ -519,6 +522,7 @@ server_request_tun(struct ssh *ssh)
|
|||||||
Channel *c = NULL;
|
Channel *c = NULL;
|
||||||
int mode, tun;
|
int mode, tun;
|
||||||
int sock;
|
int sock;
|
||||||
|
char *tmp, *ifname = NULL;
|
||||||
|
|
||||||
mode = packet_get_int();
|
mode = packet_get_int();
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@ -541,9 +545,10 @@ server_request_tun(struct ssh *ssh)
|
|||||||
goto done;
|
goto done;
|
||||||
tun = forced_tun_device;
|
tun = forced_tun_device;
|
||||||
}
|
}
|
||||||
sock = tun_open(tun, mode);
|
sock = tun_open(tun, mode, &ifname);
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
debug("Tunnel forwarding using interface %s", ifname);
|
||||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
|
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
||||||
c->datagram = 1;
|
c->datagram = 1;
|
||||||
@ -553,6 +558,19 @@ server_request_tun(struct ssh *ssh)
|
|||||||
sys_tun_outfilter, NULL, NULL);
|
sys_tun_outfilter, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the list of names exposed to the session
|
||||||
|
* XXX remove these if the tunnels are closed (won't matter
|
||||||
|
* much if they are already in the environment though)
|
||||||
|
*/
|
||||||
|
tmp = tun_fwd_ifnames;
|
||||||
|
xasprintf(&tun_fwd_ifnames, "%s%s%s",
|
||||||
|
tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames,
|
||||||
|
tun_fwd_ifnames == NULL ? "" : ",",
|
||||||
|
ifname);
|
||||||
|
free(tmp);
|
||||||
|
free(ifname);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
packet_send_debug("Failed to open the tunnel device.");
|
packet_send_debug("Failed to open the tunnel device.");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
|
/* $OpenBSD: session.c,v 1.293 2017/10/23 05:08:00 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
@ -140,6 +140,7 @@ extern u_int utmp_len;
|
|||||||
extern int startup_pipe;
|
extern int startup_pipe;
|
||||||
extern void destroy_sensitive_data(void);
|
extern void destroy_sensitive_data(void);
|
||||||
extern Buffer loginmsg;
|
extern Buffer loginmsg;
|
||||||
|
char *tun_fwd_ifnames; /* serverloop.c */
|
||||||
|
|
||||||
/* original command from peer. */
|
/* original command from peer. */
|
||||||
const char *original_command = NULL;
|
const char *original_command = NULL;
|
||||||
@ -1066,6 +1067,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
|
|||||||
free(laddr);
|
free(laddr);
|
||||||
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
|
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
|
||||||
|
|
||||||
|
if (tun_fwd_ifnames != NULL)
|
||||||
|
child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames);
|
||||||
if (auth_info_file != NULL)
|
if (auth_info_file != NULL)
|
||||||
child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
|
child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
|
||||||
if (s->ttyfd != -1)
|
if (s->ttyfd != -1)
|
||||||
|
9
ssh.1
9
ssh.1
@ -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.1,v 1.386 2017/10/21 23:06:24 millert Exp $
|
.\" $OpenBSD: ssh.1,v 1.387 2017/10/23 05:08:00 djm Exp $
|
||||||
.Dd $Mdocdate: October 21 2017 $
|
.Dd $Mdocdate: October 23 2017 $
|
||||||
.Dt SSH 1
|
.Dt SSH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -1395,6 +1395,11 @@ This is set to the name of the tty (path to the device) associated
|
|||||||
with the current shell or command.
|
with the current shell or command.
|
||||||
If the current session has no tty,
|
If the current session has no tty,
|
||||||
this variable is not set.
|
this variable is not set.
|
||||||
|
.It Ev SSH_TUNNEL
|
||||||
|
Optionally set by
|
||||||
|
.Xr sshd 8
|
||||||
|
to contain the interface names assigned if tunnel forwarding was
|
||||||
|
requested by the client.
|
||||||
.It Ev SSH_USER_AUTH
|
.It Ev SSH_USER_AUTH
|
||||||
Optionally set by
|
Optionally set by
|
||||||
.Xr sshd 8 ,
|
.Xr sshd 8 ,
|
||||||
|
108
ssh.c
108
ssh.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssh.c,v 1.465 2017/10/21 23:06:24 millert Exp $ */
|
/* $OpenBSD: ssh.c,v 1.466 2017/10/23 05:08:00 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,10 @@ char *config = NULL;
|
|||||||
*/
|
*/
|
||||||
char *host;
|
char *host;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
/* socket address the host resolves to */
|
/* socket address the host resolves to */
|
||||||
struct sockaddr_storage hostaddr;
|
struct sockaddr_storage hostaddr;
|
||||||
|
|
||||||
@ -208,8 +212,8 @@ usage(void)
|
|||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ssh_session2(struct ssh *);
|
static int ssh_session2(struct ssh *, struct passwd *);
|
||||||
static void load_public_identity_files(void);
|
static void load_public_identity_files(struct passwd *);
|
||||||
static void main_sigchld_handler(int);
|
static void main_sigchld_handler(int);
|
||||||
|
|
||||||
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
|
/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
|
||||||
@ -456,14 +460,14 @@ resolve_canonicalize(char **hostp, int port)
|
|||||||
* file if the user specifies a config file on the command line.
|
* file if the user specifies a config file on the command line.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
|
process_config_files(const char *host_name, struct passwd *pw, int post_canon)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (config != NULL) {
|
if (config != NULL) {
|
||||||
if (strcasecmp(config, "none") != 0 &&
|
if (strcasecmp(config, "none") != 0 &&
|
||||||
!read_config_file(config, pw, host, host_arg, &options,
|
!read_config_file(config, pw, host, host_name, &options,
|
||||||
SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
|
SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))
|
||||||
fatal("Can't open user config file %.100s: "
|
fatal("Can't open user config file %.100s: "
|
||||||
"%.100s", config, strerror(errno));
|
"%.100s", config, strerror(errno));
|
||||||
@ -471,13 +475,13 @@ process_config_files(const char *host_arg, struct passwd *pw, int post_canon)
|
|||||||
r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
|
r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
|
||||||
_PATH_SSH_USER_CONFFILE);
|
_PATH_SSH_USER_CONFFILE);
|
||||||
if (r > 0 && (size_t)r < sizeof(buf))
|
if (r > 0 && (size_t)r < sizeof(buf))
|
||||||
(void)read_config_file(buf, pw, host, host_arg,
|
(void)read_config_file(buf, pw, host, host_name,
|
||||||
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
|
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
|
||||||
(post_canon ? SSHCONF_POSTCANON : 0));
|
(post_canon ? SSHCONF_POSTCANON : 0));
|
||||||
|
|
||||||
/* Read systemwide configuration file after user config. */
|
/* Read systemwide configuration file after user config. */
|
||||||
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
|
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
|
||||||
host, host_arg, &options,
|
host, host_name, &options,
|
||||||
post_canon ? SSHCONF_POSTCANON : 0);
|
post_canon ? SSHCONF_POSTCANON : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,9 +515,8 @@ main(int ac, char **av)
|
|||||||
struct ssh *ssh = NULL;
|
struct ssh *ssh = NULL;
|
||||||
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
|
int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
|
||||||
int config_test = 0, opt_terminated = 0;
|
int config_test = 0, opt_terminated = 0;
|
||||||
char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile;
|
char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile;
|
||||||
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
|
char cname[NI_MAXHOST];
|
||||||
char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
extern int optind, optreset;
|
extern int optind, optreset;
|
||||||
@ -1203,6 +1206,7 @@ main(int ac, char **av)
|
|||||||
if (options.user == NULL)
|
if (options.user == NULL)
|
||||||
options.user = xstrdup(pw->pw_name);
|
options.user = xstrdup(pw->pw_name);
|
||||||
|
|
||||||
|
/* Set up strings used to percent_expand() arguments */
|
||||||
if (gethostname(thishost, sizeof(thishost)) == -1)
|
if (gethostname(thishost, sizeof(thishost)) == -1)
|
||||||
fatal("gethostname: %s", strerror(errno));
|
fatal("gethostname: %s", strerror(errno));
|
||||||
strlcpy(shorthost, thishost, sizeof(shorthost));
|
strlcpy(shorthost, thishost, sizeof(shorthost));
|
||||||
@ -1220,24 +1224,11 @@ main(int ac, char **av)
|
|||||||
ssh_digest_free(md);
|
ssh_digest_free(md);
|
||||||
conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
|
||||||
|
|
||||||
if (options.local_command != NULL) {
|
/*
|
||||||
debug3("expanding LocalCommand: %s", options.local_command);
|
* Expand tokens in arguments. NB. LocalCommand is expanded later,
|
||||||
cp = options.local_command;
|
* after port-forwarding is set up, so it may pick up any local
|
||||||
options.local_command = percent_expand(cp,
|
* tunnel interface name allocated.
|
||||||
"C", conn_hash_hex,
|
*/
|
||||||
"L", shorthost,
|
|
||||||
"d", pw->pw_dir,
|
|
||||||
"h", host,
|
|
||||||
"l", thishost,
|
|
||||||
"n", host_arg,
|
|
||||||
"p", portstr,
|
|
||||||
"r", options.user,
|
|
||||||
"u", pw->pw_name,
|
|
||||||
(char *)NULL);
|
|
||||||
debug3("expanded LocalCommand: %s", options.local_command);
|
|
||||||
free(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.remote_command != NULL) {
|
if (options.remote_command != NULL) {
|
||||||
debug3("expanding RemoteCommand: %s", options.remote_command);
|
debug3("expanding RemoteCommand: %s", options.remote_command);
|
||||||
cp = options.remote_command;
|
cp = options.remote_command;
|
||||||
@ -1256,7 +1247,6 @@ main(int ac, char **av)
|
|||||||
free(cp);
|
free(cp);
|
||||||
buffer_append(&command, options.remote_command,
|
buffer_append(&command, options.remote_command,
|
||||||
strlen(options.remote_command));
|
strlen(options.remote_command));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.control_path != NULL) {
|
if (options.control_path != NULL) {
|
||||||
@ -1427,7 +1417,7 @@ main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* load options.identity_files */
|
/* load options.identity_files */
|
||||||
load_public_identity_files();
|
load_public_identity_files(pw);
|
||||||
|
|
||||||
/* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */
|
/* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */
|
||||||
if (options.identity_agent &&
|
if (options.identity_agent &&
|
||||||
@ -1491,7 +1481,7 @@ main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
skip_connect:
|
skip_connect:
|
||||||
exit_status = ssh_session2(ssh);
|
exit_status = ssh_session2(ssh, pw);
|
||||||
packet_close();
|
packet_close();
|
||||||
|
|
||||||
if (options.control_path != NULL && muxserver_sock != -1)
|
if (options.control_path != NULL && muxserver_sock != -1)
|
||||||
@ -1650,7 +1640,7 @@ ssh_init_stdio_forwarding(struct ssh *ssh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ssh_init_forwarding(struct ssh *ssh)
|
ssh_init_forwarding(struct ssh *ssh, char **ifname)
|
||||||
{
|
{
|
||||||
int success = 0;
|
int success = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -1708,8 +1698,9 @@ ssh_init_forwarding(struct ssh *ssh)
|
|||||||
|
|
||||||
/* Initiate tunnel forwarding. */
|
/* Initiate tunnel forwarding. */
|
||||||
if (options.tun_open != SSH_TUNMODE_NO) {
|
if (options.tun_open != SSH_TUNMODE_NO) {
|
||||||
if (client_request_tun_fwd(ssh, options.tun_open,
|
if ((*ifname = client_request_tun_fwd(ssh,
|
||||||
options.tun_local, options.tun_remote) == -1) {
|
options.tun_open, options.tun_local,
|
||||||
|
options.tun_remote)) == NULL) {
|
||||||
if (options.exit_on_forward_failure)
|
if (options.exit_on_forward_failure)
|
||||||
fatal("Could not request tunnel forwarding.");
|
fatal("Could not request tunnel forwarding.");
|
||||||
else
|
else
|
||||||
@ -1824,14 +1815,35 @@ ssh_session2_open(struct ssh *ssh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ssh_session2(struct ssh *ssh)
|
ssh_session2(struct ssh *ssh, struct passwd *pw)
|
||||||
{
|
{
|
||||||
int id = -1;
|
int id = -1;
|
||||||
|
char *cp, *tun_fwd_ifname = NULL;
|
||||||
|
|
||||||
/* XXX should be pre-session */
|
/* XXX should be pre-session */
|
||||||
if (!options.control_persist)
|
if (!options.control_persist)
|
||||||
ssh_init_stdio_forwarding(ssh);
|
ssh_init_stdio_forwarding(ssh);
|
||||||
ssh_init_forwarding(ssh);
|
|
||||||
|
ssh_init_forwarding(ssh, &tun_fwd_ifname);
|
||||||
|
|
||||||
|
if (options.local_command != NULL) {
|
||||||
|
debug3("expanding LocalCommand: %s", options.local_command);
|
||||||
|
cp = options.local_command;
|
||||||
|
options.local_command = percent_expand(cp,
|
||||||
|
"C", conn_hash_hex,
|
||||||
|
"L", shorthost,
|
||||||
|
"d", pw->pw_dir,
|
||||||
|
"h", host,
|
||||||
|
"l", thishost,
|
||||||
|
"n", host_arg,
|
||||||
|
"p", portstr,
|
||||||
|
"r", options.user,
|
||||||
|
"u", pw->pw_name,
|
||||||
|
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
|
||||||
|
(char *)NULL);
|
||||||
|
debug3("expanded LocalCommand: %s", options.local_command);
|
||||||
|
free(cp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Start listening for multiplex clients */
|
/* Start listening for multiplex clients */
|
||||||
if (!packet_get_mux())
|
if (!packet_get_mux())
|
||||||
@ -1907,12 +1919,10 @@ ssh_session2(struct ssh *ssh)
|
|||||||
|
|
||||||
/* Loads all IdentityFile and CertificateFile keys */
|
/* Loads all IdentityFile and CertificateFile keys */
|
||||||
static void
|
static void
|
||||||
load_public_identity_files(void)
|
load_public_identity_files(struct passwd *pw)
|
||||||
{
|
{
|
||||||
char *filename, *cp, thishost[NI_MAXHOST];
|
char *filename, *cp;
|
||||||
char *pwdir = NULL, *pwname = NULL;
|
|
||||||
struct sshkey *public;
|
struct sshkey *public;
|
||||||
struct passwd *pw;
|
|
||||||
int i;
|
int i;
|
||||||
u_int n_ids, n_certs;
|
u_int n_ids, n_certs;
|
||||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||||
@ -1951,11 +1961,6 @@ load_public_identity_files(void)
|
|||||||
#endif /* ENABLE_PKCS11 */
|
#endif /* ENABLE_PKCS11 */
|
||||||
if ((pw = getpwuid(original_real_uid)) == NULL)
|
if ((pw = getpwuid(original_real_uid)) == NULL)
|
||||||
fatal("load_public_identity_files: getpwuid failed");
|
fatal("load_public_identity_files: getpwuid failed");
|
||||||
pwname = xstrdup(pw->pw_name);
|
|
||||||
pwdir = xstrdup(pw->pw_dir);
|
|
||||||
if (gethostname(thishost, sizeof(thishost)) == -1)
|
|
||||||
fatal("load_public_identity_files: gethostname: %s",
|
|
||||||
strerror(errno));
|
|
||||||
for (i = 0; i < options.num_identity_files; i++) {
|
for (i = 0; i < options.num_identity_files; i++) {
|
||||||
if (n_ids >= SSH_MAX_IDENTITY_FILES ||
|
if (n_ids >= SSH_MAX_IDENTITY_FILES ||
|
||||||
strcasecmp(options.identity_files[i], "none") == 0) {
|
strcasecmp(options.identity_files[i], "none") == 0) {
|
||||||
@ -1965,8 +1970,8 @@ load_public_identity_files(void)
|
|||||||
}
|
}
|
||||||
cp = tilde_expand_filename(options.identity_files[i],
|
cp = tilde_expand_filename(options.identity_files[i],
|
||||||
original_real_uid);
|
original_real_uid);
|
||||||
filename = percent_expand(cp, "d", pwdir,
|
filename = percent_expand(cp, "d", pw->pw_dir,
|
||||||
"u", pwname, "l", thishost, "h", host,
|
"u", pw->pw_name, "l", thishost, "h", host,
|
||||||
"r", options.user, (char *)NULL);
|
"r", options.user, (char *)NULL);
|
||||||
free(cp);
|
free(cp);
|
||||||
public = key_load_public(filename, NULL);
|
public = key_load_public(filename, NULL);
|
||||||
@ -2011,8 +2016,8 @@ load_public_identity_files(void)
|
|||||||
for (i = 0; i < options.num_certificate_files; i++) {
|
for (i = 0; i < options.num_certificate_files; i++) {
|
||||||
cp = tilde_expand_filename(options.certificate_files[i],
|
cp = tilde_expand_filename(options.certificate_files[i],
|
||||||
original_real_uid);
|
original_real_uid);
|
||||||
filename = percent_expand(cp, "d", pwdir,
|
filename = percent_expand(cp, "d", pw->pw_dir,
|
||||||
"u", pwname, "l", thishost, "h", host,
|
"u", pw->pw_name, "l", thishost, "h", host,
|
||||||
"r", options.user, (char *)NULL);
|
"r", options.user, (char *)NULL);
|
||||||
free(cp);
|
free(cp);
|
||||||
|
|
||||||
@ -2045,11 +2050,6 @@ load_public_identity_files(void)
|
|||||||
memcpy(options.certificate_files,
|
memcpy(options.certificate_files,
|
||||||
certificate_files, sizeof(certificate_files));
|
certificate_files, sizeof(certificate_files));
|
||||||
memcpy(options.certificates, certificates, sizeof(certificates));
|
memcpy(options.certificates, certificates, sizeof(certificates));
|
||||||
|
|
||||||
explicit_bzero(pwname, strlen(pwname));
|
|
||||||
free(pwname);
|
|
||||||
explicit_bzero(pwdir, strlen(pwdir));
|
|
||||||
free(pwdir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
16
ssh_config.5
16
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.260 2017/10/21 23:06:24 millert Exp $
|
.\" $OpenBSD: ssh_config.5,v 1.261 2017/10/23 05:08:00 djm Exp $
|
||||||
.Dd $Mdocdate: October 21 2017 $
|
.Dd $Mdocdate: October 23 2017 $
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -1713,6 +1713,16 @@ The original remote hostname, as given on the command line.
|
|||||||
The remote port.
|
The remote port.
|
||||||
.It %r
|
.It %r
|
||||||
The remote username.
|
The remote username.
|
||||||
|
.It \&%T
|
||||||
|
The local
|
||||||
|
.Xr tun 4
|
||||||
|
or
|
||||||
|
.Xr tap 4
|
||||||
|
network interface assigned if
|
||||||
|
.Cm Tunnel
|
||||||
|
forwarding was requested, or
|
||||||
|
.Cm NONE
|
||||||
|
otherwise.
|
||||||
.It %u
|
.It %u
|
||||||
The local username.
|
The local username.
|
||||||
.El
|
.El
|
||||||
@ -1735,7 +1745,7 @@ and
|
|||||||
accept the tokens %%, %d, %h, %l, %r, and %u.
|
accept the tokens %%, %d, %h, %l, %r, and %u.
|
||||||
.Pp
|
.Pp
|
||||||
.Cm LocalCommand
|
.Cm LocalCommand
|
||||||
accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
|
accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, %T, and %u.
|
||||||
.Pp
|
.Pp
|
||||||
.Cm ProxyCommand
|
.Cm ProxyCommand
|
||||||
accepts the tokens %%, %h, %p, and %r.
|
accepts the tokens %%, %h, %p, and %r.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user