rendered paste bodyIndex: AuthSocket.h
===================================================================
--- AuthSocket.h (révision 5401)
+++ AuthSocket.h (copie de travail)
@@ -53,6 +53,11 @@
bool _HandleXferCancel();
bool _HandleXferAccept();
+ bool _HandleInformationRetrieveAnsw();
+ bool _HandleGMLevelAnsw();
+ bool _HandleBanIPAnsw();
+ bool _HandleRealmCharsAnsw();
+
void _SetVSFields(std::string rI);
FILE *pPatch;
Index: SpecialCodes.h
===================================================================
--- SpecialCodes.h (révision 0)
+++ SpecialCodes.h (révision 0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** \file
+ \ingroup realmd
+*/
+
+#ifndef _SPECIALCODES_H
+#define _SPECIALCODES_H
+
+enum eRealmSendCmds
+{
+ REALM_SEND_ACCT_INFOS = 0x100,
+ REALM_SEND_BANIP_STATUS = 0x101
+};
+
+enum eRealmReceivedCmds
+{
+ REALM_RECV_ACCT_INFOS_ANSW = 0x102,
+ REALM_RECV_ACCT_BANIP_ANSW = 0x103,
+ REALM_RECV_ACCT_MOD_INFOS = 0x104,
+ REALM_RECV_ACCT_ADD_BANIP = 0x105,
+ REALM_RECV_ACCT_RM_BANIP = 0x106,
+ REALM_RECV_ACCT_ADD_BANACCT = 0x107,
+ REALM_RECV_ACCT_RM_BANACCT = 0x108,
+ REALM_RECV_ACCT_ADDACCOUNT = 0x109,
+ REALM_RECV_ACCT_DELACCOUNT = 0x110
+};
+#endif
Index: Main.cpp
===================================================================
--- Main.cpp (révision 5401)
+++ Main.cpp (copie de travail)
@@ -31,6 +31,8 @@
#include "SystemConfig.h"
#include "Util.h"
+#include "AccountHandler.h"
+
#ifdef WIN32
#include "ServiceWin32.h"
char serviceName[] = "realmd";
@@ -182,6 +184,15 @@
return 1;
}
+ // Activate or not account caching system, precache them before launching connection port
+ if(sConfig.GetIntDefault("AccountCaching", 0) == 1)
+ {
+ AcctMgr.Initialize(sConfig.GetIntDefault("AccountReloadingDelay", 300));
+ AcctMgr.ReloadEverythingIfNeed();
+ sLog.outString();
+ sLog.outString("Accounts will be reloaded in %u seconds", sConfig.GetIntDefault("AccountReloadingDelay", 300));
+ }
+
///- Launch the listening network socket
port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0");
Index: Makefile.am
===================================================================
--- Makefile.am (révision 5401)
+++ Makefile.am (copie de travail)
@@ -27,7 +27,10 @@
AuthSocket.h \
Main.cpp \
RealmList.cpp \
- RealmList.h
+ RealmList.h \
+ AccountHandler.cpp \
+ AccountHandler.h \
+ SpecialCodes.h
## Link realm list daemon against the shared library
mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la
Index: AuthSocket.cpp
===================================================================
--- AuthSocket.cpp (révision 5401)
+++ AuthSocket.cpp (copie de travail)
@@ -30,6 +30,10 @@
#include <cwctype> // needs for towupper
#include <openssl/md5.h>
#include "Auth/Sha1.h"
+#include "AccountHandler.h"
+#include "Config/ConfigEnv.h"
+#include <sstream>
+#include "SpecialCodes.h"
extern RealmList m_realmList;
@@ -156,6 +160,12 @@
bool (AuthSocket::*handler)(void);
}AuthHandler;
+typedef struct SpecialCodesHandler
+{
+ eRealmReceivedCmds cmd;
+ bool (AuthSocket::*handler)(void);
+}SpecialCodesHandler;
+
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some paltform
#if defined( __GNUC__ )
#pragma pack()
@@ -206,7 +216,24 @@
{ XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel }
};
+const SpecialCodesHandler sptable[] =
+{
+ { REALM_RECV_ACCT_INFOS_ANSW, &AuthSocket::_HandleInformationRetrieveAnsw},
+ { REALM_RECV_ACCT_BANIP_ANSW, &AuthSocket::_HandleBanIPAnsw }
+
+ // Reserved for future implementation of features like ban without waiting reload time etc
+ /*{ REALM_RECV_ACCT_MOD_INFOS,
+ { REALM_RECV_ACCT_ADD_BANIP,
+ { REALM_RECV_ACCT_RM_BANIP,
+ { REALM_RECV_ACCT_ADD_BANACCT,
+ { REALM_RECV_ACCT_RM_BANACCT,
+ { REALM_RECV_ACCT_MOD_REALMCHARS,
+ { REALM_RECV_ACCT_ADDACCOUNT,
+ { REALM_RECV_ACCT_DELACCOUNT,*/
+};
+
#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler)
+#define TOTAL_SPECIAL_COMMANDS sizeof(sptable)/sizeof(SpecialCodesHandler)
///Holds the MD5 hash of client patches present on the server
Patcher PatchesCache;
@@ -260,6 +287,17 @@
// assert(0);
size_t i;
+ for(i=0;i<TOTAL_SPECIAL_COMMANDS;i++)
+ {
+ if ((uint8)sptable[i].cmd == _cmd)
+ if(!(*this.*sptable[i].handler) ())
+ {
+ DEBUG_LOG("Special Commands Handler failed for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+ return;
+ }
+ break;
+ }
+
///- Circle through known commands and call the correct command handler
for (i=0;i<AUTH_TOTAL_COMMANDS; i++)
{
@@ -287,6 +325,51 @@
}
}
+bool AuthSocket::_HandleInformationRetrieveAnsw()
+{
+ std::vector<uint8> buf;
+ buf.resize(3);
+
+ ibuf.Read((char *)&buf[0], 3);
+
+ /*
+ Buf[0] = cmd
+ Buf[1] = account id
+ Buf[2] = account name
+ Buf[3] = realm id (for sending to good game server :P
+ */
+
+ Account* acct;
+
+ if(buf[1] != 0)
+ acct = AcctMgr.FindAccountById(buf[1]);
+ else
+ acct = AcctMgr.FindAccountByName((char *)buf[2]);
+
+ SendInformationRetreiveToGS(buf[3],acct->id, acct->name, acct->security, acct->locale, acct->tbc, acct->banned, acct->locked, acct->I, acct->LastIp);
+
+ return true;
+}
+
+bool AuthSocket::_HandleBanIPAnsw()
+{
+ std::vector<uint8> buf;
+ buf.resize(1);
+
+ ibuf.Read((char *)&buf[0], 1);
+
+ /*
+ Buf[0] = cmd
+ Buf[1] = IP
+ */
+
+ bool IpIsBanned = AcctMgr.IpBan((char *)buf[1]);
+
+ SendIpBanStatusToGS(buf[1], IpIsBanned);
+
+ return true;
+}
+
/// Make the SRP6 calculation from hash in dB
void AuthSocket::_SetVSFields(std::string rI)
{
@@ -320,6 +403,8 @@
/// Logon Challenge command handler
bool AuthSocket::_HandleLogonChallenge()
{
+ AcctMgr.ReloadEverythingIfNeed();
+
DEBUG_LOG("Entering _HandleLogonChallenge");
if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
return false;
@@ -370,6 +455,8 @@
pkt << (uint8) AUTH_LOGON_CHALLENGE;
pkt << (uint8) 0x00;
+ if(sConfig.GetIntDefault("AccountCaching", 0) != 1)
+ {
///- Verify that this IP is not in the ip_banned table
// No SQL injection possible (paste the IP address as passed by the socket)
dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
@@ -484,10 +571,98 @@
{
pkt<< (uint8) REALM_AUTH_NO_MATCH;
}
- }
- } //valid version
+ }
+ }
+ else
+ {
+ if(AcctMgr.IpBan(GetRemoteAddress()))
+ {
+ pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
+ }
+ else
+ {
+ Account* acct = AcctMgr.FindAccountByName(_safelogin);
+
+ if(acct)
+ {
+ bool locked = false;
+
+ if(acct->locked == 1) // if ip is locked
+ {
+ if ( strcmp(acct->LastIp.c_str(),GetRemoteAddress().c_str()) )
+ {
+ pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
+ locked=true;
+ }
+ }
+
+ if (!locked)
+ {
+ if(acct->banned)
+ {
+ pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED;
+ }
+ else
+ {
+ ///- Get the password from the account table, upper it, and make the SRP6 calculation
+ std::string rI = acct->I;
+ _SetVSFields(rI);
+ b.SetRand(19 * 8);
+ BigNumber gmod=g.ModExp(b, N);
+ B = ((v * 3) + gmod) % N;
+
+ if (B.GetNumBytes() < 32)
+ sLog.outDetail("Interesting, calculation of B in realmd is < 32.");
+
+ ASSERT(gmod.GetNumBytes() <= 32);
+
+ BigNumber unk3;
+ unk3.SetRand(16*8);
+
+ ///- Fill the response packet with the result
+ pkt << (uint8)REALM_AUTH_SUCCESS;
+ pkt.append(B.AsByteArray(), B.GetNumBytes());
+ pkt << (uint8)1;
+ pkt.append(g.AsByteArray(), 1);
+ pkt << (uint8)32;
+ pkt.append(N.AsByteArray(), 32);
+ pkt.append(s.AsByteArray(), s.GetNumBytes());
+ pkt.append(unk3.AsByteArray(), 16);
+ pkt << (uint8)0; // Added in 1.12.x client branch
+
+ uint8 secLevel = acct->security;
+ _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
+
+ // There isn't many differents locale so i think we can hardcode them all
+
+ char charbuffer[3];
+ charbuffer[0] = ch->country[3];
+ charbuffer[1] = ch->country[2];
+ charbuffer[2] = '\0';
+
+ if(strcmp (charbuffer,"fr") == 0)
+ _localization = 2;
+ else if(strcmp (charbuffer,"de") == 0)
+ _localization = 3;
+ else
+ _localization = 0;
+
+ }
+ }
+ else
+ {
+ pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
+ }
+ }
+ else //no account
+ {
+ pkt<< (uint8) REALM_AUTH_NO_MATCH;
+ }
+ }
+ }
+ } //valid version
else
- ///<li> else
+ ///<li> else
{
///- Check if we have the apropriate patch on the disk
char tmp[64];
@@ -535,7 +710,7 @@
}
/// </ul>
SendBuf((char const*)pkt.contents(), pkt.size());
- return true;
+ return true;
}
/// Logon Proof command handler
@@ -661,9 +836,13 @@
ibuf.Remove(5);
+ std::string rI;
+ uint32 id;
+
+ if(sConfig.GetIntDefault("AccountCaching", 0) != 1)
+ {
///- Get the user id (else close the connection)
// No SQL injection (escaped user name)
-
QueryResult *result = dbRealmServer.PQuery("SELECT id,sha_pass_hash FROM account WHERE UPPER(username) = '%s'",_safelogin.c_str());
if(!result)
{
@@ -672,9 +851,16 @@
return false;
}
- uint32 id = (*result)[0].GetUInt32();
- std::string rI = (*result)[1].GetCppString();
+ id = (*result)[0].GetUInt32();
+ rI = (*result)[1].GetCppString();
delete result;
+ }
+ else
+ {
+ Account* acct = AcctMgr.FindAccountByName(_safelogin);
+ id = acct->id;
+ rI = acct->I;
+ }
///- Update realm list if need
m_realmList.UpdateIfNeed();
@@ -687,17 +873,22 @@
for( i = m_realmList.begin(); i != m_realmList.end(); i++ )
{
uint8 AmountOfCharacters;
-
- // No SQL injection. id of realm is controlled by the database.
- result = dbRealmServer.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
- if( result )
- {
- Field *fields = result->Fetch();
- AmountOfCharacters = fields[0].GetUInt8();
- delete result;
- }
- else
+ if(sConfig.GetIntDefault("AccountCaching", 0) != 1)
+ {
+ // No SQL injection. id of realm is controlled by the database.
+ QueryResult* result = dbRealmServer.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
+ if( result )
+ {
+ Field *fields = result->Fetch();
+ AmountOfCharacters = fields[0].GetUInt8();
+ delete result;
+ }
+ else
AmountOfCharacters = 0;
+ }
+ else
+ AmountOfCharacters = AcctMgr.GetNumChar(i->second.m_ID, id);
+
uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;