[auth-options.c includes.h misc.c misc.h readconf.c servconf.c]
     [serverloop.c ssh.c ssh_config.5 sshd_config.5 configure.ac]
     two changes to the new ssh tunnel support. this breaks compatibility
     with the initial commit but is required for a portable approach.
     - make the tunnel id u_int and platform friendly, use predefined types.
     - support configuration of layer 2 (ethernet) or layer 3
     (point-to-point, default) modes. configuration is done using the
     Tunnel (yes|point-to-point|ethernet|no) option is ssh_config(5) and
     restricted by the PermitTunnel (yes|point-to-point|ethernet|no) option
     in sshd_config(5).
     ok djm@, man page bits by jmc@
This commit is contained in:
Damien Miller 2005-12-13 19:33:19 +11:00
parent 957d4e430e
commit 7b58e80036
12 changed files with 177 additions and 52 deletions

View File

@ -36,6 +36,18 @@
- jmc@cvs.openbsd.org 2005/12/08 15:06:29 - jmc@cvs.openbsd.org 2005/12/08 15:06:29
[ssh_config.5] [ssh_config.5]
keep options in order; keep options in order;
- reyk@cvs.openbsd.org 2005/12/08 18:34:11
[auth-options.c includes.h misc.c misc.h readconf.c servconf.c]
[serverloop.c ssh.c ssh_config.5 sshd_config.5 configure.ac]
two changes to the new ssh tunnel support. this breaks compatibility
with the initial commit but is required for a portable approach.
- make the tunnel id u_int and platform friendly, use predefined types.
- support configuration of layer 2 (ethernet) or layer 3
(point-to-point, default) modes. configuration is done using the
Tunnel (yes|point-to-point|ethernet|no) option is ssh_config(5) and
restricted by the PermitTunnel (yes|point-to-point|ethernet|no) option
in sshd_config(5).
ok djm@, man page bits by jmc@
20051201 20051201
- (djm) [envpass.sh] Remove regress script that was accidentally committed - (djm) [envpass.sh] Remove regress script that was accidentally committed
@ -3428,4 +3440,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
$Id: ChangeLog,v 1.4023 2005/12/13 08:30:45 djm Exp $ $Id: ChangeLog,v 1.4024 2005/12/13 08:33:19 djm Exp $

View File

