Skip to content

Commit

Permalink
Incrementado o suporte ao mac_address
Browse files Browse the repository at this point in the history
- Foi necessário adicionar algumas alterações nos pacotes de comunicação entre os servidores. (não tem nada haver com o cliente)
- A Alteração original para implementação do mac_address foi feita por @Megasantos no commit d1ebe6d
--- Esta alteração apenas visa compartilhar entre os 3 servers a informação do mac_address para que seja possível criar logs de segurança utilizando o mac_address em todos os 3 servers.

-> Funções de NPC agora podem utilizar o comando

*getcharmac({<account_id:int>})
Obtém o endereço mac_address do jogador o qual foi invocado o script ou na conta invocada (neste caso é necessário que esteja online, para pegar offline, utilize sql)
-> Não achei necessário o uso de parametros como name ou char_id pois já existem outras funções que podem fazer isso.

Caso de sucesso no retorno, o conteudo do mac será no formato: "00-00-00-00-00-00" ou embranco (caso seu client não esteja diffado para enviar o pacote do mac)
Caso de erro no retorno, o conteudo do mac será: "" e será lançado um alerta no servidor de mapas.

Exemplo:

set @self_mac$, getcharmac();
set @acc_mac$, getcharmac(2000001);
set @acc_mac2$, getcharmac(getcharid(3, "João"));
  • Loading branch information
carloshenrq committed Jun 9, 2016
1 parent fe3941e commit 51dd5f2
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 45 deletions.
3 changes: 2 additions & 1 deletion sql/logs.sql
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ CREATE TABLE IF NOT EXISTS `loginlog` (
`ip` varchar(15) NOT NULL DEFAULT '',
`user` varchar(23) NOT NULL DEFAULT '',
`rcode` tinyint(4) NOT NULL DEFAULT '0',
`log` varchar(255) NOT NULL DEFAULT ''
`log` varchar(255) NOT NULL DEFAULT '',
`mac_address` VARCHAR(18) NULL DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
Expand Down
2 changes: 2 additions & 0 deletions sql/upgrades/2016-06-09--03-32--logs.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `loginlog`
ADD COLUMN `mac_address` VARCHAR(18) NULL DEFAULT NULL;
35 changes: 29 additions & 6 deletions src/char/char.c
Original file line number Diff line number Diff line change
Expand Up @@ -2348,7 +2348,10 @@ void char_parse_fromlogin_auth_state(int fd)
uint8 clienttype = RFIFOB(fd,24);
int group_id = RFIFOL(fd,25);
unsigned int expiration_time = RFIFOL(fd, 29);
RFIFOSKIP(fd,33);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
char mac_address[MAC_LENGTH];
safestrncpy(mac_address, (const char*)RFIFOP(fd, 33), MAC_LENGTH);
RFIFOSKIP(fd,33 + MAC_LENGTH);

if (sockt->session_is_active(request_id) && (sd=(struct char_session_data*)sockt->session[request_id]->session_data) &&
!sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex )
Expand All @@ -2368,6 +2371,8 @@ void char_parse_fromlogin_auth_state(int fd)
chr->auth_error(client_fd, 0);
break;
}
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(sockt->session[client_fd]->mac_address, mac_address, MAC_LENGTH);
chr->auth_ok(client_fd, sd);
break;
case 1:// auth failed
Expand Down Expand Up @@ -3267,7 +3272,10 @@ void char_parse_frommap_char_select_req(int fd)
uint32 login_id2 = RFIFOL(fd,10);
uint32 ip = RFIFOL(fd,14);
int32 group_id = RFIFOL(fd, 18);
RFIFOSKIP(fd,22);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
char mac_address[MAC_LENGTH];
safestrncpy(mac_address, (const char*)RFIFOP(fd, 22), MAC_LENGTH);
RFIFOSKIP(fd,22 + MAC_LENGTH);

