summaryrefslogtreecommitdiff
path: root/src/transports/cred.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transports/cred.c')
-rw-r--r--src/transports/cred.c129
1 files changed, 87 insertions, 42 deletions
diff --git a/src/transports/cred.c b/src/transports/cred.c
index 05d2c8dc..913ec36c 100644
--- a/src/transports/cred.c
+++ b/src/transports/cred.c
@@ -11,31 +11,10 @@
int git_cred_has_username(git_cred *cred)
{
- int ret = 0;
+ if (cred->credtype == GIT_CREDTYPE_DEFAULT)
+ return 0;
- switch (cred->credtype) {
- case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
- git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
- ret = !!c->username;
- break;
- }
- case GIT_CREDTYPE_SSH_KEY: {
- git_cred_ssh_key *c = (git_cred_ssh_key *)cred;
- ret = !!c->username;
- break;
- }
- case GIT_CREDTYPE_SSH_CUSTOM: {
- git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred;
- ret = !!c->username;
- break;
- }
- case GIT_CREDTYPE_DEFAULT: {
- ret = 0;
- break;
- }
- }
-
- return ret;
+ return 1;
}
static void plaintext_free(struct git_cred *cred)
@@ -51,7 +30,6 @@ static void plaintext_free(struct git_cred *cred)
git__free(c->password);
}
- git__memzero(c, sizeof(*c));
git__free(c);
}
@@ -94,8 +72,13 @@ static void ssh_key_free(struct git_cred *cred)
(git_cred_ssh_key *)cred;
git__free(c->username);
- git__free(c->publickey);
- git__free(c->privatekey);
+
+ if (c->privatekey) {
+ /* Zero the memory which previously held the private key */
+ size_t key_len = strlen(c->privatekey);
+ git__memzero(c->privatekey, key_len);
+ git__free(c->privatekey);
+ }
if (c->passphrase) {
/* Zero the memory which previously held the passphrase */
@@ -104,7 +87,22 @@ static void ssh_key_free(struct git_cred *cred)
git__free(c->passphrase);
}
- git__memzero(c, sizeof(*c));
+ if (c->publickey) {
+ /* Zero the memory which previously held the public key */
+ size_t key_len = strlen(c->publickey);
+ git__memzero(c->publickey, key_len);
+ git__free(c->publickey);
+ }
+
+ git__free(c);
+}
+
+static void ssh_interactive_free(struct git_cred *cred)
+{
+ git_cred_ssh_interactive *c = (git_cred_ssh_interactive *)cred;
+
+ git__free(c->username);
+
git__free(c);
}
@@ -113,9 +111,14 @@ static void ssh_custom_free(struct git_cred *cred)
git_cred_ssh_custom *c = (git_cred_ssh_custom *)cred;
git__free(c->username);
- git__free(c->publickey);
- git__memzero(c, sizeof(*c));
+ if (c->publickey) {
+ /* Zero the memory which previously held the publickey */
+ size_t key_len = strlen(c->publickey);
+ git__memzero(c->publickey, key_len);
+ git__free(c->publickey);
+ }
+
git__free(c);
}
@@ -135,7 +138,7 @@ int git_cred_ssh_key_new(
{
git_cred_ssh_key *c;
- assert(cred && privatekey);
+ assert(username && cred && privatekey);
c = git__calloc(1, sizeof(git_cred_ssh_key));
GITERR_CHECK_ALLOC(c);
@@ -143,10 +146,8 @@ int git_cred_ssh_key_new(
c->parent.credtype = GIT_CREDTYPE_SSH_KEY;
c->parent.free = ssh_key_free;
- if (username) {
- c->username = git__strdup(username);
- GITERR_CHECK_ALLOC(c->username);
- }
+ c->username = git__strdup(username);
+ GITERR_CHECK_ALLOC(c->username);
c->privatekey = git__strdup(privatekey);
GITERR_CHECK_ALLOC(c->privatekey);
@@ -165,17 +166,63 @@ int git_cred_ssh_key_new(
return 0;
}
+int git_cred_ssh_interactive_new(
+ git_cred **out,
+ const char *username,
+ git_cred_ssh_interactive_callback prompt_callback,
+ void *payload)
+{
+ git_cred_ssh_interactive *c;
+
+ assert(out && username && prompt_callback);
+
+ c = git__calloc(1, sizeof(git_cred_ssh_interactive));
+ GITERR_CHECK_ALLOC(c);
+
+ c->parent.credtype = GIT_CREDTYPE_SSH_INTERACTIVE;
+ c->parent.free = ssh_interactive_free;
+
+ c->username = git__strdup(username);
+ GITERR_CHECK_ALLOC(c->username);
+
+ c->prompt_callback = prompt_callback;
+ c->payload = payload;
+
+ *out = &c->parent;
+ return 0;
+}
+
+int git_cred_ssh_key_from_agent(git_cred **cred, const char *username) {
+ git_cred_ssh_key *c;
+
+ assert(username && cred);
+
+ c = git__calloc(1, sizeof(git_cred_ssh_key));
+ GITERR_CHECK_ALLOC(c);
+
+ c->parent.credtype = GIT_CREDTYPE_SSH_KEY;
+ c->parent.free = ssh_key_free;
+
+ c->username = git__strdup(username);
+ GITERR_CHECK_ALLOC(c->username);
+
+ c->privatekey = NULL;
+
+ *cred = &c->parent;
+ return 0;
+}
+
int git_cred_ssh_custom_new(
git_cred **cred,
const char *username,
const char *publickey,
size_t publickey_len,
git_cred_sign_callback sign_callback,
- void *sign_data)
+ void *payload)
{
git_cred_ssh_custom *c;
- assert(cred);
+ assert(username && cred);
c = git__calloc(1, sizeof(git_cred_ssh_custom));
GITERR_CHECK_ALLOC(c);
@@ -183,10 +230,8 @@ int git_cred_ssh_custom_new(
c->parent.credtype = GIT_CREDTYPE_SSH_CUSTOM;
c->parent.free = ssh_custom_free;
- if (username) {
- c->username = git__strdup(username);
- GITERR_CHECK_ALLOC(c->username);
- }
+ c->username = git__strdup(username);
+ GITERR_CHECK_ALLOC(c->username);
if (publickey_len > 0) {
c->publickey = git__malloc(publickey_len);
@@ -197,7 +242,7 @@ int git_cred_ssh_custom_new(
c->publickey_len = publickey_len;
c->sign_callback = sign_callback;
- c->sign_data = sign_data;
+ c->payload = payload;
*cred = &c->parent;
return 0;