summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-12-13 19:29:02 +1100
committerDamien Miller <djm@mindrot.org>2005-12-13 19:29:02 +1100
commitd27b947178df3689bfb7fdfb62a5f1337ef73481 (patch)
treec8678325c355b3602bdabca16da1baa8707818eb
parent6dbdb6afeec1820b2799c2693fc8e8b364be8228 (diff)
- 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
-rw-r--r--ChangeLog17
-rw-r--r--auth-options.c41
-rw-r--r--auth-options.h3
-rw-r--r--channels.c42
-rw-r--r--channels.h4
-rw-r--r--clientloop.c11
-rw-r--r--misc.c58
-rw-r--r--misc.h4
-rw-r--r--readconf.c52
-rw-r--r--readconf.h10
-rw-r--r--scp.c3
-rw-r--r--servconf.c12
-rw-r--r--servconf.h5
-rw-r--r--serverloop.c34
-rw-r--r--sftp.c3
-rw-r--r--ssh.120
-rw-r--r--ssh.c39
-rw-r--r--ssh_config5
-rw-r--r--ssh_config.538
-rw-r--r--sshconnect.c38
-rw-r--r--sshconnect.h4
-rw-r--r--sshd.810
-rw-r--r--sshd_config3
-rw-r--r--sshd_config.58
24 files changed, 433 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index d187f2aa0..96ed9a05d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,21 @@
7 [ssh.1] 7 [ssh.1]
8 avoid ambiguities in describing TZ; 8 avoid ambiguities in describing TZ;
9 ok djm@ 9 ok djm@
10 - reyk@cvs.openbsd.org 2005/12/06 22:38:28
11 [auth-options.c auth-options.h channels.c channels.h clientloop.c]
12 [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h]
13 [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c]
14 [sshconnect.h sshd.8 sshd_config sshd_config.5]
15 Add support for tun(4) forwarding over OpenSSH, based on an idea and
16 initial channel code bits by markus@. This is a simple and easy way to
17 use OpenSSH for ad hoc virtual private network connections, e.g.
18 administrative tunnels or secure wireless access. It's based on a new
19 ssh channel and works similar to the existing TCP forwarding support,
20 except that it depends on the tun(4) network interface on both ends of
21 the connection for layer 2 or layer 3 tunneling. This diff also adds
22 support for LocalCommand in the ssh(1) client.
23
24 ok djm@, markus@, jmc@ (manpages), tested and discussed with others
10 25
1120051201 2620051201
12 - (djm) [envpass.sh] Remove regress script that was accidentally committed 27 - (djm) [envpass.sh] Remove regress script that was accidentally committed
@@ -3399,4 +3414,4 @@
3399 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 3414 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
3400 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 3415 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
3401 3416
3402$Id: ChangeLog,v 1.4018 2005/12/13 08:25:43 djm Exp $ 3417$Id: ChangeLog,v 1.4019 2005/12/13 08:29:02 djm Exp $
diff --git a/auth-options.c b/auth-options.c
index a85e40835..54798d9ad 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth-options.c,v 1.31 2005/03/10 22:40:38 deraadt Exp $"); 13RCSID("$OpenBSD: auth-options.c,v 1.32 2005/12/06 22:38:27 reyk Exp $");
14 14
15#include "xmalloc.h" 15#include "xmalloc.h"
16#include "match.h" 16#include "match.h"
@@ -35,6 +35,9 @@ char *forced_command = NULL;
35/* "environment=" options. */ 35/* "environment=" options. */
36struct envstring *custom_environment = NULL; 36struct envstring *custom_environment = NULL;
37 37
38/* "tunnel=" option. */
39int forced_tun_device = -1;
40
38extern ServerOptions options; 41extern ServerOptions options;
39 42
40void 43void
@@ -54,6 +57,7 @@ auth_clear_options(void)
54 xfree(forced_command); 57 xfree(forced_command);
55 forced_command = NULL; 58 forced_command = NULL;
56 } 59 }
60 forced_tun_device = -1;
57 channel_clear_permitted_opens(); 61 channel_clear_permitted_opens();
58 auth_debug_reset(); 62 auth_debug_reset();
59} 63}
@@ -269,6 +273,41 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
269 xfree(patterns); 273 xfree(patterns);
270 goto next_option; 274 goto next_option;
271 } 275 }
276 cp = "tunnel=\"";
277 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
278 char *tun = NULL;
279 opts += strlen(cp);
280 tun = xmalloc(strlen(opts) + 1);
281 i = 0;
282 while (*opts) {
283 if (*opts == '"')
284 break;
285 tun[i++] = *opts++;
286 }
287 if (!*opts) {
288 debug("%.100s, line %lu: missing end quote",
289 file, linenum);
290 auth_debug_add("%.100s, line %lu: missing end quote",
291 file, linenum);
292 xfree(tun);
293 forced_tun_device = -1;
294 goto bad_option;
295 }
296 tun[i] = 0;
297 forced_tun_device = a2tun(tun, NULL);
298 xfree(tun);
299 if (forced_tun_device < -1) {
300 debug("%.100s, line %lu: invalid tun device",
301 file, linenum);
302 auth_debug_add("%.100s, line %lu: invalid tun device",
303 file, linenum);
304 forced_tun_device = -1;
305 goto bad_option;
306 }
307 auth_debug_add("Forced tun device: %d", forced_tun_device);
308 opts++;
309 goto next_option;
310 }
272next_option: 311next_option:
273 /* 312 /*
274 * Skip the comma, and move to the next option 313 * Skip the comma, and move to the next option
diff --git a/auth-options.h b/auth-options.h
index 15fb21255..3cd02a71f 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.h,v 1.12 2002/07/21 18:34:43 stevesk Exp $ */ 1/* $OpenBSD: auth-options.h,v 1.13 2005/12/06 22:38:27 reyk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,6 +28,7 @@ extern int no_x11_forwarding_flag;
28extern int no_pty_flag; 28extern int no_pty_flag;
29extern char *forced_command; 29extern char *forced_command;
30extern struct envstring *custom_environment; 30extern struct envstring *custom_environment;
31extern int forced_tun_device;
31 32
32int auth_parse_options(struct passwd *, char *, char *, u_long); 33int auth_parse_options(struct passwd *, char *, char *, u_long);
33void auth_clear_options(void); 34void auth_clear_options(void);
diff --git a/channels.c b/channels.c
index 9607717cc..b4fd89f96 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.228 2005/12/06 22:38:27 reyk Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -1414,6 +1414,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
1414 debug2("channel %d: filter stops", c->self); 1414 debug2("channel %d: filter stops", c->self);
1415 chan_read_failed(c); 1415 chan_read_failed(c);
1416 } 1416 }
1417 } else if (c->datagram) {
1418 buffer_put_string(&c->input, buf, len);
1417 } else { 1419 } else {
1418 buffer_append(&c->input, buf, len); 1420 buffer_append(&c->input, buf, len);
1419 } 1421 }
@@ -1432,6 +1434,23 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1432 if (c->wfd != -1 && 1434 if (c->wfd != -1 &&
1433 FD_ISSET(c->wfd, writeset) && 1435 FD_ISSET(c->wfd, writeset) &&
1434 buffer_len(&c->output) > 0) { 1436 buffer_len(&c->output) > 0) {
1437 if (c->datagram) {
1438 data = buffer_get_string(&c->output, &dlen);
1439 /* ignore truncated writes, datagrams might get lost */
1440 c->local_consumed += dlen + 4;
1441 len = write(c->wfd, data, dlen);
1442 xfree(data);
1443 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1444 return 1;
1445 if (len <= 0) {
1446 if (c->type != SSH_CHANNEL_OPEN)
1447 chan_mark_dead(c);
1448 else
1449 chan_write_failed(c);
1450 return -1;
1451 }
1452 return 1;
1453 }
1435 data = buffer_ptr(&c->output); 1454 data = buffer_ptr(&c->output);
1436 dlen = buffer_len(&c->output); 1455 dlen = buffer_len(&c->output);
1437#ifdef _AIX 1456#ifdef _AIX
@@ -1792,6 +1811,22 @@ channel_output_poll(void)
1792 if ((c->istate == CHAN_INPUT_OPEN || 1811 if ((c->istate == CHAN_INPUT_OPEN ||
1793 c->istate == CHAN_INPUT_WAIT_DRAIN) && 1812 c->istate == CHAN_INPUT_WAIT_DRAIN) &&
1794 (len = buffer_len(&c->input)) > 0) { 1813 (len = buffer_len(&c->input)) > 0) {
1814 if (c->datagram) {
1815 if (len > 0) {
1816 u_char *data;
1817 u_int dlen;
1818
1819 data = buffer_get_string(&c->input,
1820 &dlen);
1821 packet_start(SSH2_MSG_CHANNEL_DATA);
1822 packet_put_int(c->remote_id);
1823 packet_put_string(data, dlen);
1824 packet_send();
1825 c->remote_window -= dlen + 4;
1826 xfree(data);
1827 }
1828 continue;
1829 }
1795 /* 1830 /*
1796 * Send some data for the other side over the secure 1831 * Send some data for the other side over the secure
1797 * connection. 1832 * connection.
@@ -1914,7 +1949,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
1914 c->local_window -= data_len; 1949 c->local_window -= data_len;
1915 } 1950 }
1916 packet_check_eom(); 1951 packet_check_eom();
1917 buffer_append(&c->output, data, data_len); 1952 if (c->datagram)
1953 buffer_put_string(&c->output, data, data_len);
1954 else
1955 buffer_append(&c->output, data, data_len);
1918 xfree(data); 1956 xfree(data);
1919} 1957}
1920 1958
diff --git a/channels.h b/channels.h
index 7e1cc7c5a..743a2065e 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.80 2005/10/10 10:23:08 djm Exp $ */ 1/* $OpenBSD: channels.h,v 1.81 2005/12/06 22:38:27 reyk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -112,6 +112,8 @@ struct Channel {
112 112
113 /* filter */ 113 /* filter */
114 channel_filter_fn *input_filter; 114 channel_filter_fn *input_filter;
115
116 int datagram; /* keep boundaries */
115}; 117};
116 118
117#define CHAN_EXTENDED_IGNORE 0 119#define CHAN_EXTENDED_IGNORE 0
diff --git a/clientloop.c b/clientloop.c
index 001c8f119..a97734c3f 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.145 2005/10/30 08:52:17 djm Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.146 2005/12/06 22:38:27 reyk Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -914,6 +914,15 @@ process_cmdline(void)
914 logit(" -Lport:host:hostport Request local forward"); 914 logit(" -Lport:host:hostport Request local forward");
915 logit(" -Rport:host:hostport Request remote forward"); 915 logit(" -Rport:host:hostport Request remote forward");
916 logit(" -KRhostport Cancel remote forward"); 916 logit(" -KRhostport Cancel remote forward");
917 if (!options.permit_local_command)
918 goto out;
919 logit(" !args Execute local command");
920 goto out;
921 }
922
923 if (*s == '!' && options.permit_local_command) {
924 s++;
925 ssh_local_cmd(s);
917 goto out; 926 goto out;
918 } 927 }
919 928
diff --git a/misc.c b/misc.c
index 27b947f0c..9b23e2c37 100644
--- a/misc.c
+++ b/misc.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "includes.h" 26#include "includes.h"
27RCSID("$OpenBSD: misc.c,v 1.35 2005/09/13 23:40:07 djm Exp $"); 27RCSID("$OpenBSD: misc.c,v 1.36 2005/12/06 22:38:27 reyk Exp $");
28 28
29#include "misc.h" 29#include "misc.h"
30#include "log.h" 30#include "log.h"
@@ -194,6 +194,37 @@ a2port(const char *s)
194 return port; 194 return port;
195} 195}
196 196
197int
198a2tun(const char *s, int *remote)
199{
200 const char *errstr = NULL;
201 char *sp, *ep;
202 int tun;
203
204 if (remote != NULL) {
205 *remote = -1;
206 sp = xstrdup(s);
207 if ((ep = strchr(sp, ':')) == NULL) {
208 xfree(sp);
209 return (a2tun(s, NULL));
210 }
211 ep[0] = '\0'; ep++;
212 *remote = a2tun(ep, NULL);
213 tun = a2tun(sp, NULL);
214 xfree(sp);
215 return (tun);
216 }
217
218 if (strcasecmp(s, "any") == 0)
219 return (-1);
220
221 tun = strtonum(s, 0, INT_MAX, &errstr);
222 if (errstr != NULL || tun < -1)
223 return (-2);
224
225 return (tun);
226}
227
197#define SECONDS 1 228#define SECONDS 1
198#define MINUTES (SECONDS * 60) 229#define MINUTES (SECONDS * 60)
199#define HOURS (MINUTES * 60) 230#define HOURS (MINUTES * 60)
@@ -507,6 +538,31 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
507 return -1; 538 return -1;
508} 539}
509 540
541int
542tun_open(int tun)
543{
544 char name[100];
545 int i, fd;
546
547 if (tun > -1) {
548 snprintf(name, sizeof(name), "/dev/tun%d", tun);
549 if ((fd = open(name, O_RDWR)) >= 0) {
550 debug("%s: %s: %d", __func__, name, fd);
551 return (fd);
552 }
553 } else {
554 for (i = 100; i >= 0; i--) {
555 snprintf(name, sizeof(name), "/dev/tun%d", i);
556 if ((fd = open(name, O_RDWR)) >= 0) {
557 debug("%s: %s: %d", __func__, name, fd);
558 return (fd);
559 }
560 }
561 }
562 debug("%s: %s failed: %s", __func__, name, strerror(errno));
563 return (-1);
564}
565
510void 566void
511sanitise_stdfd(void) 567sanitise_stdfd(void)
512{ 568{
diff --git a/misc.h b/misc.h
index 51541336c..ff2ba1b5a 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.h,v 1.26 2005/09/13 23:40:07 djm Exp $ */ 1/* $OpenBSD: misc.h,v 1.27 2005/12/06 22:38:27 reyk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,6 +20,7 @@ int set_nonblock(int);
20int unset_nonblock(int); 20int unset_nonblock(int);
21void set_nodelay(int); 21void set_nodelay(int);
22int a2port(const char *); 22int a2port(const char *);
23int a2tun(const char *, int *);
23char *hpdelim(char **); 24char *hpdelim(char **);
24char *cleanhostname(char *); 25char *cleanhostname(char *);
25char *colon(char *); 26char *colon(char *);
@@ -49,3 +50,4 @@ void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
49char *read_passphrase(const char *, int); 50char *read_passphrase(const char *, int);
50int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); 51int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
51int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); 52int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
53int tun_open(int);
diff --git a/readconf.c b/readconf.c
index cf27a9f41..b6aad9d8d 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.144 2005/12/06 22:38:27 reyk Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -70,6 +70,10 @@ RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $");
70 Cipher none 70 Cipher none
71 PasswordAuthentication no 71 PasswordAuthentication no
72 72
73 Host vpn.fake.com
74 Tunnel yes
75 TunnelDevice 3
76
73 # Defaults for various options 77 # Defaults for various options
74 Host * 78 Host *
75 ForwardAgent no 79 ForwardAgent no
@@ -107,6 +111,7 @@ typedef enum {
107 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 111 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
108 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 112 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
109 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 113 oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
114 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
110 oDeprecated, oUnsupported 115 oDeprecated, oUnsupported
111} OpCodes; 116} OpCodes;
112 117
@@ -198,6 +203,10 @@ static struct {
198 { "controlpath", oControlPath }, 203 { "controlpath", oControlPath },
199 { "controlmaster", oControlMaster }, 204 { "controlmaster", oControlMaster },
200 { "hashknownhosts", oHashKnownHosts }, 205 { "hashknownhosts", oHashKnownHosts },
206 { "tunnel", oTunnel },
207 { "tunneldevice", oTunnelDevice },
208 { "localcommand", oLocalCommand },
209 { "permitlocalcommand", oPermitLocalCommand },
201 { NULL, oBadOption } 210 { NULL, oBadOption }
202}; 211};
203 212
@@ -264,6 +273,7 @@ clear_forwardings(Options *options)
264 xfree(options->remote_forwards[i].connect_host); 273 xfree(options->remote_forwards[i].connect_host);
265 } 274 }
266 options->num_remote_forwards = 0; 275 options->num_remote_forwards = 0;
276 options->tun_open = 0;
267} 277}
268 278
269/* 279/*
@@ -296,7 +306,7 @@ process_config_line(Options *options, const char *host,
296 int *activep) 306 int *activep)
297{ 307{
298 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 308 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
299 int opcode, *intptr, value; 309 int opcode, *intptr, value, value2;
300 size_t len; 310 size_t len;
301 Forward fwd; 311 Forward fwd;
302 312
@@ -553,9 +563,10 @@ parse_string:
553 goto parse_string; 563 goto parse_string;
554 564
555 case oProxyCommand: 565 case oProxyCommand:
566 charptr = &options->proxy_command;
567parse_command:
556 if (s == NULL) 568 if (s == NULL)
557 fatal("%.200s line %d: Missing argument.", filename, linenum); 569 fatal("%.200s line %d: Missing argument.", filename, linenum);
558 charptr = &options->proxy_command;
559 len = strspn(s, WHITESPACE "="); 570 len = strspn(s, WHITESPACE "=");
560 if (*activep && *charptr == NULL) 571 if (*activep && *charptr == NULL)
561 *charptr = xstrdup(s + len); 572 *charptr = xstrdup(s + len);
@@ -822,6 +833,31 @@ parse_int:
822 intptr = &options->hash_known_hosts; 833 intptr = &options->hash_known_hosts;
823 goto parse_flag; 834 goto parse_flag;
824 835
836 case oTunnel:
837 intptr = &options->tun_open;
838 goto parse_flag;
839
840 case oTunnelDevice:
841 arg = strdelim(&s);
842 if (!arg || *arg == '\0')
843 fatal("%.200s line %d: Missing argument.", filename, linenum);
844 value = a2tun(arg, &value2);
845 if (value < -1)
846 fatal("%.200s line %d: Bad tun device.", filename, linenum);
847 if (*activep) {
848 options->tun_local = value;
849 options->tun_remote = value2;
850 }
851 break;
852
853 case oLocalCommand:
854 charptr = &options->local_command;
855 goto parse_command;
856
857 case oPermitLocalCommand:
858 intptr = &options->permit_local_command;
859 goto parse_flag;
860
825 case oDeprecated: 861 case oDeprecated:
826 debug("%s line %d: Deprecated option \"%s\"", 862 debug("%s line %d: Deprecated option \"%s\"",
827 filename, linenum, keyword); 863 filename, linenum, keyword);
@@ -966,6 +1002,11 @@ initialize_options(Options * options)
966 options->control_path = NULL; 1002 options->control_path = NULL;
967 options->control_master = -1; 1003 options->control_master = -1;
968 options->hash_known_hosts = -1; 1004 options->hash_known_hosts = -1;
1005 options->tun_open = -1;
1006 options->tun_local = -1;
1007 options->tun_remote = -1;
1008 options->local_command = NULL;
1009 options->permit_local_command = -1;
969} 1010}
970 1011
971/* 1012/*
@@ -1090,6 +1131,11 @@ fill_default_options(Options * options)
1090 options->control_master = 0; 1131 options->control_master = 0;
1091 if (options->hash_known_hosts == -1) 1132 if (options->hash_known_hosts == -1)
1092 options->hash_known_hosts = 0; 1133 options->hash_known_hosts = 0;
1134 if (options->tun_open == -1)
1135 options->tun_open = 0;
1136 if (options->permit_local_command == -1)
1137 options->permit_local_command = 0;
1138 /* options->local_command should not be set by default */
1093 /* options->proxy_command should not be set by default */ 1139 /* options->proxy_command should not be set by default */
1094 /* options->user will be set in the main program if appropriate */ 1140 /* options->user will be set in the main program if appropriate */
1095 /* options->hostname will be set in the main program if appropriate */ 1141 /* options->hostname will be set in the main program if appropriate */
diff --git a/readconf.h b/readconf.h
index 2b9deb9db..4565b2c2c 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.67 2005/06/08 11:25:09 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -114,6 +114,14 @@ typedef struct {
114 int control_master; 114 int control_master;
115 115
116 int hash_known_hosts; 116 int hash_known_hosts;
117
118 int tun_open; /* tun(4) */
119 int tun_local; /* force tun device (optional) */
120 int tun_remote; /* force tun device (optional) */
121
122 char *local_command;
123 int permit_local_command;
124
117} Options; 125} Options;
118 126
119#define SSHCTL_MASTER_NO 0 127#define SSHCTL_MASTER_NO 0
diff --git a/scp.c b/scp.c
index a19021f85..5dced6ce4 100644
--- a/scp.c
+++ b/scp.c
@@ -71,7 +71,7 @@
71 */ 71 */
72 72
73#include "includes.h" 73#include "includes.h"
74RCSID("$OpenBSD: scp.c,v 1.127 2005/11/12 18:38:15 deraadt Exp $"); 74RCSID("$OpenBSD: scp.c,v 1.128 2005/12/06 22:38:27 reyk Exp $");
75 75
76#include "xmalloc.h" 76#include "xmalloc.h"
77#include "atomicio.h" 77#include "atomicio.h"
@@ -231,6 +231,7 @@ main(int argc, char **argv)
231 addargs(&args, "ssh"); /* overwritten with ssh_program */ 231 addargs(&args, "ssh"); /* overwritten with ssh_program */
232 addargs(&args, "-x"); 232 addargs(&args, "-x");
233 addargs(&args, "-oForwardAgent no"); 233 addargs(&args, "-oForwardAgent no");
234 addargs(&args, "-oPermitLocalCommand no");
234 addargs(&args, "-oClearAllForwardings yes"); 235 addargs(&args, "-oClearAllForwardings yes");
235 236
236 fflag = tflag = 0; 237 fflag = tflag = 0;
diff --git a/servconf.c b/servconf.c
index 9e420a527..91a0ced29 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: servconf.c,v 1.144 2005/08/06 10:03:12 dtucker Exp $"); 13RCSID("$OpenBSD: servconf.c,v 1.145 2005/12/06 22:38:27 reyk Exp $");
14 14
15#include "ssh.h" 15#include "ssh.h"
16#include "log.h" 16#include "log.h"
@@ -101,6 +101,7 @@ initialize_server_options(ServerOptions *options)
101 options->authorized_keys_file = NULL; 101 options->authorized_keys_file = NULL;
102 options->authorized_keys_file2 = NULL; 102 options->authorized_keys_file2 = NULL;
103 options->num_accept_env = 0; 103 options->num_accept_env = 0;
104 options->permit_tun = -1;
104 105
105 /* Needs to be accessable in many places */ 106 /* Needs to be accessable in many places */
106 use_privsep = -1; 107 use_privsep = -1;
@@ -229,6 +230,8 @@ fill_default_server_options(ServerOptions *options)
229 } 230 }
230 if (options->authorized_keys_file == NULL) 231 if (options->authorized_keys_file == NULL)
231 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; 232 options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
233 if (options->permit_tun == -1)
234 options->permit_tun = 0;
232 235
233 /* Turn privilege separation on by default */ 236 /* Turn privilege separation on by default */
234 if (use_privsep == -1) 237 if (use_privsep == -1)
@@ -270,7 +273,7 @@ typedef enum {
270 sBanner, sUseDNS, sHostbasedAuthentication, 273 sBanner, sUseDNS, sHostbasedAuthentication,
271 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 274 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
272 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 275 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
273 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, 276 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
274 sUsePrivilegeSeparation, 277 sUsePrivilegeSeparation,
275 sDeprecated, sUnsupported 278 sDeprecated, sUnsupported
276} ServerOpCodes; 279} ServerOpCodes;
@@ -373,6 +376,7 @@ static struct {
373 { "authorizedkeysfile2", sAuthorizedKeysFile2 }, 376 { "authorizedkeysfile2", sAuthorizedKeysFile2 },
374 { "useprivilegeseparation", sUsePrivilegeSeparation}, 377 { "useprivilegeseparation", sUsePrivilegeSeparation},
375 { "acceptenv", sAcceptEnv }, 378 { "acceptenv", sAcceptEnv },
379 { "permittunnel", sPermitTunnel },
376 { NULL, sBadOption } 380 { NULL, sBadOption }
377}; 381};
378 382
@@ -962,6 +966,10 @@ parse_flag:
962 } 966 }
963 break; 967 break;
964 968
969 case sPermitTunnel:
970 intptr = &options->permit_tun;
971 goto parse_flag;
972
965 case sDeprecated: 973 case sDeprecated:
966 logit("%s line %d: Deprecated option %s", 974 logit("%s line %d: Deprecated option %s",
967 filename, linenum, arg); 975 filename, linenum, arg);
diff --git a/servconf.h b/servconf.h
index f7e56d521..ab82c8f57 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.71 2004/12/23 23:11:00 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -133,7 +133,10 @@ typedef struct {
133 133
134 char *authorized_keys_file; /* File containing public keys */ 134 char *authorized_keys_file; /* File containing public keys */
135 char *authorized_keys_file2; 135 char *authorized_keys_file2;
136
136 int use_pam; /* Enable auth via PAM */ 137 int use_pam; /* Enable auth via PAM */
138
139 int permit_tun;
137} ServerOptions; 140} ServerOptions;
138 141
139void initialize_server_options(ServerOptions *); 142void initialize_server_options(ServerOptions *);
diff --git a/serverloop.c b/serverloop.c
index 03376bacf..199f7696d 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.121 2005/10/31 11:48:29 djm Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.122 2005/12/06 22:38:27 reyk Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -914,6 +914,36 @@ server_request_direct_tcpip(void)
914} 914}
915 915
916static Channel * 916static Channel *
917server_request_tun(void)
918{
919 Channel *c = NULL;
920 int sock, tun;
921
922 if (!options.permit_tun) {
923 packet_send_debug("Server has disabled tunnel device forwarding.");
924 return NULL;
925 }
926
927 tun = packet_get_int();
928 if (forced_tun_device != -1) {
929 if (tun != -1 && forced_tun_device != tun)
930 goto done;
931 tun = forced_tun_device;
932 }
933 sock = tun_open(tun);
934 if (sock < 0)
935 goto done;
936 c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
937 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
938 c->datagram = 1;
939
940 done:
941 if (c == NULL)
942 packet_send_debug("Failed to open the tunnel device.");
943 return c;
944}
945
946static Channel *
917server_request_session(void) 947server_request_session(void)
918{ 948{
919 Channel *c; 949 Channel *c;
@@ -958,6 +988,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
958 c = server_request_session(); 988 c = server_request_session();
959 } else if (strcmp(ctype, "direct-tcpip") == 0) { 989 } else if (strcmp(ctype, "direct-tcpip") == 0) {
960 c = server_request_direct_tcpip(); 990 c = server_request_direct_tcpip();
991 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
992 c = server_request_tun();
961 } 993 }
962 if (c != NULL) { 994 if (c != NULL) {
963 debug("server_input_channel_open: confirm %s", ctype); 995 debug("server_input_channel_open: confirm %s", ctype);
diff --git a/sftp.c b/sftp.c
index ff3223ad2..24f6dc538 100644
--- a/sftp.c
+++ b/sftp.c
@@ -16,7 +16,7 @@
16 16
17#include "includes.h" 17#include "includes.h"
18 18
19RCSID("$OpenBSD: sftp.c,v 1.68 2005/10/31 06:15:04 dtucker Exp $"); 19RCSID("$OpenBSD: sftp.c,v 1.69 2005/12/06 22:38:27 reyk Exp $");
20 20
21#ifdef USE_LIBEDIT 21#ifdef USE_LIBEDIT
22#include <histedit.h> 22#include <histedit.h>
@@ -1457,6 +1457,7 @@ main(int argc, char **argv)
1457 addargs(&args, "ssh"); /* overwritten with ssh_program */ 1457 addargs(&args, "ssh"); /* overwritten with ssh_program */
1458 addargs(&args, "-oForwardX11 no"); 1458 addargs(&args, "-oForwardX11 no");
1459 addargs(&args, "-oForwardAgent no"); 1459 addargs(&args, "-oForwardAgent no");
1460 addargs(&args, "-oPermitLocalCommand no");
1460 addargs(&args, "-oClearAllForwardings yes"); 1461 addargs(&args, "-oClearAllForwardings yes");
1461 1462
1462 ll = SYSLOG_LEVEL_INFO; 1463 ll = SYSLOG_LEVEL_INFO;
diff --git a/ssh.1 b/ssh.1
index dd97a8995..8a55c2f64 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.214 2005/11/30 11:45:20 jmc Exp $ 37.\" $OpenBSD: ssh.1,v 1.215 2005/12/06 22:38:27 reyk Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -77,6 +77,7 @@
77.Sm on 77.Sm on
78.Oc 78.Oc
79.Op Fl S Ar ctl_path 79.Op Fl S Ar ctl_path
80.Op Fl w Ar tunnel : tunnel
80.Oo Ar user Ns @ Oc Ns Ar hostname 81.Oo Ar user Ns @ Oc Ns Ar hostname
81.Op Ar command 82.Op Ar command
82.Sh DESCRIPTION 83.Sh DESCRIPTION
@@ -301,6 +302,12 @@ options (see below).
301It also allows the cancellation of existing remote port-forwardings 302It also allows the cancellation of existing remote port-forwardings
302using 303using
303.Fl KR Ar hostport . 304.Fl KR Ar hostport .
305The
306.Ic ! Ar command
307allows the user to execute a local command if the
308.Ic PermitLocalCommand
309option is enabled in
310.Xr ssh_config 5 .
304Basic help is available, using the 311Basic help is available, using the
305.Fl h 312.Fl h
306option. 313option.
@@ -747,12 +754,14 @@ For full details of the options listed below, and their possible values, see
747.It IdentityFile 754.It IdentityFile
748.It IdentitiesOnly 755.It IdentitiesOnly
749.It KbdInteractiveDevices 756.It KbdInteractiveDevices
757.It LocalCommand
750.It LocalForward 758.It LocalForward
751.It LogLevel 759.It LogLevel
752.It MACs 760.It MACs
753.It NoHostAuthenticationForLocalhost 761.It NoHostAuthenticationForLocalhost
754.It NumberOfPasswordPrompts 762.It NumberOfPasswordPrompts
755.It PasswordAuthentication 763.It PasswordAuthentication
764.It PermitLocalCommand
756.It Port 765.It Port
757.It PreferredAuthentications 766.It PreferredAuthentications
758.It Protocol 767.It Protocol
@@ -767,6 +776,8 @@ For full details of the options listed below, and their possible values, see
767.It SmartcardDevice 776.It SmartcardDevice
768.It StrictHostKeyChecking 777.It StrictHostKeyChecking
769.It TCPKeepAlive 778.It TCPKeepAlive
779.It Tunnel
780.It TunnelDevice
770.It UsePrivilegedPort 781.It UsePrivilegedPort
771.It User 782.It User
772.It UserKnownHostsFile 783.It UserKnownHostsFile
@@ -866,6 +877,13 @@ Multiple
866.Fl v 877.Fl v
867options increase the verbosity. 878options increase the verbosity.
868The maximum is 3. 879The maximum is 3.
880.It Fl w
881Requests a
882.Xr tun 4
883device on the client and server like the
884.Cm Tunnel
885directive in
886.Xr ssh_config 5 .
869.It Fl X 887.It Fl X
870Enables X11 forwarding. 888Enables X11 forwarding.
871This can also be specified on a per-host basis in a configuration file. 889This can also be specified on a per-host basis in a configuration file.
diff --git a/ssh.c b/ssh.c
index 2227755cd..8a4a0e4c9 100644
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: ssh.c,v 1.254 2005/10/30 08:52:18 djm Exp $"); 43RCSID("$OpenBSD: ssh.c,v 1.255 2005/12/06 22:38:27 reyk Exp $");
44 44
45#include <openssl/evp.h> 45#include <openssl/evp.h>
46#include <openssl/err.h> 46#include <openssl/err.h>
@@ -162,7 +162,7 @@ usage(void)
162" [-i identity_file] [-L [bind_address:]port:host:hostport]\n" 162" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
163" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" 163" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
164" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" 164" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
165" [user@]hostname [command]\n" 165" [-w tunnel:tunnel] [user@]hostname [command]\n"
166 ); 166 );
167 exit(1); 167 exit(1);
168} 168}
@@ -244,7 +244,7 @@ main(int ac, char **av)
244 244
245again: 245again:
246 while ((opt = getopt(ac, av, 246 while ((opt = getopt(ac, av,
247 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) { 247 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
248 switch (opt) { 248 switch (opt) {
249 case '1': 249 case '1':
250 options.protocol = SSH_PROTO_1; 250 options.protocol = SSH_PROTO_1;
@@ -340,6 +340,14 @@ again:
340 if (opt == 'V') 340 if (opt == 'V')
341 exit(0); 341 exit(0);
342 break; 342 break;
343 case 'w':
344 options.tun_open = 1;
345 options.tun_local = a2tun(optarg, &options.tun_remote);
346 if (options.tun_local < -1) {
347 fprintf(stderr, "Bad tun device '%s'\n", optarg);
348 exit(1);
349 }
350 break;
343 case 'q': 351 case 'q':
344 options.log_level = SYSLOG_LEVEL_QUIET; 352 options.log_level = SYSLOG_LEVEL_QUIET;
345 break; 353 break;
@@ -1059,6 +1067,26 @@ ssh_session2_setup(int id, void *arg)
1059 packet_send(); 1067 packet_send();
1060 } 1068 }
1061 1069
1070 if (options.tun_open) {
1071 Channel *c;
1072 int fd;
1073
1074 debug("Requesting tun.");
1075 if ((fd = tun_open(options.tun_local)) >= 0) {
1076 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
1077 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1078 0, "tun", 1);
1079 c->datagram = 1;
1080 packet_start(SSH2_MSG_CHANNEL_OPEN);
1081 packet_put_cstring("tun@openssh.com");
1082 packet_put_int(c->self);
1083 packet_put_int(c->local_window_max);
1084 packet_put_int(c->local_maxpacket);
1085 packet_put_int(options.tun_remote);
1086 packet_send();
1087 }
1088 }
1089
1062 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1090 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1063 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); 1091 NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
1064 1092
@@ -1123,6 +1151,11 @@ ssh_session2(void)
1123 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1151 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1124 id = ssh_session2_open(); 1152 id = ssh_session2_open();
1125 1153
1154 /* Execute a local command */
1155 if (options.local_command != NULL &&
1156 options.permit_local_command)
1157 ssh_local_cmd(options.local_command);
1158
1126 /* If requested, let ssh continue in the background. */ 1159 /* If requested, let ssh continue in the background. */
1127 if (fork_after_authentication_flag) 1160 if (fork_after_authentication_flag)
1128 if (daemon(1, 1) < 0) 1161 if (daemon(1, 1) < 0)
diff --git a/ssh_config b/ssh_config
index f41bee0a2..7bc8762d6 100644
--- a/ssh_config
+++ b/ssh_config
@@ -1,4 +1,4 @@
1# $OpenBSD: ssh_config,v 1.20 2005/01/28 09:45:53 dtucker Exp $ 1# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
2 2
3# This is the ssh client system-wide configuration file. See 3# This is the ssh client system-wide configuration file. See
4# ssh_config(5) for more information. This file provides defaults for 4# ssh_config(5) for more information. This file provides defaults for
@@ -37,3 +37,6 @@
37# Cipher 3des 37# Cipher 3des
38# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc 38# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
39# EscapeChar ~ 39# EscapeChar ~
40# Tunnel no
41# TunnelDevice any:any
42# PermitLocalCommand no
diff --git a/ssh_config.5 b/ssh_config.5
index 13cdee88b..d1930baab 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh_config.5,v 1.64 2005/10/30 08:43:47 jmc Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.65 2005/12/06 22:38:27 reyk Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
@@ -556,6 +556,14 @@ The default is
556Specifies the list of methods to use in keyboard-interactive authentication. 556Specifies the list of methods to use in keyboard-interactive authentication.
557Multiple method names must be comma-separated. 557Multiple method names must be comma-separated.
558The default is to use the server specified list. 558The default is to use the server specified list.
559.It Cm LocalCommand
560Specifies a command to execute on the local machine after successfully
561connecting to the server.
562The command string extends to the end of the line, and is executed with
563.Pa /bin/sh .
564This directive is ignored unless
565.Cm PermitLocalCommand
566has been enabled.
559.It Cm LocalForward 567.It Cm LocalForward
560Specifies that a TCP/IP port on the local machine be forwarded over 568Specifies that a TCP/IP port on the local machine be forwarded over
561the secure channel to the specified host and port from the remote machine. 569the secure channel to the specified host and port from the remote machine.
@@ -628,6 +636,19 @@ The default is
628.It Cm Port 636.It Cm Port
629Specifies the port number to connect on the remote host. 637Specifies the port number to connect on the remote host.
630Default is 22. 638Default is 22.
639.It Cm PermitLocalCommand
640Allow local command execution via the
641.Ic LocalCommand
642option or using the
643.Ic ! Ar command
644escape sequence in
645.Xr ssh 1 .
646The argument must be
647.Dq yes
648or
649.Dq no .
650The default is
651.Dq no .
631.It Cm PreferredAuthentications 652.It Cm PreferredAuthentications
632Specifies the order in which the client should try protocol 2 653Specifies the order in which the client should try protocol 2
633authentication methods. 654authentication methods.
@@ -887,6 +908,21 @@ Note that this option must be set to
887for 908for
888.Cm RhostsRSAAuthentication 909.Cm RhostsRSAAuthentication
889with older servers. 910with older servers.
911.It Cm Tunnel
912Request starting
913.Xr tun 4
914device forwarding between the client and the server.
915The argument must be
916.Dq yes
917or
918.Dq no .
919The default is
920.Dq no .
921.It Cm TunnelDevice
922Force a specified
923.Xr tun 4
924device on the client.
925Without this option, the next available device will be used.
890.It Cm User 926.It Cm User
891Specifies the user to log in as. 927Specifies the user to log in as.
892This can be useful when a different user name is used on different machines. 928This can be useful when a different user name is used on different machines.
diff --git a/sshconnect.c b/sshconnect.c
index 2245a8af6..64ffec240 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect.c,v 1.170 2005/10/30 08:52:18 djm Exp $"); 16RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19 19
@@ -1034,3 +1034,39 @@ warn_changed_key(Key *host_key)
1034 1034
1035 xfree(fp); 1035 xfree(fp);
1036} 1036}
1037
1038/*
1039 * Execute a local command
1040 */
1041int
1042ssh_local_cmd(const char *args)
1043{
1044 char *shell;
1045 pid_t pid;
1046 int status;
1047
1048 if (!options.permit_local_command ||
1049 args == NULL || !*args)
1050 return (1);
1051
1052 if ((shell = getenv("SHELL")) == NULL)
1053 shell = _PATH_BSHELL;
1054
1055 pid = fork();
1056 if (pid == 0) {
1057 debug3("Executing %s -c \"%s\"", shell, args);
1058 execl(shell, shell, "-c", args, (char *)NULL);
1059 error("Couldn't execute %s -c \"%s\": %s",
1060 shell, args, strerror(errno));
1061 _exit(1);
1062 } else if (pid == -1)
1063 fatal("fork failed: %.100s", strerror(errno));
1064 while (waitpid(pid, &status, 0) == -1)
1065 if (errno != EINTR)
1066 fatal("Couldn't wait for child: %s", strerror(errno));
1067
1068 if (!WIFEXITED(status))
1069 return (1);
1070
1071 return (WEXITSTATUS(status));
1072}
diff --git a/sshconnect.h b/sshconnect.h
index 0be30fe69..e7c7a2b34 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.17 2002/06/19 00:27:55 deraadt Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.18 2005/12/06 22:38:28 reyk Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -49,7 +49,7 @@ void ssh_userauth1(const char *, const char *, char *, Sensitive *);
49void ssh_userauth2(const char *, const char *, char *, Sensitive *); 49void ssh_userauth2(const char *, const char *, char *, Sensitive *);
50 50
51void ssh_put_password(char *); 51void ssh_put_password(char *);
52 52int ssh_local_cmd(const char *);
53 53
54/* 54/*
55 * Macros to raise/lower permissions. 55 * Macros to raise/lower permissions.
diff --git a/sshd.8 b/sshd.8
index c610f47b8..53eddcdfb 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.208 2005/06/08 03:50:00 djm Exp $ 37.\" $OpenBSD: sshd.8,v 1.209 2005/12/06 22:38:28 reyk Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
@@ -518,6 +518,12 @@ Multiple
518options may be applied separated by commas. 518options may be applied separated by commas.
519No pattern matching is performed on the specified hostnames, 519No pattern matching is performed on the specified hostnames,
520they must be literal domains or addresses. 520they must be literal domains or addresses.
521.It Cm tunnel="n"
522Force a
523.Xr tun 4
524device on the server.
525Without this option, the next available device will be used if
526the client requests a tunnel.
521.El 527.El
522.Ss Examples 528.Ss Examples
5231024 33 12121...312314325 ylo@foo.bar 5291024 33 12121...312314325 ylo@foo.bar
@@ -527,6 +533,8 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
527command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi 533command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi
528.Pp 534.Pp
529permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 535permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323
536.Pp
537tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== reyk@openbsd.org
530.Sh SSH_KNOWN_HOSTS FILE FORMAT 538.Sh SSH_KNOWN_HOSTS FILE FORMAT
531The 539The
532.Pa /etc/ssh/ssh_known_hosts 540.Pa /etc/ssh/ssh_known_hosts
diff --git a/sshd_config b/sshd_config
index 1440c05ff..4957dd1a6 100644
--- a/sshd_config
+++ b/sshd_config
@@ -1,4 +1,4 @@
1# $OpenBSD: sshd_config,v 1.72 2005/07/25 11:59:40 markus Exp $ 1# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
2 2
3# This is the sshd server system-wide configuration file. See 3# This is the sshd server system-wide configuration file. See
4# sshd_config(5) for more information. 4# sshd_config(5) for more information.
@@ -96,6 +96,7 @@
96#UseDNS yes 96#UseDNS yes
97#PidFile /var/run/sshd.pid 97#PidFile /var/run/sshd.pid
98#MaxStartups 10 98#MaxStartups 10
99#PermitTunnel no
99 100
100# no default banner path 101# no default banner path
101#Banner /some/path 102#Banner /some/path
diff --git a/sshd_config.5 b/sshd_config.5
index 45c1c0131..3835fcd62 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd_config.5,v 1.45 2005/09/21 23:36:54 djm Exp $ 37.\" $OpenBSD: sshd_config.5,v 1.46 2005/12/06 22:38:28 reyk Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD_CONFIG 5 39.Dt SSHD_CONFIG 5
40.Os 40.Os
@@ -502,6 +502,12 @@ All other authentication methods are disabled for root.
502If this option is set to 502If this option is set to
503.Dq no 503.Dq no
504root is not allowed to log in. 504root is not allowed to log in.
505.It Cm PermitTunnel
506Specifies whether
507.Xr tun 4
508device forwarding is allowed.
509The default is
510.Dq no .
505.It Cm PermitUserEnvironment 511.It Cm PermitUserEnvironment
506Specifies whether 512Specifies whether
507.Pa ~/.ssh/environment 513.Pa ~/.ssh/environment