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 /channels.c | |
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
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 42 |
1 files changed, 40 insertions, 2 deletions
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 | ||