From 0ca42de3c492675b30becf21b6e8596738e20c0d Mon Sep 17 00:00:00 2001 From: Fabio <507164+falemagn@users.noreply.github.com> Date: Fri, 21 Jul 2023 09:22:55 +0200 Subject: [PATCH] Asynchronous user authentication. --- src/internal.c | 36 +++++++++++++++++++++++++++--------- src/ssh.c | 2 +- wolfssh/error.h | 3 ++- wolfssh/ssh.h | 3 ++- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index 54c969080..379870559 100644 --- a/src/internal.c +++ b/src/internal.c @@ -414,6 +414,9 @@ const char* GetErrorString(int err) case WS_MATCH_UA_KEY_ID_E: return "unable to match user auth key type"; + + case WS_AUTH_PENDING: + return "userauth is still pending (callback would block)"; default: return "Unknown error code"; @@ -4947,6 +4950,10 @@ static int DoUserAuthRequestNone(WOLFSSH* ssh, WS_UserAuthData* authData, ret = WS_USER_AUTH_E; #endif } + else if (ret == WOLFSSH_USERAUTH_WOULD_BLOCK) { + WLOG(WS_LOG_DEBUG, "DUARN: userauth callback would block"); + ret = WS_AUTH_PENDING; + } else { WLOG(WS_LOG_DEBUG, "DUARN: none check failed, retry"); ret = SendUserAuthFailure(ssh, 0); @@ -5029,6 +5036,10 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, ret = WS_USER_AUTH_E; #endif } + else if (ret == WOLFSSH_USERAUTH_WOULD_BLOCK) { + WLOG(WS_LOG_DEBUG, "DUARPW: userauth callback would block"); + ret = WS_AUTH_PENDING; + } else { WLOG(WS_LOG_DEBUG, "DUARPW: password check failed, retry"); ret = SendUserAuthFailure(ssh, 0); @@ -5842,6 +5853,10 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, authFailure = 1; ret = WS_SUCCESS; } + else if (ret == WOLFSSH_USERAUTH_WOULD_BLOCK) { + WLOG(WS_LOG_DEBUG, "DUARPK: userauth callback would block"); + ret = WS_AUTH_PENDING; + } else { authFailure = 1; } @@ -7178,17 +7193,20 @@ static int DoPacket(WOLFSSH* ssh) ret = SendUnimplemented(ssh); } - if (payloadSz > 0) { - idx += payloadIdx; - if (idx + padSz > len) { - WLOG(WS_LOG_DEBUG, "Not enough data in buffer for pad."); - ret = WS_BUFFER_E; + /* if the auth is still pending, don't discard the packet data */ + if (ret != WS_AUTH_PENDING) { + if (payloadSz > 0) { + idx += payloadIdx; + if (idx + padSz > len) { + WLOG(WS_LOG_DEBUG, "Not enough data in buffer for pad."); + ret = WS_BUFFER_E; + } } - } - idx += padSz; - ssh->inputBuffer.idx = idx; - ssh->peerSeq++; + idx += padSz; + ssh->inputBuffer.idx = idx; + ssh->peerSeq++; + } return ret; } diff --git a/src/ssh.c b/src/ssh.c index 2db5e340c..365a83c4c 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -400,7 +400,7 @@ int wolfSSH_accept(WOLFSSH* ssh) return WS_BAD_ARGUMENT; /* clear want read/writes for retry */ - if (ssh->error == WS_WANT_READ || ssh->error == WS_WANT_WRITE) + if (ssh->error == WS_WANT_READ || ssh->error == WS_WANT_WRITE || ssh->error == WS_AUTH_PENDING) ssh->error = 0; if (ssh->error != 0) { diff --git a/wolfssh/error.h b/wolfssh/error.h index d964b7ac3..092844d30 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -128,8 +128,9 @@ enum WS_ErrorCodes { WS_CERT_KEY_SIZE_E = -1087, /* Key size error */ WS_CTX_KEY_COUNT_E = -1088, /* Adding too many private keys */ WS_MATCH_UA_KEY_ID_E = -1089, /* Match user auth key key fail */ + WS_AUTH_PENDING = -1090, /* User authentication still pending */ - WS_LAST_E = -1089 /* Update this to indicate last error */ + WS_LAST_E = -1090 /* Update this to indicate last error */ }; diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index a42004b37..fa6b1df76 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -317,7 +317,8 @@ enum WS_UserAuthResults WOLFSSH_USERAUTH_INVALID_USER, WOLFSSH_USERAUTH_INVALID_PASSWORD, WOLFSSH_USERAUTH_REJECTED, - WOLFSSH_USERAUTH_INVALID_PUBLICKEY + WOLFSSH_USERAUTH_INVALID_PUBLICKEY, + WOLFSSH_USERAUTH_WOULD_BLOCK }; enum WS_DisconnectReasonCodes {