mirror of https://github.com/wolfSSL/wolfssh.git
adjust shutdown for sending exit status cleanly
parent
f41e706825
commit
0d480fa419
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
51
src/ssh.c
51
src/ssh.c
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue