From 9bf7e921e7807def51f32ff48ad6920618735a8d Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sun, 6 Feb 2022 01:15:11 -0300 Subject: All new accounts will now have their passwords stored in SHA256. Supersedes all previous authentication methods, except VAULT TOKEN. This is done on registration and when changing password. --- configure.ac | 20 ++++++++++++++++++++ src/elogin/login.c | 9 ++++++++- src/elogin/md5calc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/elogin/md5calc.h | 2 ++ src/elogin/parse.c | 17 ++++++++++------- 5 files changed, 90 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index ef4e156..8a89d54 100644 --- a/configure.ac +++ b/configure.ac @@ -330,4 +330,24 @@ AC_MSG_CHECKING([PCRE library]) AC_CHECK_HEADER([pcre.h], [], [AC_MSG_ERROR([PCRE header not found])]) AC_SEARCH_LIBS([pcre_study], [pcre], [], AC_MSG_ERROR([PCRE not found or incompatible])) +# +# OpenSSL library +# + +AC_MSG_CHECKING([OpenSSL library]) +dnl Order matters! +if test "$PORTNAME" != "win32"; then + AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) + FOUND_SSL_LIB="no" + AC_CHECK_LIB(ssl, OPENSSL_init_ssl, [FOUND_SSL_LIB="yes"]) + AC_CHECK_LIB(ssl, SSL_library_init, [FOUND_SSL_LIB="yes"]) + AS_IF([test "x$FOUND_SSL_LIB" = xno], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) +else + AC_SEARCH_LIBS(CRYPTO_new_ex_data, eay32 crypto, [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])]) + FOUND_SSL_LIB="no" + AC_SEARCH_LIBS(OPENSSL_init_ssl, ssleay32 ssl, [FOUND_SSL_LIB="yes"]) + AC_SEARCH_LIBS(SSL_library_init, ssleay32 ssl, [FOUND_SSL_LIB="yes"]) + AS_IF([test "x$FOUND_SSL_LIB" = xno], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])]) +fi + AC_OUTPUT(Makefile src/Makefile) diff --git a/src/elogin/login.c b/src/elogin/login.c index 854ba97..d7074ca 100644 --- a/src/elogin/login.c +++ b/src/elogin/login.c @@ -24,7 +24,8 @@ bool elogin_check_password_pre(const char **md5key __attribute__ ((unused)), const char **refpassPtr) { if (!strcmp(*passwdPtr, *refpassPtr) || - pass_ok(*passwdPtr, *refpassPtr)) + pass_ok(*passwdPtr, *refpassPtr) || + pass_sha256(*passwdPtr, *refpassPtr)) { hookStop(); return 1; @@ -33,3 +34,9 @@ bool elogin_check_password_pre(const char **md5key __attribute__ ((unused)), hookStop(); return 0; } + +// For new accounts (currently saved in plain text): +// Intercept: account.c account_db_sql_create +// Set acc->pass to hashed version + + diff --git a/src/elogin/md5calc.c b/src/elogin/md5calc.c index d5dbed3..a0d58e3 100644 --- a/src/elogin/md5calc.c +++ b/src/elogin/md5calc.c @@ -11,6 +11,8 @@ #include #include #include "mt_rand.h" +#include "common/memmgr.h" +#include #ifndef UINT_MAX #define UINT_MAX 4294967295U @@ -365,6 +367,54 @@ int pass_ok(const char *password, const char *crypted) return(0); } +/*******************************************************************************/ +// SHA256 wrappers [TMW2] +void sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65]) +{ + int i = 0; + + for(i = 0; i < SHA256_DIGEST_LENGTH; i++) + { + sprintf(outputBuffer + (i * 2), "%02x", hash[i]); + } + + outputBuffer[64] = 0; +} + +void sha256 (const char* message, char* outputBuffer) +{ + unsigned char obuf[SHA256_DIGEST_LENGTH]; + SHA256((const unsigned char*)(message), strlen(message), obuf); + sha256_hash_string(obuf, outputBuffer); +} + +// Hash a password with a salt. +char *SHA256_CRYPT(const char *key) +{ + char *md5str; + md5str = (char *)aMalloc((64+1)*sizeof(char)); + sha256(key, md5str); + + return(md5str); +} + +/*******************************************************************************/ + +int pass_sha256(const char *password, const char *crypted) +{ + if (!password || !crypted) + return 0; + + char *md5str; + md5str = (char *)aMalloc((64+1)*sizeof(char)); + sha256(password, md5str); + + if (!strcmp(crypted, md5str)) + return(1); + + return(0); +} + // [M|h]ashes up an IP address and a secret key // to return a hopefully unique masked IP. in_addr_t MD5_ip(char *secret, in_addr_t ip) diff --git a/src/elogin/md5calc.h b/src/elogin/md5calc.h index cf82738..d3db357 100644 --- a/src/elogin/md5calc.h +++ b/src/elogin/md5calc.h @@ -7,7 +7,9 @@ void MD5_String (const char *string, char *output); void MD5_String2binary (const char *string, char *output); char *MD5_saltcrypt(const char *key, const char *salt); char *make_salt(void); +char *SHA256_CRYPT(const char *key); int pass_ok(const char *password, const char *crypted); +int pass_sha256(const char *password, const char *crypted); in_addr_t MD5_ip(char *secret, in_addr_t ip); #endif diff --git a/src/elogin/parse.c b/src/elogin/parse.c index 73e1ab1..2eb71f5 100644 --- a/src/elogin/parse.c +++ b/src/elogin/parse.c @@ -185,15 +185,15 @@ enum parsefunc_rcode elogin_parse_ping_pre(int *fd __attribute__ ((unused)), void elogin_parse_change_paassword(int fd) { - char actual_pass[24], new_pass[24]; + char actual_pass[65], new_pass[65]; int status = 0; struct mmo_account acc; const int accountId = RFIFOL (fd, 2); - memcpy (actual_pass, RFIFOP (fd, 6), 24); - actual_pass[23] = '\0'; - memcpy (new_pass, RFIFOP (fd, 30), 24); - new_pass[23] = '\0'; + memcpy (actual_pass, RFIFOP (fd, 6), 65); + actual_pass[64] = '\0'; + memcpy (new_pass, RFIFOP (fd, 30), 65); + new_pass[64] = '\0'; if (!login->accounts->load_num(login->accounts, &acc, accountId)) { @@ -202,12 +202,15 @@ void elogin_parse_change_paassword(int fd) return; } - if (!strcmp(actual_pass, acc.pass) || pass_ok(actual_pass, acc.pass)) + if (!strcmp(actual_pass, acc.pass) || + pass_ok(actual_pass, acc.pass) || + pass_sha256(actual_pass, acc.pass)) { // changed ok status = 1; // Hash password - safestrncpy(acc.pass, MD5_saltcrypt(new_pass, make_salt()), sizeof(acc.pass)); + //safestrncpy(acc.pass, MD5_saltcrypt(new_pass, make_salt()), sizeof(acc.pass)); + safestrncpy(acc.pass, SHA256_CRYPT(new_pass), sizeof(acc.pass)); login->accounts->save(login->accounts, &acc); } else -- cgit v1.2.3-60-g2f50