diff options
Diffstat (limited to 'lib/url.c')
-rw-r--r-- | lib/url.c | 190 |
1 files changed, 106 insertions, 84 deletions
@@ -449,6 +449,10 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_safefree(data->state.aptr.host); Curl_safefree(data->state.aptr.cookiehost); Curl_safefree(data->state.aptr.rtsp_transport); + Curl_safefree(data->state.aptr.user); + Curl_safefree(data->state.aptr.passwd); + Curl_safefree(data->state.aptr.proxyuser); + Curl_safefree(data->state.aptr.proxypasswd); #ifndef CURL_DISABLE_DOH if(data->req.doh) { @@ -1699,11 +1703,11 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) } conn->bits.proxy_user_passwd = - (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE; + (data->state.aptr.proxyuser) ? TRUE : FALSE; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; #endif /* CURL_DISABLE_PROXY */ - conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; + conn->bits.user_passwd = (data->state.aptr.user) ? TRUE : FALSE; #ifndef CURL_DISABLE_FTP conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; @@ -1970,36 +1974,50 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(result) return result; - /* 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) { - 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; + /* + * User name and password set with their own options override the + * credentials possibly set in the URL. + */ + if(!data->state.aptr.user) { + /* 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) { + 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; + result = Curl_setstropt(&data->state.aptr.user, decoded); + if(result) + return result; + } + else if(uc != CURLUE_NO_USER) + return Curl_uc_to_curlcode(uc); } - else if(uc != CURLUE_NO_USER) - return Curl_uc_to_curlcode(uc); - uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); - if(!uc) { - 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; + if(!data->state.aptr.passwd) { + uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); + if(!uc) { + 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; + result = Curl_setstropt(&data->state.aptr.passwd, decoded); + if(result) + return result; + } + else if(uc != CURLUE_NO_PASSWORD) + return Curl_uc_to_curlcode(uc); } - else if(uc != CURLUE_NO_PASSWORD) - return Curl_uc_to_curlcode(uc); uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options, CURLU_URLDECODE); @@ -2390,6 +2408,10 @@ static CURLcode parse_proxy(struct Curl_easy *data, if(proxyuser || proxypasswd) { Curl_safefree(proxyinfo->user); proxyinfo->user = proxyuser; + result = Curl_setstropt(&data->state.aptr.proxyuser, + proxyuser); + if(result) + goto error; Curl_safefree(proxyinfo->passwd); if(!proxypasswd) { proxypasswd = strdup(""); @@ -2399,6 +2421,10 @@ static CURLcode parse_proxy(struct Curl_easy *data, } } proxyinfo->passwd = proxypasswd; + result = Curl_setstropt(&data->state.aptr.proxypasswd, + proxypasswd); + if(result) + goto error; conn->bits.proxy_user_passwd = TRUE; /* enable it */ } @@ -2455,18 +2481,26 @@ static CURLcode parse_proxy(struct Curl_easy *data, static CURLcode parse_proxy_auth(struct Curl_easy *data, struct connectdata *conn) { - const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ? - data->set.str[STRING_PROXYUSERNAME] : ""; - const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ? - data->set.str[STRING_PROXYPASSWORD] : ""; + const char *proxyuser = data->state.aptr.proxyuser ? + data->state.aptr.proxyuser : ""; + const char *proxypasswd = data->state.aptr.proxypasswd ? + data->state.aptr.proxypasswd : ""; CURLcode result = CURLE_OK; - if(proxyuser) + if(proxyuser) { result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL, REJECT_ZERO); - if(!result && proxypasswd) + if(!result) + result = Curl_setstropt(&data->state.aptr.proxyuser, + conn->http_proxy.user); + } + if(!result && proxypasswd) { result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd, NULL, REJECT_ZERO); + if(!result) + result = Curl_setstropt(&data->state.aptr.proxypasswd, + conn->http_proxy.passwd); + } return result; } @@ -2808,44 +2842,19 @@ static CURLcode parse_remote_port(struct Curl_easy *data, * option or a .netrc file, if applicable. */ static CURLcode override_login(struct Curl_easy *data, - struct connectdata *conn, - char **userp, char **passwdp, char **optionsp) + struct connectdata *conn) { - bool user_changed = FALSE; - bool passwd_changed = FALSE; CURLUcode uc; + char **userp = &conn->user; + char **passwdp = &conn->passwd; + char **optionsp = &conn->options; if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) { - /* ignore user+password in the URL */ - if(*userp) { - Curl_safefree(*userp); - user_changed = TRUE; - } - if(*passwdp) { - Curl_safefree(*passwdp); - passwd_changed = TRUE; - } + Curl_safefree(*userp); + Curl_safefree(*passwdp); conn->bits.user_passwd = FALSE; /* disable user+password */ } - if(data->set.str[STRING_USERNAME]) { - free(*userp); - *userp = strdup(data->set.str[STRING_USERNAME]); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - conn->bits.user_passwd = TRUE; /* enable user+password */ - user_changed = TRUE; - } - - if(data->set.str[STRING_PASSWORD]) { - free(*passwdp); - *passwdp = strdup(data->set.str[STRING_PASSWORD]); - if(!*passwdp) - return CURLE_OUT_OF_MEMORY; - conn->bits.user_passwd = TRUE; /* enable user+password */ - passwd_changed = TRUE; - } - if(data->set.str[STRING_OPTIONS]) { free(*optionsp); *optionsp = strdup(data->set.str[STRING_OPTIONS]); @@ -2854,8 +2863,7 @@ static CURLcode override_login(struct Curl_easy *data, } conn->bits.netrc = FALSE; - if(data->set.use_netrc != CURL_NETRC_IGNORED && - (!*userp || !**userp || !*passwdp || !**passwdp)) { + if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { bool netrc_user_changed = FALSE; bool netrc_passwd_changed = FALSE; int ret; @@ -2865,8 +2873,8 @@ static CURLcode override_login(struct Curl_easy *data, &netrc_user_changed, &netrc_passwd_changed, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { - infof(data, "Couldn't find host %s in the .netrc file; using defaults\n", - conn->host.name); + infof(data, "Couldn't find host %s in the %s file; using defaults\n", + conn->host.name, data->set.str[STRING_NETRC_FILE]); } else if(ret < 0) { return CURLE_OUT_OF_MEMORY; @@ -2877,29 +2885,44 @@ static CURLcode override_login(struct Curl_easy *data, different host or similar. */ conn->bits.netrc = TRUE; conn->bits.user_passwd = TRUE; /* enable user+password */ - - if(netrc_user_changed) { - user_changed = TRUE; - } - if(netrc_passwd_changed) { - passwd_changed = TRUE; - } } } /* for updated strings, we update them in the URL */ - if(user_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, + if(*userp) { + CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp); + if(result) + return result; + } + if(data->state.aptr.user) { + uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user, CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); + if(!*userp) { + *userp = strdup(data->state.aptr.user); + if(!*userp) + return CURLE_OUT_OF_MEMORY; + } } - if(passwd_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, - CURLU_URLENCODE); + + if(*passwdp) { + CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp); + if(result) + return result; + } + if(data->state.aptr.passwd) { + uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, + data->state.aptr.passwd, CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); + if(!*passwdp) { + *passwdp = strdup(data->state.aptr.passwd); + if(!*passwdp) + return CURLE_OUT_OF_MEMORY; + } } + return CURLE_OK; } @@ -3560,8 +3583,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* Check for overridden login details and set them accordingly so they they are known when protocol->setup_connection is called! */ - result = override_login(data, conn, &conn->user, &conn->passwd, - &conn->options); + result = override_login(data, conn); if(result) goto out; |