mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-24 07:03:45 +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
|
* This will be called if the remote host requires
|
||||||
* authentication in order to connect to it.
|
* 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);
|
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);
|
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.
|
* 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;
|
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)
|
int git_remote_set_transport(git_remote *remote, git_transport *transport)
|
||||||
{
|
{
|
||||||
assert(remote && transport);
|
assert(remote && transport);
|
||||||
|
@ -248,6 +248,7 @@ static int on_headers_complete(http_parser *parser)
|
|||||||
http_subtransport *t = ctx->t;
|
http_subtransport *t = ctx->t;
|
||||||
http_stream *s = ctx->s;
|
http_stream *s = ctx->s;
|
||||||
git_buf buf = GIT_BUF_INIT;
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
int error = 0, no_callback = 0;
|
||||||
|
|
||||||
/* Both parse_header_name and parse_header_value are populated
|
/* Both parse_header_name and parse_header_value are populated
|
||||||
* and ready for consumption. */
|
* and ready for consumption. */
|
||||||
@ -256,9 +257,12 @@ static int on_headers_complete(http_parser *parser)
|
|||||||
return t->parse_error = PARSE_ERROR_GENERIC;
|
return t->parse_error = PARSE_ERROR_GENERIC;
|
||||||
|
|
||||||
/* Check for an authentication failure. */
|
/* Check for an authentication failure. */
|
||||||
|
|
||||||
if (parser->status_code == 401 &&
|
if (parser->status_code == 401 &&
|
||||||
get_verb == s->verb &&
|
get_verb == s->verb) {
|
||||||
t->owner->cred_acquire_cb) {
|
if (!t->owner->cred_acquire_payload) {
|
||||||
|
no_callback = 1;
|
||||||
|
} else {
|
||||||
int allowed_types = 0;
|
int allowed_types = 0;
|
||||||
|
|
||||||
if (parse_unauthorized_response(&t->www_authenticate,
|
if (parse_unauthorized_response(&t->www_authenticate,
|
||||||
@ -268,19 +272,30 @@ static int on_headers_complete(http_parser *parser)
|
|||||||
if (allowed_types &&
|
if (allowed_types &&
|
||||||
(!t->cred || 0 == (t->cred->credtype & allowed_types))) {
|
(!t->cred || 0 == (t->cred->credtype & allowed_types))) {
|
||||||
|
|
||||||
if (t->owner->cred_acquire_cb(&t->cred,
|
error = t->owner->cred_acquire_cb(&t->cred,
|
||||||
t->owner->url,
|
t->owner->url,
|
||||||
t->connection_data.user,
|
t->connection_data.user,
|
||||||
allowed_types,
|
allowed_types,
|
||||||
t->owner->cred_acquire_payload) < 0)
|
t->owner->cred_acquire_payload);
|
||||||
return PARSE_ERROR_GENERIC;
|
|
||||||
|
|
||||||
|
if (error == GIT_PASSTHROUGH) {
|
||||||
|
no_callback = 1;
|
||||||
|
} else if (error < 0) {
|
||||||
|
return PARSE_ERROR_GENERIC;
|
||||||
|
} else {
|
||||||
assert(t->cred);
|
assert(t->cred);
|
||||||
|
|
||||||
/* Successfully acquired a credential. */
|
/* Successfully acquired a credential. */
|
||||||
return t->parse_error = PARSE_ERROR_REPLAY;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
@ -387,6 +387,7 @@ static int _git_ssh_setup_conn(
|
|||||||
{
|
{
|
||||||
char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
|
char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL;
|
||||||
const char *default_port="22";
|
const char *default_port="22";
|
||||||
|
int no_callback = 0;
|
||||||
ssh_stream *s;
|
ssh_stream *s;
|
||||||
LIBSSH2_SESSION* session=NULL;
|
LIBSSH2_SESSION* session=NULL;
|
||||||
LIBSSH2_CHANNEL* channel=NULL;
|
LIBSSH2_CHANNEL* channel=NULL;
|
||||||
@ -413,24 +414,31 @@ static int _git_ssh_setup_conn(
|
|||||||
if (user && pass) {
|
if (user && pass) {
|
||||||
if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0)
|
if (git_cred_userpass_plaintext_new(&t->cred, user, pass) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
} else if (t->owner->cred_acquire_cb) {
|
} else if (!t->owner->cred_acquire_cb) {
|
||||||
if (t->owner->cred_acquire_cb(
|
no_callback = 1;
|
||||||
&t->cred, t->owner->url, user,
|
} else {
|
||||||
|
int error;
|
||||||
|
error = t->owner->cred_acquire_cb(&t->cred, t->owner->url, user,
|
||||||
GIT_CREDTYPE_USERPASS_PLAINTEXT |
|
GIT_CREDTYPE_USERPASS_PLAINTEXT |
|
||||||
GIT_CREDTYPE_SSH_KEY |
|
GIT_CREDTYPE_SSH_KEY | GIT_CREDTYPE_SSH_CUSTOM |
|
||||||
GIT_CREDTYPE_SSH_INTERACTIVE |
|
GIT_CREDTYPE_SSH_INTERACTIVE,
|
||||||
GIT_CREDTYPE_SSH_CUSTOM,
|
t->owner->cred_acquire_payload);
|
||||||
t->owner->cred_acquire_payload) < 0)
|
|
||||||
goto on_error;
|
|
||||||
|
|
||||||
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");
|
giterr_set(GITERR_SSH, "Callback failed to initialize SSH credentials");
|
||||||
goto on_error;
|
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;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t->cred);
|
assert(t->cred);
|
||||||
|
|
||||||
if (_git_ssh_session_create(&session, s->socket) < 0)
|
if (_git_ssh_session_create(&session, s->socket) < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user