From fda22526e2f492815f2cc4a539a785a5f884aac6 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 31 Oct 2023 14:42:09 -0600 Subject: [PATCH] add linux server side sending of exit-status --- apps/wolfsshd/wolfsshd.c | 12 ++++++++- src/internal.c | 58 ++++++++++++++++++++++++++++++++++++++++ src/ssh.c | 15 +++++++++++ wolfssh/internal.h | 2 ++ wolfssh/ssh.h | 1 + 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index b8b3673f..55184621 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -1308,7 +1308,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue opening shell"); exit(1); } - exit(0); /* exit child process and close down SSH connection */ + exit(ret); /* exit child process and close down SSH connection */ } /* do not wait for status of child process, and signal that the child can @@ -1454,6 +1454,16 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, } } + /* get return value of child process */ + { + int waitStatus; + waitpid(-1, &waitStatus, WNOHANG); + if (wolfSSH_SendExitStatus(ssh, (word32)WEXITSTATUS(waitStatus)) != + WS_SUCCESS) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue sending childs exit " + "status"); + } + } (void)conn; return WS_SUCCESS; } diff --git a/src/internal.c b/src/internal.c index 4e69277f..ba11fc25 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14034,6 +14034,64 @@ int SendChannelSuccess(WOLFSSH* ssh, word32 channelId, int success) } +/* Sends out the channel exit-status msg + * returns WS_SUCCESS on success */ +int SendChannelExitStatus(WOLFSSH* ssh, word32 channelId, word32 exitStatus) +{ + byte* output; + word32 idx; + int ret = WS_SUCCESS; + WOLFSSH_CHANNEL* channel = NULL; + const char cType[] = "exit-status"; + int typeSz; + + WLOG(WS_LOG_DEBUG, "Entering SendChannelExitStatus()"); + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + channel = ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF); + if (channel == NULL) { + WLOG(WS_LOG_DEBUG, "Invalid channel"); + ret = WS_INVALID_CHANID; + } + } + + if (ret == WS_SUCCESS) { + typeSz = (word32)WSTRLEN(cType); + ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + LENGTH_SZ + + typeSz + BOOLEAN_SZ + UINT32_SZ); + } + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_CHANNEL_REQUEST; + c32toa(channel->peerChannel, output + idx); + idx += UINT32_SZ; + + c32toa(typeSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, cType, typeSz); + idx += typeSz; + output[idx++] = 0; /* boolean of want reply is always false */ + c32toa(exitStatus, output + idx); + idx += UINT32_SZ; + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = wolfSSH_SendPacket(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendChannelExitStatus(), ret = %d", ret); + return ret; +} + + #if (defined(WOLFSSH_SFTP) || defined(WOLFSSH_SCP)) && \ !defined(NO_WOLFSSH_SERVER) /* cleans up absolute path diff --git a/src/ssh.c b/src/ssh.c index de760c02..a7e8e968 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -1375,6 +1375,21 @@ int wolfSSH_GetExitStatus(WOLFSSH* ssh) } return ssh->exitStatus; } + + +/* Sends the commands exit status to the peer + * returns WS_SUCCESS on success */ +int wolfSSH_SendExitStatus(WOLFSSH* ssh, word32 exitStatus) +{ + if (ssh == NULL) { + WLOG(WS_LOG_DEBUG, "wolfSSH_SendExitStatus WOLFSSH struct was NULL"); + return WS_BAD_ARGUMENT; + } + WLOG(WS_LOG_DEBUG, "wolfSSH_SendExitStatus sending exit status %u", + exitStatus); + + return SendChannelExitStatus(ssh, ssh->defaultPeerChannelId, exitStatus); +} #endif diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 054c1e19..fe435b33 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -956,6 +956,8 @@ WOLFSSH_LOCAL int SendChannelTerminalResize(WOLFSSH*, word32, word32, word32, WOLFSSH_LOCAL int SendChannelTerminalRequest(WOLFSSH* ssh); WOLFSSH_LOCAL int SendChannelAgentRequest(WOLFSSH* ssh); WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, word32, int); +WOLFSSH_LOCAL int SendChannelExitStatus(WOLFSSH* ssh, word32 channelId, + word32 exitStatus); WOLFSSH_LOCAL int GenerateKey(byte, byte, byte*, word32, const byte*, word32, const byte*, word32, const byte*, word32, byte doKeyPad); diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index 6e57aa67..63c16574 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -294,6 +294,7 @@ WOLFSSH_API void wolfSSH_SetTerminalResizeCb(WOLFSSH* ssh, WS_CallbackTerminalSize cb); WOLFSSH_API void wolfSSH_SetTerminalResizeCtx(WOLFSSH* ssh, void* usrCtx); WOLFSSH_API int wolfSSH_GetExitStatus(WOLFSSH* ssh); +WOLFSSH_API int wolfSSH_SendExitStatus(WOLFSSH* ssh, word32 exitStatus); enum WS_HighwaterSide {