@@ -314,7 +314,8 @@ static int test_ConfigCopy(void)
314314 ret = wolfSSHD_ConfigSetHostCertFile (head , "/etc/ssh/host_cert.pub" );
315315 if (ret == WS_SUCCESS )
316316 ret = wolfSSHD_ConfigSetUserCAKeysFile (head , "/etc/ssh/ca.pub" );
317- /* AuthorizedKeysFile must go through PCL so authKeysFileSet flag is set */
317+ /* AuthorizedKeysFile via PCL to also exercise the config-parse path; the
318+ * authKeysFileSet flag is set either way and must survive the copy */
318319 if (ret == WS_SUCCESS ) ret = PCL ("AuthorizedKeysFile .ssh/authorized_keys" );
319320
320321 /* scalar fields */
@@ -996,6 +997,62 @@ static int test_IncludeRecursionBound(void)
996997 return ret ;
997998}
998999
1000+ /* The public wolfSSHD_ConfigSetAuthKeysFile setter must mark the authorized
1001+ * keys file as explicitly configured, otherwise certificate public-key logins
1002+ * skip the authorized-keys check and rely on CA validation alone. */
1003+ static int test_ConfigSetAuthKeysFile (void )
1004+ {
1005+ int ret = WS_SUCCESS ;
1006+ WOLFSSHD_CONFIG * conf ;
1007+
1008+ conf = wolfSSHD_ConfigNew (NULL );
1009+ if (conf == NULL )
1010+ ret = WS_MEMORY_E ;
1011+
1012+ /* fresh config has no explicit authorized keys file */
1013+ if (ret == WS_SUCCESS ) {
1014+ if (wolfSSHD_ConfigGetAuthKeysFileSet (conf ) != 0 )
1015+ ret = WS_FATAL_ERROR ;
1016+ }
1017+
1018+ /* configuring a file through the public setter must set the flag */
1019+ if (ret == WS_SUCCESS )
1020+ ret = wolfSSHD_ConfigSetAuthKeysFile (conf , ".ssh/authorized_keys" );
1021+ if (ret == WS_SUCCESS ) {
1022+ if (wolfSSHD_ConfigGetAuthKeysFileSet (conf ) == 0 )
1023+ ret = WS_FATAL_ERROR ;
1024+ }
1025+
1026+ /* a failed update must leave the existing configuration intact: an
1027+ * all-whitespace file makes CreateString fail, and both the previously
1028+ * configured file and the flag must be untouched, not half cleared */
1029+ if (ret == WS_SUCCESS ) {
1030+ if (wolfSSHD_ConfigSetAuthKeysFile (conf , " " ) == WS_SUCCESS )
1031+ ret = WS_FATAL_ERROR ; /* the bad value should have been rejected */
1032+ }
1033+ if (ret == WS_SUCCESS ) {
1034+ if (wolfSSHD_ConfigGetAuthKeysFile (conf ) == NULL ||
1035+ XSTRCMP (wolfSSHD_ConfigGetAuthKeysFile (conf ),
1036+ ".ssh/authorized_keys" ) != 0 )
1037+ ret = WS_FATAL_ERROR ;
1038+ }
1039+ if (ret == WS_SUCCESS ) {
1040+ if (wolfSSHD_ConfigGetAuthKeysFileSet (conf ) == 0 )
1041+ ret = WS_FATAL_ERROR ;
1042+ }
1043+
1044+ /* removing the file must clear the flag again */
1045+ if (ret == WS_SUCCESS )
1046+ ret = wolfSSHD_ConfigSetAuthKeysFile (conf , NULL );
1047+ if (ret == WS_SUCCESS ) {
1048+ if (wolfSSHD_ConfigGetAuthKeysFileSet (conf ) != 0 )
1049+ ret = WS_FATAL_ERROR ;
1050+ }
1051+
1052+ wolfSSHD_ConfigFree (conf );
1053+ return ret ;
1054+ }
1055+
9991056/* Verifies ConfigFree releases all string fields - most useful under ASan. */
10001057static int test_ConfigFree (void )
10011058{
@@ -1438,6 +1495,7 @@ const TEST_CASE testCases[] = {
14381495 TEST_DECL (test_CAKeysFileDiffers ),
14391496 TEST_DECL (test_IncludeRecursionBound ),
14401497 TEST_DECL (test_GetUserAuthTypes ),
1498+ TEST_DECL (test_ConfigSetAuthKeysFile ),
14411499 TEST_DECL (test_ConfigFree ),
14421500#ifdef WOLFSSL_BASE64_ENCODE
14431501 TEST_DECL (test_CheckAuthKeysLine ),
0 commit comments