@ -10,7 +10,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: auth-options.c,v 1.32 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: auth-options.c,v 1.33 2005/12/08 18:34:11 reyk Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "match.h" #include "match.h"
@ -296,7 +296,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
tun[i] = 0; tun[i] = 0;
forced_tun_device = a2tun(tun, NULL); forced_tun_device = a2tun(tun, NULL);
xfree(tun); xfree(tun);
if (forced_tun_device < -1) { if (forced_tun_device == SSH_TUNID_ERR) {
debug("%.100s, line %lu: invalid tun device", debug("%.100s, line %lu: invalid tun device",
file, linenum); file, linenum);
auth_debug_add("%.100s, line %lu: invalid tun device", auth_debug_add("%.100s, line %lu: invalid tun device",

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.312 2005/11/29 02:40:34 tim Exp $ # $Id: configure.ac,v 1.313 2005/12/13 08:33:20 djm Exp $
# #
# Copyright (c) 1999-2004 Damien Miller # Copyright (c) 1999-2004 Damien Miller
# #
@ -654,6 +654,7 @@ AC_CHECK_HEADERS( \
login_cap.h \ login_cap.h \
maillock.h \ maillock.h \
ndir.h \ ndir.h \
net/if.h \
netdb.h \ netdb.h \
netgroup.h \ netgroup.h \
netinet/in_systm.h \ netinet/in_systm.h \

View File

@ -1,4 +1,4 @@
/* $OpenBSD: includes.h,v 1.20 2005/11/15 11:59:54 millert Exp $ */ /* $OpenBSD: includes.h,v 1.21 2005/12/08 18:34:11 reyk Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -148,6 +148,9 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
#include <netinet/in.h> /* For IPv6 macros */ #include <netinet/in.h> /* For IPv6 macros */
#include <netinet/ip.h> /* For IPTOS macros */ #include <netinet/ip.h> /* For IPTOS macros */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#include <arpa/inet.h> #include <arpa/inet.h>
#if defined(HAVE_NETDB_H) #if defined(HAVE_NETDB_H)
# include <netdb.h> # include <netdb.h>

75
misc.c
View File

@ -24,7 +24,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: misc.c,v 1.36 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: misc.c,v 1.37 2005/12/08 18:34:11 reyk Exp $");
#include "misc.h" #include "misc.h"
#include "log.h" #include "log.h"
@ -202,7 +202,7 @@ a2tun(const char *s, int *remote)
int tun; int tun;
if (remote != NULL) { if (remote != NULL) {
*remote = -1; *remote = SSH_TUNID_ANY;
sp = xstrdup(s); sp = xstrdup(s);
if ((ep = strchr(sp, ':')) == NULL) { if ((ep = strchr(sp, ':')) == NULL) {
xfree(sp); xfree(sp);
@ -212,15 +212,15 @@ a2tun(const char *s, int *remote)
*remote = a2tun(ep, NULL); *remote = a2tun(ep, NULL);
tun = a2tun(sp, NULL); tun = a2tun(sp, NULL);
xfree(sp); xfree(sp);
return (tun); return (*remote == SSH_TUNID_ERR ? *remote : tun);
} }
if (strcasecmp(s, "any") == 0) if (strcasecmp(s, "any") == 0)
return (-1); return (SSH_TUNID_ANY);
tun = strtonum(s, 0, INT_MAX, &errstr); tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
if (errstr != NULL || tun < -1) if (errstr != NULL)
return (-2); return (SSH_TUNID_ERR);
return (tun); return (tun);
} }
@ -539,27 +539,60 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
} }
int int
tun_open(int tun) tun_open(int tun, int mode)
{ {
struct ifreq ifr;
char name[100]; char name[100];
int i, fd; int fd = -1, sock;
if (tun > -1) { /* Open the tunnel device */
if (tun <= SSH_TUNID_MAX) {
snprintf(name, sizeof(name), "/dev/tun%d", tun); snprintf(name, sizeof(name), "/dev/tun%d", tun);
if ((fd = open(name, O_RDWR)) >= 0) { fd = open(name, O_RDWR);
debug("%s: %s: %d", __func__, name, fd); } else if (tun == SSH_TUNID_ANY) {
return (fd); for (tun = 100; tun >= 0; tun--) {
snprintf(name, sizeof(name), "/dev/tun%d", tun);
if ((fd = open(name, O_RDWR)) >= 0)
break;
} }
} else { } else {
for (i = 100; i >= 0; i--) { debug("%s: invalid tunnel %u\n", __func__, tun);
snprintf(name, sizeof(name), "/dev/tun%d", i); return (-1);
if ((fd = open(name, O_RDWR)) >= 0) {
debug("%s: %s: %d", __func__, name, fd);
return (fd);
}
}
} }
debug("%s: %s failed: %s", __func__, name, strerror(errno));
if (fd < 0) {
debug("%s: %s open failed: %s", __func__, name, strerror(errno));
return (-1);
}
debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
/* Set the tunnel device operation mode */
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
goto failed;
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)
goto failed;
if (mode == SSH_TUNMODE_ETHERNET) {
ifr.ifr_flags |= IFF_LINK0;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
goto failed;
}
ifr.ifr_flags |= IFF_UP;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)
goto failed;
close(sock);
return (fd);
failed:
if (fd >= 0)
close(fd);
if (sock >= 0)
close(sock);
debug("%s: failed to set %s mode %d: %s", __func__, name,
mode, strerror(errno));
return (-1); return (-1);
} }

16
misc.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.27 2005/12/06 22:38:27 reyk Exp $ */ /* $OpenBSD: misc.h,v 1.28 2005/12/08 18:34:11 reyk Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -50,4 +50,16 @@ void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
char *read_passphrase(const char *, int); char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
int tun_open(int);
int tun_open(int, int);
/* Common definitions for ssh tunnel device forwarding */
#define SSH_TUNMODE_NO 0x00
#define SSH_TUNMODE_POINTOPOINT 0x01
#define SSH_TUNMODE_ETHERNET 0x02
#define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT
#define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET)
#define SSH_TUNID_ANY 0x7fffffff
#define SSH_TUNID_ERR (SSH_TUNID_ANY - 1)
#define SSH_TUNID_MAX (SSH_TUNID_ANY - 2)

View File

@ -12,7 +12,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.144 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $");
#include "ssh.h" #include "ssh.h"
#include "xmalloc.h" #include "xmalloc.h"
@ -273,7 +273,7 @@ clear_forwardings(Options *options)
xfree(options->remote_forwards[i].connect_host); xfree(options->remote_forwards[i].connect_host);
} }
options->num_remote_forwards = 0; options->num_remote_forwards = 0;
options->tun_open = 0; options->tun_open = SSH_TUNMODE_NO;
} }
/* /*
@ -835,14 +835,32 @@ parse_int:
case oTunnel: case oTunnel:
intptr = &options->tun_open; intptr = &options->tun_open;
goto parse_flag; arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing yes/point-to-point/"
"ethernet/no argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcasecmp(arg, "ethernet") == 0)
value = SSH_TUNMODE_ETHERNET;
else if (strcasecmp(arg, "point-to-point") == 0)
value = SSH_TUNMODE_POINTOPOINT;
else if (strcasecmp(arg, "yes") == 0)
value = SSH_TUNMODE_DEFAULT;
else if (strcasecmp(arg, "no") == 0)
value = SSH_TUNMODE_NO;
else
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg);
if (*activep)
*intptr = value;
break;
case oTunnelDevice: case oTunnelDevice:
arg = strdelim(&s); arg = strdelim(&s);
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum); fatal("%.200s line %d: Missing argument.", filename, linenum);
value = a2tun(arg, &value2); value = a2tun(arg, &value2);
if (value < -1) if (value == SSH_TUNID_ERR)
fatal("%.200s line %d: Bad tun device.", filename, linenum); fatal("%.200s line %d: Bad tun device.", filename, linenum);
if (*activep) { if (*activep) {
options->tun_local = value; options->tun_local = value;
@ -1132,7 +1150,11 @@ fill_default_options(Options * options)
if (options->hash_known_hosts == -1) if (options->hash_known_hosts == -1)
options->hash_known_hosts = 0; options->hash_known_hosts = 0;
if (options->tun_open == -1) if (options->tun_open == -1)
options->tun_open = 0; options->tun_open = SSH_TUNMODE_NO;
if (options->tun_local == -1)
options->tun_local = SSH_TUNID_ANY;
if (options->tun_remote == -1)
options->tun_remote = SSH_TUNID_ANY;
if (options->permit_local_command == -1) if (options->permit_local_command == -1)
options->permit_local_command = 0; options->permit_local_command = 0;
/* options->local_command should not be set by default */ /* options->local_command should not be set by default */

