From 227764a8033c773397bc997239bfad1f85ef40a5 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Sun, 16 Jan 2011 21:23:50 +0100 Subject: [PATCH] Made ssh_userauth_none nonblocking --- include/libssh/libssh.h | 1 + include/libssh/session.h | 3 ++- src/auth.c | 56 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 5a3505cc..2dbdb7eb 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -155,6 +155,7 @@ enum ssh_auth_e { SSH_AUTH_DENIED, SSH_AUTH_PARTIAL, SSH_AUTH_INFO, + SSH_AUTH_AGAIN, SSH_AUTH_ERROR=-1 }; diff --git a/include/libssh/session.h b/include/libssh/session.h index 3bbd0a8a..bcb4ed4a 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -53,7 +53,8 @@ enum ssh_dh_state_e { enum ssh_pending_call_e { SSH_PENDING_CALL_NONE = 0, - SSH_PENDING_CALL_CONNECT + SSH_PENDING_CALL_CONNECT, + SSH_PENDING_CALL_AUTH_NONE }; /* libssh calls may block an undefined amount of time */ diff --git a/src/auth.c b/src/auth.c index 2ae9a9db..96ec06a9 100644 --- a/src/auth.c +++ b/src/auth.c @@ -226,15 +226,48 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok){ return rc; } +static int auth_status_termination(void *user){ + ssh_session session=(ssh_session)user; + switch(session->auth_state){ + case SSH_AUTH_STATE_NONE: + case SSH_AUTH_STATE_KBDINT_SENT: + return 0; + default: + return 1; + } +} + +/** + * @internal + * @brief waits for a response of an authentication function + * @param[in] session SSH session + * @returns SSH_AUTH_SUCCESS Authentication success, or pubkey accepted + * SSH_AUTH_PARTIAL Authentication succeeded but another mean + * of authentication is needed. + * SSH_AUTH_INFO Data for keyboard-interactive + * SSH_AUTH_AGAIN In nonblocking mode, call has to be made again + * SSH_AUTH_ERROR Error during the process. + */ static int wait_auth_status(ssh_session session) { int rc = SSH_AUTH_ERROR; enter_function(); - while (session->auth_state == SSH_AUTH_STATE_NONE || - session->auth_state == SSH_AUTH_STATE_KBDINT_SENT) { - if (ssh_handle_packets(session,-1) != SSH_OK) - break; + if(ssh_is_blocking(session)){ + if(ssh_handle_packets_termination(session,-1,auth_status_termination, + session) == SSH_ERROR){ + leave_function(); + return SSH_AUTH_ERROR; + } + } else { + if(ssh_handle_packets(session, 0) == SSH_ERROR){ + leave_function(); + return SSH_AUTH_ERROR; + } + if(!auth_status_termination(session)){ + leave_function(); + return SSH_AUTH_AGAIN; + } } switch(session->auth_state){ case SSH_AUTH_STATE_ERROR: @@ -349,6 +382,16 @@ int ssh_userauth_none(ssh_session session, const char *username) { leave_function(); return rc; } + switch(session->pending_call_state){ + case SSH_PENDING_CALL_NONE: + break; + case SSH_PENDING_CALL_AUTH_NONE: + goto pending; + default: + ssh_set_error(session,SSH_FATAL,"Bad call during pending SSH call in ssh_userauth_none"); + goto error; + rc=SSH_ERROR; + } if (ask_userauth(session) < 0) { ssh_string_free(user); @@ -376,12 +419,15 @@ int ssh_userauth_none(ssh_session session, const char *username) { ssh_string_free(method); ssh_string_free(user); session->auth_state=SSH_AUTH_STATE_NONE; + session->pending_call_state=SSH_PENDING_CALL_AUTH_NONE; if (packet_send(session) == SSH_ERROR) { leave_function(); return rc; } +pending: rc = wait_auth_status(session); - + if (rc != SSH_AUTH_AGAIN) + session->pending_call_state=SSH_PENDING_CALL_NONE; leave_function(); return rc; error: