Commit a2e873d1 by Vicent Martí

Merge pull request #1972 from ghedo/ssh_agent

ssh: add support for ssh-agent authentication
parents 43cb8b32 138e014c
......@@ -131,6 +131,18 @@ GIT_EXTERN(int) git_cred_ssh_key_new(
const char *passphrase);
/**
* Create a new ssh key credential object used for querying an ssh-agent.
* The supplied credential parameter will be internally duplicated.
*
* @param out The newly created credential object.
* @param username username to use to authenticate
* @return 0 for success or an error code for failure
*/
GIT_EXTERN(int) git_cred_ssh_key_from_agent(
git_cred **out,
const char *username);
/**
* Create an ssh key credential with a custom signing function.
*
* This lets you use your own function to sign the challenge.
......
......@@ -165,6 +165,28 @@ int git_cred_ssh_key_new(
return 0;
}
int git_cred_ssh_key_from_agent(git_cred **cred, const char *username) {
git_cred_ssh_key *c;
assert(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;
if (username) {
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,
......
......@@ -235,6 +235,50 @@ static int git_ssh_extract_url_parts(
return 0;
}
static int ssh_agent_auth(LIBSSH2_SESSION *session, git_cred_ssh_key *c) {
int rc = LIBSSH2_ERROR_NONE;
struct libssh2_agent_publickey *curr, *prev = NULL;
LIBSSH2_AGENT *agent = libssh2_agent_init(session);
if (agent == NULL)
return -1;
rc = libssh2_agent_connect(agent);
if (rc != LIBSSH2_ERROR_NONE)
goto shutdown;
rc = libssh2_agent_list_identities(agent);
if (rc != LIBSSH2_ERROR_NONE)
goto shutdown;
while (1) {
rc = libssh2_agent_get_identity(agent, &curr, prev);
if (rc < 0)
goto shutdown;
if (rc == 1)
goto shutdown;
rc = libssh2_agent_userauth(agent, c->username, curr);
if (rc == 0)
break;
prev = curr;
}
shutdown:
libssh2_agent_disconnect(agent);
libssh2_agent_free(agent);
return rc;
}
static int _git_ssh_authenticate_session(
LIBSSH2_SESSION* session,
const char *user,
......@@ -253,8 +297,14 @@ static int _git_ssh_authenticate_session(
case GIT_CREDTYPE_SSH_KEY: {
git_cred_ssh_key *c = (git_cred_ssh_key *)cred;
user = c->username ? c->username : user;
rc = libssh2_userauth_publickey_fromfile(
session, c->username, c->publickey, c->privatekey, c->passphrase);
if (c->privatekey)
rc = libssh2_userauth_publickey_fromfile(
session, c->username, c->publickey,
c->privatekey, c->passphrase);
else
rc = ssh_agent_auth(session, c);
break;
}
case GIT_CREDTYPE_SSH_CUSTOM: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment