mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-24 03:17:06 +00:00
Merge pull request #2282 from libgit2/cmn/remote-easier-bind
A few niceties for binding authors
This commit is contained in:
commit
a32d684f86
@ -468,6 +468,9 @@ struct git_remote_callbacks {
|
||||
/**
|
||||
* This will be called if the remote host requires
|
||||
* authentication in order to connect to it.
|
||||
*
|
||||
* Returning GIT_PASSTHROUGH will make libgit2 behave as
|
||||
* though this field isn't set.
|
||||
*/
|
||||
int (*credentials)(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data);
|
||||
|
||||
@ -519,6 +522,17 @@ GIT_EXTERN(int) git_remote_init_callbacks(
|
||||
*/
|
||||
GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, const git_remote_callbacks *callbacks);
|
||||
|
||||
/**
|
||||
* Retrieve the current callback structure
|
||||
*
|
||||
* This provides read access to the callbacks structure as the remote
|
||||
* sees it.
|
||||
*
|
||||
* @param remote the remote to query
|
||||
* @return a pointer to the callbacks structure
|
||||
*/
|
||||
GIT_EXTERN(const git_remote_callbacks *) git_remote_get_callbacks(git_remote *remote);
|
||||
|
||||
/**
|
||||
* Get the statistics structure that is filled in by the fetch operation.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
goto on_error;
|
||||
} 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 (!t->cred) {
|
||||
if (error == GIT_PASSTHROUGH)
|
||||
no_callback = 1;
|
||||
else if (error < 0)
|
||||
goto on_error;
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user