View File

@ -10,7 +10,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.145 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $");
#include "ssh.h" #include "ssh.h"
#include "log.h" #include "log.h"
@ -231,7 +231,7 @@ fill_default_server_options(ServerOptions *options)
if (options->authorized_keys_file == NULL) if (options->authorized_keys_file == NULL)
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
if (options->permit_tun == -1) if (options->permit_tun == -1)
options->permit_tun = 0; options->permit_tun = SSH_TUNMODE_NO;
/* Turn privilege separation on by default */ /* Turn privilege separation on by default */
if (use_privsep == -1) if (use_privsep == -1)
@ -968,7 +968,25 @@ parse_flag:
case sPermitTunnel: case sPermitTunnel:
intptr = &options->permit_tun; intptr = &options->permit_tun;
goto parse_flag; arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing yes/point-to-point/"
"ethernet/no argument.", filename, linenum);
value = 0; /* silence compiler */
if (strcasecmp(arg, "ethernet") == 0)
value = SSH_TUNMODE_ETHERNET;
else if (strcasecmp(arg, "point-to-point") == 0)
value = SSH_TUNMODE_POINTOPOINT;
else if (strcasecmp(arg, "yes") == 0)
value = SSH_TUNMODE_YES;
else if (strcasecmp(arg, "no") == 0)
value = SSH_TUNMODE_NO;
else
fatal("%s line %d: Bad yes/point-to-point/ethernet/"
"no argument: %s", filename, linenum, arg);
if (*intptr == -1)
*intptr = value;
break;
case sDeprecated: case sDeprecated:
logit("%s line %d: Deprecated option %s", logit("%s line %d: Deprecated option %s",

View File

@ -35,7 +35,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.122 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: serverloop.c,v 1.123 2005/12/08 18:34:11 reyk Exp $");
#include "xmalloc.h" #include "xmalloc.h"
#include "packet.h" #include "packet.h"
@ -917,20 +917,31 @@ static Channel *
server_request_tun(void) server_request_tun(void)
{ {
Channel *c = NULL; Channel *c = NULL;
int sock, tun; int mode, tun;
int sock;
if (!options.permit_tun) { mode = packet_get_int();
packet_send_debug("Server has disabled tunnel device forwarding."); switch (mode) {
case SSH_TUNMODE_POINTOPOINT:
case SSH_TUNMODE_ETHERNET:
break;
default:
packet_send_debug("Unsupported tunnel device mode.");
return NULL;
}
if ((options.permit_tun & mode) == 0) {
packet_send_debug("Server has rejected tunnel device "
"forwarding");
return NULL; return NULL;
} }
tun = packet_get_int(); tun = packet_get_int();
if (forced_tun_device != -1) { if (forced_tun_device != SSH_TUNID_ANY) {
if (tun != -1 && forced_tun_device != tun) if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
goto done; goto done;
tun = forced_tun_device; tun = forced_tun_device;
} }
sock = tun_open(tun); sock = tun_open(tun, mode);
if (sock < 0) if (sock < 0)
goto done; goto done;
c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,

13
ssh.c
View File

@ -40,7 +40,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.255 2005/12/06 22:38:27 reyk Exp $"); RCSID("$OpenBSD: ssh.c,v 1.256 2005/12/08 18:34:11 reyk Exp $");
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -341,9 +341,10 @@ again:
exit(0); exit(0);
break; break;
case 'w': case 'w':
options.tun_open = 1; if (options.tun_open == -1)
options.tun_open = SSH_TUNMODE_DEFAULT;
options.tun_local = a2tun(optarg, &options.tun_remote); options.tun_local = a2tun(optarg, &options.tun_remote);
if (options.tun_local < -1) { if (options.tun_local == SSH_TUNID_ERR) {
fprintf(stderr, "Bad tun device '%s'\n", optarg); fprintf(stderr, "Bad tun device '%s'\n", optarg);
exit(1); exit(1);
} }
@ -1067,12 +1068,13 @@ ssh_session2_setup(int id, void *arg)
packet_send(); packet_send();
} }
if (options.tun_open) { if (options.tun_open != SSH_TUNMODE_NO) {
Channel *c; Channel *c;
int fd; int fd;
debug("Requesting tun."); debug("Requesting tun.");
if ((fd = tun_open(options.tun_local)) >= 0) { if ((fd = tun_open(options.tun_local,
options.tun_open)) >= 0) {
c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "tun", 1); 0, "tun", 1);
@ -1082,6 +1084,7 @@ ssh_session2_setup(int id, void *arg)
packet_put_int(c->self); packet_put_int(c->self);
packet_put_int(c->local_window_max); packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket); packet_put_int(c->local_maxpacket);
packet_put_int(options.tun_open);
packet_put_int(options.tun_remote); packet_put_int(options.tun_remote);
packet_send(); packet_send();
} }

View File

@ -34,7 +34,7 @@
.\" (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.67 2005/12/08 15:06:29 jmc Exp $ .\" $OpenBSD: ssh_config.5,v 1.68 2005/12/08 18:34:11 reyk Exp $
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
@ -911,9 +911,13 @@ with older servers.
.It Cm Tunnel .It Cm Tunnel
Request starting Request starting
.Xr tun 4 .Xr tun 4
device forwarding between the client and the server. device forwarding between the client and the server. This option also
allows requesting layer 2 (ethernet) instead of layer 3
(point-to-point) tunneling from the server.
The argument must be The argument must be
.Dq yes .Dq yes ,
.Dq point-to-point ,
.Dq ethernet
or or
.Dq no . .Dq no .
The default is The default is

View File

@ -34,7 +34,7 @@
.\" (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: sshd_config.5,v 1.46 2005/12/06 22:38:28 reyk Exp $ .\" $OpenBSD: sshd_config.5,v 1.47 2005/12/08 18:34:11 reyk Exp $
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
@ -506,6 +506,12 @@ root is not allowed to log in.
Specifies whether Specifies whether
.Xr tun 4 .Xr tun 4
device forwarding is allowed. device forwarding is allowed.
The argument must be
.Dq yes ,
.Dq point-to-point ,
.Dq ethernet
or
.Dq no .
The default is The default is
.Dq no . .Dq no .
.It Cm PermitUserEnvironment .It Cm PermitUserEnvironment