mirror of
https://github.com/curl/curl.git
synced 2026-07-27 23:53:06 +03:00
url: use same credentials on redirect
Previously it could lose the username and only use the password. Added test 998 and 999 to verify. Reported-by: Tobias Bora Fixes #15262 Closes #15282
This commit is contained in:
parent
eb77297ccc
commit
9bee39bfed
6 changed files with 257 additions and 73 deletions
|
|
@ -679,6 +679,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_USERNAME] ||
|
||||
data->set.str[STRING_PASSWORD])
|
||||
data->state.creds_from = CREDS_OPTION;
|
||||
if(!result)
|
||||
result = Curl_setstropt(&data->state.aptr.user,
|
||||
data->set.str[STRING_USERNAME]);
|
||||
|
|
|
|||
19
lib/url.c
19
lib/url.c
|
|
@ -1860,10 +1860,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
|||
return result;
|
||||
|
||||
/*
|
||||
* username and password set with their own options override the
|
||||
* credentials possibly set in the URL.
|
||||
* username and password set with their own options override the credentials
|
||||
* possibly set in the URL, but netrc does not.
|
||||
*/
|
||||
if(!data->set.str[STRING_PASSWORD]) {
|
||||
if(!data->state.aptr.passwd || (data->state.creds_from != CREDS_OPTION)) {
|
||||
uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
|
||||
if(!uc) {
|
||||
char *decoded;
|
||||
|
|
@ -1876,12 +1876,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
|||
result = Curl_setstropt(&data->state.aptr.passwd, decoded);
|
||||
if(result)
|
||||
return result;
|
||||
data->state.creds_from = CREDS_URL;
|
||||
}
|
||||
else if(uc != CURLUE_NO_PASSWORD)
|
||||
return Curl_uc_to_curlcode(uc);
|
||||
}
|
||||
|
||||
if(!data->set.str[STRING_USERNAME]) {
|
||||
if(!data->state.aptr.user || (data->state.creds_from != CREDS_OPTION)) {
|
||||
/* we do not 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 */
|
||||
|
|
@ -1895,13 +1896,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
|||
return result;
|
||||
conn->user = decoded;
|
||||
result = Curl_setstropt(&data->state.aptr.user, decoded);
|
||||
data->state.creds_from = CREDS_URL;
|
||||
}
|
||||
else if(uc != CURLUE_NO_USER)
|
||||
return Curl_uc_to_curlcode(uc);
|
||||
else if(data->state.aptr.passwd) {
|
||||
/* no user was set but a password, set a blank user */
|
||||
result = Curl_setstropt(&data->state.aptr.user, "");
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2685,7 +2683,8 @@ static CURLcode override_login(struct Curl_easy *data,
|
|||
int ret;
|
||||
bool url_provided = FALSE;
|
||||
|
||||
if(data->state.aptr.user) {
|
||||
if(data->state.aptr.user &&
|
||||
(data->state.creds_from != CREDS_NETRC)) {
|
||||
/* there was a username in the URL. Use the URL decoded version */
|
||||
userp = &data->state.aptr.user;
|
||||
url_provided = TRUE;
|
||||
|
|
@ -2733,6 +2732,7 @@ static CURLcode override_login(struct Curl_easy *data,
|
|||
result = Curl_setstropt(&data->state.aptr.user, *userp);
|
||||
if(result)
|
||||
return result;
|
||||
data->state.creds_from = CREDS_NETRC;
|
||||
}
|
||||
}
|
||||
if(data->state.aptr.user) {
|
||||
|
|
@ -2750,6 +2750,7 @@ static CURLcode override_login(struct Curl_easy *data,
|
|||
CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
|
||||
if(result)
|
||||
return result;
|
||||
data->state.creds_from = CREDS_NETRC;
|
||||
}
|
||||
if(data->state.aptr.passwd) {
|
||||
uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
|
||||
|
|
|
|||
|
|
@ -1206,6 +1206,11 @@ struct urlpieces {
|
|||
char *query;
|
||||
};
|
||||
|
||||
#define CREDS_NONE 0
|
||||
#define CREDS_URL 1 /* from URL */
|
||||
#define CREDS_OPTION 2 /* set with a CURLOPT_ */
|
||||
#define CREDS_NETRC 3 /* found in netrc */
|
||||
|
||||
struct UrlState {
|
||||
/* buffers to store authentication data in, as parsed from input options */
|
||||
struct curltime keeps_speed; /* for the progress meter really */
|
||||
|
|
@ -1344,7 +1349,6 @@ struct UrlState {
|
|||
char *proxypasswd;
|
||||
#endif
|
||||
} aptr;
|
||||
|
||||
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
|
||||
to be used in the library's request(s) */
|
||||
unsigned char httpversion; /* the lowest HTTP version*10 reported by any
|
||||
|
|
@ -1354,6 +1358,9 @@ struct UrlState {
|
|||
unsigned char select_bits; /* != 0 -> bitmask of socket events for this
|
||||
transfer overriding anything the socket may
|
||||
report */
|
||||
unsigned int creds_from:2; /* where is the server credentials originating
|
||||
from, see the CREDS_* defines above */
|
||||
|
||||
/* when curl_easy_perform() is called, the multi handle is "owned" by
|
||||
the easy handle so curl_easy_cleanup() on such an easy handle will
|
||||
also close the multi handle! */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue