Skip to content

Commit

Permalink
Refactoring Channels
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ejohnstown committed Nov 4, 2024
1 parent 9746fa3 commit 68b4bdf
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 94 deletions.
55 changes: 45 additions & 10 deletions examples/echoserver/echoserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
52 changes: 0 additions & 52 deletions src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 2 additions & 1 deletion src/wolfscp.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ int DoScpSource(WOLFSSH* ssh)
return ret;
}

int DoScpRequest(WOLFSSH* ssh)
int wolfSSH_SCP_DoRequest(WOLFSSH* ssh)
{
int ret = WS_SUCCESS;

Expand Down Expand Up @@ -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;
Expand Down
68 changes: 38 additions & 30 deletions tests/testsuite.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -163,18 +141,49 @@ 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 */
k_sleep(Z_TIMEOUT_TICKS(100));
#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");
Expand All @@ -184,7 +193,6 @@ int wolfSSH_TestsuiteTest(int argc, char** argv)
wolfSSH_SftpTest(1);
#endif
#endif

return EXIT_SUCCESS;
}

Expand Down
1 change: 0 additions & 1 deletion wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down
1 change: 1 addition & 0 deletions wolfssh/wolfscp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 68b4bdf

Please sign in to comment.