url: reject ASCII control characters and space in host names

Host names like "127.0.0.1 moo" would otherwise be accepted by some
getaddrinfo() implementations.

Updated test 1034 and 1035 accordingly.

Fixes #2073
Closes #2092
This commit is contained in:
Daniel Stenberg 2017-11-17 16:48:37 +01:00
parent 9554c3c6e5
commit fa939220df
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 47 additions and 48 deletions

View File

@ -1687,7 +1687,7 @@ static bool is_ASCII_name(const char *hostname)
/* /*
* Perform any necessary IDN conversion of hostname * Perform any necessary IDN conversion of hostname
*/ */
static void fix_hostname(struct connectdata *conn, struct hostname *host) static CURLcode fix_hostname(struct connectdata *conn, struct hostname *host)
{ {
size_t len; size_t len;
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
@ -1727,9 +1727,11 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host)
/* change the name pointer to point to the encoded hostname */ /* change the name pointer to point to the encoded hostname */
host->name = host->encalloc; host->name = host->encalloc;
} }
else else {
infof(data, "Failed to convert %s to ACE; %s\n", host->name, failf(data, "Failed to convert %s to ACE; %s\n", host->name,
idn2_strerror(rc)); idn2_strerror(rc));
return CURLE_URL_MALFORMAT;
}
} }
#elif defined(USE_WIN32_IDN) #elif defined(USE_WIN32_IDN)
char *ace_hostname = NULL; char *ace_hostname = NULL;
@ -1739,12 +1741,24 @@ static void fix_hostname(struct connectdata *conn, struct hostname *host)
/* change the name pointer to point to the encoded hostname */ /* change the name pointer to point to the encoded hostname */
host->name = host->encalloc; host->name = host->encalloc;
} }
else else {
infof(data, "Failed to convert %s to ACE;\n", host->name); failf(data, "Failed to convert %s to ACE;\n", host->name);
return CURLE_URL_MALFORMAT;
}
#else #else
infof(data, "IDN support not present, can't parse Unicode domains\n"); infof(data, "IDN support not present, can't parse Unicode domains\n");
#endif #endif
} }
{
char *hostp;
for(hostp = host->name; *hostp; hostp++) {
if(*hostp <= 32) {
failf(data, "Host name '%s' contains bad letter", host->name);
return CURLE_URL_MALFORMAT;
}
}
}
return CURLE_OK;
} }
/* /*
@ -4178,13 +4192,24 @@ static CURLcode create_conn(struct Curl_easy *data,
/************************************************************* /*************************************************************
* IDN-fix the hostnames * IDN-fix the hostnames
*************************************************************/ *************************************************************/
fix_hostname(conn, &conn->host); result = fix_hostname(conn, &conn->host);
if(conn->bits.conn_to_host) if(result)
fix_hostname(conn, &conn->conn_to_host); goto out;
if(conn->bits.httpproxy) if(conn->bits.conn_to_host) {
fix_hostname(conn, &conn->http_proxy.host); result = fix_hostname(conn, &conn->conn_to_host);
if(conn->bits.socksproxy) if(result)
fix_hostname(conn, &conn->socks_proxy.host); goto out;
}
if(conn->bits.httpproxy) {
result = fix_hostname(conn, &conn->http_proxy.host);
if(result)
goto out;
}
if(conn->bits.socksproxy) {
result = fix_hostname(conn, &conn->socks_proxy.host);
if(result)
goto out;
}
/************************************************************* /*************************************************************
* Check whether the host and the "connect to host" are equal. * Check whether the host and the "connect to host" are equal.

View File

@ -13,24 +13,17 @@ config file
# #
# Server-side # Server-side
<reply> <reply>
<data>
HTTP/1.0 503 Service Unavailable
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake swsclose
Content-Type: text/html
Funny-head: yesyes
</data>
</reply> </reply>
# #
# Client-side # Client-side
<client> <client>
<server> <server>
http none
</server> </server>
<features> <features>
idn idn
http
</features> </features>
<setenv> <setenv>
LC_ALL= LC_ALL=
@ -54,17 +47,9 @@ url = "http://invalid-utf8-
</client> </client>
# #
# Verify data after the test has been "shot"
<verify> <verify>
<strip> <errorcode>
^User-Agent:.* 3
</strip> </errorcode>
<protocol>
GET http://invalid-utf8-â<>.local/page/1034 HTTP/1.1
Host: invalid-utf8-â<>.local
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
</verify> </verify>
</testcase> </testcase>

View File

@ -12,24 +12,17 @@ FAILURE
# #
# Server-side # Server-side
<reply> <reply>
<data>
HTTP/1.0 503 Service Unavailable
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake swsclose
Content-Type: text/html
Funny-head: yesyes
</data>
</reply> </reply>
# #
# Client-side # Client-side
<client> <client>
<server> <server>
http none
</server> </server>
<features> <features>
idn idn
http
</features> </features>
<setenv> <setenv>
LC_ALL= LC_ALL=
@ -52,12 +45,8 @@ http://too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local/page/10
<strip> <strip>
^User-Agent:.* ^User-Agent:.*
</strip> </strip>
<protocol> <errorcode>
GET http://too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local/page/1035 HTTP/1.1 3
Host: too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local </errorcode>
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
</verify> </verify>
</testcase> </testcase>