From 2be9edb363a39efd2838d6963ec3edc5afd0795f 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 1/3] Asynchronous user authentication. --- src/internal.c | 52 ++++++++++++++++++++++++++++++++++++------------- src/ssh.c | 2 +- wolfssh/error.h | 3 ++- wolfssh/ssh.h | 1 + 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/internal.c b/src/internal.c index 2b722f7d8..f8849e867 100644 --- a/src/internal.c +++ b/src/internal.c @@ -430,6 +430,9 @@ const char* GetErrorString(int err) case WS_KEY_FORMAT_E: return "key format wrong error"; + case WS_AUTH_PENDING: + return "userauth is still pending (callback would block)"; + default: return "Unknown error code"; } @@ -5344,6 +5347,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); @@ -5429,6 +5436,10 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, #endif ret = WS_USER_AUTH_E; } + 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"); authFailure = 1; @@ -6241,6 +6252,7 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PUBLICKEY, authData, ssh->userAuthCtx); WLOG(WS_LOG_DEBUG, "DUARPK: callback result = %d", ret); + #ifdef DEBUG_WOLFSSH switch (ret) { case WOLFSSH_USERAUTH_SUCCESS: @@ -6270,6 +6282,10 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, case WOLFSSH_USERAUTH_PARTIAL_SUCCESS: WLOG(WS_LOG_DEBUG, "DUARPK: user auth partial success"); break; + + case WOLFSSH_USERAUTH_WOULD_BLOCK: + WLOG(WS_LOG_DEBUG, "DUARPK: userauth callback would block"); + break; default: WLOG(WS_LOG_DEBUG, @@ -6277,13 +6293,18 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, } #endif - if (ret == WOLFSSH_USERAUTH_PARTIAL_SUCCESS) { - partialSuccess = 1; + if (ret == WOLFSSH_USERAUTH_WOULD_BLOCK) { + ret = WS_AUTH_PENDING; } - else if (ret != WOLFSSH_USERAUTH_SUCCESS) { - authFailure = 1; + else { + if (ret == WOLFSSH_USERAUTH_PARTIAL_SUCCESS) { + partialSuccess = 1; + } + else if (ret != WOLFSSH_USERAUTH_SUCCESS) { + authFailure = 1; + } + ret = WS_SUCCESS; } - ret = WS_SUCCESS; } else { WLOG(WS_LOG_DEBUG, "DUARPK: no userauth callback set"); @@ -7685,17 +7706,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 4e3758d72..f572143a4 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -408,7 +408,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 598ec1a48..6fdf72cb6 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -131,8 +131,9 @@ enum WS_ErrorCodes { WS_KEY_AUTH_MAGIC_E = -1090, /* OpenSSH key auth magic check fail */ WS_KEY_CHECK_VAL_E = -1091, /* OpenSSH key check value fail */ WS_KEY_FORMAT_E = -1092, /* OpenSSH key format fail */ + WS_AUTH_PENDING = -1093, /* User authentication still pending */ - WS_LAST_E = -1092 /* Update this to indicate last error */ + WS_LAST_E = -1093 /* Update this to indicate last error */ }; diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index ab315daad..4a9f61ba8 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -330,6 +330,7 @@ enum WS_UserAuthResults WOLFSSH_USERAUTH_REJECTED, WOLFSSH_USERAUTH_INVALID_PUBLICKEY, WOLFSSH_USERAUTH_PARTIAL_SUCCESS + WOLFSSH_USERAUTH_WOULD_BLOCK }; enum WS_DisconnectReasonCodes { From ece378f38e06b45def1b0679c8161cc9f8e8bc8f Mon Sep 17 00:00:00 2001 From: Fabio <507164+falemagn@users.noreply.github.com> Date: Fri, 20 Oct 2023 09:35:49 +0200 Subject: [PATCH 2/3] Added missing comma. --- wolfssh/ssh.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index 4a9f61ba8..abe3d6931 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -329,7 +329,7 @@ enum WS_UserAuthResults WOLFSSH_USERAUTH_INVALID_PASSWORD, WOLFSSH_USERAUTH_REJECTED, WOLFSSH_USERAUTH_INVALID_PUBLICKEY, - WOLFSSH_USERAUTH_PARTIAL_SUCCESS + WOLFSSH_USERAUTH_PARTIAL_SUCCESS, WOLFSSH_USERAUTH_WOULD_BLOCK }; From 6695a0b36814e39dd882fee882784f4a4e702f2e Mon Sep 17 00:00:00 2001 From: Fabio <507164+falemagn@users.noreply.github.com> Date: Fri, 17 Nov 2023 20:00:20 +0100 Subject: [PATCH 3/3] In DoUserAuthRequestPassword() do not set ssh->clientState to CLIENT_USERAUTH_DONE if ret is not WS_SUCCESS. --- src/internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index f8849e867..775dbe517 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5458,7 +5458,7 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, if (authFailure || partialSuccess) { ret = SendUserAuthFailure(ssh, partialSuccess); } - else { + else if (ret == WS_SUCCESS) { ssh->clientState = CLIENT_USERAUTH_DONE; }