Skip to content

Commit 2568b26

Browse files
authored
Merge pull request #914 from padelsbach/negative-test-cases
Add negative test case for CheckPasswordHashUnix
2 parents 8efa825 + 80da96e commit 2568b26

3 files changed

Lines changed: 88 additions & 5 deletions

File tree

apps/wolfsshd/auth.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,6 @@ USER_NODE* AddNewUser(USER_NODE* list, byte type, const byte* username,
151151
}
152152
#endif
153153

154-
enum {
155-
WSSHD_AUTH_FAILURE = 0,
156-
WSSHD_AUTH_SUCCESS = 1
157-
};
158-
159154
/* TODO: Can use wolfSSH_ReadKey_buffer? */
160155
static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
161156
word32 keySz)
@@ -312,7 +307,11 @@ static int ExtractSalt(char* hash, char** salt, int saltSz)
312307
#endif
313308

314309
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
310+
#ifdef WOLFSSHD_UNIT_TEST
311+
int CheckPasswordHashUnix(const char* input, char* stored)
312+
#else
315313
static int CheckPasswordHashUnix(const char* input, char* stored)
314+
#endif
316315
{
317316
int ret = WSSHD_AUTH_SUCCESS;
318317
char* hashedInput;

apps/wolfsshd/auth.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ int DefaultUserAuthTypes(WOLFSSH* ssh, void* ctx);
3434

3535
typedef struct WOLFSSHD_AUTH WOLFSSHD_AUTH;
3636

37+
enum {
38+
WSSHD_AUTH_FAILURE = 0,
39+
WSSHD_AUTH_SUCCESS = 1
40+
};
41+
3742
/*
3843
* Returns WSSHD_AUTH_SUCCESS if user found, WSSHD_AUTH_FAILURE if user not
3944
* found, and negative values if an error occurs during checking.
@@ -73,4 +78,10 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
7378
HANDLE wolfSSHD_GetAuthToken(const WOLFSSHD_AUTH* auth);
7479
int wolfSSHD_GetHomeDirectory(WOLFSSHD_AUTH* auth, WOLFSSH* ssh, WCHAR* out, int outSz);
7580
#endif
81+
82+
#ifdef WOLFSSHD_UNIT_TEST
83+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
84+
int CheckPasswordHashUnix(const char* input, char* stored);
85+
#endif
86+
#endif
7687
#endif /* WOLFAUTH_H */

apps/wolfsshd/test/test_configuration.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1+
/* Match auth.c's feature-test macros so crypt() is declared and so the
2+
* pre-existing CleanupWildcardTest code keeps seeing DT_DIR. Must come
3+
* before any system header is pulled in. */
4+
#ifdef __linux__
5+
#ifndef _XOPEN_SOURCE
6+
#define _XOPEN_SOURCE
7+
#endif
8+
#ifndef _GNU_SOURCE
9+
#define _GNU_SOURCE
10+
#endif
11+
#endif
12+
113
#include <stdarg.h>
14+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
15+
#include <unistd.h>
16+
#endif
17+
#ifdef HAVE_CRYPT_H
18+
#include <crypt.h>
19+
#endif
220

321
#include <wolfssh/ssh.h>
422
#include <configuration.h>
23+
#include <auth.h>
524

625
#ifndef WOLFSSH_DEFAULT_LOG_WIDTH
726
#define WOLFSSH_DEFAULT_LOG_WIDTH 120
@@ -396,10 +415,64 @@ static int test_ConfigFree(void)
396415
return ret;
397416
}
398417

418+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
419+
/* Negative-path coverage for CheckPasswordHashUnix so mutation of the
420+
* ConstantCompare clause (the only substantive check once crypt() has
421+
* produced its fixed-length output) does not survive the test suite. */
422+
static int test_CheckPasswordHashUnix(void)
423+
{
424+
int ret = WS_SUCCESS;
425+
const char* correct = "wolfssh-test-pass";
426+
const char* wrong = "wolfssh-test-wrong";
427+
/* SHA-512 crypt salt; portable across glibc-based crypt() impls. */
428+
const char* salt = "$6$wolfsshtestsalt$";
429+
char stored[128];
430+
char* hash;
431+
int rc;
432+
433+
hash = crypt(correct, salt);
434+
if (hash == NULL || hash[0] == '*' || WSTRLEN(hash) == 0) {
435+
Log(" crypt() unavailable or refused salt, skipping.\n");
436+
return WS_SUCCESS;
437+
}
438+
if (WSTRLEN(hash) >= sizeof(stored)) {
439+
return WS_FATAL_ERROR;
440+
}
441+
WMEMCPY(stored, hash, WSTRLEN(hash) + 1);
442+
443+
Log(" Testing scenario: correct password authenticates.");
444+
rc = CheckPasswordHashUnix(correct, stored);
445+
if (rc == WSSHD_AUTH_SUCCESS) {
446+
Log(" PASSED.\n");
447+
}
448+
else {
449+
Log(" FAILED.\n");
450+
ret = WS_FATAL_ERROR;
451+
}
452+
453+
if (ret == WS_SUCCESS) {
454+
Log(" Testing scenario: wrong password is rejected.");
455+
rc = CheckPasswordHashUnix(wrong, stored);
456+
if (rc == WSSHD_AUTH_FAILURE) {
457+
Log(" PASSED.\n");
458+
}
459+
else {
460+
Log(" FAILED.\n");
461+
ret = WS_FATAL_ERROR;
462+
}
463+
}
464+
465+
return ret;
466+
}
467+
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
468+
399469
const TEST_CASE testCases[] = {
400470
TEST_DECL(test_ParseConfigLine),
401471
TEST_DECL(test_ConfigCopy),
402472
TEST_DECL(test_ConfigFree),
473+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
474+
TEST_DECL(test_CheckPasswordHashUnix),
475+
#endif
403476
};
404477

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

0 commit comments

Comments
 (0)