mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-23 09:10:46 +00:00
Merge pull request #1972 from ghedo/ssh_agent
ssh: add support for ssh-agent authentication
This commit is contained in:
commit
a2e873d1a1
@ -130,6 +130,18 @@ GIT_EXTERN(int) git_cred_ssh_key_new(
|
||||
const char *privatekey,
|
||||
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.
|
||||
*
|
||||
|
@ -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: {
|
||||
|
Loading…
Reference in New Issue
Block a user