Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 40 additions & 9 deletions apps/wolfsshd/wolfsshd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,23 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
#include <sys/ioctl.h>
#endif

static int SHELL_IsPty(WOLFSSH* ssh)
{
WOLFSSH_CHANNEL* channel;
int ret = WS_SUCCESS;
word32 channelId = 0;

ret = wolfSSH_GetLastRxId(ssh, &channelId);
if (ret == WS_SUCCESS) {
channel = wolfSSH_ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF);
}

if (ret == WS_SUCCESS) {
ret = wolfSSH_ChannelIsPty(channel);
}
return ret;
}

/* handles creating a new shell env. and maintains SSH connection for incoming
* user input as well as output of the shell.
* return WS_SUCCESS on success */
Expand Down Expand Up @@ -1193,6 +1210,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;
Expand All @@ -1204,6 +1222,12 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,

forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf);

ptyReq = SHELL_IsPty(ssh);
if (ptyReq < 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure get channel PTY state");
return WS_FATAL_ERROR;
}

/* do not overwrite a forced command with 'exec' sub shell. Only set the
* 'exec' command when no forced command is set */
if (forcedCmd == NULL) {
Expand All @@ -1223,8 +1247,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
return WS_FATAL_ERROR;
}


/* create pipes for stdout and stderr */
if (forcedCmd) {
if (!ptyReq || forcedCmd) {
if (pipe(stdoutPipe) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue creating stdout pipe");
return WS_FATAL_ERROR;
Expand Down Expand Up @@ -1263,7 +1288,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
signal(SIGINT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);

if (forcedCmd) {
if (!ptyReq || forcedCmd) {
close(stdoutPipe[0]);
close(stderrPipe[0]);
close(stdinPipe[1]);
Expand Down Expand Up @@ -1390,7 +1415,13 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
close(stderrPipe[1]);
close(stdinPipe[1]);
}
else {
else if (!ptyReq) {
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) {
Expand Down Expand Up @@ -1443,7 +1474,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
#endif

wolfSSH_SetTerminalResizeCtx(ssh, (void*)&childFd);
if (forcedCmd) {
if (!ptyReq || forcedCmd) {
close(stdoutPipe[1]);
close(stderrPipe[1]);
close(stdinPipe[0]);
Expand All @@ -1469,7 +1500,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 || forcedCmd) {
FD_SET(stdoutPipe[0], &readFds);
if (stdoutPipe[0] > maxFd)
maxFd = stdoutPipe[0];
Expand Down Expand Up @@ -1515,7 +1546,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
if (cnt_r <= 0)
break;

if (forcedCmd) {
if (!ptyReq || forcedCmd) {
cnt_w = (int)write(stdinPipe[1], channelBuffer,
cnt_r);
}
Expand Down Expand Up @@ -1555,7 +1586,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 || forcedCmd)) {
/* SSH is done, close stdin pipe to child process */
close(stdinPipe[1]);
stdinPipe[1] = -1;
Expand Down Expand Up @@ -1585,7 +1616,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
}
}

if (forcedCmd) {
if (!ptyReq || forcedCmd) {
if (FD_ISSET(stderrPipe[0], &readFds)) {
cnt_r = (int)read(stderrPipe[0], shellBuffer,
sizeof shellBuffer);
Expand Down Expand Up @@ -1725,7 +1756,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 || forcedCmd) {
int readSz;

fcntl(stdoutPipe[0], F_SETFL, fcntl(stdoutPipe[0], F_GETFL)
Expand Down
1 change: 1 addition & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -8951,6 +8951,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
word32 termSz, modesSz = 0;
word32 widthChar, heightRows, widthPixels, heightPixels;

channel->ptyReq = 1; /* recieved a pty request */
termSz = (word32)sizeof(term);
ret = GetString(term, &termSz, buf, len, &begin);
if (ret == WS_SUCCESS)
Expand Down
12 changes: 12 additions & 0 deletions src/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -3233,6 +3233,18 @@ WS_SessionType wolfSSH_ChannelGetSessionType(const WOLFSSH_CHANNEL* channel)
}


#if defined(WOLFSSH_TERM)
/* returns 1 if a PTY was requested, 0 if not, and negative on failure */
int wolfSSH_ChannelIsPty(const WOLFSSH_CHANNEL* channel)
{
if (channel == NULL) {
return WS_BAD_ARGUMENT;
}
return channel->ptyReq;
}
#endif


const char* wolfSSH_ChannelGetSessionCommand(const WOLFSSH_CHANNEL* channel)
{
const char* cmd = NULL;
Expand Down
1 change: 1 addition & 0 deletions wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,7 @@ struct WOLFSSH_CHANNEL {
byte eofRxd : 1;
byte eofTxd : 1;
byte openConfirmed : 1;
byte ptyReq : 1; /* flag for if interactive pty request was received */
word32 channel;
word32 windowSz;
word32 maxPacketSz;
Expand Down
1 change: 1 addition & 0 deletions wolfssh/ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ChannelIsPty(const WOLFSSH_CHANNEL* channel);

/* Channel callbacks */
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);
Expand Down
Loading