summaryrefslogtreecommitdiff
path: root/src/transports
diff options
context:
space:
mode:
authorAlessandro Ghedini <alessandro@ghedini.me>2013-11-20 14:11:44 +0100
committerAlessandro Ghedini <alessandro@ghedini.me>2013-11-20 14:11:44 +0100
commitee7040fd9b056ef61c538717c11c3eab48d86ac5 (patch)
treee19e1ae9ae34cd841c2f857a4321a8577d8827b3 /src/transports
parent43cb8b32428b1b29994874349ec22eb5372e152c (diff)
downloadlibgit2-ee7040fd9b056ef61c538717c11c3eab48d86ac5.tar.gz
ssh: add support for ssh-agent authentication
Diffstat (limited to 'src/transports')
-rw-r--r--src/transports/cred.c22
-rw-r--r--src/transports/ssh.c54
2 files changed, 74 insertions, 2 deletions
diff --git a/src/transports/cred.c b/src/transports/cred.c
index 05d2c8dc6..abae70b51 100644
--- a/src/transports/cred.c
+++ b/src/transports/cred.c
@@ -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,
diff --git a/src/transports/ssh.c b/src/transports/ssh.c
index 4a905e3c9..37f17080a 100644
--- a/src/transports/ssh.c
+++ b/src/transports/ssh.c
@@ -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: {