noproxy: support for space-separated names is deprecated

To be removed in July 2024.

Assisted-by: Michael Osipov
Fixes #10209
Closes #10215
This commit is contained in:
Daniel Stenberg 2023-01-03 14:58:37 +01:00
parent bb393e521f
commit 7ad8a7ba9e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 88 additions and 44 deletions

View File

@ -52,6 +52,25 @@ We remove support for building curl with the gskit TLS library in August 2023.
- build breakages in this code take weeks or more to get detected
- fixing gskit code is mostly done "flying blind"
## space-separated `NOPROXY` patterns
When specifying patterns/domain names for curl that should *not* go through a
proxy, the curl tool features the `--noproxy` command line option and the
library supports the `NO_PROXY` environment variable and the `CURLOPT_NOPROXY`
libcurl option.
They all set the same list of patterns. This list is documented to be a set of
**comma-separated** names, but can also be provided separated with just
space. The ability to just use spaces for this has never been documented but
some users may still have come to rely on this.
Several other tools and utilities also parse the `NO_PROXY` environment
variable but do not consider a space to be a valid separator. Using spaces for
separator is probably less portable and might cause more friction than commas
do. Users should use commas for this for greater portability.
curl will remove the support for space-separated names in July 2024.
## past removals
- Pipelining

View File

