]> git.proxmox.com Git - libgit2.git/commitdiff
ssh: add support for ssh-agent authentication
authorAlessandro Ghedini <alessandro@ghedini.me>
Wed, 20 Nov 2013 13:11:44 +0000 (14:11 +0100)
committerAlessandro Ghedini <alessandro@ghedini.me>
Wed, 20 Nov 2013 13:11:44 +0000 (14:11 +0100)
src/transports/cred.c
src/transports/ssh.c

index 05d2c8dc6efec4b155776f55711554d35581fab4..abae70b514d4ee4c1a89b8f4bfb428f4df0bbd7b 100644 (file)
@@ -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,
index 4a905e3c9006f22556f2630d55b69b1f93bdf558..37f17080a2c28410f7aa40c45223b87df74bf2a7 100644 (file)
@@ -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: {