diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2017-11-17 16:48:37 +0100 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2017-11-22 11:14:06 +0100 | 
| commit | fa939220dfff7607ed7b0522b549ecb482a5e1ac (patch) | |
| tree | 9bca9d18c034a82b117525900fb27a4aa37986af /lib | |
| parent | 9554c3c6e56e23153d4e1025b62c7a6402464a7c (diff) | |
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
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/url.c | 49 | 
1 files changed, 37 insertions, 12 deletions
@@ -1687,7 +1687,7 @@ static bool is_ASCII_name(const char *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;    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 */          host->name = host->encalloc;        } -      else -        infof(data, "Failed to convert %s to ACE; %s\n", host->name, +      else { +        failf(data, "Failed to convert %s to ACE; %s\n", host->name,                idn2_strerror(rc)); +        return CURLE_URL_MALFORMAT; +      }      }  #elif defined(USE_WIN32_IDN)      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 */        host->name = host->encalloc;      } -    else -      infof(data, "Failed to convert %s to ACE;\n", host->name); +    else { +      failf(data, "Failed to convert %s to ACE;\n", host->name); +      return CURLE_URL_MALFORMAT; +    }  #else      infof(data, "IDN support not present, can't parse Unicode domains\n");  #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     *************************************************************/ -  fix_hostname(conn, &conn->host); -  if(conn->bits.conn_to_host) -    fix_hostname(conn, &conn->conn_to_host); -  if(conn->bits.httpproxy) -    fix_hostname(conn, &conn->http_proxy.host); -  if(conn->bits.socksproxy) -    fix_hostname(conn, &conn->socks_proxy.host); +  result = fix_hostname(conn, &conn->host); +  if(result) +    goto out; +  if(conn->bits.conn_to_host) { +    result = fix_hostname(conn, &conn->conn_to_host); +    if(result) +      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.  | 
