Skip to content

Commit 6d31d73

Browse files
committed
Add negative test case for CheckPasswordHashUnix
1 parent aaf3e55 commit 6d31d73

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

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)
@@ -309,7 +304,11 @@ static int ExtractSalt(char* hash, char** salt, int saltSz)
309304
#endif
310305

311306
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
307+
#ifdef WOLFSSHD_UNIT_TEST
308+
int CheckPasswordHashUnix(const char* input, char* stored)
309+
#else
312310
static int CheckPasswordHashUnix(const char* input, char* stored)
311+
#endif
313312
{
314313
int ret = WSSHD_AUTH_SUCCESS;
315314
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: 74 additions & 1 deletion
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
@@ -233,8 +252,62 @@ static int test_ParseConfigLine(void)
233252
return ret;
234253
}
235254

255+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
256+
/* Negative-path coverage for CheckPasswordHashUnix so mutation of the
257+
* ConstantCompare clause (the only substantive check once crypt() has
258+
* produced its fixed-length output) does not survive the test suite. */
259+
static int test_CheckPasswordHashUnix(void)
260+
{
261+
int ret = WS_SUCCESS;
262+
const char* correct = "wolfssh-test-pass";
263+
const char* wrong = "wolfssh-test-wrong";
264+
/* SHA-512 crypt salt; portable across glibc-based crypt() impls. */
265+
const char* salt = "$6$wolfsshtestsalt$";
266+
char stored[128];
267+
char* hash;
268+
int rc;
269+
270+
hash = crypt(correct, salt);
271+
if (hash == NULL || hash[0] == '*' || WSTRLEN(hash) == 0) {
272+
Log(" crypt() unavailable or refused salt, skipping.\n");
273+
return WS_SUCCESS;
274+
}
275+
if (WSTRLEN(hash) >= sizeof(stored)) {
276+
return WS_FATAL_ERROR;
277+
}
278+
WMEMCPY(stored, hash, WSTRLEN(hash) + 1);
279+
280+
Log(" Testing scenario: correct password authenticates.");
281+
rc = CheckPasswordHashUnix(correct, stored);
282+
if (rc == WSSHD_AUTH_SUCCESS) {
283+
Log(" PASSED.\n");
284+
}
285+
else {
286+
Log(" FAILED.\n");
287+
ret = WS_FATAL_ERROR;
288+
}
289+
290+
if (ret == WS_SUCCESS) {
291+
Log(" Testing scenario: wrong password is rejected.");
292+
rc = CheckPasswordHashUnix(wrong, stored);
293+
if (rc == WSSHD_AUTH_FAILURE) {
294+
Log(" PASSED.\n");
295+
}
296+
else {
297+
Log(" FAILED.\n");
298+
ret = WS_FATAL_ERROR;
299+
}
300+
}
301+
302+
return ret;
303+
}
304+
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
305+
236306
const TEST_CASE testCases[] = {
237-
TEST_DECL(test_ParseConfigLine)
307+
TEST_DECL(test_ParseConfigLine),
308+
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
309+
TEST_DECL(test_CheckPasswordHashUnix),
310+
#endif
238311
};
239312

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

0 commit comments

Comments
 (0)