From 67e82f1a0bc2a9078cfe11e0add190fa7cc4b891 Mon Sep 17 00:00:00 2001
From: Helmut Grohne <helmut@subdivi.de>
Date: Tue, 19 Jan 2010 20:24:19 +0100
Subject: fixed a few buffer overruns

strncpy does not always terminate strings. Unterminated strings
(without a length) are bad. So better terminate them.
---
 src/map/chrif.c  | 9 ++++++---
 src/map/clif.c   | 4 ++--
 src/map/npc.c    | 8 +++++---
 src/map/pc.c     | 3 ++-
 src/map/script.c | 7 ++++---
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/map/chrif.c b/src/map/chrif.c
index c4a528b..1f5673a 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -51,7 +51,8 @@ static int chrif_state;
  */
 void chrif_setuserid (char *id)
 {
-    strncpy (userid, id, 24);
+    strncpy (userid, id, sizeof(userid)-1);
+    userid[sizeof(userid)-1] = '\0';
 }
 
 /*==========================================
@@ -60,7 +61,8 @@ void chrif_setuserid (char *id)
  */
 void chrif_setpasswd (char *pwd)
 {
-    strncpy (passwd, pwd, 24);
+    strncpy (passwd, pwd, sizeof(passwd)-1);
+    passwd[sizeof(passwd)-1] = '\0';
 }
 
 /*==========================================
@@ -69,7 +71,8 @@ void chrif_setpasswd (char *pwd)
  */
 void chrif_setip (char *ip)
 {
-    strncpy (char_ip_str, ip, 16);
+    strncpy (char_ip_str, ip, sizeof(char_ip_str)-1);
+    char_ip_str[sizeof(char_ip_str)-1] = '\0';
     char_ip = inet_addr (char_ip_str);
 }
 
diff --git a/src/map/clif.c b/src/map/clif.c
index c3099d7..86be79c 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -8204,14 +8204,14 @@ void clif_parse_NpcStringInput (int fd, struct map_session_data *sd)
 
     len = RFIFOW (fd, 2) - 7;
 
-    if (len >= sizeof (sd->npc_str))
+    if (len >= sizeof (sd->npc_str)-1)
     {
         printf ("clif: input string too long !\n");
         memcpy (sd->npc_str, RFIFOP (fd, 8), sizeof (sd->npc_str));
-        sd->npc_str[sizeof (sd->npc_str) - 1] = 0;
     }
     else
         strncpy (sd->npc_str, RFIFOP (fd, 8), len);
+    sd->npc_str[sizeof (sd->npc_str) - 1] = 0;
     map_scriptcont (sd, RFIFOL (fd, 4));
 }
 
diff --git a/src/map/npc.c b/src/map/npc.c
index 49fe578..4ff5ba2 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -321,7 +321,8 @@ int npc_event_doall_l (const char *name, int rid, int argc, argrec_t * args)
     int  c = 0;
     char buf[64] = "::";
 
-    strncpy (buf + 2, name, 62);
+    strncpy (buf + 2, name, sizeof(buf)-3);
+    buf[sizeof(buf)-1] = '\0';
     strdb_foreach (ev_db, npc_event_doall_sub, &c, buf, rid, argc, args);
     return c;
 }
@@ -1477,7 +1478,8 @@ int npc_convertlabel_db (void *key, void *data, va_list ap)
                                                 * (num + 1));
 
     *p = '\0';
-    strncpy (lst[num].name, lname, 24);
+    strncpy (lst[num].name, lname, sizeof(lst[num].name)-1);
+    lst[num].name[sizeof(lst[num].name)-1] = '\0';
     *p = ':';
     lst[num].pos = pos;
     nd->u.scr.label_list = lst;
