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 {
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) {
......
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