summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMadCamel <madcamel@gmail.com>2010-01-26 18:44:06 -0500
committerMadCamel <madcamel@gmail.com>2010-01-26 18:44:06 -0500
commite6fabf4ccdf96658e5952c5a597bb68b0b801741 (patch)
tree2c829554463cb4ec6f269a4bdd7361919ec24319 /src
parentabe96e3b05a99a984d6f00098f1aa9759814b542 (diff)
downloadtmwa-e6fabf4ccdf96658e5952c5a597bb68b0b801741.tar.gz
tmwa-e6fabf4ccdf96658e5952c5a597bb68b0b801741.tar.bz2
tmwa-e6fabf4ccdf96658e5952c5a597bb68b0b801741.tar.xz
tmwa-e6fabf4ccdf96658e5952c5a597bb68b0b801741.zip
Added password encryption to the accounts database, removed logging of plaintext passwords
Will auto-convert accounts DB to new format.
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c15
-rw-r--r--src/ladmin/md5calc.c42
-rw-r--r--src/ladmin/md5calc.h5
-rw-r--r--src/login/login.c105
-rw-r--r--src/login/login.h3
-rw-r--r--src/login/md5calc.c40
-rw-r--r--src/login/md5calc.h3
7 files changed, 144 insertions, 69 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 3755d1f..2b25399 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -16,7 +16,6 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <stdarg.h>
-#include <sys/wait.h>
#include "core.h"
#include "socket.h"
@@ -115,8 +114,6 @@ int online_gm_display_min_level = 20; // minimum GM level to display 'GM' when
int *online_chars; // same size of char_dat, and id value of current server (or -1)
time_t update_online; // to update online files when we receiving information from a server (not less than 8 seconds)
-pid_t pid = 0; // For forked DB writes
-
//------------------------------
// Writing function of logs file
//------------------------------
@@ -831,17 +828,7 @@ void mmo_char_sync (void)
//----------------------------------------------------
int mmo_char_sync_timer (int tid, unsigned int tick, int id, int data)
{
- if (pid != 0)
- {
- int status;
- pid_t temp = waitpid (pid, &status, WNOHANG);
-
- // Need to check status too?
- if (temp == 0)
- {
- return 0;
- }
- }
+ pid_t pid;
// This can take a lot of time. Fork a child to handle the work and return at once
// If we're unable to fork just continue running the function normally
diff --git a/src/ladmin/md5calc.c b/src/ladmin/md5calc.c
index 49a4aaa..cf9d958 100644
--- a/src/ladmin/md5calc.c
+++ b/src/ladmin/md5calc.c
@@ -1,4 +1,4 @@
-// $Id: md5calc.c,v 1.1.1.1 2004/09/10 17:26:53 MagicalTux Exp $
+// $Id: md5calc.c,v 1.1.1.1 2004/09/10 17:26:54 MagicalTux Exp $
/***********************************************************
* md5 calculation algorithm
*
@@ -10,6 +10,7 @@
#include "md5calc.h"
#include <string.h>
#include <stdio.h>
+#include "mt_rand.h"
#ifndef UINT_MAX
#define UINT_MAX 4294967295U
@@ -291,3 +292,42 @@ void MD5_String (const char *string, char *output)
digest[8], digest[9], digest[10], digest[11],
digest[12], digest[13], digest[14], digest[15]);
}
+
+// Hash a password with a salt.
+char *MD5_saltcrypt(const char *key, const char *salt)
+{
+ char buf[66], *sbuf = buf+32;
+ static char obuf[33];
+
+ // hash the key then the salt
+ // buf ends up as a 64char null terminated string
+ MD5_String(key, buf);
+ MD5_String(salt, sbuf);
+
+ // Hash the buffer back into sbuf
+ MD5_String(buf, sbuf);
+
+ snprintf(obuf, 32, "!%s$%s", salt, sbuf);
+ return(obuf);
+}
+
+char *make_salt() {
+ static char salt[6];
+ int i;
+ for (i=0; i<5; i++)
+ salt[i] = (char)((mt_rand() % 78) + 48);
+ salt[5] = '\0';
+ return(salt);
+}
+
+int pass_ok(const char *password, const char *crypted) {
+ char buf[40], *salt=buf+1;
+
+ strncpy(buf, crypted, 40);
+ *strchr(buf, '$') = '\0';
+
+ if (!strcmp(crypted, MD5_saltcrypt(password, salt)))
+ return(1);
+
+ return(0);
+}
diff --git a/src/ladmin/md5calc.h b/src/ladmin/md5calc.h
index ddf176c..3571466 100644
--- a/src/ladmin/md5calc.h
+++ b/src/ladmin/md5calc.h
@@ -1,8 +1,11 @@
-// $Id: md5calc.h,v 1.1.1.1 2004/09/10 17:26:53 MagicalTux Exp $
+// $Id: md5calc.h,v 1.1.1.1 2004/09/10 17:26:54 MagicalTux Exp $
#ifndef _MD5CALC_H_
#define _MD5CALC_H_
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();
+int pass_ok(const char *password, const char *crypted);
#endif
diff --git a/src/login/login.c b/src/login/login.c
index 47b0967..5298bed 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -27,9 +27,7 @@
#include "lock.h"
#include "mt_rand.h"
-#ifdef PASSWORDENC
#include "md5calc.h"
-#endif
#ifdef MEMWATCH
#include "memwatch.h"
@@ -106,7 +104,7 @@ int auth_fifo_pos = 0;
struct auth_dat
{
int account_id, sex;
- char userid[24], pass[24], lastlogin[24];
+ char userid[24], pass[40], lastlogin[24];
int logincount;
int state; // packet 0x006a value + 1 (0: compte OK)
char email[40]; // e-mail (by default: a@a.com)
@@ -667,9 +665,21 @@ int mmo_auth_init (void)
strncpy (auth_dat[auth_num].userid, userid, 24);
- pass[23] = '\0';
+ memo[254] = '\0';
+ remove_control_chars (memo);
+ strncpy (auth_dat[auth_num].memo, memo, 255);
+
+ pass[39] = '\0';
remove_control_chars (pass);
- strncpy (auth_dat[auth_num].pass, pass, 24);
+ // If a password is not encrypted, we encrypt it now.
+ // A password beginning with ! and - in the memo field is our magic
+ if (pass[0] != '!' && memo[0] == '-') {
+ strcpy(auth_dat[auth_num].pass, MD5_saltcrypt(pass, make_salt()));
+ auth_dat[auth_num].memo[0] = '!';
+ printf("encrypting pass: %s %s\n", pass, auth_dat[auth_num].pass);
+ }
+ else
+ strcpy(auth_dat[auth_num].pass, pass);
lastlogin[23] = '\0';
remove_control_chars (lastlogin);
@@ -727,10 +737,6 @@ int mmo_auth_init (void)
remove_control_chars (last_ip);
strncpy (auth_dat[auth_num].last_ip, last_ip, 16);
- memo[254] = '\0';
- remove_control_chars (memo);
- strncpy (auth_dat[auth_num].memo, memo, 255);
-
for (j = 0; j < ACCOUNT_REG2_NUM; j++)
{
p += n;
@@ -839,10 +845,6 @@ int mmo_auth_init (void)
strncpy (auth_dat[auth_num].userid, userid, 24);
- pass[23] = '\0';
- remove_control_chars (pass);
- strncpy (auth_dat[auth_num].pass, pass, 24);
-
lastlogin[23] = '\0';
remove_control_chars (lastlogin);
strncpy (auth_dat[auth_num].lastlogin, lastlogin, 24);
@@ -879,7 +881,7 @@ int mmo_auth_init (void)
auth_dat[auth_num].ban_until_time = 0;
auth_dat[auth_num].connect_until_time = 0;
strncpy (auth_dat[auth_num].last_ip, "-", 16);
- strncpy (auth_dat[auth_num].memo, "-", 255);
+ strncpy (auth_dat[auth_num].memo, "!", 255);
for (j = 0; j < ACCOUNT_REG2_NUM; j++)
{
@@ -1174,8 +1176,8 @@ int mmo_auth_new (struct mmo_account *account, char sex, char *email)
strncpy (auth_dat[i].userid, account->userid, 24);
auth_dat[i].userid[23] = '\0';
- strncpy (auth_dat[i].pass, account->passwd, 24);
- auth_dat[i].pass[23] = '\0';
+ strcpy(auth_dat[i].pass, MD5_saltcrypt(account->passwd, make_salt()));
+ auth_dat[i].pass[39] = '\0';
memcpy (auth_dat[i].lastlogin, "-", 2);
@@ -1210,7 +1212,7 @@ int mmo_auth_new (struct mmo_account *account, char sex, char *email)
strncpy (auth_dat[i].last_ip, "-", 16);
- strncpy (auth_dat[i].memo, "-", 255);
+ strncpy (auth_dat[i].memo, "!", 255);
auth_dat[i].account_reg2_num = 0;
@@ -1228,7 +1230,9 @@ int mmo_auth (struct mmo_account *account, int fd)
struct timeval tv;
char tmpstr[256];
int len, newaccount = 0;
+#ifdef PASSWDENC
char md5str[64], md5bin[32];
+#endif
char ip[16];
unsigned char *sin_addr =
(unsigned char *) &session[fd]->client_addr.sin_addr;
@@ -1271,9 +1275,8 @@ int mmo_auth (struct mmo_account *account, int fd)
if (newaccount)
{
login_log
- ("Attempt of creation of an already existant account (account: %s_%c, pass: %s, received pass: %s, ip: %s)"
- RETCODE, account->userid, account->userid[len + 1],
- auth_dat[i].pass, account->passwd, ip);
+ ("Attempt of creation of an already existant account (account: %s_%c, ip: %s)"
+ RETCODE, account->userid, account->userid[len + 1], ip);
return 9; // 9 = Account already exists
}
ld = session[fd]->session_data;
@@ -1312,13 +1315,13 @@ int mmo_auth (struct mmo_account *account, int fd)
// printf("client [%s] accountpass [%s]\n", account->passwd, auth_dat[i].pass);
}
#endif
- if ((strcmp (account->passwd, auth_dat[i].pass) && !encpasswdok))
+ if ((!pass_ok (account->passwd, auth_dat[i].pass)) && !encpasswdok)
{
if (account->passwdenc == 0)
login_log
- ("Invalid password (account: %s, pass: %s, received pass: %s, ip: %s)"
- RETCODE, account->userid, auth_dat[i].pass,
- account->passwd, ip);
+ ("Invalid password (account: %s, ip: %s)"
+ RETCODE, account->userid, ip);
+
#ifdef PASSWORDENC
else
{
@@ -1347,8 +1350,8 @@ int mmo_auth (struct mmo_account *account, int fd)
if (auth_dat[i].state)
{
login_log
- ("Connection refused (account: %s, pass: %s, state: %d, ip: %s)"
- RETCODE, account->userid, account->passwd, auth_dat[i].state,
+ ("Connection refused (account: %s, state: %d, ip: %s)"
+ RETCODE, account->userid, auth_dat[i].state,
ip);
switch (auth_dat[i].state)
{ // packet 0x006a value + 1
@@ -1378,15 +1381,15 @@ int mmo_auth (struct mmo_account *account, int fd)
if (auth_dat[i].ban_until_time > time (NULL))
{ // always banned
login_log
- ("Connection refused (account: %s, pass: %s, banned until %s, ip: %s)"
- RETCODE, account->userid, account->passwd, tmpstr, ip);
+ ("Connection refused (account: %s, banned until %s, ip: %s)"
+ RETCODE, account->userid, tmpstr, ip);
return 6; // 6 = Your are Prohibited to log in until %s
}
else
{ // ban is finished
login_log
- ("End of ban (account: %s, pass: %s, previously banned until %s -> not more banned, ip: %s)"
- RETCODE, account->userid, account->passwd, tmpstr, ip);
+ ("End of ban (account: %s, previously banned until %s -> not more banned, ip: %s)"
+ RETCODE, account->userid, tmpstr, ip);
auth_dat[i].ban_until_time = 0; // reset the ban time
}
}
@@ -1395,8 +1398,8 @@ int mmo_auth (struct mmo_account *account, int fd)
&& auth_dat[i].connect_until_time < time (NULL))
{
login_log
- ("Connection refused (account: %s, pass: %s, expired ID, ip: %s)"
- RETCODE, account->userid, account->passwd, ip);
+ ("Connection refused (account: %s, expired ID, ip: %s)"
+ RETCODE, account->userid, ip);
return 2; // 2 = This ID is expired
}
@@ -1408,8 +1411,8 @@ int mmo_auth (struct mmo_account *account, int fd)
if (newaccount == 0)
{
login_log
- ("Unknown account (account: %s, received pass: %s, ip: %s)"
- RETCODE, account->userid, account->passwd, ip);
+ ("Unknown account (account: %s, ip: %s)"
+ RETCODE, account->userid, ip);
return 0; // 0 = Unregistered ID
}
else
@@ -1417,8 +1420,8 @@ int mmo_auth (struct mmo_account *account, int fd)
int new_id =
mmo_auth_new (account, account->userid[len + 1], "a@a.com");
login_log
- ("Account creation and authentification accepted (account %s (id: %d), pass: %s, sex: %c, connection with _F/_M, ip: %s)"
- RETCODE, account->userid, new_id, account->passwd,
+ ("Account creation and authentification accepted (account %s (id: %d), sex: %c, connection with _F/_M, ip: %s)"
+ RETCODE, account->userid, new_id,
account->userid[len + 1], ip);
auth_before_save_file = 0; // Creation of an account -> save accounts file immediatly
}
@@ -2140,14 +2143,14 @@ int parse_fromchar (int fd)
{
if (auth_dat[i].account_id == acc)
{
- if (strcmpi (auth_dat[i].pass, actual_pass) == 0)
+ if (pass_ok (actual_pass, auth_dat[i].pass))
{
if (strlen (new_pass) < 4)
status = 3;
else
{
status = 1;
- memcpy (auth_dat[i].pass, new_pass, 24);
+ strcpy (auth_dat[i].pass, MD5_saltcrypt(new_pass, make_salt()));
login_log
("Char-server '%s': Change pass success (account: %d (%s), ip: %s."
RETCODE, server[id].name, acc,
@@ -2393,14 +2396,14 @@ int parse_admin (int fd)
else if (ma.sex != 'F' && ma.sex != 'M')
{
login_log
- ("'ladmin': Attempt to create an invalid account (account: %s, received pass: %s, invalid sex, ip: %s)"
- RETCODE, ma.userid, ma.passwd, ip);
+ ("'ladmin': Attempt to create an invalid account (account: %s, invalid sex, ip: %s)"
+ RETCODE, ma.userid, ip);
}
else if (account_id_count > END_ACCOUNT_NUM)
{
login_log
- ("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, pass: %s, sex: %c, ip: %s)"
- RETCODE, ma.userid, ma.passwd, ma.sex, ip);
+ ("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, sex: %c, ip: %s)"
+ RETCODE, ma.userid, ma.sex, ip);
}
else
{
@@ -2412,9 +2415,8 @@ int parse_admin (int fd)
0)
{
login_log
- ("'ladmin': Attempt to create an already existing account (account: %s, pass: %s, received pass: %s, ip: %s)"
- RETCODE, auth_dat[i].userid,
- auth_dat[i].pass, ma.passwd, ip);
+ ("'ladmin': Attempt to create an already existing account (account: %s ip: %s)"
+ RETCODE, auth_dat[i].userid, ip);
break;
}
}
@@ -2427,8 +2429,8 @@ int parse_admin (int fd)
remove_control_chars (email);
new_id = mmo_auth_new (&ma, ma.sex, email);
login_log
- ("'ladmin': Account creation (account: %s (id: %d), pass: %s, sex: %c, email: %s, ip: %s)"
- RETCODE, ma.userid, new_id, ma.passwd,
+ ("'ladmin': Account creation (account: %s (id: %d), sex: %c, email: %s, ip: %s)"
+ RETCODE, ma.userid, new_id,
ma.sex, auth_dat[i].email, ip);
WFIFOL (fd, 2) = new_id;
mmo_auth_sync ();
@@ -2494,9 +2496,8 @@ int parse_admin (int fd)
if (i != -1)
{
memcpy (WFIFOP (fd, 6), auth_dat[i].userid, 24);
- memcpy (auth_dat[i].pass, RFIFOP (fd, 26), 24);
- auth_dat[i].pass[23] = '\0';
- remove_control_chars (auth_dat[i].pass);
+ strcpy (auth_dat[i].pass, MD5_saltcrypt(RFIFOP (fd, 26), make_salt()));
+ auth_dat[i].pass[39] = '\0';
WFIFOL (fd, 2) = auth_dat[i].account_id;
login_log
("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)"
@@ -2625,7 +2626,7 @@ int parse_admin (int fd)
if (i != -1)
{
memcpy (WFIFOP (fd, 6), auth_dat[i].userid, 24);
- if (strcmp (auth_dat[i].pass, RFIFOP (fd, 26)) == 0)
+ if ( pass_ok(RFIFOP (fd, 26), auth_dat[i].pass) )
{
WFIFOL (fd, 2) = auth_dat[i].account_id;
login_log
@@ -2963,7 +2964,7 @@ int parse_admin (int fd)
memset (auth_dat[i].memo, '\0', size_of_memo);
if (RFIFOW (fd, 26) == 0)
{
- strncpy (auth_dat[i].memo, "-", size_of_memo);
+ strncpy (auth_dat[i].memo, "!", size_of_memo);
}
else if (RFIFOW (fd, 26) > size_of_memo - 1)
{
diff --git a/src/login/login.h b/src/login/login.h
index f28afeb..98025f8 100644
--- a/src/login/login.h
+++ b/src/login/login.h
@@ -6,7 +6,8 @@
#define LOGIN_CONF_NAME "conf/login_athena.conf"
#define LAN_CONF_NAME "conf/lan_support.conf"
-#define PASSWORDENC 3 // A definition is given when making an encryption password correspond.
+// It seems we don't need to emulate RO's "password encryption" - MC/TMW
+//#define PASSWORDENC 3 // A definition is given when making an encryption password correspond.
// It is 1 at the time of passwordencrypt.
// It is made into 2 at the time of passwordencrypt2.
// When it is made 3, it corresponds to both.
diff --git a/src/login/md5calc.c b/src/login/md5calc.c
index 8e6df2c..cf9d958 100644
--- a/src/login/md5calc.c
+++ b/src/login/md5calc.c
@@ -10,6 +10,7 @@
#include "md5calc.h"
#include <string.h>
#include <stdio.h>
+#include "mt_rand.h"
#ifndef UINT_MAX
#define UINT_MAX 4294967295U
@@ -291,3 +292,42 @@ void MD5_String (const char *string, char *output)
digest[8], digest[9], digest[10], digest[11],
digest[12], digest[13], digest[14], digest[15]);
}
+
+// Hash a password with a salt.
+char *MD5_saltcrypt(const char *key, const char *salt)
+{
+ char buf[66], *sbuf = buf+32;
+ static char obuf[33];
+
+ // hash the key then the salt
+ // buf ends up as a 64char null terminated string
+ MD5_String(key, buf);
+ MD5_String(salt, sbuf);
+
+ // Hash the buffer back into sbuf
+ MD5_String(buf, sbuf);
+
+ snprintf(obuf, 32, "!%s$%s", salt, sbuf);
+ return(obuf);
+}
+
+char *make_salt() {
+ static char salt[6];
+ int i;
+ for (i=0; i<5; i++)
+ salt[i] = (char)((mt_rand() % 78) + 48);
+ salt[5] = '\0';
+ return(salt);
+}
+
+int pass_ok(const char *password, const char *crypted) {
+ char buf[40], *salt=buf+1;
+
+ strncpy(buf, crypted, 40);
+ *strchr(buf, '$') = '\0';
+
+ if (!strcmp(crypted, MD5_saltcrypt(password, salt)))
+ return(1);
+
+ return(0);
+}
diff --git a/src/login/md5calc.h b/src/login/md5calc.h
index 4a57861..3571466 100644
--- a/src/login/md5calc.h
+++ b/src/login/md5calc.h
@@ -4,5 +4,8 @@
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();
+int pass_ok(const char *password, const char *crypted);
#endif