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