auth: made keyboard-interactive nonblocking
Этот коммит содержится в:
родитель
27dea35608
Коммит
1f31415760
@ -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 */
|
||||||
|
52
src/auth.c
52
src/auth.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user