Skip to content

Commit 2a21844

Browse files
authored
Merge pull request #832 from JacobBarthelmeh/pty
do not treat shell as interactive until pty-req received
2 parents 4e087a0 + 91c9279 commit 2a21844

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

apps/wolfsshd/wolfsshd.c

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,23 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11641164
#include <sys/ioctl.h>
11651165
#endif
11661166

1167+
static int SHELL_IsPty(WOLFSSH* ssh)
1168+
{
1169+
WOLFSSH_CHANNEL* channel;
1170+
int ret = WS_SUCCESS;
1171+
word32 channelId = 0;
1172+
1173+
ret = wolfSSH_GetLastRxId(ssh, &channelId);
1174+
if (ret == WS_SUCCESS) {
1175+
channel = wolfSSH_ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF);
1176+
}
1177+
1178+
if (ret == WS_SUCCESS) {
1179+
ret = wolfSSH_ChannelIsPty(channel);
1180+
}
1181+
return ret;
1182+
}
1183+
11671184
/* handles creating a new shell env. and maintains SSH connection for incoming
11681185
* user input as well as output of the shell.
11691186
* return WS_SUCCESS on success */
@@ -1193,6 +1210,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11931210
int wantWrite = 0;
11941211
int peerConnected = 1;
11951212
int stdoutEmpty = 0;
1213+
int ptyReq = 0;
11961214

11971215
childFd = -1;
11981216
stdoutPipe[0] = -1;
@@ -1204,6 +1222,12 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
12041222

12051223
forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf);
12061224

1225+
ptyReq = SHELL_IsPty(ssh);
1226+
if (ptyReq < 0) {
1227+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure get channel PTY state");
1228+
return WS_FATAL_ERROR;
1229+
}
1230+
12071231
/* do not overwrite a forced command with 'exec' sub shell. Only set the
12081232
* 'exec' command when no forced command is set */
12091233
if (forcedCmd == NULL) {
@@ -1223,8 +1247,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
12231247
return WS_FATAL_ERROR;
12241248
}
12251249

