From 847724a86dac7394cf4c80e213a7742f4501f7b3 Mon Sep 17 00:00:00 2001 From: David von Oheimb Date: Thu, 1 Aug 2024 21:33:18 +0200 Subject: [PATCH] OSSL_HTTP_adapt_proxy(): fix handling of escaped IPv6 host addresses and of whitespace in no_proxy Reviewed-by: Viktor Dukhovni Reviewed-by: Tomas Mraz Reviewed-by: Neil Horman Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/25533) (cherry picked from commit b59b74fd07ed541df9d555dc62ca6dd3ac97365b) --- crypto/http/http_lib.c | 18 ++++++++++++++++-- doc/man3/OSSL_HTTP_parse_url.pod | 6 +++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c index cd0e25c85e4..44c8c0f89e4 100644 --- a/crypto/http/http_lib.c +++ b/crypto/http/http_lib.c @@ -9,11 +9,18 @@ #include /* for sscanf() */ #include +#ifndef OPENSSL_NO_SOCK +# include "../bio/bio_local.h" /* for NI_MAXHOST */ +#endif #include #include #include /* for BIO_snprintf() */ #include #include "internal/cryptlib.h" /* for ossl_assert() */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 255 +#endif +#include "crypto/ctype.h" /* for ossl_isspace() */ static void init_pstring(char **pstr) { @@ -251,10 +258,17 @@ static int use_proxy(const char *no_proxy, const char *server) { size_t sl; const char *found = NULL; + char host[NI_MAXHOST]; if (!ossl_assert(server != NULL)) return 0; sl = strlen(server); + if (sl >= 2 && sl < sizeof(host) + 2 && server[0] == '[' && server[sl - 1] == ']') { + /* strip leading '[' and trailing ']' from escaped IPv6 address */ + sl -= 2; + strncpy(host, server + 1, sl); + server = host; + } /* * using environment variable names, both lowercase and uppercase variants, @@ -268,8 +282,8 @@ static int use_proxy(const char *no_proxy, const char *server) if (no_proxy != NULL) found = strstr(no_proxy, server); while (found != NULL - && ((found != no_proxy && found[-1] != ' ' && found[-1] != ',') - || (found[sl] != '\0' && found[sl] != ' ' && found[sl] != ','))) + && ((found != no_proxy && !ossl_isspace(found[-1]) && found[-1] != ',') + || (found[sl] != '\0' && !ossl_isspace(found[sl]) && found[sl] != ','))) found = strstr(found + 1, server); return found == NULL; } diff --git a/doc/man3/OSSL_HTTP_parse_url.pod b/doc/man3/OSSL_HTTP_parse_url.pod index b9c59a9decb..f139f275aad 100644 --- a/doc/man3/OSSL_HTTP_parse_url.pod +++ b/doc/man3/OSSL_HTTP_parse_url.pod @@ -42,8 +42,12 @@ take any further default value from the C environment variable, or from C if I is nonzero. If I is NULL, take any default exclusion value from the C environment variable, or else from C. -Return the determined proxy hostname unless the exclusion contains I. +Return the determined proxy host unless the exclusion value, +which is a list of proxy hosts separated by C<,> and/or whitespace, +contains I. Otherwise return NULL. +In case I is a string enclosed with C<[> and C<]>, it is assumed to be +an escaped IPv6 address and so the C<[> and C<]> are ignored for the comparison. OSSL_parse_url() parses its input string I as a URL of the form C<[scheme://][userinfo@]host[:port][/path][?query][#fragment]> and splits it up -- 2.47.2