@@ -1856,7 +1858,7 @@ static int npc_parse_function (char *w1, char *w2, char *w3, char *w4,
 
     p = (char *) aCalloc (50, sizeof (char));
 
-    strncpy (p, w3, 50);
+    strncpy (p, w3, 49);
     strdb_insert (script_get_userfunc_db (), p, script);
 
 //  label_db=script_get_label_db();
diff --git a/src/map/pc.c b/src/map/pc.c
index 689bcd2..9741852 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -8359,7 +8359,8 @@ int pc_setsavepoint (struct map_session_data *sd, char *mapname, int x, int y)
 {
     nullpo_retr (0, sd);
 
-    strncpy (sd->status.save_point.map, mapname, 24);
+    strncpy (sd->status.save_point.map, mapname, 23);
+    sd->status.save_point.map[23] = '\0';
     sd->status.save_point.x = x;
     sd->status.save_point.y = y;
 
diff --git a/src/map/script.c b/src/map/script.c
index bbde20c..03a092e 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -5691,7 +5691,7 @@ int buildin_getcastlename (struct script_state *st)
             if (strcmp (mapname, gc->map_name) == 0)
             {
                 buf = (char *) aCalloc (24, sizeof (char));
-                strncpy (buf, gc->castle_name, 24);
+                strncpy (buf, gc->castle_name, 23);
                 break;
             }
         }
@@ -6942,10 +6942,10 @@ int buildin_getsavepoint (struct script_state *st)
 
     x = sd->status.save_point.x;
     y = sd->status.save_point.y;
-    strncpy (mapname, sd->status.save_point.map, 24);
     switch (type)
     {
         case 0:
+            strncpy (mapname, sd->status.save_point.map, 23);
             push_str (st->stack, C_STR, mapname);
             break;
         case 1:
@@ -7068,7 +7068,8 @@ int buildin_fakenpcname (struct script_state *st)
     nd = npc_name2id (name);
     if (!nd)
         return 1;
-    strncpy (nd->name, newname, 24);
+    strncpy (nd->name, newname, sizeof(nd->name)-1);
+    nd->name[sizeof(nd->name)-1] = '\0';
     nd->class = newsprite;
 
     // Refresh this npc
-- 
cgit v1.2.3-70-g09d2


From ea5866863cbdad80eb69351417018c6104c5f43b Mon Sep 17 00:00:00 2001
From: Helmut Grohne <helmut@subdivi.de>
Date: Tue, 19 Jan 2010 20:33:25 +0100
Subject: fixed a few memory leaks

---
 src/map/magic-interpreter-parser.y | 2 ++
 src/map/magic-stmt.c               | 4 +++-
 src/map/script.c                   | 4 +---
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/map/magic-interpreter-parser.y b/src/map/magic-interpreter-parser.y
index 047e38c..04d5630 100644
--- a/src/map/magic-interpreter-parser.y
+++ b/src/map/magic-interpreter-parser.y
@@ -268,6 +268,8 @@ spellconf_option	: ID '=' expr
 
                               if (!failed_flag)
                                   add_teleport_anchor(anchor, @1.first_line);
+                              else
+                                  free(anchor);
                               failed_flag = 0;
                           }
 			| PROCEDURE ID '(' proc_formals_list ')' '=' effect_list
diff --git a/src/map/magic-stmt.c b/src/map/magic-stmt.c
index 1a1ced7..93ef65f 100644
--- a/src/map/magic-stmt.c
+++ b/src/map/magic-stmt.c
@@ -1161,7 +1161,7 @@ static effect_t *run_foreach (invocation_t * invocation, effect_t * foreach,
         cont_activation_record_t *ar =
             add_stack_entry (invocation, CONT_STACK_FOREACH, return_location);
         int  entities_allocd = 64;
-        int *entities_collect = malloc (entities_allocd * sizeof (int));
+        int *entities_collect;
         int *entities;
         int *shuffle_board;
         int  entities_nr = 0;
@@ -1170,6 +1170,8 @@ static effect_t *run_foreach (invocation_t * invocation, effect_t * foreach,
         if (!ar)
             return return_location;
 
+        entities_collect = malloc (entities_allocd * sizeof (int));
+
         find_entities_in_area (area.v.v_area, &entities_allocd, &entities_nr,
                                &entities_collect, filter);
 
diff --git a/src/map/script.c b/src/map/script.c
index 03a092e..0ede96c 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -6264,7 +6264,6 @@ int buildin_strmobinfo (struct script_state *st)
     if (num == 1)
     {
         char *buf;
-        buf = calloc (24, 1);
         buf = mob_db[class].name;
         push_str (st->stack, C_STR, buf);
         return 0;
@@ -6272,7 +6271,6 @@ int buildin_strmobinfo (struct script_state *st)
     else if (num == 2)
     {
         char *buf;
-        buf = calloc (24, 1);
         buf = mob_db[class].jname;
         push_str (st->stack, C_STR, buf);
         return 0;
@@ -6938,13 +6936,13 @@ int buildin_getsavepoint (struct script_state *st)
     sd = script_rid2sd (st);
 
     type = conv_num (st, &(st->stack->stack_data[st->start + 2]));
-    mapname = calloc (24, 1);
 
     x = sd->status.save_point.x;
     y = sd->status.save_point.y;
     switch (type)
     {
         case 0:
+            mapname = calloc (24, 1);
             strncpy (mapname, sd->status.save_point.map, 23);
             push_str (st->stack, C_STR, mapname);
             break;
-- 
cgit v1.2.3-70-g09d2


From dc0c8b2ca0f3867f1b4641092b9f90738ca8c7af Mon Sep 17 00:00:00 2001
From: Helmut Grohne <helmut@subdivi.de>
Date: Tue, 19 Jan 2010 20:34:06 +0100
Subject: fixed a buffer overrun and use of uninitialized

The target buffer for the memcpy only takes like 24 chars.
strcat on an uninitialized buffer is a bad idea.
---
 src/map/npc.c | 2 +-
 src/map/tmw.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/map/npc.c b/src/map/npc.c
index 4ff5ba2..edbf548 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -74,7 +74,7 @@ int npc_enable_sub (struct block_list *bl, va_list ap)
         if (nd->flag & 1)       // ��������������
             return 1;
 
-        memcpy (name, nd->name, 50);
+        memcpy (name, nd->name, sizeof(nd->name));
         if (sd->areanpc_id == nd->bl.id)
             return 1;
         sd->areanpc_id = nd->bl.id;
diff --git a/src/map/tmw.c b/src/map/tmw.c
index 2849983..3c506c5 100644
--- a/src/map/tmw.c
+++ b/src/map/tmw.c
@@ -146,7 +146,7 @@ void tmw_GmHackMsg (const char *fmt, ...)
     va_end (ap);
 
     char outbuf[512 + 5];
-    strcat (outbuf, "[GM] ");
+    strcpy (outbuf, "[GM] ");
     strcat (outbuf, buf);
 
     intif_wis_message_to_gm (wisp_server_name,
-- 
cgit v1.2.3-70-g09d2


From 88b9a3ac5b0e2b99d1105d69d4b0da608d7ae1e4 Mon Sep 17 00:00:00 2001
From: MadCamel <madcamel@gmail.com>
Date: Tue, 26 Jan 2010 18:44:06 -0500
Subject: Added password encryption to the accounts database, removed logging
 of plaintext passwords Will auto-convert accounts DB to new format.

---
 src/char/char.c      |  15 +-------
 src/ladmin/md5calc.c |  42 ++++++++++++++++++++-
 src/ladmin/md5calc.h |   5 ++-
 src/login/login.c    | 105 ++++++++++++++++++++++++++-------------------------
 src/login/login.h    |   3 +-
 src/login/md5calc.c  |  40 ++++++++++++++++++++
 src/login/md5calc.h  |   3 ++
 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
-- 
cgit v1.2.3-70-g09d2


From 809146978c6b85bb00ca2441ef2490441f4a91da Mon Sep 17 00:00:00 2001
From: Jared Adams <jaxad0127@gmail.com>
Date: Mon, 18 Jan 2010 19:36:34 +0000
Subject: Attempt to fix forking problem on platinum

---
 src/char/char.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/char/char.c b/src/char/char.c
index 2b25399..3755d1f 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -16,6 +16,7 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <stdarg.h>
+#include <sys/wait.h>
 
 #include "core.h"
 #include "socket.h"
@@ -114,6 +115,8 @@ 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
 //------------------------------
@@ -828,7 +831,17 @@ void mmo_char_sync (void)
 //----------------------------------------------------
 int mmo_char_sync_timer (int tid, unsigned int tick, int id, int data)
 {
-    pid_t pid;
+    if (pid != 0)
+    {
+        int status;
+        pid_t temp = waitpid (pid, &status, WNOHANG);
+
+        // Need to check status too?
+        if (temp == 0)
+        {
+            return 0;
+        }
+    }
 
     // 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
-- 
cgit v1.2.3-70-g09d2