From 791b54d9a3f3b3217f6c520e97720a66f0d745ae Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 9 Apr 2024 10:15:34 -0700 Subject: [PATCH] Changing Channels 1. Allow some of the shell code in the echoserver for handling echo. 2. Add check for echo to the shell start cb to skip forking a child process to handle the shell. 3. Always all the echo test in the testsuite. 4. Check a return value on execv of the shell in the echoserver. 5. Whitespace. --- examples/echoserver/echoserver.c | 63 +++++++++++++++++--------------- tests/testsuite.c | 5 --- wolfssh/error.h | 2 +- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index e56de8c44..5574d5d71 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -176,13 +176,11 @@ typedef struct WS_FwdCbActionCtx { #endif -#ifdef WOLFSSH_SHELL typedef struct WS_ShellCtx { int isConnected; WS_SOCKET_T childFd; word32 channelId; } WS_ShellCtx; -#endif typedef struct { @@ -202,10 +200,8 @@ typedef struct { WS_FwdCbActionCtx fwdCbCtx; byte fwdBuffer[EXAMPLE_BUFFER_SZ]; #endif -#ifdef WOLFSSH_SHELL WS_ShellCtx shellCtx; byte shellBuffer[EXAMPLE_BUFFER_SZ]; -#endif #ifdef WOLFSSH_SFTP int doSftp; #endif @@ -217,8 +213,6 @@ typedef struct { } thread_ctx_t; -#ifdef WOLFSSH_SHELL - static byte find_char(const byte* str, const byte* buf, word32 bufSz) { const byte* cur; @@ -281,8 +275,6 @@ static int process_bytes(thread_ctx_t* threadCtx, return stop; } -#endif /* WOLFSSH_SHELL */ - #if defined(WOLFSSL_PTHREADS) && defined(WOLFSSL_TEST_GLOBAL_REQ) @@ -595,23 +587,33 @@ static int termios_show(int fd) } return 0; } -#endif +#endif /* SHELL_DEBUG */ +#endif /* WOLFSSH_SHELL */ static int wsShellStartCb(WOLFSSH_CHANNEL* channel, void* ctx) { if (ctx != NULL) { thread_ctx_t* threadCtx; +#ifdef WOLFSSH_SHELL WOLFSSH* ssh; const char *userName; struct passwd *p_passwd; struct termios tios; pid_t childPid; int rc; +#endif /* WOLFSSH_SHELL */ threadCtx = (thread_ctx_t*)ctx; - ssh = threadCtx->ssh; threadCtx->shellCtx.isConnected = 1; + if (threadCtx->echo) { + /* Running as the echoserver. Don't check the user with + * the system. One of the canned users is OK here. */ + return 0; + } + +#ifdef WOLFSSH_SHELL + ssh = threadCtx->ssh; wolfSSH_ChannelGetId(channel, &threadCtx->shellCtx.channelId, WS_CHANNEL_ID_PEER); userName = wolfSSH_GetUsername(ssh); @@ -650,6 +652,10 @@ static int wsShellStartCb(WOLFSSH_CHANNEL* channel, void* ctx) } rc = execv("/bin/sh", (char **)args); + if (rc < 0) { + printf("execv failed: rc =%d,errno=%x\n", rc, errno); + return WS_FATAL_ERROR; + } } #ifdef SHELL_DEBUG printf("In childPid > 0; getpid=%d\n", (int)getpid()); @@ -687,11 +693,13 @@ static int wsShellStartCb(WOLFSSH_CHANNEL* channel, void* ctx) #endif /* HAVE_SYS_IOCTL_H */ wolfSSH_SetTerminalResizeCtx(ssh, (void*)&threadCtx->shellCtx.childFd); +#else /* WOLFSSH_SHELL */ + (void)channel; +#endif /* WOLFSSH_SHELL */ } return 0; } -#endif /* WOLFSSH_SHELL */ #ifdef WOLFSSH_SCP @@ -826,23 +834,18 @@ static int ssh_worker(thread_ctx_t* threadCtx) while (ChildRunning) { fd_set readFds, exFds; WS_SOCKET_T maxFd; - int cnt_r; -#if defined(WOLFSSH_SHELL) || defined(WOLFSSH_AGENT) || defined(WOLFSSH_FWD) - int cnt_w; -#endif + int cnt_r, cnt_w = 0; FD_ZERO(&readFds); FD_ZERO(&exFds); FD_SET(sshFd, &readFds); maxFd = sshFd; - #ifdef WOLFSSH_SHELL if (threadCtx->shellCtx.isConnected) { FD_SET(threadCtx->shellCtx.childFd, &readFds); if (threadCtx->shellCtx.childFd > maxFd) maxFd = threadCtx->shellCtx.childFd; } - #endif /* WOLFSSH_SHELL */ #ifdef WOLFSSH_AGENT if (threadCtx->agentCbCtx.state == AGENT_STATE_LISTEN) { FD_SET(agentListenFd, &readFds); @@ -902,7 +905,6 @@ static int ssh_worker(thread_ctx_t* threadCtx) if (cnt_r < 0) { rc = wolfSSH_get_error(ssh); if (rc == WS_CHAN_RXD) { - #ifdef WOLFSSH_SHELL if (threadCtx->shellCtx.isConnected && lastChannel == threadCtx->shellCtx.channelId) { cnt_r = wolfSSH_ChannelIdRead(ssh, @@ -914,11 +916,7 @@ static int ssh_worker(thread_ctx_t* threadCtx) #ifdef SHELL_DEBUG buf_dump(threadCtx->channelBuffer, cnt_r); #endif - if (!threadCtx->echo) { - cnt_w = (int)write(threadCtx->shellCtx.childFd, - threadCtx->channelBuffer, cnt_r); - } - else { + if (threadCtx->echo) { cnt_w = wolfSSH_ChannelIdSend(ssh, threadCtx->shellCtx.channelId, threadCtx->channelBuffer, cnt_r); @@ -929,10 +927,15 @@ static int ssh_worker(thread_ctx_t* threadCtx) ChildRunning = !doStop; } } + #ifdef WOLFSSH_SHELL + else { + cnt_w = (int)write(threadCtx->shellCtx.childFd, + threadCtx->channelBuffer, cnt_r); + } + #endif /* WOLFSSH_SHELL */ if (cnt_w <= 0) break; } - #endif /* WOLFSSH_SHELL */ #ifdef WOLFSSH_AGENT if (lastChannel == agentChannelId) { cnt_r = wolfSSH_ChannelIdRead(ssh, agentChannelId, @@ -1018,7 +1021,7 @@ static int ssh_worker(thread_ctx_t* threadCtx) } } #ifdef WOLFSSH_SHELL - if (threadCtx->shellCtx.isConnected) { + if (threadCtx->shellCtx.isConnected && !threadCtx->echo) { if (FD_ISSET(threadCtx->shellCtx.childFd, &readFds)) { cnt_r = (int)read(threadCtx->shellCtx.childFd, threadCtx->shellBuffer, @@ -2346,6 +2349,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) char** argv = serverArgs->argv; serverArgs->return_code = EXIT_SUCCESS; +#ifndef WOLFSSH_SHELL + echo = 1; +#endif + if (argc > 0) { const char* optlist = "?1a:d:efEp:R:Ni:j:I:J:K:P:k:"; myoptind = 0; @@ -2378,9 +2385,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) break; case 'f': - #ifdef WOLFSSH_SHELL - echo = 1; - #endif + echo = 1; break; case 'p': @@ -2481,9 +2486,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth); wolfSSH_SetUserAuthResult(ctx, wsUserAuthResult); wolfSSH_CTX_SetBanner(ctx, echoserverBanner); -#ifdef WOLFSSH_SHELL wolfSSH_CTX_SetChannelReqShellCb(ctx, wsShellStartCb); -#endif #ifdef WOLFSSH_AGENT wolfSSH_CTX_set_agent_cb(ctx, wolfSSH_AGENT_DefaultActions, NULL); #endif diff --git a/tests/testsuite.c b/tests/testsuite.c index f8f36b5c1..fa5e4073c 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -68,8 +68,6 @@ 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"; @@ -149,7 +147,6 @@ static void wolfSSH_EchoTest(void) FreeTcpReady(&ready); } -#endif /* WOLFSSH_SHELL */ int wolfSSH_TestsuiteTest(int argc, char** argv) @@ -178,9 +175,7 @@ int wolfSSH_TestsuiteTest(int argc, char** argv) ChangeToWolfSshRoot(); #endif -#ifdef WOLFSSH_SHELL wolfSSH_EchoTest(); -#endif wolfSSH_Cleanup(); diff --git a/wolfssh/error.h b/wolfssh/error.h index 3749a55b5..c2d9fd43b 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -133,7 +133,7 @@ enum WS_ErrorCodes { WS_KEY_FORMAT_E = -1092, /* OpenSSH key format fail */ WS_SFTP_NOT_FILE_E = -1093, /* Not a regular file */ WS_MSGID_NOT_ALLOWED_E = -1094, /* Message not allowed before userauth */ - + WS_LAST_E = -1094 /* Update this to indicate last error */ };