1
1

auth: made keyboard-interactive nonblocking

Этот коммит содержится в:
Aris Adamantiadis 2011-09-11 13:51:02 +02:00
родитель 27dea35608
Коммит 1f31415760
2 изменённых файлов: 40 добавлений и 16 удалений

Просмотреть файл

@ -57,7 +57,9 @@ enum ssh_pending_call_e {
SSH_PENDING_CALL_AUTH_PASSWORD, SSH_PENDING_CALL_AUTH_PASSWORD,
SSH_PENDING_CALL_AUTH_OFFER_PUBKEY, SSH_PENDING_CALL_AUTH_OFFER_PUBKEY,
SSH_PENDING_CALL_AUTH_PUBKEY, SSH_PENDING_CALL_AUTH_PUBKEY,
SSH_PENDING_CALL_AUTH_AGENT SSH_PENDING_CALL_AUTH_AGENT,
SSH_PENDING_CALL_AUTH_KBDINT_INIT,
SSH_PENDING_CALL_AUTH_KBDINT_SEND
}; };
/* libssh calls may block an undefined amount of time */ /* libssh calls may block an undefined amount of time */

Просмотреть файл

@ -1510,8 +1510,15 @@ static int ssh_userauth_kbdint_init(ssh_session session,
{ {
ssh_string str; ssh_string str;
int rc; int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT)
goto pending;
if (session->pending_call_state != SSH_PENDING_CALL_NONE){
ssh_set_error_invalid(session,"ssh_userauth_kbdint_init");
return SSH_ERROR;
}
rc = ssh_userauth_request_service(session); rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN)
return SSH_AUTH_AGAIN;
if (rc != SSH_OK) { if (rc != SSH_OK) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
@ -1591,13 +1598,16 @@ static int ssh_userauth_kbdint_init(ssh_session session,
} }
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; session->auth_state = SSH_AUTH_STATE_KBDINT_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT;
ssh_log(session,SSH_LOG_PROTOCOL,"Sending keyboard-interactive init request");
rc = packet_send(session); rc = packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
pending:
rc = ssh_userauth_get_response(session); rc = ssh_userauth_get_response(session);
if (rc != SSH_AUTH_AGAIN)
session->pending_call_state = SSH_PENDING_CALL_NONE;
return rc; return rc;
fail: fail:
ssh_set_error_oom(session); ssh_set_error_oom(session);
@ -1622,7 +1632,12 @@ static int ssh_userauth_kbdint_send(ssh_session session)
ssh_string answer; ssh_string answer;
uint32_t i; uint32_t i;
int rc; int rc;
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND)
goto pending;
if (session->pending_call_state != SSH_PENDING_CALL_NONE){
ssh_set_error_invalid(session,"ssh_userauth_kbdint_send");
return SSH_ERROR;
}
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE); rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE);
if (rc < 0) { if (rc < 0) {
goto fail; goto fail;
@ -1652,16 +1667,19 @@ static int ssh_userauth_kbdint_send(ssh_session session)
} }
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT; session->auth_state = SSH_AUTH_STATE_KBDINT_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_SEND;
ssh_kbdint_free(session->kbdint); ssh_kbdint_free(session->kbdint);
session->kbdint = NULL; session->kbdint = NULL;
ssh_log(session,SSH_LOG_PROTOCOL,"Sending keyboard-interactive response packet");
rc = packet_send(session); rc = packet_send(session);
if (rc == SSH_ERROR) { if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR; return SSH_AUTH_ERROR;
} }
pending:
rc = ssh_userauth_get_response(session); rc = ssh_userauth_get_response(session);
if (rc != SSH_AUTH_AGAIN)
session->pending_call_state = SSH_PENDING_CALL_NONE;
return rc; return rc;
fail: fail:
ssh_set_error_oom(session); ssh_set_error_oom(session);
@ -1837,24 +1855,28 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
return SSH_AUTH_DENIED; return SSH_AUTH_DENIED;
} }
#endif #endif
if ((session->pending_call_state == SSH_PENDING_CALL_NONE && session->kbdint == NULL) ||
if (session->kbdint == NULL) { session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT)
rc = ssh_userauth_kbdint_init(session, user, submethods); rc = ssh_userauth_kbdint_init(session, user, submethods);
else if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND ||
return rc; session->kbdint != NULL) {
} else {
/* /*
* If we are at this point, it is because session->kbdint exists. * If we are at this point, it is because session->kbdint exists.
* It means the user has set some information there we need to send * It means the user has set some information there we need to send
* the server and then we need to ack the status (new questions or ok * the server and then we need to ack the status (new questions or ok
* pass in). * pass in).
* It is possible that session->kbdint is NULL while we're waiting for
* a reply, hence the test for the pending call.
*/ */
rc = ssh_userauth_kbdint_send(session); rc = ssh_userauth_kbdint_send(session);
} else {
return rc; /* We are here because session->kbdint == NULL & state != NONE.
* This should not happen
*/
rc = SSH_AUTH_ERROR;
ssh_set_error(session,SSH_FATAL,"Invalid state in %s", __FUNCTION__);
} }
return rc;
return SSH_AUTH_DENIED;
} }
/** /**