common.c revision 300665
1/*-
2 * Copyright (c) 1998-2014 Dag-Erling Sm��rgrav
3 * Copyright (c) 2013 Michael Gmelin <freebsd@grem.de>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer
11 *    in this position and unchanged.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/lib/libfetch/common.c 300665 2016-05-25 07:39:48Z truckman $");
32
33#include <sys/param.h>
34#include <sys/socket.h>
35#include <sys/time.h>
36#include <sys/uio.h>
37
38#include <netinet/in.h>
39
40#include <ctype.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <netdb.h>
44#include <poll.h>
45#include <pwd.h>
46#include <stdarg.h>
47#include <stdlib.h>
48#include <stdio.h>
49#include <string.h>
50#include <unistd.h>
51
52#ifdef WITH_SSL
53#include <openssl/x509v3.h>
54#endif
55
56#include "fetch.h"
57#include "common.h"
58
59
60/*** Local data **************************************************************/
61
62/*
63 * Error messages for resolver errors
64 */
65static struct fetcherr netdb_errlist[] = {
66#ifdef EAI_NODATA
67	{ EAI_NODATA,	FETCH_RESOLV,	"Host not found" },
68#endif
69	{ EAI_AGAIN,	FETCH_TEMP,	"Transient resolver failure" },
70	{ EAI_FAIL,	FETCH_RESOLV,	"Non-recoverable resolver failure" },
71	{ EAI_NONAME,	FETCH_RESOLV,	"No address record" },
72	{ -1,		FETCH_UNKNOWN,	"Unknown resolver error" }
73};
74
75/* End-of-Line */
76static const char ENDL[2] = "\r\n";
77
78
79/*** Error-reporting functions ***********************************************/
80
81/*
82 * Map error code to string
83 */
84static struct fetcherr *
85fetch_finderr(struct fetcherr *p, int e)
86{
87	while (p->num != -1 && p->num != e)
88		p++;
89	return (p);
90}
91
92/*
93 * Set error code
94 */
95void
96fetch_seterr(struct fetcherr *p, int e)
97{
98	p = fetch_finderr(p, e);
99	fetchLastErrCode = p->cat;
100	snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string);
101}
102
103/*
104 * Set error code according to errno
105 */
106void
107fetch_syserr(void)
108{
109	switch (errno) {
110	case 0:
111		fetchLastErrCode = FETCH_OK;
112		break;
113	case EPERM:
114	case EACCES:
115	case EROFS:
116	case EAUTH:
117	case ENEEDAUTH:
118		fetchLastErrCode = FETCH_AUTH;
119		break;
120	case ENOENT:
121	case EISDIR: /* XXX */
122		fetchLastErrCode = FETCH_UNAVAIL;
123		break;
124	case ENOMEM:
125		fetchLastErrCode = FETCH_MEMORY;
126		break;
127	case EBUSY:
128	case EAGAIN:
129		fetchLastErrCode = FETCH_TEMP;
130		break;
131	case EEXIST:
132		fetchLastErrCode = FETCH_EXISTS;
133		break;
134	case ENOSPC:
135		fetchLastErrCode = FETCH_FULL;
136		break;
137	case EADDRINUSE:
138	case EADDRNOTAVAIL:
139	case ENETDOWN:
140	case ENETUNREACH:
141	case ENETRESET:
142	case EHOSTUNREACH:
143		fetchLastErrCode = FETCH_NETWORK;
144		break;
145	case ECONNABORTED:
146	case ECONNRESET:
147		fetchLastErrCode = FETCH_ABORT;
148		break;
149	case ETIMEDOUT:
150		fetchLastErrCode = FETCH_TIMEOUT;
151		break;
152	case ECONNREFUSED:
153	case EHOSTDOWN:
154		fetchLastErrCode = FETCH_DOWN;
155		break;
156default:
157		fetchLastErrCode = FETCH_UNKNOWN;
158	}
159	snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno));
160}
161
162
163/*
164 * Emit status message
165 */
166void
167fetch_info(const char *fmt, ...)
168{
169	va_list ap;
170
171	va_start(ap, fmt);
172	vfprintf(stderr, fmt, ap);
173	va_end(ap);
174	fputc('\n', stderr);
175}
176
177
178/*** Network-related utility functions ***************************************/
179
180/*
181 * Return the default port for a scheme
182 */
183int
184fetch_default_port(const char *scheme)
185{
186	struct servent *se;
187
188	if ((se = getservbyname(scheme, "tcp")) != NULL)
189		return (ntohs(se->s_port));
190	if (strcasecmp(scheme, SCHEME_FTP) == 0)
191		return (FTP_DEFAULT_PORT);
192	if (strcasecmp(scheme, SCHEME_HTTP) == 0)
193		return (HTTP_DEFAULT_PORT);
194	return (0);
195}
196
197/*
198 * Return the default proxy port for a scheme
199 */
200int
201fetch_default_proxy_port(const char *scheme)
202{
203	if (strcasecmp(scheme, SCHEME_FTP) == 0)
204		return (FTP_DEFAULT_PROXY_PORT);
205	if (strcasecmp(scheme, SCHEME_HTTP) == 0)
206		return (HTTP_DEFAULT_PROXY_PORT);
207	return (0);
208}
209
210
211/*
212 * Create a connection for an existing descriptor.
213 */
214conn_t *
215fetch_reopen(int sd)
216{
217	conn_t *conn;
218	int opt = 1;
219
220	/* allocate and fill connection structure */
221	if ((conn = calloc(1, sizeof(*conn))) == NULL)
222		return (NULL);
223	fcntl(sd, F_SETFD, FD_CLOEXEC);
224	setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof opt);
225	conn->sd = sd;
226	++conn->ref;
227	return (conn);
228}
229
230
231/*
232 * Bump a connection's reference count.
233 */
234conn_t *
235fetch_ref(conn_t *conn)
236{
237
238	++conn->ref;
239	return (conn);
240}
241
242
243/*
244 * Bind a socket to a specific local address
245 */
246int
247fetch_bind(int sd, int af, const char *addr)
248{
249	struct addrinfo hints, *res, *res0;
250	int err;
251
252	memset(&hints, 0, sizeof(hints));
253	hints.ai_family = af;
254	hints.ai_socktype = SOCK_STREAM;
255	hints.ai_protocol = 0;
256	if ((err = getaddrinfo(addr, NULL, &hints, &res0)) != 0)
257		return (-1);
258	for (res = res0; res; res = res->ai_next)
259		if (bind(sd, res->ai_addr, res->ai_addrlen) == 0) {
260			freeaddrinfo(res0);
261			return (0);
262		}
263	freeaddrinfo(res0);
264	return (-1);
265}
266
267
268/*
269 * Establish a TCP connection to the specified port on the specified host.
270 */
271conn_t *
272fetch_connect(const char *host, int port, int af, int verbose)
273{
274	conn_t *conn;
275	char pbuf[10];
276	const char *bindaddr;
277	struct addrinfo hints, *res, *res0;
278	int sd, err;
279
280	DEBUG(fprintf(stderr, "---> %s:%d\n", host, port));
281
282	if (verbose)
283		fetch_info("looking up %s", host);
284
285	/* look up host name and set up socket address structure */
286	snprintf(pbuf, sizeof(pbuf), "%d", port);
287	memset(&hints, 0, sizeof(hints));
288	hints.ai_family = af;
289	hints.ai_socktype = SOCK_STREAM;
290	hints.ai_protocol = 0;
291	if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) {
292		netdb_seterr(err);
293		return (NULL);
294	}
295	bindaddr = getenv("FETCH_BIND_ADDRESS");
296
297	if (verbose)
298		fetch_info("connecting to %s:%d", host, port);
299
300	/* try to connect */
301	for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) {
302		if ((sd = socket(res->ai_family, res->ai_socktype,
303			 res->ai_protocol)) == -1)
304			continue;
305		if (bindaddr != NULL && *bindaddr != '\0' &&
306		    fetch_bind(sd, res->ai_family, bindaddr) != 0) {
307			fetch_info("failed to bind to '%s'", bindaddr);
308			close(sd);
309			continue;
310		}
311		if (connect(sd, res->ai_addr, res->ai_addrlen) == 0 &&
312		    fcntl(sd, F_SETFL, O_NONBLOCK) == 0)
313			break;
314		close(sd);
315	}
316	freeaddrinfo(res0);
317	if (sd == -1) {
318		fetch_syserr();
319		return (NULL);
320	}
321
322	if ((conn = fetch_reopen(sd)) == NULL) {
323		fetch_syserr();
324		close(sd);
325	}
326	return (conn);
327}
328
329#ifdef WITH_SSL
330/*
331 * Convert characters A-Z to lowercase (intentionally avoid any locale
332 * specific conversions).
333 */
334static char
335fetch_ssl_tolower(char in)
336{
337	if (in >= 'A' && in <= 'Z')
338		return (in + 32);
339	else
340		return (in);
341}
342
343/*
344 * isalpha implementation that intentionally avoids any locale specific
345 * conversions.
346 */
347static int
348fetch_ssl_isalpha(char in)
349{
350	return ((in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z'));
351}
352
353/*
354 * Check if passed hostnames a and b are equal.
355 */
356static int
357fetch_ssl_hname_equal(const char *a, size_t alen, const char *b,
358    size_t blen)
359{
360	size_t i;
361
362	if (alen != blen)
363		return (0);
364	for (i = 0; i < alen; ++i) {
365		if (fetch_ssl_tolower(a[i]) != fetch_ssl_tolower(b[i]))
366			return (0);
367	}
368	return (1);
369}
370
371/*
372 * Check if domain label is traditional, meaning that only A-Z, a-z, 0-9
373 * and '-' (hyphen) are allowed. Hyphens have to be surrounded by alpha-
374 * numeric characters. Double hyphens (like they're found in IDN a-labels
375 * 'xn--') are not allowed. Empty labels are invalid.
376 */
377static int
378fetch_ssl_is_trad_domain_label(const char *l, size_t len, int wcok)
379{
380	size_t i;
381
382	if (!len || l[0] == '-' || l[len-1] == '-')
383		return (0);
384	for (i = 0; i < len; ++i) {
385		if (!isdigit(l[i]) &&
386		    !fetch_ssl_isalpha(l[i]) &&
387		    !(l[i] == '*' && wcok) &&
388		    !(l[i] == '-' && l[i - 1] != '-'))
389			return (0);
390	}
391	return (1);
392}
393
394/*
395 * Check if host name consists only of numbers. This might indicate an IP
396 * address, which is not a good idea for CN wildcard comparison.
397 */
398static int
399fetch_ssl_hname_is_only_numbers(const char *hostname, size_t len)
400{
401	size_t i;
402
403	for (i = 0; i < len; ++i) {
404		if (!((hostname[i] >= '0' && hostname[i] <= '9') ||
405		    hostname[i] == '.'))
406			return (0);
407	}
408	return (1);
409}
410
411/*
412 * Check if the host name h passed matches the pattern passed in m which
413 * is usually part of subjectAltName or CN of a certificate presented to
414 * the client. This includes wildcard matching. The algorithm is based on
415 * RFC6125, sections 6.4.3 and 7.2, which clarifies RFC2818 and RFC3280.
416 */
417static int
418fetch_ssl_hname_match(const char *h, size_t hlen, const char *m,
419    size_t mlen)
420{
421	int delta, hdotidx, mdot1idx, wcidx;
422	const char *hdot, *mdot1, *mdot2;
423	const char *wc; /* wildcard */
424
425	if (!(h && *h && m && *m))
426		return (0);
427	if ((wc = strnstr(m, "*", mlen)) == NULL)
428		return (fetch_ssl_hname_equal(h, hlen, m, mlen));
429	wcidx = wc - m;
430	/* hostname should not be just dots and numbers */
431	if (fetch_ssl_hname_is_only_numbers(h, hlen))
432		return (0);
433	/* only one wildcard allowed in pattern */
434	if (strnstr(wc + 1, "*", mlen - wcidx - 1) != NULL)
435		return (0);
436	/*
437	 * there must be at least two more domain labels and
438	 * wildcard has to be in the leftmost label (RFC6125)
439	 */
440	mdot1 = strnstr(m, ".", mlen);
441	if (mdot1 == NULL || mdot1 < wc || (mlen - (mdot1 - m)) < 4)
442		return (0);
443	mdot1idx = mdot1 - m;
444	mdot2 = strnstr(mdot1 + 1, ".", mlen - mdot1idx - 1);
445	if (mdot2 == NULL || (mlen - (mdot2 - m)) < 2)
446		return (0);
447	/* hostname must contain a dot and not be the 1st char */
448	hdot = strnstr(h, ".", hlen);
449	if (hdot == NULL || hdot == h)
450		return (0);
451	hdotidx = hdot - h;
452	/*
453	 * host part of hostname must be at least as long as
454	 * pattern it's supposed to match
455	 */
456	if (hdotidx < mdot1idx)
457		return (0);
458	/*
459	 * don't allow wildcards in non-traditional domain names
460	 * (IDN, A-label, U-label...)
461	 */
462	if (!fetch_ssl_is_trad_domain_label(h, hdotidx, 0) ||
463	    !fetch_ssl_is_trad_domain_label(m, mdot1idx, 1))
464		return (0);
465	/* match domain part (part after first dot) */
466	if (!fetch_ssl_hname_equal(hdot, hlen - hdotidx, mdot1,
467	    mlen - mdot1idx))
468		return (0);
469	/* match part left of wildcard */
470	if (!fetch_ssl_hname_equal(h, wcidx, m, wcidx))
471		return (0);
472	/* match part right of wildcard */
473	delta = mdot1idx - wcidx - 1;
474	if (!fetch_ssl_hname_equal(hdot - delta, delta,
475	    mdot1 - delta, delta))
476		return (0);
477	/* all tests succeeded, it's a match */
478	return (1);
479}
480
481/*
482 * Get numeric host address info - returns NULL if host was not an IP
483 * address. The caller is responsible for deallocation using
484 * freeaddrinfo(3).
485 */
486static struct addrinfo *
487fetch_ssl_get_numeric_addrinfo(const char *hostname, size_t len)
488{
489	struct addrinfo hints, *res;
490	char *host;
491
492	host = (char *)malloc(len + 1);
493	memcpy(host, hostname, len);
494	host[len] = '\0';
495	memset(&hints, 0, sizeof(hints));
496	hints.ai_family = PF_UNSPEC;
497	hints.ai_socktype = SOCK_STREAM;
498	hints.ai_protocol = 0;
499	hints.ai_flags = AI_NUMERICHOST;
500	/* port is not relevant for this purpose */
501	if (getaddrinfo(host, "443", &hints, &res) != 0)
502		res = NULL;
503	free(host);
504	return res;
505}
506
507/*
508 * Compare ip address in addrinfo with address passes.
509 */
510static int
511fetch_ssl_ipaddr_match_bin(const struct addrinfo *lhost, const char *rhost,
512    size_t rhostlen)
513{
514	const void *left;
515
516	if (lhost->ai_family == AF_INET && rhostlen == 4) {
517		left = (void *)&((struct sockaddr_in*)(void *)
518		    lhost->ai_addr)->sin_addr.s_addr;
519#ifdef INET6
520	} else if (lhost->ai_family == AF_INET6 && rhostlen == 16) {
521		left = (void *)&((struct sockaddr_in6 *)(void *)
522		    lhost->ai_addr)->sin6_addr;
523#endif
524	} else
525		return (0);
526	return (!memcmp(left, (const void *)rhost, rhostlen) ? 1 : 0);
527}
528
529/*
530 * Compare ip address in addrinfo with host passed. If host is not an IP
531 * address, comparison will fail.
532 */
533static int
534fetch_ssl_ipaddr_match(const struct addrinfo *laddr, const char *r,
535    size_t rlen)
536{
537	struct addrinfo *raddr;
538	int ret;
539	char *rip;
540
541	ret = 0;
542	if ((raddr = fetch_ssl_get_numeric_addrinfo(r, rlen)) == NULL)
543		return 0; /* not a numeric host */
544
545	if (laddr->ai_family == raddr->ai_family) {
546		if (laddr->ai_family == AF_INET) {
547			rip = (char *)&((struct sockaddr_in *)(void *)
548			    raddr->ai_addr)->sin_addr.s_addr;
549			ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 4);
550#ifdef INET6
551		} else if (laddr->ai_family == AF_INET6) {
552			rip = (char *)&((struct sockaddr_in6 *)(void *)
553			    raddr->ai_addr)->sin6_addr;
554			ret = fetch_ssl_ipaddr_match_bin(laddr, rip, 16);
555#endif
556		}
557
558	}
559	freeaddrinfo(raddr);
560	return (ret);
561}
562
563/*
564 * Verify server certificate by subjectAltName.
565 */
566static int
567fetch_ssl_verify_altname(STACK_OF(GENERAL_NAME) *altnames,
568    const char *host, struct addrinfo *ip)
569{
570	const GENERAL_NAME *name;
571	size_t nslen;
572	int i;
573	const char *ns;
574
575	for (i = 0; i < sk_GENERAL_NAME_num(altnames); ++i) {
576#if OPENSSL_VERSION_NUMBER < 0x10000000L
577		/*
578		 * This is a workaround, since the following line causes
579		 * alignment issues in clang:
580		 * name = sk_GENERAL_NAME_value(altnames, i);
581		 * OpenSSL explicitly warns not to use those macros
582		 * directly, but there isn't much choice (and there
583		 * shouldn't be any ill side effects)
584		 */
585		name = (GENERAL_NAME *)SKM_sk_value(void, altnames, i);
586#else
587		name = sk_GENERAL_NAME_value(altnames, i);
588#endif
589		ns = (const char *)ASN1_STRING_data(name->d.ia5);
590		nslen = (size_t)ASN1_STRING_length(name->d.ia5);
591
592		if (name->type == GEN_DNS && ip == NULL &&
593		    fetch_ssl_hname_match(host, strlen(host), ns, nslen))
594			return (1);
595		else if (name->type == GEN_IPADD && ip != NULL &&
596		    fetch_ssl_ipaddr_match_bin(ip, ns, nslen))
597			return (1);
598	}
599	return (0);
600}
601
602/*
603 * Verify server certificate by CN.
604 */
605static int
606fetch_ssl_verify_cn(X509_NAME *subject, const char *host,
607    struct addrinfo *ip)
608{
609	ASN1_STRING *namedata;
610	X509_NAME_ENTRY *nameentry;
611	int cnlen, lastpos, loc, ret;
612	unsigned char *cn;
613
614	ret = 0;
615	lastpos = -1;
616	loc = -1;
617	cn = NULL;
618	/* get most specific CN (last entry in list) and compare */
619	while ((lastpos = X509_NAME_get_index_by_NID(subject,
620	    NID_commonName, lastpos)) != -1)
621		loc = lastpos;
622
623	if (loc > -1) {
624		nameentry = X509_NAME_get_entry(subject, loc);
625		namedata = X509_NAME_ENTRY_get_data(nameentry);
626		cnlen = ASN1_STRING_to_UTF8(&cn, namedata);
627		if (ip == NULL &&
628		    fetch_ssl_hname_match(host, strlen(host), cn, cnlen))
629			ret = 1;
630		else if (ip != NULL && fetch_ssl_ipaddr_match(ip, cn, cnlen))
631			ret = 1;
632		OPENSSL_free(cn);
633	}
634	return (ret);
635}
636
637/*
638 * Verify that server certificate subjectAltName/CN matches
639 * hostname. First check, if there are alternative subject names. If yes,
640 * those have to match. Only if those don't exist it falls back to
641 * checking the subject's CN.
642 */
643static int
644fetch_ssl_verify_hname(X509 *cert, const char *host)
645{
646	struct addrinfo *ip;
647	STACK_OF(GENERAL_NAME) *altnames;
648	X509_NAME *subject;
649	int ret;
650
651	ret = 0;
652	ip = fetch_ssl_get_numeric_addrinfo(host, strlen(host));
653	altnames = X509_get_ext_d2i(cert, NID_subject_alt_name,
654	    NULL, NULL);
655
656	if (altnames != NULL) {
657		ret = fetch_ssl_verify_altname(altnames, host, ip);
658	} else {
659		subject = X509_get_subject_name(cert);
660		if (subject != NULL)
661			ret = fetch_ssl_verify_cn(subject, host, ip);
662	}
663
664	if (ip != NULL)
665		freeaddrinfo(ip);
666	if (altnames != NULL)
667		GENERAL_NAMES_free(altnames);
668	return (ret);
669}
670
671/*
672 * Configure transport security layer based on environment.
673 */
674static void
675fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose)
676{
677	long ssl_ctx_options;
678
679	ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET;
680	if (getenv("SSL_ALLOW_SSL3") == NULL)
681		ssl_ctx_options |= SSL_OP_NO_SSLv3;
682	if (getenv("SSL_NO_TLS1") != NULL)
683		ssl_ctx_options |= SSL_OP_NO_TLSv1;
684	if (getenv("SSL_NO_TLS1_1") != NULL)
685		ssl_ctx_options |= SSL_OP_NO_TLSv1_1;
686	if (getenv("SSL_NO_TLS1_2") != NULL)
687		ssl_ctx_options |= SSL_OP_NO_TLSv1_2;
688	if (verbose)
689		fetch_info("SSL options: %lx", ssl_ctx_options);
690	SSL_CTX_set_options(ctx, ssl_ctx_options);
691}
692
693
694/*
695 * Configure peer verification based on environment.
696 */
697#define LOCAL_CERT_FILE	"/usr/local/etc/ssl/cert.pem"
698#define BASE_CERT_FILE	"/etc/ssl/cert.pem"
699static int
700fetch_ssl_setup_peer_verification(SSL_CTX *ctx, int verbose)
701{
702	X509_LOOKUP *crl_lookup;
703	X509_STORE *crl_store;
704	const char *ca_cert_file, *ca_cert_path, *crl_file;
705
706	if (getenv("SSL_NO_VERIFY_PEER") == NULL) {
707		ca_cert_file = getenv("SSL_CA_CERT_FILE");
708		if (ca_cert_file == NULL &&
709		    access(LOCAL_CERT_FILE, R_OK) == 0)
710			ca_cert_file = LOCAL_CERT_FILE;
711		if (ca_cert_file == NULL &&
712		    access(BASE_CERT_FILE, R_OK) == 0)
713			ca_cert_file = BASE_CERT_FILE;
714		ca_cert_path = getenv("SSL_CA_CERT_PATH");
715		if (verbose) {
716			fetch_info("Peer verification enabled");
717			if (ca_cert_file != NULL)
718				fetch_info("Using CA cert file: %s",
719				    ca_cert_file);
720			if (ca_cert_path != NULL)
721				fetch_info("Using CA cert path: %s",
722				    ca_cert_path);
723			if (ca_cert_file == NULL && ca_cert_path == NULL)
724				fetch_info("Using OpenSSL default "
725				    "CA cert file and path");
726		}
727		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER,
728		    fetch_ssl_cb_verify_crt);
729		if (ca_cert_file != NULL || ca_cert_path != NULL)
730			SSL_CTX_load_verify_locations(ctx, ca_cert_file,
731			    ca_cert_path);
732		else
733			SSL_CTX_set_default_verify_paths(ctx);
734		if ((crl_file = getenv("SSL_CRL_FILE")) != NULL) {
735			if (verbose)
736				fetch_info("Using CRL file: %s", crl_file);
737			crl_store = SSL_CTX_get_cert_store(ctx);
738			crl_lookup = X509_STORE_add_lookup(crl_store,
739			    X509_LOOKUP_file());
740			if (crl_lookup == NULL ||
741			    !X509_load_crl_file(crl_lookup, crl_file,
742				X509_FILETYPE_PEM)) {
743				fprintf(stderr,
744				    "Could not load CRL file %s\n",
745				    crl_file);
746				return (0);
747			}
748			X509_STORE_set_flags(crl_store,
749			    X509_V_FLAG_CRL_CHECK |
750			    X509_V_FLAG_CRL_CHECK_ALL);
751		}
752	}
753	return (1);
754}
755
756/*
757 * Configure client certificate based on environment.
758 */
759static int
760fetch_ssl_setup_client_certificate(SSL_CTX *ctx, int verbose)
761{
762	const char *client_cert_file, *client_key_file;
763
764	if ((client_cert_file = getenv("SSL_CLIENT_CERT_FILE")) != NULL) {
765		client_key_file = getenv("SSL_CLIENT_KEY_FILE") != NULL ?
766		    getenv("SSL_CLIENT_KEY_FILE") : client_cert_file;
767		if (verbose) {
768			fetch_info("Using client cert file: %s",
769			    client_cert_file);
770			fetch_info("Using client key file: %s",
771			    client_key_file);
772		}
773		if (SSL_CTX_use_certificate_chain_file(ctx,
774			client_cert_file) != 1) {
775			fprintf(stderr,
776			    "Could not load client certificate %s\n",
777			    client_cert_file);
778			return (0);
779		}
780		if (SSL_CTX_use_PrivateKey_file(ctx, client_key_file,
781			SSL_FILETYPE_PEM) != 1) {
782			fprintf(stderr,
783			    "Could not load client key %s\n",
784			    client_key_file);
785			return (0);
786		}
787	}
788	return (1);
789}
790
791/*
792 * Callback for SSL certificate verification, this is called on server
793 * cert verification. It takes no decision, but informs the user in case
794 * verification failed.
795 */
796int
797fetch_ssl_cb_verify_crt(int verified, X509_STORE_CTX *ctx)
798{
799	X509 *crt;
800	X509_NAME *name;
801	char *str;
802
803	str = NULL;
804	if (!verified) {
805		if ((crt = X509_STORE_CTX_get_current_cert(ctx)) != NULL &&
806		    (name = X509_get_subject_name(crt)) != NULL)
807			str = X509_NAME_oneline(name, 0, 0);
808		fprintf(stderr, "Certificate verification failed for %s\n",
809		    str != NULL ? str : "no relevant certificate");
810		OPENSSL_free(str);
811	}
812	return (verified);
813}
814
815#endif
816
817/*
818 * Enable SSL on a connection.
819 */
820int
821fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
822{
823#ifdef WITH_SSL
824	int ret, ssl_err;
825	X509_NAME *name;
826	char *str;
827
828	/* Init the SSL library and context */
829	if (!SSL_library_init()){
830		fprintf(stderr, "SSL library init failed\n");
831		return (-1);
832	}
833
834	SSL_load_error_strings();
835
836	conn->ssl_meth = SSLv23_client_method();
837	conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth);
838	SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY);
839
840	fetch_ssl_setup_transport_layer(conn->ssl_ctx, verbose);
841	if (!fetch_ssl_setup_peer_verification(conn->ssl_ctx, verbose))
842		return (-1);
843	if (!fetch_ssl_setup_client_certificate(conn->ssl_ctx, verbose))
844		return (-1);
845
846	conn->ssl = SSL_new(conn->ssl_ctx);
847	if (conn->ssl == NULL) {
848		fprintf(stderr, "SSL context creation failed\n");
849		return (-1);
850	}
851	SSL_set_fd(conn->ssl, conn->sd);
852
853#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
854	if (!SSL_set_tlsext_host_name(conn->ssl,
855	    __DECONST(struct url *, URL)->host)) {
856		fprintf(stderr,
857		    "TLS server name indication extension failed for host %s\n",
858		    URL->host);
859		return (-1);
860	}
861#endif
862	while ((ret = SSL_connect(conn->ssl)) == -1) {
863		ssl_err = SSL_get_error(conn->ssl, ret);
864		if (ssl_err != SSL_ERROR_WANT_READ &&
865		    ssl_err != SSL_ERROR_WANT_WRITE) {
866			ERR_print_errors_fp(stderr);
867			return (-1);
868		}
869	}
870	conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);
871
872	if (conn->ssl_cert == NULL) {
873		fprintf(stderr, "No server SSL certificate\n");
874		return (-1);
875	}
876
877	if (getenv("SSL_NO_VERIFY_HOSTNAME") == NULL) {
878		if (verbose)
879			fetch_info("Verify hostname");
880		if (!fetch_ssl_verify_hname(conn->ssl_cert, URL->host)) {
881			fprintf(stderr,
882			    "SSL certificate subject doesn't match host %s\n",
883			    URL->host);
884			return (-1);
885		}
886	}
887
888	if (verbose) {
889		fetch_info("%s connection established using %s",
890		    SSL_get_version(conn->ssl), SSL_get_cipher(conn->ssl));
891		name = X509_get_subject_name(conn->ssl_cert);
892		str = X509_NAME_oneline(name, 0, 0);
893		fetch_info("Certificate subject: %s", str);
894		OPENSSL_free(str);
895		name = X509_get_issuer_name(conn->ssl_cert);
896		str = X509_NAME_oneline(name, 0, 0);
897		fetch_info("Certificate issuer: %s", str);
898		OPENSSL_free(str);
899	}
900
901	return (0);
902#else
903	(void)conn;
904	(void)verbose;
905	fprintf(stderr, "SSL support disabled\n");
906	return (-1);
907#endif
908}
909
910#define FETCH_READ_WAIT		-2
911#define FETCH_READ_ERROR	-1
912#define FETCH_READ_DONE		 0
913
914#ifdef WITH_SSL
915static ssize_t
916fetch_ssl_read(SSL *ssl, char *buf, size_t len)
917{
918	ssize_t rlen;
919	int ssl_err;
920
921	rlen = SSL_read(ssl, buf, len);
922	if (rlen < 0) {
923		ssl_err = SSL_get_error(ssl, rlen);
924		if (ssl_err == SSL_ERROR_WANT_READ ||
925		    ssl_err == SSL_ERROR_WANT_WRITE) {
926			return (FETCH_READ_WAIT);
927		} else {
928			ERR_print_errors_fp(stderr);
929			return (FETCH_READ_ERROR);
930		}
931	}
932	return (rlen);
933}
934#endif
935
936static ssize_t
937fetch_socket_read(int sd, char *buf, size_t len)
938{
939	ssize_t rlen;
940
941	rlen = read(sd, buf, len);
942	if (rlen < 0) {
943		if (errno == EAGAIN || (errno == EINTR && fetchRestartCalls))
944			return (FETCH_READ_WAIT);
945		else
946			return (FETCH_READ_ERROR);
947	}
948	return (rlen);
949}
950
951/*
952 * Read a character from a connection w/ timeout
953 */
954ssize_t
955fetch_read(conn_t *conn, char *buf, size_t len)
956{
957	struct timeval now, timeout, delta;
958	struct pollfd pfd;
959	ssize_t rlen;
960	int deltams;
961
962	if (fetchTimeout > 0) {
963		gettimeofday(&timeout, NULL);
964		timeout.tv_sec += fetchTimeout;
965	}
966
967	deltams = INFTIM;
968	memset(&pfd, 0, sizeof pfd);
969	pfd.fd = conn->sd;
970	pfd.events = POLLIN | POLLERR;
971
972	for (;;) {
973		/*
974		 * The socket is non-blocking.  Instead of the canonical
975		 * poll() -> read(), we do the following:
976		 *
977		 * 1) call read() or SSL_read().
978		 * 2) if we received some data, return it.
979		 * 3) if an error occurred, return -1.
980		 * 4) if read() or SSL_read() signaled EOF, return.
981		 * 5) if we did not receive any data but we're not at EOF,
982		 *    call poll().
983		 *
984		 * In the SSL case, this is necessary because if we
985		 * receive a close notification, we have to call
986		 * SSL_read() one additional time after we've read
987		 * everything we received.
988		 *
989		 * In the non-SSL case, it may improve performance (very
990		 * slightly) when reading small amounts of data.
991		 */
992#ifdef WITH_SSL
993		if (conn->ssl != NULL)
994			rlen = fetch_ssl_read(conn->ssl, buf, len);
995		else
996#endif
997			rlen = fetch_socket_read(conn->sd, buf, len);
998		if (rlen >= 0) {
999			break;
1000		} else if (rlen == FETCH_READ_ERROR) {
1001			fetch_syserr();
1002			return (-1);
1003		}
1004		// assert(rlen == FETCH_READ_WAIT);
1005		if (fetchTimeout > 0) {
1006			gettimeofday(&now, NULL);
1007			if (!timercmp(&timeout, &now, >)) {
1008				errno = ETIMEDOUT;
1009				fetch_syserr();
1010				return (-1);
1011			}
1012			timersub(&timeout, &now, &delta);
1013			deltams = delta.tv_sec * 1000 +
1014			    delta.tv_usec / 1000;;
1015		}
1016		errno = 0;
1017		pfd.revents = 0;
1018		if (poll(&pfd, 1, deltams) < 0) {
1019			if (errno == EINTR && fetchRestartCalls)
1020				continue;
1021			fetch_syserr();
1022			return (-1);
1023		}
1024	}
1025	return (rlen);
1026}
1027
1028
1029/*
1030 * Read a line of text from a connection w/ timeout
1031 */
1032#define MIN_BUF_SIZE 1024
1033
1034int
1035fetch_getln(conn_t *conn)
1036{
1037	char *tmp;
1038	size_t tmpsize;
1039	ssize_t len;
1040	char c;
1041
1042	if (conn->buf == NULL) {
1043		if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) {
1044			errno = ENOMEM;
1045			return (-1);
1046		}
1047		conn->bufsize = MIN_BUF_SIZE;
1048	}
1049
1050	conn->buf[0] = '\0';
1051	conn->buflen = 0;
1052
1053	do {
1054		len = fetch_read(conn, &c, 1);
1055		if (len == -1)
1056			return (-1);
1057		if (len == 0)
1058			break;
1059		conn->buf[conn->buflen++] = c;
1060		if (conn->buflen == conn->bufsize) {
1061			tmp = conn->buf;
1062			tmpsize = conn->bufsize * 2 + 1;
1063			if ((tmp = realloc(tmp, tmpsize)) == NULL) {
1064				errno = ENOMEM;
1065				return (-1);
1066			}
1067			conn->buf = tmp;
1068			conn->bufsize = tmpsize;
1069		}
1070	} while (c != '\n');
1071
1072	conn->buf[conn->buflen] = '\0';
1073	DEBUG(fprintf(stderr, "<<< %s", conn->buf));
1074	return (0);
1075}
1076
1077
1078/*
1079 * Write to a connection w/ timeout
1080 */
1081ssize_t
1082fetch_write(conn_t *conn, const char *buf, size_t len)
1083{
1084	struct iovec iov;
1085
1086	iov.iov_base = __DECONST(char *, buf);
1087	iov.iov_len = len;
1088	return fetch_writev(conn, &iov, 1);
1089}
1090
1091/*
1092 * Write a vector to a connection w/ timeout
1093 * Note: can modify the iovec.
1094 */
1095ssize_t
1096fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
1097{
1098	struct timeval now, timeout, delta;
1099	struct pollfd pfd;
1100	ssize_t wlen, total;
1101	int deltams;
1102
1103	memset(&pfd, 0, sizeof pfd);
1104	if (fetchTimeout) {
1105		pfd.fd = conn->sd;
1106		pfd.events = POLLOUT | POLLERR;
1107		gettimeofday(&timeout, NULL);
1108		timeout.tv_sec += fetchTimeout;
1109	}
1110
1111	total = 0;
1112	while (iovcnt > 0) {
1113		while (fetchTimeout && pfd.revents == 0) {
1114			gettimeofday(&now, NULL);
1115			if (!timercmp(&timeout, &now, >)) {
1116				errno = ETIMEDOUT;
1117				fetch_syserr();
1118				return (-1);
1119			}
1120			timersub(&timeout, &now, &delta);
1121			deltams = delta.tv_sec * 1000 +
1122			    delta.tv_usec / 1000;
1123			errno = 0;
1124			pfd.revents = 0;
1125			if (poll(&pfd, 1, deltams) < 0) {
1126				/* POSIX compliance */
1127				if (errno == EAGAIN)
1128					continue;
1129				if (errno == EINTR && fetchRestartCalls)
1130					continue;
1131				return (-1);
1132			}
1133		}
1134		errno = 0;
1135#ifdef WITH_SSL
1136		if (conn->ssl != NULL)
1137			wlen = SSL_write(conn->ssl,
1138			    iov->iov_base, iov->iov_len);
1139		else
1140#endif
1141			wlen = writev(conn->sd, iov, iovcnt);
1142		if (wlen == 0) {
1143			/* we consider a short write a failure */
1144			/* XXX perhaps we shouldn't in the SSL case */
1145			errno = EPIPE;
1146			fetch_syserr();
1147			return (-1);
1148		}
1149		if (wlen < 0) {
1150			if (errno == EINTR && fetchRestartCalls)
1151				continue;
1152			return (-1);
1153		}
1154		total += wlen;
1155		while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
1156			wlen -= iov->iov_len;
1157			iov++;
1158			iovcnt--;
1159		}
1160		if (iovcnt > 0) {
1161			iov->iov_len -= wlen;
1162			iov->iov_base = __DECONST(char *, iov->iov_base) + wlen;
1163		}
1164	}
1165	return (total);
1166}
1167
1168
1169/*
1170 * Write a line of text to a connection w/ timeout
1171 */
1172int
1173fetch_putln(conn_t *conn, const char *str, size_t len)
1174{
1175	struct iovec iov[2];
1176	int ret;
1177
1178	DEBUG(fprintf(stderr, ">>> %s\n", str));
1179	iov[0].iov_base = __DECONST(char *, str);
1180	iov[0].iov_len = len;
1181	iov[1].iov_base = __DECONST(char *, ENDL);
1182	iov[1].iov_len = sizeof(ENDL);
1183	if (len == 0)
1184		ret = fetch_writev(conn, &iov[1], 1);
1185	else
1186		ret = fetch_writev(conn, iov, 2);
1187	if (ret == -1)
1188		return (-1);
1189	return (0);
1190}
1191
1192
1193/*
1194 * Close connection
1195 */
1196int
1197fetch_close(conn_t *conn)
1198{
1199	int ret;
1200
1201	if (--conn->ref > 0)
1202		return (0);
1203#ifdef WITH_SSL
1204	if (conn->ssl) {
1205		SSL_shutdown(conn->ssl);
1206		SSL_set_connect_state(conn->ssl);
1207		SSL_free(conn->ssl);
1208		conn->ssl = NULL;
1209	}
1210	if (conn->ssl_ctx) {
1211		SSL_CTX_free(conn->ssl_ctx);
1212		conn->ssl_ctx = NULL;
1213	}
1214	if (conn->ssl_cert) {
1215		X509_free(conn->ssl_cert);
1216		conn->ssl_cert = NULL;
1217	}
1218#endif
1219	ret = close(conn->sd);
1220	free(conn->buf);
1221	free(conn);
1222	return (ret);
1223}
1224
1225
1226/*** Directory-related utility functions *************************************/
1227
1228int
1229fetch_add_entry(struct url_ent **p, int *size, int *len,
1230    const char *name, struct url_stat *us)
1231{
1232	struct url_ent *tmp;
1233
1234	if (*p == NULL) {
1235		*size = 0;
1236		*len = 0;
1237	}
1238
1239	if (*len >= *size - 1) {
1240		tmp = realloc(*p, (*size * 2 + 1) * sizeof(**p));
1241		if (tmp == NULL) {
1242			errno = ENOMEM;
1243			fetch_syserr();
1244			return (-1);
1245		}
1246		*size = (*size * 2 + 1);
1247		*p = tmp;
1248	}
1249
1250	tmp = *p + *len;
1251	snprintf(tmp->name, PATH_MAX, "%s", name);
1252	memcpy(&tmp->stat, us, sizeof(*us));
1253
1254	(*len)++;
1255	(++tmp)->name[0] = 0;
1256
1257	return (0);
1258}
1259
1260
1261/*** Authentication-related utility functions ********************************/
1262
1263static const char *
1264fetch_read_word(FILE *f)
1265{
1266	static char word[1024];
1267
1268	if (fscanf(f, " %1023s ", word) != 1)
1269		return (NULL);
1270	return (word);
1271}
1272
1273/*
1274 * Get authentication data for a URL from .netrc
1275 */
1276int
1277fetch_netrc_auth(struct url *url)
1278{
1279	char fn[PATH_MAX];
1280	const char *word;
1281	char *p;
1282	FILE *f;
1283
1284	if ((p = getenv("NETRC")) != NULL) {
1285		if (snprintf(fn, sizeof(fn), "%s", p) >= (int)sizeof(fn)) {
1286			fetch_info("$NETRC specifies a file name "
1287			    "longer than PATH_MAX");
1288			return (-1);
1289		}
1290	} else {
1291		if ((p = getenv("HOME")) != NULL) {
1292			struct passwd *pwd;
1293
1294			if ((pwd = getpwuid(getuid())) == NULL ||
1295			    (p = pwd->pw_dir) == NULL)
1296				return (-1);
1297		}
1298		if (snprintf(fn, sizeof(fn), "%s/.netrc", p) >= (int)sizeof(fn))
1299			return (-1);
1300	}
1301
1302	if ((f = fopen(fn, "r")) == NULL)
1303		return (-1);
1304	while ((word = fetch_read_word(f)) != NULL) {
1305		if (strcmp(word, "default") == 0) {
1306			DEBUG(fetch_info("Using default .netrc settings"));
1307			break;
1308		}
1309		if (strcmp(word, "machine") == 0 &&
1310		    (word = fetch_read_word(f)) != NULL &&
1311		    strcasecmp(word, url->host) == 0) {
1312			DEBUG(fetch_info("Using .netrc settings for %s", word));
1313			break;
1314		}
1315	}
1316	if (word == NULL)
1317		goto ferr;
1318	while ((word = fetch_read_word(f)) != NULL) {
1319		if (strcmp(word, "login") == 0) {
1320			if ((word = fetch_read_word(f)) == NULL)
1321				goto ferr;
1322			if (snprintf(url->user, sizeof(url->user),
1323				"%s", word) > (int)sizeof(url->user)) {
1324				fetch_info("login name in .netrc is too long");
1325				url->user[0] = '\0';
1326			}
1327		} else if (strcmp(word, "password") == 0) {
1328			if ((word = fetch_read_word(f)) == NULL)
1329				goto ferr;
1330			if (snprintf(url->pwd, sizeof(url->pwd),
1331				"%s", word) > (int)sizeof(url->pwd)) {
1332				fetch_info("password in .netrc is too long");
1333				url->pwd[0] = '\0';
1334			}
1335		} else if (strcmp(word, "account") == 0) {
1336			if ((word = fetch_read_word(f)) == NULL)
1337				goto ferr;
1338			/* XXX not supported! */
1339		} else {
1340			break;
1341		}
1342	}
1343	fclose(f);
1344	return (0);
1345 ferr:
1346	fclose(f);
1347	return (-1);
1348}
1349
1350/*
1351 * The no_proxy environment variable specifies a set of domains for
1352 * which the proxy should not be consulted; the contents is a comma-,
1353 * or space-separated list of domain names.  A single asterisk will
1354 * override all proxy variables and no transactions will be proxied
1355 * (for compatibility with lynx and curl, see the discussion at
1356 * <http://curl.haxx.se/mail/archive_pre_oct_99/0009.html>).
1357 */
1358int
1359fetch_no_proxy_match(const char *host)
1360{
1361	const char *no_proxy, *p, *q;
1362	size_t h_len, d_len;
1363
1364	if ((no_proxy = getenv("NO_PROXY")) == NULL &&
1365	    (no_proxy = getenv("no_proxy")) == NULL)
1366		return (0);
1367
1368	/* asterisk matches any hostname */
1369	if (strcmp(no_proxy, "*") == 0)
1370		return (1);
1371
1372	h_len = strlen(host);
1373	p = no_proxy;
1374	do {
1375		/* position p at the beginning of a domain suffix */
1376		while (*p == ',' || isspace((unsigned char)*p))
1377			p++;
1378
1379		/* position q at the first separator character */
1380		for (q = p; *q; ++q)
1381			if (*q == ',' || isspace((unsigned char)*q))
1382				break;
1383
1384		d_len = q - p;
1385		if (d_len > 0 && h_len >= d_len &&
1386		    strncasecmp(host + h_len - d_len,
1387			p, d_len) == 0) {
1388			/* domain name matches */
1389			return (1);
1390		}
1391
1392		p = q + 1;
1393	} while (*q);
1394
1395	return (0);
1396}
1397