5757 #define WOLFSSHD_TIMEOUT 1
5858#endif
5959
60+ #ifdef EXAMPLE_BUFFER_SZ
61+ #warning use WOLFSSHD_SHELL_BUFFER_SZ instead of EXAMPLE_BUFFER_SZ
62+ #define WOLFSSHD_SHELL_BUFFER_SZ EXAMPLE_BUFFER_SZ
63+ #endif
64+
6065#if defined(WOLFSSH_SHELL ) && !defined(_WIN32 )
6166 #ifdef HAVE_PTY_H
6267 #include <pty.h>
@@ -815,10 +820,11 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
815820{
816821 BOOL ret ;
817822 word32 shellChannelId = 0 ;
818- #ifndef EXAMPLE_BUFFER_SZ
819- #define EXAMPLE_BUFFER_SZ 4096
823+ #ifndef WOLFSSHD_SHELL_BUFFER_SZ
824+ /* default to try and read max packet size */
825+ #define WOLFSSHD_SHELL_BUFFER_SZ 32768
820826#endif
821- byte shellBuffer [EXAMPLE_BUFFER_SZ ];
827+ byte shellBuffer [WOLFSSHD_SHELL_BUFFER_SZ ];
822828 int cnt_r , cnt_w ;
823829 HANDLE ptyIn = NULL , ptyOut = NULL ;
824830 HANDLE cnslIn = NULL , cnslOut = NULL ;
@@ -1105,9 +1111,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11051111 }
11061112
11071113 if (readPending ) {
1108- WMEMSET (shellBuffer , 0 , EXAMPLE_BUFFER_SZ );
1114+ WMEMSET (shellBuffer , 0 , WOLFSSHD_SHELL_BUFFER_SZ );
11091115
1110- if (ReadFile (ptyOut , shellBuffer , EXAMPLE_BUFFER_SZ , & cnt_r ,
1116+ if (ReadFile (ptyOut , shellBuffer , WOLFSSHD_SHELL_BUFFER_SZ , & cnt_r ,
11111117 NULL ) != TRUE) {
11121118 wolfSSH_Log (WS_LOG_INFO ,
11131119 "[SSHD] Error reading from pipe for console" );
@@ -1163,16 +1169,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11631169 int rc ;
11641170 WS_SOCKET_T childFd = 0 ;
11651171 int stdoutPipe [2 ], stderrPipe [2 ];
1172+ int stdinPipe [2 ];
11661173 pid_t childPid ;
11671174
1168- #ifndef EXAMPLE_BUFFER_SZ
1169- #define EXAMPLE_BUFFER_SZ 4096
1175+ #ifndef WOLFSSHD_SHELL_BUFFER_SZ
1176+ /* default to try and read max packet size */
1177+ #define WOLFSSHD_SHELL_BUFFER_SZ 32768
11701178#endif
11711179#ifndef MAX_IDLE_COUNT
11721180 #define MAX_IDLE_COUNT 2
11731181#endif
1174- byte shellBuffer [EXAMPLE_BUFFER_SZ ];
1175- byte channelBuffer [EXAMPLE_BUFFER_SZ ];
1182+ byte shellBuffer [WOLFSSHD_SHELL_BUFFER_SZ ];
1183+ byte channelBuffer [WOLFSSHD_SHELL_BUFFER_SZ ];
11761184 char * forcedCmd ;
11771185 int windowFull = 0 ; /* Contains size of bytes from shellBuffer that did
11781186 * not get passed on to wolfSSH yet. This happens
@@ -1186,6 +1194,8 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
11861194 stdoutPipe [1 ] = -1 ;
11871195 stderrPipe [0 ] = -1 ;
11881196 stderrPipe [1 ] = -1 ;
1197+ stdinPipe [0 ] = -1 ;
1198+ stdinPipe [1 ] = -1 ;
11891199
11901200 forcedCmd = wolfSSHD_ConfigGetForcedCmd (usrConf );
11911201
@@ -1216,10 +1226,18 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
12161226 }
12171227 if (pipe (stderrPipe ) != 0 ) {
12181228 close (stdoutPipe [0 ]);
1219- close (stderrPipe [1 ]);
1229+ close (stdoutPipe [1 ]);
12201230 wolfSSH_Log (WS_LOG_ERROR , "[SSHD] Issue creating stderr pipe" );
12211231 return WS_FATAL_ERROR ;
12221232 }
1233+ if (pipe (stdinPipe ) != 0 ) {
1234+ close (stdoutPipe [0 ]);
1235+ close (stdoutPipe [1 ]);
1236+ close (stderrPipe [0 ]);
1237+ close (stderrPipe [1 ]);
1238+ wolfSSH_Log (WS_LOG_ERROR , "[SSHD] Issue creating stdin pipe" );
1239+ return WS_FATAL_ERROR ;
1240+ }
12231241 }
12241242
12251243 ChildRunning = 1 ;
@@ -1243,8 +1261,20 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
12431261 if (forcedCmd ) {
12441262 close (stdoutPipe [0 ]);
12451263 close (stderrPipe [0 ]);
1264+ close (stdinPipe [1 ]);
12461265 stdoutPipe [0 ] = -1 ;
12471266 stderrPipe [0 ] = -1 ;
1267+ stdinPipe [1 ] = -1 ;
1268+
1269+ if (dup2 (stdinPipe [0 ], STDIN_FILENO ) == -1 ) {
1270+ wolfSSH_Log (WS_LOG_ERROR ,
1271+ "[SSHD] Error redirecting stdin pipe" );
1272+ if (wolfSSHD_AuthReducePermissions (conn -> auth ) != WS_SUCCESS ) {
1273+ exit (1 );
1274+ }
1275+
1276+ return WS_FATAL_ERROR ;
1277+ }
12481278 if (dup2 (stdoutPipe [1 ], STDOUT_FILENO ) == -1 ) {
12491279 wolfSSH_Log (WS_LOG_ERROR ,
12501280 "[SSHD] Error redirecting stdout pipe" );
@@ -1354,6 +1384,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
13541384 ret = execv (cmd , (char * * )args );
13551385 close (stdoutPipe [1 ]);
13561386 close (stderrPipe [1 ]);
1387+ close (stdinPipe [1 ]);
13571388 }
13581389 else {
13591390 ret = execv (cmd , (char * * )args );
@@ -1411,6 +1442,7 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14111442 if (forcedCmd ) {
14121443 close (stdoutPipe [1 ]);
14131444 close (stderrPipe [1 ]);
1445+ close (stdinPipe [0 ]);
14141446 }
14151447
14161448 while (ChildRunning || windowFull || !stdoutEmpty || peerConnected ) {
@@ -1431,23 +1463,23 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14311463 FD_SET (sshFd , & writeFds );
14321464 }
14331465
1434- /* select on stdout/stderr pipes with forced commands */
1435- if (forcedCmd ) {
1436- FD_SET (stdoutPipe [0 ], & readFds );
1437- if (stdoutPipe [0 ] > maxFd )
1438- maxFd = stdoutPipe [0 ];
1466+ if (wolfSSH_stream_peek (ssh , tmp , 1 ) <= 0 ) {
1467+ /* select on stdout/stderr pipes with forced commands */
1468+ if (forcedCmd ) {
1469+ FD_SET (stdoutPipe [0 ], & readFds );
1470+ if (stdoutPipe [0 ] > maxFd )
1471+ maxFd = stdoutPipe [0 ];
14391472
1440- FD_SET (stderrPipe [0 ], & readFds );
1441- if (stderrPipe [0 ] > maxFd )
1442- maxFd = stderrPipe [0 ];
1443- }
1444- else {
1445- FD_SET (childFd , & readFds );
1446- if (childFd > maxFd )
1447- maxFd = childFd ;
1448- }
1473+ FD_SET (stderrPipe [0 ], & readFds );
1474+ if (stderrPipe [0 ] > maxFd )
1475+ maxFd = stderrPipe [0 ];
1476+ }
1477+ else {
1478+ FD_SET (childFd , & readFds );
1479+ if (childFd > maxFd )
1480+ maxFd = childFd ;
1481+ }
14491482
1450- if (wolfSSH_stream_peek (ssh , tmp , 1 ) <= 0 ) {
14511483 rc = select ((int )maxFd + 1 , & readFds , & writeFds , NULL , NULL );
14521484 if (rc == -1 )
14531485 break ;
@@ -1478,8 +1510,15 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
14781510 sizeof channelBuffer );
14791511 if (cnt_r <= 0 )
14801512 break ;
1481- cnt_w = (int )write (childFd ,
1482- channelBuffer , cnt_r );
1513+
1514+ if (forcedCmd ) {
1515+ cnt_w = (int )write (stdinPipe [1 ], channelBuffer ,
1516+ cnt_r );
1517+ }
1518+ else {
1519+ cnt_w = (int )write (childFd , channelBuffer ,
1520+ cnt_r );
1521+ }
14831522 if (cnt_w <= 0 )
14841523 break ;
14851524 }
@@ -1503,6 +1542,21 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
15031542 break ;
15041543 }
15051544 }
1545+
1546+ /* did the channel just receive an EOF? */
1547+ if (cnt_r == 0 ) {
1548+ int eof ;
1549+ WOLFSSH_CHANNEL * current ;
1550+
1551+ current = wolfSSH_ChannelFind (ssh , lastChannel ,
1552+ WS_CHANNEL_ID_SELF );
1553+ eof = wolfSSH_ChannelGetEof (current );
1554+ if (eof && forcedCmd ) {
1555+ /* SSH is done, close stdin pipe to child process */
1556+ close (stdinPipe [1 ]);
1557+ stdinPipe [1 ] = -1 ;
1558+ }
1559+ }
15061560 }
15071561
15081562 /* if the window was previously full, try resending the data */
@@ -1683,8 +1737,12 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
16831737 if (readSz > 0 ) {
16841738 wolfSSH_extended_data_send (ssh , shellBuffer , readSz );
16851739 }
1740+
16861741 close (stdoutPipe [0 ]);
16871742 close (stderrPipe [0 ]);
1743+ if (stdinPipe [1 ] != -1 ) {
1744+ close (stdinPipe [1 ]);
1745+ }
16881746 }
16891747
16901748 (void )conn ;
0 commit comments