Skip to content
Permalink
Browse files
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
  • Loading branch information
djmdjm committed Oct 23, 2017
1 parent 887669e commit b7548b1
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 77 deletions.
@@ -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>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1601,23 +1601,25 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
return c;
}

int
char *
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
int local_tun, int remote_tun)
{
Channel *c;
int fd;
char *ifname = NULL;

if (tun_mode == SSH_TUNMODE_NO)
return 0;

debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);

/* 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.");
return -1;
return NULL;
}
debug("Tunnel forwarding using interface %s", ifname);

c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -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_send();

return 0;
return ifname;
}

/* 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>
@@ -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_session2_setup(struct ssh *, int, int, int,
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);

/* Escape filter for protocol 2 sessions */
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) 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
tun_open(int tun, int mode)
tun_open(int tun, int mode, char **ifname)
{
#if defined(CUSTOM_SYS_TUN_OPEN)
return (sys_tun_open(tun, mode));
return (sys_tun_open(tun, mode, ifname));
#elif defined(SSH_TUN_OPENBSD)
struct ifreq ifr;
char name[100];
int fd = -1, sock;
const char *tunbase = "tun";

if (ifname != NULL)
*ifname = NULL;

if (mode == SSH_TUNMODE_ETHERNET)
tunbase = "tap";

@@ -1020,6 +1023,9 @@ tun_open(int tun, int mode)
}
}

if (ifname != NULL)
*ifname = xstrdup(ifr.ifr_name);

close(sock);
return fd;

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>
@@ -87,7 +87,7 @@ void replacearg(arglist *, u_int, char *, ...)
__attribute__((format(printf, 3, 4)));
void freeargs(arglist *);

int tun_open(int, int);
int tun_open(int, int, char **);

/* Common definitions for ssh tunnel device forwarding */
#define SSH_TUNMODE_NO 0x00
@@ -56,12 +56,15 @@
#include <linux/if_tun.h>

int
sys_tun_open(int tun, int mode)
sys_tun_open(int tun, int mode, char **ifname)
{
struct ifreq ifr;
int fd = -1;
const char *name = NULL;

if (ifname != NULL)
*ifname = NULL;

if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
debug("%s: failed to open tunnel control interface: %s",
__func__, strerror(errno));
@@ -99,6 +102,9 @@ sys_tun_open(int tun, int mode)
else
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);

failed:
@@ -116,13 +122,16 @@ sys_tun_open(int tun, int mode)
#endif

int
sys_tun_open(int tun, int mode)
sys_tun_open(int tun, int mode, char **ifname)
{
struct ifreq ifr;
char name[100];
int fd = -1, sock, flag;
const char *tunbase = "tun";

if (ifname != NULL)
*ifname = NULL;

if (mode == SSH_TUNMODE_ETHERNET) {
#ifdef SSH_TUN_NO_L2
debug("%s: no layer 2 tunnelling support", __func__);
@@ -180,6 +189,9 @@ sys_tun_open(int tun, int mode)
goto failed;
}

if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)))
goto failed;

close(sock);
return (fd);

@@ -22,7 +22,7 @@ struct ssh;

#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
# define CUSTOM_SYS_TUN_OPEN
int sys_tun_open(int, int);
int sys_tun_open(int, int, char **);
#endif

#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
@@ -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>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -99,6 +99,9 @@ static volatile sig_atomic_t received_sigterm = 0;
/* prototypes */
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
* the race between select() and child_terminated
@@ -519,6 +522,7 @@ server_request_tun(struct ssh *ssh)
Channel *c = NULL;
int mode, tun;
int sock;
char *tmp, *ifname = NULL;

mode = packet_get_int();
switch (mode) {
@@ -541,9 +545,10 @@ server_request_tun(struct ssh *ssh)
goto done;
tun = forced_tun_device;
}
sock = tun_open(tun, mode);
sock = tun_open(tun, mode, &ifname);
if (sock < 0)
goto done;
debug("Tunnel forwarding using interface %s", ifname);
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
@@ -553,6 +558,19 @@ server_request_tun(struct ssh *ssh)
sys_tun_outfilter, NULL, NULL);
#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:
if (c == NULL)
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
* All rights reserved
@@ -140,6 +140,7 @@ extern u_int utmp_len;
extern int startup_pipe;
extern void destroy_sensitive_data(void);
extern Buffer loginmsg;
char *tun_fwd_ifnames; /* serverloop.c */

/* original command from peer. */
const char *original_command = NULL;
@@ -1066,6 +1067,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
free(laddr);
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)
child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
if (s->ttyfd != -1)
9 ssh.1
@@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.386 2017/10/21 23:06:24 millert Exp $
.Dd $Mdocdate: October 21 2017 $
.\" $OpenBSD: ssh.1,v 1.387 2017/10/23 05:08:00 djm Exp $
.Dd $Mdocdate: October 23 2017 $
.Dt SSH 1
.Os
.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.
If the current session has no tty,
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
Optionally set by
.Xr sshd 8 ,

0 comments on commit b7548b1

Please sign in to comment.