Skip to content

Commit 97a0c7b

Browse files
Fix wolfSSHD_ConfigCopy and wolfSSHD_ConfigFree, and Add the regression test
1 parent 91cbb64 commit 97a0c7b

2 files changed

Lines changed: 201 additions & 3 deletions

File tree

apps/wolfsshd/configuration.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,30 @@ static WOLFSSHD_CONFIG* wolfSSHD_ConfigCopy(WOLFSSHD_CONFIG* conf)
277277
newConf->heap);
278278
}
279279

280+
if (ret == WS_SUCCESS && conf->hostCertFile) {
281+
ret = CreateString(&newConf->hostCertFile, conf->hostCertFile,
282+
(int)WSTRLEN(conf->hostCertFile),
283+
newConf->heap);
284+
}
285+
286+
if (ret == WS_SUCCESS && conf->pidFile) {
287+
ret = CreateString(&newConf->pidFile, conf->pidFile,
288+
(int)WSTRLEN(conf->pidFile),
289+
newConf->heap);
290+
}
291+
292+
if (ret == WS_SUCCESS && conf->userCAKeysFile) {
293+
ret = CreateString(&newConf->userCAKeysFile, conf->userCAKeysFile,
294+
(int)WSTRLEN(conf->userCAKeysFile),
295+
newConf->heap);
296+
}
297+
298+
if (ret == WS_SUCCESS && conf->forceCmd) {
299+
ret = CreateString(&newConf->forceCmd, conf->forceCmd,
300+
(int)WSTRLEN(conf->forceCmd),
301+
newConf->heap);
302+
}
303+
280304
if (ret == WS_SUCCESS) {
281305
newConf->loginTimer = conf->loginTimer;
282306
newConf->port = conf->port;
@@ -285,6 +309,11 @@ static WOLFSSHD_CONFIG* wolfSSHD_ConfigCopy(WOLFSSHD_CONFIG* conf)
285309
newConf->usePrivilegeSeparation = conf->usePrivilegeSeparation;
286310
newConf->permitRootLogin = conf->permitRootLogin;
287311
newConf->permitEmptyPasswords = conf->permitEmptyPasswords;
312+
newConf->authKeysFileSet = conf->authKeysFileSet;
313+
}
314+
else {
315+
wolfSSHD_ConfigFree(newConf);
316+
newConf = NULL;
288317
}
289318
}
290319

@@ -310,8 +339,12 @@ void wolfSSHD_ConfigFree(WOLFSSHD_CONFIG* conf)
310339
FreeString(&current->listenAddress, heap);
311340
FreeString(&current->authKeysFile, heap);
312341
FreeString(&current->hostKeyFile, heap);
313-
FreeString(&current->hostCertFile, heap);
314-
FreeString(&current->pidFile, heap);
342+
FreeString(&current->hostCertFile, heap);
343+
FreeString(&current->pidFile, heap);
344+
FreeString(&current->userCAKeysFile, heap);
345+
FreeString(&current->forceCmd, heap);
346+
FreeString(&current->usrAppliesTo, heap);
347+
FreeString(&current->groupAppliesTo, heap);
315348

316349
WFREE(current, heap, DYNTYPE_SSHD);
317350
current = next;

apps/wolfsshd/test/test_configuration.c

Lines changed: 166 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
236399
const 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

240405
int main(int argc, char** argv)

0 commit comments

Comments
 (0)