From ffb02b1630da85e063a816cc6dddcdc004a8ff72 Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Tue, 8 Jan 2013 12:58:20 -0800 Subject: [PATCH 1/2] Expose stock user/pass credential utility --- include/git2/transport.h | 20 ++++++++++++++++++++ src/transports/cred.c | 20 ++++++++++++++++++++ tests-clar/network/cred.c | 27 +++++++++++++++++++++++++++ tests-clar/online/clone.c | 29 ++++------------------------- 4 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 tests-clar/network/cred.c diff --git a/include/git2/transport.h b/include/git2/transport.h index fba5fb920..f03e9fc87 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -68,6 +68,26 @@ typedef int (*git_cred_acquire_cb)( unsigned int allowed_types, void *payload); +/** + * Payload for git_cred_stock_userpass_plaintext. + */ +typedef struct git_cred_stock_userpass_plaintext_payload { + char *username; + char *password; +} git_cred_stock_userpass_plaintext_payload; + + +/** + * Stock callback usable as a git_cred_acquire_cb. This calls + * git_cred_userpass_plaintext_new unless the protocol has not specified + * GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type. + */ +GIT_EXTERN(int) git_cred_stock_userpass_plaintext( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload); + /* *** End interface for credentials acquisition *** *** Begin base transport interface *** diff --git a/src/transports/cred.c b/src/transports/cred.c index 85472bd6a..5ecb8a4b9 100644 --- a/src/transports/cred.c +++ b/src/transports/cred.c @@ -57,3 +57,23 @@ int git_cred_userpass_plaintext_new( *cred = &c->parent; return 0; } + +int git_cred_stock_userpass_plaintext( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload) +{ + git_cred_stock_userpass_plaintext_payload *userpass = + (git_cred_stock_userpass_plaintext_payload*)payload; + + GIT_UNUSED(url); + + if (!userpass || !userpass->username || !userpass->password) return -1; + + if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || + git_cred_userpass_plaintext_new(cred, userpass->username, userpass->password) < 0) + return -1; + + return 0; +} diff --git a/tests-clar/network/cred.c b/tests-clar/network/cred.c new file mode 100644 index 000000000..52920c3f2 --- /dev/null +++ b/tests-clar/network/cred.c @@ -0,0 +1,27 @@ +#include "clar_libgit2.h" + +#include "git2/transport.h" + +void test_network_cred__stock_userpass_validates_args(void) +{ + git_cred_stock_userpass_plaintext_payload payload = {0}; + + cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, NULL)); + + payload.username = "user"; + cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, &payload)); + + payload.username = NULL; + payload.username = "pass"; + cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, &payload)); +} + +void test_network_cred__stock_userpass_validates_that_method_is_allowed(void) +{ + git_cred *cred; + git_cred_stock_userpass_plaintext_payload payload = {"user", "pass"}; + + cl_git_fail(git_cred_stock_userpass_plaintext(&cred, NULL, 0, &payload)); + cl_git_pass(git_cred_stock_userpass_plaintext(&cred, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload)); + git__free(cred); +} diff --git a/tests-clar/online/clone.c b/tests-clar/online/clone.c index 082ed52b3..9c51d692c 100644 --- a/tests-clar/online/clone.c +++ b/tests-clar/online/clone.c @@ -121,7 +121,7 @@ static int update_tips(const char *refname, const git_oid *a, const git_oid *b, return 0; } -void test_clone_network__custom_remote_callbacks(void) +void test_online_clone__custom_remote_callbacks(void) { git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT; int callcount = 0; @@ -134,39 +134,18 @@ void test_clone_network__custom_remote_callbacks(void) cl_assert(callcount > 0); } -struct cred_user_pass { - const char *user; - const char *pass; -}; - -static int cred_acquire( - git_cred **cred, - const char *url, - unsigned int allowed_types, - void *payload) -{ - struct cred_user_pass *user_pass = (struct cred_user_pass*)payload; - - GIT_UNUSED(url); - if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || - git_cred_userpass_plaintext_new(cred, user_pass->user, user_pass->pass) < 0) - return -1; - - return 0; -} - -void test_clone_network__credentials(void) +void test_online_clone__credentials(void) { /* Remote URL environment variable must be set. User and password are optional. */ const char *remote_url = cl_getenv("GITTEST_REMOTE_URL"); - struct cred_user_pass user_pass = { + git_cred_stock_userpass_plaintext_payload user_pass = { cl_getenv("GITTEST_REMOTE_USER"), cl_getenv("GITTEST_REMOTE_PASS") }; if (!remote_url) return; - g_options.cred_acquire_cb = cred_acquire; + g_options.cred_acquire_cb = git_cred_stock_userpass_plaintext; g_options.cred_acquire_payload = &user_pass; cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options)); From 520dcc1c000c7c29058d6ae56982461e782210fe Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Tue, 8 Jan 2013 19:55:59 -0800 Subject: [PATCH 2/2] Move credential helpers to their own (optional) header --- include/git2/cred_helpers.h | 50 +++++++++++++++++++++++++++++++++++ include/git2/transport.h | 21 +-------------- src/transports/cred.c | 21 +-------------- src/transports/cred_helpers.c | 28 ++++++++++++++++++++ tests-clar/network/cred.c | 16 +++++------ tests-clar/online/clone.c | 5 ++-- 6 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 include/git2/cred_helpers.h create mode 100644 src/transports/cred_helpers.c diff --git a/include/git2/cred_helpers.h b/include/git2/cred_helpers.h new file mode 100644 index 000000000..7c213c8dd --- /dev/null +++ b/include/git2/cred_helpers.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_git_cred_helpers_h__ +#define INCLUDE_git_cred_helpers_h__ + +#include "git2/transport.h" + +/** + * @file git2/cred_helpers.h + * @brief Utility functions for credential management + * @defgroup git_cred_helpers credential management helpers + * @ingroup Git + * @{ + */ +GIT_BEGIN_DECL + +/** + * Payload for git_cred_stock_userpass_plaintext. + */ +typedef struct git_cred_userpass_payload { + char *username; + char *password; +} git_cred_userpass_payload; + + +/** + * Stock callback usable as a git_cred_acquire_cb. This calls + * git_cred_userpass_plaintext_new unless the protocol has not specified + * GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type. + * + * @param cred The newly created credential object. + * @param url The resource for which we are demanding a credential. + * @param allowed_types A bitmask stating which cred types are OK to return. + * @param payload The payload provided when specifying this callback. (This is + * interpreted as a `git_cred_userpass_payload*`.) + */ +GIT_EXTERN(int) git_cred_userpass( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload); + + +/** @} */ +GIT_END_DECL +#endif diff --git a/include/git2/transport.h b/include/git2/transport.h index f03e9fc87..1aa87cabe 100644 --- a/include/git2/transport.h +++ b/include/git2/transport.h @@ -61,6 +61,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( * @param cred The newly created credential object. * @param url The resource for which we are demanding a credential. * @param allowed_types A bitmask stating which cred types are OK to return. + * @param payload The payload provided when specifying this callback. */ typedef int (*git_cred_acquire_cb)( git_cred **cred, @@ -68,26 +69,6 @@ typedef int (*git_cred_acquire_cb)( unsigned int allowed_types, void *payload); -/** - * Payload for git_cred_stock_userpass_plaintext. - */ -typedef struct git_cred_stock_userpass_plaintext_payload { - char *username; - char *password; -} git_cred_stock_userpass_plaintext_payload; - - -/** - * Stock callback usable as a git_cred_acquire_cb. This calls - * git_cred_userpass_plaintext_new unless the protocol has not specified - * GIT_CREDTYPE_USERPASS_PLAINTEXT as an allowed type. - */ -GIT_EXTERN(int) git_cred_stock_userpass_plaintext( - git_cred **cred, - const char *url, - unsigned int allowed_types, - void *payload); - /* *** End interface for credentials acquisition *** *** Begin base transport interface *** diff --git a/src/transports/cred.c b/src/transports/cred.c index 5ecb8a4b9..ecb026062 100644 --- a/src/transports/cred.c +++ b/src/transports/cred.c @@ -7,6 +7,7 @@ #include "git2.h" #include "smart.h" +#include "git2/cred_helpers.h" static void plaintext_free(struct git_cred *cred) { @@ -57,23 +58,3 @@ int git_cred_userpass_plaintext_new( *cred = &c->parent; return 0; } - -int git_cred_stock_userpass_plaintext( - git_cred **cred, - const char *url, - unsigned int allowed_types, - void *payload) -{ - git_cred_stock_userpass_plaintext_payload *userpass = - (git_cred_stock_userpass_plaintext_payload*)payload; - - GIT_UNUSED(url); - - if (!userpass || !userpass->username || !userpass->password) return -1; - - if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || - git_cred_userpass_plaintext_new(cred, userpass->username, userpass->password) < 0) - return -1; - - return 0; -} diff --git a/src/transports/cred_helpers.c b/src/transports/cred_helpers.c new file mode 100644 index 000000000..8d8eb9990 --- /dev/null +++ b/src/transports/cred_helpers.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "common.h" +#include "git2/cred_helpers.h" + +int git_cred_userpass( + git_cred **cred, + const char *url, + unsigned int allowed_types, + void *payload) +{ + git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload; + + GIT_UNUSED(url); + + if (!userpass || !userpass->username || !userpass->password) return -1; + + if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 || + git_cred_userpass_plaintext_new(cred, userpass->username, userpass->password) < 0) + return -1; + + return 0; +} diff --git a/tests-clar/network/cred.c b/tests-clar/network/cred.c index 52920c3f2..0fdcf3aa0 100644 --- a/tests-clar/network/cred.c +++ b/tests-clar/network/cred.c @@ -1,27 +1,27 @@ #include "clar_libgit2.h" -#include "git2/transport.h" +#include "git2/cred_helpers.h" void test_network_cred__stock_userpass_validates_args(void) { - git_cred_stock_userpass_plaintext_payload payload = {0}; + git_cred_userpass_payload payload = {0}; - cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, NULL)); + cl_git_fail(git_cred_userpass(NULL, NULL, 0, NULL)); payload.username = "user"; - cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, &payload)); + cl_git_fail(git_cred_userpass(NULL, NULL, 0, &payload)); payload.username = NULL; payload.username = "pass"; - cl_git_fail(git_cred_stock_userpass_plaintext(NULL, NULL, 0, &payload)); + cl_git_fail(git_cred_userpass(NULL, NULL, 0, &payload)); } void test_network_cred__stock_userpass_validates_that_method_is_allowed(void) { git_cred *cred; - git_cred_stock_userpass_plaintext_payload payload = {"user", "pass"}; + git_cred_userpass_payload payload = {"user", "pass"}; - cl_git_fail(git_cred_stock_userpass_plaintext(&cred, NULL, 0, &payload)); - cl_git_pass(git_cred_stock_userpass_plaintext(&cred, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload)); + cl_git_fail(git_cred_userpass(&cred, NULL, 0, &payload)); + cl_git_pass(git_cred_userpass(&cred, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload)); git__free(cred); } diff --git a/tests-clar/online/clone.c b/tests-clar/online/clone.c index 9c51d692c..8226bd054 100644 --- a/tests-clar/online/clone.c +++ b/tests-clar/online/clone.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "git2/clone.h" +#include "git2/cred_helpers.h" #include "repository.h" #define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository" @@ -138,14 +139,14 @@ void test_online_clone__credentials(void) { /* Remote URL environment variable must be set. User and password are optional. */ const char *remote_url = cl_getenv("GITTEST_REMOTE_URL"); - git_cred_stock_userpass_plaintext_payload user_pass = { + git_cred_userpass_payload user_pass = { cl_getenv("GITTEST_REMOTE_USER"), cl_getenv("GITTEST_REMOTE_PASS") }; if (!remote_url) return; - g_options.cred_acquire_cb = git_cred_stock_userpass_plaintext; + g_options.cred_acquire_cb = git_cred_userpass; g_options.cred_acquire_payload = &user_pass; cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options));