From 68b4bdfcd27cfa6f8a6d001a4a13f39e50c00c1f Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 14 Mar 2024 13:13:13 -0700 Subject: [PATCH] Refactoring Channels 1. Modify the testsuite to leave out the echo test if the shell build is disabled. The testsuite hangs because the shell code is missing. 2. Modify the echoserver's call to wolfSSH_SFTP_accept() to handle non-blocking better. Needs to check for want_read. --- examples/echoserver/echoserver.c | 55 +++++++++++++++++++++----- src/ssh.c | 52 ------------------------ src/wolfscp.c | 3 +- tests/testsuite.c | 68 ++++++++++++++++++-------------- wolfssh/internal.h | 1 - wolfssh/wolfscp.h | 1 + 6 files changed, 86 insertions(+), 94 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 87262632a..bcb51d3c3 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -208,6 +208,9 @@ typedef struct { #endif #ifdef WOLFSSH_SFTP int doSftp; +#endif +#ifdef WOLFSSH_SCP + int doScp; #endif byte channelBuffer[EXAMPLE_BUFFER_SZ]; char statsBuffer[EXAMPLE_BUFFER_SZ]; @@ -736,6 +739,28 @@ static int wsShellStartCb(WOLFSSH_CHANNEL* channel, void* ctx) #endif /* WOLFSSH_SHELL */ +#ifdef WOLFSSH_SCP +static int wsExecStartCb(WOLFSSH_CHANNEL* channel, void* vCtx) +{ + thread_ctx_t* threadCtx; + const char* cmd; + WS_SessionType type; + + if (!vCtx || !channel) { + return 0; + } + + threadCtx = (thread_ctx_t*)vCtx; + cmd = wolfSSH_ChannelGetSessionCommand(channel); + type = wolfSSH_ChannelGetSessionType(channel); + + threadCtx->doScp = (type == WOLFSSH_SESSION_EXEC && WSTRSTR(cmd, "scp")); + + return 0; +} +#endif /* WOLFSSH_SCP */ + + #ifdef WOLFSSH_SFTP static int wsSubsysStartCb(WOLFSSH_CHANNEL* channel, void* vCtx) { @@ -751,10 +776,8 @@ static int wsSubsysStartCb(WOLFSSH_CHANNEL* channel, void* vCtx) cmd = wolfSSH_ChannelGetSessionCommand(channel); type = wolfSSH_ChannelGetSessionType(channel); - if (type == WOLFSSH_SESSION_SUBSYSTEM - && WSTRCMP(cmd, "sftp") == 0) { - threadCtx->doSftp = 1; - } + threadCtx->doSftp = (type == WOLFSSH_SESSION_SUBSYSTEM + && !WSTRCMP(cmd, "sftp")); return 0; } @@ -992,6 +1015,11 @@ static int ssh_worker(thread_ctx_t* threadCtx) channel. The additional channel is only used with the agent. */ cnt_r = wolfSSH_worker(ssh, &lastChannel); + #ifdef WOLFSSH_SCP + if (threadCtx->doScp) { + return WS_SCP_INIT; + } + #endif #ifdef WOLFSSH_SFTP if (threadCtx->doSftp) { return WS_SFTP_COMPLETE; @@ -1556,16 +1584,20 @@ static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs) #endif switch (ret) { - case WS_SCP_COMPLETE: - printf("scp file transfer completed\n"); - ret = 0; - break; - case WS_SUCCESS: ret = ssh_worker(threadCtx); + #ifdef WOLFSSH_SCP + if (ret == WS_SCP_INIT) { + ret = wolfSSH_SCP_DoRequest(threadCtx->ssh); + } + #endif #ifdef WOLFSSH_SFTP if (ret == WS_SFTP_COMPLETE) { - ret = wolfSSH_SFTP_accept(threadCtx->ssh); + do { + ret = wolfSSH_SFTP_accept(threadCtx->ssh); + error = wolfSSH_get_error(threadCtx->ssh); + } while (ret != WS_SFTP_COMPLETE + && (error == WS_WANT_READ || error == WS_WANT_WRITE)); } if (ret == WS_SFTP_COMPLETE) { ret = sftp_worker(threadCtx); @@ -2624,6 +2656,9 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) #ifdef WOLFSSH_FWD wolfSSH_CTX_SetFwdCb(ctx, wolfSSH_FwdDefaultActions, NULL); #endif +#ifdef WOLFSSH_SCP + wolfSSH_CTX_SetChannelReqExecCb(ctx, wsExecStartCb); +#endif #ifdef WOLFSSH_SFTP wolfSSH_CTX_SetChannelReqSubsysCb(ctx, wsSubsysStartCb); #endif diff --git a/src/ssh.c b/src/ssh.c index 94fec225e..dc7644208 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -546,45 +546,6 @@ int wolfSSH_accept(WOLFSSH* ssh) ssh->acceptState = ACCEPT_SERVER_USERAUTH_SENT; WLOG(WS_LOG_DEBUG, acceptState, "SERVER_USERAUTH_SENT"); #if 0 - case ACCEPT_SERVER_USERAUTH_SENT: - while (ssh->clientState < CLIENT_CHANNEL_OPEN_DONE) { - if (DoReceive(ssh) < 0) { - WLOG(WS_LOG_DEBUG, acceptError, - "SERVER_USERAUTH_SENT", ssh->error); - return WS_FATAL_ERROR; - } - } - ssh->acceptState = ACCEPT_SERVER_CHANNEL_ACCEPT_SENT; - WLOG(WS_LOG_DEBUG, acceptState, "SERVER_CHANNEL_ACCEPT_SENT"); - NO_BREAK; - - case ACCEPT_SERVER_CHANNEL_ACCEPT_SENT: - while (ssh->clientState < CLIENT_DONE) { - if (DoReceive(ssh) < 0) { - WLOG(WS_LOG_DEBUG, acceptError, - "SERVER_CHANNEL_ACCEPT_SENT", ssh->error); - return WS_FATAL_ERROR; - } - } - -#ifdef WOLFSSH_SCP - if (ChannelCommandIsScp(ssh)) { - ssh->acceptState = ACCEPT_INIT_SCP_TRANSFER; - WLOG(WS_LOG_DEBUG, acceptState, "ACCEPT_INIT_SCP_TRANSFER"); - return WS_SCP_INIT; - } -#endif -#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_SERVER) - { - const char* cmd = wolfSSH_GetSessionCommand(ssh); - if (cmd != NULL && - WOLFSSH_SESSION_SUBSYSTEM == wolfSSH_GetSessionType(ssh) - && (WSTRNCMP(cmd, "sftp", 4) == 0)) { - ssh->acceptState = ACCEPT_INIT_SFTP; - return wolfSSH_SFTP_accept(ssh); - } - } -#endif /* WOLFSSH_SFTP and !NO_WOLFSSH_SERVER */ #ifdef WOLFSSH_AGENT if (ssh->useAgent) { WOLFSSH_AGENT_CTX* newAgent; @@ -639,19 +600,6 @@ int wolfSSH_accept(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_SESSION_ESTABLISHED"); break; -#ifdef WOLFSSH_SCP - case ACCEPT_INIT_SCP_TRANSFER: - if (DoScpRequest(ssh) < 0) { - WLOG(WS_LOG_DEBUG, acceptError, "INIT_SCP_TRANSFER", - ssh->error); - return WS_FATAL_ERROR; - } - return WS_SCP_COMPLETE; -#endif -#ifdef WOLFSSH_SFTP - case ACCEPT_INIT_SFTP: - return wolfSSH_SFTP_accept(ssh); -#endif #endif /* 0 */ } } /* end while */ diff --git a/src/wolfscp.c b/src/wolfscp.c index 1be04b2af..7c27bc44c 100644 --- a/src/wolfscp.c +++ b/src/wolfscp.c @@ -664,7 +664,7 @@ int DoScpSource(WOLFSSH* ssh) return ret; } -int DoScpRequest(WOLFSSH* ssh) +int wolfSSH_SCP_DoRequest(WOLFSSH* ssh) { int ret = WS_SUCCESS; @@ -789,6 +789,7 @@ WOLFSSH_API int wolfSSH_SetScpErrorMsg(WOLFSSH* ssh, const char* message) /* Determine if channel command sent in initial negotiation is scp. * Return 1 if yes, 0 if no */ +/* XXX Obsolete. Remove. */ int ChannelCommandIsScp(WOLFSSH* ssh) { const char* cmd; diff --git a/tests/testsuite.c b/tests/testsuite.c index 6ab4a8507..845f67dfe 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -69,6 +69,8 @@ char* myoptarg = NULL; #if !defined(NO_WOLFSSH_SERVER) && !defined(NO_WOLFSSH_CLIENT) && \ !defined(SINGLE_THREADED) && !defined(WOLFSSH_TEST_BLOCK) +#ifdef WOLFSSH_SHELL + static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) { static char password[] = "upthehill"; @@ -91,7 +93,7 @@ static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) #define NUMARGS 5 #define ARGLEN 32 -int wolfSSH_TestsuiteTest(int argc, char** argv) +static void wolfSSH_EchoTest(void) { tcp_ready ready; THREAD_TYPE serverThread; @@ -106,30 +108,6 @@ int wolfSSH_TestsuiteTest(int argc, char** argv) int serverArgc = 0; int clientArgc = 0; - (void)argc; - (void)argv; - - WSTARTTCP(); - - #if defined(DEBUG_WOLFSSH) - wolfSSH_Debugging_ON(); - #endif - - wolfSSH_Init(); - - #if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2) - { - int i; - for (i = 0; i < FIPS_CAST_COUNT; i++) { - wc_RunCast_fips(i); - } - } - #endif /* HAVE_FIPS */ - - #if !defined(WOLFSSL_TIRTOS) - ChangeToWolfSshRoot(); - #endif - InitTcpReady(&ready); WSTRNCPY(serverArgv[serverArgc++], "echoserver", ARGLEN); @@ -163,9 +141,6 @@ int wolfSSH_TestsuiteTest(int argc, char** argv) clientArgs.user_auth = tsClientUserAuth; client_test(&clientArgs); - if (clientArgs.return_code != 0) { - return clientArgs.return_code; - } #ifdef WOLFSSH_ZEPHYR /* Weird deadlock without this sleep */ @@ -173,8 +148,42 @@ int wolfSSH_TestsuiteTest(int argc, char** argv) #endif ThreadJoin(serverThread); - wolfSSH_Cleanup(); FreeTcpReady(&ready); +} +#endif /* WOLFSSH_SHELL */ + + +int wolfSSH_TestsuiteTest(int argc, char** argv) +{ + (void)argc; + (void)argv; + + WSTARTTCP(); + + #if defined(DEBUG_WOLFSSH) + wolfSSH_Debugging_ON(); + #endif + + wolfSSH_Init(); + + #if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2) + { + int i; + for (i = 0; i < FIPS_CAST_COUNT; i++) { + wc_RunCast_fips(i); + } + } + #endif /* HAVE_FIPS */ + + #if !defined(WOLFSSL_TIRTOS) + ChangeToWolfSshRoot(); + #endif + +#ifdef WOLFSSH_SHELL + wolfSSH_EchoTest(); +#endif + + wolfSSH_Cleanup(); #ifdef WOLFSSH_SFTP printf("testing SFTP blocking\n"); @@ -184,7 +193,6 @@ int wolfSSH_TestsuiteTest(int argc, char** argv) wolfSSH_SftpTest(1); #endif #endif - return EXIT_SUCCESS; } diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 731a9688d..0cd1f0268 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -1263,7 +1263,6 @@ enum WS_ScpDirection { }; WOLFSSH_LOCAL int ChannelCommandIsScp(WOLFSSH*); -WOLFSSH_LOCAL int DoScpRequest(WOLFSSH*); WOLFSSH_LOCAL int DoScpSink(WOLFSSH* ssh); WOLFSSH_LOCAL int DoScpSource(WOLFSSH* ssh); WOLFSSH_LOCAL int ParseScpCommand(WOLFSSH*); diff --git a/wolfssh/wolfscp.h b/wolfssh/wolfscp.h index eba468dc2..87ca7eae1 100644 --- a/wolfssh/wolfscp.h +++ b/wolfssh/wolfscp.h @@ -137,6 +137,7 @@ WOLFSSH_API int wolfSSH_SetScpErrorMsg(WOLFSSH*, const char*); WOLFSSH_API int wolfSSH_SCP_connect(WOLFSSH*, byte*); WOLFSSH_API int wolfSSH_SCP_to(WOLFSSH*, const char*, const char*); WOLFSSH_API int wolfSSH_SCP_from(WOLFSSH*, const char*, const char*); +WOLFSSH_API int wolfSSH_SCP_DoRequest(WOLFSSH* ssh); #ifdef __cplusplus