SSH1: make authentication nonblocking
Этот коммит содержится в:
родитель
ebfb2a5cdb
Коммит
af225e68cb
46
src/auth1.c
46
src/auth1.c
@ -34,12 +34,23 @@
|
|||||||
#include "libssh/string.h"
|
#include "libssh/string.h"
|
||||||
|
|
||||||
#ifdef WITH_SSH1
|
#ifdef WITH_SSH1
|
||||||
|
|
||||||
|
static int ssh_auth_status_termination(void *s){
|
||||||
|
ssh_session session=s;
|
||||||
|
if(session->auth_state != SSH_AUTH_STATE_NONE ||
|
||||||
|
session->session_state == SSH_SESSION_STATE_ERROR)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int wait_auth1_status(ssh_session session) {
|
static int wait_auth1_status(ssh_session session) {
|
||||||
enter_function();
|
enter_function();
|
||||||
/* wait for a packet */
|
/* wait for a packet */
|
||||||
while(session->auth_state == SSH_AUTH_STATE_NONE)
|
if (ssh_handle_packets_termination(session,SSH_TIMEOUT_USER,
|
||||||
if (ssh_handle_packets(session, -2) != SSH_OK)
|
ssh_auth_status_termination, session) != SSH_OK){
|
||||||
break;
|
leave_function();
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
ssh_log(session,SSH_LOG_PROTOCOL,"Auth state : %d",session->auth_state);
|
ssh_log(session,SSH_LOG_PROTOCOL,"Auth state : %d",session->auth_state);
|
||||||
leave_function();
|
leave_function();
|
||||||
switch(session->auth_state) {
|
switch(session->auth_state) {
|
||||||
@ -48,7 +59,7 @@ static int wait_auth1_status(ssh_session session) {
|
|||||||
case SSH_AUTH_STATE_FAILED:
|
case SSH_AUTH_STATE_FAILED:
|
||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
default:
|
default:
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_AGAIN;
|
||||||
}
|
}
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
@ -67,6 +78,7 @@ void ssh_auth1_handler(ssh_session session, uint8_t type){
|
|||||||
|
|
||||||
static int send_username(ssh_session session, const char *username) {
|
static int send_username(ssh_session session, const char *username) {
|
||||||
ssh_string user = NULL;
|
ssh_string user = NULL;
|
||||||
|
int rc;
|
||||||
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
||||||
if(session->auth_service_state == SSH_AUTH_SERVICE_USER_SENT) {
|
if(session->auth_service_state == SSH_AUTH_SERVICE_USER_SENT) {
|
||||||
if(session->auth_state == SSH_AUTH_STATE_FAILED)
|
if(session->auth_state == SSH_AUTH_STATE_FAILED)
|
||||||
@ -75,7 +87,8 @@ static int send_username(ssh_session session, const char *username) {
|
|||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
|
if (session->auth_service_state == SSH_AUTH_SERVICE_SENT)
|
||||||
|
goto pending;
|
||||||
if (!username) {
|
if (!username) {
|
||||||
if(!(username = session->username)) {
|
if(!(username = session->username)) {
|
||||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||||
@ -101,20 +114,28 @@ static int send_username(ssh_session session, const char *username) {
|
|||||||
}
|
}
|
||||||
ssh_string_free(user);
|
ssh_string_free(user);
|
||||||
session->auth_state=SSH_AUTH_STATE_NONE;
|
session->auth_state=SSH_AUTH_STATE_NONE;
|
||||||
|
session->auth_service_state = SSH_AUTH_SERVICE_SENT;
|
||||||
if (packet_send(session) == SSH_ERROR) {
|
if (packet_send(session) == SSH_ERROR) {
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
|
pending:
|
||||||
if(wait_auth1_status(session) == SSH_AUTH_SUCCESS){
|
rc = wait_auth1_status(session);
|
||||||
|
switch (rc){
|
||||||
|
case SSH_AUTH_SUCCESS:
|
||||||
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
||||||
session->auth_state=SSH_AUTH_STATE_SUCCESS;
|
session->auth_state=SSH_AUTH_STATE_SUCCESS;
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
} else {
|
case SSH_AUTH_DENIED:
|
||||||
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
||||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Password authentication necessary for user %s",username);
|
ssh_set_error(session,SSH_REQUEST_DENIED,"Password authentication necessary for user %s",username);
|
||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
|
case SSH_AUTH_AGAIN:
|
||||||
|
return SSH_AUTH_AGAIN;
|
||||||
|
default:
|
||||||
|
session->auth_service_state = SSH_AUTH_SERVICE_NONE;
|
||||||
|
session->auth_state=SSH_AUTH_STATE_ERROR;
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use the "none" authentication question */
|
/* use the "none" authentication question */
|
||||||
@ -146,7 +167,8 @@ int ssh_userauth1_password(ssh_session session, const char *username,
|
|||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD)
|
||||||
|
goto pending;
|
||||||
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
|
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
|
||||||
* easy to guess password sizes.
|
* easy to guess password sizes.
|
||||||
* not that sure ...
|
* not that sure ...
|
||||||
@ -195,11 +217,15 @@ int ssh_userauth1_password(ssh_session session, const char *username,
|
|||||||
ssh_string_burn(pwd);
|
ssh_string_burn(pwd);
|
||||||
ssh_string_free(pwd);
|
ssh_string_free(pwd);
|
||||||
session->auth_state=SSH_AUTH_STATE_NONE;
|
session->auth_state=SSH_AUTH_STATE_NONE;
|
||||||
|
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
|
||||||
if (packet_send(session) == SSH_ERROR) {
|
if (packet_send(session) == SSH_ERROR) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
|
pending:
|
||||||
rc = wait_auth1_status(session);
|
rc = wait_auth1_status(session);
|
||||||
|
if (rc != SSH_AUTH_AGAIN)
|
||||||
|
session->pending_call_state = SSH_PENDING_CALL_NONE;
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user