@@ -1222,6 +1222,81 @@ static int test_DoUserAuthBanner(void)
12221222 return result ;
12231223}
12241224
1225+ #if defined(WOLFSSH_TEST_INTERNAL ) && defined(WOLFSSH_SCP )
1226+ /* Verify GetScpFileMode strips setuid/setgid/sticky bits from a peer-supplied
1227+ * SCP C/D record mode, matching the masking already done on the send path.
1228+ * The receive path cannot be exercised end-to-end because both peers mask the
1229+ * mode before transmitting, so this drives the parser directly. */
1230+ static int test_ScpGetFileMode (void )
1231+ {
1232+ WOLFSSH_CTX * ctx = NULL ;
1233+ WOLFSSH * ssh = NULL ;
1234+ static const char * hdrs [] = {
1235+ "C4755 0 f\n" , /* setuid set */
1236+ "D2755 0 d\n" , /* setgid set */
1237+ "D1755 0 d\n" , /* sticky set */
1238+ "D7777 0 d\n" , /* all special bits set */
1239+ "C0644 0 f\n" /* ordinary mode, unaffected */
1240+ };
1241+ static const int expected [] = { 0755 , 0755 , 0755 , 0777 , 0644 };
1242+ /* records the parser must reject */
1243+ static const char * badHdrs [] = {
1244+ "C8755 0 f\n" , /* '8' is not an octal digit */
1245+ "X4755 0 f\n" , /* prefix is neither 'C' nor 'D' */
1246+ "C75" /* shorter than the mode field */
1247+ };
1248+ int result = 0 ;
1249+ int ret ;
1250+ int i ;
1251+ word32 idx ;
1252+
1253+ ctx = wolfSSH_CTX_new (WOLFSSH_ENDPOINT_SERVER , NULL );
1254+ if (ctx == NULL )
1255+ return -420 ;
1256+ ssh = wolfSSH_new (ctx );
1257+ if (ssh == NULL ) {
1258+ wolfSSH_CTX_free (ctx );
1259+ return -421 ;
1260+ }
1261+
1262+ for (i = 0 ; i < (int )(sizeof (hdrs ) / sizeof (hdrs [0 ])); i ++ ) {
1263+ idx = 0 ;
1264+ ssh -> scpFileMode = 0 ;
1265+ ret = wolfSSH_TestScpGetFileMode (ssh , (byte * )hdrs [i ],
1266+ (word32 )WSTRLEN (hdrs [i ]), & idx );
1267+ if (ret != WS_SUCCESS ) {
1268+ result = -422 ;
1269+ break ;
1270+ }
1271+ if (ssh -> scpFileMode != expected [i ]) {
1272+ result = -423 ;
1273+ break ;
1274+ }
1275+ /* index advances past the 'C'/'D', four mode octets, and the
1276+ * trailing space */
1277+ if (idx != 6 ) {
1278+ result = -424 ;
1279+ break ;
1280+ }
1281+ }
1282+
1283+ for (i = 0 ; result == 0 &&
1284+ i < (int )(sizeof (badHdrs ) / sizeof (badHdrs [0 ])); i ++ ) {
1285+ idx = 0 ;
1286+ ret = wolfSSH_TestScpGetFileMode (ssh , (byte * )badHdrs [i ],
1287+ (word32 )WSTRLEN (badHdrs [i ]), & idx );
1288+ if (ret != WS_BAD_ARGUMENT ) {
1289+ result = -425 ;
1290+ break ;
1291+ }
1292+ }
1293+
1294+ wolfSSH_free (ssh );
1295+ wolfSSH_CTX_free (ctx );
1296+ return result ;
1297+ }
1298+ #endif /* WOLFSSH_TEST_INTERNAL && WOLFSSH_SCP */
1299+
12251300static int test_ChannelPutData (void )
12261301{
12271302 WOLFSSH_CTX * ctx = NULL ;
@@ -4850,6 +4925,12 @@ int wolfSSH_UnitTest(int argc, char** argv)
48504925 printf ("ChannelPutData: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
48514926 testResult = testResult || unitResult ;
48524927
4928+ #if defined(WOLFSSH_TEST_INTERNAL ) && defined(WOLFSSH_SCP )
4929+ unitResult = test_ScpGetFileMode ();
4930+ printf ("ScpGetFileMode: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
4931+ testResult = testResult || unitResult ;
4932+ #endif
4933+
48534934 unitResult = test_MsgHighwater ();
48544935 printf ("MsgHighwater: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
48554936 testResult = testResult || unitResult ;
0 commit comments