netcat.c revision 323121
1/* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */
2/*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *   notice, this list of conditions and the following disclaimer in the
13 *   documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *   derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Re-written nc(1) for OpenBSD. Original implementation by
31 * *Hobbit* <hobbit@avian.org>.
32 */
33
34#include "includes.h"
35
36#include <sys/types.h>
37#include <sys/socket.h>
38#include <sys/time.h>
39#include <sys/uio.h>
40#include <sys/un.h>
41
42#include <netinet/in.h>
43#include <netinet/tcp.h>
44#include <netinet/ip.h>
45
46#include <errno.h>
47#include <netdb.h>
48#include <stdarg.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53#include <fcntl.h>
54#include <limits.h>
55#include "atomicio.h"
56
57#ifdef HAVE_POLL_H
58#include <poll.h>
59#else
60# ifdef HAVE_SYS_POLL_H
61#  include <sys/poll.h>
62# endif
63#endif
64
65/* Telnet options from arpa/telnet.h */
66#define IAC	255
67#define DONT	254
68#define DO	253
69#define WONT	252
70#define WILL	251
71
72#ifndef SUN_LEN
73#define SUN_LEN(su) \
74	(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
75#endif
76
77#define PORT_MAX	65535
78#define PORT_MAX_LEN	6
79#define UNIX_DG_TMP_SOCKET_SIZE	19
80
81#define POLL_STDIN 0
82#define POLL_NETOUT 1
83#define POLL_NETIN 2
84#define POLL_STDOUT 3
85#define BUFSIZE 16384
86
87/* Command Line Options */
88int	dflag;					/* detached, no stdin */
89int	Fflag;					/* fdpass sock to stdout */
90unsigned int iflag;				/* Interval Flag */
91int	kflag;					/* More than one connect */
92int	lflag;					/* Bind to local port */
93int	Nflag;					/* shutdown() network socket */
94int	nflag;					/* Don't do name look up */
95char   *Pflag;					/* Proxy username */
96char   *pflag;					/* Localport flag */
97int	rflag;					/* Random ports flag */
98char   *sflag;					/* Source Address */
99int	tflag;					/* Telnet Emulation */
100int	uflag;					/* UDP - Default to TCP */
101int	vflag;					/* Verbosity */
102int	xflag;					/* Socks proxy */
103int	zflag;					/* Port Scan Flag */
104int	Dflag;					/* sodebug */
105int	Iflag;					/* TCP receive buffer size */
106int	Oflag;					/* TCP send buffer size */
107int	Sflag;					/* TCP MD5 signature option */
108int	Tflag = -1;				/* IP Type of Service */
109int	rtableid = -1;
110
111int timeout = -1;
112int family = AF_UNSPEC;
113char *portlist[PORT_MAX+1];
114char *unix_dg_tmp_socket;
115
116void	atelnet(int, unsigned char *, unsigned int);
117void	build_ports(char *);
118void	help(void);
119int	local_listen(char *, char *, struct addrinfo);
120void	readwrite(int);
121void	fdpass(int nfd) __attribute__((noreturn));
122int	remote_connect(const char *, const char *, struct addrinfo);
123int	timeout_connect(int, const struct sockaddr *, socklen_t);
124int	socks_connect(const char *, const char *, struct addrinfo,
125	    const char *, const char *, struct addrinfo, int, const char *);
126int	udptest(int);
127int	unix_bind(char *);
128int	unix_connect(char *);
129int	unix_listen(char *);
130void	set_common_sockopts(int);
131int	map_tos(char *, int *);
132void	report_connect(const struct sockaddr *, socklen_t);
133void	usage(int);
134ssize_t drainbuf(int, unsigned char *, size_t *);
135ssize_t fillbuf(int, unsigned char *, size_t *);
136
137static void err(int, const char *, ...) __attribute__((format(printf, 2, 3)));
138static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3)));
139static void warn(const char *, ...) __attribute__((format(printf, 1, 2)));
140
141static void
142err(int r, const char *fmt, ...)
143{
144	va_list args;
145
146	va_start(args, fmt);
147	fprintf(stderr, "%s: ", strerror(errno));
148	vfprintf(stderr, fmt, args);
149	fputc('\n', stderr);
150	va_end(args);
151	exit(r);
152}
153
154static void
155errx(int r, const char *fmt, ...)
156{
157	va_list args;
158
159	va_start(args, fmt);
160	vfprintf(stderr, fmt, args);
161	fputc('\n', stderr);
162	va_end(args);
163	exit(r);
164}
165
166static void
167warn(const char *fmt, ...)
168{
169	va_list args;
170
171	va_start(args, fmt);
172	fprintf(stderr, "%s: ", strerror(errno));
173	vfprintf(stderr, fmt, args);
174	fputc('\n', stderr);
175	va_end(args);
176}
177
178int
179main(int argc, char *argv[])
180{
181	int ch, s, ret, socksv;
182	char *host, *uport;
183	struct addrinfo hints;
184	struct servent *sv;
185	socklen_t len;
186	struct sockaddr_storage cliaddr;
187	char *proxy = NULL;
188	const char *errstr, *proxyhost = "", *proxyport = NULL;
189	struct addrinfo proxyhints;
190	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
191
192	ret = 1;
193	s = 0;
194	socksv = 5;
195	host = NULL;
196	uport = NULL;
197	sv = NULL;
198
199	while ((ch = getopt(argc, argv,
200	    "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) {
201		switch (ch) {
202		case '4':
203			family = AF_INET;
204			break;
205		case '6':
206			family = AF_INET6;
207			break;
208		case 'U':
209			family = AF_UNIX;
210			break;
211		case 'X':
212			if (strcasecmp(optarg, "connect") == 0)
213				socksv = -1; /* HTTP proxy CONNECT */
214			else if (strcmp(optarg, "4") == 0)
215				socksv = 4; /* SOCKS v.4 */
216			else if (strcmp(optarg, "5") == 0)
217				socksv = 5; /* SOCKS v.5 */
218			else
219				errx(1, "unsupported proxy protocol");
220			break;
221		case 'd':
222			dflag = 1;
223			break;
224		case 'F':
225			Fflag = 1;
226			break;
227		case 'h':
228			help();
229			break;
230		case 'i':
231			iflag = strtonum(optarg, 0, UINT_MAX, &errstr);
232			if (errstr)
233				errx(1, "interval %s: %s", errstr, optarg);
234			break;
235		case 'k':
236			kflag = 1;
237			break;
238		case 'l':
239			lflag = 1;
240			break;
241		case 'N':
242			Nflag = 1;
243			break;
244		case 'n':
245			nflag = 1;
246			break;
247		case 'P':
248			Pflag = optarg;
249			break;
250		case 'p':
251			pflag = optarg;
252			break;
253		case 'r':
254			rflag = 1;
255			break;
256		case 's':
257			sflag = optarg;
258			break;
259		case 't':
260			tflag = 1;
261			break;
262		case 'u':
263			uflag = 1;
264			break;
265#ifdef SO_RTABLE
266		case 'V':
267			rtableid = (int)strtonum(optarg, 0,
268			    RT_TABLEID_MAX, &errstr);
269			if (errstr)
270				errx(1, "rtable %s: %s", errstr, optarg);
271			break;
272#endif
273		case 'v':
274			vflag = 1;
275			break;
276		case 'w':
277			timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr);
278			if (errstr)
279				errx(1, "timeout %s: %s", errstr, optarg);
280			timeout *= 1000;
281			break;
282		case 'x':
283			xflag = 1;
284			if ((proxy = strdup(optarg)) == NULL)
285				errx(1, "strdup");
286			break;
287		case 'z':
288			zflag = 1;
289			break;
290		case 'D':
291			Dflag = 1;
292			break;
293		case 'I':
294			Iflag = strtonum(optarg, 1, 65536 << 14, &errstr);
295			if (errstr != NULL)
296				errx(1, "TCP receive window %s: %s",
297				    errstr, optarg);
298			break;
299		case 'O':
300			Oflag = strtonum(optarg, 1, 65536 << 14, &errstr);
301			if (errstr != NULL)
302				errx(1, "TCP send window %s: %s",
303				    errstr, optarg);
304			break;
305		case 'S':
306			Sflag = 1;
307			break;
308		case 'T':
309			errstr = NULL;
310			errno = 0;
311			if (map_tos(optarg, &Tflag))
312				break;
313			if (strlen(optarg) > 1 && optarg[0] == '0' &&
314			    optarg[1] == 'x')
315				Tflag = (int)strtol(optarg, NULL, 16);
316			else
317				Tflag = (int)strtonum(optarg, 0, 255,
318				    &errstr);
319			if (Tflag < 0 || Tflag > 255 || errstr || errno)
320				errx(1, "illegal tos value %s", optarg);
321			break;
322		default:
323			usage(1);
324		}
325	}
326	argc -= optind;
327	argv += optind;
328
329	/* Cruft to make sure options are clean, and used properly. */
330	if (argv[0] && !argv[1] && family == AF_UNIX) {
331		host = argv[0];
332		uport = NULL;
333	} else if (argv[0] && !argv[1]) {
334		if  (!lflag)
335			usage(1);
336		uport = argv[0];
337		host = NULL;
338	} else if (argv[0] && argv[1]) {
339		host = argv[0];
340		uport = argv[1];
341	} else
342		usage(1);
343
344	if (lflag && sflag)
345		errx(1, "cannot use -s and -l");
346	if (lflag && pflag)
347		errx(1, "cannot use -p and -l");
348	if (lflag && zflag)
349		errx(1, "cannot use -z and -l");
350	if (!lflag && kflag)
351		errx(1, "must use -l with -k");
352
353	/* Get name of temporary socket for unix datagram client */
354	if ((family == AF_UNIX) && uflag && !lflag) {
355		if (sflag) {
356			unix_dg_tmp_socket = sflag;
357		} else {
358			strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
359				UNIX_DG_TMP_SOCKET_SIZE);
360			if (mktemp(unix_dg_tmp_socket_buf) == NULL)
361				err(1, "mktemp");
362			unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
363		}
364	}
365
366	/* Initialize addrinfo structure. */
367	if (family != AF_UNIX) {
368		memset(&hints, 0, sizeof(struct addrinfo));
369		hints.ai_family = family;
370		hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
371		hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
372		if (nflag)
373			hints.ai_flags |= AI_NUMERICHOST;
374	}
375
376	if (xflag) {
377		if (uflag)
378			errx(1, "no proxy support for UDP mode");
379
380		if (lflag)
381			errx(1, "no proxy support for listen");
382
383		if (family == AF_UNIX)
384			errx(1, "no proxy support for unix sockets");
385
386		/* XXX IPv6 transport to proxy would probably work */
387		if (family == AF_INET6)
388			errx(1, "no proxy support for IPv6");
389
390		if (sflag)
391			errx(1, "no proxy support for local source address");
392
393		proxyhost = strsep(&proxy, ":");
394		proxyport = proxy;
395
396		memset(&proxyhints, 0, sizeof(struct addrinfo));
397		proxyhints.ai_family = family;
398		proxyhints.ai_socktype = SOCK_STREAM;
399		proxyhints.ai_protocol = IPPROTO_TCP;
400		if (nflag)
401			proxyhints.ai_flags |= AI_NUMERICHOST;
402	}
403
404	if (lflag) {
405		int connfd;
406		ret = 0;
407
408		if (family == AF_UNIX) {
409			if (uflag)
410				s = unix_bind(host);
411			else
412				s = unix_listen(host);
413		}
414
415		/* Allow only one connection at a time, but stay alive. */
416		for (;;) {
417			if (family != AF_UNIX)
418				s = local_listen(host, uport, hints);
419			if (s < 0)
420				err(1, "local_listen");
421			/*
422			 * For UDP and -k, don't connect the socket, let it
423			 * receive datagrams from multiple socket pairs.
424			 */
425			if (uflag && kflag)
426				readwrite(s);
427			/*
428			 * For UDP and not -k, we will use recvfrom() initially
429			 * to wait for a caller, then use the regular functions
430			 * to talk to the caller.
431			 */
432			else if (uflag && !kflag) {
433				int rv, plen;
434				char buf[16384];
435				struct sockaddr_storage z;
436
437				len = sizeof(z);
438				plen = 2048;
439				rv = recvfrom(s, buf, plen, MSG_PEEK,
440				    (struct sockaddr *)&z, &len);
441				if (rv < 0)
442					err(1, "recvfrom");
443
444				rv = connect(s, (struct sockaddr *)&z, len);
445				if (rv < 0)
446					err(1, "connect");
447
448				if (vflag)
449					report_connect((struct sockaddr *)&z, len);
450
451				readwrite(s);
452			} else {
453				len = sizeof(cliaddr);
454				connfd = accept(s, (struct sockaddr *)&cliaddr,
455				    &len);
456				if (connfd == -1) {
457					/* For now, all errnos are fatal */
458					err(1, "accept");
459				}
460				if (vflag)
461					report_connect((struct sockaddr *)&cliaddr, len);
462
463				readwrite(connfd);
464				close(connfd);
465			}
466
467			if (family != AF_UNIX)
468				close(s);
469			else if (uflag) {
470				if (connect(s, NULL, 0) < 0)
471					err(1, "connect");
472			}
473
474			if (!kflag)
475				break;
476		}
477	} else if (family == AF_UNIX) {
478		ret = 0;
479
480		if ((s = unix_connect(host)) > 0 && !zflag) {
481			readwrite(s);
482			close(s);
483		} else
484			ret = 1;
485
486		if (uflag)
487			unlink(unix_dg_tmp_socket);
488		exit(ret);
489
490	} else {
491		int i = 0;
492
493		/* Construct the portlist[] array. */
494		build_ports(uport);
495
496		/* Cycle through portlist, connecting to each port. */
497		for (i = 0; portlist[i] != NULL; i++) {
498			if (s)
499				close(s);
500
501			if (xflag)
502				s = socks_connect(host, portlist[i], hints,
503				    proxyhost, proxyport, proxyhints, socksv,
504				    Pflag);
505			else
506				s = remote_connect(host, portlist[i], hints);
507
508			if (s < 0)
509				continue;
510
511			ret = 0;
512			if (vflag || zflag) {
513				/* For UDP, make sure we are connected. */
514				if (uflag) {
515					if (udptest(s) == -1) {
516						ret = 1;
517						continue;
518					}
519				}
520
521				/* Don't look up port if -n. */
522				if (nflag)
523					sv = NULL;
524				else {
525					sv = getservbyport(
526					    ntohs(atoi(portlist[i])),
527					    uflag ? "udp" : "tcp");
528				}
529
530				fprintf(stderr,
531				    "Connection to %s %s port [%s/%s] "
532				    "succeeded!\n", host, portlist[i],
533				    uflag ? "udp" : "tcp",
534				    sv ? sv->s_name : "*");
535			}
536			if (Fflag)
537				fdpass(s);
538			else if (!zflag)
539				readwrite(s);
540		}
541	}
542
543	if (s)
544		close(s);
545
546	exit(ret);
547}
548
549/*
550 * unix_bind()
551 * Returns a unix socket bound to the given path
552 */
553int
554unix_bind(char *path)
555{
556	struct sockaddr_un sun_sa;
557	int s;
558
559	/* Create unix domain socket. */
560	if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
561	     0)) < 0)
562		return (-1);
563
564	memset(&sun_sa, 0, sizeof(struct sockaddr_un));
565	sun_sa.sun_family = AF_UNIX;
566
567	if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >=
568	    sizeof(sun_sa.sun_path)) {
569		close(s);
570		errno = ENAMETOOLONG;
571		return (-1);
572	}
573
574	if (bind(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) {
575		close(s);
576		return (-1);
577	}
578	return (s);
579}
580
581/*
582 * unix_connect()
583 * Returns a socket connected to a local unix socket. Returns -1 on failure.
584 */
585int
586unix_connect(char *path)
587{
588	struct sockaddr_un sun_sa;
589	int s;
590
591	if (uflag) {
592		if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
593			return (-1);
594	} else {
595		if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
596			return (-1);
597	}
598	(void)fcntl(s, F_SETFD, FD_CLOEXEC);
599
600	memset(&sun_sa, 0, sizeof(struct sockaddr_un));
601	sun_sa.sun_family = AF_UNIX;
602
603	if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >=
604	    sizeof(sun_sa.sun_path)) {
605		close(s);
606		errno = ENAMETOOLONG;
607		return (-1);
608	}
609	if (connect(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) {
610		close(s);
611		return (-1);
612	}
613	return (s);
614
615}
616
617/*
618 * unix_listen()
619 * Create a unix domain socket, and listen on it.
620 */
621int
622unix_listen(char *path)
623{
624	int s;
625	if ((s = unix_bind(path)) < 0)
626		return (-1);
627
628	if (listen(s, 5) < 0) {
629		close(s);
630		return (-1);
631	}
632	return (s);
633}
634
635/*
636 * remote_connect()
637 * Returns a socket connected to a remote host. Properly binds to a local
638 * port or source address if needed. Returns -1 on failure.
639 */
640int
641remote_connect(const char *host, const char *port, struct addrinfo hints)
642{
643	struct addrinfo *res, *res0;
644	int s, error;
645#if defined(SO_RTABLE) || defined(SO_BINDANY)
646	int on = 1;
647#endif
648
649	if ((error = getaddrinfo(host, port, &hints, &res)))
650		errx(1, "getaddrinfo: %s", gai_strerror(error));
651
652	res0 = res;
653	do {
654		if ((s = socket(res0->ai_family, res0->ai_socktype,
655		    res0->ai_protocol)) < 0)
656			continue;
657
658#ifdef SO_RTABLE
659		if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE,
660		    &rtableid, sizeof(rtableid)) == -1))
661			err(1, "setsockopt SO_RTABLE");
662#endif
663		/* Bind to a local port or source address if specified. */
664		if (sflag || pflag) {
665			struct addrinfo ahints, *ares;
666
667#ifdef SO_BINDANY
668			/* try SO_BINDANY, but don't insist */
669			setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on));
670#endif
671			memset(&ahints, 0, sizeof(struct addrinfo));
672			ahints.ai_family = res0->ai_family;
673			ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
674			ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
675			ahints.ai_flags = AI_PASSIVE;
676			if ((error = getaddrinfo(sflag, pflag, &ahints, &ares)))
677				errx(1, "getaddrinfo: %s", gai_strerror(error));
678
679			if (bind(s, (struct sockaddr *)ares->ai_addr,
680			    ares->ai_addrlen) < 0)
681				err(1, "bind failed");
682			freeaddrinfo(ares);
683		}
684
685		set_common_sockopts(s);
686
687		if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
688			break;
689		else if (vflag)
690			warn("connect to %s port %s (%s) failed", host, port,
691			    uflag ? "udp" : "tcp");
692
693		close(s);
694		s = -1;
695	} while ((res0 = res0->ai_next) != NULL);
696
697	freeaddrinfo(res);
698
699	return (s);
700}
701
702int
703timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
704{
705	struct pollfd pfd;
706	socklen_t optlen;
707	int flags = 0, optval;
708	int ret;
709
710	if (timeout != -1) {
711		flags = fcntl(s, F_GETFL, 0);
712		if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1)
713			err(1, "set non-blocking mode");
714	}
715
716	if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
717		pfd.fd = s;
718		pfd.events = POLLOUT;
719		if ((ret = poll(&pfd, 1, timeout)) == 1) {
720			optlen = sizeof(optval);
721			if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
722			    &optval, &optlen)) == 0) {
723				errno = optval;
724				ret = optval == 0 ? 0 : -1;
725			}
726		} else if (ret == 0) {
727			errno = ETIMEDOUT;
728			ret = -1;
729		} else
730			err(1, "poll failed");
731	}
732
733	if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1)
734		err(1, "restoring flags");
735
736	return (ret);
737}
738
739/*
740 * local_listen()
741 * Returns a socket listening on a local port, binds to specified source
742 * address. Returns -1 on failure.
743 */
744int
745local_listen(char *host, char *port, struct addrinfo hints)
746{
747	struct addrinfo *res, *res0;
748	int s, ret, x = 1;
749	int error;
750
751	/* Allow nodename to be null. */
752	hints.ai_flags |= AI_PASSIVE;
753
754	/*
755	 * In the case of binding to a wildcard address
756	 * default to binding to an ipv4 address.
757	 */
758	if (host == NULL && hints.ai_family == AF_UNSPEC)
759		hints.ai_family = AF_INET;
760
761	if ((error = getaddrinfo(host, port, &hints, &res)))
762		errx(1, "getaddrinfo: %s", gai_strerror(error));
763
764	res0 = res;
765	do {
766		if ((s = socket(res0->ai_family, res0->ai_socktype,
767		    res0->ai_protocol)) < 0)
768			continue;
769
770#ifdef SO_RTABLE
771		if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE,
772		    &rtableid, sizeof(rtableid)) == -1))
773			err(1, "setsockopt SO_RTABLE");
774#endif
775#ifdef SO_REUSEPORT
776		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
777		if (ret == -1)
778			err(1, "setsockopt");
779#endif
780		set_common_sockopts(s);
781
782		if (bind(s, (struct sockaddr *)res0->ai_addr,
783		    res0->ai_addrlen) == 0)
784			break;
785
786		close(s);
787		s = -1;
788	} while ((res0 = res0->ai_next) != NULL);
789
790	if (!uflag && s != -1) {
791		if (listen(s, 1) < 0)
792			err(1, "listen");
793	}
794
795	freeaddrinfo(res);
796
797	return (s);
798}
799
800/*
801 * readwrite()
802 * Loop that polls on the network file descriptor and stdin.
803 */
804void
805readwrite(int net_fd)
806{
807	struct pollfd pfd[4];
808	int stdin_fd = STDIN_FILENO;
809	int stdout_fd = STDOUT_FILENO;
810	unsigned char netinbuf[BUFSIZE];
811	size_t netinbufpos = 0;
812	unsigned char stdinbuf[BUFSIZE];
813	size_t stdinbufpos = 0;
814	int n, num_fds;
815	ssize_t ret;
816
817	/* don't read from stdin if requested */
818	if (dflag)
819		stdin_fd = -1;
820
821	/* stdin */
822	pfd[POLL_STDIN].fd = stdin_fd;
823	pfd[POLL_STDIN].events = POLLIN;
824
825	/* network out */
826	pfd[POLL_NETOUT].fd = net_fd;
827	pfd[POLL_NETOUT].events = 0;
828
829	/* network in */
830	pfd[POLL_NETIN].fd = net_fd;
831	pfd[POLL_NETIN].events = POLLIN;
832
833	/* stdout */
834	pfd[POLL_STDOUT].fd = stdout_fd;
835	pfd[POLL_STDOUT].events = 0;
836
837	while (1) {
838		/* both inputs are gone, buffers are empty, we are done */
839		if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1
840		    && stdinbufpos == 0 && netinbufpos == 0) {
841			close(net_fd);
842			return;
843		}
844		/* both outputs are gone, we can't continue */
845		if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
846			close(net_fd);
847			return;
848		}
849		/* listen and net in gone, queues empty, done */
850		if (lflag && pfd[POLL_NETIN].fd == -1
851		    && stdinbufpos == 0 && netinbufpos == 0) {
852			close(net_fd);
853			return;
854		}
855
856		/* help says -i is for "wait between lines sent". We read and
857		 * write arbitrary amounts of data, and we don't want to start
858		 * scanning for newlines, so this is as good as it gets */
859		if (iflag)
860			sleep(iflag);
861
862		/* poll */
863		num_fds = poll(pfd, 4, timeout);
864
865		/* treat poll errors */
866		if (num_fds == -1) {
867			close(net_fd);
868			err(1, "polling error");
869		}
870
871		/* timeout happened */
872		if (num_fds == 0)
873			return;
874
875		/* treat socket error conditions */
876		for (n = 0; n < 4; n++) {
877			if (pfd[n].revents & (POLLERR|POLLNVAL)) {
878				pfd[n].fd = -1;
879			}
880		}
881		/* reading is possible after HUP */
882		if (pfd[POLL_STDIN].events & POLLIN &&
883		    pfd[POLL_STDIN].revents & POLLHUP &&
884		    ! (pfd[POLL_STDIN].revents & POLLIN))
885				pfd[POLL_STDIN].fd = -1;
886
887		if (pfd[POLL_NETIN].events & POLLIN &&
888		    pfd[POLL_NETIN].revents & POLLHUP &&
889		    ! (pfd[POLL_NETIN].revents & POLLIN))
890				pfd[POLL_NETIN].fd = -1;
891
892		if (pfd[POLL_NETOUT].revents & POLLHUP) {
893			if (Nflag)
894				shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
895			pfd[POLL_NETOUT].fd = -1;
896		}
897		/* if HUP, stop watching stdout */
898		if (pfd[POLL_STDOUT].revents & POLLHUP)
899			pfd[POLL_STDOUT].fd = -1;
900		/* if no net out, stop watching stdin */
901		if (pfd[POLL_NETOUT].fd == -1)
902			pfd[POLL_STDIN].fd = -1;
903		/* if no stdout, stop watching net in */
904		if (pfd[POLL_STDOUT].fd == -1) {
905			if (pfd[POLL_NETIN].fd != -1)
906				shutdown(pfd[POLL_NETIN].fd, SHUT_RD);
907			pfd[POLL_NETIN].fd = -1;
908		}
909
910		/* try to read from stdin */
911		if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) {
912			ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf,
913			    &stdinbufpos);
914			/* error or eof on stdin - remove from pfd */
915			if (ret == 0 || ret == -1)
916				pfd[POLL_STDIN].fd = -1;
917			/* read something - poll net out */
918			if (stdinbufpos > 0)
919				pfd[POLL_NETOUT].events = POLLOUT;
920			/* filled buffer - remove self from polling */
921			if (stdinbufpos == BUFSIZE)
922				pfd[POLL_STDIN].events = 0;
923		}
924		/* try to write to network */
925		if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
926			ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
927			    &stdinbufpos);
928			if (ret == -1)
929				pfd[POLL_NETOUT].fd = -1;
930			/* buffer empty - remove self from polling */
931			if (stdinbufpos == 0)
932				pfd[POLL_NETOUT].events = 0;
933			/* buffer no longer full - poll stdin again */
934			if (stdinbufpos < BUFSIZE)
935				pfd[POLL_STDIN].events = POLLIN;
936		}
937		/* try to read from network */
938		if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) {
939			ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf,
940			    &netinbufpos);
941			if (ret == -1)
942				pfd[POLL_NETIN].fd = -1;
943			/* eof on net in - remove from pfd */
944			if (ret == 0) {
945				shutdown(pfd[POLL_NETIN].fd, SHUT_RD);
946				pfd[POLL_NETIN].fd = -1;
947			}
948			/* read something - poll stdout */
949			if (netinbufpos > 0)
950				pfd[POLL_STDOUT].events = POLLOUT;
951			/* filled buffer - remove self from polling */
952			if (netinbufpos == BUFSIZE)
953				pfd[POLL_NETIN].events = 0;
954			/* handle telnet */
955			if (tflag)
956				atelnet(pfd[POLL_NETIN].fd, netinbuf,
957				    netinbufpos);
958		}
959		/* try to write to stdout */
960		if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
961			ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
962			    &netinbufpos);
963			if (ret == -1)
964				pfd[POLL_STDOUT].fd = -1;
965			/* buffer empty - remove self from polling */
966			if (netinbufpos == 0)
967				pfd[POLL_STDOUT].events = 0;
968			/* buffer no longer full - poll net in again */
969			if (netinbufpos < BUFSIZE)
970				pfd[POLL_NETIN].events = POLLIN;
971		}
972
973		/* stdin gone and queue empty? */
974		if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) {
975			if (pfd[POLL_NETOUT].fd != -1 && Nflag)
976				shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
977			pfd[POLL_NETOUT].fd = -1;
978		}
979		/* net in gone and queue empty? */
980		if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) {
981			pfd[POLL_STDOUT].fd = -1;
982		}
983	}
984}
985
986ssize_t
987drainbuf(int fd, unsigned char *buf, size_t *bufpos)
988{
989	ssize_t n;
990	ssize_t adjust;
991
992	n = write(fd, buf, *bufpos);
993	/* don't treat EAGAIN, EINTR as error */
994	if (n == -1 && (errno == EAGAIN || errno == EINTR))
995		n = -2;
996	if (n <= 0)
997		return n;
998	/* adjust buffer */
999	adjust = *bufpos - n;
1000	if (adjust > 0)
1001		memmove(buf, buf + n, adjust);
1002	*bufpos -= n;
1003	return n;
1004}
1005
1006
1007ssize_t
1008fillbuf(int fd, unsigned char *buf, size_t *bufpos)
1009{
1010	size_t num = BUFSIZE - *bufpos;
1011	ssize_t n;
1012
1013	n = read(fd, buf + *bufpos, num);
1014	/* don't treat EAGAIN, EINTR as error */
1015	if (n == -1 && (errno == EAGAIN || errno == EINTR))
1016		n = -2;
1017	if (n <= 0)
1018		return n;
1019	*bufpos += n;
1020	return n;
1021}
1022
1023/*
1024 * fdpass()
1025 * Pass the connected file descriptor to stdout and exit.
1026 */
1027void
1028fdpass(int nfd)
1029{
1030#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
1031	struct msghdr msg;
1032#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
1033	union {
1034		struct cmsghdr hdr;
1035		char buf[CMSG_SPACE(sizeof(int))];
1036	} cmsgbuf;
1037	struct cmsghdr *cmsg;
1038#endif
1039	struct iovec vec;
1040	char ch = '\0';
1041	struct pollfd pfd;
1042	ssize_t r;
1043
1044	memset(&msg, 0, sizeof(msg));
1045#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
1046	msg.msg_accrights = (caddr_t)&nfd;
1047	msg.msg_accrightslen = sizeof(nfd);
1048#else
1049	memset(&cmsgbuf, 0, sizeof(cmsgbuf));
1050	msg.msg_control = (caddr_t)&cmsgbuf.buf;
1051	msg.msg_controllen = sizeof(cmsgbuf.buf);
1052	cmsg = CMSG_FIRSTHDR(&msg);
1053	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1054	cmsg->cmsg_level = SOL_SOCKET;
1055	cmsg->cmsg_type = SCM_RIGHTS;
1056	*(int *)CMSG_DATA(cmsg) = nfd;
1057#endif
1058
1059	vec.iov_base = &ch;
1060	vec.iov_len = 1;
1061	msg.msg_iov = &vec;
1062	msg.msg_iovlen = 1;
1063
1064	bzero(&pfd, sizeof(pfd));
1065	pfd.fd = STDOUT_FILENO;
1066	for (;;) {
1067		r = sendmsg(STDOUT_FILENO, &msg, 0);
1068		if (r == -1) {
1069			if (errno == EAGAIN || errno == EINTR) {
1070				pfd.events = POLLOUT;
1071				if (poll(&pfd, 1, -1) == -1)
1072					err(1, "poll");
1073				continue;
1074			}
1075			err(1, "sendmsg");
1076		} else if (r == -1)
1077			errx(1, "sendmsg: unexpected return value %zd", r);
1078		else
1079			break;
1080	}
1081	exit(0);
1082#else
1083	errx(1, "%s: file descriptor passing not supported", __func__);
1084#endif
1085}
1086
1087/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
1088void
1089atelnet(int nfd, unsigned char *buf, unsigned int size)
1090{
1091	unsigned char *p, *end;
1092	unsigned char obuf[4];
1093
1094	if (size < 3)
1095		return;
1096	end = buf + size - 2;
1097
1098	for (p = buf; p < end; p++) {
1099		if (*p != IAC)
1100			continue;
1101
1102		obuf[0] = IAC;
1103		p++;
1104		if ((*p == WILL) || (*p == WONT))
1105			obuf[1] = DONT;
1106		else if ((*p == DO) || (*p == DONT))
1107			obuf[1] = WONT;
1108		else
1109			continue;
1110
1111		p++;
1112		obuf[2] = *p;
1113		if (atomicio(vwrite, nfd, obuf, 3) != 3)
1114			warn("Write Error!");
1115	}
1116}
1117
1118/*
1119 * build_ports()
1120 * Build an array of ports in portlist[], listing each port
1121 * that we should try to connect to.
1122 */
1123void
1124build_ports(char *p)
1125{
1126	const char *errstr;
1127	char *n;
1128	int hi, lo, cp;
1129	int x = 0;
1130
1131	if ((n = strchr(p, '-')) != NULL) {
1132		*n = '\0';
1133		n++;
1134
1135		/* Make sure the ports are in order: lowest->highest. */
1136		hi = strtonum(n, 1, PORT_MAX, &errstr);
1137		if (errstr)
1138			errx(1, "port number %s: %s", errstr, n);
1139		lo = strtonum(p, 1, PORT_MAX, &errstr);
1140		if (errstr)
1141			errx(1, "port number %s: %s", errstr, p);
1142
1143		if (lo > hi) {
1144			cp = hi;
1145			hi = lo;
1146			lo = cp;
1147		}
1148
1149		/* Load ports sequentially. */
1150		for (cp = lo; cp <= hi; cp++) {
1151			portlist[x] = calloc(1, PORT_MAX_LEN);
1152			if (portlist[x] == NULL)
1153				errx(1, "calloc");
1154			snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
1155			x++;
1156		}
1157
1158		/* Randomly swap ports. */
1159		if (rflag) {
1160			int y;
1161			char *c;
1162
1163			for (x = 0; x <= (hi - lo); x++) {
1164				y = (arc4random() & 0xFFFF) % (hi - lo);
1165				c = portlist[x];
1166				portlist[x] = portlist[y];
1167				portlist[y] = c;
1168			}
1169		}
1170	} else {
1171		hi = strtonum(p, 1, PORT_MAX, &errstr);
1172		if (errstr)
1173			errx(1, "port number %s: %s", errstr, p);
1174		portlist[0] = strdup(p);
1175		if (portlist[0] == NULL)
1176			errx(1, "strdup");
1177	}
1178}
1179
1180/*
1181 * udptest()
1182 * Do a few writes to see if the UDP port is there.
1183 * Fails once PF state table is full.
1184 */
1185int
1186udptest(int s)
1187{
1188	int i, ret;
1189
1190	for (i = 0; i <= 3; i++) {
1191		if (write(s, "X", 1) == 1)
1192			ret = 1;
1193		else
1194			ret = -1;
1195	}
1196	return (ret);
1197}
1198
1199void
1200set_common_sockopts(int s)
1201{
1202	int x = 1;
1203
1204#ifdef TCP_MD5SIG
1205	if (Sflag) {
1206		if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG,
1207			&x, sizeof(x)) == -1)
1208			err(1, "setsockopt");
1209	}
1210#endif
1211	if (Dflag) {
1212		if (setsockopt(s, SOL_SOCKET, SO_DEBUG,
1213			&x, sizeof(x)) == -1)
1214			err(1, "setsockopt");
1215	}
1216	if (Tflag != -1) {
1217		if (setsockopt(s, IPPROTO_IP, IP_TOS,
1218		    &Tflag, sizeof(Tflag)) == -1)
1219			err(1, "set IP ToS");
1220	}
1221	if (Iflag) {
1222		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
1223		    &Iflag, sizeof(Iflag)) == -1)
1224			err(1, "set TCP receive buffer size");
1225	}
1226	if (Oflag) {
1227		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
1228		    &Oflag, sizeof(Oflag)) == -1)
1229			err(1, "set TCP send buffer size");
1230	}
1231}
1232
1233int
1234map_tos(char *s, int *val)
1235{
1236	/* DiffServ Codepoints and other TOS mappings */
1237	const struct toskeywords {
1238		const char	*keyword;
1239		int		 val;
1240	} *t, toskeywords[] = {
1241		{ "af11",		IPTOS_DSCP_AF11 },
1242		{ "af12",		IPTOS_DSCP_AF12 },
1243		{ "af13",		IPTOS_DSCP_AF13 },
1244		{ "af21",		IPTOS_DSCP_AF21 },
1245		{ "af22",		IPTOS_DSCP_AF22 },
1246		{ "af23",		IPTOS_DSCP_AF23 },
1247		{ "af31",		IPTOS_DSCP_AF31 },
1248		{ "af32",		IPTOS_DSCP_AF32 },
1249		{ "af33",		IPTOS_DSCP_AF33 },
1250		{ "af41",		IPTOS_DSCP_AF41 },
1251		{ "af42",		IPTOS_DSCP_AF42 },
1252		{ "af43",		IPTOS_DSCP_AF43 },
1253		{ "critical",		IPTOS_PREC_CRITIC_ECP },
1254		{ "cs0",		IPTOS_DSCP_CS0 },
1255		{ "cs1",		IPTOS_DSCP_CS1 },
1256		{ "cs2",		IPTOS_DSCP_CS2 },
1257		{ "cs3",		IPTOS_DSCP_CS3 },
1258		{ "cs4",		IPTOS_DSCP_CS4 },
1259		{ "cs5",		IPTOS_DSCP_CS5 },
1260		{ "cs6",		IPTOS_DSCP_CS6 },
1261		{ "cs7",		IPTOS_DSCP_CS7 },
1262		{ "ef",			IPTOS_DSCP_EF },
1263		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
1264		{ "lowdelay",		IPTOS_LOWDELAY },
1265		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
1266		{ "reliability",	IPTOS_RELIABILITY },
1267		{ "throughput",		IPTOS_THROUGHPUT },
1268		{ NULL, 		-1 },
1269	};
1270
1271	for (t = toskeywords; t->keyword != NULL; t++) {
1272		if (strcmp(s, t->keyword) == 0) {
1273			*val = t->val;
1274			return (1);
1275		}
1276	}
1277
1278	return (0);
1279}
1280
1281void
1282report_connect(const struct sockaddr *sa, socklen_t salen)
1283{
1284	char remote_host[NI_MAXHOST];
1285	char remote_port[NI_MAXSERV];
1286	int herr;
1287	int flags = NI_NUMERICSERV;
1288
1289	if (nflag)
1290		flags |= NI_NUMERICHOST;
1291
1292	if ((herr = getnameinfo(sa, salen,
1293	    remote_host, sizeof(remote_host),
1294	    remote_port, sizeof(remote_port),
1295	    flags)) != 0) {
1296		if (herr == EAI_SYSTEM)
1297			err(1, "getnameinfo");
1298		else
1299			errx(1, "getnameinfo: %s", gai_strerror(herr));
1300	}
1301
1302	fprintf(stderr,
1303	    "Connection from %s %s "
1304	    "received!\n", remote_host, remote_port);
1305}
1306
1307void
1308help(void)
1309{
1310	usage(0);
1311	fprintf(stderr, "\tCommand Summary:\n\
1312	\t-4		Use IPv4\n\
1313	\t-6		Use IPv6\n\
1314	\t-D		Enable the debug socket option\n\
1315	\t-d		Detach from stdin\n\
1316	\t-F		Pass socket fd\n\
1317	\t-h		This help text\n\
1318	\t-I length	TCP receive buffer length\n\
1319	\t-i secs\t	Delay interval for lines sent, ports scanned\n\
1320	\t-k		Keep inbound sockets open for multiple connects\n\
1321	\t-l		Listen mode, for inbound connects\n\
1322	\t-N		Shutdown the network socket after EOF on stdin\n\
1323	\t-n		Suppress name/port resolutions\n\
1324	\t-O length	TCP send buffer length\n\
1325	\t-P proxyuser\tUsername for proxy authentication\n\
1326	\t-p port\t	Specify local port for remote connects\n\
1327	\t-r		Randomize remote ports\n\
1328	\t-S		Enable the TCP MD5 signature option\n\
1329	\t-s addr\t	Local source address\n\
1330	\t-T toskeyword\tSet IP Type of Service\n\
1331	\t-t		Answer TELNET negotiation\n\
1332	\t-U		Use UNIX domain socket\n\
1333	\t-u		UDP mode\n\
1334	\t-V rtable	Specify alternate routing table\n\
1335	\t-v		Verbose\n\
1336	\t-w secs\t	Timeout for connects and final net reads\n\
1337	\t-X proto	Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
1338	\t-x addr[:port]\tSpecify proxy address and port\n\
1339	\t-z		Zero-I/O mode [used for scanning]\n\
1340	Port numbers can be individual or ranges: lo-hi [inclusive]\n");
1341	exit(1);
1342}
1343
1344void
1345usage(int ret)
1346{
1347	fprintf(stderr,
1348	    "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n"
1349	    "\t  [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n"
1350	    "\t  [-V rtable] [-w timeout] [-X proxy_protocol]\n"
1351	    "\t  [-x proxy_address[:port]] [destination] [port]\n");
1352	if (ret)
1353		exit(1);
1354}
1355
1356/* *** src/usr.bin/nc/socks.c *** */
1357
1358
1359/*	$OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $	*/
1360
1361/*
1362 * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
1363 * Copyright (c) 2004, 2005 Damien Miller.  All rights reserved.
1364 *
1365 * Redistribution and use in source and binary forms, with or without
1366 * modification, are permitted provided that the following conditions
1367 * are met:
1368 * 1. Redistributions of source code must retain the above copyright
1369 *    notice, this list of conditions and the following disclaimer.
1370 * 2. Redistributions in binary form must reproduce the above copyright
1371 *    notice, this list of conditions and the following disclaimer in the
1372 *    documentation and/or other materials provided with the distribution.
1373 *
1374 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1375 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1376 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1377 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1378 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1379 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1380 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1381 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1382 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1383 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1384 */
1385
1386#include <sys/types.h>
1387#include <sys/socket.h>
1388#include <netinet/in.h>
1389#include <arpa/inet.h>
1390
1391#include <errno.h>
1392#include <netdb.h>
1393#include <stdio.h>
1394#include <stdlib.h>
1395#include <string.h>
1396#include <unistd.h>
1397#include <resolv.h>
1398
1399#define SOCKS_PORT	"1080"
1400#define HTTP_PROXY_PORT	"3128"
1401#define HTTP_MAXHDRS	64
1402#define SOCKS_V5	5
1403#define SOCKS_V4	4
1404#define SOCKS_NOAUTH	0
1405#define SOCKS_NOMETHOD	0xff
1406#define SOCKS_CONNECT	1
1407#define SOCKS_IPV4	1
1408#define SOCKS_DOMAIN	3
1409#define SOCKS_IPV6	4
1410
1411int	remote_connect(const char *, const char *, struct addrinfo);
1412int	socks_connect(const char *, const char *, struct addrinfo,
1413	    const char *, const char *, struct addrinfo, int,
1414	    const char *);
1415
1416static int
1417decode_addrport(const char *h, const char *p, struct sockaddr *addr,
1418    socklen_t addrlen, int v4only, int numeric)
1419{
1420	int r;
1421	struct addrinfo hints, *res;
1422
1423	bzero(&hints, sizeof(hints));
1424	hints.ai_family = v4only ? PF_INET : PF_UNSPEC;
1425	hints.ai_flags = numeric ? AI_NUMERICHOST : 0;
1426	hints.ai_socktype = SOCK_STREAM;
1427	r = getaddrinfo(h, p, &hints, &res);
1428	/* Don't fatal when attempting to convert a numeric address */
1429	if (r != 0) {
1430		if (!numeric) {
1431			errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p,
1432			    gai_strerror(r));
1433		}
1434		return (-1);
1435	}
1436	if (addrlen < res->ai_addrlen) {
1437		freeaddrinfo(res);
1438		errx(1, "internal error: addrlen < res->ai_addrlen");
1439	}
1440	memcpy(addr, res->ai_addr, res->ai_addrlen);
1441	freeaddrinfo(res);
1442	return (0);
1443}
1444
1445static int
1446proxy_read_line(int fd, char *buf, size_t bufsz)
1447{
1448	size_t off;
1449
1450	for(off = 0;;) {
1451		if (off >= bufsz)
1452			errx(1, "proxy read too long");
1453		if (atomicio(read, fd, buf + off, 1) != 1)
1454			err(1, "proxy read");
1455		/* Skip CR */
1456		if (buf[off] == '\r')
1457			continue;
1458		if (buf[off] == '\n') {
1459			buf[off] = '\0';
1460			break;
1461		}
1462		off++;
1463	}
1464	return (off);
1465}
1466
1467static const char *
1468getproxypass(const char *proxyuser, const char *proxyhost)
1469{
1470	char prompt[512];
1471	static char pw[256];
1472
1473	snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ",
1474	   proxyuser, proxyhost);
1475	if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL)
1476		errx(1, "Unable to read proxy passphrase");
1477	return (pw);
1478}
1479
1480int
1481socks_connect(const char *host, const char *port,
1482    struct addrinfo hints __attribute__ ((__unused__)),
1483    const char *proxyhost, const char *proxyport, struct addrinfo proxyhints,
1484    int socksv, const char *proxyuser)
1485{
1486	int proxyfd, r, authretry = 0;
1487	size_t hlen, wlen = 0;
1488	unsigned char buf[1024];
1489	size_t cnt;
1490	struct sockaddr_storage addr;
1491	struct sockaddr_in *in4 = (struct sockaddr_in *)&addr;
1492	struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr;
1493	in_port_t serverport;
1494	const char *proxypass = NULL;
1495
1496	if (proxyport == NULL)
1497		proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT;
1498
1499	/* Abuse API to lookup port */
1500	if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr,
1501	    sizeof(addr), 1, 1) == -1)
1502		errx(1, "unknown port \"%.64s\"", port);
1503	serverport = in4->sin_port;
1504
1505 again:
1506	if (authretry++ > 3)
1507		errx(1, "Too many authentication failures");
1508
1509	proxyfd = remote_connect(proxyhost, proxyport, proxyhints);
1510
1511	if (proxyfd < 0)
1512		return (-1);
1513
1514	if (socksv == 5) {
1515		if (decode_addrport(host, port, (struct sockaddr *)&addr,
1516		    sizeof(addr), 0, 1) == -1)
1517			addr.ss_family = 0; /* used in switch below */
1518
1519		/* Version 5, one method: no authentication */
1520		buf[0] = SOCKS_V5;
1521		buf[1] = 1;
1522		buf[2] = SOCKS_NOAUTH;
1523		cnt = atomicio(vwrite, proxyfd, buf, 3);
1524		if (cnt != 3)
1525			err(1, "write failed (%zu/3)", cnt);
1526
1527		cnt = atomicio(read, proxyfd, buf, 2);
1528		if (cnt != 2)
1529			err(1, "read failed (%zu/3)", cnt);
1530
1531		if (buf[1] == SOCKS_NOMETHOD)
1532			errx(1, "authentication method negotiation failed");
1533
1534		switch (addr.ss_family) {
1535		case 0:
1536			/* Version 5, connect: domain name */
1537
1538			/* Max domain name length is 255 bytes */
1539			hlen = strlen(host);
1540			if (hlen > 255)
1541				errx(1, "host name too long for SOCKS5");
1542			buf[0] = SOCKS_V5;
1543			buf[1] = SOCKS_CONNECT;
1544			buf[2] = 0;
1545			buf[3] = SOCKS_DOMAIN;
1546			buf[4] = hlen;
1547			memcpy(buf + 5, host, hlen);
1548			memcpy(buf + 5 + hlen, &serverport, sizeof serverport);
1549			wlen = 7 + hlen;
1550			break;
1551		case AF_INET:
1552			/* Version 5, connect: IPv4 address */
1553			buf[0] = SOCKS_V5;
1554			buf[1] = SOCKS_CONNECT;
1555			buf[2] = 0;
1556			buf[3] = SOCKS_IPV4;
1557			memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
1558			memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port);
1559			wlen = 10;
1560			break;
1561		case AF_INET6:
1562			/* Version 5, connect: IPv6 address */
1563			buf[0] = SOCKS_V5;
1564			buf[1] = SOCKS_CONNECT;
1565			buf[2] = 0;
1566			buf[3] = SOCKS_IPV6;
1567			memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr);
1568			memcpy(buf + 20, &in6->sin6_port,
1569			    sizeof in6->sin6_port);
1570			wlen = 22;
1571			break;
1572		default:
1573			errx(1, "internal error: silly AF");
1574		}
1575
1576		cnt = atomicio(vwrite, proxyfd, buf, wlen);
1577		if (cnt != wlen)
1578			err(1, "write failed (%zu/%zu)", cnt, wlen);
1579
1580		cnt = atomicio(read, proxyfd, buf, 4);
1581		if (cnt != 4)
1582			err(1, "read failed (%zu/4)", cnt);
1583		if (buf[1] != 0)
1584			errx(1, "connection failed, SOCKS error %d", buf[1]);
1585		switch (buf[3]) {
1586		case SOCKS_IPV4:
1587			cnt = atomicio(read, proxyfd, buf + 4, 6);
1588			if (cnt != 6)
1589				err(1, "read failed (%zu/6)", cnt);
1590			break;
1591		case SOCKS_IPV6:
1592			cnt = atomicio(read, proxyfd, buf + 4, 18);
1593			if (cnt != 18)
1594				err(1, "read failed (%zu/18)", cnt);
1595			break;
1596		default:
1597			errx(1, "connection failed, unsupported address type");
1598		}
1599	} else if (socksv == 4) {
1600		/* This will exit on lookup failure */
1601		decode_addrport(host, port, (struct sockaddr *)&addr,
1602		    sizeof(addr), 1, 0);
1603
1604		/* Version 4 */
1605		buf[0] = SOCKS_V4;
1606		buf[1] = SOCKS_CONNECT;	/* connect */
1607		memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port);
1608		memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
1609		buf[8] = 0;	/* empty username */
1610		wlen = 9;
1611
1612		cnt = atomicio(vwrite, proxyfd, buf, wlen);
1613		if (cnt != wlen)
1614			err(1, "write failed (%zu/%zu)", cnt, wlen);
1615
1616		cnt = atomicio(read, proxyfd, buf, 8);
1617		if (cnt != 8)
1618			err(1, "read failed (%zu/8)", cnt);
1619		if (buf[1] != 90)
1620			errx(1, "connection failed, SOCKS error %d", buf[1]);
1621	} else if (socksv == -1) {
1622		/* HTTP proxy CONNECT */
1623
1624		/* Disallow bad chars in hostname */
1625		if (strcspn(host, "\r\n\t []:") != strlen(host))
1626			errx(1, "Invalid hostname");
1627
1628		/* Try to be sane about numeric IPv6 addresses */
1629		if (strchr(host, ':') != NULL) {
1630			r = snprintf(buf, sizeof(buf),
1631			    "CONNECT [%s]:%d HTTP/1.0\r\n",
1632			    host, ntohs(serverport));
1633		} else {
1634			r = snprintf(buf, sizeof(buf),
1635			    "CONNECT %s:%d HTTP/1.0\r\n",
1636			    host, ntohs(serverport));
1637		}
1638		if (r == -1 || (size_t)r >= sizeof(buf))
1639			errx(1, "hostname too long");
1640		r = strlen(buf);
1641
1642		cnt = atomicio(vwrite, proxyfd, buf, r);
1643		if (cnt != (size_t)r)
1644			err(1, "write failed (%zu/%d)", cnt, r);
1645
1646		if (authretry > 1) {
1647			char resp[1024];
1648
1649			proxypass = getproxypass(proxyuser, proxyhost);
1650			r = snprintf(buf, sizeof(buf), "%s:%s",
1651			    proxyuser, proxypass);
1652			if (r == -1 || (size_t)r >= sizeof(buf) ||
1653			    b64_ntop(buf, strlen(buf), resp,
1654			    sizeof(resp)) == -1)
1655				errx(1, "Proxy username/password too long");
1656			r = snprintf(buf, sizeof(buf), "Proxy-Authorization: "
1657			    "Basic %s\r\n", resp);
1658			if (r == -1 || (size_t)r >= sizeof(buf))
1659				errx(1, "Proxy auth response too long");
1660			r = strlen(buf);
1661			if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != (size_t)r)
1662				err(1, "write failed (%zu/%d)", cnt, r);
1663		}
1664
1665		/* Terminate headers */
1666		if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2)
1667			err(1, "write failed (2/%d)", r);
1668
1669		/* Read status reply */
1670		proxy_read_line(proxyfd, buf, sizeof(buf));
1671		if (proxyuser != NULL &&
1672		    strncmp(buf, "HTTP/1.0 407 ", 12) == 0) {
1673			if (authretry > 1) {
1674				fprintf(stderr, "Proxy authentication "
1675				    "failed\n");
1676			}
1677			close(proxyfd);
1678			goto again;
1679		} else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 &&
1680		    strncmp(buf, "HTTP/1.1 200 ", 12) != 0)
1681			errx(1, "Proxy error: \"%s\"", buf);
1682
1683		/* Headers continue until we hit an empty line */
1684		for (r = 0; r < HTTP_MAXHDRS; r++) {
1685			proxy_read_line(proxyfd, buf, sizeof(buf));
1686			if (*buf == '\0')
1687				break;
1688		}
1689		if (*buf != '\0')
1690			errx(1, "Too many proxy headers received");
1691	} else
1692		errx(1, "Unknown proxy protocol %d", socksv);
1693
1694	return (proxyfd);
1695}
1696
1697