summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-12-08 18:34:12 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-12-08 18:34:12 +0000
commit71e9c1668d8823e2153147c31d4d55045ff4112c (patch)
tree4add4b6e62b561c08001e9bd96fed4da3229880c /usr.bin
parentb0e765b15c8ba03873c4d8f9a97dc1bc518b24f2 (diff)
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@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/README.tun4
-rw-r--r--usr.bin/ssh/auth-options.c4
-rw-r--r--usr.bin/ssh/includes.h4
-rw-r--r--usr.bin/ssh/misc.c75
-rw-r--r--usr.bin/ssh/misc.h16
-rw-r--r--usr.bin/ssh/readconf.c32
-rw-r--r--usr.bin/ssh/servconf.c24
-rw-r--r--usr.bin/ssh/serverloop.c25
-rw-r--r--usr.bin/ssh/ssh.c13
-rw-r--r--usr.bin/ssh/ssh_config.510
-rw-r--r--usr.bin/ssh/sshd_config.58
11 files changed, 163 insertions, 52 deletions
diff --git a/usr.bin/ssh/README.tun b/usr.bin/ssh/README.tun
index f08a7461603..d814f396d5b 100644
--- a/usr.bin/ssh/README.tun
+++ b/usr.bin/ssh/README.tun
@@ -74,7 +74,7 @@ ssh tunnel destination over multiple ssh sessions.
User puffy
ProxyCommand ssh access.somewhere.net nc dmzgw 22
Host sshgateway
- Tunnel yes
+ Tunnel Ethernet
TunnelDevice 0:any
PermitLocalCommand yes
LocalCommand sh /etc/netstart tun0
@@ -129,4 +129,4 @@ interconnect corporate networks.
Reyk Floeter
-$OpenBSD: README.tun,v 1.2 2005/12/07 09:38:26 reyk Exp $
+$OpenBSD: README.tun,v 1.3 2005/12/08 18:34:10 reyk Exp $
diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c
index 54798d9ad5a..ad97e612939 100644
--- a/usr.bin/ssh/auth-options.c
+++ b/usr.bin/ssh/auth-options.c
@@ -10,7 +10,7 @@
*/
#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 "match.h"
@@ -296,7 +296,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
tun[i] = 0;
forced_tun_device = a2tun(tun, NULL);
xfree(tun);
- if (forced_tun_device < -1) {
+ if (forced_tun_device == SSH_TUNID_ERR) {
debug("%.100s, line %lu: invalid tun device",
file, linenum);
auth_debug_add("%.100s, line %lu: invalid tun device",
diff --git a/usr.bin/ssh/includes.h b/usr.bin/ssh/includes.h
index 93d9d851ea5..3c3dc76867f 100644
--- a/usr.bin/ssh/includes.h
+++ b/usr.bin/ssh/includes.h
@@ -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>
@@ -38,6 +38,8 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
#include <arpa/inet.h>
#include <netdb.h>
+#include <net/if.h>
+
#include <stddef.h>
#include <netgroup.h>
#include <stdio.h>
diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c
index dc715ac6778..d70e199c578 100644
--- a/usr.bin/ssh/misc.c
+++ b/usr.bin/ssh/misc.c
@@ -24,7 +24,7 @@
*/
#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 "log.h"
@@ -196,7 +196,7 @@ a2tun(const char *s, int *remote)
int tun;
if (remote != NULL) {
- *remote = -1;
+ *remote = SSH_TUNID_ANY;
sp = xstrdup(s);
if ((ep = strchr(sp, ':')) == NULL) {
xfree(sp);
@@ -206,15 +206,15 @@ a2tun(const char *s, int *remote)
*remote = a2tun(ep, NULL);
tun = a2tun(sp, NULL);
xfree(sp);
- return (tun);
+ return (*remote == SSH_TUNID_ERR ? *remote : tun);
}
if (strcasecmp(s, "any") == 0)
- return (-1);
+ return (SSH_TUNID_ANY);
- tun = strtonum(s, 0, INT_MAX, &errstr);
- if (errstr != NULL || tun < -1)
- return (-2);
+ tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
+ if (errstr != NULL)
+ return (SSH_TUNID_ERR);
return (tun);
}
@@ -533,27 +533,60 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
}
int
-tun_open(int tun)
+tun_open(int tun, int mode)
{
+ struct ifreq ifr;
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);
- if ((fd = open(name, O_RDWR)) >= 0) {
- debug("%s: %s: %d", __func__, name, fd);
- return (fd);
+ fd = open(name, O_RDWR);
+ } else if (tun == SSH_TUNID_ANY) {
+ for (tun = 100; tun >= 0; tun--) {
+ snprintf(name, sizeof(name), "/dev/tun%d", tun);
+ if ((fd = open(name, O_RDWR)) >= 0)
+ break;
}
} else {
- for (i = 100; i >= 0; i--) {
- snprintf(name, sizeof(name), "/dev/tun%d", i);
- if ((fd = open(name, O_RDWR)) >= 0) {
- debug("%s: %s: %d", __func__, name, fd);
- return (fd);
- }
- }
+ debug("%s: invalid tunnel %u\n", __func__, tun);
+ return (-1);
+ }
+
+ 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;
}
- debug("%s: %s failed: %s", __func__, name, strerror(errno));
+ 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);
}
diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h
index ff2ba1b5a7a..41591068695 100644
--- a/usr.bin/ssh/misc.h
+++ b/usr.bin/ssh/misc.h
@@ -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>
@@ -50,4 +50,16 @@ void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
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)
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 68da34eb1c0..6f11e640b9a 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -12,7 +12,7 @@
*/
#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 "xmalloc.h"
@@ -271,7 +271,7 @@ clear_forwardings(Options *options)
xfree(options->remote_forwards[i].connect_host);
}
options->num_remote_forwards = 0;
- options->tun_open = 0;
+ options->tun_open = SSH_TUNMODE_NO;
}
/*
@@ -833,14 +833,32 @@ parse_int:
case oTunnel:
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:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = a2tun(arg, &value2);
- if (value < -1)
+ if (value == SSH_TUNID_ERR)
fatal("%.200s line %d: Bad tun device.", filename, linenum);
if (*activep) {
options->tun_local = value;
@@ -1130,7 +1148,11 @@ fill_default_options(Options * options)
if (options->hash_known_hosts == -1)
options->hash_known_hosts = 0;
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)
options->permit_local_command = 0;
/* options->local_command should not be set by default */
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 307c4d0ef45..8ce43cca63f 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -10,7 +10,7 @@
*/
#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 "log.h"
@@ -221,7 +221,7 @@ fill_default_server_options(ServerOptions *options)
if (options->authorized_keys_file == NULL)
options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
if (options->permit_tun == -1)
- options->permit_tun = 0;
+ options->permit_tun = SSH_TUNMODE_NO;
/* Turn privilege separation on by default */
if (use_privsep == -1)
@@ -927,7 +927,25 @@ parse_flag:
case sPermitTunnel:
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:
logit("%s line %d: Deprecated option %s",
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index 651ba0a3fc9..d0130b088a8 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/serverloop.c
@@ -35,7 +35,7 @@
*/
#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 "packet.h"
@@ -915,20 +915,31 @@ static Channel *
server_request_tun(void)
{
Channel *c = NULL;
- int sock, tun;
+ int mode, tun;
+ int sock;
- if (!options.permit_tun) {
- packet_send_debug("Server has disabled tunnel device forwarding.");
+ mode = packet_get_int();
+ 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;
}
tun = packet_get_int();
- if (forced_tun_device != -1) {
- if (tun != -1 && forced_tun_device != tun)
+ if (forced_tun_device != SSH_TUNID_ANY) {
+ if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
goto done;
tun = forced_tun_device;
}
- sock = tun_open(tun);
+ sock = tun_open(tun, mode);
if (sock < 0)
goto done;
c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index 80e33f1ec34..6f208446551 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/ssh.c
@@ -40,7 +40,7 @@
*/
#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/err.h>
@@ -336,9 +336,10 @@ again:
exit(0);
break;
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);
- if (options.tun_local < -1) {
+ if (options.tun_local == SSH_TUNID_ERR) {
fprintf(stderr, "Bad tun device '%s'\n", optarg);
exit(1);
}
@@ -1055,12 +1056,13 @@ ssh_session2_setup(int id, void *arg)
packet_send();
}
- if (options.tun_open) {
+ if (options.tun_open != SSH_TUNMODE_NO) {
Channel *c;
int fd;
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,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "tun", 1);
@@ -1070,6 +1072,7 @@ ssh_session2_setup(int id, void *arg)
packet_put_int(c->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
+ packet_put_int(options.tun_open);
packet_put_int(options.tun_remote);
packet_send();
}
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 281b4046b15..68061182c9f 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -34,7 +34,7 @@
.\" (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_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
.Dt SSH_CONFIG 5
.Os
@@ -911,9 +911,13 @@ with older servers.
.It Cm Tunnel
Request starting
.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
-.Dq yes
+.Dq yes ,
+.Dq point-to-point ,
+.Dq ethernet
or
.Dq no .
The default is
diff --git a/usr.bin/ssh/sshd_config.5 b/usr.bin/ssh/sshd_config.5
index a16018334a2..41579deadf5 100644
--- a/usr.bin/ssh/sshd_config.5
+++ b/usr.bin/ssh/sshd_config.5
@@ -34,7 +34,7 @@
.\" (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: 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
.Dt SSHD_CONFIG 5
.Os
@@ -506,6 +506,12 @@ root is not allowed to log in.
Specifies whether
.Xr tun 4
device forwarding is allowed.
+The argument must be
+.Dq yes ,
+.Dq point-to-point ,
+.Dq ethernet
+or
+.Dq no .
The default is
.Dq no .
.It Cm PermitUserEnvironment