diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2011-09-11 00:40:24 +0200 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2011-09-11 17:22:26 +0200 |
commit | 33bd3d6cd935f93b6d2c8b89d11e32c5f540ea6c (patch) | |
tree | c8fcda22a9aad929f2350fa3c857930fd3258ec2 /src/auth.c | |
parent | 28bfc7645c16a407d6fc3889a3ce611cbb86ec8f (diff) | |
download | libssh-33bd3d6cd935f93b6d2c8b89d11e32c5f540ea6c.tar.gz libssh-33bd3d6cd935f93b6d2c8b89d11e32c5f540ea6c.tar.xz libssh-33bd3d6cd935f93b6d2c8b89d11e32c5f540ea6c.zip |
auth: Implement nonblocking ssh_auth_agent
Diffstat (limited to 'src/auth.c')
-rw-r--r-- | src/auth.c | 104 |
1 files changed, 68 insertions, 36 deletions
@@ -903,6 +903,19 @@ fail: 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. * @@ -926,12 +939,9 @@ fail: * before you connect to the server. */ int ssh_userauth_agent(ssh_session session, - const char *username) -{ - ssh_key pubkey; - char *comment; + const char *username) { int rc; - + struct ssh_agent_state_struct *state; if (session == NULL) { return SSH_AUTH_ERROR; } @@ -939,41 +949,63 @@ int ssh_userauth_agent(ssh_session session, if (!agent_is_running(session)) { return SSH_AUTH_DENIED; } - - for (pubkey = ssh_agent_get_first_ident(session, &comment); - pubkey != NULL; - pubkey = ssh_agent_get_next_ident(session, &comment)) { - ssh_log(session, SSH_LOG_RARE, "Trying identity %s", comment); - - rc = ssh_userauth_try_publickey(session, username, pubkey); - if (rc == SSH_AUTH_ERROR) { - ssh_string_free_char(comment); - ssh_key_free(pubkey); - return rc; - } else if (rc != SSH_AUTH_SUCCESS) { - ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s refused by server", comment); - ssh_string_free_char(comment); - ssh_key_free(pubkey); - continue; + if (!session->agent_state){ + session->agent_state = malloc(sizeof(struct ssh_agent_state_struct)); + ZERO_STRUCTP(session->agent_state); + session->agent_state->state=SSH_AGENT_STATE_NONE; + } + state = session->agent_state; + 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) { + ssh_string_free_char(state->comment); + 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; + } else if (rc != SSH_AUTH_SUCCESS) { + ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s refused by server", state->comment); + ssh_string_free_char(state->comment); + ssh_key_free(state->pubkey); + state->pubkey = ssh_agent_get_next_ident(session, &state->comment); + state->state = SSH_AGENT_STATE_NONE; + continue; + } - ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s accepted by server", comment); - - rc = ssh_userauth_agent_publickey(session, username, pubkey); - ssh_string_free_char(comment); - ssh_key_free(pubkey); - if (rc == SSH_AUTH_ERROR) { - return rc; - } else if (rc != SSH_AUTH_SUCCESS) { - ssh_log(session, - SSH_LOG_RARE, - "Server accepted public key but refused the signature"); - continue; + ssh_log(session, SSH_LOG_PROTOCOL, "Public key of %s accepted by server", state->comment); + state->state = SSH_AGENT_STATE_AUTH; + } + if (state->state == SSH_AGENT_STATE_AUTH){ + 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) { + SAFE_FREE(session->agent_state); + return rc; + } else if (rc != SSH_AUTH_SUCCESS) { + ssh_log(session, + SSH_LOG_RARE, + "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; + } + SAFE_FREE(session->agent_state); + return SSH_AUTH_SUCCESS; } - - return SSH_AUTH_SUCCESS; } - + SAFE_FREE(session->agent_state); return SSH_AUTH_ERROR; } #endif |