if( core->runflag != CHARSERVER_ST_RUNNING )
{
Expand All @@ -3286,6 +3294,9 @@ void char_parse_frommap_char_select_req(int fd)
node->group_id = group_id;
//node->sex = 0;
node->ip = ntohl(ip);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(node->mac_address, mac_address, MAC_LENGTH);
safestrncpy(sockt->session[fd]->mac_address, node->mac_address, MAC_LENGTH);
/* sounds troublesome. */
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
//node->gmlevel = 0;
Expand Down Expand Up @@ -3346,6 +3357,8 @@ void char_parse_frommap_change_map_server(int fd)
node->ip = ntohl(RFIFOL(fd,31));
node->group_id = RFIFOL(fd,35);
node->changing_mapservers = 1;
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(node->mac_address, (const char*)RFIFOP(fd,39), MAC_LENGTH);
idb_put(auth_db, RFIFOL(fd,2), node);

data = idb_ensure(chr->online_char_db, RFIFOL(fd,2), chr->create_online_char_data);
Expand All @@ -3357,7 +3370,7 @@ void char_parse_frommap_change_map_server(int fd)
} else { //Reply with nak
chr->change_map_server_ack(fd, RFIFOP(fd,2), false);
}
RFIFOSKIP(fd,39);
RFIFOSKIP(fd,39 + MAC_LENGTH);
}

void char_parse_frommap_remove_friend(int fd)
Expand Down Expand Up @@ -3747,9 +3760,11 @@ void char_parse_frommap_ping(int fd)
void char_map_auth_ok(int fd, int account_id, struct char_auth_node* node, struct mmo_charstatus* cd)
{
nullpo_retv(cd);
WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus));
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus) + MAC_LENGTH);
WFIFOW(fd,0) = 0x2afd;
WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus) + MAC_LENGTH;
WFIFOL(fd,4) = account_id;
if (node)
{
Expand All @@ -3758,6 +3773,8 @@ void char_map_auth_ok(int fd, int account_id, struct char_auth_node* node, struc
WFIFOL(fd,16) = (uint32)node->expiration_time; // FIXME: will wrap to negative after "19-Jan-2038, 03:14:07 AM GMT"
WFIFOL(fd,20) = node->group_id;
WFIFOB(fd,24) = node->changing_mapservers;
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
memcpy(WFIFOP(fd,25), node->mac_address, MAC_LENGTH);
}
else
{
Expand All @@ -3766,8 +3783,10 @@ void char_map_auth_ok(int fd, int account_id, struct char_auth_node* node, struc
WFIFOL(fd,16) = 0;
WFIFOL(fd,20) = 0;
WFIFOB(fd,24) = 0;
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
memcpy(WFIFOP(fd,25), "00-00-00-00-00-00", MAC_LENGTH);
}
memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
memcpy(WFIFOP(fd,25 + MAC_LENGTH), cd, sizeof(struct mmo_charstatus));
WFIFOSET(fd, WFIFOW(fd,2));
}

Expand Down Expand Up @@ -4496,6 +4515,8 @@ void char_parse_char_connect(int fd, struct char_session_data* sd, uint32 ipl)
chr->auth_error(fd, 0);
return;
}
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(sockt->session[fd]->mac_address, node->mac_address, MAC_LENGTH);
idb_remove(auth_db, account_id);
chr->auth_ok(fd, sd);
}
Expand Down Expand Up @@ -4690,6 +4711,8 @@ void char_parse_char_select(int fd, struct char_session_data* sd, uint32 ipl)
node->expiration_time = sd->expiration_time;
node->group_id = sd->group_id;
node->ip = ipl;
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(node->mac_address, sockt->session[fd]->mac_address, MAC_LENGTH);
idb_put(auth_db, sd->account_id, node);
}

Expand Down
3 changes: 3 additions & 0 deletions src/char/char.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ struct char_auth_node {
time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
int group_id;
unsigned changing_mapservers : 1;

// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
char mac_address[MAC_LENGTH];
};

