summaryrefslogtreecommitdiff
path: root/src/login/login.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/login.c')
-rw-r--r--src/login/login.c132
1 files changed, 82 insertions, 50 deletions
diff --git a/src/login/login.c b/src/login/login.c
index 846f24027..caace34da 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -6,25 +6,26 @@
#include "login.h"
+#include "login/HPMlogin.h"
+#include "login/account.h"
+#include "login/ipban.h"
+#include "login/loginlog.h"
+#include "common/HPM.h"
+#include "common/cbasetypes.h"
+#include "common/core.h"
+#include "common/db.h"
+#include "common/malloc.h"
+#include "common/md5calc.h"
+#include "common/nullpo.h"
+#include "common/random.h"
+#include "common/showmsg.h"
+#include "common/socket.h"
+#include "common/strlib.h"
+#include "common/timer.h"
+#include "common/utils.h"
+
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-
-#include "HPMlogin.h"
-#include "account.h"
-#include "ipban.h"
-#include "loginlog.h"
-#include "../common/HPM.h"
-#include "../common/core.h"
-#include "../common/db.h"
-#include "../common/malloc.h"
-#include "../common/md5calc.h"
-#include "../common/random.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-#include "../common/timer.h"
-#include "../common/utils.h"
struct login_interface login_s;
struct Login_Config login_config;
@@ -98,6 +99,7 @@ static int login_online_db_setoffline(DBKey key, DBData *data, va_list ap)
{
struct online_login_data* p = DB->data2ptr(data);
int server_id = va_arg(ap, int);
+ nullpo_ret(p);
if( server_id == -1 )
{
p->char_server = -1;
@@ -118,6 +120,7 @@ static int login_online_db_setoffline(DBKey key, DBData *data, va_list ap)
static int login_online_data_cleanup_sub(DBKey key, DBData *data, va_list ap)
{
struct online_login_data *character= DB->data2ptr(data);
+ nullpo_ret(character);
if (character->char_server == -2) //Unknown server.. set them offline
login->remove_online_user(character->account_id);
return 0;
@@ -136,6 +139,7 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
{
int i, c;
+ nullpo_ret(buf);
for( i = 0, c = 0; i < ARRAYLENGTH(server); ++i )
{
int fd = server[i].fd;
@@ -155,6 +159,7 @@ int charif_sendallwos(int sfd, uint8* buf, size_t len)
/// Initializes a server structure.
void chrif_server_init(int id)
{
+ Assert_retv(id >= 0 && id < MAX_SERVERS);
memset(&server[id], 0, sizeof(server[id]));
server[id].fd = -1;
}
@@ -163,7 +168,8 @@ void chrif_server_init(int id)
/// Destroys a server structure.
void chrif_server_destroy(int id)
{
- if( server[id].fd != -1 )
+ Assert_retv(id >= 0 && id < MAX_SERVERS);
+ if (server[id].fd != -1)
{
do_close(server[id].fd);
server[id].fd = -1;
@@ -183,6 +189,7 @@ void chrif_server_reset(int id)
/// Called when the connection to Char Server is disconnected.
void chrif_on_disconnect(int id)
{
+ Assert_retv(id >= 0 && id < MAX_SERVERS);
ShowStatus("Char-server '%s' has disconnected.\n", server[id].name);
chrif_server_reset(id);
}
@@ -207,6 +214,9 @@ bool login_check_encrypted(const char* str1, const char* str2, const char* passw
{
char tmpstr[64+1], md5str[32+1];
+ nullpo_ret(str1);
+ nullpo_ret(str2);
+ nullpo_ret(passwd);
safesnprintf(tmpstr, sizeof(tmpstr), "%s%s", str1, str2);
MD5_String(tmpstr, md5str);
@@ -215,17 +225,16 @@ bool login_check_encrypted(const char* str1, const char* str2, const char* passw
bool login_check_password(const char* md5key, int passwdenc, const char* passwd, const char* refpass)
{
- if(passwdenc == 0)
- {
+ nullpo_ret(passwd);
+ nullpo_ret(refpass);
+ if(passwdenc == PWENC_NONE) {
return (0==strcmp(passwd, refpass));
- }
- else
- {
- // password mode set to 1 -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
- // password mode set to 2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
+ } else {
+ // password mode set to PWENC_ENCRYPT -> md5(md5key, refpass) enable with <passwordencrypt></passwordencrypt>
+ // password mode set to PWENC_ENCRYPT2 -> md5(refpass, md5key) enable with <passwordencrypt2></passwordencrypt2>
- return ((passwdenc&0x01) && login->check_encrypted(md5key, refpass, passwd)) ||
- ((passwdenc&0x02) && login->check_encrypted(refpass, md5key, passwd));
+ return ((passwdenc&PWENC_ENCRYPT) && login->check_encrypted(md5key, refpass, passwd)) ||
+ ((passwdenc&PWENC_ENCRYPT2) && login->check_encrypted(refpass, md5key, passwd));
}
}
@@ -248,6 +257,7 @@ int login_lan_config_read(const char *lancfgName)
int line_num = 0;
char line[1024], w1[64], w2[64], w3[64], w4[64];
+ nullpo_ret(lancfgName);
if((fp = fopen(lancfgName, "r")) == NULL) {
ShowWarning("LAN Support configuration file is not found: %s\n", lancfgName);
return 1;
@@ -348,6 +358,7 @@ void login_fromchar_parse_auth(int fd, int id, const char *const ip)
}
else
{// authentication not found
+ nullpo_retv(ip);
ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, NULL);
}
@@ -382,7 +393,7 @@ void login_fromchar_parse_request_change_email(int fd, int id, const char *const
if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0' )
ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
else {
- memcpy(acc.email, email, 40);
+ memcpy(acc.email, email, sizeof(acc.email));
ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
// Save
accounts->save(accounts, &acc);
@@ -489,7 +500,7 @@ void login_fromchar_parse_change_email(int fd, int id, const char *const ip)
if( strcmpi(acc.email, actual_email) != 0 )
ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
else {
- safestrncpy(acc.email, new_email, 40);
+ safestrncpy(acc.email, new_email, sizeof(acc.email));
ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
// Save
accounts->save(accounts, &acc);
@@ -719,9 +730,9 @@ void login_fromchar_parse_change_pincode(int fd)
{
struct mmo_account acc;
- if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ) {
- safestrncpy( acc.pincode, (char*)RFIFOP(fd,6), sizeof(acc.pincode) );
- acc.pincode_change = ((unsigned int)time( NULL ));
+ if (accounts->load_num(accounts, &acc, RFIFOL(fd,2))) {
+ safestrncpy(acc.pincode, (char*)RFIFOP(fd,6), sizeof(acc.pincode));
+ acc.pincode_change = ((unsigned int)time(NULL));
accounts->save(accounts, &acc);
}
RFIFOSKIP(fd,11);
@@ -739,7 +750,7 @@ bool login_fromchar_parse_wrong_pincode(int fd)
return true;
}
- login_log(host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed");
+ login_log(host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed"); // FIXME: Do we really want to log this with the same code as successful logins?
}
login->remove_online_user(acc.account_id);
@@ -1008,6 +1019,9 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
int64 tick = timer->gettick();
struct mmo_account acc;
+ nullpo_retr(3, userid);
+ nullpo_retr(3, pass);
+ nullpo_retr(3, last_ip);
//Account Registration Flood Protection by [Kevin]
if( new_reg_tick == 0 )
new_reg_tick = timer->gettick();
@@ -1060,11 +1074,13 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
//-----------------------------------------------------
// Check/authentication of a connection
//-----------------------------------------------------
+// TODO: Map result values to an enum (or at least document them)
int login_mmo_auth(struct login_session_data* sd, bool isServer) {
struct mmo_account acc;
size_t len;
char ip[16];
+ nullpo_ret(sd);
ip2str(session[sd->fd]->client_addr, ip);
// DNS Blacklist check
@@ -1095,7 +1111,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
// Account creation with _M/_F
if( login_config.new_account_flag ) {
if (len > 2 && sd->passwd[0] != '\0' && // valid user and password lengths
- sd->passwdenc == 0 && // unencoded password
+ sd->passwdenc == PWENC_NONE && // unencoded password
sd->userid[len-2] == '_' && memchr("FfMm", sd->userid[len-1], 4)) // _M/_F suffix
{
int result;
@@ -1206,6 +1222,7 @@ void login_connection_problem(int fd, uint8 status)
void login_kick(struct login_session_data* sd)
{
uint8 buf[6];
+ nullpo_retv(sd);
WBUFW(buf,0) = 0x2734;
WBUFL(buf,2) = sd->account_id;
charif_sendallwos(-1, buf, 6);
@@ -1213,14 +1230,16 @@ void login_kick(struct login_session_data* sd)
void login_auth_ok(struct login_session_data* sd)
{
- int fd = sd->fd;
- uint32 ip = session[fd]->client_addr;
-
+ int fd = 0;
+ uint32 ip;
uint8 server_num, n;
uint32 subnet_char_ip;
struct login_auth_node* node;
int i;
+ nullpo_retv(sd);
+ fd = sd->fd;
+ ip = session[fd]->client_addr;
if( runflag != LOGINSERVER_ST_RUNNING )
{
// players can only login while running
@@ -1336,9 +1355,12 @@ void login_auth_ok(struct login_session_data* sd)
void login_auth_failed(struct login_session_data* sd, int result)
{
- int fd = sd->fd;
- uint32 ip = session[fd]->client_addr;
+ int fd;
+ uint32 ip;
+ nullpo_retv(sd);
+ fd = sd->fd;
+ ip = session[fd]->client_addr;
if (login_config.log_login)
{
const char* error;
@@ -1368,7 +1390,7 @@ void login_auth_failed(struct login_session_data* sd, int result)
default : error = "Unknown Error."; break;
}
- login_log(ip, sd->userid, result, error);
+ login_log(ip, sd->userid, result, error); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
}
if( result == 1 && login_config.dynamic_pass_failure_ban )
@@ -1409,11 +1431,13 @@ void login_login_error(int fd, uint8 status)
WFIFOSET(fd,23);
}
+void login_parse_ping(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_ping(int fd, struct login_session_data* sd)
{
RFIFOSKIP(fd,26);
}
+void login_parse_client_md5(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_client_md5(int fd, struct login_session_data* sd)
{
sd->has_client_hash = 1;
@@ -1422,6 +1446,7 @@ void login_parse_client_md5(int fd, struct login_session_data* sd)
RFIFOSKIP(fd,18);
}
+bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip) __attribute__((nonnull (2)));
bool login_parse_client_login(int fd, struct login_session_data* sd, const char *const ip)
{
uint32 version;
@@ -1478,7 +1503,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
safestrncpy(sd->passwd, password, PASSWD_LEN);
if( login_config.use_md5_passwds )
MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = 0;
+ sd->passwdenc = PWENC_NONE;
}
else
{
@@ -1487,8 +1512,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
sd->passwdenc = PASSWORDENC;
}
- if( sd->passwdenc != 0 && login_config.use_md5_passwds )
- {
+ if (sd->passwdenc != PWENC_NONE && login_config.use_md5_passwds) {
login->auth_failed(sd, 3); // send "rejected from server"
return true;
}
@@ -1502,6 +1526,7 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
return false;
}
+void login_send_coding_key(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_send_coding_key(int fd, struct login_session_data* sd)
{
WFIFOHEAD(fd,4 + sd->md5keylen);
@@ -1511,6 +1536,7 @@ void login_send_coding_key(int fd, struct login_session_data* sd)
WFIFOSET(fd,WFIFOW(fd,2));
}
+void login_parse_request_coding_key(int fd, struct login_session_data* sd) __attribute__((nonnull (2)));
void login_parse_request_coding_key(int fd, struct login_session_data* sd)
{
memset(sd->md5key, '\0', sizeof(sd->md5key));
@@ -1520,6 +1546,7 @@ void login_parse_request_coding_key(int fd, struct login_session_data* sd)
login->send_coding_key(fd, sd);
}
+void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status) __attribute__((nonnull (2)));
void login_char_server_connection_status(int fd, struct login_session_data* sd, uint8 status)
{
WFIFOHEAD(fd,3);
@@ -1528,7 +1555,8 @@ void login_char_server_connection_status(int fd, struct login_session_data* sd,
WFIFOSET(fd,3);
}
-void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip)
+void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip, uint32 ipl) __attribute__((nonnull (2, 3)));
+void login_parse_request_connection(int fd, struct login_session_data* sd, const char *const ip, uint32 ipl)
{
char server_name[20];
char message[256];
@@ -1542,7 +1570,7 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const
safestrncpy(sd->passwd, (char*)RFIFOP(fd,26), NAME_LENGTH);
if( login_config.use_md5_passwds )
MD5_String(sd->passwd, sd->passwd);
- sd->passwdenc = 0;
+ sd->passwdenc = PWENC_NONE;
sd->version = login_config.client_version_to_connect; // hack to skip version check
server_ip = ntohl(RFIFOL(fd,54));
server_port = ntohs(RFIFOW(fd,58));
@@ -1556,11 +1584,13 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const
login_log(session[fd]->client_addr, sd->userid, 100, message);
result = login->mmo_auth(sd, true);
- if( runflag == LOGINSERVER_ST_RUNNING &&
+ if (runflag == LOGINSERVER_ST_RUNNING &&
result == -1 &&
sd->sex == 'S' &&
- sd->account_id >= 0 && sd->account_id < ARRAYLENGTH(server) &&
- !session_isValid(server[sd->account_id].fd) )
+ sd->account_id >= 0 &&
+ sd->account_id < ARRAYLENGTH(server) &&
+ !session_isValid(server[sd->account_id].fd) &&
+ login->lan_subnetcheck(ipl))
{
ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
safestrncpy(server[sd->account_id].name, server_name, sizeof(server[sd->account_id].name));
@@ -1686,7 +1716,7 @@ int login_parse_login(int fd)
if (RFIFOREST(fd) < 86)
return 0;
{
- login->parse_request_connection(fd, sd, ip);
+ login->parse_request_connection(fd, sd, ip, ipl);
}
return 0; // processing will continue elsewhere
@@ -1738,7 +1768,9 @@ void login_set_defaults()
int login_config_read(const char* cfgName)
{
char line[1024], w1[1024], w2[1024];
- FILE* fp = fopen(cfgName, "r");
+ FILE* fp;
+ nullpo_retr(1, cfgName);
+ fp = fopen(cfgName, "r");
if (fp == NULL) {
ShowError("Configuration file (%s) not found.\n", cfgName);
return 1;