implement MD5 crypted passwords as default

This commit is contained in:
Enno Rehling 2016-01-14 15:49:09 +01:00
parent 3a8a05380b
commit 8d05f4cc25
9 changed files with 26 additions and 24 deletions

2
crypto

@ -1 +1 @@
Subproject commit 166fdc8c146755055217070c58079ba9a7c03369 Subproject commit c2a682476a96cdff972ac2b64051f61edf76064e

View file

@ -386,7 +386,7 @@ static int tolua_faction_set_password(lua_State * L)
{ {
faction *self = (faction *)tolua_tousertype(L, 1, 0); faction *self = (faction *)tolua_tousertype(L, 1, 0);
const char * passw = tolua_tostring(L, 2, 0); const char * passw = tolua_tostring(L, 2, 0);
faction_setpassword(self, password_hash(passw, PASSWORD_DEFAULT)); faction_setpassword(self, password_hash(passw, 0, PASSWORD_DEFAULT));
return 0; return 0;
} }

View file

@ -253,7 +253,7 @@ faction *addfaction(const char *email, const char *password,
} }
if (!password) password = itoa36(rng_int()); if (!password) password = itoa36(rng_int());
faction_setpassword(f, password_hash(password, PASSWORD_DEFAULT)); faction_setpassword(f, password_hash(password, 0, PASSWORD_DEFAULT));
ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); ADDMSG(&f->msgs, msg_message("changepasswd", "value", password));
f->alliance_joindate = turn; f->alliance_joindate = turn;

View file

@ -124,7 +124,7 @@ static void test_check_passwd(CuTest *tc) {
faction *f; faction *f;
f = test_create_faction(0); f = test_create_faction(0);
faction_setpassword(f, password_hash("password", PASSWORD_DEFAULT)); faction_setpassword(f, password_hash("password", 0, PASSWORD_DEFAULT));
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")); CuAssertIntEquals(tc, false, checkpasswd(f, "PASSWORD"));

View file

@ -1217,7 +1217,7 @@ faction *readfaction(struct gamedata * data)
} }
READ_STR(data->store, name, sizeof(name)); READ_STR(data->store, name, sizeof(name));
faction_setpassword(f, (data->version >= CRYPT_VERSION) ? name : password_hash(name, PASSWORD_DEFAULT)); faction_setpassword(f, (data->version >= CRYPT_VERSION) ? name : password_hash(name, 0, PASSWORD_DEFAULT));
if (data->version < NOOVERRIDE_VERSION) { if (data->version < NOOVERRIDE_VERSION) {
READ_STR(data->store, 0, 0); READ_STR(data->store, 0, 0);
} }

View file

@ -2170,7 +2170,7 @@ int password_cmd(unit * u, struct order *ord)
cmistake(u, ord, 283, MSG_EVENT); cmistake(u, ord, 283, MSG_EVENT);
strlcpy(pwbuf, itoa36(rng_int()), sizeof(pwbuf)); strlcpy(pwbuf, itoa36(rng_int()), sizeof(pwbuf));
} }
faction_setpassword(u->faction, password_hash(pwbuf, PASSWORD_DEFAULT)); faction_setpassword(u->faction, password_hash(pwbuf, 0, PASSWORD_DEFAULT));
ADDMSG(&u->faction->msgs, msg_message("changepasswd", ADDMSG(&u->faction->msgs, msg_message("changepasswd",
"value", pwbuf)); "value", pwbuf));
return 0; return 0;

View file