/**
Expand Down
3 changes: 3 additions & 0 deletions src/common/mmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ enum _max_level_ {

#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable

// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
#define MAC_LENGTH 18

enum item_types {
IT_HEALING = 0,
IT_UNKNOWN, //1
Expand Down
4 changes: 4 additions & 0 deletions src/common/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/db.h"
#include "common/mmo.h"

#ifdef WIN32
# include "common/winapi.h"
Expand Down Expand Up @@ -107,6 +108,9 @@ struct socket_data {

uint32 client_addr; // remote client address

// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
char mac_address[MAC_LENGTH];

uint8 *rdata, *wdata;
size_t max_rdata, max_wdata;
size_t rdata_size, wdata_size;
Expand Down
59 changes: 39 additions & 20 deletions src/login/login.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,9 @@ uint32 login_lan_subnet_check(uint32 ip)
return sockt->lan_subnet_check(ip, NULL);
}

void login_fromchar_auth_ack(int fd, int account_id, uint32 login_id1, uint32 login_id2, uint8 sex, int request_id, struct login_auth_node* node)
void login_fromchar_auth_ack(int fd, int account_id, uint32 login_id1, uint32 login_id2, uint8 sex, int request_id, const char* mac_address, struct login_auth_node* node)
{
WFIFOHEAD(fd,33);
WFIFOHEAD(fd,33 + MAC_LENGTH);
WFIFOW(fd,0) = 0x2713;
WFIFOL(fd,2) = account_id;
WFIFOL(fd,6) = login_id1;
Expand All @@ -292,7 +292,8 @@ void login_fromchar_auth_ack(int fd, int account_id, uint32 login_id1, uint32 lo
WFIFOL(fd,25) = 0;
WFIFOL(fd,29) = 0;
}
WFIFOSET(fd,33);
memcpy(WFIFOP(fd,33), mac_address, MAC_LENGTH);
WFIFOSET(fd,33 + MAC_LENGTH);
}

void login_fromchar_parse_auth(int fd, int id, const char *const ip)
Expand All @@ -319,15 +320,15 @@ void login_fromchar_parse_auth(int fd, int id, const char *const ip)
//ShowStatus("Servidor de personagem '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);

// send ack
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, node);
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, node->mac_address, node);
// each auth entry can only be used once
idb_remove(login->auth_db, account_id);
}
else
{// authentication not found
nullpo_retv(ip);
ShowStatus("Servidor de personagem '%s': autenticacao da conta %d RECUSADA (ip: %s).\n", server[id].name, account_id, ip);
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, NULL);
ShowStatus("Servidor de personagem '%s': autenticacao da conta %d RECUSADA (ip: %s, mac: %s).\n", server[id].name, account_id, ip, node->mac_address);
login->fromchar_auth_ack(fd, account_id, login_id1, login_id2, sex, request_id, node->mac_address, NULL);
}
}

Expand Down Expand Up @@ -717,7 +718,8 @@ bool login_fromchar_parse_wrong_pincode(int fd)
return true;
}

login_log(sockt->host2ip(acc.last_ip), acc.userid, 100, "Falha na verificacao do PIN"); // FIXME: Do we really want to log this with the same code as successful logins?
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(sockt->host2ip(acc.last_ip), acc.userid, 100, "Falha na verificacao do PIN", acc.mac_address); // FIXME: Do we really want to log this with the same code as successful logins?
}

login->remove_online_user(acc.account_id);
Expand Down Expand Up @@ -1146,7 +1148,7 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
}
}

ShowNotice("Autenticacao aceita (conta: %s, id: %d, ip: %s mac: %s)\n", sd->userid, acc.account_id, ip, sd->mac_address);
ShowNotice("Autenticacao aceita (conta: %s, id: %d, ip: %s, mac: %s)\n", sd->userid, acc.account_id, ip, sockt->session[sd->fd]->mac_address);

// update session data
sd->account_id = acc.account_id;
Expand All @@ -1156,7 +1158,9 @@ int login_mmo_auth(struct login_session_data* sd, bool isServer) {
sd->sex = acc.sex;
sd->group_id = (uint8)acc.group_id;
sd->expiration_time = acc.expiration_time;
memcpy(acc.mac_address, sd->mac_address, sizeof(acc.mac_address));
// Author: Megasantos
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
memcpy(acc.mac_address, sockt->session[sd->fd]->mac_address, sizeof(acc.mac_address));

// update account data
timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S");
Expand Down Expand Up @@ -1254,7 +1258,8 @@ void login_auth_ok(struct login_session_data* sd)
}
}

login_log(ip, sd->userid, 100, "Conectado com sucesso");
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(ip, sd->userid, 100, "Conectado com sucesso", sockt->session[fd]->mac_address);
ShowStatus("Conexao do usuario '%s' aceita.\n", sd->userid);

WFIFOHEAD(fd,47+32*server_num);
Expand Down Expand Up @@ -1301,6 +1306,8 @@ void login_auth_ok(struct login_session_data* sd)
node->clienttype = sd->clienttype;
node->group_id = sd->group_id;
node->expiration_time = sd->expiration_time;
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(node->mac_address, sockt->session[fd]->mac_address, MAC_LENGTH);
idb_put(login->auth_db, sd->account_id, node);

{
Expand Down Expand Up @@ -1350,7 +1357,8 @@ void login_auth_failed(struct login_session_data* sd, int result)
default : error = "Erro desconhecido"; break;
}

login_log(ip, sd->userid, result, error); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(ip, sd->userid, result, error, sockt->session[fd]->mac_address); // FIXME: result can be 100, conflicting with the value 100 we use for successful login...
}

if (result == 1 && login->config->dynamic_pass_failure_ban && !sockt->trusted_ip_check(ip))
Expand Down Expand Up @@ -1425,7 +1433,6 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
char *token = (char *)RFIFOP(fd, 0x5C);
char *macaddress = (char *)RFIFOP(fd, 0x3c);
size_t uAccLen = strlen(accname);
size_t uMacaddress = MAC_LENGTH;
size_t uTokenLen = RFIFOREST(fd) - 0x5C;

version = RFIFOL(fd,4);
Expand All @@ -1436,7 +1443,9 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
}

safestrncpy(username, accname, NAME_LENGTH);
safestrncpy(sd->mac_address, macaddress, uMacaddress);
// Author: Megasantos
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
safestrncpy(sockt->session[sd->fd]->mac_address, macaddress, MAC_LENGTH);
safestrncpy(password, token, min(uTokenLen+1, PASSWD_LEN)); // Variable-length field, don't copy more than necessary
clienttype = RFIFOB(fd, 8);
}
Expand All @@ -1462,15 +1471,19 @@ bool login_parse_client_login(int fd, struct login_session_data* sd, const char
safestrncpy(sd->userid, username, NAME_LENGTH);
if( israwpass )
{
ShowStatus("Requisicao de conexao de %s (ip: %s mac: %s).\n", sd->userid, ip, sd->mac_address);
// Author: Megasantos
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
ShowStatus("Requisicao de conexao de %s (ip: %s, mac: %s).\n", sd->userid, ip, sockt->session[sd->fd]->mac_address);
safestrncpy(sd->passwd, password, PASSWD_LEN);
if (login->config->use_md5_passwds)
MD5_String(sd->passwd, sd->passwd);
sd->passwdenc = PWENC_NONE;
}
else
{
ShowStatus("Requisicao de conexao (modo passwdenc) de %s (ip: %s mac: %s).\n", sd->userid, ip, sd->mac_address);
// Author: Megasantos
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
ShowStatus("Requisicao de conexao (modo passwdenc) de %s (ip: %s, mac: %s).\n", sd->userid, ip, sockt->session[sd->fd]->mac_address);
bin2hex(sd->passwd, passhash, 16); // raw binary data here!
sd->passwdenc = PASSWORDENC;
}
Expand Down Expand Up @@ -1544,7 +1557,8 @@ void login_parse_request_connection(int fd, struct login_session_data* sd, const

ShowInfo("Requisicao de conexao do servidor de personagem '%s' @ %u.%u.%u.%u:%u (conta: '%s', senha: '%s', ip: '%s')\n", server_name, CONVIP(server_ip), server_port, sd->userid, sd->passwd, ip);
sprintf(message, "charserver - %s@%u.%u.%u.%u:%u", server_name, CONVIP(server_ip), server_port);
login_log(sockt->session[fd]->client_addr, sd->userid, 100, message);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(sockt->session[fd]->client_addr, sd->userid, 100, message, sockt->session[fd]->mac_address);

result = login->mmo_auth(sd, true);
if (core->runflag == LOGINSERVER_ST_RUNNING &&
Expand Down Expand Up @@ -1600,8 +1614,11 @@ int login_parse_login(int fd)
{
// Perform ip-ban check
if (login->config->ipban && !sockt->trusted_ip_check(ipl) && ipban_check(ipl)) {
ShowStatus("Conexao recusada: IP nao esta autorizado (ip: %s mac: %s).\n", ip, sd->mac_address);
login_log(ipl, "unknown", -3, "ip banned");
// Author: Megasantos
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
ShowStatus("Conexao recusada: IP nao esta autorizado (ip: %s, mac: %s).\n", ip, sockt->session[sd->fd]->mac_address);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(ipl, "unknown", -3, "ip banned", sockt->session[fd]->mac_address);
login->login_error(fd, 3); // 3 = Rejected from Server
sockt->eof(fd);
return 0;
Expand Down Expand Up @@ -1851,7 +1868,8 @@ int do_final(void) {
aFree(tmp);
}

login_log(0, "Servidor de login", 100, "Fechando...");
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(0, "Servidor de login", 100, "Fechando...", "");

if (login->config->log_login)
loginlog_final();
Expand Down Expand Up @@ -2021,7 +2039,8 @@ int do_init(int argc, char** argv)
}

ShowStatus("O servidor de login esta "CL_GREEN"pronto"CL_RESET" (Escutando na porta %u).\n\n", login->config->login_port);
login_log(0, "Servidor de login", 100, "Iniciou");
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
login_log(0, "Servidor de login", 100, "Iniciou", "");

return 0;
}
Expand Down
8 changes: 4 additions & 4 deletions src/login/login.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ enum password_enc {
#define PASSWORDENC PWENC_BOTH

#define PASSWD_LEN (32+1) // 23+1 for plaintext, 32+1 for md5-ed passwords
#define MAC_LENGTH 18

struct login_session_data {
int account_id;
Expand All @@ -69,8 +68,6 @@ struct login_session_data {

int fd;

char mac_address[MAC_LENGTH];

time_t expiration_time;
};

Expand Down Expand Up @@ -131,6 +128,9 @@ struct login_auth_node {
uint8 clienttype;
int group_id;
time_t expiration_time;

// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
char mac_address[MAC_LENGTH];
};

//-----------------------------------------------------
Expand Down Expand Up @@ -173,7 +173,7 @@ struct login_interface {
void (*fromchar_accinfo) (int fd, int account_id, int u_fd, int u_aid, int u_group, int map_fd, struct mmo_account *acc);
void (*fromchar_account) (int fd, int account_id, struct mmo_account *acc);
void (*fromchar_account_update_other) (int account_id, unsigned int state);
void (*fromchar_auth_ack) (int fd, int account_id, uint32 login_id1, uint32 login_id2, uint8 sex, int request_id, struct login_auth_node* node);
void (*fromchar_auth_ack) (int fd, int account_id, uint32 login_id1, uint32 login_id2, uint8 sex, int request_id, const char* mac_address, struct login_auth_node* node);
void (*fromchar_ban) (int account_id, time_t timestamp);
void (*fromchar_change_sex_other) (int account_id, char sex);
void (*fromchar_pong) (int fd);
Expand Down
3 changes: 2 additions & 1 deletion src/login/loginlog.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
#ifdef BRATHENA_CORE
// TODO: Interface
unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes);
void login_log(uint32 ip, const char* username, int rcode, const char* message);
// [CarlosHenrq] Enviando mac_address no pacote entre os servidores.
void login_log(uint32 ip, const char* username, int rcode, const char* message, const char* mac_address);
bool loginlog_init(void);
bool loginlog_final(void);
bool loginlog_config_read(const char* w1, const char* w2);
Expand Down

0 comments on commit 51dd5f2

Please sign in to comment.