diff options
author | djm <> | 2004-10-17 03:13:55 +0000 |
---|---|---|
committer | djm <> | 2004-10-17 03:13:55 +0000 |
commit | 91294475ad30114d23728b4a7599c81a0e1a99a3 (patch) | |
tree | 1f23c7ad55ad26e1dda318b65e9a34e4e26af6f1 /src/usr.bin | |
parent | 8a16cf0bfbdc91bb8136c9cedf795be3e0496e8c (diff) | |
download | openbsd-91294475ad30114d23728b4a7599c81a0e1a99a3.tar.gz openbsd-91294475ad30114d23728b4a7599c81a0e1a99a3.tar.bz2 openbsd-91294475ad30114d23728b4a7599c81a0e1a99a3.zip |
http proxy CONNECT support; ok beck@
Diffstat (limited to 'src/usr.bin')
-rw-r--r-- | src/usr.bin/nc/nc.1 | 32 | ||||
-rw-r--r-- | src/usr.bin/nc/netcat.c | 19 | ||||
-rw-r--r-- | src/usr.bin/nc/socks.c | 86 |
3 files changed, 111 insertions, 26 deletions
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1 index 182950a952..44cdb14bbc 100644 --- a/src/usr.bin/nc/nc.1 +++ b/src/usr.bin/nc/nc.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: nc.1,v 1.32 2004/07/15 15:07:52 markus Exp $ | 1 | .\" $OpenBSD: nc.1,v 1.33 2004/10/17 03:13:55 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 1996 David Sacerdote | 3 | .\" Copyright (c) 1996 David Sacerdote |
4 | .\" All rights reserved. | 4 | .\" All rights reserved. |
@@ -39,7 +39,7 @@ | |||
39 | .Op Fl p Ar source_port | 39 | .Op Fl p Ar source_port |
40 | .Op Fl s Ar source_ip_address | 40 | .Op Fl s Ar source_ip_address |
41 | .Op Fl w Ar timeout | 41 | .Op Fl w Ar timeout |
42 | .Op Fl X Ar socks_version | 42 | .Op Fl X Ar proxy_protocol |
43 | .Oo Xo | 43 | .Oo Xo |
44 | .Fl x Ar proxy_address Ns Oo : Ns | 44 | .Fl x Ar proxy_address Ns Oo : Ns |
45 | .Ar port Oc Oc | 45 | .Ar port Oc Oc |
@@ -78,6 +78,9 @@ shell-script based HTTP clients and servers | |||
78 | .It | 78 | .It |
79 | network daemon testing | 79 | network daemon testing |
80 | .It | 80 | .It |
81 | a SOCKS or HTTP ProxyCommand for | ||
82 | .Xr ssh 1 | ||
83 | .It | ||
81 | and much, much more | 84 | and much, much more |
82 | .El | 85 | .El |
83 | .Pp | 86 | .Pp |
@@ -171,13 +174,19 @@ will listen forever for a connection, with or without the | |||
171 | .Fl w | 174 | .Fl w |
172 | flag. | 175 | flag. |
173 | The default is no timeout. | 176 | The default is no timeout. |
174 | .It Fl X Ar socks_version | 177 | .It Fl X Ar proxy_version |
175 | Requests that | 178 | Requests that |
176 | .Nm | 179 | .Nm |
177 | should use the specified version of the SOCKS protocol when talking to | 180 | should use the specified protocol when talking to the proxy server. |
178 | a SOCKS proxy. | 181 | Supported protocols are |
179 | SOCKS versions 4 and 5 are currently supported. | 182 | .Dq 4 |
180 | If the version is not specified, SOCKS version 5 is used. | 183 | (SOCKS v.4), |
184 | .Dq 5 | ||
185 | (SOCKS v.5) | ||
186 | and | ||
187 | .Dq connect | ||
188 | (HTTPS proxy). | ||
189 | If the protocol is not specified, SOCKS version 5 is used. | ||
181 | .It Xo | 190 | .It Xo |
182 | .Fl x Ar proxy_address Ns Oo : Ns | 191 | .Fl x Ar proxy_address Ns Oo : Ns |
183 | .Ar port Oc | 192 | .Ar port Oc |
@@ -186,13 +195,14 @@ Requests that | |||
186 | .Nm | 195 | .Nm |
187 | should connect to | 196 | should connect to |
188 | .Ar hostname | 197 | .Ar hostname |
189 | using a SOCKS proxy at | 198 | using a proxy at |
190 | .Ar proxy_address | 199 | .Ar proxy_address |
191 | and | 200 | and |
192 | .Ar port . | 201 | .Ar port . |
193 | If | 202 | If |
194 | .Ar port | 203 | .Ar port |
195 | is not specified, port 1080 is used. | 204 | is not specified, the well-known port for the proxy protocol is used (1080 |
205 | for SOCKS, 3128 for HTTPS). | ||
196 | .It Fl z | 206 | .It Fl z |
197 | Specifies that | 207 | Specifies that |
198 | .Nm | 208 | .Nm |
@@ -342,6 +352,10 @@ responded with an ICMP packet after three seconds: | |||
342 | Create and listen on a Unix Domain Socket: | 352 | Create and listen on a Unix Domain Socket: |
343 | .Pp | 353 | .Pp |
344 | .Dl $ nc -lU /var/tmp/dsocket | 354 | .Dl $ nc -lU /var/tmp/dsocket |
355 | .Pp | ||
356 | Connect to port 42 of hostname via an HTTP proxy at 10.2.3.4: | ||
357 | .Pp | ||
358 | .Dl $ nc -x10.2.3.4:8080 -Xconnect hostname 42 | ||
345 | .Sh SEE ALSO | 359 | .Sh SEE ALSO |
346 | .Xr cat 1 | 360 | .Xr cat 1 |
347 | .Sh AUTHORS | 361 | .Sh AUTHORS |
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index a2cb168e32..5e034466d4 100644 --- a/src/usr.bin/nc/netcat.c +++ b/src/usr.bin/nc/netcat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: netcat.c,v 1.74 2004/09/15 18:44:45 deraadt Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.75 2004/10/17 03:13:55 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
4 | * | 4 | * |
@@ -127,9 +127,14 @@ main(int argc, char *argv[]) | |||
127 | family = AF_UNIX; | 127 | family = AF_UNIX; |
128 | break; | 128 | break; |
129 | case 'X': | 129 | case 'X': |
130 | socksv = (int)strtoul(optarg, &endp, 10); | 130 | if (strcasecmp(optarg, "connect") == 0) |
131 | if ((socksv != 4 && socksv != 5) || *endp != '\0') | 131 | socksv = -1; /* HTTP proxy CONNECT */ |
132 | errx(1, "only SOCKS version 4 and 5 supported"); | 132 | else if (strcmp(optarg, "4") == 0) |
133 | socksv = 4; /* SOCKS v.4 */ | ||
134 | else if (strcmp(optarg, "5") == 0) | ||
135 | socksv = 5; /* SOCKS v.5 */ | ||
136 | else | ||
137 | errx(1, "unsupported proxy protocol"); | ||
133 | break; | 138 | break; |
134 | case 'd': | 139 | case 'd': |
135 | dflag = 1; | 140 | dflag = 1; |
@@ -779,8 +784,8 @@ help(void) | |||
779 | \t-u UDP mode\n\ | 784 | \t-u UDP mode\n\ |
780 | \t-v Verbose\n\ | 785 | \t-v Verbose\n\ |
781 | \t-w secs\t Timeout for connects and final net reads\n\ | 786 | \t-w secs\t Timeout for connects and final net reads\n\ |
782 | \t-X vers\t SOCKS version (4 or 5)\n\ | 787 | \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ |
783 | \t-x addr[:port]\tSpecify socks proxy address and port\n\ | 788 | \t-x addr[:port]\tSpecify proxy address and port\n\ |
784 | \t-z Zero-I/O mode [used for scanning]\n\ | 789 | \t-z Zero-I/O mode [used for scanning]\n\ |
785 | Port numbers can be individual or ranges: lo-hi [inclusive]\n"); | 790 | Port numbers can be individual or ranges: lo-hi [inclusive]\n"); |
786 | exit(1); | 791 | exit(1); |
@@ -790,7 +795,7 @@ void | |||
790 | usage(int ret) | 795 | usage(int ret) |
791 | { | 796 | { |
792 | fprintf(stderr, "usage: nc [-46DdhklnrStUuvz] [-i interval] [-p source_port]\n"); | 797 | fprintf(stderr, "usage: nc [-46DdhklnrStUuvz] [-i interval] [-p source_port]\n"); |
793 | fprintf(stderr, "\t [-s source_ip_address] [-w timeout] [-X socks_version]\n"); | 798 | fprintf(stderr, "\t [-s source_ip_address] [-w timeout] [-X proxy_version]\n"); |
794 | fprintf(stderr, "\t [-x proxy_address[:port]] [hostname] [port[s]]\n"); | 799 | fprintf(stderr, "\t [-x proxy_address[:port]] [hostname] [port[s]]\n"); |
795 | if (ret) | 800 | if (ret) |
796 | exit(1); | 801 | exit(1); |
diff --git a/src/usr.bin/nc/socks.c b/src/usr.bin/nc/socks.c index a6b4fdd7e3..e7d35b601a 100644 --- a/src/usr.bin/nc/socks.c +++ b/src/usr.bin/nc/socks.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: socks.c,v 1.8 2003/07/07 21:36:23 deraadt Exp $ */ | 1 | /* $OpenBSD: socks.c,v 1.9 2004/10/17 03:13:55 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. | 4 | * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. |
@@ -30,6 +30,7 @@ | |||
30 | #include <arpa/inet.h> | 30 | #include <arpa/inet.h> |
31 | 31 | ||
32 | #include <err.h> | 32 | #include <err.h> |
33 | #include <errno.h> | ||
33 | #include <netdb.h> | 34 | #include <netdb.h> |
34 | #include <stdio.h> | 35 | #include <stdio.h> |
35 | #include <stdlib.h> | 36 | #include <stdlib.h> |
@@ -37,13 +38,15 @@ | |||
37 | #include <unistd.h> | 38 | #include <unistd.h> |
38 | 39 | ||
39 | #define SOCKS_PORT "1080" | 40 | #define SOCKS_PORT "1080" |
41 | #define HTTP_PROXY_PORT "3128" | ||
42 | #define HTTP_MAXHDRS 64 | ||
40 | #define SOCKS_V5 5 | 43 | #define SOCKS_V5 5 |
41 | #define SOCKS_V4 4 | 44 | #define SOCKS_V4 4 |
42 | #define SOCKS_NOAUTH 0 | 45 | #define SOCKS_NOAUTH 0 |
43 | #define SOCKS_NOMETHOD 0xff | 46 | #define SOCKS_NOMETHOD 0xff |
44 | #define SOCKS_CONNECT 1 | 47 | #define SOCKS_CONNECT 1 |
45 | #define SOCKS_IPV4 1 | 48 | #define SOCKS_IPV4 1 |
46 | #define SOCKS_MAXCMDSZ 10 | 49 | |
47 | 50 | ||
48 | int remote_connect(char *, char *, struct addrinfo); | 51 | int remote_connect(char *, char *, struct addrinfo); |
49 | int socks_connect(char *host, char *port, struct addrinfo hints, | 52 | int socks_connect(char *host, char *port, struct addrinfo hints, |
@@ -81,21 +84,46 @@ decode_port(const char *s) | |||
81 | errx (1, "cannot decode port \"%s\"", s); | 84 | errx (1, "cannot decode port \"%s\"", s); |
82 | } | 85 | } |
83 | 86 | ||
87 | static int | ||
88 | proxy_read_line(int fd, char *buf, int bufsz) | ||
89 | { | ||
90 | int r, off; | ||
91 | |||
92 | for(off = 0;;) { | ||
93 | if (off >= bufsz) | ||
94 | errx(1, "proxy read too long"); | ||
95 | if ((r = read(fd, buf + off, 1)) <= 0) { | ||
96 | if (r == -1 && errno == EINTR) | ||
97 | continue; | ||
98 | err(1, "proxy read"); | ||
99 | } | ||
100 | /* Skip CR */ | ||
101 | if (buf[off] == '\r') | ||
102 | continue; | ||
103 | if (buf[off] == '\n') { | ||
104 | buf[off] = '\0'; | ||
105 | break; | ||
106 | } | ||
107 | off++; | ||
108 | } | ||
109 | return (off); | ||
110 | } | ||
111 | |||
84 | int | 112 | int |
85 | socks_connect(char *host, char *port, struct addrinfo hints, | 113 | socks_connect(char *host, char *port, struct addrinfo hints, |
86 | char *proxyhost, char *proxyport, struct addrinfo proxyhints, | 114 | char *proxyhost, char *proxyport, struct addrinfo proxyhints, |
87 | int socksv) | 115 | int socksv) |
88 | { | 116 | { |
89 | int proxyfd; | 117 | int proxyfd, r; |
90 | unsigned char buf[SOCKS_MAXCMDSZ]; | 118 | unsigned char buf[1024]; |
91 | ssize_t cnt; | 119 | ssize_t cnt; |
92 | in_addr_t serveraddr; | 120 | in_addr_t serveraddr; |
93 | in_port_t serverport; | 121 | in_port_t serverport; |
94 | 122 | ||
95 | if (proxyport) | 123 | if (proxyport == NULL) |
96 | proxyfd = remote_connect(proxyhost, proxyport, proxyhints); | 124 | proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; |
97 | else | 125 | |
98 | proxyfd = remote_connect(proxyhost, SOCKS_PORT, proxyhints); | 126 | proxyfd = remote_connect(proxyhost, proxyport, proxyhints); |
99 | 127 | ||
100 | if (proxyfd < 0) | 128 | if (proxyfd < 0) |
101 | return -1; | 129 | return -1; |
@@ -141,7 +169,7 @@ socks_connect(char *host, char *port, struct addrinfo hints, | |||
141 | errx (1, "unexpected reply size %d (expected 10)", cnt); | 169 | errx (1, "unexpected reply size %d (expected 10)", cnt); |
142 | if (buf[1] != 0) | 170 | if (buf[1] != 0) |
143 | errx (1, "connection failed, SOCKS error %d", buf[1]); | 171 | errx (1, "connection failed, SOCKS error %d", buf[1]); |
144 | } else { | 172 | } else if (socksv == 4) { |
145 | /* Version 4 */ | 173 | /* Version 4 */ |
146 | buf[0] = SOCKS_V4; | 174 | buf[0] = SOCKS_V4; |
147 | buf[1] = SOCKS_CONNECT; /* connect */ | 175 | buf[1] = SOCKS_CONNECT; /* connect */ |
@@ -163,7 +191,45 @@ socks_connect(char *host, char *port, struct addrinfo hints, | |||
163 | errx (1, "unexpected reply size %d (expected 8)", cnt); | 191 | errx (1, "unexpected reply size %d (expected 8)", cnt); |
164 | if (buf[1] != 90) | 192 | if (buf[1] != 90) |
165 | errx (1, "connection failed, SOCKS error %d", buf[1]); | 193 | errx (1, "connection failed, SOCKS error %d", buf[1]); |
166 | } | 194 | } else if (socksv == -1) { |
195 | /* HTTP proxy CONNECT */ | ||
196 | |||
197 | /* Disallow bad chars in hostname */ | ||
198 | if (strcspn(host, "\r\n\t []:") != strlen(host)) | ||
199 | errx (1, "Invalid hostname"); | ||
200 | |||
201 | /* Try to be sane about numeric IPv6 addresses */ | ||
202 | if (strchr(host, ':') != NULL) { | ||
203 | r = snprintf(buf, sizeof(buf), | ||
204 | "CONNECT [%s]:%d HTTP/1.0\r\n\r\n", | ||
205 | host, ntohs(serverport)); | ||
206 | } else { | ||
207 | r = snprintf(buf, sizeof(buf), | ||
208 | "CONNECT %s:%d HTTP/1.0\r\n\r\n", | ||
209 | host, ntohs(serverport)); | ||
210 | } | ||
211 | if (r == -1 || r >= sizeof(buf)) | ||
212 | errx (1, "hostname too long"); | ||
213 | r = strlen(buf); | ||
214 | |||
215 | /* XXX atomicio */ | ||
216 | cnt = write (proxyfd, buf, r); | ||
217 | if (cnt == -1) | ||
218 | err (1, "write failed"); | ||
219 | if (cnt != r) | ||
220 | errx (1, "short write, %d (expected %d)", cnt, r); | ||
221 | |||
222 | /* Read reply */ | ||
223 | for (r = 0; r < HTTP_MAXHDRS; r++) { | ||
224 | proxy_read_line(proxyfd, buf, sizeof(buf)); | ||
225 | if (r == 0 && strncmp(buf, "HTTP/1.0 200 ", 12) != 0) | ||
226 | errx (1, "Proxy error: \"%s\"", buf); | ||
227 | /* Discard headers until we hit an empty line */ | ||
228 | if (*buf == '\0') | ||
229 | break; | ||
230 | } | ||
231 | } else | ||
232 | errx (1, "Unknown proxy protocol %d", socksv); | ||
167 | 233 | ||
168 | return proxyfd; | 234 | return proxyfd; |
169 | } | 235 | } |