summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-06-23 16:23:51 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-06-25 09:57:19 +0200
commitd5ed571948a088468a2f4b9b457677e99fb80510 (patch)
tree6381e553674782cbdd6f59dbeec18ccc2715d7b0
parent31e53584db5879894809fbde5445aac7553ac3e2 (diff)
downloadcurl-d5ed571948a088468a2f4b9b457677e99fb80510.tar.gz
url: allow user + password to contain "control codes" for HTTP(S)
Reported-by: Jon Johnson Jr Fixes #5582 Closes #5592
-rw-r--r--lib/http.c6
-rw-r--r--lib/url.c29
-rw-r--r--lib/urldata.h2
3 files changed, 25 insertions, 12 deletions
diff --git a/lib/http.c b/lib/http.c
index 482f9ad0a..19e471ee6 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -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
diff --git a/lib/url.c b/lib/url.c
index 8163fb58b..4e5587d34 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -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)
diff --git a/lib/urldata.h b/lib/urldata.h
index 74b43abaa..3e44be87e 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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. */