@@ -233,8 +233,173 @@ static int test_ParseConfigLine(void)
233233 return ret ;
234234}
235235
236+ static int test_ConfigCopy (void )
237+ {
238+ int ret = WS_SUCCESS ;
239+ WOLFSSHD_CONFIG * head ;
240+ WOLFSSHD_CONFIG * conf ;
241+ WOLFSSHD_CONFIG * match ;
242+
243+ head = wolfSSHD_ConfigNew (NULL );
244+ if (head == NULL )
245+ ret = WS_MEMORY_E ;
246+ conf = head ;
247+
248+ /* string fields via ParseConfigLine */
249+ #define PCL (s ) ParseConfigLine(&conf, s, (int)WSTRLEN(s))
250+ if (ret == WS_SUCCESS ) ret = PCL ("Banner /etc/issue" );
251+ if (ret == WS_SUCCESS ) ret = PCL ("ChrootDirectory /var/chroot" );
252+ if (ret == WS_SUCCESS ) ret = PCL ("HostKey /etc/ssh/ssh_host_key" );
253+ if (ret == WS_SUCCESS ) ret = PCL ("ForceCommand /bin/restricted" );
254+ if (ret == WS_SUCCESS ) ret = PCL ("PidFile /var/run/sshd.pid" );
255+
256+ /* string fields via public setters */
257+ if (ret == WS_SUCCESS )
258+ ret = wolfSSHD_ConfigSetHostCertFile (head , "/etc/ssh/host_cert.pub" );
259+ if (ret == WS_SUCCESS )
260+ ret = wolfSSHD_ConfigSetUserCAKeysFile (head , "/etc/ssh/ca.pub" );
261+ if (ret == WS_SUCCESS )
262+ ret = wolfSSHD_ConfigSetAuthKeysFile (head , ".ssh/authorized_keys" );
263+
264+ /* scalar fields */
265+ if (ret == WS_SUCCESS ) ret = PCL ("Port 2222" );
266+ if (ret == WS_SUCCESS ) ret = PCL ("LoginGraceTime 30" );
267+ if (ret == WS_SUCCESS ) ret = PCL ("PasswordAuthentication yes" );
268+ if (ret == WS_SUCCESS ) ret = PCL ("PermitEmptyPasswords yes" );
269+ if (ret == WS_SUCCESS ) ret = PCL ("PermitRootLogin yes" );
270+ if (ret == WS_SUCCESS ) ret = PCL ("UsePrivilegeSeparation yes" );
271+
272+ /* trigger ConfigCopy via Match; conf advances to the new node */
273+ if (ret == WS_SUCCESS ) ret = PCL ("Match User testuser" );
274+ #undef PCL
275+
276+ /* retrieve match node from the list head */
277+ if (ret == WS_SUCCESS ) {
278+ match = wolfSSHD_GetUserConf (head , "testuser" , NULL , NULL , NULL ,
279+ NULL , NULL , NULL );
280+ if (match == NULL || match == head )
281+ ret = WS_FATAL_ERROR ;
282+ }
283+
284+ /* verify string fields were copied */
285+ if (ret == WS_SUCCESS ) {
286+ if (wolfSSHD_ConfigGetBanner (match ) == NULL ||
287+ XSTRCMP (wolfSSHD_ConfigGetBanner (match ), "/etc/issue" ) != 0 )
288+ ret = WS_FATAL_ERROR ;
289+ }
290+ if (ret == WS_SUCCESS ) {
291+ if (wolfSSHD_ConfigGetChroot (match ) == NULL ||
292+ XSTRCMP (wolfSSHD_ConfigGetChroot (match ), "/var/chroot" ) != 0 )
293+ ret = WS_FATAL_ERROR ;
294+ }
295+ if (ret == WS_SUCCESS ) {
296+ if (wolfSSHD_ConfigGetHostKeyFile (match ) == NULL ||
297+ XSTRCMP (wolfSSHD_ConfigGetHostKeyFile (match ),
298+ "/etc/ssh/ssh_host_key" ) != 0 )
299+ ret = WS_FATAL_ERROR ;
300+ }
301+ if (ret == WS_SUCCESS ) {
302+ if (wolfSSHD_ConfigGetHostCertFile (match ) == NULL ||
303+ XSTRCMP (wolfSSHD_ConfigGetHostCertFile (match ),
304+ "/etc/ssh/host_cert.pub" ) != 0 )
305+ ret = WS_FATAL_ERROR ;
306+ }
307+ if (ret == WS_SUCCESS ) {
308+ if (wolfSSHD_ConfigGetUserCAKeysFile (match ) == NULL ||
309+ XSTRCMP (wolfSSHD_ConfigGetUserCAKeysFile (match ),
310+ "/etc/ssh/ca.pub" ) != 0 )
311+ ret = WS_FATAL_ERROR ;
312+ }
313+ if (ret == WS_SUCCESS ) {
314+ if (wolfSSHD_ConfigGetAuthKeysFile (match ) == NULL ||
315+ XSTRCMP (wolfSSHD_ConfigGetAuthKeysFile (match ),
316+ ".ssh/authorized_keys" ) != 0 )
317+ ret = WS_FATAL_ERROR ;
318+ }
319+ if (ret == WS_SUCCESS ) {
320+ if (wolfSSHD_ConfigGetForcedCmd (match ) == NULL ||
321+ XSTRCMP (wolfSSHD_ConfigGetForcedCmd (match ),
322+ "/bin/restricted" ) != 0 )
323+ ret = WS_FATAL_ERROR ;
324+ }
325+
326+ /* verify authKeysFileSet flag was copied */
327+ if (ret == WS_SUCCESS ) {
328+ if (wolfSSHD_ConfigGetAuthKeysFileSet (match ) == 0 )
329+ ret = WS_FATAL_ERROR ;
330+ }
331+
332+ /* verify scalar fields were copied */
333+ if (ret == WS_SUCCESS ) {
334+ if (wolfSSHD_ConfigGetPort (match ) != 2222 )
335+ ret = WS_FATAL_ERROR ;
336+ }
337+ if (ret == WS_SUCCESS ) {
338+ if (wolfSSHD_ConfigGetGraceTime (match ) != 30 )
339+ ret = WS_FATAL_ERROR ;
340+ }
341+ if (ret == WS_SUCCESS ) {
342+ if (wolfSSHD_ConfigGetPwAuth (match ) == 0 )
343+ ret = WS_FATAL_ERROR ;
344+ }
345+ if (ret == WS_SUCCESS ) {
346+ if (wolfSSHD_ConfigGetPermitEmptyPw (match ) == 0 )
347+ ret = WS_FATAL_ERROR ;
348+ }
349+ if (ret == WS_SUCCESS ) {
350+ if (wolfSSHD_ConfigGetPermitRoot (match ) == 0 )
351+ ret = WS_FATAL_ERROR ;
352+ }
353+ if (ret == WS_SUCCESS ) {
354+ if (wolfSSHD_ConfigGetPrivilegeSeparation (match ) == 0 )
355+ ret = WS_FATAL_ERROR ;
356+ }
357+
358+ wolfSSHD_ConfigFree (head );
359+ return ret ;
360+ }
361+
362+ /* Verifies ConfigFree releases all string fields — most useful under ASan. */
363+ static int test_ConfigFree (void )
364+ {
365+ int ret = WS_SUCCESS ;
366+ WOLFSSHD_CONFIG * head ;
367+ WOLFSSHD_CONFIG * conf ;
368+
369+ head = wolfSSHD_ConfigNew (NULL );
370+ if (head == NULL )
371+ ret = WS_MEMORY_E ;
372+ conf = head ;
373+
374+ #define PCL (s ) ParseConfigLine(&conf, s, (int)WSTRLEN(s))
375+ if (ret == WS_SUCCESS ) ret = PCL ("Banner /etc/issue" );
376+ if (ret == WS_SUCCESS ) ret = PCL ("ChrootDirectory /var/chroot" );
377+ if (ret == WS_SUCCESS ) ret = PCL ("HostKey /etc/ssh/ssh_host_key" );
378+ if (ret == WS_SUCCESS ) ret = PCL ("ForceCommand /bin/restricted" );
379+ if (ret == WS_SUCCESS ) ret = PCL ("PidFile /var/run/sshd.pid" );
380+ if (ret == WS_SUCCESS )
381+ ret = wolfSSHD_ConfigSetHostCertFile (head , "/etc/ssh/host_cert.pub" );
382+ if (ret == WS_SUCCESS )
383+ ret = wolfSSHD_ConfigSetUserCAKeysFile (head , "/etc/ssh/ca.pub" );
384+ if (ret == WS_SUCCESS )
385+ ret = wolfSSHD_ConfigSetAuthKeysFile (head , ".ssh/authorized_keys" );
386+
387+ /* Match User — allocates usrAppliesTo on the copied node */
388+ if (ret == WS_SUCCESS ) ret = PCL ("Match User alice" );
389+
390+ /* Match Group — allocates groupAppliesTo on the next copied node */
391+ if (ret == WS_SUCCESS ) ret = PCL ("Match Group staff" );
392+ #undef PCL
393+
394+ /* Free must not crash and must release every allocation */
395+ wolfSSHD_ConfigFree (head );
396+ return ret ;
397+ }
398+
236399const TEST_CASE testCases [] = {
237- TEST_DECL (test_ParseConfigLine )
400+ TEST_DECL (test_ParseConfigLine ),
401+ TEST_DECL (test_ConfigCopy ),
402+ TEST_DECL (test_ConfigFree ),
238403};
239404
240405int main (int argc , char * * argv )
0 commit comments