diff --git a/external/bsd/fetch/dist/libfetch/common.c b/external/bsd/fetch/dist/libfetch/common.c index 6c17f7365046..e9377436afad 100644 --- a/external/bsd/fetch/dist/libfetch/common.c +++ b/external/bsd/fetch/dist/libfetch/common.c @@ -430,7 +430,7 @@ fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *)) * Enable SSL on a connection. */ int -fetch_ssl(conn_t *conn, int verbose) +fetch_ssl(conn_t *conn, int verbose, int verify) { #ifdef WITH_SSL @@ -445,6 +445,10 @@ fetch_ssl(conn_t *conn, int verbose) conn->ssl_meth = SSLv23_client_method(); conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY); + if (verify) { + SSL_CTX_set_default_verify_paths(conn->ssl_ctx); + SSL_CTX_set_verify(conn->ssl_ctx, SSL_VERIFY_PEER, NULL); + } conn->ssl = SSL_new(conn->ssl_ctx); if (conn->ssl == NULL){ diff --git a/external/bsd/fetch/dist/libfetch/common.h b/external/bsd/fetch/dist/libfetch/common.h index 2ca30090fc12..03abd8be5bde 100644 --- a/external/bsd/fetch/dist/libfetch/common.h +++ b/external/bsd/fetch/dist/libfetch/common.h @@ -98,7 +98,7 @@ conn_t *fetch_cache_get(const struct url *, int); 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 *, int, 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); diff --git a/external/bsd/fetch/dist/libfetch/fetch.3 b/external/bsd/fetch/dist/libfetch/fetch.3 index d4e4ce904890..58b64b99610c 100644 --- a/external/bsd/fetch/dist/libfetch/fetch.3 +++ b/external/bsd/fetch/dist/libfetch/fetch.3 @@ -27,7 +27,7 @@ .\" $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 $ .\" -.Dd January 22, 2010 +.Dd December 8, 2023 .Dt FETCH 3 .Os .Sh NAME @@ -357,6 +357,14 @@ functions is read-only, and that a stream returned by one of the functions is write-only. .Sh PROTOCOL INDEPENDENT FLAGS If the +.Ql V +(verify) flag is specified, the library will refuse to fetch from URLs +that can't be cryptographically verified. +This limits +.Nm +to HTTPS URLs fetched from servers with valid certificates. +.Pp +If the .Ql i (if-modified-since) flag is specified, the library will try to fetch the content only if it is newer than diff --git a/external/bsd/fetch/dist/libfetch/ftp.c b/external/bsd/fetch/dist/libfetch/ftp.c index 60fdbc65196c..c69757c9f8c1 100644 --- a/external/bsd/fetch/dist/libfetch/ftp.c +++ b/external/bsd/fetch/dist/libfetch/ftp.c @@ -1035,7 +1035,7 @@ static conn_t * ftp_connect(struct url *url, struct url *purl, const char *flags) { conn_t *conn; - int e, direct, verbose; + int e, direct, verbose, verify; #ifdef INET6 int af = AF_UNSPEC; #else @@ -1044,11 +1044,20 @@ ftp_connect(struct url *url, struct url *purl, const char *flags) direct = CHECK_FLAG('d'); verbose = CHECK_FLAG('v'); + verify = CHECK_FLAG('V'); if (CHECK_FLAG('4')) af = AF_INET; else if (CHECK_FLAG('6')) af = AF_INET6; + if (verify) { + /* can't verify FTP */ + fetchLastErrCode = FETCH_AUTH; + snprintf(fetchLastErrString, MAXERRSTRING, + "unable to authenticate %s:// URLs", url->scheme); + return (NULL); + } + if (direct) purl = NULL; diff --git a/external/bsd/fetch/dist/libfetch/http.c b/external/bsd/fetch/dist/libfetch/http.c index 5670eb22a93b..8259dd3126f2 100644 --- a/external/bsd/fetch/dist/libfetch/http.c +++ b/external/bsd/fetch/dist/libfetch/http.c @@ -711,7 +711,7 @@ static conn_t * http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) { conn_t *conn; - int af, verbose; + int af, verbose, verify; #ifdef TCP_NOPUSH int val; #endif @@ -725,6 +725,7 @@ http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) #endif verbose = CHECK_FLAG('v'); + verify = CHECK_FLAG('V'); if (CHECK_FLAG('4')) af = AF_INET; #ifdef INET6 @@ -740,6 +741,14 @@ http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) return (NULL); } + if (verify && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) { + /* can't verify non-HTTPS */ + fetchLastErrCode = FETCH_AUTH; + snprintf(fetchLastErrString, MAXERRSTRING, + "unable to authenticate %s:// URLs", URL->scheme); + return (NULL); + } + if ((conn = fetch_cache_get(URL, af)) != NULL) { *cached = 1; return (conn); @@ -749,7 +758,7 @@ http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) /* fetch_connect() has already set an error code */ return (NULL); if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && - fetch_ssl(conn, verbose) == -1) { + fetch_ssl(conn, verbose, verify) == -1) { fetch_close(conn); /* grrr */ #ifdef EAUTH diff --git a/external/bsd/pkg_install/dist/admin/audit.c b/external/bsd/pkg_install/dist/admin/audit.c index c08caa685f42..5c2ea0699587 100644 --- a/external/bsd/pkg_install/dist/admin/audit.c +++ b/external/bsd/pkg_install/dist/admin/audit.c @@ -318,12 +318,25 @@ fetch_pkg_vulnerabilities(int argc, char **argv) fetchLastErrString); flags = fetch_flags; + + /* + * If the user specified PKGVULNURL=http://... or ftp://... (or + * if that is the default), enable insecure transport to + * download it -- this way we don't break existing setups that + * never expected secure transport in the first place. + * + * If you want secure transport, use https or file URLs. + */ + if (strcasecmp(url->scheme, SCHEME_HTTP) == 0 || + strcasecmp(url->scheme, SCHEME_FTP)) + flags = insecure_fetch_flags; + if (update_pkg_vuln) { fd = open(pkg_vulnerabilities_file, O_RDONLY); if (fd != -1 && fstat(fd, &sb) != -1) { url->last_modified = sb.st_mtime; snprintf(my_flags, sizeof(my_flags), "%si", - fetch_flags); + flags); flags = my_flags; } else update_pkg_vuln = 0; diff --git a/external/bsd/pkg_install/dist/lib/lib.h b/external/bsd/pkg_install/dist/lib/lib.h index a5b184d20b98..1036ffcc8435 100644 --- a/external/bsd/pkg_install/dist/lib/lib.h +++ b/external/bsd/pkg_install/dist/lib/lib.h @@ -461,6 +461,7 @@ extern const char *gpg_keyring_sign; extern const char *gpg_keyring_verify; extern const char *gpg_sign_as; extern char fetch_flags[]; +extern char insecure_fetch_flags[]; extern const char *pkg_vulnerabilities_dir; extern const char *pkg_vulnerabilities_file; diff --git a/external/bsd/pkg_install/dist/lib/parse-config.c b/external/bsd/pkg_install/dist/lib/parse-config.c index aa30476cd72e..a2fb6f989800 100644 --- a/external/bsd/pkg_install/dist/lib/parse-config.c +++ b/external/bsd/pkg_install/dist/lib/parse-config.c @@ -58,6 +58,7 @@ static int cache_connections_host = 4; const char *config_file = SYSCONFDIR"/pkg_install.conf"; char fetch_flags[10] = ""; /* Workaround Mac OS X linker issues with BSS */ +char insecure_fetch_flags[10] = ""; static const char *active_ftp; static const char *verbose_netio; static const char *ignore_proxy; @@ -84,6 +85,7 @@ const char *pkg_vulnerabilities_dir; const char *pkg_vulnerabilities_file; const char *pkg_vulnerabilities_url; const char *ignore_advisories = NULL; +const char *insecure_transport = NULL; const char tnf_vulnerability_base[] = "http://cdn.NetBSD.org/pub/NetBSD/packages/vulns"; const char *acceptable_licenses = NULL; @@ -111,6 +113,7 @@ static struct config_variable { { "GPG_SIGN_AS", &gpg_sign_as }, { "IGNORE_PROXY", &ignore_proxy }, { "IGNORE_URL", &ignore_advisories }, + { "INSECURE_TRANSPORT", &insecure_transport }, { "PKG_DBDIR", &config_pkg_dbdir }, { "PKG_PATH", &config_pkg_path }, { "PKG_REFCOUNT_DBDIR", &config_pkg_refcount_dbdir }, @@ -244,11 +247,25 @@ pkg_install_config(void) fetchConnectionCacheInit(cache_connections, cache_connections_host); #endif - snprintf(fetch_flags, sizeof(fetch_flags), "%s%s%s%s", + snprintf(insecure_fetch_flags, sizeof(insecure_fetch_flags), + "%s%s%s%s", (do_cache_index) ? "c" : "", (verbose_netio && *verbose_netio) ? "v" : "", (active_ftp && *active_ftp) ? "a" : "", (ignore_proxy && *ignore_proxy) ? "d" : ""); + +#if defined(__NetBSD__) && __NetBSD_Version__ >= 1000000000 + snprintf(fetch_flags, sizeof(fetch_flags), "%s%s", + insecure_fetch_flags, + (insecure_transport && *insecure_transport) ? "" : "V"); +#else + /* + * Provisional until after pkgsrc-2023Q4 is branched -- don't + * require secure transports by default except on NetBSD 10. + */ + snprintf(fetch_flags, sizeof(fetch_flags), "%s", + insecure_fetch_flags); +#endif } void diff --git a/external/bsd/pkg_install/dist/lib/pkg_io.c b/external/bsd/pkg_install/dist/lib/pkg_io.c index 7432533893c1..016b4df5dd2d 100644 --- a/external/bsd/pkg_install/dist/lib/pkg_io.c +++ b/external/bsd/pkg_install/dist/lib/pkg_io.c @@ -65,6 +65,26 @@ struct pkg_path { static char *orig_cwd, *last_toplevel; static TAILQ_HEAD(, pkg_path) pkg_path = TAILQ_HEAD_INITIALIZER(pkg_path); +static const char * +pkg_fetch_flags(const struct url *url) +{ + + /* + * If the user specified PKG_PATH=http://... or ftp://..., or + * passed an http/ftp URL on the command line of a package to + * install, enable insecure transport to download it -- this + * way we don't break existing setups that never expected + * secure transport in the first place. + * + * If you want secure transport, use https or file URLs. + */ + if (strcasecmp(url->scheme, SCHEME_HTTP) == 0 || + strcasecmp(url->scheme, SCHEME_FTP) == 0) + return insecure_fetch_flags; + + return fetch_flags; +} + #ifndef BOOTSTRAP struct fetch_archive { struct url *url; @@ -80,7 +100,7 @@ fetch_archive_open(struct archive *a, void *client_data) struct fetch_archive *f = client_data; struct url_stat us; - f->fetch = fetchXGet(f->url, &us, fetch_flags); + f->fetch = fetchXGet(f->url, &us, pkg_fetch_flags(f->url)); if (f->fetch == NULL) return ENOENT; f->size = us.size; @@ -118,7 +138,7 @@ fetch_archive_read(struct archive *a, void *client_data, free(url); } fetchIO_close(f->fetch); - f->fetch = fetchXGet(f->url, &us, fetch_flags); + f->fetch = fetchXGet(f->url, &us, pkg_fetch_flags(f->url)); if (f->fetch == NULL) return -1; if (us.size != f->size) @@ -255,7 +275,7 @@ find_best_package_int(struct url *url, const char *pattern, url_pattern = xasprintf("%*.*s*", (int)i, (int)i, pattern); fetchInitURLList(&ue); - if (fetchList(&ue, url, url_pattern, fetch_flags)) { + if (fetchList(&ue, url, url_pattern, pkg_fetch_flags(url))) { char *base_url; base_url = fetchStringifyURL(url); warnx("Can't process %s/%s: %s", base_url, url_pattern,