Merge branch 'ap/http-preserve-wwwauth-redirect' into jch
When an HTTP request triggers a redirect and the target yields an authentication challenge, the WWW-Authenticate headers received during the redirect are now explicitly preserved across the credential URL update, fixing an issue where they were incorrectly cleared. * ap/http-preserve-wwwauth-redirect: http: preserve wwwauth_headers across redirectsjch
commit
1628a153f4
16
credential.c
16
credential.c
|
|
@ -708,3 +708,19 @@ void credential_from_url(struct credential *c, const char *url)
|
|||
if (credential_from_url_gently(c, url, 0) < 0)
|
||||
die(_("credential url cannot be parsed: %s"), url);
|
||||
}
|
||||
|
||||
void credential_update_url(struct credential *c, const char *url)
|
||||
{
|
||||
struct strvec wwwauth_headers = STRVEC_INIT;
|
||||
|
||||
/*
|
||||
* credential_from_url() clears the whole credential. Preserve the
|
||||
* WWW-Authenticate list, which is derived from the server's original
|
||||
* response rather than from the URL and is required to authenticate to
|
||||
* the new URL.
|
||||
*/
|
||||
SWAP(wwwauth_headers, c->wwwauth_headers);
|
||||
credential_from_url(c, url);
|
||||
SWAP(c->wwwauth_headers, wwwauth_headers);
|
||||
strvec_clear(&wwwauth_headers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,6 +305,14 @@ void credential_write(const struct credential *, FILE *,
|
|||
void credential_from_url(struct credential *, const char *url);
|
||||
int credential_from_url_gently(struct credential *, const char *url, int quiet);
|
||||
|
||||
/*
|
||||
* Update the URL-derived fields (protocol, host, path) of an existing
|
||||
* credential to match a new URL. Unlike credential_from_url(), this function
|
||||
* preserves state that was derived from a server's HTTP redirect response,
|
||||
* such as the WWW-Authenticate headers.
|
||||
*/
|
||||
void credential_update_url(struct credential *c, const char *url);
|
||||
|
||||
int credential_match(const struct credential *want,
|
||||
const struct credential *have, int match_password);
|
||||
|
||||
|
|
|
|||
9
http.c
9
http.c
|
|
@ -2429,7 +2429,14 @@ static int http_request_recoverable(const char *url,
|
|||
if (options->effective_url && options->base_url) {
|
||||
if (update_url_from_redirect(options->base_url,
|
||||
url, options->effective_url)) {
|
||||
credential_from_url(&http_auth, options->base_url->buf);
|
||||
/*
|
||||
* Use credential_update_url() rather than
|
||||
* credential_from_url() so that the WWW-Authenticate
|
||||
* challenge the server sent with the redirect target's
|
||||
* response is preserved and handed to the credential
|
||||
* helper.
|
||||
*/
|
||||
credential_update_url(&http_auth, options->base_url->buf);
|
||||
url = options->effective_url->buf;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ RewriteRule ^/dumb-redir/(.*)$ /dumb/$1 [R=301]
|
|||
RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301]
|
||||
RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
|
||||
RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301]
|
||||
RewriteRule ^/custom_auth_redir/(.*)$ /custom_auth/$1 [R=302]
|
||||
RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301]
|
||||
RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302]
|
||||
|
||||
|
|
|
|||
|
|
@ -557,6 +557,51 @@ test_expect_success 'access using bearer auth' '
|
|||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'bearer auth after redirect preserves wwwauth headers' '
|
||||
test_when_finished "per_test_cleanup" &&
|
||||
|
||||
set_credential_reply get <<-EOF &&
|
||||
capability[]=authtype
|
||||
authtype=Bearer
|
||||
credential=YS1naXQtdG9rZW4=
|
||||
EOF
|
||||
|
||||
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
||||
id=1 creds=Bearer YS1naXQtdG9rZW4=
|
||||
EOF
|
||||
|
||||
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
||||
id=1 status=200
|
||||
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
|
||||
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
||||
id=default response=WWW-Authenticate: Basic realm="example.com"
|
||||
EOF
|
||||
|
||||
test_config_global credential.helper test-helper &&
|
||||
test_config_global credential.useHttpPath true &&
|
||||
git ls-remote "$HTTPD_URL/custom_auth_redir/repo.git" &&
|
||||
|
||||
expect_credential_query get <<-EOF &&
|
||||
capability[]=authtype
|
||||
capability[]=state
|
||||
protocol=http
|
||||
host=$HTTPD_DEST
|
||||
path=custom_auth/repo.git
|
||||
wwwauth[]=FooBar param1="value1" param2="value2"
|
||||
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
||||
wwwauth[]=Basic realm="example.com"
|
||||
EOF
|
||||
|
||||
expect_credential_query store <<-EOF
|
||||
capability[]=authtype
|
||||
authtype=Bearer
|
||||
credential=YS1naXQtdG9rZW4=
|
||||
protocol=http
|
||||
host=$HTTPD_DEST
|
||||
path=custom_auth/repo.git
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'access using bearer auth with invalid credentials' '
|
||||
test_when_finished "per_test_cleanup" &&
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue