03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk/* $OpenBSD: socks.c,v 1.17 2006/09/25 04:51:20 ray Exp $ */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Copyright (c) 2004, 2005 Damien Miller. All rights reserved.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Redistribution and use in source and binary forms, with or without
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * modification, are permitted provided that the following conditions
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * are met:
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * 1. Redistributions of source code must retain the above copyright
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * notice, this list of conditions and the following disclaimer.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * 2. Redistributions in binary form must reproduce the above copyright
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * notice, this list of conditions and the following disclaimer in the
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * documentation and/or other materials provided with the distribution.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk#pragma ident "%Z%%M% %I% %E% SMI"
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkint remote_connect(const char *, const char *, struct addrinfo);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkint socks_connect(const char *, const char *,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk const char *, const char *, struct addrinfo, int,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk const char *);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Convert string representation of host (h) and service/port (p) into
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * sockaddr structure and return 0 on success, -1 on failure.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Indicate whether the host address is IPv4 (v4only) and numeric.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkdecode_addrport(const char *h, const char *p, struct sockaddr *addr,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Don't fatal when attempting to convert a numeric address */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (r != 0) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (0);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Read single line from a descriptor into buffer up to bufsz bytes,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * byte by byte. Returns length of the line (including ending NULL),
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * exits upon failure.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk for (off = 0; ; ) {
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Skip CR */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * we rewite \r\n to NULL since socks_connect() relies
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * on *buf being zero in that case.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * Read proxy password from user and return it. The arguments are used
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * only for prompt construction.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkstatic const char *
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vkgetproxypass(const char *proxyuser, const char *proxyhost)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) snprintf(prompt, sizeof (prompt), "Proxy password for %s@%s: ",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (pw);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk/* perform connection via proxy using SOCKSv[45] or HTTP proxy CONNECT */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vksocks_connect(const char *host, const char *port, const char *proxyhost,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk const char *proxyport, struct addrinfo proxyhints, int socksv,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk const char *proxyuser)
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT;
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Abuse API to lookup port */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk proxyfd = remote_connect(proxyhost, proxyport, proxyhints);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk return (-1);
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk if (decode_addrport(host, port, (struct sockaddr *)&addr,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Version 5, one method: no authentication */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Version 5, connect: domain name */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Max domain name length is 255 bytes */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Version 5, connect: IPv4 address */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Version 5, connect: IPv6 address */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * read proxy reply which is 4 byte "header", BND.ADDR
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * and BND.PORT according to RFC 1928, section 6. BND.ADDR
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * is 4 bytes in case of IPv4 which gives us 10 bytes in sum.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* This will exit on lookup failure */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) decode_addrport(host, port, (struct sockaddr *)&addr,
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Version 4 */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) memcpy(buf + 2, &in4->sin_port, sizeof (in4->sin_port));
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk (void) memcpy(buf + 4, &in4->sin_addr, sizeof (in4->sin_addr));
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * SOCKSv4 proxy replies consists of 2 byte "header",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk * port number and numeric IPv4 address which gives 8 bytes.
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* HTTP proxy CONNECT according to RFC 2817, section 5 */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Disallow bad chars in hostname */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Try to be sane about numeric IPv6 addresses */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "CONNECT [%s]:%d HTTP/1.0\r\n",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "CONNECT %s:%d HTTP/1.0\r\n",
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Terminate headers */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Read status reply */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk "failed\n");
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk /* Headers continue until we hit an empty line */
03100a6332bd4edc7a53091fcf7c9a7131bcdaa7vk for (r = 0; r < HTTP_MAXHDRS; r++) {