[Midnightbsd-cvs] src [10846] trunk/lib/libfetch: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Jun 12 20:43:57 EDT 2018


Revision: 10846
          http://svnweb.midnightbsd.org/src/?rev=10846
Author:   laffer1
Date:     2018-06-12 20:43:56 -0400 (Tue, 12 Jun 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/lib/libfetch/Makefile
    trunk/lib/libfetch/common.c
    trunk/lib/libfetch/common.h
    trunk/lib/libfetch/fetch.3
    trunk/lib/libfetch/fetch.c
    trunk/lib/libfetch/fetch.h
    trunk/lib/libfetch/file.c
    trunk/lib/libfetch/ftp.c
    trunk/lib/libfetch/http.c

Modified: trunk/lib/libfetch/Makefile
===================================================================
--- trunk/lib/libfetch/Makefile	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/Makefile	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+# $MidnightBSD$
 # $FreeBSD: stable/10/lib/libfetch/Makefile 240496 2012-09-14 13:00:43Z des $
 
 .include <bsd.own.mk>

Modified: trunk/lib/libfetch/common.c
===================================================================
--- trunk/lib/libfetch/common.c	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/common.c	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (c) 1998-2014 Dag-Erling Smørgrav
+ * Copyright (c) 1998-2016 Dag-Erling Smørgrav
  * Copyright (c) 2013 Michael Gmelin <freebsd at grem.de>
  * All rights reserved.
  *
@@ -28,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/lib/libfetch/common.c 277060 2015-01-12 10:02:23Z des $");
+__FBSDID("$FreeBSD: stable/10/lib/libfetch/common.c 323660 2017-09-17 01:32:45Z marius $");
 
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -153,7 +154,7 @@
 	case EHOSTDOWN:
 		fetchLastErrCode = FETCH_DOWN;
 		break;
-default:
+	default:
 		fetchLastErrCode = FETCH_UNKNOWN;
 	}
 	snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno));
@@ -241,24 +242,96 @@
 
 
 /*
+ * Resolve an address
+ */
+struct addrinfo *
+fetch_resolve(const char *addr, int port, int af)
+{
+	char hbuf[256], sbuf[8];
+	struct addrinfo hints, *res;
+	const char *hb, *he, *sep;
+	const char *host, *service;
+	int err, len;
+
+	/* first, check for a bracketed IPv6 address */
+	if (*addr == '[') {
+		hb = addr + 1;
+		if ((sep = strchr(hb, ']')) == NULL) {
+			errno = EINVAL;
+			goto syserr;
+		}
+		he = sep++;
+	} else {
+		hb = addr;
+		sep = strchrnul(hb, ':');
+		he = sep;
+	}
+
+	/* see if we need to copy the host name */
+	if (*he != '\0') {
+		len = snprintf(hbuf, sizeof(hbuf),
+		    "%.*s", (int)(he - hb), hb);
+		if (len < 0)
+			goto syserr;
+		if (len >= (int)sizeof(hbuf)) {
+			errno = ENAMETOOLONG;
+			goto syserr;
+		}
+		host = hbuf;
+	} else {
+		host = hb;
+	}
+
+	/* was it followed by a service name? */
+	if (*sep == '\0' && port != 0) {
+		if (port < 1 || port > 65535) {
+			errno = EINVAL;
+			goto syserr;
+		}
+		if (snprintf(sbuf, sizeof(sbuf), "%d", port) < 0)
+			goto syserr;
+		service = sbuf;
+	} else if (*sep != '\0') {
+		service = sep + 1;
+	} else {
+		service = NULL;
+	}
+
+	/* resolve */
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = af;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_ADDRCONFIG;
+	if ((err = getaddrinfo(host, service, &hints, &res)) != 0) {
+		netdb_seterr(err);
+		return (NULL);
+	}
+	return (res);
+syserr:
+	fetch_syserr();
+	return (NULL);
+}
+
+
+
+/*
  * Bind a socket to a specific local address
  */
 int
 fetch_bind(int sd, int af, const char *addr)
 {
-	struct addrinfo hints, *res, *res0;
+	struct addrinfo *cliai, *ai;
 	int err;
 
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = af;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = 0;
-	if ((err = getaddrinfo(addr, NULL, &hints, &res0)) != 0)
+	if ((cliai = fetch_resolve(addr, 0, af)) == NULL)
 		return (-1);
-	for (res = res0; res; res = res->ai_next)
-		if (bind(sd, res->ai_addr, res->ai_addrlen) == 0)
-			return (0);
-	return (-1);
+	for (ai = cliai; ai != NULL; ai = ai->ai_next)
+		if ((err = bind(sd, ai->ai_addr, ai->ai_addrlen)) == 0)
+			break;
+	if (err != 0)
+		fetch_syserr();
+	freeaddrinfo(cliai);
+	return (err == 0 ? 0 : -1);
 }
 
 
