From owner-svn-src-stable@freebsd.org Fri Mar 24 14:19:54 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BF20CD1B787; Fri, 24 Mar 2017 14:19:54 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 816751BB1; Fri, 24 Mar 2017 14:19:54 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2OEJrrW031968; Fri, 24 Mar 2017 14:19:53 GMT (envelope-from des@FreeBSD.org) Received: (from des@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2OEJrqY031963; Fri, 24 Mar 2017 14:19:53 GMT (envelope-from des@FreeBSD.org) Message-Id: <201703241419.v2OEJrqY031963@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: des set sender to des@FreeBSD.org using -f From: =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= Date: Fri, 24 Mar 2017 14:19:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r315902 - stable/11/lib/libfetch X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Mar 2017 14:19:54 -0000 Author: des Date: Fri Mar 24 14:19:52 2017 New Revision: 315902 URL: https://svnweb.freebsd.org/changeset/base/315902 Log: MFH (r313974,r314596): open .netrc early in case we want to drop privs MFH (r314396,r315143): fix a crash caused by an incorrect format string MFH (r314701): fix handling of 416 errors when requesting a range MFH (r315455): fix parsing of IP literals (square brackets) PR: 212065, 217723 Modified: stable/11/lib/libfetch/common.c stable/11/lib/libfetch/common.h stable/11/lib/libfetch/fetch.c stable/11/lib/libfetch/fetch.h stable/11/lib/libfetch/http.c Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libfetch/common.c ============================================================================== --- stable/11/lib/libfetch/common.c Fri Mar 24 13:46:26 2017 (r315901) +++ stable/11/lib/libfetch/common.c Fri Mar 24 14:19:52 2017 (r315902) @@ -153,7 +153,7 @@ fetch_syserr(void) case EHOSTDOWN: fetchLastErrCode = FETCH_DOWN; break; -default: + default: fetchLastErrCode = FETCH_UNKNOWN; } snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno)); @@ -248,37 +248,51 @@ fetch_resolve(const char *addr, int port { char hbuf[256], sbuf[8]; struct addrinfo hints, *res; - const char *sep, *host, *service; + const char *hb, *he, *sep; + const char *host, *service; int err, len; - /* split address if necessary */ - err = EAI_SYSTEM; - if ((sep = strchr(addr, ':')) != NULL) { + /* 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)(sep - addr), addr); + "%.*s", (int)(he - hb), hb); if (len < 0) - return (NULL); + goto syserr; if (len >= (int)sizeof(hbuf)) { errno = ENAMETOOLONG; - fetch_syserr(); - return (NULL); + goto syserr; } host = hbuf; - service = sep + 1; - } else if (port != 0) { + } else { + host = hb; + } + + /* was it followed by a service name? */ + if (*sep == '\0' && port != 0) { if (port < 1 || port > 65535) { errno = EINVAL; - fetch_syserr(); - return (NULL); - } - if (snprintf(sbuf, sizeof(sbuf), "%d", port) < 0) { - fetch_syserr(); - return (NULL); + goto syserr; } - host = addr; + if (snprintf(sbuf, sizeof(sbuf), "%d", port) < 0) + goto syserr; service = sbuf; + } else if (*sep != '\0') { + service = sep; } else { - host = addr; service = NULL; } @@ -292,6 +306,9 @@ fetch_resolve(const char *addr, int port return (NULL); } return (res); +syserr: + fetch_syserr(); + return (NULL); } @@ -371,7 +388,7 @@ fetch_connect(const char *host, int port } if (err != 0) { if (verbose) - fetch_info("failed to connect to %s:%s", host, port); + fetch_info("failed to connect to %s:%d", host, port); goto syserr; } @@ -1339,16 +1356,11 @@ fetch_read_word(FILE *f) 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)) { @@ -1368,8 +1380,25 @@ fetch_netrc_auth(struct url *url) 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: stable/11/lib/libfetch/common.h ============================================================================== --- stable/11/lib/libfetch/common.h Fri Mar 24 13:46:26 2017 (r315901) +++ stable/11/lib/libfetch/common.h Fri Mar 24 14:19:52 2017 (r315902) @@ -73,7 +73,7 @@ struct iovec; 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); Modified: stable/11/lib/libfetch/fetch.c ============================================================================== --- stable/11/lib/libfetch/fetch.c Fri Mar 24 13:46:26 2017 (r315901) +++ stable/11/lib/libfetch/fetch.c Fri Mar 24 14:19:52 2017 (r315902) @@ -284,6 +284,7 @@ fetchMakeURL(const char *scheme, const c seturl(pwd); #undef seturl u->port = port; + u->netrcfd = -2; return (u); } @@ -349,6 +350,7 @@ fetchParseURL(const char *URL) fetch_syserr(); return (NULL); } + u->netrcfd = -2; /* scheme name */ if ((p = strstr(URL, ":/"))) { @@ -384,18 +386,17 @@ fetchParseURL(const char *URL) } /* 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 +443,12 @@ nohost: } 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: stable/11/lib/libfetch/fetch.h ============================================================================== --- stable/11/lib/libfetch/fetch.h Fri Mar 24 13:46:26 2017 (r315901) +++ stable/11/lib/libfetch/fetch.h Fri Mar 24 14:19:52 2017 (r315902) @@ -47,6 +47,7 @@ struct url { off_t offset; size_t length; time_t ims_time; + int netrcfd; }; struct url_stat { Modified: stable/11/lib/libfetch/http.c ============================================================================== --- stable/11/lib/libfetch/http.c Fri Mar 24 13:46:26 2017 (r315901) +++ stable/11/lib/libfetch/http.c Fri Mar 24 14:19:52 2017 (r315902) @@ -118,7 +118,7 @@ __FBSDID("$FreeBSD$"); || (xyz) == HTTP_USE_PROXY \ || (xyz) == HTTP_SEE_OTHER) -#define HTTP_ERROR(xyz) ((xyz) > 400 && (xyz) < 599) +#define HTTP_ERROR(xyz) ((xyz) >= 400 && (xyz) <= 599) /***************************************************************************** @@ -1604,20 +1604,11 @@ http_request_body(struct url *URL, const 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); - 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); + snprintf(hbuf, sizeof(hbuf), "%s:%d", host, url->port); + host = hbuf; } /* send request */ @@ -1925,7 +1916,7 @@ http_request_body(struct url *URL, const /* 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;