diff options
author | des <des@FreeBSD.org> | 2017-03-24 14:19:52 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2017-03-24 14:19:52 +0000 |
commit | 9cc8c478616cc8ad4c03db6529c1064888fc1acf (patch) | |
tree | 988e2bfb49ffca19739e87e0d00446a65d7e1b95 /lib/libfetch/common.c | |
parent | 4df1b0ecbe8b97b7b2a33fe8acc3e1936f273f92 (diff) | |
download | FreeBSD-src-9cc8c478616cc8ad4c03db6529c1064888fc1acf.zip FreeBSD-src-9cc8c478616cc8ad4c03db6529c1064888fc1acf.tar.gz |
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
Diffstat (limited to 'lib/libfetch/common.c')
-rw-r--r-- | lib/libfetch/common.c | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index 4145314..40fc2a7 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -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, int af) { 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, int af) return (NULL); } return (res); +syserr: + fetch_syserr(); + return (NULL); } @@ -371,7 +388,7 @@ fetch_connect(const char *host, int port, int af, int verbose) } 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")); |