Merge pull request #1903 from ethomson/ssh Allowed credential types should be a bitfield
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
diff --git a/include/git2/transport.h b/include/git2/transport.h
index 9901b15..065b318 100644
--- a/include/git2/transport.h
+++ b/include/git2/transport.h
@@ -28,11 +28,16 @@ GIT_BEGIN_DECL
*** Begin interface for credentials acquisition ***
*/
+/** Authentication type requested */
typedef enum {
/* git_cred_userpass_plaintext */
- GIT_CREDTYPE_USERPASS_PLAINTEXT = 1,
- GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = 2,
- GIT_CREDTYPE_SSH_PUBLICKEY = 3,
+ GIT_CREDTYPE_USERPASS_PLAINTEXT = (1u << 0),
+
+ /* git_cred_ssh_keyfile_passphrase */
+ GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE = (1u << 1),
+
+ /* git_cred_ssh_publickey */
+ GIT_CREDTYPE_SSH_PUBLICKEY = (1u << 2),
} git_credtype_t;
/* The base structure for all credential types */
@@ -56,7 +61,7 @@ typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));
typedef int (*git_cred_sign_callback)(void *, ...);
#endif
-/* A ssh key file and passphrase */
+/* An ssh key file and passphrase */
typedef struct git_cred_ssh_keyfile_passphrase {
git_cred parent;
char *username;
@@ -65,7 +70,7 @@ typedef struct git_cred_ssh_keyfile_passphrase {
char *passphrase;
} git_cred_ssh_keyfile_passphrase;
-/* A ssh public key and authentication callback */
+/* An ssh public key and authentication callback */
typedef struct git_cred_ssh_publickey {
git_cred parent;
char *username;
@@ -123,17 +128,17 @@ GIT_EXTERN(int) git_cred_ssh_keyfile_passphrase_new(
* @param username username to use to authenticate
* @param publickey The bytes of the public key.
* @param publickey_len The length of the public key in bytes.
- * @param sign_fn The callback method for authenticating.
- * @param sign_data The abstract data sent to the sign_callback method.
+ * @param sign_fn The callback method to sign the data during the challenge.
+ * @param sign_data The data to pass to the sign function.
* @return 0 for success or an error code for failure
*/
GIT_EXTERN(int) git_cred_ssh_publickey_new(
git_cred **out,
const char *username,
const char *publickey,
- size_t publickey_len,
- git_cred_sign_callback sign_fn,
- void *sign_data);
+ size_t publickey_len,
+ git_cred_sign_callback sign_fn,
+ void *sign_data);
/**
* Signature of a function which acquires a credential object.
diff --git a/src/transports/cred.c b/src/transports/cred.c
index 35aaf4f..79b17e8 100644
--- a/src/transports/cred.c
+++ b/src/transports/cred.c
@@ -58,7 +58,7 @@ int git_cred_userpass_plaintext_new(
{
git_cred_userpass_plaintext *c;
- assert(cred);
+ assert(cred && username && password);
c = git__malloc(sizeof(git_cred_userpass_plaintext));
GITERR_CHECK_ALLOC(c);
diff --git a/src/transports/ssh.c b/src/transports/ssh.c
index 62f3f0b..647211f 100644
--- a/src/transports/ssh.c
+++ b/src/transports/ssh.c
@@ -349,7 +349,8 @@ static int _git_ssh_setup_conn(
if (t->owner->cred_acquire_cb(
&t->cred, t->owner->url, user,
GIT_CREDTYPE_USERPASS_PLAINTEXT |
- GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE,
+ GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE |
+ GIT_CREDTYPE_SSH_PUBLICKEY,
t->owner->cred_acquire_payload) < 0)
goto on_error;
diff --git a/tests-clar/online/push.c b/tests-clar/online/push.c
index 957cef7..d3d2374 100644
--- a/tests-clar/online/push.c
+++ b/tests-clar/online/push.c
@@ -37,23 +37,34 @@ static git_oid _tag_lightweight;
static git_oid _tag_tag;
static int cred_acquire_cb(
- git_cred **cred,
- const char *url,
- const char *user_from_url,
- unsigned int allowed_types,
- void *payload)
+ git_cred **cred,
+ const char *url,
+ const char *user_from_url,
+ unsigned int allowed_types,
+ void *payload)
{
GIT_UNUSED(url);
GIT_UNUSED(user_from_url);
+ GIT_UNUSED(payload);
- if (GIT_CREDTYPE_SSH_PUBLICKEY & allowed_types)
+ if (GIT_CREDTYPE_SSH_KEYFILE_PASSPHRASE & allowed_types) {
+ if (!_remote_user || !_remote_ssh_pubkey || !_remote_ssh_key || !_remote_ssh_passphrase) {
+ printf("GITTEST_REMOTE_USER, GITTEST_REMOTE_SSH_PUBKEY, GITTEST_REMOTE_SSH_KEY and GITTEST_REMOTE_SSH_PASSPHRASE must be set\n");
+ return -1;
+ }
return git_cred_ssh_keyfile_passphrase_new(cred, _remote_user, _remote_ssh_pubkey, _remote_ssh_key, _remote_ssh_passphrase);
+ }
+
+ if (GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) {
+ if (!_remote_user || !_remote_pass) {
+ printf("GITTEST_REMOTE_USER and GITTEST_REMOTE_PASS must be set\n");
+ return -1;
+ }
- if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
- git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass) < 0)
- return -1;
+ return git_cred_userpass_plaintext_new(cred, _remote_user, _remote_pass);
+ }
- return 0;
+ return -1;
}
typedef struct {