diff options
author | Damien Miller <djm@mindrot.org> | 2005-12-13 19:29:02 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-12-13 19:29:02 +1100 |
commit | d27b947178df3689bfb7fdfb62a5f1337ef73481 (patch) | |
tree | c8678325c355b3602bdabca16da1baa8707818eb | |
parent | 6dbdb6afeec1820b2799c2693fc8e8b364be8228 (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-- | ChangeLog | 17 | ||||
-rw-r--r-- | auth-options.c | 41 | ||||
-rw-r--r-- | auth-options.h | 3 | ||||
-rw-r--r-- | channels.c | 42 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | clientloop.c | 11 | ||||
-rw-r--r-- | misc.c | 58 | ||||
-rw-r--r-- | misc.h | 4 | ||||
-rw-r--r-- | readconf.c | 52 | ||||
-rw-r--r-- | readconf.h | 10 | ||||
-rw-r--r-- | scp.c | 3 | ||||
-rw-r--r-- | servconf.c | 12 | ||||
-rw-r--r-- | servconf.h | 5 | ||||
-rw-r--r-- | serverloop.c | 34 | ||||
-rw-r--r-- | sftp.c | 3 | ||||
-rw-r--r-- | ssh.1 | 20 | ||||
-rw-r--r-- | ssh.c | 39 | ||||
-rw-r--r-- | ssh_config | 5 | ||||
-rw-r--r-- | ssh_config.5 | 38 | ||||
-rw-r--r-- | sshconnect.c | 38 | ||||
-rw-r--r-- | sshconnect.h | 4 | ||||
-rw-r--r-- | sshd.8 | 10 | ||||
-rw-r--r-- | sshd_config | 3 | ||||
-rw-r--r-- | sshd_config.5 | 8 |
24 files changed, 433 insertions, 31 deletions
@@ -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 | ||
11 | 20051201 | 26 | 20051201 |
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" |
13 | RCSID("$OpenBSD: auth-options.c,v 1.31 2005/03/10 22:40:38 deraadt Exp $"); | 13 | RCSID("$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. */ |
36 | struct envstring *custom_environment = NULL; | 36 | struct envstring *custom_environment = NULL; |
37 | 37 | ||
38 | /* "tunnel=" option. */ | ||
39 | int forced_tun_device = -1; | ||
40 | |||
38 | extern ServerOptions options; | 41 | extern ServerOptions options; |
39 | 42 | ||
40 | void | 43 | void |
@@ -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 | } | ||
272 | next_option: | 311 | next_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; | |||
28 | extern int no_pty_flag; | 28 | extern int no_pty_flag; |
29 | extern char *forced_command; | 29 | extern char *forced_command; |
30 | extern struct envstring *custom_environment; | 30 | extern struct envstring *custom_environment; |
31 | extern int forced_tun_device; | ||
31 | 32 | ||
32 | int auth_parse_options(struct passwd *, char *, char *, u_long); | 33 | int auth_parse_options(struct passwd *, char *, char *, u_long); |
33 | void auth_clear_options(void); | 34 | void 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" |
42 | RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $"); | 42 | RCSID("$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" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.145 2005/10/30 08:52:17 djm Exp $"); | 62 | RCSID("$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 | ||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "includes.h" | 26 | #include "includes.h" |
27 | RCSID("$OpenBSD: misc.c,v 1.35 2005/09/13 23:40:07 djm Exp $"); | 27 | RCSID("$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 | ||
197 | int | ||
198 | a2tun(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 | ||
541 | int | ||
542 | tun_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 | |||
510 | void | 566 | void |
511 | sanitise_stdfd(void) | 567 | sanitise_stdfd(void) |
512 | { | 568 | { |
@@ -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); | |||
20 | int unset_nonblock(int); | 20 | int unset_nonblock(int); |
21 | void set_nodelay(int); | 21 | void set_nodelay(int); |
22 | int a2port(const char *); | 22 | int a2port(const char *); |
23 | int a2tun(const char *, int *); | ||
23 | char *hpdelim(char **); | 24 | char *hpdelim(char **); |
24 | char *cleanhostname(char *); | 25 | char *cleanhostname(char *); |
25 | char *colon(char *); | 26 | char *colon(char *); |
@@ -49,3 +50,4 @@ void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); | |||
49 | char *read_passphrase(const char *, int); | 50 | char *read_passphrase(const char *, int); |
50 | int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); | 51 | int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); |
51 | int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); | 52 | int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); |
53 | int 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" |
15 | RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); | 15 | RCSID("$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; | ||
567 | parse_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 |
@@ -71,7 +71,7 @@ | |||
71 | */ | 71 | */ |
72 | 72 | ||
73 | #include "includes.h" | 73 | #include "includes.h" |
74 | RCSID("$OpenBSD: scp.c,v 1.127 2005/11/12 18:38:15 deraadt Exp $"); | 74 | RCSID("$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" |
13 | RCSID("$OpenBSD: servconf.c,v 1.144 2005/08/06 10:03:12 dtucker Exp $"); | 13 | RCSID("$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 | ||
139 | void initialize_server_options(ServerOptions *); | 142 | void 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" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.121 2005/10/31 11:48:29 djm Exp $"); | 38 | RCSID("$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 | ||
916 | static Channel * | 916 | static Channel * |
917 | server_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 | |||
946 | static Channel * | ||
917 | server_request_session(void) | 947 | server_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); |
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include "includes.h" | 17 | #include "includes.h" |
18 | 18 | ||
19 | RCSID("$OpenBSD: sftp.c,v 1.68 2005/10/31 06:15:04 dtucker Exp $"); | 19 | RCSID("$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; |
@@ -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). | |||
301 | It also allows the cancellation of existing remote port-forwardings | 302 | It also allows the cancellation of existing remote port-forwardings |
302 | using | 303 | using |
303 | .Fl KR Ar hostport . | 304 | .Fl KR Ar hostport . |
305 | The | ||
306 | .Ic ! Ar command | ||
307 | allows the user to execute a local command if the | ||
308 | .Ic PermitLocalCommand | ||
309 | option is enabled in | ||
310 | .Xr ssh_config 5 . | ||
304 | Basic help is available, using the | 311 | Basic help is available, using the |
305 | .Fl h | 312 | .Fl h |
306 | option. | 313 | option. |
@@ -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 |
867 | options increase the verbosity. | 878 | options increase the verbosity. |
868 | The maximum is 3. | 879 | The maximum is 3. |
880 | .It Fl w | ||
881 | Requests a | ||
882 | .Xr tun 4 | ||
883 | device on the client and server like the | ||
884 | .Cm Tunnel | ||
885 | directive in | ||
886 | .Xr ssh_config 5 . | ||
869 | .It Fl X | 887 | .It Fl X |
870 | Enables X11 forwarding. | 888 | Enables X11 forwarding. |
871 | This can also be specified on a per-host basis in a configuration file. | 889 | This can also be specified on a per-host basis in a configuration file. |
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: ssh.c,v 1.254 2005/10/30 08:52:18 djm Exp $"); | 43 | RCSID("$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 | ||
245 | again: | 245 | again: |
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 | |||
556 | Specifies the list of methods to use in keyboard-interactive authentication. | 556 | Specifies the list of methods to use in keyboard-interactive authentication. |
557 | Multiple method names must be comma-separated. | 557 | Multiple method names must be comma-separated. |
558 | The default is to use the server specified list. | 558 | The default is to use the server specified list. |
559 | .It Cm LocalCommand | ||
560 | Specifies a command to execute on the local machine after successfully | ||
561 | connecting to the server. | ||
562 | The command string extends to the end of the line, and is executed with | ||
563 | .Pa /bin/sh . | ||
564 | This directive is ignored unless | ||
565 | .Cm PermitLocalCommand | ||
566 | has been enabled. | ||
559 | .It Cm LocalForward | 567 | .It Cm LocalForward |
560 | Specifies that a TCP/IP port on the local machine be forwarded over | 568 | Specifies that a TCP/IP port on the local machine be forwarded over |
561 | the secure channel to the specified host and port from the remote machine. | 569 | the 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 |
629 | Specifies the port number to connect on the remote host. | 637 | Specifies the port number to connect on the remote host. |
630 | Default is 22. | 638 | Default is 22. |
639 | .It Cm PermitLocalCommand | ||
640 | Allow local command execution via the | ||
641 | .Ic LocalCommand | ||
642 | option or using the | ||
643 | .Ic ! Ar command | ||
644 | escape sequence in | ||
645 | .Xr ssh 1 . | ||
646 | The argument must be | ||
647 | .Dq yes | ||
648 | or | ||
649 | .Dq no . | ||
650 | The default is | ||
651 | .Dq no . | ||
631 | .It Cm PreferredAuthentications | 652 | .It Cm PreferredAuthentications |
632 | Specifies the order in which the client should try protocol 2 | 653 | Specifies the order in which the client should try protocol 2 |
633 | authentication methods. | 654 | authentication methods. |
@@ -887,6 +908,21 @@ Note that this option must be set to | |||
887 | for | 908 | for |
888 | .Cm RhostsRSAAuthentication | 909 | .Cm RhostsRSAAuthentication |
889 | with older servers. | 910 | with older servers. |
911 | .It Cm Tunnel | ||
912 | Request starting | ||
913 | .Xr tun 4 | ||
914 | device forwarding between the client and the server. | ||
915 | The argument must be | ||
916 | .Dq yes | ||
917 | or | ||
918 | .Dq no . | ||
919 | The default is | ||
920 | .Dq no . | ||
921 | .It Cm TunnelDevice | ||
922 | Force a specified | ||
923 | .Xr tun 4 | ||
924 | device on the client. | ||
925 | Without this option, the next available device will be used. | ||
890 | .It Cm User | 926 | .It Cm User |
891 | Specifies the user to log in as. | 927 | Specifies the user to log in as. |
892 | This can be useful when a different user name is used on different machines. | 928 | This 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" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.170 2005/10/30 08:52:18 djm Exp $"); | 16 | RCSID("$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 | */ | ||
1041 | int | ||
1042 | ssh_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 *); | |||
49 | void ssh_userauth2(const char *, const char *, char *, Sensitive *); | 49 | void ssh_userauth2(const char *, const char *, char *, Sensitive *); |
50 | 50 | ||
51 | void ssh_put_password(char *); | 51 | void ssh_put_password(char *); |
52 | 52 | int ssh_local_cmd(const char *); | |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Macros to raise/lower permissions. | 55 | * Macros to raise/lower permissions. |
@@ -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 | |||
518 | options may be applied separated by commas. | 518 | options may be applied separated by commas. |
519 | No pattern matching is performed on the specified hostnames, | 519 | No pattern matching is performed on the specified hostnames, |
520 | they must be literal domains or addresses. | 520 | they must be literal domains or addresses. |
521 | .It Cm tunnel="n" | ||
522 | Force a | ||
523 | .Xr tun 4 | ||
524 | device on the server. | ||
525 | Without this option, the next available device will be used if | ||
526 | the client requests a tunnel. | ||
521 | .El | 527 | .El |
522 | .Ss Examples | 528 | .Ss Examples |
523 | 1024 33 12121...312314325 ylo@foo.bar | 529 | 1024 33 12121...312314325 ylo@foo.bar |
@@ -527,6 +533,8 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula | |||
527 | command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi | 533 | command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi |
528 | .Pp | 534 | .Pp |
529 | permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 | 535 | permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 |
536 | .Pp | ||
537 | tunnel="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 |
531 | The | 539 | The |
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. | |||
502 | If this option is set to | 502 | If this option is set to |
503 | .Dq no | 503 | .Dq no |
504 | root is not allowed to log in. | 504 | root is not allowed to log in. |
505 | .It Cm PermitTunnel | ||
506 | Specifies whether | ||
507 | .Xr tun 4 | ||
508 | device forwarding is allowed. | ||
509 | The default is | ||
510 | .Dq no . | ||
505 | .It Cm PermitUserEnvironment | 511 | .It Cm PermitUserEnvironment |
506 | Specifies whether | 512 | Specifies whether |
507 | .Pa ~/.ssh/environment | 513 | .Pa ~/.ssh/environment |