@ -119,8 +119,10 @@ enum nametype {
* Checks if the host is in the noproxy list. returns TRUE if it matches and
* therefore the proxy should NOT be used.
****************************************************************/
bool Curl_check_noproxy(const char *name, const char *no_proxy)
bool Curl_check_noproxy(const char *name, const char *no_proxy,
bool *spacesep)
{
*spacesep = FALSE;
/*
* If we don't have a hostname at all, like for example with a FILE
* transfer, we have nothing to interrogate the noproxy list with.
@ -244,6 +246,15 @@ bool Curl_check_noproxy(const char *name, const char *no_proxy)
if(match)
return TRUE;
} /* if(tokenlen) */
/* pass blanks after pattern */
while(ISBLANK(*p))
p++;
/* if not a comma! */
if(*p && (*p != ',')) {
*spacesep = TRUE;
continue;
}
/* pass any number of commas */
while(*p == ',')
p++;
} /* while(*p) */

View File

@ -37,7 +37,8 @@ UNITTEST bool Curl_cidr6_match(const char *ipv6,
unsigned int bits);
#endif
bool Curl_check_noproxy(const char *name, const char *no_proxy);
bool Curl_check_noproxy(const char *name, const char *no_proxy,
bool *spacesep);
#endif

View File

@ -2401,6 +2401,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
char *socksproxy = NULL;
char *no_proxy = NULL;
CURLcode result = CURLE_OK;
bool spacesep = FALSE;
/*************************************************************
* Extract the user and password from the authentication string
@ -2447,7 +2448,8 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
}
if(Curl_check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
data->set.str[STRING_NOPROXY] : no_proxy)) {
data->set.str[STRING_NOPROXY] : no_proxy,
&spacesep)) {
Curl_safefree(proxy);
Curl_safefree(socksproxy);
}
@ -2456,6 +2458,8 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
/* if the host is not in the noproxy list, detect proxy. */
proxy = detect_proxy(data, conn);
#endif /* CURL_DISABLE_HTTP */
if(spacesep)
infof(data, "space-separated NOPROXY patterns are deprecated");
Curl_safefree(no_proxy);

View File

@ -46,6 +46,7 @@ struct noproxy {
const char *a;
const char *n;
bool match;
bool space; /* space separated */
};
UNITTEST_START
@ -77,50 +78,52 @@ UNITTEST_START
{ NULL, NULL, 0, FALSE} /* end marker */
};
struct noproxy list[]= {
{ "www.example.com", "localhost,.example.com,.example.de", TRUE},
{ "www.example.com.", "localhost,.example.com,.example.de", TRUE},
{ "example.com", "localhost,.example.com,.example.de", TRUE},
{ "example.com.", "localhost,.example.com,.example.de", TRUE},
{ "www.example.com", "localhost,.example.com.,.example.de", TRUE},
{ "www.example.com", "localhost,www.example.com.,.example.de", TRUE},
{ "example.com", "localhost,example.com,.example.de", TRUE},
{ "example.com.", "localhost,example.com,.example.de", TRUE},
{ "nexample.com", "localhost,example.com,.example.de", FALSE},
{ "www.example.com", "localhost,example.com,.example.de", TRUE},
{ "127.0.0.1", "127.0.0.1,localhost", TRUE},
{ "127.0.0.1", "127.0.0.1,localhost,", TRUE},
{ "127.0.0.1", "127.0.0.1/8,localhost,", TRUE},
{ "127.0.0.1", "127.0.0.1/28,localhost,", TRUE},
{ "127.0.0.1", "127.0.0.1/31,localhost,", TRUE},
{ "127.0.0.1", "localhost,127.0.0.1", TRUE},
{ "www.example.com", "localhost .example.com .example.de", TRUE, TRUE},
{ "www.example.com", "localhost,.example.com,.example.de", TRUE, FALSE},
{ "www.example.com.", "localhost,.example.com,.example.de", TRUE, FALSE},
{ "example.com", "localhost,.example.com,.example.de", TRUE, FALSE},
{ "example.com.", "localhost,.example.com,.example.de", TRUE, FALSE},
{ "www.example.com", "localhost,.example.com.,.example.de", TRUE, FALSE},
{ "www.example.com", "localhost,www.example.com.,.example.de",
TRUE, FALSE},
{ "example.com", "localhost,example.com,.example.de", TRUE, FALSE},
{ "example.com.", "localhost,example.com,.example.de", TRUE, FALSE},
{ "nexample.com", "localhost,example.com,.example.de", FALSE, FALSE},
{ "www.example.com", "localhost,example.com,.example.de", TRUE, FALSE},
{ "127.0.0.1", "127.0.0.1,localhost", TRUE, FALSE},
{ "127.0.0.1", "127.0.0.1,localhost,", TRUE, FALSE},
{ "127.0.0.1", "127.0.0.1/8,localhost,", TRUE, FALSE},
{ "127.0.0.1", "127.0.0.1/28,localhost,", TRUE, FALSE},
{ "127.0.0.1", "127.0.0.1/31,localhost,", TRUE, FALSE},
{ "127.0.0.1", "localhost,127.0.0.1", TRUE, FALSE},
{ "127.0.0.1", "localhost,127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1."
"127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127."
"0.0.1.127.0.0.1.127.0.0." /* 128 bytes "address" */, FALSE},
"0.0.1.127.0.0.1.127.0.0." /* 128 bytes "address" */, FALSE, FALSE},
{ "127.0.0.1", "localhost,127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1."
"127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127.0.0.1.127."
"0.0.1.127.0.0.1.127.0.0" /* 127 bytes "address" */, FALSE},
{ "localhost", "localhost,127.0.0.1", TRUE},
{ "localhost", "127.0.0.1,localhost", TRUE},
{ "foobar", "barfoo", FALSE},
{ "foobar", "foobar", TRUE},
{ "192.168.0.1", "foobar", FALSE},
{ "192.168.0.1", "192.168.0.0/16", TRUE},
{ "192.168.0.1", "192.168.0.0/24", TRUE},
{ "192.168.0.1", "192.168.0.0/32", FALSE},
{ "192.168.0.1", "192.168.0.0", FALSE},
{ "192.168.1.1", "192.168.0.0/24", FALSE},
{ "192.168.1.1", "foo, bar, 192.168.0.0/24", FALSE},
{ "192.168.1.1", "foo, bar, 192.168.0.0/16", TRUE},
{ "[::1]", "foo, bar, 192.168.0.0/16", FALSE},
{ "[::1]", "foo, bar, ::1/64", TRUE},
{ "bar", "foo, bar, ::1/64", TRUE},
{ "BAr", "foo, bar, ::1/64", TRUE},
{ "BAr", "foo,,,,, bar, ::1/64", TRUE},
{ "www.example.com", "foo, .example.com", TRUE},
{ "www.example.com", "www2.example.com, .example.net", FALSE},
{ "example.com", ".example.com, .example.net", TRUE},
{ "nonexample.com", ".example.com, .example.net", FALSE},
{ NULL, NULL, FALSE}
"0.0.1.127.0.0.1.127.0.0" /* 127 bytes "address" */, FALSE, FALSE},
{ "localhost", "localhost,127.0.0.1", TRUE, FALSE},
{ "localhost", "127.0.0.1,localhost", TRUE, FALSE},
{ "foobar", "barfoo", FALSE, FALSE},
{ "foobar", "foobar", TRUE, FALSE},
{ "192.168.0.1", "foobar", FALSE, FALSE},
{ "192.168.0.1", "192.168.0.0/16", TRUE, FALSE},
{ "192.168.0.1", "192.168.0.0/24", TRUE, FALSE},
{ "192.168.0.1", "192.168.0.0/32", FALSE, FALSE},
{ "192.168.0.1", "192.168.0.0", FALSE, FALSE},
{ "192.168.1.1", "192.168.0.0/24", FALSE, FALSE},
{ "192.168.1.1", "foo, bar, 192.168.0.0/24", FALSE, FALSE},
{ "192.168.1.1", "foo, bar, 192.168.0.0/16", TRUE, FALSE},
{ "[::1]", "foo, bar, 192.168.0.0/16", FALSE, FALSE},
{ "[::1]", "foo, bar, ::1/64", TRUE, FALSE},
{ "bar", "foo, bar, ::1/64", TRUE, FALSE},
{ "BAr", "foo, bar, ::1/64", TRUE, FALSE},
{ "BAr", "foo,,,,, bar, ::1/64", TRUE, FALSE},
{ "www.example.com", "foo, .example.com", TRUE, FALSE},
{ "www.example.com", "www2.example.com, .example.net", FALSE, FALSE},
{ "example.com", ".example.com, .example.net", TRUE, FALSE},
{ "nonexample.com", ".example.com, .example.net", FALSE, FALSE},
{ NULL, NULL, FALSE, FALSE}
};
for(i = 0; list4[i].a; i++) {
bool match = Curl_cidr4_match(list4[i].a, list4[i].n, list4[i].bits);
@ -141,13 +144,19 @@ UNITTEST_START
}
}
for(i = 0; list[i].a; i++) {
bool match = Curl_check_noproxy(list[i].a, list[i].n);
bool spacesep = FALSE;
bool match = Curl_check_noproxy(list[i].a, list[i].n, &spacesep);
if(match != list[i].match) {
fprintf(stderr, "%s in %s should %smatch\n",
list[i].a, list[i].n,
list[i].match ? "": "not ");
err++;
}
if(spacesep != list[i].space) {
fprintf(stderr, "%s is claimed to be %sspace separated\n",
list[i].n, list[i].space?"":"NOT ");
err++;
}
}
return err;
}