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