1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-29 01:03:57 +03:00

auth: Implement nonblocking ssh_auth_agent

This commit is contained in:
Aris Adamantiadis
2011-09-11 00:40:24 +02:00
parent 28bfc7645c
commit 33bd3d6cd9
2 changed files with 71 additions and 38 deletions

View File

@@ -117,6 +117,7 @@ struct ssh_session_struct {
enum ssh_auth_service_state_e auth_service_state; enum ssh_auth_service_state_e auth_service_state;
enum ssh_auth_state_e auth_state; enum ssh_auth_state_e auth_state;
enum ssh_channel_request_state_e global_req_state; enum ssh_channel_request_state_e global_req_state;
struct ssh_agent_state_struct *agent_state;
KEX server_kex; KEX server_kex;
KEX client_kex; KEX client_kex;

View File

@@ -903,6 +903,19 @@ fail:
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
enum ssh_agent_state_e {
SSH_AGENT_STATE_NONE = 0,
SSH_AGENT_STATE_PUBKEY,
SSH_AGENT_STATE_AUTH
};
struct ssh_agent_state_struct {
enum ssh_agent_state_e state;
ssh_key pubkey;
char *comment;
};
/** /**
* @brief Try to do public key authentication with ssh agent. * @brief Try to do public key authentication with ssh agent.
* *
@@ -926,12 +939,9 @@ fail:
* before you connect to the server. * before you connect to the server.
*/ */
int ssh_userauth_agent(ssh_session session, int ssh_userauth_agent(ssh_session session,
const char *username) const char *username) {
{
ssh_key pubkey;
char *comment;
int rc; int rc;
struct ssh_agent_state_struct *state;
if (session == NULL) { if (session == NULL) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
@@ -939,41 +949,63 @@ int ssh_userauth_agent(ssh_session session,
if (!agent_is_running(session)) { if (!agent_is_running(session)) {
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
if (!session->agent_state){
for (pubkey = ssh_agent_get_first_ident(session, &comment); session->agent_state = malloc(sizeof(struct ssh_agent_state_struct));
pubkey != NULL; ZERO_STRUCTP(session->agent_state);
pubkey = ssh_agent_get_next_ident(session, &comment)) { session->agent_state->state=SSH_AGENT_STATE_NONE;
ssh_log(session, SSH_LOG_RARE, "Trying identity %s", comment); }
state = session->agent_state;
rc = ssh_userauth_try_publickey(session, username, pubkey); if (state->pubkey == NULL)
state->pubkey = ssh_agent_get_first_ident(session, &state->comment);
while (state->pubkey != NULL) {
if(state->state == SSH_AGENT_STATE_NONE){
ssh_log(session, SSH_LOG_RARE, "Trying identity %s", state->comment);
}
if(state->state == SSH_AGENT_STATE_NONE ||
state->state == SSH_AGENT_STATE_PUBKEY){
rc = ssh_userauth_try_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_ERROR) { if (rc == SSH_AUTH_ERROR) {
ssh_string_free_char(comment); ssh_string_free_char(state->comment);
ssh_key_free(pubkey); ssh_key_free(state->pubkey);
SAFE_FREE(session->agent_state);
return rc;
} else if (rc == SSH_AUTH_AGAIN) {
state->state = SSH_AGENT_STATE_PUBKEY;
return rc; return rc;
} else if (rc != SSH_AUTH_SUCCESS) { } else if (rc != SSH_AUTH_SUCCESS) {
ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s refused by server", comment); ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s refused by server", state->comment);
ssh_string_free_char(comment); ssh_string_free_char(state->comment);
ssh_key_free(pubkey); ssh_key_free(state->pubkey);
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue; continue;
} }
ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s accepted by server", comment); ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s accepted by server", state->comment);
state->state = SSH_AGENT_STATE_AUTH;
rc = ssh_userauth_agent_publickey(session, username, pubkey); }
ssh_string_free_char(comment); if (state->state == SSH_AGENT_STATE_AUTH){
ssh_key_free(pubkey); rc = ssh_userauth_agent_publickey(session, username, state->pubkey);
if (rc == SSH_AUTH_AGAIN)
return rc;
ssh_string_free_char(state->comment);
ssh_key_free(state->pubkey);
if (rc == SSH_AUTH_ERROR) { if (rc == SSH_AUTH_ERROR) {
SAFE_FREE(session->agent_state);
return rc; return rc;
} else if (rc != SSH_AUTH_SUCCESS) { } else if (rc != SSH_AUTH_SUCCESS) {
ssh_log(session, ssh_log(session,
SSH_LOG_RARE, SSH_LOG_RARE,
"Server accepted public key but refused the signature"); "Server accepted public key but refused the signature");
state->pubkey = ssh_agent_get_next_ident(session, &state->comment);
state->state = SSH_AGENT_STATE_NONE;
continue; continue;
} }
SAFE_FREE(session->agent_state);
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
} }
}
SAFE_FREE(session->agent_state);
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
#endif #endif