/ external / libfetch / common.c
common.c
   1  /*-
   2   * SPDX-License-Identifier: BSD-3-Clause
   3   *
   4   * Copyright (c) 1998-2016 Dag-Erling Smørgrav
   5   * Copyright (c) 2013 Michael Gmelin <freebsd@grem.de>
   6   * All rights reserved.
   7   *
   8   * Redistribution and use in source and binary forms, with or without
   9   * modification, are permitted provided that the following conditions
  10   * are met:
  11   * 1. Redistributions of source code must retain the above copyright
  12   *    notice, this list of conditions and the following disclaimer
  13   *    in this position and unchanged.
  14   * 2. Redistributions in binary form must reproduce the above copyright
  15   *    notice, this list of conditions and the following disclaimer in the
  16   *    documentation and/or other materials provided with the distribution.
  17   * 3. The name of the author may not be used to endorse or promote products
  18   *    derived from this software without specific prior written permission
  19   *
  20   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  21   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  22   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  24   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  29   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30   */
  31  
  32  #include "bsd_compat.h"
  33  
  34  #include <sys/param.h>
  35  #include <sys/socket.h>
  36  #include <sys/time.h>
  37  #include <sys/uio.h>
  38  
  39  #include <netinet/in.h>
  40  
  41  #include <ctype.h>
  42  #include <errno.h>
  43  #include <fcntl.h>
  44  #include <inttypes.h>
  45  #include <netdb.h>
  46  #include <paths.h>
  47  #include <poll.h>
  48  #include <pwd.h>
  49  #include <stdarg.h>
  50  #include <stdlib.h>
  51  #include <stdio.h>
  52  #include <string.h>
  53  #include <unistd.h>
  54  
  55  #ifdef WITH_SSL
  56  #include <openssl/x509v3.h>
  57  #endif
  58  
  59  #include "fetch.h"
  60  #include "common.h"
  61  
  62  #ifndef INFTIM
  63  #define INFTIM (-1)
  64  #endif
  65  
  66  /*** Local data **************************************************************/
  67  
  68  /*
  69   * Error messages for resolver errors
  70   */
  71  static struct fetcherr netdb_errlist[] = {
  72  #ifdef EAI_ADDRFAMILY
  73  	{ EAI_ADDRFAMILY, FETCH_RESOLV, "Address family for host not supported" },
  74  #endif
  75  #ifdef EAI_NODATA
  76  	{ EAI_NODATA,	FETCH_RESOLV,	"No address for host" },
  77  #endif
  78  	{ EAI_AGAIN,	FETCH_TEMP,	"Transient resolver failure" },
  79  	{ EAI_FAIL,	FETCH_RESOLV,	"Non-recoverable resolver failure" },
  80  	{ EAI_NONAME,	FETCH_RESOLV,	"Host does not resolve" },
  81  	{ -1,		FETCH_UNKNOWN,	"Unknown resolver error" }
  82  };
  83  
  84  /*
  85   * SOCKS5 error enumerations
  86   */
  87  enum SOCKS5_ERR {
  88  /* Protocol errors */
  89  	SOCKS5_ERR_SELECTION,
  90  	SOCKS5_ERR_READ_METHOD,
  91  	SOCKS5_ERR_VER5_ONLY,
  92  	SOCKS5_ERR_NOMETHODS,
  93  	SOCKS5_ERR_NOTIMPLEMENTED,
  94  	SOCKS5_ERR_HOSTNAME_SIZE,
  95  	SOCKS5_ERR_REQUEST,
  96  	SOCKS5_ERR_REPLY,
  97  	SOCKS5_ERR_NON_VER5_RESP,
  98  	SOCKS5_ERR_GENERAL,
  99  	SOCKS5_ERR_NOT_ALLOWED,
 100  	SOCKS5_ERR_NET_UNREACHABLE,
 101  	SOCKS5_ERR_HOST_UNREACHABLE,
 102  	SOCKS5_ERR_CONN_REFUSED,
 103  	SOCKS5_ERR_TTL_EXPIRED,
 104  	SOCKS5_ERR_COM_UNSUPPORTED,
 105  	SOCKS5_ERR_ADDR_UNSUPPORTED,
 106  	SOCKS5_ERR_UNSPECIFIED,
 107  /* Configuration errors */
 108  	SOCKS5_ERR_BAD_HOST,
 109  	SOCKS5_ERR_BAD_PROXY_FORMAT,
 110  	SOCKS5_ERR_BAD_PORT
 111  };
 112  
 113  /*
 114   * Error messages for SOCKS5 errors
 115   */
 116  static struct fetcherr socks5_errlist[] = {
 117  /* SOCKS5 protocol errors */
 118  	{ SOCKS5_ERR_SELECTION,		FETCH_ABORT,	"SOCKS5: Failed to send selection method" },
 119  	{ SOCKS5_ERR_READ_METHOD,	FETCH_ABORT,	"SOCKS5: Failed to read method" },
 120  	{ SOCKS5_ERR_VER5_ONLY,		FETCH_PROTO,	"SOCKS5: Only version 5 is implemented" },
 121  	{ SOCKS5_ERR_NOMETHODS,		FETCH_PROTO,	"SOCKS5: No acceptable methods" },
 122  	{ SOCKS5_ERR_NOTIMPLEMENTED,	FETCH_PROTO,	"SOCKS5: Method currently not implemented" },
 123  	{ SOCKS5_ERR_HOSTNAME_SIZE,	FETCH_PROTO,	"SOCKS5: Hostname size is above 256 bytes" },
 124  	{ SOCKS5_ERR_REQUEST,		FETCH_PROTO,	"SOCKS5: Failed to request" },
 125  	{ SOCKS5_ERR_REPLY,		FETCH_PROTO,	"SOCKS5: Failed to receive reply" },
 126  	{ SOCKS5_ERR_NON_VER5_RESP,	FETCH_PROTO,	"SOCKS5: Server responded with a non-version 5 response" },
 127  	{ SOCKS5_ERR_GENERAL,		FETCH_ABORT,	"SOCKS5: General server failure" },
 128  	{ SOCKS5_ERR_NOT_ALLOWED,	FETCH_AUTH,	"SOCKS5: Connection not allowed by ruleset" },
 129  	{ SOCKS5_ERR_NET_UNREACHABLE,	FETCH_NETWORK,	"SOCKS5: Network unreachable" },
 130  	{ SOCKS5_ERR_HOST_UNREACHABLE,	FETCH_ABORT,	"SOCKS5: Host unreachable" },
 131  	{ SOCKS5_ERR_CONN_REFUSED,	FETCH_ABORT,	"SOCKS5: Connection refused" },
 132  	{ SOCKS5_ERR_TTL_EXPIRED,	FETCH_TIMEOUT,	"SOCKS5: TTL expired" },
 133  	{ SOCKS5_ERR_COM_UNSUPPORTED,	FETCH_PROTO,	"SOCKS5: Command not supported" },
 134  	{ SOCKS5_ERR_ADDR_UNSUPPORTED,	FETCH_ABORT,	"SOCKS5: Address type not supported" },
 135  	{ SOCKS5_ERR_UNSPECIFIED,	FETCH_UNKNOWN,	"SOCKS5: Unspecified error" },
 136  /* Configuration error */
 137  	{ SOCKS5_ERR_BAD_HOST,		FETCH_ABORT,	"SOCKS5: Bad proxy host" },
 138  	{ SOCKS5_ERR_BAD_PROXY_FORMAT,	FETCH_ABORT,	"SOCKS5: Bad proxy format" },
 139  	{ SOCKS5_ERR_BAD_PORT,		FETCH_ABORT,	"SOCKS5: Bad port" }
 140  };
 141  
 142  /* End-of-Line */
 143  static const char ENDL[2] = { '\r', '\n' };
 144  
 145  
 146  /*** Error-reporting functions ***********************************************/
 147  
 148  /*
 149   * Map error code to string
 150   */
 151  static struct fetcherr *
 152  fetch_finderr(struct fetcherr *p, int e)
 153  {
 154  	while (p->num != -1 && p->num != e)
 155  		p++;
 156  	return (p);
 157  }
 158  
 159  /*
 160   * Set error code
 161   */
 162  void
 163  fetch_seterr(struct fetcherr *p, int e)
 164  {
 165  	p = fetch_finderr(p, e);
 166  	fetchLastErrCode = p->cat;
 167  	snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string);
 168  }
 169  
 170  /*
 171   * Set error code according to errno
 172   */
 173  void
 174  fetch_syserr(void)
 175  {
 176  	switch (errno) {
 177  	case 0:
 178  		fetchLastErrCode = FETCH_OK;
 179  		break;
 180  	case EPERM:
 181  	case EACCES:
 182  	case EROFS:
 183  	case EAUTH:
 184  	case ENEEDAUTH:
 185  		fetchLastErrCode = FETCH_AUTH;
 186  		break;
 187  	case ENOENT:
 188  	case EISDIR: /* XXX */
 189  		fetchLastErrCode = FETCH_UNAVAIL;
 190  		break;
 191  	case ENOMEM:
 192  		fetchLastErrCode = FETCH_MEMORY;
 193  		break;
 194  	case EBUSY:
 195  	case EAGAIN:
 196  		fetchLastErrCode = FETCH_TEMP;
 197  		break;
 198  	case EEXIST:
 199  		fetchLastErrCode = FETCH_EXISTS;
 200  		break;
 201  	case ENOSPC:
 202  		fetchLastErrCode = FETCH_FULL;
 203  		break;
 204  	case EADDRINUSE:
 205  	case EADDRNOTAVAIL:
 206  	case ENETDOWN:
 207  	case ENETUNREACH:
 208  	case ENETRESET:
 209  	case EHOSTUNREACH:
 210  		fetchLastErrCode = FETCH_NETWORK;
 211  		break;
 212  	case ECONNABORTED:
 213  	case ECONNRESET:
 214  		fetchLastErrCode = FETCH_ABORT;
 215  		break;
 216  	case ETIMEDOUT:
 217  		fetchLastErrCode = FETCH_TIMEOUT;
 218  		break;
 219  	case ECONNREFUSED:
 220  	case EHOSTDOWN:
 221  		fetchLastErrCode = FETCH_DOWN;
 222  		break;
 223  	default:
 224  		fetchLastErrCode = FETCH_UNKNOWN;
 225  	}
 226  	snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno));
 227  }
 228  
 229  
 230  /*
 231   * Emit status message
 232   */
 233  void
 234  fetch_info(const char *fmt, ...)
 235  {
 236  	va_list ap;
 237  	int serrno = errno;
 238  
 239  	va_start(ap, fmt);
 240  	vfprintf(stderr, fmt, ap);
 241  	va_end(ap);
 242  	fputc('\n', stderr);
 243  	errno = serrno;
 244  }
 245  #define fetch_verbose(...)						\
 246  	do { if (verbose) fetch_info(__VA_ARGS__); } while (0)
 247  
 248  
 249  /*** Network-related utility functions ***************************************/
 250  
 251  /*
 252   * Return the default port for a scheme
 253   */
 254  int
 255  fetch_default_port(const char *scheme)
 256  {
 257  	struct servent *se;
 258  
 259  	if ((se = getservbyname(scheme, "tcp")) != NULL)
 260  		return (ntohs(se->s_port));
 261  	if (strcmp(scheme, SCHEME_FTP) == 0)
 262  		return (FTP_DEFAULT_PORT);
 263  	if (strcmp(scheme, SCHEME_HTTP) == 0)
 264  		return (HTTP_DEFAULT_PORT);
 265  	return (0);
 266  }
 267  
 268  /*
 269   * Return the default proxy port for a scheme
 270   */
 271  int
 272  fetch_default_proxy_port(const char *scheme)
 273  {
 274  	if (strcmp(scheme, SCHEME_FTP) == 0)
 275  		return (FTP_DEFAULT_PROXY_PORT);
 276  	if (strcmp(scheme, SCHEME_HTTP) == 0)
 277  		return (HTTP_DEFAULT_PROXY_PORT);
 278  	return (0);
 279  }
 280  
 281  
 282  /*
 283   * Create a connection for an existing descriptor.
 284   */
 285  conn_t *
 286  fetch_reopen(int sd)
 287  {
 288  	conn_t *conn;
 289  	int flags;
 290  #ifdef SO_NOSIGPIPE
 291  	int opt = 1;
 292  #endif
 293  
 294  	/* allocate and fill connection structure */
 295  	if ((conn = calloc(1, sizeof(*conn))) == NULL)
 296  		return (NULL);
 297  	flags = fcntl(sd, F_GETFD);
 298  	if (flags != -1 && (flags & FD_CLOEXEC) == 0)
 299  		(void)fcntl(sd, F_SETFD, flags | FD_CLOEXEC);
 300  	flags = fcntl(sd, F_GETFL);
 301  	if (flags != -1 && (flags & O_NONBLOCK) == 0)
 302  		(void)fcntl(sd, F_SETFL, flags | O_NONBLOCK);
 303  #ifdef SO_NOSIGPIPE
 304  	(void)setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
 305  #endif
 306  	conn->sd = sd;
 307  	++conn->ref;
 308  	return (conn);
 309  }
 310  
 311  
 312  /*
 313   * Bump a connection's reference count.
 314   */
 315  conn_t *
 316  fetch_ref(conn_t *conn)
 317  {
 318  	++conn->ref;
 319  	return (conn);
 320  }
 321  
 322  
 323  /*
 324   * Resolve an address
 325   */
 326  struct addrinfo *
 327  fetch_resolve(const char *addr, int port, int af)
 328  {
 329  	char hbuf[256], sbuf[8];
 330  	struct addrinfo hints, *res;
 331  	const char *hb, *he, *sep;
 332  	const char *host, *service;
 333  	int err, len;
 334  
 335  	/* first, check for a bracketed IPv6 address */
 336  	if (*addr == '[') {
 337  		hb = addr + 1;
 338  		if ((sep = strchr(hb, ']')) == NULL) {
 339  			errno = EINVAL;
 340  			goto syserr;
 341  		}
 342  		he = sep++;
 343  	} else {
 344  		hb = addr;
 345  		sep = strchrnul(hb, ':');
 346  		he = sep;
 347  	}
 348  
 349  	/* see if we need to copy the host name */
 350  	if (*he != '\0') {
 351  		len = snprintf(hbuf, sizeof(hbuf),
 352  		    "%.*s", (int)(he - hb), hb);
 353  		if (len < 0)
 354  			goto syserr;
 355  		if (len >= (int)sizeof(hbuf)) {
 356  			errno = ENAMETOOLONG;
 357  			goto syserr;
 358  		}
 359  		host = hbuf;
 360  	} else {
 361  		host = hb;
 362  	}
 363  
 364  	/* was it followed by a service name? */
 365  	if (*sep == '\0' && port != 0) {
 366  		if (port < 1 || port > 65535) {
 367  			errno = EINVAL;
 368  			goto syserr;
 369  		}
 370  		if (snprintf(sbuf, sizeof(sbuf), "%d", port) < 0)
 371  			goto syserr;
 372  		service = sbuf;
 373  	} else if (*sep != '\0') {
 374  		service = sep + 1;
 375  	} else {
 376  		service = NULL;
 377  	}
 378  
 379  	/* resolve */
 380  	memset(&hints, 0, sizeof(hints));
 381  	hints.ai_family = af;
 382  	hints.ai_socktype = SOCK_STREAM;
 383  	hints.ai_flags = AI_ADDRCONFIG;
 384  	if ((err = getaddrinfo(host, service, &hints, &res)) != 0) {
 385  		netdb_seterr(err);
 386  		return (NULL);
 387  	}
 388  	return (res);
 389  syserr:
 390  	fetch_syserr();
 391  	return (NULL);
 392  }
 393  
 394  
 395  /*
 396   * Bind a socket to a specific local address
 397   */
 398  int
 399  fetch_bind(int sd, int af, const char *addr)
 400  {
 401  	struct addrinfo *cliai, *ai;
 402  	int err;
 403  
 404  	if ((cliai = fetch_resolve(addr, 0, af)) == NULL)
 405  		return (-1);
 406  	for (ai = cliai; ai != NULL; ai = ai->ai_next)
 407  		if ((err = bind(sd, ai->ai_addr, ai->ai_addrlen)) == 0)
 408  			break;
 409  	if (err != 0)
 410  		fetch_syserr();
 411  	freeaddrinfo(cliai);
 412  	return (err == 0 ? 0 : -1);
 413  }
 414  
 415  
 416  /*
 417   * SOCKS5 connection initiation, based on RFC 1928
 418   * Default DNS resolution over SOCKS5
 419   */
 420  int
 421  fetch_socks5_init(conn_t *conn, const char *host, int port, int verbose)
 422  {
 423  	/*
 424  	 * Size is based on largest packet prefix (4 bytes) +
 425  	 * Largest FQDN (256) + one byte size (1) +
 426  	 * Port (2)
 427  	 */
 428  	unsigned char buf[BUFF_SIZE];
 429  	unsigned char *ptr;
 430  	int ret = 1;
 431  
 432  	fetch_verbose("Initializing SOCKS5 connection: %s:%d", host, port);
 433  
 434  	/* Connection initialization */
 435  	ptr = buf;
 436  	*ptr++ = SOCKS_VERSION_5;
 437  	*ptr++ = SOCKS_CONNECTION;
 438  	*ptr++ = SOCKS_RSV;
 439  
 440  	if (fetch_write(conn, buf, 3) != 3) {
 441  		ret = SOCKS5_ERR_SELECTION;
 442  		goto fail;
 443  	}
 444  
 445  	/* Verify response from SOCKS5 server */
 446  	if (fetch_read(conn, buf, 2) != 2) {
 447  		ret = SOCKS5_ERR_READ_METHOD;
 448  		goto fail;
 449  	}
 450  
 451  	ptr = buf;
 452  	if (ptr[0] != SOCKS_VERSION_5) {
 453  		ret = SOCKS5_ERR_VER5_ONLY;
 454  		goto fail;
 455  	}
 456  	if (ptr[1] == SOCKS_NOMETHODS) {
 457  		ret = SOCKS5_ERR_NOMETHODS;
 458  		goto fail;
 459  	}
 460  	else if (ptr[1] != SOCKS5_NOTIMPLEMENTED) {
 461  		ret = SOCKS5_ERR_NOTIMPLEMENTED;
 462  		goto fail;
 463  	}
 464  
 465  	/* Send Request */
 466  	*ptr++ = SOCKS_VERSION_5;
 467  	*ptr++ = SOCKS_CONNECTION;
 468  	*ptr++ = SOCKS_RSV;
 469  	/* Encode all targets as a hostname to avoid DNS leaks */
 470  	*ptr++ = SOCKS_ATYP_DOMAINNAME;
 471  	if (strlen(host) > FQDN_SIZE) {
 472  		ret = SOCKS5_ERR_HOSTNAME_SIZE;
 473  		goto fail;
 474  	}
 475  	*ptr++ = strlen(host);
 476  	memcpy(ptr, host, strlen(host));
 477  	ptr = ptr + strlen(host);
 478  
 479  	port = htons(port);
 480  	*ptr++ = port & 0x00ff;
 481  	*ptr++ = (port & 0xff00) >> 8;
 482  
 483  	if (fetch_write(conn, buf, ptr - buf) != ptr - buf) {
 484  		ret = SOCKS5_ERR_REQUEST;
 485  		goto fail;
 486  	}
 487  
 488  	/* BND.ADDR is variable length, read the largest on non-blocking socket */
 489  	if (!fetch_read(conn, buf, BUFF_SIZE)) {
 490  		ret = SOCKS5_ERR_REPLY;
 491  		goto fail;
 492  	}
 493  
 494  	ptr = buf;
 495  	if (*ptr++ != SOCKS_VERSION_5) {
 496  		ret = SOCKS5_ERR_NON_VER5_RESP;
 497  		goto fail;
 498  	}
 499  
 500  	switch (*ptr++) {
 501  	case SOCKS_SUCCESS:
 502  		break;
 503  	case SOCKS_GENERAL_FAILURE:
 504  		ret = SOCKS5_ERR_GENERAL;
 505  		goto fail;
 506  	case SOCKS_CONNECTION_NOT_ALLOWED:
 507  		ret = SOCKS5_ERR_NOT_ALLOWED;
 508  		goto fail;
 509  	case SOCKS_NETWORK_UNREACHABLE:
 510  		ret = SOCKS5_ERR_NET_UNREACHABLE;
 511  		goto fail;
 512  	case SOCKS_HOST_UNREACHABLE:
 513  		ret = SOCKS5_ERR_HOST_UNREACHABLE;
 514  		goto fail;
 515  	case SOCKS_CONNECTION_REFUSED:
 516  		ret = SOCKS5_ERR_CONN_REFUSED;
 517  		goto fail;
 518  	case SOCKS_TTL_EXPIRED:
 519  		ret = SOCKS5_ERR_TTL_EXPIRED;
 520  		goto fail;
 521  	case SOCKS_COMMAND_NOT_SUPPORTED:
 522  		ret = SOCKS5_ERR_COM_UNSUPPORTED;
 523  		goto fail;
 524  	case SOCKS_ADDRESS_NOT_SUPPORTED:
 525  		ret = SOCKS5_ERR_ADDR_UNSUPPORTED;
 526  		goto fail;
 527  	default:
 528  		ret = SOCKS5_ERR_UNSPECIFIED;
 529  		goto fail;
 530  	}
 531  
 532  	return (ret);
 533  
 534  fail:
 535  	socks5_seterr(ret);
 536  	return (0);
 537  }
 538  
 539  /*
 540   * Perform SOCKS5 initialization
 541   */
 542  int
 543  fetch_socks5_getenv(char **host, int *port)
 544  {
 545  	char *socks5env, *endptr, *ext;
 546  	const char *portDelim;
 547  	size_t slen;
 548  
 549  	portDelim = ":";
 550  	if ((socks5env = getenv("SOCKS5_PROXY")) == NULL || *socks5env == '\0') {
 551  		*host = NULL;
 552  		*port = -1;
 553  		return (-1);
 554  	}
 555  
 556  	/*
 557  	 * IPv6 addresses begin and end in brackets.  Set the port delimiter
 558  	 * accordingly and search for it so we can do appropriate validation.
 559  	 */
 560  	if (socks5env[0] == '[')
 561  		portDelim = "]:";
 562  
 563  	slen = strlen(socks5env);
 564  	ext = strstr(socks5env, portDelim);
 565  	if (socks5env[0] == '[') {
 566  		if (socks5env[slen - 1] == ']') {
 567  			*host = strndup(socks5env, slen);
 568  		} else if (ext != NULL) {
 569  			*host = strndup(socks5env, ext - socks5env + 1);
 570  		} else {
 571  			socks5_seterr(SOCKS5_ERR_BAD_PROXY_FORMAT);
 572  			return (0);
 573  		}
 574  	} else {
 575  		*host = strndup(socks5env, ext - socks5env);
 576  	}
 577  
 578  	if (*host == NULL)
 579  		return (-1);
 580  	if (ext == NULL) {
 581  		*port = 1080; /* Default port as defined in RFC1928 */
 582  	} else {
 583  		ext += strlen(portDelim);
 584  		errno = 0;
 585  		*port = strtoimax(ext, (char **)&endptr, 10);
 586  		if (*endptr != '\0' || errno != 0 || *port < 0 ||
 587  		    *port > 65535) {
 588  			free(*host);
 589  			*host = NULL;
 590  			socks5_seterr(SOCKS5_ERR_BAD_PORT);
 591  			return (0);
 592  		}
 593  	}
 594  
 595  	return (2);
 596  }
 597  
 598  
 599  /*
 600   * Establish a TCP connection to the specified port on the specified host.
 601   */
 602  conn_t *
 603  fetch_connect(const char *host, int port, int af, int verbose)
 604  {
 605  	struct addrinfo *cais = NULL, *sais = NULL, *cai, *sai;
 606  	const char *bindaddr;
 607  	conn_t *conn = NULL;
 608  	int err = 0, sd = -1;
 609  	char *sockshost;
 610  	int socksport;
 611  
 612  	DEBUGF("---> %s:%d\n", host, port);
 613  
 614  	/*
 615  	 * Check if SOCKS5_PROXY env variable is set.  fetch_socks5_getenv
 616  	 * will either set sockshost = NULL or allocate memory in all cases.
 617  	 */
 618  	sockshost = NULL;
 619  	if (!fetch_socks5_getenv(&sockshost, &socksport))
 620  		goto fail;
 621  
 622  	/* Not using SOCKS5 proxy */
 623  	if (sockshost == NULL) {
 624  		/* resolve server address */
 625  		fetch_verbose("resolving server address: %s:%d", host, port);
 626  		if ((sais = fetch_resolve(host, port, af)) == NULL)
 627  			goto fail;
 628  
 629  		/* resolve client address */
 630  		bindaddr = getenv("FETCH_BIND_ADDRESS");
 631  		if (bindaddr != NULL && *bindaddr != '\0') {
 632  			fetch_verbose("resolving client address: %s", bindaddr);
 633  			if ((cais = fetch_resolve(bindaddr, 0, af)) == NULL)
 634  				goto fail;
 635  		}
 636  	} else {
 637  		/* resolve socks5 proxy address */
 638  		fetch_verbose("resolving SOCKS5 server address: %s:%d",
 639  		    sockshost, socksport);
 640  		if ((sais = fetch_resolve(sockshost, socksport, af)) == NULL) {
 641  			socks5_seterr(SOCKS5_ERR_BAD_HOST);
 642  			goto fail;
 643  		}
 644  	}
 645  
 646  	/* try each server address in turn */
 647  	for (err = 0, sai = sais; sai != NULL; sai = sai->ai_next) {
 648  		/* open socket */
 649  		if ((sd = socket(sai->ai_family, SOCK_STREAM, 0)) < 0) {
 650  			err = -1;
 651  			if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
 652  				continue;
 653  			goto syserr;
 654  		}
 655  		/* attempt to bind to client address */
 656  		for (err = 0, cai = cais; cai != NULL; cai = cai->ai_next) {
 657  			if (cai->ai_family != sai->ai_family)
 658  				continue;
 659  			if ((err = bind(sd, cai->ai_addr, cai->ai_addrlen)) == 0)
 660  				break;
 661  		}
 662  		if (err != 0) {
 663  			fetch_verbose("failed to bind to %s", bindaddr);
 664  			goto syserr;
 665  		}
 666  		/* attempt to connect to server address */
 667  		while ((err = connect(sd, sai->ai_addr, sai->ai_addrlen)) < 0) {
 668  			if (errno == EINTR && fetchRestartCalls)
 669  				continue;
 670  			break;
 671  		}
 672  		/* success? */
 673  		if (err == 0)
 674  			break;
 675  		/* clean up before next attempt */
 676  		close(sd);
 677  		sd = -1;
 678  	}
 679  	if (err != 0) {
 680  		if (verbose && sockshost == NULL) {
 681  			fetch_info("failed to connect to %s:%d", host, port);
 682  			goto syserr;
 683  		} else if (sockshost != NULL) {
 684  			fetch_verbose("failed to connect to SOCKS5 server %s:%d",
 685  			    sockshost, socksport);
 686  			socks5_seterr(SOCKS5_ERR_CONN_REFUSED);
 687  			goto fail;
 688  		}
 689  		goto syserr;
 690  	}
 691  
 692  	if ((conn = fetch_reopen(sd)) == NULL)
 693  		goto syserr;
 694  
 695  	if (sockshost)
 696  		if (!fetch_socks5_init(conn, host, port, verbose))
 697  			goto fail;
 698  	free(sockshost);
 699  	if (cais != NULL)
 700  		freeaddrinfo(cais);
 701  	if (sais != NULL)
 702  		freeaddrinfo(sais);
 703  	return (conn);
 704  syserr:
 705  	fetch_syserr();
 706  fail:
 707  	free(sockshost);
 708  	/* Fully close if it was opened; otherwise just don't leak the fd. */
 709  	if (conn != NULL)
 710  		fetch_close(conn);
 711  	else if (sd >= 0)
 712  		close(sd);
 713  	if (cais != NULL)
 714  		freeaddrinfo(cais);
 715  	if (sais != NULL)
 716  		freeaddrinfo(sais);
 717  	return (NULL);
 718  }
 719  
 720  #ifdef WITH_SSL
 721  /*
 722   * Convert characters A-Z to lowercase (intentionally avoid any locale
 723   * specific conversions).
 724   */
 725  static char
 726  fetch_ssl_tolower(char in)
 727  {
 728  	if (in >= 'A' && in <= 'Z')
 729  		return (in + 32);
 730  	else
 731  		return (in);
 732  }
 733  
 734  /*
 735   * isalpha implementation that intentionally avoids any locale specific
 736   * conversions.
 737   */
 738  static int
 739  fetch_ssl_isalpha(char in)
 740  {
 741  	return ((in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z'));
 742  }
 743  
 744  /*
 745   * Check if passed hostnames a and b are equal.
 746   */
 747  static int
 748  fetch_ssl_hname_equal(const char *a, size_t alen, const char *b,
 749      size_t blen)
 750  {
 751  	size_t i;
 752  
 753  	if (alen != blen)
 754  		return (0);
 755  	for (i = 0; i < alen; ++i) {
 756  		if (fetch_ssl_tolower(a[i]) != fetch_ssl_tolower(b[i]))
 757  			return (0);
 758  	}
 759  	return (1);
 760  }
 761  
 762  /*
 763   * Check if domain label is traditional, meaning that only A-Z, a-z, 0-9
 764   * and '-' (hyphen) are allowed. Hyphens have to be surrounded by alpha-
 765   * numeric characters. Double hyphens (like they're found in IDN a-labels
 766   * 'xn--') are not allowed. Empty labels are invalid.
 767   */
 768  static int
 769  fetch_ssl_is_trad_domain_label(const char *l, size_t len, int wcok)
 770  {
 771  	size_t i;
 772  
 773  	if (!len || l[0] == '-' || l[len-1] == '-')
 774  		return (0);
 775  	for (i = 0; i < len; ++i) {
 776  		if (!isdigit(l[i]) &&
 777  		    !fetch_ssl_isalpha(l[i]) &&
 778  		    !(l[i] == '*' && wcok) &&
 779  		    !(l[i] == '-' && l[i - 1] != '-'))
 780  			return (0);
 781  	}
 782  	return (1);
 783  }
 784  
 785  /*
 786   * Check if host name consists only of numbers. This might indicate an IP
 787   * address, which is not a good idea for CN wildcard comparison.
 788   */
 789  static int
 790  fetch_ssl_hname_is_only_numbers(const char *hostname, size_t len)
 791  {
 792  	size_t i;
 793  
 794  	for (i = 0; i < len; ++i) {
 795  		if (!((hostname[i] >= '0' && hostname[i] <= '9') ||
 796  		    hostname[i] == '.'))
 797  			return (0);
 798  	}
 799  	return (1);
 800  }
 801  
 802  /*
 803   * Check if the host name h passed matches the pattern passed in m which
 804   * is usually part of subjectAltName or CN of a certificate presented to
 805   * the client. This includes wildcard matching. The algorithm is based on
 806   * RFC6125, sections 6.4.3 and 7.2, which clarifies RFC2818 and RFC3280.
 807   */
 808  static int
 809  fetch_ssl_hname_match(const char *h, size_t hlen, const char *m,
 810      size_t mlen)
 811  {
 812  	int delta, hdotidx, mdot1idx, wcidx;
 813  	const char *hdot, *mdot1, *mdot2;
 814  	const char *wc; /* wildcard */
 815  
 816  	if (!(h && *h && m && *m))
 817  		return (0);
 818  	if ((wc = strnstr(m, "*", mlen)) == NULL)
 819  		return (fetch_ssl_hname_equal(h, hlen, m, mlen));
 820  	wcidx = wc - m;
 821  	/* hostname should not be just dots and numbers */
 822  	if (fetch_ssl_hname_is_only_numbers(h, hlen))
 823  		return (0);
 824  	/* only one wildcard allowed in pattern */
 825  	if (strnstr(wc + 1, "*", mlen - wcidx - 1) != NULL)
 826  		return (0);
 827  	/*
 828  	 * there must be at least two more domain labels and
 829  	 * wildcard has to be in the leftmost label (RFC6125)
 830  	 */
 831  	mdot1 = strnstr(m, ".", mlen);
 832  	if (mdot1 == NULL || mdot1 < wc || (mlen - (mdot1 - m)) < 4)
 833  		return (0);
 834  	mdot1idx = mdot1 - m;
 835  	mdot2 = strnstr(mdot1 + 1, ".", mlen - mdot1idx - 1);
 836  	if (mdot2 == NULL || (mlen - (mdot2 - m)) < 2)
 837  		return (0);
 838  	/* hostname must contain a dot and not be the 1st char */
 839  	hdot = strnstr(h, ".", hlen);
 840  	if (hdot == NULL || hdot == h)
 841  		return (0);
 842  	hdotidx = hdot - h;
 843  	/*
 844  	 * host part of hostname must be at least as long as
 845  	 * pattern it's supposed to match
 846  	 */
 847  	if (hdotidx < mdot1idx)
 848  		return (0);
 849  	/*
 850  	 * don't allow wildcards in non-traditional domain names
 851  	 * (IDN, A-label, U-label...)
 852  	 */
 853  	if (!fetch_ssl_is_trad_domain_label(h, hdotidx, 0) ||
 854  	    !fetch_ssl_is_trad_domain_label(m, mdot1idx, 1))
 855  		return (0);
 856  	/* match domain part (part after first dot) */
 857  	if (!fetch_ssl_hname_equal(hdot, hlen - hdotidx, mdot1,
 858  	    mlen - mdot1idx))
 859  		return (0);
 860  	/* match part left of wildcard */
 861  	if (!fetch_ssl_hname_equal(h, wcidx, m, wcidx))
 862  		return (0);
 863  	/* match part right of wildcard */
 864  	delta = mdot1idx - wcidx - 1;
 865  	if (!fetch_ssl_hname_equal(hdot - delta, delta,
 866  	    mdot1 - delta, delta))
 867  		return (0);
 868  	/* all tests succeeded, it's a match */
 869  	return (1);
 870  }
 871  
 872  /*
 873   * Get numeric host address info - returns NULL if host was not an IP
 874   * address. The caller is responsible for deallocation using
 875   * freeaddrinfo(3).
 876   */
 877  static struct addrinfo *
 878  fetch_ssl_get_numeric_addrinfo(const char *hostname, size_t len)
 879  {
 880  	struct addrinfo hints, *res;
 881  	char *host;
 882  
 883  	host = (char *)malloc(len + 1);
 884  	memcpy(host, hostname, len);
 885  	host[len] = '\0';
 886  	memset(&hints, 0, sizeof(hints));
 887  	hints.ai_family = PF_UNSPEC;
 888  	hints.ai_socktype = SOCK_STREAM;
 889  	hints.ai_protocol = 0;
 890  	hints.ai_flags = AI_NUMERICHOST;
 891  	/* port is not relevant for this purpose */
 892  	if (getaddrinfo(host, "443", &hints, &res) != 0)
 893  		res = NULL;
 894  	free(host);
 895  	return res;
 896  }
 897  
 898  /*
 899   * Compare ip address in addrinfo with address passes.
 900   */
 901  static int
 902  fetch_ssl_ipaddr_match_bin(const struct addrinfo *lhost, const char *rhost,
 903      size_t rhostlen)
 904  {
 905  	const void *left;
 906  
 907  	if (lhost->ai_family == AF_INET && rhostlen == 4) {
 908  		left = (void *)&((struct sockaddr_in*)(void *)
 909  		    lhost->ai_addr)->sin_addr.s_addr;
 910  #ifdef INET6
 911  	} else if (lhost->ai_family == AF_INET6 && rhostlen == 16) {
 912  		left = (void *)&((struct sockaddr_in6 *)(void *)
 913  		    lhost->ai_addr)->sin6_addr;
 914  #endif
 915  	} else
 916  		return (0);
 917  	return (!memcmp(left, (const void *)rhost, rhostlen) ? 1 : 0);
 918  }
 919  
 920  /*
 921   * Compare ip address in addrinfo with host passed. If host is not an IP
 922   * address, comparison will fail.
 923   */
 924  static int
 925  fetch_ssl_ipaddr_match(const struct addrinfo *laddr, const char *r,
 926      size_t rlen)
 927  {
 928  	struct addrinfo *raddr;
 929  	int ret;
 930  	char *rip;
 931  
 932  	ret = 0;
 933  	if ((raddr = fetch_ssl_get_numeric_addrinfo(r, rlen)) == NULL)
 934  		return 0; /* not a numeric host */
 935  
 936  	if (laddr->ai_family == raddr->ai_family) {
 937  		if (laddr->ai_family == AF_INET) {
 938  			rip = (char *)&((struct sockaddr_in *)(void *)
 939  			    raddr->ai_addr)->sin_addr.s_addr;
 940  			ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 4);
 941  #ifdef INET6
 942  		} else if (laddr->ai_family == AF_INET6) {
 943  			rip = (char *)&((struct sockaddr_in6 *)(void *)
 944  			    raddr->ai_addr)->sin6_addr;
 945  			ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 16);
 946  #endif
 947  		}
 948  
 949  	}
 950  	freeaddrinfo(raddr);
 951  	return (ret);
 952  }
 953  
 954  /*
 955   * Verify server certificate by subjectAltName.
 956   */
 957  static int
 958  fetch_ssl_verify_altname(STACK_OF(GENERAL_NAME) *altnames,
 959      const char *host, struct addrinfo *ip)
 960  {
 961  	const GENERAL_NAME *name;
 962  	size_t nslen;
 963  	int i;
 964  	const char *ns;
 965  
 966  	for (i = 0; i < sk_GENERAL_NAME_num(altnames); ++i) {
 967  		name = sk_GENERAL_NAME_value(altnames, i);
 968  		ns = (const char *)ASN1_STRING_get0_data(name->d.ia5);
 969  		nslen = (size_t)ASN1_STRING_length(name->d.ia5);
 970  
 971  		if (name->type == GEN_DNS && ip == NULL &&
 972  		    fetch_ssl_hname_match(host, strlen(host), ns, nslen))
 973  			return (1);
 974  		else if (name->type == GEN_IPADD && ip != NULL &&
 975  		    fetch_ssl_ipaddr_match_bin(ip, ns, nslen))
 976  			return (1);
 977  	}
 978  	return (0);
 979  }
 980  
 981  /*
 982   * Verify server certificate by CN.
 983   */
 984  static int
 985  fetch_ssl_verify_cn(X509_NAME *subject, const char *host,
 986      struct addrinfo *ip)
 987  {
 988  	ASN1_STRING *namedata;
 989  	X509_NAME_ENTRY *nameentry;
 990  	int cnlen, lastpos, loc, ret;
 991  	unsigned char *cn;
 992  
 993  	ret = 0;
 994  	lastpos = -1;
 995  	loc = -1;
 996  	cn = NULL;
 997  	/* get most specific CN (last entry in list) and compare */
 998  	while ((lastpos = X509_NAME_get_index_by_NID(subject,
 999  	    NID_commonName, lastpos)) != -1)
1000  		loc = lastpos;
1001  
1002  	if (loc > -1) {
1003  		nameentry = X509_NAME_get_entry(subject, loc);
1004  		namedata = X509_NAME_ENTRY_get_data(nameentry);
1005  		cnlen = ASN1_STRING_to_UTF8(&cn, namedata);
1006  		if (ip == NULL &&
1007  		    fetch_ssl_hname_match(host, strlen(host), cn, cnlen))
1008  			ret = 1;
1009  		else if (ip != NULL && fetch_ssl_ipaddr_match(ip, cn, cnlen))
1010  			ret = 1;
1011  		OPENSSL_free(cn);
1012  	}
1013  	return (ret);
1014  }
1015  
1016  /*
1017   * Verify that server certificate subjectAltName/CN matches
1018   * hostname. First check, if there are alternative subject names. If yes,
1019   * those have to match. Only if those don't exist it falls back to
1020   * checking the subject's CN.
1021   */
1022  static int
1023  fetch_ssl_verify_hname(X509 *cert, const char *host)
1024  {
1025  	struct addrinfo *ip;
1026  	STACK_OF(GENERAL_NAME) *altnames;
1027  	X509_NAME *subject;
1028  	int ret;
1029  
1030  	ret = 0;
1031  	ip = fetch_ssl_get_numeric_addrinfo(host, strlen(host));
1032  	altnames = X509_get_ext_d2i(cert, NID_subject_alt_name,
1033  	    NULL, NULL);
1034  
1035  	if (altnames != NULL) {
1036  		ret = fetch_ssl_verify_altname(altnames, host, ip);
1037  	} else {
1038  		subject = X509_get_subject_name(cert);
1039  		if (subject != NULL)
1040  			ret = fetch_ssl_verify_cn(subject, host, ip);
1041  	}
1042  
1043  	if (ip != NULL)
1044  		freeaddrinfo(ip);
1045  	if (altnames != NULL)
1046  		GENERAL_NAMES_free(altnames);
1047  	return (ret);
1048  }
1049  
1050  /*
1051   * Configure transport security layer based on environment.
1052   */
1053  static void
1054  fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose)
1055  {
1056  	long ssl_ctx_options;
1057  
1058  	ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_SSLv3 | SSL_OP_NO_TICKET;
1059  	if (getenv("SSL_NO_TLS1") != NULL)
1060  		ssl_ctx_options |= SSL_OP_NO_TLSv1;
1061  	if (getenv("SSL_NO_TLS1_1") != NULL)
1062  		ssl_ctx_options |= SSL_OP_NO_TLSv1_1;
1063  	if (getenv("SSL_NO_TLS1_2") != NULL)
1064  		ssl_ctx_options |= SSL_OP_NO_TLSv1_2;
1065  	if (getenv("SSL_NO_TLS1_3") != NULL)
1066  		ssl_ctx_options |= SSL_OP_NO_TLSv1_3;
1067  	fetch_verbose("SSL options: %lx", ssl_ctx_options);
1068  	SSL_CTX_set_options(ctx, ssl_ctx_options);
1069  }
1070  
1071  
1072  /*
1073   * Configure peer verification based on environment.
1074   */
1075  static int
1076  fetch_ssl_setup_peer_verification(SSL_CTX *ctx, int verbose)
1077  {
1078  	X509_LOOKUP *crl_lookup;
1079  	X509_STORE *crl_store;
1080  	const char *ca_cert_file, *ca_cert_path, *crl_file;
1081  
1082  	if (getenv("SSL_NO_VERIFY_PEER") == NULL) {
1083  		ca_cert_file = getenv("SSL_CA_CERT_FILE");
1084  		ca_cert_path = getenv("SSL_CA_CERT_PATH");
1085  		if (verbose) {
1086  			fetch_info("Peer verification enabled");
1087  			if (ca_cert_file != NULL)
1088  				fetch_info("Using CA cert file: %s",
1089  				    ca_cert_file);
1090  			if (ca_cert_path != NULL)
1091  				fetch_info("Using CA cert path: %s",
1092  				    ca_cert_path);
1093  			if (ca_cert_file == NULL && ca_cert_path == NULL)
1094  				fetch_info("Using OpenSSL default "
1095  				    "CA cert file and path");
1096  		}
1097  		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER,
1098  		    fetch_ssl_cb_verify_crt);
1099  		if (ca_cert_file != NULL || ca_cert_path != NULL)
1100  			SSL_CTX_load_verify_locations(ctx, ca_cert_file,
1101  			    ca_cert_path);
1102  		else
1103  			SSL_CTX_set_default_verify_paths(ctx);
1104  		if ((crl_file = getenv("SSL_CRL_FILE")) != NULL) {
1105  			fetch_verbose("Using CRL file: %s", crl_file);
1106  			crl_store = SSL_CTX_get_cert_store(ctx);
1107  			crl_lookup = X509_STORE_add_lookup(crl_store,
1108  			    X509_LOOKUP_file());
1109  			if (crl_lookup == NULL ||
1110  			    !X509_load_crl_file(crl_lookup, crl_file,
1111  				X509_FILETYPE_PEM)) {
1112  				fetch_info("Could not load CRL file %s",
1113  				    crl_file);
1114  				return (0);
1115  			}
1116  			X509_STORE_set_flags(crl_store,
1117  			    X509_V_FLAG_CRL_CHECK |
1118  			    X509_V_FLAG_CRL_CHECK_ALL);
1119  		}
1120  	}
1121  	return (1);
1122  }
1123  
1124  /*
1125   * Configure client certificate based on environment.
1126   */
1127  static int
1128  fetch_ssl_setup_client_certificate(SSL_CTX *ctx, int verbose)
1129  {
1130  	const char *client_cert_file, *client_key_file;
1131  
1132  	if ((client_cert_file = getenv("SSL_CLIENT_CERT_FILE")) != NULL) {
1133  		client_key_file = getenv("SSL_CLIENT_KEY_FILE") != NULL ?
1134  		    getenv("SSL_CLIENT_KEY_FILE") : client_cert_file;
1135  		fetch_verbose("Using client cert file: %s", client_cert_file);
1136  		fetch_verbose("Using client key file: %s", client_key_file);
1137  		if (SSL_CTX_use_certificate_chain_file(ctx,
1138  			client_cert_file) != 1) {
1139  			fetch_info("Could not load client certificate %s",
1140  			    client_cert_file);
1141  			return (0);
1142  		}
1143  		if (SSL_CTX_use_PrivateKey_file(ctx, client_key_file,
1144  			SSL_FILETYPE_PEM) != 1) {
1145  			fetch_info("Could not load client key %s",
1146  			    client_key_file);
1147  			return (0);
1148  		}
1149  	}
1150  	return (1);
1151  }
1152  
1153  /*
1154   * Callback for SSL certificate verification, this is called on server
1155   * cert verification. It takes no decision, but informs the user in case
1156   * verification failed.
1157   */
1158  int
1159  fetch_ssl_cb_verify_crt(int verified, X509_STORE_CTX *ctx)
1160  {
1161  	X509 *crt;
1162  	X509_NAME *name;
1163  	char *str;
1164  
1165  	str = NULL;
1166  	if (!verified) {
1167  		if ((crt = X509_STORE_CTX_get_current_cert(ctx)) != NULL &&
1168  		    (name = X509_get_subject_name(crt)) != NULL)
1169  			str = X509_NAME_oneline(name, 0, 0);
1170  		fetch_info("Certificate verification failed for %s",
1171  		    str != NULL ? str : "no relevant certificate");
1172  		OPENSSL_free(str);
1173  	}
1174  	return (verified);
1175  }
1176  
1177  #endif
1178  
1179  /*
1180   * Enable SSL on a connection.
1181   */
1182  int
1183  fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
1184  {
1185  #ifdef WITH_SSL
1186  	int ret, ssl_err;
1187  	X509_NAME *name;
1188  	char *str;
1189  
1190  	if ((conn->ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) {
1191  		fetch_info("SSL context creation failed");
1192  		ERR_print_errors_fp(stderr);
1193  		return (-1);
1194  	}
1195  	SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY);
1196  
1197  	fetch_ssl_setup_transport_layer(conn->ssl_ctx, verbose);
1198  	if (!fetch_ssl_setup_peer_verification(conn->ssl_ctx, verbose))
1199  		return (-1);
1200  	if (!fetch_ssl_setup_client_certificate(conn->ssl_ctx, verbose))
1201  		return (-1);
1202  
1203  	conn->ssl = SSL_new(conn->ssl_ctx);
1204  	if (conn->ssl == NULL) {
1205  		fetch_info("SSL connection creation failed");
1206  		ERR_print_errors_fp(stderr);
1207  		return (-1);
1208  	}
1209  	SSL_set_fd(conn->ssl, conn->sd);
1210  
1211  #if !defined(OPENSSL_NO_TLSEXT)
1212  	if (!SSL_set_tlsext_host_name(conn->ssl, __DECONST(char *, URL->host))) {
1213  		fetch_info("Failed to set TLS server name indication for host %s",
1214  		    URL->host);
1215  		return (-1);
1216  	}
1217  #endif
1218  	while ((ret = SSL_connect(conn->ssl)) == -1) {
1219  		ssl_err = SSL_get_error(conn->ssl, ret);
1220  		if (ssl_err != SSL_ERROR_WANT_READ &&
1221  		    ssl_err != SSL_ERROR_WANT_WRITE) {
1222  			ERR_print_errors_fp(stderr);
1223  			return (-1);
1224  		}
1225  	}
1226  	conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);
1227  
1228  	if (conn->ssl_cert == NULL) {
1229  		fetch_info("No server SSL certificate");
1230  		return (-1);
1231  	}
1232  
1233  	if (getenv("SSL_NO_VERIFY_HOSTNAME") == NULL) {
1234  		fetch_verbose("Verify hostname");
1235  		if (!fetch_ssl_verify_hname(conn->ssl_cert, URL->host)) {
1236  			fetch_info("SSL certificate subject does not match host %s",
1237  			    URL->host);
1238  			return (-1);
1239  		}
1240  	}
1241  
1242  	if (verbose) {
1243  		fetch_info("%s connection established using %s",
1244  		    SSL_get_version(conn->ssl), SSL_get_cipher(conn->ssl));
1245  		name = X509_get_subject_name(conn->ssl_cert);
1246  		str = X509_NAME_oneline(name, 0, 0);
1247  		fetch_info("Certificate subject: %s", str);
1248  		OPENSSL_free(str);
1249  		name = X509_get_issuer_name(conn->ssl_cert);
1250  		str = X509_NAME_oneline(name, 0, 0);
1251  		fetch_info("Certificate issuer: %s", str);
1252  		OPENSSL_free(str);
1253  	}
1254  
1255  	return (0);
1256  #else
1257  	(void)conn;
1258  	(void)verbose;
1259  	(void)URL;
1260  	fetch_info("SSL support disabled");
1261  	return (-1);
1262  #endif
1263  }
1264  
1265  #define FETCH_READ_WAIT		-2
1266  #define FETCH_READ_ERROR	-1
1267  #define FETCH_READ_DONE		 0
1268  
1269  #ifdef WITH_SSL
1270  static ssize_t
1271  fetch_ssl_read(SSL *ssl, char *buf, size_t len)
1272  {
1273  	ssize_t rlen;
1274  	int ssl_err;
1275  
1276  	rlen = SSL_read(ssl, buf, len);
1277  	if (rlen < 0) {
1278  		ssl_err = SSL_get_error(ssl, rlen);
1279  		if (ssl_err == SSL_ERROR_WANT_READ ||
1280  		    ssl_err == SSL_ERROR_WANT_WRITE) {
1281  			return (FETCH_READ_WAIT);
1282  		} else {
1283  			ERR_print_errors_fp(stderr);
1284  			return (FETCH_READ_ERROR);
1285  		}
1286  	}
1287  	return (rlen);
1288  }
1289  #endif
1290  
1291  static ssize_t
1292  fetch_socket_read(int sd, char *buf, size_t len)
1293  {
1294  	ssize_t rlen;
1295  
1296  	rlen = read(sd, buf, len);
1297  	if (rlen < 0) {
1298  		if (errno == EAGAIN || (errno == EINTR && fetchRestartCalls)) {
1299  			return (FETCH_READ_WAIT);
1300  		} else {
1301  			return (FETCH_READ_ERROR);
1302  		}
1303  	}
1304  	return (rlen);
1305  }
1306  
1307  /*
1308   * Read a character from a connection w/ timeout
1309   */
1310  ssize_t
1311  fetch_read(conn_t *conn, char *buf, size_t len)
1312  {
1313  	struct timeval now, timeout, delta;
1314  	struct pollfd pfd;
1315  	ssize_t rlen;
1316  	int deltams;
1317  
1318  	if (fetchTimeout > 0) {
1319  		gettimeofday(&timeout, NULL);
1320  		timeout.tv_sec += fetchTimeout;
1321  	}
1322  
1323  	deltams = INFTIM;
1324  	memset(&pfd, 0, sizeof pfd);
1325  	pfd.fd = conn->sd;
1326  	pfd.events = POLLIN | POLLERR;
1327  
1328  	for (;;) {
1329  		/*
1330  		 * The socket is non-blocking.  Instead of the canonical
1331  		 * poll() -> read(), we do the following:
1332  		 *
1333  		 * 1) call read() or SSL_read().
1334  		 * 2) if we received some data, return it.
1335  		 * 3) if an error occurred, return -1.
1336  		 * 4) if read() or SSL_read() signaled EOF, return.
1337  		 * 5) if we did not receive any data but we're not at EOF,
1338  		 *    call poll().
1339  		 *
1340  		 * In the SSL case, this is necessary because if we
1341  		 * receive a close notification, we have to call
1342  		 * SSL_read() one additional time after we've read
1343  		 * everything we received.
1344  		 *
1345  		 * In the non-SSL case, it may improve performance (very
1346  		 * slightly) when reading small amounts of data.
1347  		 */
1348  #ifdef WITH_SSL
1349  		if (conn->ssl != NULL)
1350  			rlen = fetch_ssl_read(conn->ssl, buf, len);
1351  		else
1352  #endif
1353  			rlen = fetch_socket_read(conn->sd, buf, len);
1354  		if (rlen >= 0) {
1355  			break;
1356  		} else if (rlen == FETCH_READ_ERROR) {
1357  			fetch_syserr();
1358  			return (-1);
1359  		}
1360  		// assert(rlen == FETCH_READ_WAIT);
1361  		if (fetchTimeout > 0) {
1362  			gettimeofday(&now, NULL);
1363  			if (!timercmp(&timeout, &now, >)) {
1364  				errno = ETIMEDOUT;
1365  				fetch_syserr();
1366  				return (-1);
1367  			}
1368  			timersub(&timeout, &now, &delta);
1369  			deltams = delta.tv_sec * 1000 +
1370  			    delta.tv_usec / 1000;
1371  		}
1372  		errno = 0;
1373  		pfd.revents = 0;
1374  		if (poll(&pfd, 1, deltams) < 0) {
1375  			if (errno == EINTR && fetchRestartCalls)
1376  				continue;
1377  			fetch_syserr();
1378  			return (-1);
1379  		}
1380  	}
1381  	return (rlen);
1382  }
1383  
1384  
1385  /*
1386   * Read a line of text from a connection w/ timeout
1387   */
1388  #define MIN_BUF_SIZE 1024
1389  
1390  int
1391  fetch_getln(conn_t *conn)
1392  {
1393  	char *tmp;
1394  	size_t tmpsize;
1395  	ssize_t len;
1396  	char c;
1397  
1398  	if (conn->buf == NULL) {
1399  		if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) {
1400  			errno = ENOMEM;
1401  			return (-1);
1402  		}
1403  		conn->bufsize = MIN_BUF_SIZE;
1404  	}
1405  
1406  	conn->buf[0] = '\0';
1407  	conn->buflen = 0;
1408  
1409  	do {
1410  		len = fetch_read(conn, &c, 1);
1411  		if (len == -1)
1412  			return (-1);
1413  		if (len == 0)
1414  			break;
1415  		conn->buf[conn->buflen++] = c;
1416  		if (conn->buflen == conn->bufsize) {
1417  			tmp = conn->buf;
1418  			tmpsize = conn->bufsize * 2 + 1;
1419  			if ((tmp = realloc(tmp, tmpsize)) == NULL) {
1420  				errno = ENOMEM;
1421  				return (-1);
1422  			}
1423  			conn->buf = tmp;
1424  			conn->bufsize = tmpsize;
1425  		}
1426  	} while (c != '\n');
1427  
1428  	conn->buf[conn->buflen] = '\0';
1429  	DEBUGF("<<< %s", conn->buf);
1430  	return (0);
1431  }
1432  
1433  
1434  /*
1435   * Write to a connection w/ timeout
1436   */
1437  ssize_t
1438  fetch_write(conn_t *conn, const char *buf, size_t len)
1439  {
1440  	struct iovec iov;
1441  
1442  	iov.iov_base = __DECONST(char *, buf);
1443  	iov.iov_len = len;
1444  	return (fetch_writev(conn, &iov, 1));
1445  }
1446  
1447  /*
1448   * Write a vector to a connection w/ timeout
1449   * Note: can modify the iovec.
1450   */
1451  ssize_t
1452  fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
1453  {
1454  	struct timeval now, timeout, delta;
1455  	struct pollfd pfd;
1456  	ssize_t wlen, total;
1457  	int deltams;
1458  
1459  	memset(&pfd, 0, sizeof pfd);
1460  	if (fetchTimeout) {
1461  		pfd.fd = conn->sd;
1462  		pfd.events = POLLOUT | POLLERR;
1463  		gettimeofday(&timeout, NULL);
1464  		timeout.tv_sec += fetchTimeout;
1465  	}
1466  
1467  	total = 0;
1468  	while (iovcnt > 0) {
1469  		while (fetchTimeout && pfd.revents == 0) {
1470  			gettimeofday(&now, NULL);
1471  			if (!timercmp(&timeout, &now, >)) {
1472  				errno = ETIMEDOUT;
1473  				fetch_syserr();
1474  				return (-1);
1475  			}
1476  			timersub(&timeout, &now, &delta);
1477  			deltams = delta.tv_sec * 1000 +
1478  			    delta.tv_usec / 1000;
1479  			errno = 0;
1480  			pfd.revents = 0;
1481  			if (poll(&pfd, 1, deltams) < 0) {
1482  				/* POSIX compliance */
1483  				if (errno == EAGAIN)
1484  					continue;
1485  				if (errno == EINTR && fetchRestartCalls)
1486  					continue;
1487  				return (-1);
1488  			}
1489  		}
1490  		errno = 0;
1491  #ifdef WITH_SSL
1492  		if (conn->ssl != NULL)
1493  			wlen = SSL_write(conn->ssl,
1494  			    iov->iov_base, iov->iov_len);
1495  		else
1496  #endif
1497  			wlen = writev(conn->sd, iov, iovcnt);
1498  		if (wlen == 0) {
1499  			/* we consider a short write a failure */
1500  			/* XXX perhaps we shouldn't in the SSL case */
1501  			errno = EPIPE;
1502  			fetch_syserr();
1503  			return (-1);
1504  		}
1505  		if (wlen < 0) {
1506  			if (errno == EINTR && fetchRestartCalls)
1507  				continue;
1508  			return (-1);
1509  		}
1510  		total += wlen;
1511  		while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
1512  			wlen -= iov->iov_len;
1513  			iov++;
1514  			iovcnt--;
1515  		}
1516  		if (iovcnt > 0) {
1517  			iov->iov_len -= wlen;
1518  			iov->iov_base = __DECONST(char *, iov->iov_base) + wlen;
1519  		}
1520  	}
1521  	return (total);
1522  }
1523  
1524  
1525  /*
1526   * Write a line of text to a connection w/ timeout
1527   */
1528  int
1529  fetch_putln(conn_t *conn, const char *str, size_t len)
1530  {
1531  	struct iovec iov[2];
1532  	int ret;
1533  
1534  	DEBUGF(">>> %s\n", str);
1535  	iov[0].iov_base = __DECONST(char *, str);
1536  	iov[0].iov_len = len;
1537  	iov[1].iov_base = __DECONST(char *, ENDL);
1538  	iov[1].iov_len = sizeof(ENDL);
1539  	if (len == 0)
1540  		ret = fetch_writev(conn, &iov[1], 1);
1541  	else
1542  		ret = fetch_writev(conn, iov, 2);
1543  	if (ret == -1)
1544  		return (-1);
1545  	return (0);
1546  }
1547  
1548  
1549  /*
1550   * Close connection
1551   */
1552  int
1553  fetch_close(conn_t *conn)
1554  {
1555  	int ret;
1556  
1557  	if (--conn->ref > 0)
1558  		return (0);
1559  #ifdef WITH_SSL
1560  	if (conn->ssl) {
1561  		SSL_shutdown(conn->ssl);
1562  		SSL_set_connect_state(conn->ssl);
1563  		SSL_free(conn->ssl);
1564  		conn->ssl = NULL;
1565  	}
1566  	if (conn->ssl_ctx) {
1567  		SSL_CTX_free(conn->ssl_ctx);
1568  		conn->ssl_ctx = NULL;
1569  	}
1570  	if (conn->ssl_cert) {
1571  		X509_free(conn->ssl_cert);
1572  		conn->ssl_cert = NULL;
1573  	}
1574  #endif
1575  	ret = close(conn->sd);
1576  	free(conn->buf);
1577  	free(conn);
1578  	return (ret);
1579  }
1580  
1581  
1582  /*** Directory-related utility functions *************************************/
1583  
1584  int
1585  fetch_add_entry(struct url_ent **p, int *size, int *len,
1586      const char *name, struct url_stat *us)
1587  {
1588  	struct url_ent *tmp;
1589  
1590  	if (*p == NULL) {
1591  		*size = 0;
1592  		*len = 0;
1593  	}
1594  
1595  	if (*len >= *size - 1) {
1596  		tmp = realloc(*p, (*size * 2 + 1) * sizeof(**p));
1597  		if (tmp == NULL) {
1598  			errno = ENOMEM;
1599  			fetch_syserr();
1600  			return (-1);
1601  		}
1602  		*size = (*size * 2 + 1);
1603  		*p = tmp;
1604  	}
1605  
1606  	tmp = *p + *len;
1607  	snprintf(tmp->name, PATH_MAX, "%s", name);
1608  	memcpy(&tmp->stat, us, sizeof(*us));
1609  
1610  	(*len)++;
1611  	(++tmp)->name[0] = 0;
1612  
1613  	return (0);
1614  }
1615  
1616  
1617  /*** Authentication-related utility functions ********************************/
1618  
1619  static const char *
1620  fetch_read_word(FILE *f)
1621  {
1622  	static char word[1024];
1623  
1624  	if (fscanf(f, " %1023s ", word) != 1)
1625  		return (NULL);
1626  	return (word);
1627  }
1628  
1629  static int
1630  fetch_netrc_open(void)
1631  {
1632  	struct passwd *pwd;
1633  	char fn[PATH_MAX];
1634  	const char *p;
1635  	int fd, serrno;
1636  
1637  	if ((p = getenv("NETRC")) != NULL) {
1638  		DEBUGF("NETRC=%s\n", p);
1639  		if (snprintf(fn, sizeof(fn), "%s", p) >= (int)sizeof(fn)) {
1640  			fetch_info("$NETRC specifies a file name "
1641  			    "longer than PATH_MAX");
1642  			return (-1);
1643  		}
1644  	} else {
1645  		if ((p = getenv("HOME")) == NULL) {
1646  			if ((pwd = getpwuid(getuid())) == NULL ||
1647  			    (p = pwd->pw_dir) == NULL)
1648  				return (-1);
1649  		}
1650  		if (snprintf(fn, sizeof(fn), "%s/.netrc", p) >= (int)sizeof(fn))
1651  			return (-1);
1652  	}
1653  
1654  	if ((fd = open(fn, O_RDONLY)) < 0) {
1655  		serrno = errno;
1656  		DEBUGF("%s: %s\n", fn, strerror(serrno));
1657  		errno = serrno;
1658  	}
1659  	return (fd);
1660  }
1661  
1662  /*
1663   * Get authentication data for a URL from .netrc
1664   */
1665  int
1666  fetch_netrc_auth(struct url *url)
1667  {
1668  	const char *word;
1669  	int serrno;
1670  	FILE *f;
1671  
1672  	if (url->netrcfd < 0)
1673  		url->netrcfd = fetch_netrc_open();
1674  	if (url->netrcfd < 0)
1675  		return (-1);
1676  	if ((f = fdopen(url->netrcfd, "r")) == NULL) {
1677  		serrno = errno;
1678  		DEBUGF("fdopen(netrcfd): %s", strerror(errno));
1679  		close(url->netrcfd);
1680  		url->netrcfd = -1;
1681  		errno = serrno;
1682  		return (-1);
1683  	}
1684  	rewind(f);
1685  	DEBUGF("searching netrc for %s\n", url->host);
1686  	while ((word = fetch_read_word(f)) != NULL) {
1687  		if (strcmp(word, "default") == 0) {
1688  			DEBUGF("using default netrc settings\n");
1689  			break;
1690  		}
1691  		if (strcmp(word, "machine") == 0 &&
1692  		    (word = fetch_read_word(f)) != NULL &&
1693  		    strcasecmp(word, url->host) == 0) {
1694  			DEBUGF("using netrc settings for %s\n", word);
1695  			break;
1696  		}
1697  	}
1698  	if (word == NULL)
1699  		goto ferr;
1700  	while ((word = fetch_read_word(f)) != NULL) {
1701  		if (strcmp(word, "login") == 0) {
1702  			if ((word = fetch_read_word(f)) == NULL)
1703  				goto ferr;
1704  			if (snprintf(url->user, sizeof(url->user),
1705  				"%s", word) > (int)sizeof(url->user)) {
1706  				fetch_info("login name in .netrc is too long");
1707  				url->user[0] = '\0';
1708  			}
1709  		} else if (strcmp(word, "password") == 0) {
1710  			if ((word = fetch_read_word(f)) == NULL)
1711  				goto ferr;
1712  			if (snprintf(url->pwd, sizeof(url->pwd),
1713  				"%s", word) > (int)sizeof(url->pwd)) {
1714  				fetch_info("password in .netrc is too long");
1715  				url->pwd[0] = '\0';
1716  			}
1717  		} else if (strcmp(word, "account") == 0) {
1718  			if ((word = fetch_read_word(f)) == NULL)
1719  				goto ferr;
1720  			/* XXX not supported! */
1721  		} else {
1722  			break;
1723  		}
1724  	}
1725  	fclose(f);
1726  	url->netrcfd = -1;
1727  	return (0);
1728  ferr:
1729  	serrno = errno;
1730  	fclose(f);
1731  	url->netrcfd = -1;
1732  	errno = serrno;
1733  	return (-1);
1734  }
1735  
1736  /*
1737   * The no_proxy environment variable specifies a set of domains for
1738   * which the proxy should not be consulted; the contents is a comma-,
1739   * or space-separated list of domain names.  A single asterisk will
1740   * override all proxy variables and no transactions will be proxied
1741   * (for compatibility with lynx and curl, see the discussion at
1742   * <http://curl.haxx.se/mail/archive_pre_oct_99/0009.html>).
1743   */
1744  int
1745  fetch_no_proxy_match(const char *host)
1746  {
1747  	const char *no_proxy, *p, *q;
1748  	size_t h_len, d_len;
1749  
1750  	if ((no_proxy = getenv("NO_PROXY")) == NULL &&
1751  	    (no_proxy = getenv("no_proxy")) == NULL)
1752  		return (0);
1753  
1754  	/* asterisk matches any hostname */
1755  	if (strcmp(no_proxy, "*") == 0)
1756  		return (1);
1757  
1758  	h_len = strlen(host);
1759  	p = no_proxy;
1760  	do {
1761  		/* position p at the beginning of a domain suffix */
1762  		while (*p == ',' || isspace((unsigned char)*p))
1763  			p++;
1764  
1765  		/* position q at the first separator character */
1766  		for (q = p; *q; ++q)
1767  			if (*q == ',' || isspace((unsigned char)*q))
1768  				break;
1769  
1770  		d_len = q - p;
1771  		if (d_len > 0 && h_len >= d_len &&
1772  		    strncasecmp(host + h_len - d_len,
1773  			p, d_len) == 0) {
1774  			/* domain name matches */
1775  			return (1);
1776  		}
1777  
1778  		p = q + 1;
1779  	} while (*q);
1780  
1781  	return (0);
1782  }