From 67e82f1a0bc2a9078cfe11e0add190fa7cc4b891 Mon Sep 17 00:00:00 2001 From: Helmut Grohne 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 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 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 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 #include #include -#include #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 #include +#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 #include +#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 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 #include #include +#include #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