diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/remote.c | 7 | ||||
| -rw-r--r-- | src/transports/http.c | 55 | ||||
| -rw-r--r-- | src/transports/ssh.c | 32 |
3 files changed, 62 insertions, 32 deletions
diff --git a/src/remote.c b/src/remote.c index 243086bf9..c23a4643e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1253,6 +1253,13 @@ int git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *cal return 0; } +const git_remote_callbacks *git_remote_get_callbacks(git_remote *remote) +{ + assert(remote); + + return &remote->callbacks; +} + int git_remote_set_transport(git_remote *remote, git_transport *transport) { assert(remote && transport); diff --git a/src/transports/http.c b/src/transports/http.c index c6aaeb9cf..a7eff7365 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -248,6 +248,7 @@ static int on_headers_complete(http_parser *parser) http_subtransport *t = ctx->t; http_stream *s = ctx->s; git_buf buf = GIT_BUF_INIT; + int error = 0, no_callback = 0; /* Both parse_header_name and parse_header_value are populated * and ready for consumption. */ @@ -256,29 +257,43 @@ static int on_headers_complete(http_parser *parser) return t->parse_error = PARSE_ERROR_GENERIC; /* Check for an authentication failure. */ + if (parser->status_code == 401 && - get_verb == s->verb && - t->owner->cred_acquire_cb) { - int allowed_types = 0; + get_verb == s->verb) { + if (!t->owner->cred_acquire_payload) { + no_callback = 1; + } else { + int allowed_types = 0; + + if (parse_unauthorized_response(&t->www_authenticate, + &allowed_types, &t->auth_mechanism) < 0) + return t->parse_error = PARSE_ERROR_GENERIC; + + if (allowed_types && + (!t->cred || 0 == (t->cred->credtype & allowed_types))) { + + error = t->owner->cred_acquire_cb(&t->cred, + t->owner->url, + t->connection_data.user, + allowed_types, + t->owner->cred_acquire_payload); + + if (error == GIT_PASSTHROUGH) { + no_callback = 1; + } else if (error < 0) { + return PARSE_ERROR_GENERIC; + } else { + assert(t->cred); + + /* Successfully acquired a credential. */ + return t->parse_error = PARSE_ERROR_REPLAY; + } + } + } - if (parse_unauthorized_response(&t->www_authenticate, - &allowed_types, &t->auth_mechanism) < 0) + if (no_callback) { + giterr_set(GITERR_NET, "authentication required but no callback set"); return t->parse_error = PARSE_ERROR_GENERIC; - - if (allowed_types && - (!t->cred || 0 == (t->cred->credtype & allowed_types))) { - - if (t->owner->cred_acquire_cb(&t->cred, - t->owner->url, - t->connection_data.user, - allowed_types, - t->owner->cred_acquire_payload) < 0) - return PARSE_ERROR_GENERIC; - - assert(t->cred); - - /* Successfully acquired a credential. */ - return t->parse_error = PARSE_ERROR_REPLAY; } } diff --git a/src/transports/ssh.c b/src/transports/ssh.c index dea990275..b403727c9 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -387,6 +387,7 @@ static int _git_ssh_setup_conn( { char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *default_port="22"; + int no_callback = 0; ssh_stream *s; LIBSSH2_SESSION* session=NULL; LIBSSH2_CHANNEL* channel=NULL; @@ -413,24 +414,31 @@ static int _git_ssh_setup_conn( if (user && pass) { if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0) goto on_error; - } else if (t->owner->cred_acquire_cb) { - if (t->owner->cred_acquire_cb( - &t->cred, t->owner->url, user, - GIT_CREDTYPE_USERPASS_PLAINTEXT | - GIT_CREDTYPE_SSH_KEY | - GIT_CREDTYPE_SSH_INTERACTIVE | - GIT_CREDTYPE_SSH_CUSTOM, - t->owner->cred_acquire_payload) < 0) + } else if (!t->owner->cred_acquire_cb) { + no_callback = 1; + } else { + int error; + error = t->owner->cred_acquire_cb(&t->cred, t->owner->url, user, + GIT_CREDTYPE_USERPASS_PLAINTEXT | + GIT_CREDTYPE_SSH_KEY | GIT_CREDTYPE_SSH_CUSTOM | + GIT_CREDTYPE_SSH_INTERACTIVE, + t->owner->cred_acquire_payload); + + if (error == GIT_PASSTHROUGH) + no_callback = 1; + else if (error < 0) goto on_error; - - if (!t->cred) { + else if (!t->cred) { giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials"); goto on_error; } - } else { - giterr_set(GITERR_SSH, "Cannot set up SSH connection without credentials"); + } + + if (no_callback) { + giterr_set(GITERR_SSH, "authentication required but no callback set"); goto on_error; } + assert(t->cred); if (_git_ssh_session_create(&session, s->socket) < 0) |
