wolfssh/apps/wolfsshd/test/test_configuration.c

259 lines
6.8 KiB
C

#include <stdarg.h>
#include <wolfssh/ssh.h>
#include <configuration.h>
#ifndef WOLFSSH_DEFAULT_LOG_WIDTH
#define WOLFSSH_DEFAULT_LOG_WIDTH 120
#endif
#undef FMTCHECK
#ifdef __GNUC__
#define FMTCHECK __attribute__((format(printf,1,2)))
#else
#define FMTCHECK
#endif /* __GNUC__ */
void Log(const char *const, ...) FMTCHECK;
void Log(const char *const fmt, ...)
{
va_list vlist;
char msgStr[WOLFSSH_DEFAULT_LOG_WIDTH];
va_start(vlist, fmt);
WVSNPRINTF(msgStr, sizeof(msgStr), fmt, vlist);
va_end(vlist);
}
static void CleanupWildcardTest(void)
{
WDIR dir;
struct dirent* d;
char filepath[MAX_PATH*2]; /* d_name is max_path long */
if (!WOPENDIR(NULL, NULL, &dir, "./sshd_config.d/")) {
while ((d = WREADDIR(&dir)) != NULL) {
#if defined(__QNX__) || defined(__QNXNTO__)
struct stat s;
lstat(d->d_name, &s);
if (!S_ISDIR(s.st_mode))
#else
if (d->d_type != DT_DIR)
#endif
{
WSNPRINTF(filepath, sizeof filepath, "%s%s",
"./sshd_config.d/", d->d_name);
WREMOVE(0, filepath);
}
}
WCLOSEDIR(&dir);
WRMDIR(0, "./sshd_config.d/");
}
}
static int SetupWildcardTest(void)
{
WFILE* f;
const byte fileIds[] = { 0, 1, 50, 59, 99 };
word32 fileIdsSz = (word32)(sizeof(fileIds) / sizeof(byte));
word32 i;
int ret;
char filepath[MAX_PATH];
ret = WMKDIR(0, "./sshd_config.d/", 0755);
if (ret == 0) {
for (i = 0; i < fileIdsSz; i++) {
if (fileIds[i] != 0) {
WSNPRINTF(filepath, sizeof filepath, "%s%02u-test.conf",
"./sshd_config.d/", fileIds[i]);
}
else {
WSNPRINTF(filepath, sizeof filepath, "%stest.bad",
"./sshd_config.d/");
}
WFOPEN(&f, filepath, "w");
if (f) {
word32 sz, wr;
char contents[20];
WSNPRINTF(contents, sizeof contents, "LoginGraceTime %02u",
fileIds[i]);
sz = (word32)WSTRLEN(contents);
wr = (word32)WFWRITE(contents, sizeof(char), sz, f);
WFCLOSE(f);
if (sz != wr) {
Log("Couldn't write the contents of file %s\n", filepath);
ret = WS_FATAL_ERROR;
break;
}
}
else {
Log("Couldn't create the file %s\n", filepath);
ret = WS_FATAL_ERROR;
break;
}
}
}
else {
Log("Couldn't make the test config directory\n");
ret = WS_FATAL_ERROR;
}
return ret;
}
typedef int (*TEST_FUNC)(void);
typedef struct {
const char *name;
TEST_FUNC func;
} TEST_CASE;
#define TEST_DECL(func) { #func, func }
#define TEST_CASE_CNT (int)(sizeof(testCases) / sizeof(*testCases))
static void TestSetup(const TEST_CASE* tc)
{
Log("Running %s.\n", tc->name);
}
static void TestCleanup(void)
{
}
static int RunTest(const TEST_CASE* tc)
{
int ret;
TestSetup(tc);
ret = tc->func();
if (ret != 0) {
Log("%s FAILED.\n", tc->name);
}
else {
Log("%s PASSED.\n", tc->name);
}
TestCleanup();
return ret;
}
typedef struct {
const char* desc;
const char* line;
int shouldFail;
} CONFIG_LINE_VECTOR;
static int test_ParseConfigLine(void)
{
int ret = WS_SUCCESS;
int i;
WOLFSSHD_CONFIG* conf;
static CONFIG_LINE_VECTOR vectors[] = {
/* Port tests. */
{"Valid port", "Port 22", 0},
{"Port too big", "Port 65536", 1},
{"Negative port", "Port -99", 1},
{"Port 0", "Port 0", 1},
{"Port NaN", "Port wolfsshd", 1},
{"Port no value", "Port \n", 1},
/* Whitespace tests. */
{"Extra leading whitespace", "Port 22", 0},
{"Extra trailing whitespace", "Port 22 \n", 0},
/* Privilege separation tests. */
{"Privilege separation yes", "UsePrivilegeSeparation yes", 0},
{"Privilege separation no", "UsePrivilegeSeparation no", 0},
{"Privilege separation sandbox", "UsePrivilegeSeparation sandbox", 0},
{"Privilege separation invalid", "UsePrivilegeSeparation wolfsshd", 1},
/* Login grace time tests. */
{"Valid login grace time seconds", "LoginGraceTime 60", 0},
{"Valid login grace time minutes", "LoginGraceTime 1m", 0},
{"Valid login grace time hours", "LoginGraceTime 1h", 0},
{"Invalid login grace time", "LoginGraceTime wolfsshd", 1},
/* Permit empty password tests. */
{"Permit empty password no", "PermitEmptyPasswords no", 0},
{"Permit empty password yes", "PermitEmptyPasswords yes", 0},
{"Permit empty password invalid", "PermitEmptyPasswords wolfsshd", 1},
/* Password auth tests. */
{"Password auth no", "PasswordAuthentication no", 0},
{"Password auth yes", "PasswordAuthentication yes", 0},
{"Password auth invalid", "PasswordAuthentication wolfsshd", 1},
/* Include files tests. */
{"Include file bad", "Include sshd_config.d/test.bad", 1},
{"Include file exists", "Include sshd_config.d/01-test.conf", 0},
{"Include file DNE", "Include sshd_config.d/test-dne.conf", 1},
{"Include wildcard exists", "Include sshd_config.d/*.conf", 0},
{"Include wildcard NDE", "Include sshd_config.d/*.dne", 0},
};
const int numVectors = (int)(sizeof(vectors) / sizeof(*vectors));
conf = wolfSSHD_ConfigNew(NULL);
if (conf == NULL) {
ret = WS_MEMORY_E;
}
if (ret == WS_SUCCESS) {
for (i = 0; i < numVectors; ++i) {
Log(" Testing scenario: %s.", vectors[i].desc);
ret = ParseConfigLine(&conf, vectors[i].line,
(int)WSTRLEN(vectors[i].line));
if ((ret == WS_SUCCESS && !vectors[i].shouldFail) ||
(ret != WS_SUCCESS && vectors[i].shouldFail)) {
Log(" PASSED.\n");
ret = WS_SUCCESS;
}
else {
Log(" FAILED.\n");
ret = WS_FATAL_ERROR;
break;
}
}
wolfSSHD_ConfigFree(conf);
}
return ret;
}
const TEST_CASE testCases[] = {
TEST_DECL(test_ParseConfigLine)
};
int main(int argc, char** argv)
{
int i;
int ret = WS_SUCCESS;
(void)argc;
(void)argv;
CleanupWildcardTest();
ret = SetupWildcardTest();
if (ret == 0) {
for (i = 0; i < TEST_CASE_CNT; ++i) {
ret = RunTest(&testCases[i]);
if (ret != WS_SUCCESS) {
break;
}
}
}
CleanupWildcardTest();
return ret;
}