diff --git a/include/git2/remote.h b/include/git2/remote.h index af73ca8b3..82aff385d 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -313,7 +313,8 @@ GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); */ GIT_EXTERN(void) git_remote_set_cred_acquire_cb( git_remote *remote, - git_cred_acquire_cb cred_acquire_cb); + git_cred_acquire_cb cred_acquire_cb, + void *payload); /** * Sets a custom transport for the remote. The caller can use this function diff --git a/include/git2/transport.h b/include/git2/transport.h index 00beb4472..c2f205295 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -65,7 +65,8 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( typedef int (*git_cred_acquire_cb)( git_cred **cred, const char *url, - unsigned int allowed_types); + unsigned int allowed_types, + void *payload); /* *** End interface for credentials acquisition *** @@ -94,6 +95,7 @@ typedef struct git_transport { int (*connect)(struct git_transport *transport, const char *url, git_cred_acquire_cb cred_acquire_cb, + void *cred_acquire_payload, int direction, int flags); diff --git a/src/remote.c b/src/remote.c index 5b75e510c..670904b17 100644 --- a/src/remote.c +++ b/src/remote.c @@ -90,10 +90,9 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con /* name is optional */ assert(out && repo && url); - remote = git__malloc(sizeof(git_remote)); + remote = git__calloc(1, sizeof(git_remote)); GITERR_CHECK_ALLOC(remote); - memset(remote, 0x0, sizeof(git_remote)); remote->repo = repo; remote->check_cert = 1; remote->update_fetchhead = 1; @@ -509,7 +508,7 @@ int git_remote_connect(git_remote *remote, git_direction direction) if (!remote->check_cert) flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT; - if (t->connect(t, url, remote->cred_acquire_cb, direction, flags) < 0) + if (t->connect(t, url, remote->cred_acquire_cb, remote->cred_acquire_payload, direction, flags) < 0) goto on_error; remote->transport = t; @@ -1019,11 +1018,13 @@ int git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks void git_remote_set_cred_acquire_cb( git_remote *remote, - git_cred_acquire_cb cred_acquire_cb) + git_cred_acquire_cb cred_acquire_cb, + void *payload) { assert(remote); remote->cred_acquire_cb = cred_acquire_cb; + remote->cred_acquire_payload = payload; } int git_remote_set_transport(git_remote *remote, git_transport *transport) diff --git a/src/remote.h b/src/remote.h index 06f712fbc..8d3924497 100644 --- a/src/remote.h +++ b/src/remote.h @@ -23,6 +23,7 @@ struct git_remote { struct git_refspec fetch; struct git_refspec push; git_cred_acquire_cb cred_acquire_cb; + void *cred_acquire_payload; git_transport *transport; git_repository *repo; git_remote_callbacks callbacks; diff --git a/src/transports/http.c b/src/transports/http.c index 02f749262..fd1a99fe1 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -256,7 +256,8 @@ static int on_headers_complete(http_parser *parser) if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, - allowed_types) < 0) + allowed_types, + t->owner->cred_acquire_payload) < 0) return PARSE_ERROR_GENERIC; assert(t->cred); diff --git a/src/transports/local.c b/src/transports/local.c index 768daf3a8..53b24947c 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -143,6 +143,7 @@ static int local_connect( git_transport *transport, const char *url, git_cred_acquire_cb cred_acquire_cb, + void *cred_acquire_payload, int direction, int flags) { git_repository *repo; @@ -152,6 +153,7 @@ static int local_connect( git_buf buf = GIT_BUF_INIT; GIT_UNUSED(cred_acquire_cb); + GIT_UNUSED(cred_acquire_payload); t->url = git__strdup(url); GITERR_CHECK_ALLOC(t->url); diff --git a/src/transports/smart.c b/src/transports/smart.c index 5300a47c8..8b89fa2e8 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -62,6 +62,7 @@ static int git_smart__connect( git_transport *transport, const char *url, git_cred_acquire_cb cred_acquire_cb, + void *cred_acquire_payload, int direction, int flags) { @@ -81,6 +82,7 @@ static int git_smart__connect( t->direction = direction; t->flags = flags; t->cred_acquire_cb = cred_acquire_cb; + t->cred_acquire_payload = cred_acquire_payload; if (GIT_DIRECTION_FETCH == t->direction) service = GIT_SERVICE_UPLOADPACK_LS; diff --git a/src/transports/smart.h b/src/transports/smart.h index ea2784bb1..c86b1cbec 100644 --- a/src/transports/smart.h +++ b/src/transports/smart.h @@ -125,6 +125,7 @@ typedef struct { git_remote *owner; char *url; git_cred_acquire_cb cred_acquire_cb; + void *cred_acquire_payload; int direction; int flags; git_transport_message_cb progress_cb; diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 80ff72681..a73315975 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -694,12 +694,13 @@ int git_smart__push(git_transport *transport, git_push *push) * the data from the push report to do this without another network call */ if (push->specs.length) { git_cred_acquire_cb cred_cb = t->cred_acquire_cb; + void *cred_payload = t->cred_acquire_payload; int flags = t->flags; url = git__strdup(t->url); if (!url || t->parent.close(&t->parent) < 0 || - t->parent.connect(&t->parent, url, cred_cb, GIT_DIRECTION_PUSH, flags)) + t->parent.connect(&t->parent, url, cred_cb, cred_payload, GIT_DIRECTION_PUSH, flags)) goto on_error; } diff --git a/tests-clar/network/push.c b/tests-clar/network/push.c index acc376de7..f8856091f 100644 --- a/tests-clar/network/push.c +++ b/tests-clar/network/push.c @@ -27,10 +27,12 @@ static git_oid _oid_b1; /* git_oid *oid, git_repository *repo, (string literal) blob */ #define CREATE_BLOB(oid, repo, blob) git_blob_create_frombuffer(oid, repo, blob, sizeof(blob) - 1) -static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types) +static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types, void *payload) { GIT_UNUSED(url); + *((bool*)payload) = true; + if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass) < 0) return -1; @@ -130,6 +132,7 @@ void test_network_push__initialize(void) git_vector delete_specs = GIT_VECTOR_INIT; size_t i; char *curr_del_spec; + bool cred_acquire_called = false; _repo = cl_git_sandbox_init("push_src"); @@ -165,7 +168,7 @@ void test_network_push__initialize(void) if (_remote_url) { cl_git_pass(git_remote_add(&_remote, _repo, "test", _remote_url)); - git_remote_set_cred_acquire_cb(_remote, cred_acquire_cb); + git_remote_set_cred_acquire_cb(_remote, cred_acquire_cb, &cred_acquire_called); record_callbacks_data_clear(&_record_cbs_data); git_remote_set_callbacks(_remote, &_record_cbs);