]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libfetch/common.c
zfs: merge openzfs/zfs@ad0a55461
[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         /* Init the SSL library and context */
1208         if (!SSL_library_init()){
1209                 fprintf(stderr, "SSL library init failed\n");
1210                 return (-1);
1211         }
1212
1213         SSL_load_error_strings();
1214
1215         conn->ssl_meth = SSLv23_client_method();
1216         conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth);
1217         SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY);
1218
1219         fetch_ssl_setup_transport_layer(conn->ssl_ctx, verbose);
1220         if (!fetch_ssl_setup_peer_verification(conn->ssl_ctx, verbose))
1221                 return (-1);
1222         if (!fetch_ssl_setup_client_certificate(conn->ssl_ctx, verbose))
1223                 return (-1);
1224
1225         conn->ssl = SSL_new(conn->ssl_ctx);
1226         if (conn->ssl == NULL) {
1227                 fprintf(stderr, "SSL context creation failed\n");
1228                 return (-1);
1229         }
1230         SSL_set_fd(conn->ssl, conn->sd);
1231
1232 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
1233         if (!SSL_set_tlsext_host_name(conn->ssl,
1234             __DECONST(struct url *, URL)->host)) {
1235                 fprintf(stderr,
1236                     "TLS server name indication extension failed for host %s\n",
1237                     URL->host);
1238                 return (-1);
1239         }
1240 #endif
1241         while ((ret = SSL_connect(conn->ssl)) == -1) {
1242                 ssl_err = SSL_get_error(conn->ssl, ret);
1243                 if (ssl_err != SSL_ERROR_WANT_READ &&
1244                     ssl_err != SSL_ERROR_WANT_WRITE) {
1245                         ERR_print_errors_fp(stderr);
1246                         return (-1);
1247                 }
1248         }
1249         conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);
1250
1251         if (conn->ssl_cert == NULL) {
1252                 fprintf(stderr, "No server SSL certificate\n");
1253                 return (-1);
1254         }
1255
1256         if (getenv("SSL_NO_VERIFY_HOSTNAME") == NULL) {
1257                 if (verbose)
1258                         fetch_info("Verify hostname");
1259                 if (!fetch_ssl_verify_hname(conn->ssl_cert, URL->host)) {
1260                         fprintf(stderr,
1261                             "SSL certificate subject doesn't match host %s\n",
1262                             URL->host);
1263                         return (-1);
1264                 }
1265         }
1266
1267         if (verbose) {
1268                 fetch_info("%s connection established using %s",
1269                     SSL_get_version(conn->ssl), SSL_get_cipher(conn->ssl));
1270                 name = X509_get_subject_name(conn->ssl_cert);
1271                 str = X509_NAME_oneline(name, 0, 0);
1272                 fetch_info("Certificate subject: %s", str);
1273                 OPENSSL_free(str);
1274                 name = X509_get_issuer_name(conn->ssl_cert);
1275                 str = X509_NAME_oneline(name, 0, 0);
1276                 fetch_info("Certificate issuer: %s", str);
1277                 OPENSSL_free(str);
1278         }
1279
1280         return (0);
1281 #else
1282         (void)conn;
1283         (void)verbose;
1284         (void)URL;
1285         fprintf(stderr, "SSL support disabled\n");
1286         return (-1);
1287 #endif
1288 }
1289
1290 #define FETCH_READ_WAIT         -2
1291 #define FETCH_READ_ERROR        -1
1292 #define FETCH_READ_DONE          0
1293
1294 #ifdef WITH_SSL
1295 static ssize_t
1296 fetch_ssl_read(SSL *ssl, char *buf, size_t len)
1297 {
1298         ssize_t rlen;
1299         int ssl_err;
1300
1301         rlen = SSL_read(ssl, buf, len);
1302         if (rlen < 0) {
1303                 ssl_err = SSL_get_error(ssl, rlen);
1304                 if (ssl_err == SSL_ERROR_WANT_READ ||
1305                     ssl_err == SSL_ERROR_WANT_WRITE) {
1306                         return (FETCH_READ_WAIT);
1307                 } else {
1308                         ERR_print_errors_fp(stderr);
1309                         return (FETCH_READ_ERROR);
1310                 }
1311         }
1312         return (rlen);
1313 }
1314 #endif
1315
1316 static ssize_t
1317 fetch_socket_read(int sd, char *buf, size_t len)
1318 {
1319         ssize_t rlen;
1320
1321         rlen = read(sd, buf, len);
1322         if (rlen < 0) {
1323                 if (errno == EAGAIN || (errno == EINTR && fetchRestartCalls))
1324                         return (FETCH_READ_WAIT);
1325                 else
1326                         return (FETCH_READ_ERROR);
1327         }
1328         return (rlen);
1329 }
1330
1331 /*
1332  * Read a character from a connection w/ timeout
1333  */
1334 ssize_t
1335 fetch_read(conn_t *conn, char *buf, size_t len)
1336 {
1337         struct timeval now, timeout, delta;
1338         struct pollfd pfd;
1339         ssize_t rlen;
1340         int deltams;
1341
1342         if (fetchTimeout > 0) {
1343                 gettimeofday(&timeout, NULL);
1344                 timeout.tv_sec += fetchTimeout;
1345         }
1346
1347         deltams = INFTIM;
1348         memset(&pfd, 0, sizeof pfd);
1349         pfd.fd = conn->sd;
1350         pfd.events = POLLIN | POLLERR;
1351
1352         for (;;) {
1353                 /*
1354                  * The socket is non-blocking.  Instead of the canonical
1355                  * poll() -> read(), we do the following:
1356                  *
1357                  * 1) call read() or SSL_read().
1358                  * 2) if we received some data, return it.
1359                  * 3) if an error occurred, return -1.
1360                  * 4) if read() or SSL_read() signaled EOF, return.
1361                  * 5) if we did not receive any data but we're not at EOF,
1362                  *    call poll().
1363                  *
1364                  * In the SSL case, this is necessary because if we
1365                  * receive a close notification, we have to call
1366                  * SSL_read() one additional time after we've read
1367                  * everything we received.
1368                  *
1369                  * In the non-SSL case, it may improve performance (very
1370                  * slightly) when reading small amounts of data.
1371                  */
1372 #ifdef WITH_SSL
1373                 if (conn->ssl != NULL)
1374                         rlen = fetch_ssl_read(conn->ssl, buf, len);
1375                 else
1376 #endif
1377                         rlen = fetch_socket_read(conn->sd, buf, len);
1378                 if (rlen >= 0) {
1379                         break;
1380                 } else if (rlen == FETCH_READ_ERROR) {
1381                         fetch_syserr();
1382                         return (-1);
1383                 }
1384                 // assert(rlen == FETCH_READ_WAIT);
1385                 if (fetchTimeout > 0) {
1386                         gettimeofday(&now, NULL);
1387                         if (!timercmp(&timeout, &now, >)) {
1388                                 errno = ETIMEDOUT;
1389                                 fetch_syserr();
1390                                 return (-1);
1391                         }
1392                         timersub(&timeout, &now, &delta);
1393                         deltams = delta.tv_sec * 1000 +
1394                             delta.tv_usec / 1000;;
1395                 }
1396                 errno = 0;
1397                 pfd.revents = 0;
1398                 if (poll(&pfd, 1, deltams) < 0) {
1399                         if (errno == EINTR && fetchRestartCalls)
1400                                 continue;
1401                         fetch_syserr();
1402                         return (-1);
1403                 }
1404         }
1405         return (rlen);
1406 }
1407
1408
1409 /*
1410  * Read a line of text from a connection w/ timeout
1411  */
1412 #define MIN_BUF_SIZE 1024
1413
1414 int
1415 fetch_getln(conn_t *conn)
1416 {
1417         char *tmp;
1418         size_t tmpsize;
1419         ssize_t len;
1420         char c;
1421
1422         if (conn->buf == NULL) {
1423                 if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) {
1424                         errno = ENOMEM;
1425                         return (-1);
1426                 }
1427                 conn->bufsize = MIN_BUF_SIZE;
1428         }
1429
1430         conn->buf[0] = '\0';
1431         conn->buflen = 0;
1432
1433         do {
1434                 len = fetch_read(conn, &c, 1);
1435                 if (len == -1)
1436                         return (-1);
1437                 if (len == 0)
1438                         break;
1439                 conn->buf[conn->buflen++] = c;
1440                 if (conn->buflen == conn->bufsize) {
1441                         tmp = conn->buf;
1442                         tmpsize = conn->bufsize * 2 + 1;
1443                         if ((tmp = realloc(tmp, tmpsize)) == NULL) {
1444                                 errno = ENOMEM;
1445                                 return (-1);
1446                         }
1447                         conn->buf = tmp;
1448                         conn->bufsize = tmpsize;
1449                 }
1450         } while (c != '\n');
1451
1452         conn->buf[conn->buflen] = '\0';
1453         DEBUGF("<<< %s", conn->buf);
1454         return (0);
1455 }
1456
1457
1458 /*
1459  * Write to a connection w/ timeout
1460  */
1461 ssize_t
1462 fetch_write(conn_t *conn, const char *buf, size_t len)
1463 {
1464         struct iovec iov;
1465
1466         iov.iov_base = __DECONST(char *, buf);
1467         iov.iov_len = len;
1468         return fetch_writev(conn, &iov, 1);
1469 }
1470
1471 /*
1472  * Write a vector to a connection w/ timeout
1473  * Note: can modify the iovec.
1474  */
1475 ssize_t
1476 fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
1477 {
1478         struct timeval now, timeout, delta;
1479         struct pollfd pfd;
1480         ssize_t wlen, total;
1481         int deltams;
1482
1483         memset(&pfd, 0, sizeof pfd);
1484         if (fetchTimeout) {
1485                 pfd.fd = conn->sd;
1486                 pfd.events = POLLOUT | POLLERR;
1487                 gettimeofday(&timeout, NULL);
1488                 timeout.tv_sec += fetchTimeout;
1489         }
1490
1491         total = 0;
1492         while (iovcnt > 0) {
1493                 while (fetchTimeout && pfd.revents == 0) {
1494                         gettimeofday(&now, NULL);
1495                         if (!timercmp(&timeout, &now, >)) {
1496                                 errno = ETIMEDOUT;
1497                                 fetch_syserr();
1498                                 return (-1);
1499                         }
1500                         timersub(&timeout, &now, &delta);
1501                         deltams = delta.tv_sec * 1000 +
1502                             delta.tv_usec / 1000;
1503                         errno = 0;
1504                         pfd.revents = 0;
1505                         if (poll(&pfd, 1, deltams) < 0) {
1506                                 /* POSIX compliance */
1507                                 if (errno == EAGAIN)
1508                                         continue;
1509                                 if (errno == EINTR && fetchRestartCalls)
1510                                         continue;
1511                                 return (-1);
1512                         }
1513                 }
1514                 errno = 0;
1515 #ifdef WITH_SSL
1516                 if (conn->ssl != NULL)
1517                         wlen = SSL_write(conn->ssl,
1518                             iov->iov_base, iov->iov_len);
1519                 else
1520 #endif
1521                         wlen = writev(conn->sd, iov, iovcnt);
1522                 if (wlen == 0) {
1523                         /* we consider a short write a failure */
1524                         /* XXX perhaps we shouldn't in the SSL case */
1525                         errno = EPIPE;
1526                         fetch_syserr();
1527                         return (-1);
1528                 }
1529                 if (wlen < 0) {
1530                         if (errno == EINTR && fetchRestartCalls)
1531                                 continue;
1532                         return (-1);
1533                 }
1534                 total += wlen;
1535                 while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
1536                         wlen -= iov->iov_len;
1537                         iov++;
1538                         iovcnt--;
1539                 }
1540                 if (iovcnt > 0) {
1541                         iov->iov_len -= wlen;
1542                         iov->iov_base = __DECONST(char *, iov->iov_base) + wlen;
1543                 }
1544         }
1545         return (total);
1546 }
1547
1548
1549 /*
1550  * Write a line of text to a connection w/ timeout
1551  */
1552 int
1553 fetch_putln(conn_t *conn, const char *str, size_t len)
1554 {
1555         struct iovec iov[2];
1556         int ret;
1557
1558         DEBUGF(">>> %s\n", str);
1559         iov[0].iov_base = __DECONST(char *, str);
1560         iov[0].iov_len = len;
1561         iov[1].iov_base = __DECONST(char *, ENDL);
1562         iov[1].iov_len = sizeof(ENDL);
1563         if (len == 0)
1564                 ret = fetch_writev(conn, &iov[1], 1);
1565         else
1566                 ret = fetch_writev(conn, iov, 2);
1567         if (ret == -1)
1568                 return (-1);
1569         return (0);
1570 }
1571
1572
1573 /*
1574  * Close connection
1575  */
1576 int
1577 fetch_close(conn_t *conn)
1578 {
1579         int ret;
1580
1581         if (--conn->ref > 0)
1582                 return (0);
1583 #ifdef WITH_SSL
1584         if (conn->ssl) {
1585                 SSL_shutdown(conn->ssl);
1586                 SSL_set_connect_state(conn->ssl);
1587                 SSL_free(conn->ssl);
1588                 conn->ssl = NULL;
1589         }
1590         if (conn->ssl_ctx) {
1591                 SSL_CTX_free(conn->ssl_ctx);
1592                 conn->ssl_ctx = NULL;
1593         }
1594         if (conn->ssl_cert) {
1595                 X509_free(conn->ssl_cert);
1596                 conn->ssl_cert = NULL;
1597         }
1598 #endif
1599         ret = close(conn->sd);
1600         free(conn->buf);
1601         free(conn);
1602         return (ret);
1603 }
1604
1605
1606 /*** Directory-related utility functions *************************************/
1607
1608 int
1609 fetch_add_entry(struct url_ent **p, int *size, int *len,
1610     const char *name, struct url_stat *us)
1611 {
1612         struct url_ent *tmp;
1613
1614         if (*p == NULL) {
1615                 *size = 0;
1616                 *len = 0;
1617         }
1618
1619         if (*len >= *size - 1) {
1620                 tmp = reallocarray(*p, *size * 2 + 1, sizeof(**p));
1621                 if (tmp == NULL) {
1622                         errno = ENOMEM;
1623                         fetch_syserr();
1624                         return (-1);
1625                 }
1626                 *size = (*size * 2 + 1);
1627                 *p = tmp;
1628         }
1629
1630         tmp = *p + *len;
1631         snprintf(tmp->name, PATH_MAX, "%s", name);
1632         memcpy(&tmp->stat, us, sizeof(*us));
1633
1634         (*len)++;
1635         (++tmp)->name[0] = 0;
1636
1637         return (0);
1638 }
1639
1640
1641 /*** Authentication-related utility functions ********************************/
1642
1643 static const char *
1644 fetch_read_word(FILE *f)
1645 {
1646         static char word[1024];
1647
1648         if (fscanf(f, " %1023s ", word) != 1)
1649                 return (NULL);
1650         return (word);
1651 }
1652
1653 static int
1654 fetch_netrc_open(void)
1655 {
1656         struct passwd *pwd;
1657         char fn[PATH_MAX];
1658         const char *p;
1659         int fd, serrno;
1660
1661         if ((p = getenv("NETRC")) != NULL) {
1662                 DEBUGF("NETRC=%s\n", p);
1663                 if (snprintf(fn, sizeof(fn), "%s", p) >= (int)sizeof(fn)) {
1664                         fetch_info("$NETRC specifies a file name "
1665                             "longer than PATH_MAX");
1666                         return (-1);
1667                 }
1668         } else {
1669                 if ((p = getenv("HOME")) == NULL) {
1670                         if ((pwd = getpwuid(getuid())) == NULL ||
1671                             (p = pwd->pw_dir) == NULL)
1672                                 return (-1);
1673                 }
1674                 if (snprintf(fn, sizeof(fn), "%s/.netrc", p) >= (int)sizeof(fn))
1675                         return (-1);
1676         }
1677
1678         if ((fd = open(fn, O_RDONLY)) < 0) {
1679                 serrno = errno;
1680                 DEBUGF("%s: %s\n", fn, strerror(serrno));
1681                 errno = serrno;
1682         }
1683         return (fd);
1684 }
1685
1686 /*
1687  * Get authentication data for a URL from .netrc
1688  */
1689 int
1690 fetch_netrc_auth(struct url *url)
1691 {
1692         const char *word;
1693         int serrno;
1694         FILE *f;
1695
1696         if (url->netrcfd < 0)
1697                 url->netrcfd = fetch_netrc_open();
1698         if (url->netrcfd < 0)
1699                 return (-1);
1700         if ((f = fdopen(url->netrcfd, "r")) == NULL) {
1701                 serrno = errno;
1702                 DEBUGF("fdopen(netrcfd): %s", strerror(errno));
1703                 close(url->netrcfd);
1704                 url->netrcfd = -1;
1705                 errno = serrno;
1706                 return (-1);
1707         }
1708         rewind(f);
1709         DEBUGF("searching netrc for %s\n", url->host);
1710         while ((word = fetch_read_word(f)) != NULL) {
1711                 if (strcmp(word, "default") == 0) {
1712                         DEBUGF("using default netrc settings\n");
1713                         break;
1714                 }
1715                 if (strcmp(word, "machine") == 0 &&
1716                     (word = fetch_read_word(f)) != NULL &&
1717                     strcasecmp(word, url->host) == 0) {
1718                         DEBUGF("using netrc settings for %s\n", word);
1719                         break;
1720                 }
1721         }
1722         if (word == NULL)
1723                 goto ferr;
1724         while ((word = fetch_read_word(f)) != NULL) {
1725                 if (strcmp(word, "login") == 0) {
1726                         if ((word = fetch_read_word(f)) == NULL)
1727                                 goto ferr;
1728                         if (snprintf(url->user, sizeof(url->user),
1729                                 "%s", word) > (int)sizeof(url->user)) {
1730                                 fetch_info("login name in .netrc is too long");
1731                                 url->user[0] = '\0';
1732                         }
1733                 } else if (strcmp(word, "password") == 0) {
1734                         if ((word = fetch_read_word(f)) == NULL)
1735                                 goto ferr;
1736                         if (snprintf(url->pwd, sizeof(url->pwd),
1737                                 "%s", word) > (int)sizeof(url->pwd)) {
1738                                 fetch_info("password in .netrc is too long");
1739                                 url->pwd[0] = '\0';
1740                         }
1741                 } else if (strcmp(word, "account") == 0) {
1742                         if ((word = fetch_read_word(f)) == NULL)
1743                                 goto ferr;
1744                         /* XXX not supported! */
1745                 } else {
1746                         break;
1747                 }
1748         }
1749         fclose(f);
1750         url->netrcfd = -1;
1751         return (0);
1752 ferr:
1753         serrno = errno;
1754         fclose(f);
1755         url->netrcfd = -1;
1756         errno = serrno;
1757         return (-1);
1758 }
1759
1760 /*
1761  * The no_proxy environment variable specifies a set of domains for
1762  * which the proxy should not be consulted; the contents is a comma-,
1763  * or space-separated list of domain names.  A single asterisk will
1764  * override all proxy variables and no transactions will be proxied
1765  * (for compatibility with lynx and curl, see the discussion at
1766  * <http://curl.haxx.se/mail/archive_pre_oct_99/0009.html>).
1767  */
1768 int
1769 fetch_no_proxy_match(const char *host)
1770 {
1771         const char *no_proxy, *p, *q;
1772         size_t h_len, d_len;
1773
1774         if ((no_proxy = getenv("NO_PROXY")) == NULL &&
1775             (no_proxy = getenv("no_proxy")) == NULL)
1776                 return (0);
1777
1778         /* asterisk matches any hostname */
1779         if (strcmp(no_proxy, "*") == 0)
1780                 return (1);
1781
1782         h_len = strlen(host);
1783         p = no_proxy;
1784         do {
1785                 /* position p at the beginning of a domain suffix */
1786                 while (*p == ',' || isspace((unsigned char)*p))
1787                         p++;
1788
1789                 /* position q at the first separator character */
1790                 for (q = p; *q; ++q)
1791                         if (*q == ',' || isspace((unsigned char)*q))
1792                                 break;
1793
1794                 d_len = q - p;
1795                 if (d_len > 0 && h_len >= d_len &&
1796                     strncasecmp(host + h_len - d_len,
1797                         p, d_len) == 0) {
1798                         /* domain name matches */
1799                         return (1);
1800                 }
1801
1802                 p = q + 1;
1803         } while (*q);
1804
1805         return (0);
1806 }