@@ -169,6 +169,15 @@ username in the example above) will be left unset.
attribute 'wwwauth[]' where the order of the attributes is the same
as they appear in the HTTP response.
+`authtype`::
+
+ Indicates the type of authentication scheme used. If this is not
+ present the default is "Basic".
+ Known values include "Basic", "Digest", and "Bearer".
+ If an unknown value is provided, this is taken as the authentication
+ scheme for the `Authorization` header, and the `password` field is
+ used as the raw unencoded authorization parameters of the same header.
+
GIT
---
Part of the linkgit:git[1] suite
@@ -21,6 +21,7 @@ void credential_clear(struct credential *c)
free(c->path);
free(c->username);
free(c->password);
+ free(c->authtype);
string_list_clear(&c->helpers, 0);
strvec_clear(&c->wwwauth_headers);
@@ -235,6 +236,9 @@ int credential_read(struct credential *c, FILE *fp)
} else if (!strcmp(key, "path")) {
free(c->path);
c->path = xstrdup(value);
+ } else if (!strcmp(key, "authtype")) {
+ free(c->authtype);
+ c->authtype = xstrdup(value);
} else if (!strcmp(key, "url")) {
credential_from_url(c, value);
} else if (!strcmp(key, "quit")) {
@@ -281,6 +285,7 @@ void credential_write(const struct credential *c, FILE *fp)
credential_write_item(fp, "path", c->path, 0);
credential_write_item(fp, "username", c->username, 0);
credential_write_item(fp, "password", c->password, 0);
+ credential_write_item(fp, "authtype", c->authtype, 0);
credential_write_strvec(fp, "wwwauth", &c->wwwauth_headers);
}
@@ -140,6 +140,7 @@ struct credential {
char *protocol;
char *host;
char *path;
+ char *authtype;
};
#define CREDENTIAL_INIT { \
@@ -126,4 +126,14 @@
#define GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS
#endif
+/**
+ * CURLAUTH_BEARER was added in 7.61.0, released in July 2018.
+ * However, only 7.69.0 fixes a bug where Bearer headers were not
+ * actually sent with reused connections on subsequent transfers
+ * (curl/curl@dea17b519dc1).
+ */
+#if LIBCURL_VERSION_NUM >= 0x074500
+#define GIT_CURL_HAVE_CURLAUTH_BEARER
+#endif
+
#endif
@@ -517,7 +517,8 @@ static int curl_empty_auth_enabled(void)
static void init_curl_http_auth(struct active_request_slot *slot)
{
- if (!http_auth.username || !*http_auth.username) {
+ if (!http_auth.authtype &&
+ (!http_auth.username || !*http_auth.username)) {
if (curl_empty_auth_enabled())
curl_easy_setopt(slot->curl, CURLOPT_USERPWD, ":");
return;
@@ -525,8 +526,25 @@ static void init_curl_http_auth(struct active_request_slot *slot)
credential_fill(&http_auth);
- curl_easy_setopt(slot->curl, CURLOPT_USERNAME, http_auth.username);
- curl_easy_setopt(slot->curl, CURLOPT_PASSWORD, http_auth.password);
+ if (!http_auth.authtype || !strcasecmp(http_auth.authtype, "basic")
+ || !strcasecmp(http_auth.authtype, "digest")) {
+ curl_easy_setopt(slot->curl, CURLOPT_USERNAME,
+ http_auth.username);
+ curl_easy_setopt(slot->curl, CURLOPT_PASSWORD,
+ http_auth.password);
+#ifdef GIT_CURL_HAVE_CURLAUTH_BEARER
+ } else if (!strcasecmp(http_auth.authtype, "bearer")) {
+ curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
+ curl_easy_setopt(slot->curl, CURLOPT_XOAUTH2_BEARER,
+ http_auth.password);
+#endif
+ } else {
+ struct strbuf auth = STRBUF_INIT;
+ strbuf_addf(&auth, "Authorization: %s %s",
+ http_auth.authtype, http_auth.password);
+ slot->headers = curl_slist_append(slot->headers, auth.buf);
+ strbuf_release(&auth);
+ }
}
/* *var must be free-able */