Commit 0328eef6 by Edward Thomson

http transport: further refactor credential handling

Prepare credential handling to understand both git server and proxy
server authentication.
parent 32cb56ce
...@@ -87,6 +87,7 @@ typedef struct { ...@@ -87,6 +87,7 @@ typedef struct {
char parse_buffer_data[NETIO_BUFSIZE]; char parse_buffer_data[NETIO_BUFSIZE];
char *content_type; char *content_type;
char *location; char *location;
git_vector proxy_authenticate;
git_vector www_authenticate; git_vector www_authenticate;
enum last_cb last_cb; enum last_cb last_cb;
int parse_error; int parse_error;
...@@ -292,6 +293,12 @@ static int on_header_ready(http_subtransport *t) ...@@ -292,6 +293,12 @@ static int on_header_ready(http_subtransport *t)
GITERR_CHECK_ALLOC(t->content_type); 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))) { else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) {
char *dup = git__strdup(git_buf_cstr(value)); char *dup = git__strdup(git_buf_cstr(value));
GITERR_CHECK_ALLOC(dup); GITERR_CHECK_ALLOC(dup);
...@@ -346,7 +353,14 @@ static int on_header_value(http_parser *parser, const char *str, size_t len) ...@@ -346,7 +353,14 @@ static int on_header_value(http_parser *parser, const char *str, size_t len)
return 0; 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; parser_context *ctx = (parser_context *) parser->data;
http_subtransport *t = ctx->t; http_subtransport *t = ctx->t;
...@@ -358,17 +372,13 @@ static int on_auth_required(http_parser *parser, int allowed_types) ...@@ -358,17 +372,13 @@ static int on_auth_required(http_parser *parser, int allowed_types)
return t->parse_error; return t->parse_error;
} }
if (t->owner->cred_acquire_cb) { if (callback) {
if (t->cred) { if (*creds) {
t->cred->free(t->cred); (*creds)->free(*creds);
t->cred = NULL; *creds = NULL;
} }
ret = t->owner->cred_acquire_cb(&t->cred, ret = callback(creds, url, username, allowed_types, callback_payload);
t->owner->url,
t->gitserver_data.user,
allowed_types,
t->owner->cred_acquire_payload);
if (ret == GIT_PASSTHROUGH) { if (ret == GIT_PASSTHROUGH) {
/* treat GIT_PASSTHROUGH as if callback isn't set */ /* treat GIT_PASSTHROUGH as if callback isn't set */
...@@ -377,9 +387,9 @@ static int on_auth_required(http_parser *parser, int allowed_types) ...@@ -377,9 +387,9 @@ static int on_auth_required(http_parser *parser, int allowed_types)
t->parse_error = PARSE_ERROR_EXT; t->parse_error = PARSE_ERROR_EXT;
return t->parse_error; return t->parse_error;
} else { } 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"); giterr_set(GITERR_NET, "credential provider returned an invalid cred type");
t->parse_error = PARSE_ERROR_GENERIC; t->parse_error = PARSE_ERROR_GENERIC;
return t->parse_error; return t->parse_error;
...@@ -421,7 +431,13 @@ static int on_headers_complete(http_parser *parser) ...@@ -421,7 +431,13 @@ static int on_headers_complete(http_parser *parser)
/* Check for an authentication failure. */ /* Check for an authentication failure. */
if (parser->status_code == 401 && get_verb == s->verb) 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. /* Check for a redirect.
* Right now we only permit a redirect to the same hostname. */ * Right now we only permit a redirect to the same hostname. */
...@@ -554,6 +570,7 @@ static void clear_parser_state(http_subtransport *t) ...@@ -554,6 +570,7 @@ static void clear_parser_state(http_subtransport *t)
git__free(t->location); git__free(t->location);
t->location = NULL; t->location = NULL;
git_vector_free_deep(&t->proxy_authenticate);
git_vector_free_deep(&t->www_authenticate); git_vector_free_deep(&t->www_authenticate);
} }
...@@ -1076,10 +1093,8 @@ static int http_action( ...@@ -1076,10 +1093,8 @@ static int http_action(
assert(t->gitserver_data.host && t->gitserver_data.port && t->gitserver_data.path); assert(t->gitserver_data.host && t->gitserver_data.port && t->gitserver_data.path);
if ((ret = load_proxy_config(t)) < 0) if ((ret = load_proxy_config(t)) < 0 ||
return ret; (ret = http_connect(t)) < 0)
if ((ret = http_connect(t)) < 0)
return ret; return ret;
switch (action) { switch (action) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment