- reyk@cvs.openbsd.org 2005/12/06 22:38:28
     [auth-options.c auth-options.h channels.c channels.h clientloop.c]
     [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h]
     [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c]
     [sshconnect.h sshd.8 sshd_config sshd_config.5]
     Add support for tun(4) forwarding over OpenSSH, based on an idea and
     initial channel code bits by markus@. This is a simple and easy way to
     use OpenSSH for ad hoc virtual private network connections, e.g.
     administrative tunnels or secure wireless access. It's based on a new
     ssh channel and works similar to the existing TCP forwarding support,
     except that it depends on the tun(4) network interface on both ends of
     the connection for layer 2 or layer 3 tunneling. This diff also adds
     support for LocalCommand in the ssh(1) client.

     ok djm@, markus@, jmc@ (manpages), tested and discussed with others
diff --git a/auth-options.c b/auth-options.c
index a85e408..54798d9 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-options.c,v 1.31 2005/03/10 22:40:38 deraadt Exp $");
+RCSID("$OpenBSD: auth-options.c,v 1.32 2005/12/06 22:38:27 reyk Exp $");
 
 #include "xmalloc.h"
 #include "match.h"
@@ -35,6 +35,9 @@
 /* "environment=" options. */
 struct envstring *custom_environment = NULL;
 
+/* "tunnel=" option. */
+int forced_tun_device = -1;
+
 extern ServerOptions options;
 
 void
@@ -54,6 +57,7 @@
 		xfree(forced_command);
 		forced_command = NULL;
 	}
+	forced_tun_device = -1;
 	channel_clear_permitted_opens();
 	auth_debug_reset();
 }
@@ -269,6 +273,41 @@
 			xfree(patterns);
 			goto next_option;
 		}
+		cp = "tunnel=\"";
+		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			char *tun = NULL;
+			opts += strlen(cp);
+			tun = xmalloc(strlen(opts) + 1);
+			i = 0;
+			while (*opts) {
+				if (*opts == '"')
+					break;
+				tun[i++] = *opts++;
+			}
+			if (!*opts) {
+				debug("%.100s, line %lu: missing end quote",
+				    file, linenum);
+				auth_debug_add("%.100s, line %lu: missing end quote",
+				    file, linenum);
+				xfree(tun);
+				forced_tun_device = -1;
+				goto bad_option;
+			}
+			tun[i] = 0;
+			forced_tun_device = a2tun(tun, NULL);
+			xfree(tun);
+			if (forced_tun_device < -1) {
+				debug("%.100s, line %lu: invalid tun device",
+				    file, linenum);
+				auth_debug_add("%.100s, line %lu: invalid tun device",
+				    file, linenum);
+				forced_tun_device = -1;
+				goto bad_option;
+			}
+			auth_debug_add("Forced tun device: %d", forced_tun_device);
+			opts++;
+			goto next_option;
+		}
 next_option:
 		/*
 		 * Skip the comma, and move to the next option