@@ -268,59 +341,76 @@
 conn_t *
 fetch_connect(const char *host, int port, int af, int verbose)
 {
-	conn_t *conn;
-	char pbuf[10];
+	struct addrinfo *cais = NULL, *sais = NULL, *cai, *sai;
 	const char *bindaddr;
-	struct addrinfo hints, *res, *res0;
-	int sd, err;
+	conn_t *conn = NULL;
+	int err = 0, sd = -1;
 
 	DEBUG(fprintf(stderr, "---> %s:%d\n", host, port));
 
+	/* resolve server address */
 	if (verbose)
-		fetch_info("looking up %s", host);
+		fetch_info("resolving server address: %s:%d", host, port);
+	if ((sais = fetch_resolve(host, port, af)) == NULL)
+		goto fail;
 
-	/* look up host name and set up socket address structure */
-	snprintf(pbuf, sizeof(pbuf), "%d", port);
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = af;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = 0;
-	if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) {
-		netdb_seterr(err);
-		return (NULL);
+	/* resolve client address */
+	bindaddr = getenv("FETCH_BIND_ADDRESS");
+	if (bindaddr != NULL && *bindaddr != '\0') {
+		if (verbose)
+			fetch_info("resolving client address: %s", bindaddr);
+		if ((cais = fetch_resolve(bindaddr, 0, af)) == NULL)
+			goto fail;
 	}
-	bindaddr = getenv("FETCH_BIND_ADDRESS");
 
-	if (verbose)
-		fetch_info("connecting to %s:%d", host, port);
-
-	/* try to connect */
-	for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) {
-		if ((sd = socket(res->ai_family, res->ai_socktype,
-			 res->ai_protocol)) == -1)
-			continue;
-		if (bindaddr != NULL && *bindaddr != '\0' &&
-		    fetch_bind(sd, res->ai_family, bindaddr) != 0) {
-			fetch_info("failed to bind to '%s'", bindaddr);
-			close(sd);
-			continue;
+	/* try each server address in turn */
+	for (err = 0, sai = sais; sai != NULL; sai = sai->ai_next) {
+		/* open socket */
+		if ((sd = socket(sai->ai_family, SOCK_STREAM, 0)) < 0)
+			goto syserr;
+		/* attempt to bind to client address */
+		for (err = 0, cai = cais; cai != NULL; cai = cai->ai_next) {
+			if (cai->ai_family != sai->ai_family)
+				continue;
+			if ((err = bind(sd, cai->ai_addr, cai->ai_addrlen)) == 0)
+				break;
 		}
-		if (connect(sd, res->ai_addr, res->ai_addrlen) == 0 &&
-		    fcntl(sd, F_SETFL, O_NONBLOCK) == 0)
+		if (err != 0) {
+			if (verbose)
+				fetch_info("failed to bind to %s", bindaddr);
+			goto syserr;
+		}
+		/* attempt to connect to server address */
+		if ((err = connect(sd, sai->ai_addr, sai->ai_addrlen)) == 0)
 			break;
+		/* clean up before next attempt */
 		close(sd);
+		sd = -1;
 	}
-	freeaddrinfo(res0);
-	if (sd == -1) {
-		fetch_syserr();
-		return (NULL);
+	if (err != 0) {
+		if (verbose)
+			fetch_info("failed to connect to %s:%d", host, port);
+		goto syserr;
 	}
 
-	if ((conn = fetch_reopen(sd)) == NULL) {
-		fetch_syserr();
+	if ((conn = fetch_reopen(sd)) == NULL)
+		goto syserr;
+	if (cais != NULL)
+		freeaddrinfo(cais);
+	if (sais != NULL)
+		freeaddrinfo(sais);
+	return (conn);
+syserr:
+	fetch_syserr();
+	goto fail;
+fail:
+	if (sd >= 0)
 		close(sd);
-	}
-	return (conn);
+	if (cais != NULL)
+		freeaddrinfo(cais);
+	if (sais != NULL)
+		freeaddrinfo(sais);
+	return (NULL);
 }
 
 #ifdef WITH_SSL
@@ -673,9 +763,7 @@
 {
 	long ssl_ctx_options;
 
-	ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_TICKET;
-	if (getenv("SSL_ALLOW_SSL2") == NULL)
-		ssl_ctx_options |= SSL_OP_NO_SSLv2;
+	ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET;
 	if (getenv("SSL_ALLOW_SSL3") == NULL)
 		ssl_ctx_options |= SSL_OP_NO_SSLv3;
 	if (getenv("SSL_NO_TLS1") != NULL)
@@ -707,7 +795,8 @@
 		if (ca_cert_file == NULL &&
 		    access(LOCAL_CERT_FILE, R_OK) == 0)
 			ca_cert_file = LOCAL_CERT_FILE;
-		if (ca_cert_file == NULL)
+		if (ca_cert_file == NULL &&
+		    access(BASE_CERT_FILE, R_OK) == 0)
 			ca_cert_file = BASE_CERT_FILE;
 		ca_cert_path = getenv("SSL_CA_CERT_PATH");
 		if (verbose) {
@@ -718,11 +807,17 @@
 			if (ca_cert_path != NULL)
 				fetch_info("Using CA cert path: %s",
 				    ca_cert_path);
+			if (ca_cert_file == NULL && ca_cert_path == NULL)
+				fetch_info("Using OpenSSL default "
+				    "CA cert file and path");
 		}
 		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER,
 		    fetch_ssl_cb_verify_crt);
-		SSL_CTX_load_verify_locations(ctx, ca_cert_file,
-		    ca_cert_path);
+		if (ca_cert_file != NULL || ca_cert_path != NULL)
+			SSL_CTX_load_verify_locations(ctx, ca_cert_file,
+			    ca_cert_path);
+		else
+			SSL_CTX_set_default_verify_paths(ctx);
 		if ((crl_file = getenv("SSL_CRL_FILE")) != NULL) {
 			if (verbose)
 				fetch_info("Using CRL file: %s", crl_file);
@@ -1262,16 +1357,11 @@
 	return (word);
 }
 
-/*
- * Get authentication data for a URL from .netrc
- */
-int
-fetch_netrc_auth(struct url *url)
+static int
+fetch_netrc_open(void)
 {
+	const char *p;
 	char fn[PATH_MAX];
-	const char *word;
-	char *p;
-	FILE *f;
 
 	if ((p = getenv("NETRC")) != NULL) {
 		if (snprintf(fn, sizeof(fn), "%s", p) >= (int)sizeof(fn)) {
@@ -1291,8 +1381,25 @@
 			return (-1);
 	}
 
-	if ((f = fopen(fn, "r")) == NULL)
+	return (open(fn, O_RDONLY));
+}
+
+/*
+ * Get authentication data for a URL from .netrc
+ */
+int
+fetch_netrc_auth(struct url *url)
+{
+	const char *word;
+	FILE *f;
+
+	if (url->netrcfd == -2)
+		url->netrcfd = fetch_netrc_open();
+	if (url->netrcfd < 0)
 		return (-1);
+	if ((f = fdopen(url->netrcfd, "r")) == NULL)
+		return (-1);
+	rewind(f);
 	while ((word = fetch_read_word(f)) != NULL) {
 		if (strcmp(word, "default") == 0) {
 			DEBUG(fetch_info("Using default .netrc settings"));

Modified: trunk/lib/libfetch/common.h
===================================================================
--- trunk/lib/libfetch/common.h	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/common.h	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998-2014 Dag-Erling Smørgrav
  * All rights reserved.
@@ -25,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/lib/libfetch/common.h 268900 2014-07-20 00:29:41Z bapt $
+ * $FreeBSD: stable/10/lib/libfetch/common.h 315904 2017-03-24 14:26:01Z des $
  */
 
 #ifndef _COMMON_H_INCLUDED
@@ -73,9 +74,10 @@
 
 void		 fetch_seterr(struct fetcherr *, int);
 void		 fetch_syserr(void);
-void		 fetch_info(const char *, ...);
+void		 fetch_info(const char *, ...) __printflike(1, 2);
 int		 fetch_default_port(const char *);
 int		 fetch_default_proxy_port(const char *);
+struct addrinfo *fetch_resolve(const char *, int, int);
 int		 fetch_bind(int, int, const char *);
 conn_t		*fetch_connect(const char *, int, int, int);
 conn_t		*fetch_reopen(int);

Modified: trunk/lib/libfetch/fetch.3
===================================================================
--- trunk/lib/libfetch/fetch.3	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/fetch.3	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,6 +1,7 @@
+.\" $MidnightBSD$
 .\"-
 .\" Copyright (c) 1998-2013 Dag-Erling Smørgrav
-.\" Copyright (c) 2013 Michael Gmelin <freebsd at grem.de>
+.\" Copyright (c) 2013-2016 Michael Gmelin <freebsd at grem.de>
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,9 +25,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: stable/10/lib/libfetch/fetch.3 277060 2015-01-12 10:02:23Z des $
+.\" $FreeBSD: stable/10/lib/libfetch/fetch.3 311863 2017-01-10 08:08:49Z des $
 .\"
-.Dd October 15, 2014
+.Dd March 18, 2016
 .Dt FETCH 3
 .Os
 .Sh NAME
@@ -396,8 +397,15 @@
 .Sh HTTPS SCHEME
 Based on HTTP SCHEME.
 By default the peer is verified using the CA bundle located in
-.Pa /etc/ssl/cert.pem .
-The file may contain multiple CA certificates.
+.Pa /usr/local/etc/ssl/cert.pem .
+If this file does not exist,
+.Pa /etc/ssl/cert.pem
+is used instead.
+If neither file exists, and
+.Ev SSL_CA_CERT_PATH
+has not been set,
+OpenSSL's default CA cert and path settings apply.
+The certificate bundle can contain multiple CA certificates.
 A common source of a current CA bundle is
 .Pa \%security/ca_root_nss .
 .Pp
@@ -428,10 +436,11 @@
 The environment variable
 .Ev SSL_CLIENT_CERT_FILE
 should be set to point to a file containing key and client certificate
-to be used in PEM format. In case the key is stored in a separate
-file, the environment variable
+to be used in PEM format.
+When a PEM-format key is in a separate file from the client certificate,
+the environment variable
 .Ev SSL_CLIENT_KEY_FILE
-can be set to point to the key in PEM format.
+can be set to point to the key file.
 In case the key uses a password, the user will be prompted on standard
 input (see
 .Xr PEM 3 ) .
@@ -441,10 +450,8 @@
 allows TLSv1 and newer when negotiating the connecting with the remote
 peer.
 You can change this behavior by setting the
-.Ev SSL_ALLOW_SSL2
-and
 .Ev SSL_ALLOW_SSL3
-environment variables to allow SSLv2 and SSLv3, respectively, and
+environment variable to allow SSLv3 and
 .Ev SSL_NO_TLS1 ,
 .Ev SSL_NO_TLS1_1 and
 .Ev SSL_NO_TLS1_2
@@ -533,7 +540,7 @@
 .El
 .Pp
 The accompanying error message includes a protocol-specific error code
-and message, e.g.\& "File is not available (404 Not Found)"
+and message, like "File is not available (404 Not Found)"
 .Sh ENVIRONMENT
 .Bl -tag -width ".Ev FETCH_BIND_ADDRESS"
 .It Ev FETCH_BIND_ADDRESS
@@ -633,11 +640,11 @@
 .It Ev NETRC
 Specifies a file to use instead of
 .Pa ~/.netrc
-to look up login names and passwords for FTP sites.
+to look up login names and passwords for FTP and HTTP sites as well as
+HTTP proxies.
 See
 .Xr ftp 1
 for a description of the file format.
-This feature is experimental.
 .It Ev NO_PROXY
 Either a single asterisk, which disables the use of proxies
 altogether, or a comma- or whitespace-separated list of hosts for
@@ -646,14 +653,11 @@
 Same as
 .Ev NO_PROXY ,
 for compatibility.
-.It Ev SSL_ALLOW_SSL2
-Allow SSL version 2 when negotiating the connection (not recommended).
 .It Ev SSL_ALLOW_SSL3
 Allow SSL version 3 when negotiating the connection (not recommended).
 .It Ev SSL_CA_CERT_FILE
 CA certificate bundle containing trusted CA certificates.
-Default value:
-.Pa /etc/ssl/cert.pem .
+Default value: See HTTPS SCHEME above.
 .It Ev SSL_CA_CERT_PATH
 Path containing trusted CA hashes.
 .It Ev SSL_CLIENT_CERT_FILE
@@ -780,27 +784,27 @@
 The
 .Nm fetch
 library was mostly written by
-.An Dag-Erling Sm\(/orgrav Aq des at FreeBSD.org
+.An Dag-Erling Sm\(/orgrav Aq Mt des at FreeBSD.org
 with numerous suggestions and contributions from
-.An Jordan K. Hubbard Aq jkh at FreeBSD.org ,
-.An Eugene Skepner Aq eu at qub.com ,
-.An Hajimu Umemoto Aq ume at FreeBSD.org ,
-.An Henry Whincup Aq henry at techiebod.com ,
-.An Jukka A. Ukkonen Aq jau at iki.fi ,
-.An Jean-Fran\(,cois Dockes Aq jf at dockes.org ,
-.An Michael Gmelin Aq freebsd at grem.de
+.An Jordan K. Hubbard Aq Mt jkh at FreeBSD.org ,
+.An Eugene Skepner Aq Mt eu at qub.com ,
+.An Hajimu Umemoto Aq Mt ume at FreeBSD.org ,
+.An Henry Whincup Aq Mt henry at techiebod.com ,
+.An Jukka A. Ukkonen Aq Mt jau at iki.fi ,
+.An Jean-Fran\(,cois Dockes Aq Mt jf at dockes.org ,
+.An Michael Gmelin Aq Mt freebsd at grem.de
 and others.
 It replaces the older
 .Nm ftpio
 library written by
-.An Poul-Henning Kamp Aq phk at FreeBSD.org
+.An Poul-Henning Kamp Aq Mt phk at FreeBSD.org
 and
-.An Jordan K. Hubbard Aq jkh at FreeBSD.org .
+.An Jordan K. Hubbard Aq Mt jkh at FreeBSD.org .
 .Pp
 This manual page was written by
-.An Dag-Erling Sm\(/orgrav Aq des at FreeBSD.org
+.An Dag-Erling Sm\(/orgrav Aq Mt des at FreeBSD.org
 and
-.An Michael Gmelin Aq freebsd at grem.de .
+.An Michael Gmelin Aq Mt freebsd at grem.de .
 .Sh BUGS
 Some parts of the library are not yet implemented.
 The most notable

Modified: trunk/lib/libfetch/fetch.c
===================================================================
--- trunk/lib/libfetch/fetch.c	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/fetch.c	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Smørgrav
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/lib/libfetch/fetch.c 252375 2013-06-29 15:51:27Z kientzle $");
+__FBSDID("$FreeBSD: stable/10/lib/libfetch/fetch.c 315904 2017-03-24 14:26:01Z des $");
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -284,6 +285,7 @@
 	seturl(pwd);
 #undef seturl
 	u->port = port;
+	u->netrcfd = -2;
 
 	return (u);
 }
@@ -349,6 +351,7 @@
 		fetch_syserr();
 		return (NULL);
 	}
+	u->netrcfd = -2;
 
 	/* scheme name */
 	if ((p = strstr(URL, ":/"))) {
@@ -384,18 +387,17 @@
 	}
 
 	/* hostname */
-#ifdef INET6
 	if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
 	    (*++q == '\0' || *q == '/' || *q == ':')) {
-		if ((i = q - p - 2) > MAXHOSTNAMELEN)
+		if ((i = q - p) > MAXHOSTNAMELEN)
 			i = MAXHOSTNAMELEN;
-		strncpy(u->host, ++p, i);
+		strncpy(u->host, p, i);
 		p = q;
-	} else
-#endif
+	} else {
 		for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
 			if (i < MAXHOSTNAMELEN)
 				u->host[i++] = *p;
+	}
 
 	/* port */
 	if (*p == ':') {
@@ -442,12 +444,12 @@
 	}
 
 	DEBUG(fprintf(stderr,
-		  "scheme:   [%s]\n"
-		  "user:     [%s]\n"
-		  "password: [%s]\n"
-		  "host:     [%s]\n"
-		  "port:     [%d]\n"
-		  "document: [%s]\n",
+		  "scheme:   \"%s\"\n"
+		  "user:     \"%s\"\n"
+		  "password: \"%s\"\n"
+		  "host:     \"%s\"\n"
+		  "port:     \"%d\"\n"
+		  "document: \"%s\"\n",
 		  u->scheme, u->user, u->pwd,
 		  u->host, u->port, u->doc));
 

Modified: trunk/lib/libfetch/fetch.h
===================================================================
--- trunk/lib/libfetch/fetch.h	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/fetch.h	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Smørgrav
  * All rights reserved.
@@ -25,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/lib/libfetch/fetch.h 268900 2014-07-20 00:29:41Z bapt $
+ * $FreeBSD: stable/10/lib/libfetch/fetch.h 315904 2017-03-24 14:26:01Z des $
  */
 
 #ifndef _FETCH_H_INCLUDED
@@ -47,6 +48,7 @@
 	off_t		 offset;
 	size_t		 length;
 	time_t		 ims_time;
+	int		 netrcfd;
 };
 
 struct url_stat {

Modified: trunk/lib/libfetch/file.c
===================================================================
--- trunk/lib/libfetch/file.c	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/file.c	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998-2011 Dag-Erling Smørgrav
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/lib/libfetch/file.c 240495 2012-09-14 12:15:13Z eadler $");
+__FBSDID("$FreeBSD: stable/10/lib/libfetch/file.c 301154 2016-06-01 17:45:00Z truckman $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -48,7 +49,7 @@
 	if (us && fetchStatFile(u, us, flags) == -1)
 		return (NULL);
 
-	f = fopen(u->doc, "r");
+	f = fopen(u->doc, "re");
 
 	if (f == NULL) {
 		fetch_syserr();
@@ -61,7 +62,6 @@
 		return (NULL);
 	}
 
-	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 	return (f);
 }
 
@@ -77,9 +77,9 @@
 	FILE *f;
 
 	if (CHECK_FLAG('a'))
-		f = fopen(u->doc, "a");
+		f = fopen(u->doc, "ae");
 	else
-		f = fopen(u->doc, "w+");
+		f = fopen(u->doc, "w+e");
 
 	if (f == NULL) {
 		fetch_syserr();
@@ -92,7 +92,6 @@
 		return (NULL);
 	}
 
-	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 	return (f);
 }
 
@@ -151,5 +150,6 @@
 		fetch_add_entry(&ue, &size, &len, de->d_name, &us);
 	}
 
+	closedir(dir);
 	return (ue);
 }

Modified: trunk/lib/libfetch/ftp.c
===================================================================
--- trunk/lib/libfetch/ftp.c	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/ftp.c	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998-2011 Dag-Erling Smørgrav
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/lib/libfetch/ftp.c 226537 2011-10-19 11:43:51Z des $");
+__FBSDID("$FreeBSD: stable/10/lib/libfetch/ftp.c 311863 2017-01-10 08:08:49Z des $");
 
 /*
  * Portions of this code were taken from or based on ftpio.c:
@@ -768,8 +769,8 @@
 			fetch_info("opening data connection");
 		bindaddr = getenv("FETCH_BIND_ADDRESS");
 		if (bindaddr != NULL && *bindaddr != '\0' &&
-		    fetch_bind(sd, sa.ss_family, bindaddr) != 0)
-			goto sysouch;
+		    (e = fetch_bind(sd, sa.ss_family, bindaddr)) != 0)
+			goto ouch;
 		if (connect(sd, (struct sockaddr *)&sa, sa.ss_len) == -1)
 			goto sysouch;
 
@@ -929,7 +930,7 @@
 		if (*pwd == '\0')
 			pwd = getenv("FTP_PASSWORD");
 		if (pwd == NULL || *pwd == '\0') {
-			if ((logname = getlogin()) == 0)
+			if ((logname = getlogin()) == NULL)
 				logname = FTP_ANONYMOUS_USER;
 			if ((len = snprintf(pbuf, MAXLOGNAME + 1, "%s@", logname)) < 0)
 				len = 0;

Modified: trunk/lib/libfetch/http.c
===================================================================
--- trunk/lib/libfetch/http.c	2018-06-13 00:42:15 UTC (rev 10845)
+++ trunk/lib/libfetch/http.c	2018-06-13 00:43:56 UTC (rev 10846)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000-2014 Dag-Erling Smørgrav
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/lib/libfetch/http.c 270460 2014-08-24 14:04:20Z des $");
+__FBSDID("$FreeBSD: stable/10/lib/libfetch/http.c 315904 2017-03-24 14:26:01Z des $");
 
 /*
  * The following copyright applies to the base64 code:
@@ -114,10 +115,11 @@
 #define HTTP_REDIRECT(xyz) ((xyz) == HTTP_MOVED_PERM \
 			    || (xyz) == HTTP_MOVED_TEMP \
 			    || (xyz) == HTTP_TEMP_REDIRECT \
+			    || (xyz) == HTTP_PERM_REDIRECT \
 			    || (xyz) == HTTP_USE_PROXY \
 			    || (xyz) == HTTP_SEE_OTHER)
 
-#define HTTP_ERROR(xyz) ((xyz) > 400 && (xyz) < 599)
+#define HTTP_ERROR(xyz) ((xyz) >= 400 && (xyz) <= 599)
 
 
 /*****************************************************************************
@@ -130,8 +132,8 @@
 	int		 chunked;	/* chunked mode */
 	char		*buf;		/* chunk buffer */
 	size_t		 bufsize;	/* size of chunk buffer */
-	ssize_t		 buflen;	/* amount of data currently in buffer */
-	int		 bufpos;	/* current read offset in buffer */
+	size_t		 buflen;	/* amount of data currently in buffer */
+	size_t		 bufpos;	/* current read offset in buffer */
 	int		 eof;		/* end-of-file flag */
 	int		 error;		/* error flag */
 	size_t		 chunksize;	/* remaining size of current chunk */
@@ -215,6 +217,7 @@
 	if (io->eof)
 		return (0);
 
+	/* not chunked: just fetch the requested amount */
 	if (io->chunked == 0) {
 		if (http_growbuf(io, len) == -1)
 			return (-1);
@@ -227,6 +230,7 @@
 		return (io->buflen);
 	}
 
+	/* chunked, but we ran out: get the next chunk header */
 	if (io->chunksize == 0) {
 		switch (http_new_chunk(io)) {
 		case -1:
@@ -238,6 +242,7 @@
 		}
 	}
 
+	/* fetch the requested amount, but no more than the current chunk */
 	if (len > io->chunksize)
 		len = io->chunksize;
 	if (http_growbuf(io, len) == -1)
@@ -246,8 +251,9 @@
 		io->error = errno;
 		return (-1);
 	}
+	io->bufpos = 0;
 	io->buflen = nbytes;
-	io->chunksize -= io->buflen;
+	io->chunksize -= nbytes;
 
 	if (io->chunksize == 0) {
 		if (fetch_read(io->conn, &ch, 1) != 1 || ch != '\r' ||
@@ -255,8 +261,6 @@
 			return (-1);
 	}
 
-	io->bufpos = 0;
-
 	return (io->buflen);
 }
 
@@ -873,7 +877,7 @@
 	char locale[64], *r;
 	struct tm tm;
 
-	strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale));
+	strlcpy(locale, setlocale(LC_TIME, NULL), sizeof(locale));
 	setlocale(LC_TIME, "C");
 	r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm);
 	/*
@@ -1330,7 +1334,6 @@
 http_authorize(conn_t *conn, const char *hdr, http_auth_challenges_t *cs,
 	       http_auth_params_t *parms, struct url *url)
 {
-	http_auth_challenge_t *basic = NULL;
 	http_auth_challenge_t *digest = NULL;
 	int i;
 
@@ -1340,10 +1343,8 @@
 		return (-1);
 	}
 
-	/* Look for a Digest and a Basic challenge */
+	/* Look for a Digest */
 	for (i = 0; i < cs->count; i++) {
-		if (cs->challenges[i]->scheme == HTTPAS_BASIC)
-			basic = cs->challenges[i];
 		if (cs->challenges[i]->scheme == HTTPAS_DIGEST)
 			digest = cs->challenges[i];
 	}
@@ -1379,8 +1380,12 @@
 {
 	struct url *curl;
 	conn_t *conn;
+	hdr_t h;
+	http_headerbuf_t headerbuf;
+	const char *p;
 	int verbose;
 	int af, val;
+	int serrno;
 
 #ifdef INET6
 	af = AF_UNSPEC;
@@ -1401,6 +1406,7 @@
 	if ((conn = fetch_connect(curl->host, curl->port, af, verbose)) == NULL)
 		/* fetch_connect() has already set an error code */
 		return (NULL);
+	init_http_headerbuf(&headerbuf);
 	if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
 		http_cmd(conn, "CONNECT %s:%d HTTP/1.1",
 		    URL->host, URL->port);
@@ -1408,24 +1414,46 @@
 		    URL->host, URL->port);
 		http_cmd(conn, "");
 		if (http_get_reply(conn) != HTTP_OK) {
-			fetch_close(conn);
-			return (NULL);
+			http_seterr(conn->err);
+			goto ouch;
 		}
-		http_get_reply(conn);
+		/* Read and discard the rest of the proxy response */
+		if (fetch_getln(conn) < 0) {
+			fetch_syserr();
+			goto ouch;
+		}
+		do {
+			switch ((h = http_next_header(conn, &headerbuf, &p))) {
+			case hdr_syserror:
+				fetch_syserr();
+				goto ouch;
+			case hdr_error:
+				http_seterr(HTTP_PROTOCOL_ERROR);
+				goto ouch;
+			default:
+				/* ignore */ ;
+			}
+		} while (h > hdr_end);
 	}
 	if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 &&
 	    fetch_ssl(conn, URL, verbose) == -1) {
-		fetch_close(conn);
 		/* grrr */
 		errno = EAUTH;
 		fetch_syserr();
-		return (NULL);
+		goto ouch;
 	}
 
 	val = 1;
 	setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));
 
