summaryrefslogtreecommitdiff
path: root/usr.bin/nc
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2002-02-28 18:05:37 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2002-02-28 18:05:37 +0000
commit94001502c70887fff29b52695b4849f2c0de352f (patch)
treef15af4ca065dfefa7ddd20f48e6c7d999456cf75 /usr.bin/nc
parentd13a2472d32dcc740c7e57af21a6ba77c0c4fe8b (diff)
add support for SOCKS4 with option -X socks_version, default is 5; ok ericj@
Diffstat (limited to 'usr.bin/nc')
-rw-r--r--usr.bin/nc/nc.111
-rw-r--r--usr.bin/nc/netcat.c16
-rw-r--r--usr.bin/nc/socks.c106
3 files changed, 86 insertions, 47 deletions
diff --git a/usr.bin/nc/nc.1 b/usr.bin/nc/nc.1
index 5c0cc5e244c..759be26a31f 100644
--- a/usr.bin/nc/nc.1
+++ b/usr.bin/nc/nc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: nc.1,v 1.21 2002/02/19 22:45:18 ericj Exp $
+.\" $OpenBSD: nc.1,v 1.22 2002/02/28 18:05:36 markus Exp $
.\"
.\" Copyright (c) 1996 David Sacerdote
.\" All rights reserved.
@@ -39,6 +39,7 @@
.Op Fl s Ar source ip address
.Op Fl x Ar proxy address Op :port
.Op Fl w Ar timeout
+.Op Fl X Ar socks version
.Op Ar hostname
.Op Ar port[s]
.Sh DESCRIPTION
@@ -133,7 +134,7 @@ Requests that
.Nm
should connect to
.Ar hostname
-using a socks5 proxy at address and port.
+using a SOCKS proxy at address and port.
If port is not specified, port 1080 is used.
.It Fl z
Specifies that
@@ -141,6 +142,12 @@ Specifies that
should just scan for listening daemons, without sending any data to them.
.It Fl U
Specifies to use Unix Domain Sockets.
+.It Fl X Ar version
+Requests that
+.Nm
+should use the specified version of the SOCKS protocol when talking to
+a SOCKS proxy.
+If version is not specified, SOCKS version 5 is used.
.El
.Sh EXAMPLES
.Bl -tag -width x
diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c
index e3c0befef97..dc4fe9e37d4 100644
--- a/usr.bin/nc/netcat.c
+++ b/usr.bin/nc/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.45 2002/02/19 22:42:04 ericj Exp $ */
+/* $OpenBSD: netcat.c,v 1.46 2002/02/28 18:05:36 markus Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@@ -78,7 +78,7 @@ int local_listen(char *, char *, struct addrinfo);
void readwrite(int);
int remote_connect(char *, char *, struct addrinfo);
int socks_connect(char *, char *, struct addrinfo, char *, char *,
- struct addrinfo);
+ struct addrinfo, int);
int udptest(int);
int unix_connect(char *);
int unix_listen(char *);
@@ -87,7 +87,7 @@ void usage(int);
int
main(int argc, char *argv[])
{
- int ch, s, ret;
+ int ch, s, ret, socksv;
char *host, *uport, *endp;
struct addrinfo hints;
struct servent *sv;
@@ -99,12 +99,13 @@ main(int argc, char *argv[])
ret = 1;
s = 0;
+ socksv = 5;
host = NULL;
uport = NULL;
endp = NULL;
sv = NULL;
- while ((ch = getopt(argc, argv, "46Uhi:klnp:rs:tuvw:x:z")) != -1) {
+ while ((ch = getopt(argc, argv, "46UX:hi:klnp:rs:tuvw:x:z")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -115,6 +116,11 @@ main(int argc, char *argv[])
case 'U':
family = AF_UNIX;
break;
+ case 'X':
+ socksv = (int)strtoul(optarg, &endp, 10);
+ if ((socksv != 4 && socksv != 5) || *endp != '\0')
+ errx(1, "only SOCKS version 4 and 5 supported");
+ break;
case 'h':
help();
break;
@@ -306,7 +312,7 @@ main(int argc, char *argv[])
if (xflag)
s = socks_connect(host, portlist[i], hints,
- proxyhost, proxyport, proxyhints);
+ proxyhost, proxyport, proxyhints, socksv);
else
s = remote_connect(host, portlist[i], hints);
diff --git a/usr.bin/nc/socks.c b/usr.bin/nc/socks.c
index a68e36af067..af0fe29cff4 100644
--- a/usr.bin/nc/socks.c
+++ b/usr.bin/nc/socks.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: socks.c,v 1.4 2002/02/19 22:42:04 ericj Exp $ */
+/* $OpenBSD: socks.c,v 1.5 2002/02/28 18:05:36 markus Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -42,7 +42,8 @@
#include <unistd.h>
#define SOCKS_PORT "1080"
-#define SOCKS_VERSION 5
+#define SOCKS_V5 5
+#define SOCKS_V4 4
#define SOCKS_NOAUTH 0
#define SOCKS_NOMETHOD 0xff
#define SOCKS_CONNECT 1
@@ -84,7 +85,8 @@ decode_port (const char *s)
int
socks_connect (char *host, char *port, struct addrinfo hints,
- char *proxyhost, char *proxyport, struct addrinfo proxyhints)
+ char *proxyhost, char *proxyport, struct addrinfo proxyhints,
+ int socksv)
{
int proxyfd;
unsigned char buf[SOCKS_MAXCMDSZ];
@@ -103,43 +105,67 @@ socks_connect (char *host, char *port, struct addrinfo hints,
serveraddr = decode_addr (host);
serverport = decode_port (port);
- /* Version 5, one method: no authentication */
- buf[0] = SOCKS_VERSION;
- buf[1] = 1;
- buf[2] = SOCKS_NOAUTH;
- cnt = write (proxyfd, buf, 3);
- if (cnt == -1)
- err (1, "write failed");
- if (cnt != 3)
- errx (1, "short write, %d (expected 3)", cnt);
-
- read (proxyfd, buf, 2);
- if (buf[1] == SOCKS_NOMETHOD)
- errx (1, "authentication method negotiation failed");
-
- /* Version 5, connect: IPv4 address */
- buf[0] = SOCKS_VERSION;
- buf[1] = SOCKS_CONNECT;
- buf[2] = 0;
- buf[3] = SOCKS_IPV4;
- memcpy (buf + 4, &serveraddr, sizeof serveraddr);
- memcpy (buf + 8, &serverport, sizeof serverport);
-
- /* XXX Handle short writes better */
- cnt = write (proxyfd, buf, 10);
- if (cnt == -1)
- err (1, "write failed");
- if (cnt != 10)
- errx (1, "short write, %d (expected 10)", cnt);
-
- /* XXX Handle short reads better */
- cnt = read (proxyfd, buf, sizeof buf);
- if (cnt == -1)
- err (1, "read failed");
- if (cnt != 10)
- errx (1, "unexpected reply size %d (expected 10)", cnt);
- if (buf[1] != 0)
- errx (1, "connection failed, SOCKS error %d", buf[1]);
+ if (socksv == 5) {
+ /* Version 5, one method: no authentication */
+ buf[0] = SOCKS_V5;
+ buf[1] = 1;
+ buf[2] = SOCKS_NOAUTH;
+ cnt = write (proxyfd, buf, 3);
+ if (cnt == -1)
+ err (1, "write failed");
+ if (cnt != 3)
+ errx (1, "short write, %d (expected 3)", cnt);
+
+ read (proxyfd, buf, 2);
+ if (buf[1] == SOCKS_NOMETHOD)
+ errx (1, "authentication method negotiation failed");
+
+ /* Version 5, connect: IPv4 address */
+ buf[0] = SOCKS_V5;
+ buf[1] = SOCKS_CONNECT;
+ buf[2] = 0;
+ buf[3] = SOCKS_IPV4;
+ memcpy (buf + 4, &serveraddr, sizeof serveraddr);
+ memcpy (buf + 8, &serverport, sizeof serverport);
+
+ /* XXX Handle short writes better */
+ cnt = write (proxyfd, buf, 10);
+ if (cnt == -1)
+ err (1, "write failed");
+ if (cnt != 10)
+ errx (1, "short write, %d (expected 10)", cnt);
+
+ /* XXX Handle short reads better */
+ cnt = read (proxyfd, buf, sizeof buf);
+ if (cnt == -1)
+ err (1, "read failed");
+ if (cnt != 10)
+ errx (1, "unexpected reply size %d (expected 10)", cnt);
+ if (buf[1] != 0)
+ errx (1, "connection failed, SOCKS error %d", buf[1]);
+ } else {
+ /* Version 4 */
+ buf[0] = SOCKS_V4;
+ buf[1] = SOCKS_CONNECT; /* connect */
+ memcpy (buf + 2, &serverport, sizeof serverport);
+ memcpy (buf + 4, &serveraddr, sizeof serveraddr);
+ buf[8] = 0; /* empty username */
+
+ cnt = write (proxyfd, buf, 9);
+ if (cnt == -1)
+ err (1, "write failed");
+ if (cnt != 9)
+ errx (1, "short write, %d (expected 9)", cnt);
+
+ /* XXX Handle short reads better */
+ cnt = read (proxyfd, buf, 8);
+ if (cnt == -1)
+ err (1, "read failed");
+ if (cnt != 8)
+ errx (1, "unexpected reply size %d (expected 8)", cnt);
+ if (buf[1] != 90)
+ errx (1, "connection failed, SOCKS error %d", buf[1]);
+ }
return proxyfd;
}