aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--http.c48
-rw-r--r--http.h3
-rw-r--r--remote-curl.c4
-rwxr-xr-xt/t5563-simple-http-auth.sh133
4 files changed, 176 insertions, 12 deletions
diff --git a/http.c b/http.c
index 54ddff03fb..906eb098c8 100644
--- a/http.c
+++ b/http.c
@@ -561,18 +561,34 @@ static int curl_empty_auth_enabled(void)
return 0;
}
+struct curl_slist *http_append_auth_header(const struct credential *c,
+ struct curl_slist *headers)
+{
+ if (c->authtype && c->credential) {
+ struct strbuf auth = STRBUF_INIT;
+ strbuf_addf(&auth, "Authorization: %s %s",
+ c->authtype, c->credential);
+ headers = curl_slist_append(headers, auth.buf);
+ strbuf_release(&auth);
+ }
+ return headers;
+}
+
static void init_curl_http_auth(CURL *result)
{
- if (!http_auth.username || !*http_auth.username) {
+ if ((!http_auth.username || !*http_auth.username) &&
+ (!http_auth.credential || !*http_auth.credential)) {
if (curl_empty_auth_enabled())
curl_easy_setopt(result, CURLOPT_USERPWD, ":");
return;
}
- credential_fill(&http_auth, 0);
+ credential_fill(&http_auth, 1);
- curl_easy_setopt(result, CURLOPT_USERNAME, http_auth.username);
- curl_easy_setopt(result, CURLOPT_PASSWORD, http_auth.password);
+ if (http_auth.password) {
+ curl_easy_setopt(result, CURLOPT_USERNAME, http_auth.username);
+ curl_easy_setopt(result, CURLOPT_PASSWORD, http_auth.password);
+ }
}
/* *var must be free-able */
@@ -586,17 +602,22 @@ static void var_override(const char **var, char *value)
static void set_proxyauth_name_password(CURL *result)
{
+ if (proxy_auth.password) {
curl_easy_setopt(result, CURLOPT_PROXYUSERNAME,
proxy_auth.username);
curl_easy_setopt(result, CURLOPT_PROXYPASSWORD,
proxy_auth.password);
+ } else if (proxy_auth.authtype && proxy_auth.credential) {
+ curl_easy_setopt(result, CURLOPT_PROXYHEADER,
+ http_append_auth_header(&proxy_auth, NULL));
+ }
}
static void init_curl_proxy_auth(CURL *result)
{
if (proxy_auth.username) {
- if (!proxy_auth.password)
- credential_fill(&proxy_auth, 0);
+ if (!proxy_auth.password && !proxy_auth.credential)
+ credential_fill(&proxy_auth, 1);
set_proxyauth_name_password(result);
}
@@ -1468,7 +1489,7 @@ struct active_request_slot *get_active_slot(void)
curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve);
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
- if (http_auth.password || curl_empty_auth_enabled())
+ if (http_auth.password || http_auth.credential || curl_empty_auth_enabled())
init_curl_http_auth(slot->curl);
return slot;
@@ -1757,7 +1778,8 @@ static int handle_curl_result(struct slot_results *results)
} else if (missing_target(results))
return HTTP_MISSING_TARGET;
else if (results->http_code == 401) {
- if (http_auth.username && http_auth.password) {
+ if ((http_auth.username && http_auth.password) ||\
+ (http_auth.authtype && http_auth.credential)) {
credential_reject(&http_auth);
return HTTP_NOAUTH;
} else {
@@ -2065,11 +2087,15 @@ static int http_request(const char *url,
/* Add additional headers here */
if (options && options->extra_headers) {
const struct string_list_item *item;
- for_each_string_list_item(item, options->extra_headers) {
- headers = curl_slist_append(headers, item->string);
+ if (options && options->extra_headers) {
+ for_each_string_list_item(item, options->extra_headers) {
+ headers = curl_slist_append(headers, item->string);
+ }
}
}
+ headers = http_append_auth_header(&http_auth, headers);
+
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
@@ -2190,7 +2216,7 @@ static int http_request_reauth(const char *url,
BUG("Unknown http_request target");
}
- credential_fill(&http_auth, 0);
+ credential_fill(&http_auth, 1);
return http_request(url, result, target, options);
}
diff --git a/http.h b/http.h
index c5f8cc4620..a516ca4a9a 100644
--- a/http.h
+++ b/http.h
@@ -175,6 +175,9 @@ int http_get_file(const char *url, const char *filename,
int http_fetch_ref(const char *base, struct ref *ref);
+struct curl_slist *http_append_auth_header(const struct credential *c,
+ struct curl_slist *headers);
+
/* Helpers for fetching packs */
int http_get_info_packs(const char *base_url,
struct packed_git **packs_head);
diff --git a/remote-curl.c b/remote-curl.c
index f96bda2431..1c5416812a 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -931,7 +931,7 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece
if (err != HTTP_OK)
return -1;
- if (results.auth_avail & CURLAUTH_GSSNEGOTIATE)
+ if (results.auth_avail & CURLAUTH_GSSNEGOTIATE || http_auth.authtype)
needs_100_continue = 1;
}
@@ -942,6 +942,8 @@ retry:
headers = curl_slist_append(headers, needs_100_continue ?
"Expect: 100-continue" : "Expect:");
+ headers = http_append_auth_header(&http_auth, headers);
+
/* Add Accept-Language header */
if (rpc->hdr_accept_language)
headers = curl_slist_append(headers, rpc->hdr_accept_language);
diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh
index ab8a721ccc..b3ed0d9fc2 100755
--- a/t/t5563-simple-http-auth.sh
+++ b/t/t5563-simple-http-auth.sh
@@ -74,6 +74,7 @@ test_expect_success 'access using basic auth' '
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=Basic realm="example.com"
@@ -87,6 +88,43 @@ test_expect_success 'access using basic auth' '
EOF
'
+test_expect_success 'access using basic auth via authtype' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ capability[]=authtype
+ authtype=Basic
+ credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
+ EOF
+
+ # Basic base64(alice:secret-passwd)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
+ EOF
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ WWW-Authenticate: Basic realm="example.com"
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ GIT_CURL_VERBOSE=1 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ protocol=http
+ host=$HTTPD_DEST
+ wwwauth[]=Basic realm="example.com"
+ EOF
+
+ expect_credential_query store <<-EOF
+ capability[]=authtype
+ authtype=Basic
+ credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
+ protocol=http
+ host=$HTTPD_DEST
+ EOF
+'
+
test_expect_success 'access using basic auth invalid credentials' '
test_when_finished "per_test_cleanup" &&
@@ -108,6 +146,7 @@ test_expect_success 'access using basic auth invalid credentials' '
test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=Basic realm="example.com"
@@ -145,6 +184,7 @@ test_expect_success 'access using basic auth with extra challenges' '
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=FooBar param1="value1" param2="value2"
@@ -183,6 +223,7 @@ test_expect_success 'access using basic auth mixed-case wwwauth header name' '
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=foobar param1="value1" param2="value2"
@@ -226,6 +267,7 @@ test_expect_success 'access using basic auth with wwwauth header continuations'
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=FooBar param1="value1" param2="value2"
@@ -271,6 +313,7 @@ test_expect_success 'access using basic auth with wwwauth header empty continuat
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=FooBar param1="value1" param2="value2"
@@ -312,6 +355,7 @@ test_expect_success 'access using basic auth with wwwauth header mixed line-endi
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
expect_credential_query get <<-EOF &&
+ capability[]=authtype
protocol=http
host=$HTTPD_DEST
wwwauth[]=FooBar param1="value1" param2="value2"
@@ -326,4 +370,93 @@ test_expect_success 'access using basic auth with wwwauth header mixed line-endi
EOF
'
+test_expect_success 'access using bearer auth' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ capability[]=authtype
+ authtype=Bearer
+ credential=YS1naXQtdG9rZW4=
+ EOF
+
+ # Basic base64(a-git-token)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ Bearer YS1naXQtdG9rZW4=
+ EOF
+
+ CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ WWW-Authenticate: FooBar param1="value1" param2="value2"
+ WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
+ WWW-Authenticate: Basic realm="example.com"
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ protocol=http
+ host=$HTTPD_DEST
+ 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
+ EOF
+'
+
+test_expect_success 'access using bearer auth with invalid credentials' '
+ test_when_finished "per_test_cleanup" &&
+
+ set_credential_reply get <<-EOF &&
+ capability[]=authtype
+ authtype=Bearer
+ credential=incorrect-token
+ EOF
+
+ # Basic base64(a-git-token)
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
+ Bearer YS1naXQtdG9rZW4=
+ EOF
+
+ CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
+
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
+ WWW-Authenticate: FooBar param1="value1" param2="value2"
+ WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
+ WWW-Authenticate: Basic realm="example.com"
+ EOF
+
+ test_config_global credential.helper test-helper &&
+ test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
+
+ expect_credential_query get <<-EOF &&
+ capability[]=authtype
+ protocol=http
+ host=$HTTPD_DEST
+ 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 erase <<-EOF
+ capability[]=authtype
+ authtype=Bearer
+ credential=incorrect-token
+ protocol=http
+ host=$HTTPD_DEST
+ wwwauth[]=FooBar param1="value1" param2="value2"
+ wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
+ wwwauth[]=Basic realm="example.com"
+ EOF
+'
+
test_done