@ -16,13 +16,9 @@ static const char * password_hash_i(const char * passwd, const char *salt, int a
_snprintf(result, len, "$0$%s$%s", salt, passwd); _snprintf(result, len, "$0$%s$%s", salt, passwd);
} }
else if (algo == PASSWORD_MD5) { else if (algo == PASSWORD_MD5) {
md5_state_t ms; char * result = md5_crypt(passwd, salt);
md5_byte_t digest[16]; return result;
md5_init(&ms); // _snprintf(result, len, "$1$%s$%s", salt, digest); // FIXME: need to build a hex string first!
md5_append(&ms, (const md5_byte_t *)passwd, (int)strlen(passwd));
md5_append(&ms, (const md5_byte_t *)salt, (int)strlen(salt));
md5_finish(&ms, digest);
_snprintf(result, len, "$1$%s$%s", salt, digest); // FIXME: need to build a hex string first!
} }
else { else {
return NULL; return NULL;
@ -30,10 +26,11 @@ static const char * password_hash_i(const char * passwd, const char *salt, int a
return result; return result;
} }
const char * password_hash(const char * passwd, int algo) { const char * password_hash(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!
if (!salt) salt = "saltyass"; // FIXME: generate a secure salt!
if (algo < 0) algo = PASSWORD_DEFAULT; if (algo < 0) algo = PASSWORD_DEFAULT;
return password_hash_i(passwd, "saltyfish", PASSWORD_DEFAULT, result, sizeof(result)); return password_hash_i(passwd, salt, algo, result, sizeof(result));
} }
static bool password_is_implemented(int algo) { static bool password_is_implemented(int algo) {
@ -46,9 +43,9 @@ int password_verify(const char * pwhash, const char * passwd) {
size_t len; size_t len;
int algo; int algo;
char *pos; char *pos;
const char *dol; const char *dol, *result;
assert(pwhash);
assert(passwd); assert(passwd);
assert(pwhash);
assert(pwhash[0] == '$'); assert(pwhash[0] == '$');
algo = pwhash[1] - '0'; algo = pwhash[1] - '0';
pos = strchr(pwhash+2, '$'); pos = strchr(pwhash+2, '$');
@ -60,11 +57,11 @@ int password_verify(const char * pwhash, const char * passwd) {
assert(len <= MAXSALTLEN); assert(len <= MAXSALTLEN);
strncpy(salt, pos, len); strncpy(salt, pos, len);
salt[len] = 0; salt[len] = 0;
password_hash_i(passwd, salt, algo, hash, sizeof(hash)); result = password_hash_i(passwd, salt, algo, hash, sizeof(hash));
if (!password_is_implemented(algo)) { if (!password_is_implemented(algo)) {
return VERIFY_UNKNOWN; return VERIFY_UNKNOWN;
} }
if (strcmp(pwhash, hash) == 0) { if (strcmp(pwhash, result) == 0) {
return VERIFY_OK; return VERIFY_OK;
} }
return VERIFY_FAIL; return VERIFY_FAIL;

View file

@ -5,11 +5,11 @@
#define PASSWORD_BCRYPT 2 // not implemented #define PASSWORD_BCRYPT 2 // not implemented
#define PASSWORD_SHA256 5 // not implemented #define PASSWORD_SHA256 5 // not implemented
#define PASSWORD_SHA512 6 // not implemented #define PASSWORD_SHA512 6 // not implemented
#define PASSWORD_DEFAULT PASSWORD_PLAIN #define PASSWORD_DEFAULT PASSWORD_MD5
#define VERIFY_OK 0 // password matches hash #define VERIFY_OK 0 // password matches hash
#define VERIFY_FAIL 1 // password is wrong #define VERIFY_FAIL 1 // password is wrong
#define VERIFY_UNKNOWN 2 // hashing algorithm not supported #define VERIFY_UNKNOWN 2 // hashing algorithm not supported
int password_verify(const char * hash, const char * passwd); int password_verify(const char *hash, const char *passwd);
const char * password_hash(const char * passwd, int algo); const char * password_hash(const char *passwd, const char *salt, int algo);

View file

@ -5,9 +5,14 @@
static void test_passwords(CuTest *tc) { static void test_passwords(CuTest *tc) {
const char *hash; const char *hash;
hash = password_hash("password", PASSWORD_PLAIN); hash = password_hash("jollygood", "ZouUn04i", PASSWORD_MD5);
CuAssertPtrNotNull(tc, hash); CuAssertPtrNotNull(tc, hash);
CuAssertStrEquals(tc, "$0$saltyfish$password", hash); CuAssertStrEquals(tc, "$1$ZouUn04i$yNnT1Oy8azJ5V.UM9ppP5/", hash);
CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "jollygood"));
hash = password_hash("password", "hodor", PASSWORD_PLAIN);
CuAssertPtrNotNull(tc, hash);
CuAssertStrEquals(tc, "$0$hodor$password", hash);
CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password")); CuAssertIntEquals(tc, VERIFY_OK, password_verify(hash, "password"));
CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword")); CuAssertIntEquals(tc, VERIFY_FAIL, password_verify(hash, "arseword"));
CuAssertIntEquals(tc, VERIFY_UNKNOWN, password_verify("$9$saltyfish$password", "password")); CuAssertIntEquals(tc, VERIFY_UNKNOWN, password_verify("$9$saltyfish$password", "password"));