implement md5 password hashing (untested)

disable test for case-insensitive password test
fix faction/checkpasswd test
This commit is contained in:
Enno Rehling 2016-01-13 14:41:09 +01:00
parent b8a0c61fee
commit 799514bf40
2 changed files with 45 additions and 5 deletions

View File

@ -126,8 +126,8 @@ static void test_check_passwd(CuTest *tc) {
f = test_create_faction(0); f = test_create_faction(0);
faction_setpassword(f, password_hash("password")); faction_setpassword(f, password_hash("password"));
CuAssertIntEquals(tc, true, checkpasswd(f, "password")); CuAssertIntEquals(tc, true, checkpasswd(f, "password"));
CuAssertIntEquals(tc, true, checkpasswd(f, "PASSWORD"));
CuAssertIntEquals(tc, false, checkpasswd(f, "assword")); CuAssertIntEquals(tc, false, checkpasswd(f, "assword"));
CuAssertIntEquals(tc, false, checkpasswd(f, "PASSWORD"));
} }
static void test_get_monsters(CuTest *tc) { static void test_get_monsters(CuTest *tc) {

View File

@ -1,9 +1,12 @@
#include <platform.h> #include <platform.h>
#include "password.h" #include "password.h"
#include <md5.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#define PASSWORD_PLAIN 0 #define PASSWORD_PLAIN 0
#define PASSWORD_MD5 1 #define PASSWORD_MD5 1
@ -11,6 +14,8 @@
#define PASSWORD_BCRYPT 3 // not implemented #define PASSWORD_BCRYPT 3 // not implemented
#define PASSWORD_DEFAULT PASSWORD_PLAIN #define PASSWORD_DEFAULT PASSWORD_PLAIN
#define MAXSALTLEN 32 // maximum length in characters of any salt
static const char * password_hash_i(const char * passwd, const char *salt, int algo) { static const char * password_hash_i(const char * passwd, const char *salt, int algo) {
static char result[64]; // TODO: static result buffers are bad mojo! static char result[64]; // TODO: static result buffers are bad mojo!
assert(passwd); assert(passwd);
@ -18,6 +23,15 @@ static const char * password_hash_i(const char * passwd, const char *salt, int a
if (algo==PASSWORD_PLAIN) { if (algo==PASSWORD_PLAIN) {
_snprintf(result, sizeof(result), "$0$%s$%s", salt, passwd); _snprintf(result, sizeof(result), "$0$%s$%s", salt, passwd);
} }
else if (algo == PASSWORD_MD5) {
md5_state_t ms;
md5_byte_t digest[16];
md5_init(&ms);
md5_append(&ms, (const md5_byte_t *)passwd, strlen(passwd));
md5_append(&ms, (const md5_byte_t *)salt, strlen(salt));
md5_finish(&ms, digest);
_snprintf(result, sizeof(result), "$1$%s$%s", salt, digest); // FIXME: need to build a hex string first!
}
else { else {
return NULL; return NULL;
} }
@ -28,8 +42,34 @@ const char * password_hash(const char * passwd) {
return password_hash_i(passwd, "saltyfish", PASSWORD_DEFAULT); return password_hash_i(passwd, "saltyfish", PASSWORD_DEFAULT);
} }
int password_verify(const char * hash, const char * passwd) { static bool password_is_implemented(int algo) {
assert(hash); return algo==PASSWORD_PLAIN;
assert(passwd); }
return VERIFY_UNKNOWN;
int password_verify(const char * pwhash, const char * passwd) {
char salt[MAXSALTLEN+1];
size_t len;
int algo;
char *pos;
const char *dol, *hash;
assert(pwhash);
assert(passwd);
assert(pwhash[0] == '$');
algo = (int)strtol(pwhash + 1, &pos, 16);
assert(pos[0] == '$');
++pos;
dol = strchr(pos, '$');
assert(dol>pos && dol[0] == '$');
len = dol - pos;
assert(len <= MAXSALTLEN);
strncpy(salt, pos, len);
salt[len] = 0;
hash = password_hash_i(passwd, salt, algo);
if (!password_is_implemented(algo)) {
return VERIFY_UNKNOWN;
}
if (strcmp(pwhash, hash) == 0) {
return VERIFY_OK;
}
return VERIFY_FAIL;
} }