url: allow user + password to contain "control codes" for HTTP(S)

Reported-by: Jon Johnson Jr
Fixes #5582
Closes #5592
This commit is contained in:
Daniel Stenberg 2020-06-23 16:23:51 +02:00
parent 31e53584db
commit d5ed571948
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 25 additions and 12 deletions

View File

@ -125,7 +125,8 @@ const struct Curl_handler Curl_handler_http = {
ZERO_NULL, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
PROTOPT_CREDSPERREQUEST /* flags */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL
};
#ifdef USE_SSL
@ -150,7 +151,8 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* connection_check */
PORT_HTTPS, /* defport */
CURLPROTO_HTTPS, /* protocol */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
PROTOPT_USERPWDCTRL
};
#endif

View File

@ -1894,23 +1894,32 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
if(result)
return result;
uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user,
CURLU_URLDECODE);
/* we don't use the URL API's URL decoder option here since it rejects
control codes and we want to allow them for some schemes in the user and
password fields */
uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
if(!uc) {
conn->user = strdup(data->state.up.user);
if(!conn->user)
return CURLE_OUT_OF_MEMORY;
char *decoded;
result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL,
conn->handler->flags&PROTOPT_USERPWDCTRL ?
REJECT_ZERO : REJECT_CTRL);
if(result)
return result;
conn->user = decoded;
conn->bits.user_passwd = TRUE;
}
else if(uc != CURLUE_NO_USER)
return Curl_uc_to_curlcode(uc);
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password,
CURLU_URLDECODE);
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
if(!uc) {
conn->passwd = strdup(data->state.up.password);
if(!conn->passwd)
return CURLE_OUT_OF_MEMORY;
char *decoded;
result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL,
conn->handler->flags&PROTOPT_USERPWDCTRL ?
REJECT_ZERO : REJECT_CTRL);
if(result)
return result;
conn->passwd = decoded;
conn->bits.user_passwd = TRUE;
}
else if(uc != CURLUE_NO_PASSWORD)

View File

@ -766,6 +766,8 @@ struct Curl_handler {
HTTP proxy as HTTP proxies may know
this protocol and act as a gateway */
#define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */
#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ascii) in
user name and password */
#define CONNCHECK_NONE 0 /* No checks */
#define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */