Merge pull request #914 from padelsbach/negative-test-cases

Add negative test case for CheckPasswordHashUnix
pull/939/head
John Safranek 2026-04-20 11:26:04 -07:00 committed by GitHub
commit 2568b26b84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 88 additions and 5 deletions

View File

@ -151,11 +151,6 @@ USER_NODE* AddNewUser(USER_NODE* list, byte type, const byte* username,
}
#endif
enum {
WSSHD_AUTH_FAILURE = 0,
WSSHD_AUTH_SUCCESS = 1
};
/* TODO: Can use wolfSSH_ReadKey_buffer? */
static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
word32 keySz)
@ -312,7 +307,11 @@ static int ExtractSalt(char* hash, char** salt, int saltSz)
#endif
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
#ifdef WOLFSSHD_UNIT_TEST
int CheckPasswordHashUnix(const char* input, char* stored)
#else
static int CheckPasswordHashUnix(const char* input, char* stored)
#endif
{
int ret = WSSHD_AUTH_SUCCESS;
char* hashedInput;

View File

@ -34,6 +34,11 @@ int DefaultUserAuthTypes(WOLFSSH* ssh, void* ctx);
typedef struct WOLFSSHD_AUTH WOLFSSHD_AUTH;
enum {
WSSHD_AUTH_FAILURE = 0,
WSSHD_AUTH_SUCCESS = 1
};
/*
* Returns WSSHD_AUTH_SUCCESS if user found, WSSHD_AUTH_FAILURE if user not
* found, and negative values if an error occurs during checking.
@ -73,4 +78,10 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
HANDLE wolfSSHD_GetAuthToken(const WOLFSSHD_AUTH* auth);
int wolfSSHD_GetHomeDirectory(WOLFSSHD_AUTH* auth, WOLFSSH* ssh, WCHAR* out, int outSz);
#endif
#ifdef WOLFSSHD_UNIT_TEST
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
int CheckPasswordHashUnix(const char* input, char* stored);
#endif
#endif
#endif /* WOLFAUTH_H */

View File

@ -1,7 +1,26 @@
/* Match auth.c's feature-test macros so crypt() is declared and so the
* pre-existing CleanupWildcardTest code keeps seeing DT_DIR. Must come
* before any system header is pulled in. */
#ifdef __linux__
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#include <stdarg.h>
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
#include <unistd.h>
#endif
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#include <wolfssh/ssh.h>
#include <configuration.h>
#include <auth.h>
#ifndef WOLFSSH_DEFAULT_LOG_WIDTH
#define WOLFSSH_DEFAULT_LOG_WIDTH 120
@ -396,10 +415,64 @@ static int test_ConfigFree(void)
return ret;
}
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
/* Negative-path coverage for CheckPasswordHashUnix so mutation of the
* ConstantCompare clause (the only substantive check once crypt() has
* produced its fixed-length output) does not survive the test suite. */
static int test_CheckPasswordHashUnix(void)
{
int ret = WS_SUCCESS;
const char* correct = "wolfssh-test-pass";
const char* wrong = "wolfssh-test-wrong";
/* SHA-512 crypt salt; portable across glibc-based crypt() impls. */
const char* salt = "$6$wolfsshtestsalt$";
char stored[128];
char* hash;
int rc;
hash = crypt(correct, salt);
if (hash == NULL || hash[0] == '*' || WSTRLEN(hash) == 0) {
Log(" crypt() unavailable or refused salt, skipping.\n");
return WS_SUCCESS;
}
if (WSTRLEN(hash) >= sizeof(stored)) {
return WS_FATAL_ERROR;
}
WMEMCPY(stored, hash, WSTRLEN(hash) + 1);
Log(" Testing scenario: correct password authenticates.");
rc = CheckPasswordHashUnix(correct, stored);
if (rc == WSSHD_AUTH_SUCCESS) {
Log(" PASSED.\n");
}
else {
Log(" FAILED.\n");
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
Log(" Testing scenario: wrong password is rejected.");
rc = CheckPasswordHashUnix(wrong, stored);
if (rc == WSSHD_AUTH_FAILURE) {
Log(" PASSED.\n");
}
else {
Log(" FAILED.\n");
ret = WS_FATAL_ERROR;
}
}
return ret;
}
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
const TEST_CASE testCases[] = {
TEST_DECL(test_ParseConfigLine),
TEST_DECL(test_ConfigCopy),
TEST_DECL(test_ConfigFree),
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
TEST_DECL(test_CheckPasswordHashUnix),
#endif
};
int main(int argc, char** argv)