do not treat shell as interactive until pty-req received

pull/832/head
JacobBarthelmeh 2025-09-16 10:11:46 -06:00
parent 4e087a041a
commit 6fe09bdb35
5 changed files with 40 additions and 9 deletions

View File

@ -1193,6 +1193,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
int wantWrite = 0;
int peerConnected = 1;
int stdoutEmpty = 0;
int ptyReq = 0;
childFd = -1;
stdoutPipe[0] = -1;
@ -1203,6 +1204,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
stdinPipe[1] = -1;
forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf);
ptyReq = wolfSSH_ReceivedPtyReq(ssh);
/* do not overwrite a forced command with 'exec' sub shell. Only set the
* 'exec' command when no forced command is set */
@ -1223,8 +1225,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
return WS_FATAL_ERROR;
}
/* create pipes for stdout and stderr */
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
if (pipe(stdoutPipe) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue creating stdout pipe");
return WS_FATAL_ERROR;
@ -1263,7 +1266,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
signal(SIGINT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
close(stdoutPipe[0]);
close(stderrPipe[0]);
close(stdinPipe[1]);
@ -1390,7 +1393,13 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
close(stderrPipe[1]);
close(stdinPipe[1]);
}
else {
else if (ptyReq == 0) {
ret = execv(cmd, (char**)args);
close(stdoutPipe[1]);
close(stderrPipe[1]);
close(stdinPipe[1]);
}
else { /* open interactive shell */
ret = execv(cmd, (char**)args);
}
if (ret && errno) {
@ -1443,7 +1452,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
#endif
wolfSSH_SetTerminalResizeCtx(ssh, (void*)&childFd);
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
close(stdoutPipe[1]);
close(stderrPipe[1]);
close(stdinPipe[0]);
@ -1469,7 +1478,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (wolfSSH_stream_peek(ssh, tmp, 1) <= 0) {
/* select on stdout/stderr pipes with forced commands */
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
FD_SET(stdoutPipe[0], &readFds);
if (stdoutPipe[0] > maxFd)
maxFd = stdoutPipe[0];
@ -1515,7 +1524,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r <= 0)
break;
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
cnt_w = (int)write(stdinPipe[1], channelBuffer,
cnt_r);
}
@ -1555,7 +1564,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
current = wolfSSH_ChannelFind(ssh, lastChannel,
WS_CHANNEL_ID_SELF);
eof = wolfSSH_ChannelGetEof(current);
if (eof && forcedCmd) {
if (eof && (ptyReq == 0 || forcedCmd)) {
/* SSH is done, close stdin pipe to child process */
close(stdinPipe[1]);
stdinPipe[1] = -1;
@ -1585,7 +1594,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
}
}
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
if (FD_ISSET(stderrPipe[0], &readFds)) {
cnt_r = (int)read(stderrPipe[0], shellBuffer,
sizeof shellBuffer);
@ -1725,7 +1734,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
}
/* check for any left over data in pipes then close them */
if (forcedCmd) {
if (ptyReq == 0 || forcedCmd) {
int readSz;
fcntl(stdoutPipe[0], F_SETFL, fcntl(stdoutPipe[0], F_GETFL)

View File

@ -8951,6 +8951,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
word32 termSz, modesSz = 0;
word32 widthChar, heightRows, widthPixels, heightPixels;
ssh->ptyReq = 1; /* recieved a pty request */
termSz = (word32)sizeof(term);
ret = GetString(term, &termSz, buf, len, &begin);
if (ret == WS_SUCCESS)

View File

@ -2539,6 +2539,25 @@ WS_SessionType wolfSSH_GetSessionType(const WOLFSSH* ssh)
}
#if defined(WOLFSSH_TERM)
int wolfSSH_ReceivedPtyReq(const WOLFSSH* ssh)
{
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_ReceivedPtyReq");
if (ssh == NULL) {
return WS_BAD_ARGUMENT;
}
if (ssh->ptyReq) {
return 1;
}
else {
return 0;
}
}
#endif
const char* wolfSSH_GetSessionCommand(const WOLFSSH* ssh)
{
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_GetSessionCommand()");

View File

@ -913,6 +913,7 @@ struct WOLFSSH {
word32 heightPixels; /* pixel height */
byte* modes;
word32 modesSz;
byte ptyReq:1; /* flag for if interactive pty request was received */
#endif
#if defined(WOLFSSH_TERM) || defined(WOLFSSH_SHELL)
word32 exitStatus;

View File

@ -233,6 +233,7 @@ WOLFSSH_API WS_SessionType wolfSSH_ChannelGetSessionType(
const WOLFSSH_CHANNEL* channel);
WOLFSSH_API const char* wolfSSH_ChannelGetSessionCommand(
const WOLFSSH_CHANNEL* channel);
WOLFSSH_API int wolfSSH_ReceivedPtyReq(const WOLFSSH* ssh);
/* Channel callbacks */
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);