mirror of
https://github.com/moparisthebest/curl
synced 2024-11-11 03:55:03 -05:00
auth: only ever pick CURLAUTH_BEARER if we *have* a Bearer token
The Bearer authentication was added to cURL 7.61.0, but there is a problem: if CURLAUTH_ANY is selected, and the server supports multiple authentication methods including the Bearer method, we strongly prefer that latter method (only CURLAUTH_NEGOTIATE beats it), and if the Bearer authentication fails, we will never even try to attempt any other method. This is particularly unfortunate when we already know that we do not have any Bearer token to work with. Such a scenario happens e.g. when using Git to push to Visual Studio Team Services (which supports Basic and Bearer authentication among other methods) and specifying the Personal Access Token directly in the URL (this aproach is frequently taken by automated builds). Let's make sure that we have a Bearer token to work with before we select the Bearer authentication among the available authentication methods. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Closes #2754
This commit is contained in:
parent
26e35844e7
commit
df57b439f4
13
lib/http.c
13
lib/http.c
@ -342,11 +342,11 @@ static CURLcode http_output_bearer(struct connectdata *conn)
|
|||||||
*
|
*
|
||||||
* return TRUE if one was picked
|
* return TRUE if one was picked
|
||||||
*/
|
*/
|
||||||
static bool pickoneauth(struct auth *pick)
|
static bool pickoneauth(struct auth *pick, unsigned long mask)
|
||||||
{
|
{
|
||||||
bool picked;
|
bool picked;
|
||||||
/* only deal with authentication we want */
|
/* only deal with authentication we want */
|
||||||
unsigned long avail = pick->avail & pick->want;
|
unsigned long avail = pick->avail & pick->want & mask;
|
||||||
picked = TRUE;
|
picked = TRUE;
|
||||||
|
|
||||||
/* The order of these checks is highly relevant, as this will be the order
|
/* The order of these checks is highly relevant, as this will be the order
|
||||||
@ -508,6 +508,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|||||||
bool pickhost = FALSE;
|
bool pickhost = FALSE;
|
||||||
bool pickproxy = FALSE;
|
bool pickproxy = FALSE;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
unsigned long authmask = ~0ul;
|
||||||
|
|
||||||
|
if(!conn->oauth_bearer)
|
||||||
|
authmask &= (unsigned long)~CURLAUTH_BEARER;
|
||||||
|
|
||||||
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
|
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
|
||||||
/* this is a transient response code, ignore */
|
/* this is a transient response code, ignore */
|
||||||
@ -519,14 +523,15 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|||||||
if(conn->bits.user_passwd &&
|
if(conn->bits.user_passwd &&
|
||||||
((data->req.httpcode == 401) ||
|
((data->req.httpcode == 401) ||
|
||||||
(conn->bits.authneg && data->req.httpcode < 300))) {
|
(conn->bits.authneg && data->req.httpcode < 300))) {
|
||||||
pickhost = pickoneauth(&data->state.authhost);
|
pickhost = pickoneauth(&data->state.authhost, authmask);
|
||||||
if(!pickhost)
|
if(!pickhost)
|
||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
if(conn->bits.proxy_user_passwd &&
|
if(conn->bits.proxy_user_passwd &&
|
||||||
((data->req.httpcode == 407) ||
|
((data->req.httpcode == 407) ||
|
||||||
(conn->bits.authneg && data->req.httpcode < 300))) {
|
(conn->bits.authneg && data->req.httpcode < 300))) {
|
||||||
pickproxy = pickoneauth(&data->state.authproxy);
|
pickproxy = pickoneauth(&data->state.authproxy,
|
||||||
|
authmask & ~CURLAUTH_BEARER);
|
||||||
if(!pickproxy)
|
if(!pickproxy)
|
||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user