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:
@@ -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;
|
||||||
|
|||||||
80
src/auth.c
80
src/auth.c
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user