1250+
12261251
/* create pipes for stdout and stderr */
1227-
if (forcedCmd) {
1252+
if (!ptyReq || forcedCmd) {
12281253
if (pipe(stdoutPipe) != 0) {
12291254
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Issue creating stdout pipe");
12301255
return WS_FATAL_ERROR;
@@ -1263,7 +1288,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
12631288
signal(SIGINT, SIG_DFL);
12641289
signal(SIGCHLD, SIG_DFL);
12651290

1266-
if (forcedCmd) {
1291+
if (!ptyReq || forcedCmd) {
12671292
close(stdoutPipe[0]);
12681293
close(stderrPipe[0]);
12691294
close(stdinPipe[1]);
@@ -1390,7 +1415,13 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
13901415
close(stderrPipe[1]);
13911416
close(stdinPipe[1]);
13921417
}
1393-
else {
1418+
else if (!ptyReq) {
1419+
ret = execv(cmd, (char**)args);
1420+
close(stdoutPipe[1]);
1421+
close(stderrPipe[1]);
1422+
close(stdinPipe[1]);
1423+
}
1424+
else { /* open interactive shell */
13941425
ret = execv(cmd, (char**)args);
13951426
}
13961427
if (ret && errno) {
@@ -1443,7 +1474,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14431474
#endif
14441475

14451476
wolfSSH_SetTerminalResizeCtx(ssh, (void*)&childFd);
1446-
if (forcedCmd) {
1477+
if (!ptyReq || forcedCmd) {
14471478
close(stdoutPipe[1]);
14481479
close(stderrPipe[1]);
14491480
close(stdinPipe[0]);
@@ -1469,7 +1500,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14691500

14701501
if (wolfSSH_stream_peek(ssh, tmp, 1) <= 0) {
14711502
/* select on stdout/stderr pipes with forced commands */
1472-
if (forcedCmd) {
1503+
if (!ptyReq || forcedCmd) {
14731504
FD_SET(stdoutPipe[0], &readFds);
14741505
if (stdoutPipe[0] > maxFd)
14751506
maxFd = stdoutPipe[0];
@@ -1515,7 +1546,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15151546
if (cnt_r <= 0)
15161547
break;
15171548

1518-
if (forcedCmd) {
1549+
if (!ptyReq || forcedCmd) {
15191550
cnt_w = (int)write(stdinPipe[1], channelBuffer,
15201551
cnt_r);
15211552
}
@@ -1555,7 +1586,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15551586
current = wolfSSH_ChannelFind(ssh, lastChannel,
15561587
WS_CHANNEL_ID_SELF);
15571588
eof = wolfSSH_ChannelGetEof(current);
1558-
if (eof && forcedCmd) {
1589+
if (eof && (!ptyReq || forcedCmd)) {
15591590
/* SSH is done, close stdin pipe to child process */
15601591
close(stdinPipe[1]);
15611592
stdinPipe[1] = -1;
@@ -1585,7 +1616,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15851616
}
15861617
}
15871618

1588-
if (forcedCmd) {
1619+
if (!ptyReq || forcedCmd) {
15891620
if (FD_ISSET(stderrPipe[0], &readFds)) {
15901621
cnt_r = (int)read(stderrPipe[0], shellBuffer,
15911622
sizeof shellBuffer);
@@ -1725,7 +1756,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
17251756
}
17261757

17271758
/* check for any left over data in pipes then close them */
1728-
if (forcedCmd) {
1759+
if (!ptyReq || forcedCmd) {
17291760
int readSz;
17301761

17311762
fcntl(stdoutPipe[0], F_SETFL, fcntl(stdoutPipe[0], F_GETFL)

src/internal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8951,6 +8951,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
89518951
word32 termSz, modesSz = 0;
89528952
word32 widthChar, heightRows, widthPixels, heightPixels;
89538953

8954+
channel->ptyReq = 1; /* recieved a pty request */
89548955
termSz = (word32)sizeof(term);
89558956
ret = GetString(term, &termSz, buf, len, &begin);
89568957
if (ret == WS_SUCCESS)

src/ssh.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,6 +3233,18 @@ WS_SessionType wolfSSH_ChannelGetSessionType(const WOLFSSH_CHANNEL* channel)
32333233
}
32343234

32353235

3236+
#if defined(WOLFSSH_TERM)
3237+
/* returns 1 if a PTY was requested, 0 if not, and negative on failure */
3238+
int wolfSSH_ChannelIsPty(const WOLFSSH_CHANNEL* channel)
3239+
{
3240+
if (channel == NULL) {
3241+
return WS_BAD_ARGUMENT;
3242+
}
3243+
return channel->ptyReq;
3244+
}
3245+
#endif
3246+
3247+
32363248
const char* wolfSSH_ChannelGetSessionCommand(const WOLFSSH_CHANNEL* channel)
32373249
{
32383250
const char* cmd = NULL;

wolfssh/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ struct WOLFSSH_CHANNEL {
933933
byte eofRxd : 1;
934934
byte eofTxd : 1;
935935
byte openConfirmed : 1;
936+
byte ptyReq : 1; /* flag for if interactive pty request was received */
936937
word32 channel;
937938
word32 windowSz;
938939
word32 maxPacketSz;

wolfssh/ssh.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ WOLFSSH_API WS_SessionType wolfSSH_ChannelGetSessionType(
233233
const WOLFSSH_CHANNEL* channel);
234234
WOLFSSH_API const char* wolfSSH_ChannelGetSessionCommand(
235235
const WOLFSSH_CHANNEL* channel);
236+
WOLFSSH_API int wolfSSH_ChannelIsPty(const WOLFSSH_CHANNEL* channel);
236237

237238
/* Channel callbacks */
238239
typedef int (*WS_CallbackChannelOpen)(WOLFSSH_CHANNEL* channel, void* ctx);

0 commit comments

Comments
 (0)