+	clean_http_headerbuf(&headerbuf);
 	return (conn);
+ouch:
+	serrno = errno;
+	clean_http_headerbuf(&headerbuf);
+	fetch_close(conn);
+	errno = serrno;
+	return (NULL);
 }
 
 static struct url *
@@ -1577,21 +1605,12 @@
 		if ((conn = http_connect(url, purl, flags)) == NULL)
 			goto ouch;
 
+		/* append port number only if necessary */
 		host = url->host;
-#ifdef INET6
-		if (strchr(url->host, ':')) {
-			snprintf(hbuf, sizeof(hbuf), "[%s]", url->host);
+		if (url->port != fetch_default_port(url->scheme)) {
+			snprintf(hbuf, sizeof(hbuf), "%s:%d", host, url->port);
 			host = hbuf;
 		}
-#endif
-		if (url->port != fetch_default_port(url->scheme)) {
-			if (host != hbuf) {
-				strcpy(hbuf, host);
-				host = hbuf;
-			}
-			snprintf(hbuf + strlen(hbuf),
-			    sizeof(hbuf) - strlen(hbuf), ":%d", url->port);
-		}
 
 		/* send request */
 		if (verbose)
@@ -1625,10 +1644,8 @@
 			http_auth_params_t aparams;
 			init_http_auth_params(&aparams);
 			if (*purl->user || *purl->pwd) {
-				aparams.user = purl->user ?
-					strdup(purl->user) : strdup("");
-				aparams.password = purl->pwd?
-					strdup(purl->pwd) : strdup("");
+				aparams.user = strdup(purl->user);
+				aparams.password = strdup(purl->pwd);
 			} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL &&
 				   *p != '\0') {
 				if (http_authfromenv(p, &aparams) < 0) {
@@ -1635,6 +1652,9 @@
 					http_seterr(HTTP_NEED_PROXY_AUTH);
 					goto ouch;
 				}
+			} else if (fetch_netrc_auth(purl) == 0) {
+				aparams.user = strdup(purl->user);
+				aparams.password = strdup(purl->pwd);
 			}
 			http_authorize(conn, "Proxy-Authorization",
 				       &proxy_challenges, &aparams, url);
