Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions apps/wolfsshd/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,30 @@ static WOLFSSHD_CONFIG* wolfSSHD_ConfigCopy(WOLFSSHD_CONFIG* conf)
newConf->heap);
}

if (ret == WS_SUCCESS && conf->hostCertFile) {
ret = CreateString(&newConf->hostCertFile, conf->hostCertFile,
(int)WSTRLEN(conf->hostCertFile),
newConf->heap);
}
Comment thread
yosuke-wolfssl marked this conversation as resolved.

if (ret == WS_SUCCESS && conf->pidFile) {
ret = CreateString(&newConf->pidFile, conf->pidFile,
(int)WSTRLEN(conf->pidFile),
newConf->heap);
}

if (ret == WS_SUCCESS && conf->userCAKeysFile) {
ret = CreateString(&newConf->userCAKeysFile, conf->userCAKeysFile,
(int)WSTRLEN(conf->userCAKeysFile),
newConf->heap);
}

if (ret == WS_SUCCESS && conf->forceCmd) {
ret = CreateString(&newConf->forceCmd, conf->forceCmd,
(int)WSTRLEN(conf->forceCmd),
newConf->heap);
}
Comment thread
yosuke-wolfssl marked this conversation as resolved.

if (ret == WS_SUCCESS) {
Comment thread
yosuke-wolfssl marked this conversation as resolved.
newConf->loginTimer = conf->loginTimer;
newConf->port = conf->port;
Expand All @@ -285,6 +309,11 @@ static WOLFSSHD_CONFIG* wolfSSHD_ConfigCopy(WOLFSSHD_CONFIG* conf)
newConf->usePrivilegeSeparation = conf->usePrivilegeSeparation;
newConf->permitRootLogin = conf->permitRootLogin;
newConf->permitEmptyPasswords = conf->permitEmptyPasswords;
newConf->authKeysFileSet = conf->authKeysFileSet;
}
else {
wolfSSHD_ConfigFree(newConf);
newConf = NULL;
}
}

Expand All @@ -310,8 +339,12 @@ void wolfSSHD_ConfigFree(WOLFSSHD_CONFIG* conf)
FreeString(&current->listenAddress, heap);
FreeString(&current->authKeysFile, heap);
FreeString(&current->hostKeyFile, heap);
FreeString(&current->hostCertFile, heap);
FreeString(&current->pidFile, heap);
FreeString(&current->hostCertFile, heap);
FreeString(&current->pidFile, heap);
FreeString(&current->userCAKeysFile, heap);
FreeString(&current->forceCmd, heap);
FreeString(&current->usrAppliesTo, heap);
FreeString(&current->groupAppliesTo, heap);

WFREE(current, heap, DYNTYPE_SSHD);
current = next;
Expand Down
167 changes: 166 additions & 1 deletion apps/wolfsshd/test/test_configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,173 @@ static int test_ParseConfigLine(void)
return ret;
}

