Author: des
Date: Fri Mar 24 14:26:01 2017
New Revision: 315904
URL: https://svnweb.freebsd.org/changeset/base/315904

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/10/lib/libfetch/common.c
  stable/10/lib/libfetch/common.h
  stable/10/lib/libfetch/fetch.c
  stable/10/lib/libfetch/fetch.h
  stable/10/lib/libfetch/http.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libfetch/common.c
==============================================================================
--- stable/10/lib/libfetch/common.c     Fri Mar 24 14:25:56 2017        
(r315903)
+++ stable/10/lib/libfetch/common.c     Fri Mar 24 14:26:01 2017        
(r315904)
@@ -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/10/lib/libfetch/common.h
==============================================================================
--- stable/10/lib/libfetch/common.h     Fri Mar 24 14:25:56 2017        
(r315903)
+++ stable/10/lib/libfetch/common.h     Fri Mar 24 14:26:01 2017        
(r315904)
@@ -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/10/lib/libfetch/fetch.c
==============================================================================
--- stable/10/lib/libfetch/fetch.c      Fri Mar 24 14:25:56 2017        
(r315903)
+++ stable/10/lib/libfetch/fetch.c      Fri Mar 24 14:26:01 2017        
(r315904)
@@ -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/10/lib/libfetch/fetch.h
==============================================================================
--- stable/10/lib/libfetch/fetch.h      Fri Mar 24 14:25:56 2017        
(r315903)
+++ stable/10/lib/libfetch/fetch.h      Fri Mar 24 14:26:01 2017        
(r315904)
@@ -47,6 +47,7 @@ struct url {
        off_t            offset;
        size_t           length;
        time_t           ims_time;
+       int              netrcfd;
 };
 
 struct url_stat {

Modified: stable/10/lib/libfetch/http.c
==============================================================================
--- stable/10/lib/libfetch/http.c       Fri Mar 24 14:25:56 2017        
(r315903)
+++ stable/10/lib/libfetch/http.c       Fri Mar 24 14:26:01 2017        
(r315904)
@@ -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;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to