adjust shutdown for sending exit status cleanly

pull/614/head
JacobBarthelmeh 2023-11-05 15:58:01 -08:00
parent f41e706825
commit 0d480fa419
5 changed files with 48 additions and 80 deletions

View File

@ -1140,7 +1140,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
HeapFree(GetProcessHeap(), 0, ext.lpAttributeList);
}
if (wolfSSH_SendExitStatus(ssh, processState) !=
if (wolfSSH_SetExitStatus(ssh, processState) !=
WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue sending childs exit "
"status");
@ -1464,7 +1464,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
{
int waitStatus;
waitpid(-1, &waitStatus, WNOHANG);
if (wolfSSH_SendExitStatus(ssh, (word32)WEXITSTATUS(waitStatus)) !=
if (wolfSSH_SetExitStatus(ssh, (word32)WEXITSTATUS(waitStatus)) !=
WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue sending childs exit "
"status");
@ -1722,9 +1722,12 @@ static void* HandleConnection(void* arg)
break;
}
if (error != WS_WANT_READ && error != WS_WANT_WRITE) {
if (ret == WS_FATAL_ERROR &&
(error != WS_WANT_READ &&
error != WS_WANT_WRITE)) {
break;
}
usleep(1);
}
if (attempt == maxAttempt) {
@ -1734,6 +1737,7 @@ static void* HandleConnection(void* arg)
}
}
/* check if there is a response to the shutdown */
wolfSSH_free(ssh);
if (conn != NULL) {
WCLOSESOCKET(conn->fd);

View File

@ -982,7 +982,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
err_sys("Sending the shutdown messages failed.");
}
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS) {
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E &&
ret != WS_CHANNEL_CLOSED) {
err_sys("Failed to listen for close messages from the peer.");
}
}
@ -994,8 +995,10 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E)
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E &&
ret != WS_CHANNEL_CLOSED) {
err_sys("Closing client stream failed");
}
ClientFreeBuffers(pubKeyName, privKeyName);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)

View File

@ -14034,64 +14034,6 @@ 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

View File

@ -954,24 +954,43 @@ int wolfSSH_connect(WOLFSSH* ssh)
int wolfSSH_shutdown(WOLFSSH* ssh)
{
int ret = WS_SUCCESS;
WOLFSSH_CHANNEL* channel = NULL;
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_shutdown()");
if (ssh == NULL || ssh->channelList == NULL)
ret = WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS)
ret = SendChannelEof(ssh, ssh->channelList->peerChannel);
/* look up the channel if it still exists */
if (ret == WS_SUCCESS) {
channel = ChannelFind(ssh, ssh->channelList->peerChannel, WS_CHANNEL_ID_SELF);
}
/* continue on success and in case where queing up send packets */
if (ret == WS_SUCCESS ||
(ret != WS_BAD_ARGUMENT && ssh->error == WS_WANT_WRITE))
ret = SendChannelExit(ssh, ssh->channelList->peerChannel, 0);
/* if channel close was not already sent then send it */
if (channel != NULL && !channel->closeTxd) {
if (ret == WS_SUCCESS) {
ret = SendChannelEof(ssh, ssh->channelList->peerChannel);
}
/* continue on success and in case where queing up send packets */
if (ret == WS_SUCCESS ||
(ret != WS_BAD_ARGUMENT && ssh->error == WS_WANT_WRITE))
ret = SendChannelClose(ssh, ssh->channelList->peerChannel);
/* continue on success and in case where queing up send packets */
if (ret == WS_SUCCESS ||
(ret != WS_BAD_ARGUMENT && ssh->error == WS_WANT_WRITE)) {
ret = SendChannelExit(ssh, ssh->channelList->peerChannel,
ssh->exitStatus);
}
/* continue on success and in case where queing up send packets */
if (ret == WS_SUCCESS ||
(ret != WS_BAD_ARGUMENT && ssh->error == WS_WANT_WRITE))
ret = SendChannelClose(ssh, ssh->channelList->peerChannel);
}
/* if the channel was not yet removed then read to get
* response to SendChannelClose */
if (channel != NULL && ret == WS_SUCCESS) {
ret = wolfSSH_worker(ssh, NULL);
}
if (ssh != NULL && ssh->channelList == NULL) {
WLOG(WS_LOG_DEBUG, "channel list was already removed");
@ -1377,18 +1396,18 @@ int wolfSSH_GetExitStatus(WOLFSSH* ssh)
}
/* Sends the commands exit status to the peer
/* Sets the exit status to send on shutdown
* returns WS_SUCCESS on success */
int wolfSSH_SendExitStatus(WOLFSSH* ssh, word32 exitStatus)
int wolfSSH_SetExitStatus(WOLFSSH* ssh, word32 exitStatus)
{
if (ssh == NULL) {
WLOG(WS_LOG_DEBUG, "wolfSSH_SendExitStatus WOLFSSH struct was NULL");
WLOG(WS_LOG_DEBUG, "wolfSSH_SetExitStatus WOLFSSH struct was NULL");
return WS_BAD_ARGUMENT;
}
WLOG(WS_LOG_DEBUG, "wolfSSH_SendExitStatus sending exit status %u",
WLOG(WS_LOG_DEBUG, "wolfSSH_SetExitStatus sending exit status %u",
exitStatus);
return SendChannelExitStatus(ssh, ssh->defaultPeerChannelId, exitStatus);
ssh->exitStatus = exitStatus;
return WS_SUCCESS;
}
#endif

View File

@ -294,7 +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);
WOLFSSH_API int wolfSSH_SetExitStatus(WOLFSSH* ssh, word32 exitStatus);
enum WS_HighwaterSide {