static int test_ConfigCopy(void)
{
int ret = WS_SUCCESS;
WOLFSSHD_CONFIG* head;
WOLFSSHD_CONFIG* conf;
WOLFSSHD_CONFIG* match;

head = wolfSSHD_ConfigNew(NULL);
if (head == NULL)
ret = WS_MEMORY_E;
conf = head;

/* string fields via ParseConfigLine */
#define PCL(s) ParseConfigLine(&conf, s, (int)WSTRLEN(s))
if (ret == WS_SUCCESS) ret = PCL("Banner /etc/issue");
if (ret == WS_SUCCESS) ret = PCL("ChrootDirectory /var/chroot");
if (ret == WS_SUCCESS) ret = PCL("HostKey /etc/ssh/ssh_host_key");
if (ret == WS_SUCCESS) ret = PCL("ForceCommand /bin/restricted");
if (ret == WS_SUCCESS) ret = PCL("PidFile /var/run/sshd.pid");

/* string fields via public setters */
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetHostCertFile(head, "/etc/ssh/host_cert.pub");
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetUserCAKeysFile(head, "/etc/ssh/ca.pub");
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetAuthKeysFile(head, ".ssh/authorized_keys");

/* scalar fields */
if (ret == WS_SUCCESS) ret = PCL("Port 2222");
if (ret == WS_SUCCESS) ret = PCL("LoginGraceTime 30");
if (ret == WS_SUCCESS) ret = PCL("PasswordAuthentication yes");
if (ret == WS_SUCCESS) ret = PCL("PermitEmptyPasswords yes");
if (ret == WS_SUCCESS) ret = PCL("PermitRootLogin yes");
if (ret == WS_SUCCESS) ret = PCL("UsePrivilegeSeparation yes");

/* trigger ConfigCopy via Match; conf advances to the new node */
if (ret == WS_SUCCESS) ret = PCL("Match User testuser");
#undef PCL

/* retrieve match node from the list head */
if (ret == WS_SUCCESS) {
match = wolfSSHD_GetUserConf(head, "testuser", NULL, NULL, NULL,
NULL, NULL, NULL);
if (match == NULL || match == head)
ret = WS_FATAL_ERROR;
}

/* verify string fields were copied */
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetBanner(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetBanner(match), "/etc/issue") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetChroot(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetChroot(match), "/var/chroot") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetHostKeyFile(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetHostKeyFile(match),
"/etc/ssh/ssh_host_key") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetHostCertFile(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetHostCertFile(match),
"/etc/ssh/host_cert.pub") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetUserCAKeysFile(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetUserCAKeysFile(match),
"/etc/ssh/ca.pub") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetAuthKeysFile(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetAuthKeysFile(match),
".ssh/authorized_keys") != 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetForcedCmd(match) == NULL ||
XSTRCMP(wolfSSHD_ConfigGetForcedCmd(match),
"/bin/restricted") != 0)
ret = WS_FATAL_ERROR;
}

/* verify authKeysFileSet flag was copied */
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetAuthKeysFileSet(match) == 0)
ret = WS_FATAL_ERROR;
}

/* verify scalar fields were copied */
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetPort(match) != 2222)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetGraceTime(match) != 30)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetPwAuth(match) == 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetPermitEmptyPw(match) == 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetPermitRoot(match) == 0)
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSHD_ConfigGetPrivilegeSeparation(match) == 0)
ret = WS_FATAL_ERROR;
}

wolfSSHD_ConfigFree(head);
return ret;
}

/* Verifies ConfigFree releases all string fields — most useful under ASan. */
static int test_ConfigFree(void)
{
int ret = WS_SUCCESS;
WOLFSSHD_CONFIG* head;
WOLFSSHD_CONFIG* conf;

head = wolfSSHD_ConfigNew(NULL);
if (head == NULL)
ret = WS_MEMORY_E;
conf = head;

#define PCL(s) ParseConfigLine(&conf, s, (int)WSTRLEN(s))
if (ret == WS_SUCCESS) ret = PCL("Banner /etc/issue");
if (ret == WS_SUCCESS) ret = PCL("ChrootDirectory /var/chroot");
if (ret == WS_SUCCESS) ret = PCL("HostKey /etc/ssh/ssh_host_key");
if (ret == WS_SUCCESS) ret = PCL("ForceCommand /bin/restricted");
if (ret == WS_SUCCESS) ret = PCL("PidFile /var/run/sshd.pid");
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetHostCertFile(head, "/etc/ssh/host_cert.pub");
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetUserCAKeysFile(head, "/etc/ssh/ca.pub");
if (ret == WS_SUCCESS)
ret = wolfSSHD_ConfigSetAuthKeysFile(head, ".ssh/authorized_keys");

/* Match User — allocates usrAppliesTo on the copied node */
if (ret == WS_SUCCESS) ret = PCL("Match User alice");

/* Match Group — allocates groupAppliesTo on the next copied node */
if (ret == WS_SUCCESS) ret = PCL("Match Group staff");
#undef PCL

/* Free must not crash and must release every allocation */
wolfSSHD_ConfigFree(head);
return ret;
}

const TEST_CASE testCases[] = {
TEST_DECL(test_ParseConfigLine)
TEST_DECL(test_ParseConfigLine),
TEST_DECL(test_ConfigCopy),
TEST_DECL(test_ConfigFree),
};

int main(int argc, char** argv)
Expand Down
Loading