diff options
author | Darren Tucker <dtucker@zip.com.au> | 2003-07-03 13:55:19 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2003-07-03 13:55:19 +1000 |
commit | 46471c9a81bdd0d797149a20364645bc6ffcf2cc (patch) | |
tree | b21df0ef269b109a7dd6c6baaf8477ae87f7d478 | |
parent | 9189ff89c3c15f152d8daedb09c4101a96365da4 (diff) |
- markus@cvs.openbsd.org 2003/07/02 14:51:16
[channels.c ssh.1 ssh_config.5]
(re)add socks5 suppport to -D; ok djm@
now ssh(1) can act both as a socks 4 and socks 5 server and
dynamically forward ports.
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | channels.c | 120 | ||||
-rw-r--r-- | ssh.1 | 6 | ||||
-rw-r--r-- | ssh_config.5 | 6 |
4 files changed, 129 insertions, 10 deletions
@@ -15,6 +15,11 @@ | |||
15 | - markus@cvs.openbsd.org 2003/07/02 12:56:34 | 15 | - markus@cvs.openbsd.org 2003/07/02 12:56:34 |
16 | [channels.c] | 16 | [channels.c] |
17 | deny dynamic forwarding with -R for v1, too; ok djm@ | 17 | deny dynamic forwarding with -R for v1, too; ok djm@ |
18 | - markus@cvs.openbsd.org 2003/07/02 14:51:16 | ||
19 | [channels.c ssh.1 ssh_config.5] | ||
20 | (re)add socks5 suppport to -D; ok djm@ | ||
21 | now ssh(1) can act both as a socks 4 and socks 5 server and | ||
22 | dynamically forward ports. | ||
18 | 23 | ||
19 | 20030630 | 24 | 20030630 |
20 | - (djm) Search for support functions necessary to build our | 25 | - (djm) Search for support functions necessary to build our |
@@ -635,4 +640,4 @@ | |||
635 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. | 640 | - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. |
636 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au | 641 | Report from murple@murple.net, diagnosis from dtucker@zip.com.au |
637 | 642 | ||
638 | $Id: ChangeLog,v 1.2839 2003/07/03 03:52:04 dtucker Exp $ | 643 | $Id: ChangeLog,v 1.2840 2003/07/03 03:55:19 dtucker Exp $ |
diff --git a/channels.c b/channels.c index ce07db5c0..e5b2b8c51 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.192 2003/07/02 12:56:34 markus Exp $"); | 42 | RCSID("$OpenBSD: channels.c,v 1.193 2003/07/02 14:51:16 markus Exp $"); |
43 | 43 | ||
44 | #include "ssh.h" | 44 | #include "ssh.h" |
45 | #include "ssh1.h" | 45 | #include "ssh1.h" |
@@ -54,7 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.192 2003/07/02 12:56:34 markus Exp $"); | |||
54 | #include "key.h" | 54 | #include "key.h" |
55 | #include "authfd.h" | 55 | #include "authfd.h" |
56 | #include "pathnames.h" | 56 | #include "pathnames.h" |
57 | 57 | #include "bufaux.h" | |
58 | 58 | ||
59 | /* -- channel core */ | 59 | /* -- channel core */ |
60 | 60 | ||
@@ -941,6 +941,117 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) | |||
941 | return 1; | 941 | return 1; |
942 | } | 942 | } |
943 | 943 | ||
944 | /* try to decode a socks5 header */ | ||
945 | #define SSH_SOCKS5_AUTHDONE 0x1000 | ||
946 | #define SSH_SOCKS5_NOAUTH 0x00 | ||
947 | #define SSH_SOCKS5_IPV4 0x01 | ||
948 | #define SSH_SOCKS5_DOMAIN 0x03 | ||
949 | #define SSH_SOCKS5_IPV6 0x04 | ||
950 | #define SSH_SOCKS5_CONNECT 0x01 | ||
951 | #define SSH_SOCKS5_SUCCESS 0x00 | ||
952 | |||
953 | static int | ||
954 | channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) | ||
955 | { | ||
956 | struct { | ||
957 | u_int8_t version; | ||
958 | u_int8_t command; | ||
959 | u_int8_t reserved; | ||
960 | u_int8_t atyp; | ||
961 | } s5_req, s5_rsp; | ||
962 | u_int16_t dest_port; | ||
963 | u_char *p, dest_addr[255+1]; | ||
964 | int i, have, found, nmethods, addrlen, af; | ||
965 | |||
966 | debug2("channel %d: decode socks5", c->self); | ||
967 | p = buffer_ptr(&c->input); | ||
968 | if (p[0] != 0x05) | ||
969 | return -1; | ||
970 | have = buffer_len(&c->input); | ||
971 | if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { | ||
972 | /* format: ver | nmethods | methods */ | ||
973 | if (have < 2) | ||
974 | return 0; | ||
975 | nmethods = p[1]; | ||
976 | if (have < nmethods + 2) | ||
977 | return 0; | ||
978 | /* look for method: "NO AUTHENTICATION REQUIRED" */ | ||
979 | for (found = 0, i = 2 ; i < nmethods + 2; i++) { | ||
980 | if (p[i] == SSH_SOCKS5_NOAUTH ) { | ||
981 | found = 1; | ||
982 | break; | ||
983 | } | ||
984 | } | ||
985 | if (!found) { | ||
986 | debug("channel %d: method SSH_SOCKS5_NOAUTH not found", | ||
987 | c->self); | ||
988 | return -1; | ||
989 | } | ||
990 | buffer_consume(&c->input, nmethods + 2); | ||
991 | buffer_put_char(&c->output, 0x05); /* version */ | ||
992 | buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ | ||
993 | FD_SET(c->sock, writeset); | ||
994 | c->flags |= SSH_SOCKS5_AUTHDONE; | ||
995 | debug2("channel %d: socks5 auth done", c->self); | ||
996 | return 0; /* need more */ | ||
997 | } | ||
998 | debug2("channel %d: socks5 post auth", c->self); | ||
999 | if (have < sizeof(s5_req)+1) | ||
1000 | return 0; /* need more */ | ||
1001 | memcpy((char *)&s5_req, p, sizeof(s5_req)); | ||
1002 | if (s5_req.version != 0x05 || | ||
1003 | s5_req.command != SSH_SOCKS5_CONNECT || | ||
1004 | s5_req.reserved != 0x00) { | ||
1005 | debug("channel %d: only socks5 connect supported", c->self); | ||
1006 | return -1; | ||
1007 | } | ||
1008 | switch(s5_req.atyp){ | ||
1009 | case SSH_SOCKS5_IPV4: | ||
1010 | addrlen = 4; | ||
1011 | af = AF_INET; | ||
1012 | break; | ||
1013 | case SSH_SOCKS5_DOMAIN: | ||
1014 | addrlen = p[sizeof(s5_req)]; | ||
1015 | af = -1; | ||
1016 | break; | ||
1017 | case SSH_SOCKS5_IPV6: | ||
1018 | addrlen = 16; | ||
1019 | af = AF_INET6; | ||
1020 | break; | ||
1021 | default: | ||
1022 | debug("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); | ||
1023 | return -1; | ||
1024 | } | ||
1025 | if (have < 4 + addrlen + 2) | ||
1026 | return 0; | ||
1027 | buffer_consume(&c->input, sizeof(s5_req)); | ||
1028 | if (s5_req.atyp == SSH_SOCKS5_DOMAIN) | ||
1029 | buffer_consume(&c->input, 1); /* host string length */ | ||
1030 | buffer_get(&c->input, (char *)&dest_addr, addrlen); | ||
1031 | buffer_get(&c->input, (char *)&dest_port, 2); | ||
1032 | dest_addr[addrlen] = '\0'; | ||
1033 | if (s5_req.atyp == SSH_SOCKS5_DOMAIN) | ||
1034 | strlcpy(c->path, dest_addr, sizeof(c->path)); | ||
1035 | else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) | ||
1036 | return -1; | ||
1037 | c->host_port = ntohs(dest_port); | ||
1038 | |||
1039 | debug("channel %d: dynamic request: socks5 host %s port %u command %u", | ||
1040 | c->self, c->path, c->host_port, s5_req.command); | ||
1041 | |||
1042 | s5_rsp.version = 0x05; | ||
1043 | s5_rsp.command = SSH_SOCKS5_SUCCESS; | ||
1044 | s5_rsp.reserved = 0; /* ignored */ | ||
1045 | s5_rsp.atyp = SSH_SOCKS5_IPV4; | ||
1046 | ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY; | ||
1047 | dest_port = 0; /* ignored */ | ||
1048 | |||
1049 | buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp)); | ||
1050 | buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr)); | ||
1051 | buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port)); | ||
1052 | return 1; | ||
1053 | } | ||
1054 | |||
944 | /* dynamic port forwarding */ | 1055 | /* dynamic port forwarding */ |
945 | static void | 1056 | static void |
946 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | 1057 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) |
@@ -953,7 +1064,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | |||
953 | debug2("channel %d: pre_dynamic: have %d", c->self, have); | 1064 | debug2("channel %d: pre_dynamic: have %d", c->self, have); |
954 | /* buffer_dump(&c->input); */ | 1065 | /* buffer_dump(&c->input); */ |
955 | /* check if the fixed size part of the packet is in buffer. */ | 1066 | /* check if the fixed size part of the packet is in buffer. */ |
956 | if (have < 4) { | 1067 | if (have < 3) { |
957 | /* need more */ | 1068 | /* need more */ |
958 | FD_SET(c->sock, readset); | 1069 | FD_SET(c->sock, readset); |
959 | return; | 1070 | return; |
@@ -964,6 +1075,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | |||
964 | case 0x04: | 1075 | case 0x04: |
965 | ret = channel_decode_socks4(c, readset, writeset); | 1076 | ret = channel_decode_socks4(c, readset, writeset); |
966 | break; | 1077 | break; |
1078 | case 0x05: | ||
1079 | ret = channel_decode_socks5(c, readset, writeset); | ||
1080 | break; | ||
967 | default: | 1081 | default: |
968 | ret = -1; | 1082 | ret = -1; |
969 | break; | 1083 | break; |
@@ -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.173 2003/06/10 09:12:11 jmc Exp $ | 37 | .\" $OpenBSD: ssh.1,v 1.174 2003/07/02 14:51:16 markus Exp $ |
38 | .Dd September 25, 1999 | 38 | .Dd September 25, 1999 |
39 | .Dt SSH 1 | 39 | .Dt SSH 1 |
40 | .Os | 40 | .Os |
@@ -649,9 +649,9 @@ on the local side, and whenever a connection is made to this port, the | |||
649 | connection is forwarded over the secure channel, and the application | 649 | connection is forwarded over the secure channel, and the application |
650 | protocol is then used to determine where to connect to from the | 650 | protocol is then used to determine where to connect to from the |
651 | remote machine. | 651 | remote machine. |
652 | Currently the SOCKS4 protocol is supported, and | 652 | Currently the SOCKS4 and SOCKS5 protocols are supported, and |
653 | .Nm | 653 | .Nm |
654 | will act as a SOCKS4 server. | 654 | will act as a SOCKS server. |
655 | Only root can forward privileged ports. | 655 | Only root can forward privileged ports. |
656 | Dynamic port forwardings can also be specified in the configuration file. | 656 | Dynamic port forwardings can also be specified in the configuration file. |
657 | .It Fl 1 | 657 | .It Fl 1 |
diff --git a/ssh_config.5 b/ssh_config.5 index 56df3acec..79d05f018 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.14 2003/06/23 09:02:44 markus Exp $ | 37 | .\" $OpenBSD: ssh_config.5,v 1.15 2003/07/02 14:51:16 markus 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 |
@@ -246,9 +246,9 @@ over the secure channel, and the application | |||
246 | protocol is then used to determine where to connect to from the | 246 | protocol is then used to determine where to connect to from the |
247 | remote machine. | 247 | remote machine. |
248 | The argument must be a port number. | 248 | The argument must be a port number. |
249 | Currently the SOCKS4 protocol is supported, and | 249 | Currently the SOCKS4 and SOCKS5 protocols are supported, and |
250 | .Nm ssh | 250 | .Nm ssh |
251 | will act as a SOCKS4 server. | 251 | will act as a SOCKS server. |
252 | Multiple forwardings may be specified, and | 252 | Multiple forwardings may be specified, and |
253 | additional forwardings can be given on the command line. | 253 | additional forwardings can be given on the command line. |
254 | Only the superuser can forward privileged ports. | 254 | Only the superuser can forward privileged ports. |