diff options
Diffstat (limited to 'src/transports/cred.c')
-rw-r--r-- | src/transports/cred.c | 129 |
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; |