Skip to content

Commit

Permalink
Merge pull request #695 from JacobBarthelmeh/541
Browse files Browse the repository at this point in the history
Server side auth pending support
  • Loading branch information
ejohnstown authored Jun 5, 2024
2 parents 2e0f509 + dc66602 commit 3024d28
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 26 deletions.
31 changes: 25 additions & 6 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,8 @@ static int NonBlockSSH_accept(WOLFSSH* ssh)

while ((ret != WS_SUCCESS
&& ret != WS_SCP_COMPLETE && ret != WS_SFTP_COMPLETE)
&& (error == WS_WANT_READ || error == WS_WANT_WRITE)) {
&& (error == WS_WANT_READ || error == WS_WANT_WRITE ||
error == WS_AUTH_PENDING)) {

if (error == WS_WANT_READ)
printf("... server would read block\n");
Expand All @@ -1410,7 +1411,8 @@ static int NonBlockSSH_accept(WOLFSSH* ssh)
select_ret = tcp_select(sockfd, 1);
if (select_ret == WS_SELECT_RECV_READY ||
select_ret == WS_SELECT_ERROR_READY ||
error == WS_WANT_WRITE)
error == WS_WANT_WRITE ||
error == WS_AUTH_PENDING)
{
ret = wolfSSH_accept(ssh);
error = wolfSSH_get_error(ssh);
Expand All @@ -1432,11 +1434,16 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs)

passwdRetry = MAX_PASSWD_RETRY;

if (!threadCtx->nonBlock)
if (!threadCtx->nonBlock) {
ret = wolfSSH_accept(threadCtx->ssh);
else
if (wolfSSH_get_error(threadCtx->ssh) == WS_AUTH_PENDING) {
printf("Auth pending error, use -N for non blocking\n");
printf("Trying to close down the connection\n");
}
}
else {
ret = NonBlockSSH_accept(threadCtx->ssh);

}
#ifdef WOLFSSH_SCP
/* finish off SCP operation */
if (ret == WS_SCP_INIT) {
Expand Down Expand Up @@ -2055,6 +2062,7 @@ static int wsUserAuthResult(byte res,
}


static int userAuthWouldBlock = 0;
static int wsUserAuth(byte authType,
WS_UserAuthData* authData,
void* ctx)
Expand All @@ -2068,6 +2076,12 @@ static int wsUserAuth(byte authType,
return WOLFSSH_USERAUTH_FAILURE;
}

if (userAuthWouldBlock > 0) {
printf("User Auth would block ....\n");
userAuthWouldBlock--;
return WOLFSSH_USERAUTH_WOULD_BLOCK;
}

if (authType != WOLFSSH_USERAUTH_PASSWORD &&
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
authType != WOLFSSH_USERAUTH_NONE &&
Expand Down Expand Up @@ -2284,6 +2298,7 @@ static void ShowUsage(void)
printf(" -a <file> load in a root CA certificate file\n");
#endif
printf(" -k set the list of key algos to use\n");
printf(" -b <num> test user auth would block\n");
}


Expand Down Expand Up @@ -2345,7 +2360,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
serverArgs->return_code = EXIT_SUCCESS;

if (argc > 0) {
const char* optlist = "?1a:d:efEp:R:Ni:j:I:J:K:P:k:";
const char* optlist = "?1a:d:efEp:R:Ni:j:I:J:K:P:k:b:";
myoptind = 0;
while ((ch = mygetopt(argc, argv, optlist)) != -1) {
switch (ch) {
Expand Down Expand Up @@ -2429,6 +2444,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
passwdList = StrListAdd(passwdList, myoptarg);
break;

case 'b':
userAuthWouldBlock = atoi(myoptarg);
break;

default:
ShowUsage();
serverArgs->return_code = MY_EX_USAGE;
Expand Down
56 changes: 40 additions & 16 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,9 @@ const char* GetErrorString(int err)
case WS_ED25519_E:
return "Ed25519 buffer error";

case WS_AUTH_PENDING:
return "userauth is still pending (callback would block)";

default:
return "Unknown error code";
}
Expand Down Expand Up @@ -6111,6 +6114,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);
Expand Down Expand Up @@ -6196,6 +6203,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;
Expand All @@ -6214,7 +6225,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;
}

Expand Down Expand Up @@ -7102,6 +7113,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:
Expand Down Expand Up @@ -7131,20 +7143,29 @@ 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,
"Unexpected return value from Auth callback");
}
#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");
Expand Down Expand Up @@ -8843,18 +8864,21 @@ static int DoPacket(WOLFSSH* ssh, byte* bufferConsumed)
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++;
*bufferConsumed = 1;
idx += padSz;
ssh->inputBuffer.idx = idx;
ssh->peerSeq++;
*bufferConsumed = 1;
}

return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,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) {
Expand Down
5 changes: 3 additions & 2 deletions wolfssh/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ enum WS_ErrorCodes {
WS_SFTP_NOT_FILE_E = -1093, /* Not a regular file */
WS_MSGID_NOT_ALLOWED_E = -1094, /* Message not allowed before userauth */
WS_ED25519_E = -1095, /* Ed25519 failure */

WS_LAST_E = -1095 /* Update this to indicate last error */
WS_AUTH_PENDING = -1096, /* User authentication still pending */

WS_LAST_E = -1096 /* Update this to indicate last error */
};


Expand Down
3 changes: 2 additions & 1 deletion wolfssh/ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ 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
};

enum WS_DisconnectReasonCodes {
Expand Down

0 comments on commit 3024d28

Please sign in to comment.