Module Name: src Committed By: martin Date: Tue Oct 15 06:29:09 UTC 2024
Modified Files: src/external/bsd/fetch/dist/libfetch [netbsd-10]: common.c common.h fetch.3 ftp.c http.c Log Message: Pull up the following revisions, requested by wiz in ticket #980: external/bsd/fetch/dist/libfetch/common.c up to 1.7 external/bsd/fetch/dist/libfetch/common.h up to 1.3 external/bsd/fetch/dist/libfetch/fetch.3 up to 1.5 external/bsd/fetch/dist/libfetch/ftp.c up to 1.8 external/bsd/fetch/dist/libfetch/http.c up to 1.6 libfetch: fix pkg_install core dumps reported in PR 57179 To generate a diff of this commit: cvs rdiff -u -r1.2.54.2 -r1.2.54.3 \ src/external/bsd/fetch/dist/libfetch/common.c cvs rdiff -u -r1.2 -r1.2.36.1 src/external/bsd/fetch/dist/libfetch/common.h cvs rdiff -u -r1.4 -r1.4.26.1 src/external/bsd/fetch/dist/libfetch/fetch.3 cvs rdiff -u -r1.7 -r1.7.36.1 src/external/bsd/fetch/dist/libfetch/ftp.c cvs rdiff -u -r1.4 -r1.4.6.1 src/external/bsd/fetch/dist/libfetch/http.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/fetch/dist/libfetch/common.c diff -u src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.2 src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.3 --- src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.2 Sun Jan 14 13:19:39 2024 +++ src/external/bsd/fetch/dist/libfetch/common.c Tue Oct 15 06:29:09 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.2.54.2 2024/01/14 13:19:39 martin Exp $ */ +/* $NetBSD: common.c,v 1.2.54.3 2024/10/15 06:29:09 martin Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2008, 2010 Joerg Sonnenberger <jo...@netbsd.org> @@ -41,6 +41,13 @@ #include <sys/socket.h> #include <sys/time.h> #include <sys/uio.h> +#if defined(HAVE_POLL_H) || defined(NETBSD) +#include <poll.h> +#define HAVE_POLL +#elif HAVE_SYS_POLL_H +#define HAVE_POLL +#include <sys/poll.h> +#endif #include <netinet/in.h> #include <arpa/inet.h> @@ -236,6 +243,9 @@ fetch_reopen(int sd) conn->next_buf = NULL; conn->next_len = 0; conn->sd = sd; +#ifdef HAVE_POLL + conn->buf_events = POLLIN; +#endif return (conn); } @@ -316,6 +326,7 @@ fetch_connect(struct url *url, int af, i if ((conn = fetch_reopen(sd)) == NULL) { fetch_syserr(); close(sd); + return (NULL); } conn->cache_url = fetchCopyURL(url); conn->cache_af = af; @@ -368,7 +379,9 @@ fetch_cache_get(const struct url *url, i { conn_t *conn, *last_conn = NULL; - for (conn = connection_cache; conn; conn = conn->next_cached) { + for (conn = connection_cache; conn; last_conn = conn, + conn = conn->next_cached) + { if (conn->cache_url->port == url->port && strcmp(conn->cache_url->scheme, url->scheme) == 0 && strcmp(conn->cache_url->host, url->host) == 0 && @@ -395,8 +408,8 @@ fetch_cache_get(const struct url *url, i void fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *)) { - conn_t *iter, *last; - int global_count, host_count; + conn_t *iter, *last, *oiter; + int global_count, host_count, added; if (conn->cache_url == NULL || cache_global_limit == 0) { (*closecb)(conn); @@ -405,20 +418,28 @@ fetch_cache_put(conn_t *conn, int (*clos global_count = host_count = 0; last = NULL; - for (iter = connection_cache; iter; - last = iter, iter = iter->next_cached) { + for (iter = connection_cache; iter; ) { ++global_count; - if (strcmp(conn->cache_url->host, iter->cache_url->host) == 0) + added = !strcmp(conn->cache_url->host, iter->cache_url->host); + if (added) ++host_count; if (global_count < cache_global_limit && - host_count < cache_per_host_limit) - continue; - --global_count; - if (last != NULL) - last->next_cached = iter->next_cached; - else - connection_cache = iter->next_cached; - (*iter->cache_close)(iter); + host_count < cache_per_host_limit) { + oiter = NULL; + last = iter; + } else { + --global_count; + if (added) + --host_count; + if (last != NULL) + last->next_cached = iter->next_cached; + else + connection_cache = iter->next_cached; + oiter = iter; + } + iter = iter->next_cached; + if (oiter) + (*oiter->cache_close)(oiter); } conn->cache_close = closecb; @@ -430,7 +451,7 @@ fetch_cache_put(conn_t *conn, int (*clos * Enable SSL on a connection. */ int -fetch_ssl(conn_t *conn, int verbose) +fetch_ssl(conn_t *conn, const struct url *URL, int verbose) { #ifdef WITH_SSL @@ -455,11 +476,17 @@ fetch_ssl(conn_t *conn, int verbose) fprintf(stderr, "SSL context creation failed\n"); return (-1); } + conn->buf_events = 0; SSL_set_fd(conn->ssl, conn->sd); - if (!SSL_set_tlsext_host_name(conn->ssl, conn->cache_url->host)) { - fprintf(stderr, "SSL hostname setting failed\n"); +#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) + if (!SSL_set_tlsext_host_name(conn->ssl, (char *)(uintptr_t)URL->host)) + { + fprintf(stderr, + "TLS server name indication extension failed for host %s\n", + URL->host); return (-1); } +#endif if (SSL_connect(conn->ssl) == -1){ ERR_print_errors_fp(stderr); return (-1); @@ -491,6 +518,17 @@ fetch_ssl(conn_t *conn, int verbose) #endif } +#ifdef HAVE_POLL +static int +compute_timeout(const struct timeval *tv) +{ + struct timeval cur; + + gettimeofday(&cur, NULL); + return (tv->tv_sec - cur.tv_sec) * 1000 + + (tv->tv_usec - cur.tv_usec) / 1000; +} +#endif /* * Read a character from a connection w/ timeout @@ -498,8 +536,13 @@ fetch_ssl(conn_t *conn, int verbose) ssize_t fetch_read(conn_t *conn, char *buf, size_t len) { - struct timeval now, timeout, waittv; + struct timeval timeout_end; +#ifdef HAVE_POLL + struct pollfd pfd; +#else fd_set readfds; +#endif + int timeout_cur; ssize_t rlen; int r; @@ -516,17 +559,41 @@ fetch_read(conn_t *conn, char *buf, size } if (fetchTimeout) { +#ifndef HAVE_POLL FD_ZERO(&readfds); - gettimeofday(&timeout, NULL); - timeout.tv_sec += fetchTimeout; +#endif + gettimeofday(&timeout_end, NULL); + timeout_end.tv_sec += fetchTimeout; } for (;;) { +#ifdef HAVE_POLL + pfd.fd = conn->sd; + pfd.events = conn->buf_events; + if (fetchTimeout && pfd.events) { + do { + timeout_cur = compute_timeout(&timeout_end); + if (timeout_cur < 0) { + errno = ETIMEDOUT; + fetch_syserr(); + return (-1); + } + errno = 0; + r = poll(&pfd, 1, timeout_cur); + if (r == -1) { + if (errno == EINTR && fetchRestartCalls) + continue; + fetch_syserr(); + return (-1); + } + } while (pfd.revents == 0); +#else while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) { + struct timeval waittv, now; FD_SET(conn->sd, &readfds); gettimeofday(&now, NULL); - waittv.tv_sec = timeout.tv_sec - now.tv_sec; - waittv.tv_usec = timeout.tv_usec - now.tv_usec; + waittv.tv_sec = timeout_end.tv_sec - now.tv_sec; + waittv.tv_usec = timeout_end.tv_usec - now.tv_usec; if (waittv.tv_usec < 0) { waittv.tv_usec += 1000000; waittv.tv_sec--; @@ -544,11 +611,29 @@ fetch_read(conn_t *conn, char *buf, size fetch_syserr(); return (-1); } +#endif } #ifdef WITH_SSL - if (conn->ssl != NULL) - rlen = SSL_read(conn->ssl, buf, (int)len); - else + if (conn->ssl != NULL) { + rlen = SSL_read(conn->ssl, buf, len); + if (rlen == -1) { + switch (SSL_get_error(conn->ssl, rlen)) { + case SSL_ERROR_WANT_READ: + conn->buf_events = POLLIN; + break; + case SSL_ERROR_WANT_WRITE: + conn->buf_events = POLLOUT; + break; + default: + errno = EIO; + fetch_syserr(); + return -1; + } + } else { + /* Assume buffering on the SSL layer. */ + conn->buf_events = 0; + } + } else #endif rlen = read(conn->sd, buf, len); if (rlen >= 0) Index: src/external/bsd/fetch/dist/libfetch/common.h diff -u src/external/bsd/fetch/dist/libfetch/common.h:1.2 src/external/bsd/fetch/dist/libfetch/common.h:1.2.36.1 --- src/external/bsd/fetch/dist/libfetch/common.h:1.2 Tue Jan 7 02:13:00 2014 +++ src/external/bsd/fetch/dist/libfetch/common.h Tue Oct 15 06:29:09 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: common.h,v 1.2 2014/01/07 02:13:00 joerg Exp $ */ +/* $NetBSD: common.h,v 1.2.36.1 2024/10/15 06:29:09 martin Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * All rights reserved. @@ -45,9 +45,16 @@ #include <openssl/err.h> #endif +#if defined(__GNUC__) && __GNUC__ >= 3 +#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#else +#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg) +#endif + #if !defined(__sun) && !defined(__hpux) && !defined(__INTERIX) && \ !defined(__digital__) && !defined(__linux) && !defined(__MINT__) && \ - !defined(__sgi) + !defined(__sgi) && !defined(__minix) && !defined(__CYGWIN__) #define HAVE_SA_LEN #endif @@ -59,6 +66,7 @@ struct fetchconn { char *buf; /* buffer */ size_t bufsize; /* buffer size */ size_t buflen; /* length of buffer contents */ + int buf_events; /* poll flags for the next cycle */ char *next_buf; /* pending buffer, e.g. after getln */ size_t next_len; /* size of pending buffer */ int err; /* last protocol reply code */ @@ -90,7 +98,7 @@ struct fetcherr { void fetch_seterr(struct fetcherr *, int); void fetch_syserr(void); -void fetch_info(const char *, ...) __printflike(1, 2); +void fetch_info(const char *, ...) LIBFETCH_PRINTFLIKE(1, 2); int fetch_default_port(const char *); int fetch_default_proxy_port(const char *); int fetch_bind(int, int, const char *); @@ -98,7 +106,7 @@ conn_t *fetch_cache_get(const struct ur void fetch_cache_put(conn_t *, int (*)(conn_t *)); conn_t *fetch_connect(struct url *, int, int); conn_t *fetch_reopen(int); -int fetch_ssl(conn_t *, int); +int fetch_ssl(conn_t *, const struct url *, int); ssize_t fetch_read(conn_t *, char *, size_t); int fetch_getln(conn_t *); ssize_t fetch_write(conn_t *, const void *, size_t); Index: src/external/bsd/fetch/dist/libfetch/fetch.3 diff -u src/external/bsd/fetch/dist/libfetch/fetch.3:1.4 src/external/bsd/fetch/dist/libfetch/fetch.3:1.4.26.1 --- src/external/bsd/fetch/dist/libfetch/fetch.3:1.4 Tue May 31 16:26:47 2016 +++ src/external/bsd/fetch/dist/libfetch/fetch.3 Tue Oct 15 06:29:09 2024 @@ -25,9 +25,9 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD: fetch.3,v 1.64 2007/12/18 11:03:26 des Exp $ -.\" $NetBSD: fetch.3,v 1.4 2016/05/31 16:26:47 abhinav Exp $ +.\" $NetBSD: fetch.3,v 1.4.26.1 2024/10/15 06:29:09 martin Exp $ .\" -.Dd January 22, 2010 +.Dd December 22, 2023 .Dt FETCH 3 .Os .Sh NAME @@ -638,6 +638,10 @@ which proxies should not be used. Same as .Ev NO_PROXY , for compatibility. +.It Ev SSL_NO_VERIFY_PEER +If defined, +.Nm +will skip validating certificates when fetching HTTPS URLs. .El .Sh EXAMPLES To access a proxy server on Index: src/external/bsd/fetch/dist/libfetch/ftp.c diff -u src/external/bsd/fetch/dist/libfetch/ftp.c:1.7 src/external/bsd/fetch/dist/libfetch/ftp.c:1.7.36.1 --- src/external/bsd/fetch/dist/libfetch/ftp.c:1.7 Tue Jan 7 02:13:00 2014 +++ src/external/bsd/fetch/dist/libfetch/ftp.c Tue Oct 15 06:29:09 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ftp.c,v 1.7 2014/01/07 02:13:00 joerg Exp $ */ +/* $NetBSD: ftp.c,v 1.7.36.1 2024/10/15 06:29:09 martin Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger <jo...@netbsd.org> @@ -138,7 +138,6 @@ static void unmappedaddr(struct sockaddr_in6 *sin6, socklen_t *len) { struct sockaddr_in *sin4; - void *addrp; uint32_t addr; int port; @@ -146,8 +145,11 @@ unmappedaddr(struct sockaddr_in6 *sin6, !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) return; sin4 = (struct sockaddr_in *)(void *)sin6; - addrp = &sin6->sin6_addr.s6_addr[12]; - addr = *(uint32_t *)addrp; +#ifdef s6_addr32 + addr = sin6->sin6_addr.s6_addr32[3]; +#else + memcpy(&addr, &sin6->sin6_addr.s6_addr[12], sizeof(addr)); +#endif port = sin6->sin6_port; memset(sin4, 0, sizeof(struct sockaddr_in)); sin4->sin_addr.s_addr = addr; @@ -198,7 +200,7 @@ ftp_chkerr(conn_t *conn) /* * Send a command and check reply */ -__printflike(2, 3) +LIBFETCH_PRINTFLIKE(2, 3) static int ftp_cmd(conn_t *conn, const char *fmt, ...) { @@ -331,7 +333,8 @@ ftp_cwd(conn_t *conn, const char *path, } else if (strcmp(conn->ftp_home, "/") == 0) { dst = strdup(path - 1); } else { - asprintf(&dst, "%s/%s", conn->ftp_home, path); + if (asprintf(&dst, "%s/%s", conn->ftp_home, path) == -1) + dst = NULL; } if (dst == NULL) { fetch_syserr(); @@ -1170,12 +1173,14 @@ ftp_request(struct url *url, const char return (NULL); if ((path = fetchUnquotePath(url)) == NULL) { + fetch_close(conn); fetch_syserr(); return NULL; } /* change directory */ if (ftp_cwd(conn, path, op_arg != NULL) == -1) { + fetch_close(conn); free(path); return (NULL); } @@ -1188,12 +1193,14 @@ ftp_request(struct url *url, const char if (us && ftp_stat(conn, path, us) == -1 && fetchLastErrCode != FETCH_PROTO && fetchLastErrCode != FETCH_UNAVAIL) { + fetch_close(conn); free(path); return (NULL); } if (if_modified_since && url->last_modified > 0 && url->last_modified >= us->mtime) { + fetch_cache_put(conn, ftp_disconnect); free(path); fetchLastErrCode = FETCH_UNCHANGED; snprintf(fetchLastErrString, MAXERRSTRING, "Unchanged"); @@ -1202,6 +1209,7 @@ ftp_request(struct url *url, const char /* just a stat */ if (strcmp(op, "STAT") == 0) { + fetch_cache_put(conn, ftp_disconnect); free(path); return fetchIO_unopen(NULL, NULL, NULL, NULL); } Index: src/external/bsd/fetch/dist/libfetch/http.c diff -u src/external/bsd/fetch/dist/libfetch/http.c:1.4 src/external/bsd/fetch/dist/libfetch/http.c:1.4.6.1 --- src/external/bsd/fetch/dist/libfetch/http.c:1.4 Mon Jun 1 00:55:24 2020 +++ src/external/bsd/fetch/dist/libfetch/http.c Tue Oct 15 06:29:09 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: http.c,v 1.4 2020/06/01 00:55:24 kamil Exp $ */ +/* $NetBSD: http.c,v 1.4.6.1 2024/10/15 06:29:09 martin Exp $ */ /*- * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2003 Thomas Klausner <w...@netbsd.org> @@ -63,8 +63,12 @@ * SUCH DAMAGE. */ -#if defined(__linux__) || defined(__MINT__) +#if defined(__linux__) || defined(__MINT__) || defined(__FreeBSD_kernel__) /* Keep this down to Linux or MiNT, it can create surprises elsewhere. */ +/* + __FreeBSD_kernel__ is defined for GNU/kFreeBSD. + See http://glibc-bsd.alioth.debian.org/porting/PORTING . +*/ #define _GNU_SOURCE #endif @@ -329,7 +333,7 @@ http_closefn(void *v) setsockopt(io->conn->sd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t)sizeof(val)); fetch_cache_put(io->conn, fetch_close); -#ifdef TCP_NOPUSH +#if defined(TCP_NOPUSH) && !defined(__APPLE__) val = 1; setsockopt(io->conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val)); @@ -406,7 +410,7 @@ static struct { /* * Send a formatted line; optionally echo to terminal */ -__printflike(2, 3) +LIBFETCH_PRINTFLIKE(2, 3) static int http_cmd(conn_t *conn, const char *fmt, ...) { @@ -523,16 +527,26 @@ http_next_header(conn_t *conn, const cha static int http_parse_mtime(const char *p, time_t *mtime) { - char locale[64], *r; struct tm tm; + char *r; + +#ifdef LC_C_LOCALE + r = strptime_l(p, "%a, %d %b %Y %H:%M:%S GMT", &tm, LC_C_LOCALE); +#else + char *locale; + + locale = strdup(setlocale(LC_TIME, NULL)); + if (locale == NULL) + return (-1); - strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); setlocale(LC_TIME, "C"); r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); /* XXX should add support for date-2 and date-3 */ setlocale(LC_TIME, locale); - if (r == NULL) - return (-1); + free(locale); +#endif + if (r == NULL) + return (-1); *mtime = timegm(&tm); return (0); } @@ -710,13 +724,16 @@ http_authorize(conn_t *conn, const char static conn_t * http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) { + struct url *curl; conn_t *conn; + hdr_t h; + const char *p; int af, verbose; -#ifdef TCP_NOPUSH +#if defined(TCP_NOPUSH) && !defined(__APPLE__) int val; #endif - *cached = 1; + *cached = 0; #ifdef INET6 af = AF_UNSPEC; @@ -732,6 +749,7 @@ http_connect(struct url *URL, struct url af = AF_INET6; #endif + curl = (purl != NULL) ? purl : URL; if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) { URL = purl; } else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { @@ -740,33 +758,64 @@ http_connect(struct url *URL, struct url return (NULL); } - if ((conn = fetch_cache_get(URL, af)) != NULL) { + if ((conn = fetch_cache_get(curl, af)) != NULL) { *cached = 1; return (conn); } - if ((conn = fetch_connect(URL, af, verbose)) == NULL) + if ((conn = fetch_connect(curl, af, verbose)) == NULL) /* fetch_connect() has already set an error code */ return (NULL); + if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) { + http_cmd(conn, "CONNECT %s:%d HTTP/1.1\r\n", + URL->host, URL->port); + http_cmd(conn, "Host: %s:%d\r\n", + URL->host, URL->port); + /* proxy authorization */ + if (*purl->user || *purl->pwd) + http_basic_auth(conn, "Proxy-Authorization", + purl->user, purl->pwd); + else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') + http_authorize(conn, "Proxy-Authorization", p); + http_cmd(conn, "\r\n"); + if (http_get_reply(conn) != HTTP_OK) { + http_seterr(conn->err); + goto ouch; + } + /* Read and discard the rest of the proxy response (if any) */ + do { + switch ((h = http_next_header(conn, &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, verbose) == -1) { - fetch_close(conn); + fetch_ssl(conn, URL, verbose) == -1) { /* grrr */ #ifdef EAUTH errno = EAUTH; #else errno = EPERM; #endif - fetch_syserr(); - return (NULL); + goto ouch; } -#ifdef TCP_NOPUSH +#if defined(TCP_NOPUSH) && !defined(__APPLE__) val = 1; setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val)); #endif return (conn); +ouch: + fetch_close(conn); + return (NULL); } static struct url * @@ -800,9 +849,9 @@ set_if_modified_since(conn_t *conn, time struct tm tm; char buf[80]; gmtime_r(&last_modified, &tm); - snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4d %02d:%02d:%02d GMT", + snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4ld %02d:%02d:%02d GMT", weekdays + tm.tm_wday * 3, tm.tm_mday, months + tm.tm_mon * 3, - tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); + (long)tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); http_cmd(conn, "If-Modified-Since: %s\r\n", buf); } @@ -898,7 +947,7 @@ http_request(struct url *URL, const char if (verbose) fetch_info("requesting %s://%s%s", url->scheme, host, url->doc); - if (purl) { + if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) { http_cmd(conn, "%s %s://%s%s HTTP/1.1\r\n", op, url->scheme, host, url->doc); } else { @@ -958,7 +1007,7 @@ http_request(struct url *URL, const char * be compatible with such configurations, fiddle with socket * options to force the pending data to be written. */ -#ifdef TCP_NOPUSH +#if defined(TCP_NOPUSH) && !defined(__APPLE__) val = 0; setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));