@@ -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 )
0 commit comments