diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-10-22 11:14:06 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-11-28 15:27:11 +0000 |
commit | 0328eef6aad7861f9dbcb2e5b8e276fe65f98c09 (patch) | |
tree | 4bd861db7aef4121eacc319d2cc14b4bac8efc85 | |
parent | 32cb56ceedc5bb5738c4461bbb4e65e2314d6b66 (diff) | |
download | libgit2-0328eef6aad7861f9dbcb2e5b8e276fe65f98c09.tar.gz |
http transport: further refactor credential handling
Prepare credential handling to understand both git server and proxy
server authentication.
-rw-r--r-- | src/transports/http.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/transports/http.c b/src/transports/http.c index 6f46094e5..57aa9f7a2 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -87,6 +87,7 @@ typedef struct { char parse_buffer_data[NETIO_BUFSIZE]; char *content_type; char *location; + git_vector proxy_authenticate; git_vector www_authenticate; enum last_cb last_cb; int parse_error; @@ -292,6 +293,12 @@ static int on_header_ready(http_subtransport *t) GITERR_CHECK_ALLOC(t->content_type); } } + else if (!strcasecmp("Proxy-Authenticate", git_buf_cstr(name))) { + char *dup = git__strdup(git_buf_cstr(value)); + GITERR_CHECK_ALLOC(dup); + + git_vector_insert(&t->proxy_authenticate, dup); + } else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) { char *dup = git__strdup(git_buf_cstr(value)); GITERR_CHECK_ALLOC(dup); @@ -346,7 +353,14 @@ static int on_header_value(http_parser *parser, const char *str, size_t len) return 0; } -static int on_auth_required(http_parser *parser, int allowed_types) +static int on_auth_required( + git_cred **creds, + http_parser *parser, + const char *url, + git_cred_acquire_cb callback, + void *callback_payload, + const char *username, + int allowed_types) { parser_context *ctx = (parser_context *) parser->data; http_subtransport *t = ctx->t; @@ -358,17 +372,13 @@ static int on_auth_required(http_parser *parser, int allowed_types) return t->parse_error; } - if (t->owner->cred_acquire_cb) { - if (t->cred) { - t->cred->free(t->cred); - t->cred = NULL; + if (callback) { + if (*creds) { + (*creds)->free(*creds); + *creds = NULL; } - ret = t->owner->cred_acquire_cb(&t->cred, - t->owner->url, - t->gitserver_data.user, - allowed_types, - t->owner->cred_acquire_payload); + ret = callback(creds, url, username, allowed_types, callback_payload); if (ret == GIT_PASSTHROUGH) { /* treat GIT_PASSTHROUGH as if callback isn't set */ @@ -377,9 +387,9 @@ static int on_auth_required(http_parser *parser, int allowed_types) t->parse_error = PARSE_ERROR_EXT; return t->parse_error; } else { - assert(t->cred); + assert(*creds); - if (!(t->cred->credtype & allowed_types)) { + if (!((*creds)->credtype & allowed_types)) { giterr_set(GITERR_NET, "credential provider returned an invalid cred type"); t->parse_error = PARSE_ERROR_GENERIC; return t->parse_error; @@ -421,7 +431,13 @@ static int on_headers_complete(http_parser *parser) /* Check for an authentication failure. */ if (parser->status_code == 401 && get_verb == s->verb) - return on_auth_required(parser, allowed_www_auth_types); + return on_auth_required(&t->cred, + parser, + t->owner->url, + t->owner->cred_acquire_cb, + t->owner->cred_acquire_payload, + t->gitserver_data.user, + allowed_www_auth_types); /* Check for a redirect. * Right now we only permit a redirect to the same hostname. */ @@ -554,6 +570,7 @@ static void clear_parser_state(http_subtransport *t) git__free(t->location); t->location = NULL; + git_vector_free_deep(&t->proxy_authenticate); git_vector_free_deep(&t->www_authenticate); } @@ -1076,10 +1093,8 @@ static int http_action( assert(t->gitserver_data.host && t->gitserver_data.port && t->gitserver_data.path); - if ((ret = load_proxy_config(t)) < 0) - return ret; - - if ((ret = http_connect(t)) < 0) + if ((ret = load_proxy_config(t)) < 0 || + (ret = http_connect(t)) < 0) return ret; switch (action) { |