summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2009-01-28 16:24:41 +1100
committerDamien Miller <djm@mindrot.org>2009-01-28 16:24:41 +1100
commit1781f53d7540778fa50991d9b5aaf8f4b4a2eafd (patch)
treec53cf1aa2ea3c62479f37ac954020a0df316d018
parentccf7e224ab73a8134175504ff09d72655ba50fb2 (diff)
- djm@cvs.openbsd.org 2009/01/14 01:38:06
[channels.c] support SOCKS4A protocol, from dwmw2 AT infradead.org via bz#1482; "looks ok" markus@
-rw-r--r--ChangeLog6
-rw-r--r--channels.c50
2 files changed, 44 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e6a18f43..332dacce3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -42,6 +42,10 @@
42 values and not the sanity checked versions that we acutally use; 42 values and not the sanity checked versions that we acutally use;
43 bz#1540 reported by john.smith AT arrows.demon.co.uk 43 bz#1540 reported by john.smith AT arrows.demon.co.uk
44 ok markus@ 44 ok markus@
45 - djm@cvs.openbsd.org 2009/01/14 01:38:06
46 [channels.c]
47 support SOCKS4A protocol, from dwmw2 AT infradead.org via bz#1482;
48 "looks ok" markus@
45 49
4620090107 5020090107
47 - (djm) [uidswap.c] bz#1412: Support >16 supplemental groups in OS X. 51 - (djm) [uidswap.c] bz#1412: Support >16 supplemental groups in OS X.
@@ -5051,5 +5055,5 @@
5051 OpenServer 6 and add osr5bigcrypt support so when someone migrates 5055 OpenServer 6 and add osr5bigcrypt support so when someone migrates
5052 passwords between UnixWare and OpenServer they will still work. OK dtucker@ 5056 passwords between UnixWare and OpenServer they will still work. OK dtucker@
5053 5057
5054$Id: ChangeLog,v 1.5170 2009/01/28 05:23:06 djm Exp $ 5058$Id: ChangeLog,v 1.5171 2009/01/28 05:24:41 djm Exp $
5055 5059
diff --git a/channels.c b/channels.c
index d138882b3..2319afd4b 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.291 2009/01/01 21:14:35 djm Exp $ */ 1/* $OpenBSD: channels.c,v 1.292 2009/01/14 01:38:06 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -980,7 +980,7 @@ static int
980channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) 980channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
981{ 981{
982 char *p, *host; 982 char *p, *host;
983 u_int len, have, i, found; 983 u_int len, have, i, found, need;
984 char username[256]; 984 char username[256];
985 struct { 985 struct {
986 u_int8_t version; 986 u_int8_t version;
@@ -996,10 +996,20 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
996 if (have < len) 996 if (have < len)
997 return 0; 997 return 0;
998 p = buffer_ptr(&c->input); 998 p = buffer_ptr(&c->input);
999
1000 need = 1;
1001 /* SOCKS4A uses an invalid IP address 0.0.0.x */
1002 if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
1003 debug2("channel %d: socks4a request", c->self);
1004 /* ... and needs an extra string (the hostname) */
1005 need = 2;
1006 }
1007 /* Check for terminating NUL on the string(s) */
999 for (found = 0, i = len; i < have; i++) { 1008 for (found = 0, i = len; i < have; i++) {
1000 if (p[i] == '\0') { 1009 if (p[i] == '\0') {
1001 found = 1; 1010 found++;
1002 break; 1011 if (found == need)
1012 break;
1003 } 1013 }
1004 if (i > 1024) { 1014 if (i > 1024) {
1005 /* the peer is probably sending garbage */ 1015 /* the peer is probably sending garbage */
@@ -1008,7 +1018,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1008 return -1; 1018 return -1;
1009 } 1019 }
1010 } 1020 }
1011 if (!found) 1021 if (found < need)
1012 return 0; 1022 return 0;
1013 buffer_get(&c->input, (char *)&s4_req.version, 1); 1023 buffer_get(&c->input, (char *)&s4_req.version, 1);
1014 buffer_get(&c->input, (char *)&s4_req.command, 1); 1024 buffer_get(&c->input, (char *)&s4_req.command, 1);
@@ -1018,23 +1028,41 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1018 p = buffer_ptr(&c->input); 1028 p = buffer_ptr(&c->input);
1019 len = strlen(p); 1029 len = strlen(p);
1020 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); 1030 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1031 len++; /* trailing '\0' */
1021 if (len > have) 1032 if (len > have)
1022 fatal("channel %d: decode socks4: len %d > have %d", 1033 fatal("channel %d: decode socks4: len %d > have %d",
1023 c->self, len, have); 1034 c->self, len, have);
1024 strlcpy(username, p, sizeof(username)); 1035 strlcpy(username, p, sizeof(username));
1025 buffer_consume(&c->input, len); 1036 buffer_consume(&c->input, len);
1026 buffer_consume(&c->input, 1); /* trailing '\0' */
1027 1037
1028 host = inet_ntoa(s4_req.dest_addr); 1038 if (need == 1) { /* SOCKS4: one string */
1029 strlcpy(c->path, host, sizeof(c->path)); 1039 host = inet_ntoa(s4_req.dest_addr);
1040 strlcpy(c->path, host, sizeof(c->path));
1041 } else { /* SOCKS4A: two strings */
1042 have = buffer_len(&c->input);
1043 p = buffer_ptr(&c->input);
1044 len = strlen(p);
1045 debug2("channel %d: decode socks4a: host %s/%d",
1046 c->self, p, len);
1047 len++; /* trailing '\0' */
1048 if (len > have)
1049 fatal("channel %d: decode socks4a: len %d > have %d",
1050 c->self, len, have);
1051 if (strlcpy(c->path, p, sizeof(c->path)) >= sizeof(c->path)) {
1052 error("channel %d: hostname \"%.100s\" too long",
1053 c->self, p);
1054 return -1;
1055 }
1056 buffer_consume(&c->input, len);
1057 }
1030 c->host_port = ntohs(s4_req.dest_port); 1058 c->host_port = ntohs(s4_req.dest_port);
1031 1059
1032 debug2("channel %d: dynamic request: socks4 host %s port %u command %u", 1060 debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
1033 c->self, host, c->host_port, s4_req.command); 1061 c->self, c->path, c->host_port, s4_req.command);
1034 1062
1035 if (s4_req.command != 1) { 1063 if (s4_req.command != 1) {
1036 debug("channel %d: cannot handle: socks4 cn %d", 1064 debug("channel %d: cannot handle: %s cn %d",
1037 c->self, s4_req.command); 1065 c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);
1038 return -1; 1066 return -1;
1039 } 1067 }
1040 s4_rsp.version = 0; /* vn: 0 for reply */ 1068 s4_rsp.version = 0; /* vn: 0 for reply */