@@ -1654,10 +1674,8 @@
 			http_auth_params_t aparams;
 			init_http_auth_params(&aparams);
 			if (*url->user || *url->pwd) {
-				aparams.user = url->user ?
-					strdup(url->user) : strdup("");
-				aparams.password = url->pwd ?
-					strdup(url->pwd) : strdup("");
+				aparams.user = strdup(url->user);
+				aparams.password = strdup(url->pwd);
 			} else if ((p = getenv("HTTP_AUTH")) != NULL &&
 				   *p != '\0') {
 				if (http_authfromenv(p, &aparams) < 0) {
@@ -1664,12 +1682,13 @@
 					http_seterr(HTTP_NEED_AUTH);
 					goto ouch;
 				}
+			} else if (fetch_netrc_auth(url) == 0) {
+				aparams.user = strdup(url->user);
+				aparams.password = strdup(url->pwd);
 			} else if (fetchAuthMethod &&
 				   fetchAuthMethod(url) == 0) {
-				aparams.user = url->user ?
-					strdup(url->user) : strdup("");
-				aparams.password = url->pwd ?
-					strdup(url->pwd) : strdup("");
+				aparams.user = strdup(url->user);
+				aparams.password = strdup(url->pwd);
 			} else {
 				http_seterr(HTTP_NEED_AUTH);
 				goto ouch;
@@ -1741,6 +1760,8 @@
 			break;
 		case HTTP_MOVED_PERM:
 		case HTTP_MOVED_TEMP:
+		case HTTP_TEMP_REDIRECT:
+		case HTTP_PERM_REDIRECT:
 		case HTTP_SEE_OTHER:
 		case HTTP_USE_PROXY:
 			/*
@@ -1896,7 +1917,7 @@
 
 		/* requested range not satisfiable */
 		if (conn->err == HTTP_BAD_RANGE) {
-			if (url->offset == size && url->length == 0) {
+			if (url->offset > 0 && url->length == 0) {
 				/* asked for 0 bytes; fake it */
 				offset = url->offset;
 				clength = -1;



More information about the Midnightbsd-cvs mailing list