Commit 86774742a9bd3f3d4fc37ab35b2800abffeccfd8

Vicent Martí 2013-10-21T13:06:27

Merge pull request #1903 from ethomson/ssh Allowed credential types should be a bitfield

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 {