diff options
Diffstat (limited to 'src/realmd')
-rw-r--r-- | src/realmd/AuthCodes.h | 75 | ||||
-rw-r--r-- | src/realmd/AuthSocket.cpp | 1094 | ||||
-rw-r--r-- | src/realmd/AuthSocket.h | 86 | ||||
-rw-r--r-- | src/realmd/CMakeLists.txt | 45 | ||||
-rw-r--r-- | src/realmd/Main.cpp | 364 | ||||
-rw-r--r-- | src/realmd/Makefile.am | 59 | ||||
-rw-r--r-- | src/realmd/RealmList.cpp | 101 | ||||
-rw-r--r-- | src/realmd/RealmList.h | 67 | ||||
-rw-r--r-- | src/realmd/TrinityRealm.ico | bin | 136606 -> 0 bytes | |||
-rw-r--r-- | src/realmd/realmd.conf.dist.in | 122 | ||||
-rw-r--r-- | src/realmd/realmd.rc | 85 | ||||
-rw-r--r-- | src/realmd/resource.h | 15 |
12 files changed, 0 insertions, 2113 deletions
diff --git a/src/realmd/AuthCodes.h b/src/realmd/AuthCodes.h deleted file mode 100644 index 9a38712af83..00000000000 --- a/src/realmd/AuthCodes.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 _AUTHCODES_H -#define _AUTHCODES_H - -enum eAuthResults -{ - REALM_AUTH_SUCCESS = 0x00, - REALM_AUTH_FAILURE = 0x01, ///< Unable to connect - REALM_AUTH_UNKNOWN1 = 0x02, ///< Unable to connect - REALM_AUTH_ACCOUNT_BANNED = 0x03, ///< This <game> account has been closed and is no longer available for use. Please go to <site>/banned.html for further information. - REALM_AUTH_NO_MATCH = 0x04, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see <site> for more information - REALM_AUTH_UNKNOWN2 = 0x05, ///< The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password, see <site> for more information - REALM_AUTH_ACCOUNT_IN_USE = 0x06, ///< This account is already logged into <game>. Please check the spelling and try again. - REALM_AUTH_PREPAID_TIME_LIMIT = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing - REALM_AUTH_SERVER_FULL = 0x08, ///< Could not log in to <game> at this time. Please try again later. - REALM_AUTH_WRONG_BUILD_NUMBER = 0x09, ///< Unable to validate game version. This may be caused by file corruption or interference of another program. Please visit <site> for more information and possible solutions to this issue. - REALM_AUTH_UPDATE_CLIENT = 0x0a, ///< Downloading - REALM_AUTH_UNKNOWN3 = 0x0b, ///< Unable to connect - REALM_AUTH_ACCOUNT_FREEZED = 0x0c, ///< This <game> account has been temporarily suspended. Please go to <site>/banned.html for further information - REALM_AUTH_UNKNOWN4 = 0x0d, ///< Unable to connect - REALM_AUTH_UNKNOWN5 = 0x0e, ///< Connected. - REALM_AUTH_PARENTAL_CONTROL = 0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at <site> -}; - -enum LoginResult -{ - LOGIN_OK = 0x00, - LOGIN_FAILED = 0x01, - LOGIN_FAILED2 = 0x02, - LOGIN_BANNED = 0x03, - LOGIN_UNKNOWN_ACCOUNT = 0x04, - LOGIN_UNKNOWN_ACCOUNT3 = 0x05, - LOGIN_ALREADYONLINE = 0x06, - LOGIN_NOTIME = 0x07, - LOGIN_DBBUSY = 0x08, - LOGIN_BADVERSION = 0x09, - LOGIN_DOWNLOAD_FILE = 0x0A, - LOGIN_FAILED3 = 0x0B, - LOGIN_SUSPENDED = 0x0C, - LOGIN_FAILED4 = 0x0D, - LOGIN_CONNECTED = 0x0E, - LOGIN_PARENTALCONTROL = 0x0F, - LOGIN_LOCKED_ENFORCED = 0x10, -}; - -// we need to stick to 1 version or half of the stuff will work for someone -// others will not and opposite -// will only support WoW, WoW:TBC and WoW:WotLK 3.0.9 client build 9551... - -#define EXPECTED_TRINITY_CLIENT_BUILD {9551, 0} - -#endif diff --git a/src/realmd/AuthSocket.cpp b/src/realmd/AuthSocket.cpp deleted file mode 100644 index c5c81593737..00000000000 --- a/src/realmd/AuthSocket.cpp +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 -*/ - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "ByteBuffer.h" -#include "Config/ConfigEnv.h" -#include "Log.h" -#include "RealmList.h" -#include "AuthSocket.h" -#include "AuthCodes.h" -#include <openssl/md5.h> -#include "Auth/Sha1.h" -//#include "Util.h" -- for commented utf8ToUpperOnlyLatin - -extern RealmList m_realmList; - -extern DatabaseType LoginDatabase; - -#define ChunkSize 2048 - -enum eAuthCmd -{ - //AUTH_NO_CMD = 0xFF, - AUTH_LOGON_CHALLENGE = 0x00, - AUTH_LOGON_PROOF = 0x01, - AUTH_RECONNECT_CHALLENGE = 0x02, - AUTH_RECONNECT_PROOF = 0x03, - //update srv =4 - REALM_LIST = 0x10, - XFER_INITIATE = 0x30, - XFER_DATA = 0x31, - XFER_ACCEPT = 0x32, - XFER_RESUME = 0x33, - XFER_CANCEL = 0x34 -}; - -enum eStatus -{ - STATUS_CONNECTED = 0, - STATUS_AUTHED -}; - -// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform -#if defined( __GNUC__ ) -#pragma pack(1) -#else -#pragma pack(push,1) -#endif - -typedef struct AUTH_LOGON_CHALLENGE_C -{ - uint8 cmd; - uint8 error; - uint16 size; - uint8 gamename[4]; - uint8 version1; - uint8 version2; - uint8 version3; - uint16 build; - uint8 platform[4]; - uint8 os[4]; - uint8 country[4]; - uint32 timezone_bias; - uint32 ip; - uint8 I_len; - uint8 I[1]; -} sAuthLogonChallenge_C; - -//typedef sAuthLogonChallenge_C sAuthReconnectChallenge_C; -/* -typedef struct -{ - uint8 cmd; - uint8 error; - uint8 unk2; - uint8 B[32]; - uint8 g_len; - uint8 g[1]; - uint8 N_len; - uint8 N[32]; - uint8 s[32]; - uint8 unk3[16]; -} sAuthLogonChallenge_S; -*/ - -typedef struct AUTH_LOGON_PROOF_C -{ - uint8 cmd; - uint8 A[32]; - uint8 M1[20]; - uint8 crc_hash[20]; - uint8 number_of_keys; - uint8 unk; // Added in 1.12.x client branch -} sAuthLogonProof_C; -/* -typedef struct -{ - uint16 unk1; - uint32 unk2; - uint8 unk3[4]; - uint16 unk4[20]; -} sAuthLogonProofKey_C; -*/ -typedef struct AUTH_LOGON_PROOF_S -{ - uint8 cmd; - uint8 error; - uint8 M2[20]; - uint32 unk1; - uint32 unk2; - uint16 unk3; -} sAuthLogonProof_S; - -typedef struct AUTH_RECONNECT_PROOF_C -{ - uint8 cmd; - uint8 R1[16]; - uint8 R2[20]; - uint8 R3[20]; - uint8 number_of_keys; -} sAuthReconnectProof_C; - -typedef struct XFER_INIT -{ - uint8 cmd; // XFER_INITIATE - uint8 fileNameLen; // strlen(fileName); - uint8 fileName[5]; // fileName[fileNameLen] - uint64 file_size; // file size (bytes) - uint8 md5[MD5_DIGEST_LENGTH]; // MD5 -}XFER_INIT; - -typedef struct XFER_DATA -{ - uint8 opcode; - uint16 data_size; - uint8 data[ChunkSize]; -}XFER_DATA_STRUCT; - -typedef struct AuthHandler -{ - eAuthCmd cmd; - uint32 status; - bool (AuthSocket::*handler)(void); -}AuthHandler; - -// 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() -#else -#pragma pack(pop) -#endif - -/// Launch a thread to transfer a patch to the client -class PatcherRunnable: public ZThread::Runnable -{ - public: - PatcherRunnable(class AuthSocket *); - void run(); - - private: - AuthSocket * mySocket; -}; - -typedef struct PATCH_INFO -{ - uint8 md5[MD5_DIGEST_LENGTH]; -}PATCH_INFO; - -/// Caches MD5 hash of client patches present on the server -class Patcher -{ - public: - typedef std::map<std::string, PATCH_INFO*> Patches; - ~Patcher(); - Patcher(); - Patches::const_iterator begin() const { return _patches.begin(); } - Patches::const_iterator end() const { return _patches.end(); } - void LoadPatchMD5(char*); - bool GetHash(char * pat,uint8 mymd5[16]); - - private: - void LoadPatchesInfo(); - Patches _patches; -}; - -const AuthHandler table[] = -{ - { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge }, - { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, - { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge}, - { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof }, - { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, - { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, - { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, - { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } -}; - -#define AUTH_TOTAL_COMMANDS sizeof(table)/sizeof(AuthHandler) - -///Holds the MD5 hash of client patches present on the server -Patcher PatchesCache; - -/// Constructor - set the N and g values for SRP6 -AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h) -{ - N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword(7); - _authed = false; - pPatch = NULL; - - _accountSecurityLevel = SEC_PLAYER; -} - -/// Close patch file descriptor before leaving -AuthSocket::~AuthSocket() -{ - ZThread::Guard<ZThread::Mutex> g(patcherLock); - if(pPatch) - fclose(pPatch); -} - -/// Accept the connection and set the s random value for SRP6 -void AuthSocket::OnAccept() -{ - sLog.outBasic("Accepting connection from '%s:%d'", - GetRemoteAddress().c_str(), GetRemotePort()); - - s.SetRand(s_BYTE_SIZE * 8); -} - -/// Read the packet from the client -void AuthSocket::OnRead() -{ - ///- Read the packet - TcpSocket::OnRead(); - uint8 _cmd; - while (1) - { - if (!ibuf.GetLength()) - return; - - ///- Get the command out of it - ibuf.SoftRead((char *)&_cmd, 1); // UQ1: No longer exists in new net code ??? - //ibuf.Read((char *)&_cmd, 1); - /*char *command = (char *)malloc(1); - - ibuf.Read(command, 1); - - _cmd = (uint8)command;*/ - // assert(0); - size_t i; - - ///- Circle through known commands and call the correct command handler - for (i=0;i<AUTH_TOTAL_COMMANDS; i++) - { - if ((uint8)table[i].cmd == _cmd && - (table[i].status == STATUS_CONNECTED || - (_authed && table[i].status == STATUS_AUTHED))) - { - DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength()); - - if (!(*this.*table[i].handler)()) - { - DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength()); - return; - } - break; - } - } - - ///- Report unknown commands in the debug log - if (i==AUTH_TOTAL_COMMANDS) - { - DEBUG_LOG("[Auth] got unknown packet %u", (uint32)_cmd); - return; - } - } -} - -/// Make the SRP6 calculation from hash in dB -void AuthSocket::_SetVSFields(const std::string& rI) -{ - BigNumber I; - I.SetHexStr(rI.c_str()); - - //In case of leading zeroes in the rI hash, restore them - uint8 mDigest[SHA_DIGEST_LENGTH]; - memset(mDigest,0,SHA_DIGEST_LENGTH); - if (I.GetNumBytes() <= SHA_DIGEST_LENGTH) - memcpy(mDigest,I.AsByteArray(),I.GetNumBytes()); - - std::reverse(mDigest,mDigest+SHA_DIGEST_LENGTH); - - Sha1Hash sha; - sha.UpdateData(s.AsByteArray(), s.GetNumBytes()); - sha.UpdateData(mDigest, SHA_DIGEST_LENGTH); - sha.Finalize(); - BigNumber x; - x.SetBinary(sha.GetDigest(), sha.GetLength()); - v = g.ModExp(x, N); - // No SQL injection (username escaped) - const char *v_hex, *s_hex; - v_hex = v.AsHexStr(); - s_hex = s.AsHexStr(); - LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'",v_hex,s_hex, _safelogin.c_str() ); - OPENSSL_free((void*)v_hex); - OPENSSL_free((void*)s_hex); -} - -/// Logon Challenge command handler -bool AuthSocket::_HandleLogonChallenge() -{ - DEBUG_LOG("Entering _HandleLogonChallenge"); - if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C)) - return false; - - ///- Read the first 4 bytes (header) to get the length of the remaining of the packet - std::vector<uint8> buf; - buf.resize(4); - - ibuf.Read((char *)&buf[0], 4); - - EndianConvert(*((uint16*)(buf[0]))); - uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; - DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining); - - if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining)) - return false; - - //No big fear of memory outage (size is int16, i.e. < 65536) - buf.resize(remaining + buf.size() + 1); - buf[buf.size() - 1] = 0; - sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; - - // BigEndian code, nop in little endian case - // size already converted - EndianConvert(*((uint32*)(&ch->gamename[0]))); - EndianConvert(ch->build); - EndianConvert(*((uint32*)(&ch->platform[0]))); - EndianConvert(*((uint32*)(&ch->os[0]))); - EndianConvert(*((uint32*)(&ch->country[0]))); - EndianConvert(ch->timezone_bias); - EndianConvert(ch->ip); - - ///- Read the remaining of the packet - ibuf.Read((char *)&buf[4], remaining); - DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); - DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); - - ByteBuffer pkt; - - _login = (const char*)ch->I; - _build = ch->build; - - ///- Normalize account name - //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form - - //Escape the user login to avoid further SQL injection - //Memory will be freed on AuthSocket object destruction - _safelogin=_login; - LoginDatabase.escape_string(_safelogin); - - pkt << (uint8) AUTH_LOGON_CHALLENGE; - pkt << (uint8) 0x00; - - ///- Verify that this IP is not in the ip_banned table - // No SQL injection possible (paste the IP address as passed by the socket) - LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - - std::string address = GetRemoteAddress(); - LoginDatabase.escape_string(address); - QueryResult *result = LoginDatabase.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); - if(result) - { - pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; - sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); - delete result; - } - else - { - ///- Get the account details from the account table - // No SQL injection (escaped user name) - - result = LoginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); - if( result ) - { - ///- If the IP is 'locked', check that the player comes indeed from the correct IP address - bool locked = false; - if((*result)[2].GetUInt8() == 1) // if ip is locked - { - DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); - DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); - if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) - { - DEBUG_LOG("[AuthChallenge] Account IP differs"); - pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; - locked=true; - } - else - { - DEBUG_LOG("[AuthChallenge] Account IP matches"); - } - } - else - { - DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); - } - - if (!locked) - { - //set expired bans to inactive - LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); - ///- If the account is banned, reject the logon attempt - QueryResult *banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); - if(banresult) - { - if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) - { - pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; - sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); - } - else - { - pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; - sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); - } - - delete banresult; - } - else - { - ///- Get the password from the account table, upper it, and make the SRP6 calculation - std::string rI = (*result)[0].GetCppString(); - _SetVSFields(rI); - - b.SetRand(19 * 8); - BigNumber gmod=g.ModExp(b, N); - B = ((v * 3) + gmod) % N; - - ASSERT(gmod.GetNumBytes() <= 32); - - BigNumber unk3; - unk3.SetRand(16*8); - - ///- Fill the response packet with the result - pkt << (uint8)REALM_AUTH_SUCCESS; - - // B may be calculated < 32B so we force minnimal length to 32B - pkt.append(B.AsByteArray(32), 32); // 32 bytes - pkt << (uint8)1; - pkt.append(g.AsByteArray(), 1); - pkt << (uint8)32; - pkt.append(N.AsByteArray(), 32); - pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes - pkt.append(unk3.AsByteArray(), 16); - pkt << (uint8)0; // Added in 1.12.x client branch - - uint8 secLevel = (*result)[4].GetUInt8(); - _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; - - _localizationName.resize(4); - for(int i = 0; i <4; ++i) - _localizationName[i] = ch->country[4-i-1]; - - sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName)); - } - } - delete result; - } - else //no account - { - pkt<< (uint8) REALM_AUTH_NO_MATCH; - } - } - SendBuf((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Logon Proof command handler -bool AuthSocket::_HandleLogonProof() -{ - DEBUG_LOG("Entering _HandleLogonProof"); - ///- Read the packet - if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) - return false; - sAuthLogonProof_C lp; - ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); - - ///- Check if the client has one of the expected version numbers - bool valid_version=false; - int accepted_versions[]=EXPECTED_TRINITY_CLIENT_BUILD; - for(int i=0;accepted_versions[i];i++) - { - if(_build==accepted_versions[i]) - { - valid_version=true; - break; - } - } - - /// <ul><li> If the client has no valid version - if(!valid_version) - { - ///- Check if we have the apropriate patch on the disk - - // 24 = len("./patches/65535enGB.mpq")+1 - char tmp[24]; - // No buffer overflow (fixed length of arguments) - sprintf(tmp,"./patches/%d%s.mpq",_build, _localizationName.c_str()); - // This will be closed at the destruction of the AuthSocket (client deconnection) - FILE *pFile=fopen(tmp,"rb"); - - if(!pFile) - { - ByteBuffer pkt; - pkt << (uint8) AUTH_LOGON_CHALLENGE; - pkt << (uint8) 0x00; - pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER; - DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build); - DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp); - SendBuf((char const*)pkt.contents(), pkt.size()); - return true; - } - else // have patch - { - pPatch=pFile; - XFER_INIT xferh; - - ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it) - if(PatchesCache.GetHash(tmp,(uint8*)&xferh.md5)) - { - DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s",tmp); - } - else - { //calculate patch md5 - printf("\n[AuthChallenge] Patch info for %s was not cached.",tmp); - PatchesCache.LoadPatchMD5(tmp); - PatchesCache.GetHash(tmp,(uint8*)&xferh.md5); - } - - ///- Send a packet to the client with the file length and MD5 hash - uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT}; - SendBuf((const char*)data,sizeof(data)); - - memcpy(&xferh,"0\x05Patch",7); - xferh.cmd=XFER_INITIATE; - fseek(pPatch,0,SEEK_END); - xferh.file_size=ftell(pPatch); - - SendBuf((const char*)&xferh,sizeof(xferh)); - return true; - } - } - /// </ul> - - ///- Continue the SRP6 calculation based on data received from the client - BigNumber A; - A.SetBinary(lp.A, 32); - - Sha1Hash sha; - sha.UpdateBigNumbers(&A, &B, NULL); - sha.Finalize(); - BigNumber u; - u.SetBinary(sha.GetDigest(), 20); - BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); - - uint8 t[32]; - uint8 t1[16]; - uint8 vK[40]; - memcpy(t, S.AsByteArray(), 32); - for (int i = 0; i < 16; i++) - { - t1[i] = t[i*2]; - } - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - for (int i = 0; i < 20; i++) - { - vK[i*2] = sha.GetDigest()[i]; - } - for (int i = 0; i < 16; i++) - { - t1[i] = t[i*2+1]; - } - sha.Initialize(); - sha.UpdateData(t1, 16); - sha.Finalize(); - for (int i = 0; i < 20; i++) - { - vK[i*2+1] = sha.GetDigest()[i]; - } - K.SetBinary(vK, 40); - - uint8 hash[20]; - - sha.Initialize(); - sha.UpdateBigNumbers(&N, NULL); - sha.Finalize(); - memcpy(hash, sha.GetDigest(), 20); - sha.Initialize(); - sha.UpdateBigNumbers(&g, NULL); - sha.Finalize(); - for (int i = 0; i < 20; i++) - { - hash[i] ^= sha.GetDigest()[i]; - } - BigNumber t3; - t3.SetBinary(hash, 20); - - sha.Initialize(); - sha.UpdateData(_login); - sha.Finalize(); - uint8 t4[SHA_DIGEST_LENGTH]; - memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); - - sha.Initialize(); - sha.UpdateBigNumbers(&t3, NULL); - sha.UpdateData(t4, SHA_DIGEST_LENGTH); - sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); - sha.Finalize(); - BigNumber M; - M.SetBinary(sha.GetDigest(), 20); - - ///- Check if SRP6 results match (password is correct), else send an error - if (!memcmp(M.AsByteArray(), lp.M1, 20)) - { - sLog.outBasic("User '%s' successfully authenticated", _login.c_str()); - - ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account - // No SQL injection (escaped user name) and IP address as received by socket - const char* K_hex = K.AsHexStr(); - LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() ); - OPENSSL_free((void*)K_hex); - - ///- Finish SRP6 and send the final result to the client - sha.Initialize(); - sha.UpdateBigNumbers(&A, &M, &K, NULL); - sha.Finalize(); - - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk1 = 0x00800000; - proof.unk2 = 0x00; - proof.unk3 = 0x00; - - SendBuf((char *)&proof, sizeof(proof)); - - ///- Set _authed to true! - _authed = true; - } - else - { - char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0}; - SendBuf(data,sizeof(data)); - sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); - - uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); - if(MaxWrongPassCount > 0) - { - //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP - LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str()); - - if(QueryResult *loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str())) - { - Field* fields = loginfail->Fetch(); - uint32 failed_logins = fields[1].GetUInt32(); - - if( failed_logins >= MaxWrongPassCount ) - { - uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); - bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); - - if(WrongPassBanType) - { - uint32 acc_id = fields[0].GetUInt32(); - LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)", - acc_id, WrongPassBanTime); - sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", - _login.c_str(), WrongPassBanTime, failed_logins); - } - else - { - std::string current_ip = GetRemoteAddress(); - LoginDatabase.escape_string(current_ip); - LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')", - current_ip.c_str(), WrongPassBanTime); - sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", - current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); - } - } - delete loginfail; - } - } - } - return true; -} - -/// Reconnect Challenge command handler -bool AuthSocket::_HandleReconnectChallenge() -{ - DEBUG_LOG("Entering _HandleReconnectChallenge"); - if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C)) - return false; - - ///- Read the first 4 bytes (header) to get the length of the remaining of the packet - std::vector<uint8> buf; - buf.resize(4); - - ibuf.Read((char *)&buf[0], 4); - - EndianConvert(*((uint16*)(buf[0]))); - uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; - DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining); - - if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining)) - return false; - - //No big fear of memory outage (size is int16, i.e. < 65536) - buf.resize(remaining + buf.size() + 1); - buf[buf.size() - 1] = 0; - sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; - - ///- Read the remaining of the packet - ibuf.Read((char *)&buf[4], remaining); - DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); - DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); - - _login = (const char*)ch->I; - _safelogin = _login; - - QueryResult *result = LoginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ()); - - // Stop if the account is not found - if (!result) - { - sLog.outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); - SetCloseAndDelete(); - return false; - } - - Field* fields = result->Fetch (); - K.SetHexStr (fields[0].GetString ()); - delete result; - - ///- Sending response - ByteBuffer pkt; - pkt << (uint8) AUTH_RECONNECT_CHALLENGE; - pkt << (uint8) 0x00; - _reconnectProof.SetRand(16*8); - pkt.append(_reconnectProof.AsByteBuffer()); // 16 bytes random - pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros - SendBuf((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Reconnect Proof command handler -bool AuthSocket::_HandleReconnectProof() -{ - DEBUG_LOG("Entering _HandleReconnectProof"); - ///- Read the packet - if (ibuf.GetLength() < sizeof(sAuthReconnectProof_C)) - return false; - if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) - return false; - sAuthReconnectProof_C lp; - ibuf.Read((char *)&lp, sizeof(sAuthReconnectProof_C)); - - BigNumber t1; - t1.SetBinary(lp.R1, 16); - - Sha1Hash sha; - sha.Initialize(); - sha.UpdateData(_login); - sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); - sha.Finalize(); - - if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) - { - ///- Sending response - ByteBuffer pkt; - pkt << (uint8) AUTH_RECONNECT_PROOF; - pkt << (uint8) 0x00; - pkt << (uint16) 0x00; // 2 bytes zeros - SendBuf((char const*)pkt.contents(), pkt.size()); - - ///- Set _authed to true! - _authed = true; - - return true; - } - else - { - sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); - SetCloseAndDelete(); - return false; - } -} - -/// %Realm List command handler -bool AuthSocket::_HandleRealmList() -{ - DEBUG_LOG("Entering _HandleRealmList"); - if (ibuf.GetLength() < 5) - return false; - - ibuf.Remove(5); - - ///- Get the user id (else close the connection) - // No SQL injection (escaped user name) - - QueryResult *result = LoginDatabase.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '%s'",_safelogin.c_str()); - if(!result) - { - sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str()); - SetCloseAndDelete(); - return false; - } - - uint32 id = (*result)[0].GetUInt32(); - std::string rI = (*result)[1].GetCppString(); - delete result; - - ///- Update realm list if need - m_realmList.UpdateIfNeed(); - - ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) - ByteBuffer pkt; - pkt << (uint32) 0; - pkt << (uint16) m_realmList.size(); - RealmList::RealmMap::const_iterator i; - for( i = m_realmList.begin(); i != m_realmList.end(); i++ ) - { - uint8 AmountOfCharacters; - - // No SQL injection. id of realm is controlled by the database. - result = LoginDatabase.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; - - uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - - pkt << i->second.icon; // realm type - pkt << lock; // if 1, then realm locked - pkt << i->second.color; // if 2, then realm is offline - pkt << i->first; - pkt << i->second.address; - pkt << i->second.populationLevel; - pkt << AmountOfCharacters; - pkt << i->second.timezone; // realm category - pkt << (uint8) 0x2C; // unk, may be realm number/id? - } - pkt << (uint8) 0x10; - pkt << (uint8) 0x00; - - ByteBuffer hdr; - hdr << (uint8) REALM_LIST; - hdr << (uint16)pkt.size(); - hdr.append(pkt); - - SendBuf((char const*)hdr.contents(), hdr.size()); - - // Set check field before possible relogin to realm - _SetVSFields(rI); - return true; -} - -/// Resume patch transfer -bool AuthSocket::_HandleXferResume() -{ - DEBUG_LOG("Entering _HandleXferResume"); - ///- Check packet length and patch existence - if (ibuf.GetLength()<9 || !pPatch) - { - sLog.outError("Error while resuming patch transfer (wrong packet)"); - return false; - } - - ///- Launch a PatcherRunnable thread starting at given patch file offset - uint64 start; - ibuf.Remove(1); - ibuf.Read((char*)&start,sizeof(start)); - fseek(pPatch,start,0); - - ZThread::Thread u(new PatcherRunnable(this)); - return true; -} - -/// Cancel patch transfer -bool AuthSocket::_HandleXferCancel() -{ - DEBUG_LOG("Entering _HandleXferCancel"); - - ///- Close and delete the socket - ibuf.Remove(1); //clear input buffer - - //ZThread::Thread::sleep(15); - SetCloseAndDelete(); - - return true; -} - -/// Accept patch transfer -bool AuthSocket::_HandleXferAccept() -{ - DEBUG_LOG("Entering _HandleXferAccept"); - - ///- Check packet length and patch existence - if (!pPatch) - { - sLog.outError("Error while accepting patch transfer (wrong packet)"); - return false; - } - - ///- Launch a PatcherRunnable thread, starting at the begining of the patch file - ibuf.Remove(1); //clear input buffer - fseek(pPatch,0,0); - - ZThread::Thread u(new PatcherRunnable(this)); - - return true; -} - -/// Check if there is lag on the connection to the client -bool AuthSocket::IsLag() -{ - return (TCP_BUFSIZE_READ-GetOutputLength()< 2*ChunkSize); -} - -PatcherRunnable::PatcherRunnable(class AuthSocket * as) -{ - mySocket=as; -} - -/// Send content of patch file to the client -void PatcherRunnable::run() -{ - ZThread::Guard<ZThread::Mutex> g(mySocket->patcherLock); - XFER_DATA_STRUCT xfdata; - xfdata.opcode = XFER_DATA; - - while(!feof(mySocket->pPatch) && mySocket->Ready()) - { - ///- Wait until output buffer is reasonably empty - while(mySocket->Ready() && mySocket->IsLag()) - { - ZThread::Thread::sleep(1); - } - ///- And send content of the patch file to the client - xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch); - mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize)); - } -} - -/// Preload MD5 hashes of existing patch files on server -#ifndef _WIN32 -#include <dirent.h> -#include <errno.h> -void Patcher::LoadPatchesInfo() -{ - DIR * dirp; - //int errno; - struct dirent * dp; - dirp = opendir("./patches/"); - if(!dirp) - return; - while (dirp) - { - errno = 0; - if ((dp = readdir(dirp)) != NULL) - { - int l=strlen(dp->d_name); - if(l<8)continue; - if(!memcmp(&dp->d_name[l-4],".mpq",4)) - LoadPatchMD5(dp->d_name); - } - else - { - if(errno != 0) - { - closedir(dirp); - return; - } - break; - } - } - - if(dirp) - closedir(dirp); -} - -#else -void Patcher::LoadPatchesInfo() -{ - WIN32_FIND_DATA fil; - HANDLE hFil=FindFirstFile("./patches/*.mpq",&fil); - if(hFil==INVALID_HANDLE_VALUE) - return; //no patches were found - - do - { - LoadPatchMD5(fil.cFileName); - } - while(FindNextFile(hFil,&fil)); -} -#endif - -/// Calculate and store MD5 hash for a given patch file -void Patcher::LoadPatchMD5(char * szFileName) -{ - ///- Try to open the patch file - std::string path = "./patches/"; - path += szFileName; - FILE * pPatch=fopen(path.c_str(),"rb"); - sLog.outDebug("Loading patch info from %s\n",path.c_str()); - if(!pPatch) - { - sLog.outError("Error loading patch %s\n",path.c_str()); - return; - } - - ///- Calculate the MD5 hash - MD5_CTX ctx; - MD5_Init(&ctx); - uint8* buf = new uint8[512*1024]; - - while (!feof(pPatch)) - { - size_t read = fread(buf, 1, 512*1024, pPatch); - MD5_Update(&ctx, buf, read); - } - delete [] buf; - fclose(pPatch); - - ///- Store the result in the internal patch hash map - _patches[path] = new PATCH_INFO; - MD5_Final((uint8 *)&_patches[path]->md5 , &ctx); -} - -/// Get cached MD5 hash for a given patch file -bool Patcher::GetHash(char * pat,uint8 mymd5[16]) -{ - for( Patches::iterator i = _patches.begin(); i != _patches.end(); i++ ) - if(!stricmp(pat,i->first.c_str () )) - { - memcpy(mymd5,i->second->md5,16); - return true; - } - - return false; -} - -/// Launch the patch hashing mechanism on object creation -Patcher::Patcher() -{ - LoadPatchesInfo(); -} - -/// Empty and delete the patch map on termination -Patcher::~Patcher() -{ - for(Patches::iterator i = _patches.begin(); i != _patches.end(); i++ ) - delete i->second; -} diff --git a/src/realmd/AuthSocket.h b/src/realmd/AuthSocket.h deleted file mode 100644 index 3cae54c7789..00000000000 --- a/src/realmd/AuthSocket.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 - */ - -/// \addtogroup realmd -/// @{ -/// \file - -#ifndef _AUTHSOCKET_H -#define _AUTHSOCKET_H - -#include "Common.h" -#include "Auth/BigNumber.h" -#include "sockets/TcpSocket.h" -#include "sockets/SocketHandler.h" -#include "sockets/ListenSocket.h" -#include "sockets/Utility.h" -#include "sockets/Parse.h" -#include "sockets/Socket.h" -#include "zthread/Mutex.h" - -/// Handle login commands -class AuthSocket: public TcpSocket -{ - public: - const static int s_BYTE_SIZE = 32; - - AuthSocket(ISocketHandler& h); - ~AuthSocket(); - - void OnAccept(); - void OnRead(); - - bool _HandleLogonChallenge(); - bool _HandleLogonProof(); - bool _HandleReconnectChallenge(); - bool _HandleReconnectProof(); - bool _HandleRealmList(); - //data transfer handle for patch - - bool _HandleXferResume(); - bool _HandleXferCancel(); - bool _HandleXferAccept(); - - void _SetVSFields(const std::string& rI); - - FILE *pPatch; - ZThread::Mutex patcherLock; - bool IsLag(); - - private: - - BigNumber N, s, g, v; - BigNumber b, B; - BigNumber K; - BigNumber _reconnectProof; - - bool _authed; - - std::string _login; - std::string _safelogin; - - // Since GetLocaleByName() is _NOT_ bijective, we have to store the locale as a string. Otherwise we can't differ - // between enUS and enGB, which is important for the patch system - std::string _localizationName; - uint16 _build; - AccountTypes _accountSecurityLevel; -}; -#endif -/// @} diff --git a/src/realmd/CMakeLists.txt b/src/realmd/CMakeLists.txt deleted file mode 100644 index ab03c3143a5..00000000000 --- a/src/realmd/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -########### next target ############### - -SET(trinity-realm_SRCS -AuthCodes.h -AuthSocket.cpp -AuthSocket.h -Main.cpp -RealmList.cpp -RealmList.h -) - -add_executable(trinity-realm ${trinity-realm_SRCS}) -add_definitions( --D_TRINITY_REALM_CONFIG='"${CONF_DIR}/trinityrealm.conf"' -) -IF (DO_MYSQL) - #SET_TARGET_PROPERTIES(mangos-realmd PROPERTIES LINK_FLAGS ${MYSQL_LIBS}) - SET_TARGET_PROPERTIES(trinity-realm PROPERTIES LINK_FLAGS "-pthread") -ENDIF(DO_MYSQL) -IF (DO_POSTGRE) - SET_TARGET_PROPERTIES(trinity-realmd PROPERTIES LINK_FLAGS ${POSTGRE_LIBS}) -ENDIF(DO_POSTGRE) - - -target_link_libraries( -trinity-realm -shared -trinityframework -trinitysockets -trinitydatabase -trinityauth -trinityconfig -ZThread -zlib -${SSLLIB} -${MYSQL_LIBRARIES} -) - -install(TARGETS trinity-realm DESTINATION bin) - - -########### install files ############### - -install(FILES realmd.conf.dist.in DESTINATION etc) - diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp deleted file mode 100644 index bd318779f83..00000000000 --- a/src/realmd/Main.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 - */ - -/// \addtogroup realmd Realm Daemon -/// @{ -/// \file - -#include "Common.h" -#include "Database/DatabaseEnv.h" -#include "RealmList.h" - -#include "Config/ConfigEnv.h" -#include "Log.h" -#include "sockets/ListenSocket.h" -#include "AuthSocket.h" -#include "SystemConfig.h" -#include "Util.h" - -// Format is YYYYMMDDRR where RR is the change in the conf file -// for that day. -#ifndef _REALMDCONFVERSION -# define _REALMDCONFVERSION 2007062001 -#endif - -#ifndef _TRINITY_REALM_CONFIG -# define _TRINITY_REALM_CONFIG "TrinityRealm.conf" -#endif //_TRINITY_REALM_CONFIG - -#ifdef WIN32 -#include "ServiceWin32.h" -char serviceName[] = "TrinityRealm"; -char serviceLongName[] = "Trinity realm service"; -char serviceDescription[] = "Massive Network Game Object Server"; -/* - * -1 - not in service mode - * 0 - stopped - * 1 - running - * 2 - paused - */ -int m_ServiceStatus = -1; -#endif - -bool StartDB(); -void UnhookSignals(); -void HookSignals(); - -bool stopEvent = false; ///< Setting it to true stops the server -RealmList m_realmList; ///< Holds the list of realms for this server - -DatabaseType LoginDatabase; ///< Accessor to the realm server database - -/// Print out the usage string for this program on the console. -void usage(const char *prog) -{ - sLog.outString("Usage: \n %s [<options>]\n" - " -c config_file use config_file as configuration file\n\r" - #ifdef WIN32 - " Running as service functions:\n\r" - " --service run as service\n\r" - " -s install install service\n\r" - " -s uninstall uninstall service\n\r" - #endif - ,prog); -} - -/// Launch the realm server -extern int main(int argc, char **argv) -{ - ///- Command line parsing to get the configuration file name - char const* cfg_file = _TRINITY_REALM_CONFIG; - int c=1; - while( c < argc ) - { - if( strcmp(argv[c],"-c") == 0) - { - if( ++c >= argc ) - { - sLog.outError("Runtime-Error: -c option requires an input argument"); - usage(argv[0]); - return 1; - } - else - cfg_file = argv[c]; - } - - #ifdef WIN32 - //////////// - //Services// - //////////// - if( strcmp(argv[c],"-s") == 0) - { - if( ++c >= argc ) - { - sLog.outError("Runtime-Error: -s option requires an input argument"); - usage(argv[0]); - return 1; - } - if( strcmp(argv[c],"install") == 0) - { - if (WinServiceInstall()) - sLog.outString("Installing service"); - return 1; - } - else if( strcmp(argv[c],"uninstall") == 0) - { - if(WinServiceUninstall()) - sLog.outString("Uninstalling service"); - return 1; - } - else - { - sLog.outError("Runtime-Error: unsupported option %s",argv[c]); - usage(argv[0]); - return 1; - } - } - if( strcmp(argv[c],"--service") == 0) - { - WinServiceRun(); - } - //// - #endif - ++c; - } - - if (!sConfig.SetSource(cfg_file)) - { - sLog.outError("Could not find configuration file %s.", cfg_file); - return 1; - } - sLog.outString("Using configuration file %s.", cfg_file); - - ///- Check the version of the configuration file - uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); - if (confVersion < _REALMDCONFVERSION) - { - sLog.outError("*****************************************************************************"); - sLog.outError(" WARNING: Your trinityrealm.conf version indicates your conf file is out of date!"); - sLog.outError(" Please check for updates, as your current default values may cause"); - sLog.outError(" strange behavior."); - sLog.outError("*****************************************************************************"); - clock_t pause = 3000 + clock(); - - while (pause > clock()) {} - } - - sLog.outString( "%s (realm-daemon)", _FULLVERSION ); - sLog.outString( "<Ctrl-C> to stop.\n" ); - - /// realmd PID file creation - std::string pidfile = sConfig.GetStringDefault("PidFile", ""); - if(!pidfile.empty()) - { - uint32 pid = CreatePIDFile(pidfile); - if( !pid ) - { - sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); - return 1; - } - - sLog.outString( "Daemon PID: %u\n", pid ); - } - - ///- Initialize the database connection - if(!StartDB()) - return 1; - - ///- Initialize the log database - if(sConfig.GetBoolDefault("EnableLogDB", false)) - { - // everything successful - set var to enable DB logging once startup finished. - sLog.SetLogDBLater(true); - // ensure we've set realm to 0 (realmd realmid) - sLog.SetRealmID(0); - } - - ///- Get the list of realms for the server - m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); - if (m_realmList.size() == 0) - { - sLog.outError("No valid realms specified."); - return 1; - } - - ///- 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"); - - SocketHandler h; - ListenSocket<AuthSocket> authListenSocket(h); - if ( authListenSocket.Bind(bind_ip.c_str(),rmport)) - { - sLog.outError( "Trinity realm can not bind to %s:%d",bind_ip.c_str(), rmport ); - return 1; - } - - h.Add(&authListenSocket); - - ///- Catch termination signals - HookSignals(); - - ///- Handle affinity for multiple processors and process priority on Windows - #ifdef WIN32 - { - HANDLE hProcess = GetCurrentProcess(); - - uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); - if(Aff > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) - { - ULONG_PTR curAff = Aff & appAff; // remove non accessible processors - - if(!curAff ) - { - sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); - } - else - { - if(SetProcessAffinityMask(hProcess,curAff)) - sLog.outString("Using processors (bitmask, hex): %x", curAff); - else - sLog.outError("Can't set used processors (hex): %x", curAff); - } - } - sLog.outString(""); - } - - bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); - - if(Prio) - { - if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) - sLog.outString("TrinityRealm process priority class set to HIGH"); - else - sLog.outError("ERROR: Can't set realmd process priority class."); - sLog.outString(""); - } - } - #endif - - // maximum counter for next ping - uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); - uint32 loopCounter = 0; - - // possibly enable db logging; avoid massive startup spam by doing it here. - if (sLog.GetLogDBLater()) - { - sLog.outString("Enabling database logging..."); - sLog.SetLogDBLater(false); - // login db needs thread for logging - sLog.SetLogDB(true); - } - - ///- Wait for termination signal - while (!stopEvent) - { - - h.Select(0, 100000); - - if( (++loopCounter) == numLoops ) - { - loopCounter = 0; - sLog.outDetail("Ping MySQL to keep connection alive"); - delete LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); - } -#ifdef WIN32 - if (m_ServiceStatus == 0) stopEvent = true; - while (m_ServiceStatus == 2) Sleep(1000); -#endif - } - - ///- Wait for the delay thread to exit - LoginDatabase.ThreadEnd(); - LoginDatabase.HaltDelayThread(); - - ///- Remove signal handling before leaving - UnhookSignals(); - - sLog.outString( "Halting process..." ); - return 0; -} - -/// Handle termination signals -/** Put the global variable stopEvent to 'true' if a termination signal is caught **/ -void OnSignal(int s) -{ - switch (s) - { - case SIGINT: - case SIGTERM: - stopEvent = true; - break; - #ifdef _WIN32 - case SIGBREAK: - stopEvent = true; - break; - #endif - } - - signal(s, OnSignal); -} - -/// Initialize connection to the database -bool StartDB() -{ - std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); - if(dbstring.empty()) - { - sLog.outError("Database not specified"); - return false; - } - - if(!LoginDatabase.Initialize(dbstring.c_str())) - { - sLog.outError("Cannot connect to database"); - return false; - } - LoginDatabase.ThreadStart(); - - return true; -} - -/// Define hook 'OnSignal' for all termination signals -void HookSignals() -{ - signal(SIGINT, OnSignal); - signal(SIGTERM, OnSignal); - #ifdef _WIN32 - signal(SIGBREAK, OnSignal); - #endif -} - -/// Unhook the signals before leaving -void UnhookSignals() -{ - signal(SIGINT, 0); - signal(SIGTERM, 0); - #ifdef _WIN32 - signal(SIGBREAK, 0); - #endif -} - -/// @} diff --git a/src/realmd/Makefile.am b/src/realmd/Makefile.am deleted file mode 100644 index a14b50c847a..00000000000 --- a/src/realmd/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> -# -# Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 - -## Process this file with automake to produce Makefile.in - -## CPP flags for includes, defines, etc. -AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\" - -## Build realm list daemon as standalone program -bin_PROGRAMS = trinity-realmd -trinity_realmd_SOURCES = \ - AuthCodes.h \ - AuthSocket.cpp \ - AuthSocket.h \ - Main.cpp \ - RealmList.cpp \ - RealmList.h - -## Link realm list daemon against the shared library -trinity_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 -trinity_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libdir) $(TRINI_LIBS) - -## Additional files to include when running 'make dist' -# Include realm list daemon configuration -EXTRA_DIST = \ - realmd.conf.dist - -## Additional files to install -sysconf_DATA = \ - realmd.conf.dist - -install-data-hook: - @list='$(sysconf_DATA)'; for p in $$list; do \ - dest=`echo $$p | sed -e s/.dist//`; \ - if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \ - echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \ - else \ - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \ - $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \ - fi; \ - done - -clean-local: - rm -f $(sysconf_DATA) diff --git a/src/realmd/RealmList.cpp b/src/realmd/RealmList.cpp deleted file mode 100644 index 936f7bcd703..00000000000 --- a/src/realmd/RealmList.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 -*/ - -#include "Common.h" -#include "RealmList.h" -#include "Policies/SingletonImp.h" -#include "Database/DatabaseEnv.h" - -INSTANTIATE_SINGLETON_1( RealmList ); - -extern DatabaseType LoginDatabase; - -RealmList::RealmList( ) : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) -{ -} - -/// Load the realm list from the database -void RealmList::Initialize(uint32 updateInterval) -{ - m_UpdateInterval = updateInterval; - - ///- Get the content of the realmlist table in the database - UpdateRealms(true); -} - -void RealmList::UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu) -{ - ///- Create new if not exist or update existed - Realm& realm = m_realms[name]; - - realm.m_ID = ID; - realm.icon = icon; - realm.color = color; - realm.timezone = timezone; - realm.allowedSecurityLevel = allowedSecurityLevel; - realm.populationLevel = popu; - - ///- Append port to IP address. - std::ostringstream ss; - ss << address << ":" << port; - realm.address = ss.str(); -} - -void RealmList::UpdateIfNeed() -{ - // maybe disabled or updated recently - if(!m_UpdateInterval || m_NextUpdateTime > time(NULL)) - return; - - m_NextUpdateTime = time(NULL) + m_UpdateInterval; - - // Clears Realm list - m_realms.clear(); - - // Get the content of the realmlist table in the database - UpdateRealms(false); -} - -void RealmList::UpdateRealms(bool init) -{ - sLog.outDetail("Updating Realm List..."); - - QueryResult *result = LoginDatabase.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population FROM realmlist WHERE color <> 3 ORDER BY name" ); - - ///- Circle through results and add them to the realm map - if(result) - { - do - { - Field *fields = result->Fetch(); - - uint8 allowedSecurityLevel = fields[7].GetUInt8(); - - UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat() ); - if(init) - sLog.outString("Added realm \"%s\".", fields[1].GetString()); - } while( result->NextRow() ); - delete result; - } -} diff --git a/src/realmd/RealmList.h b/src/realmd/RealmList.h deleted file mode 100644 index b830a0827a7..00000000000 --- a/src/realmd/RealmList.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.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 - */ - -/// \addtogroup realmd -/// @{ -/// \file - -#ifndef _REALMLIST_H -#define _REALMLIST_H - -#include "Common.h" - -/// Storage object for a realm -struct Realm -{ - std::string address; - uint8 icon; - uint8 color; - uint8 timezone; - uint32 m_ID; - AccountTypes allowedSecurityLevel; - float populationLevel; -}; - -/// Storage object for the list of realms on the server -class RealmList -{ - public: - typedef std::map<std::string, Realm> RealmMap; - - RealmList(); - ~RealmList() {} - - void Initialize(uint32 updateInterval); - - void UpdateIfNeed(); - - RealmMap::const_iterator begin() const { return m_realms.begin(); } - RealmMap::const_iterator end() const { return m_realms.end(); } - uint32 size() const { return m_realms.size(); } - private: - void UpdateRealms(bool init); - void UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu); - private: - RealmMap m_realms; ///< Internal map of realms - uint32 m_UpdateInterval; - time_t m_NextUpdateTime; -}; -#endif -/// @} diff --git a/src/realmd/TrinityRealm.ico b/src/realmd/TrinityRealm.ico Binary files differdeleted file mode 100644 index da318f48a8c..00000000000 --- a/src/realmd/TrinityRealm.ico +++ /dev/null diff --git a/src/realmd/realmd.conf.dist.in b/src/realmd/realmd.conf.dist.in deleted file mode 100644 index 439f7f21200..00000000000 --- a/src/realmd/realmd.conf.dist.in +++ /dev/null @@ -1,122 +0,0 @@ -########################################## -# Trinity Core realmd configuration file # -########################################## -ConfVersion=2007062001 - -################################################################################################################### -# REALMD SETTINGS -# -# LoginDatabaseInfo -# Database connection settings for the realm server. -# Default: hostname;port;username;password;database -# .;somenumber;username;password;database - use named pipes at Windows -# Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini -# .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux -# Unix sockets: experimental, not tested -# -# LogsDir -# Logs directory setting. -# Important: Logs dir must exists, or all logs be disable -# Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be -# stored in current directory for run program. -# -# MaxPingTime -# Settings for maximum database-ping interval (minutes between pings) -# -# RealmServerPort -# Default RealmServerPort -# -# BindIP -# Bind Realm Server to IP/hostname -# -# PidFile -# Realmd daemon PID file -# Default: "" - do not create PID file -# "./realmd.pid" - create PID file (recommended name) -# -# LogLevel -# Server console level of logging -# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug -# Default: 0 -# -# LogFile -# Logfile name -# Default: "realmd.log" -# "" - empty name disable creating log file -# -# LogTimestamp -# Logfile with timestamp of server start in name -# Default: 0 - no timestamp in name -# 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# -# LogFileLevel -# Server file level of logging -# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug -# Default: 0 -# -# LogColors -# Color for messages (format "normal error basic detail debug") -# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY, -# 8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE -# Default: "" - none colors -# Example: "13 7 11 9 5" -# -# EnableLogDB -# Enable/disable logging to database (LogDatabaseInfo). -# Default: 0 - disabled -# 1 - enabled -# -# DBLogLevel -# Log level of DB logging. -# 0 = Minimum; 1 = Basic; 2 = Detail; 3 = Full/Debug -# Default: 3 -# -# UseProcessors -# Used processors mask for multi-processors system (Used only at Windows) -# Default: 0 (selected by OS) -# number (bitmask value of selected processors) -# -# ProcessPriority -# Process proirity setting (Used only at Windows) -# Default: 1 (HIGH) -# 0 (Normal) -# -# RealmsStateUpdateDelay -# Realm list Update up delay (updated at realm list request if delay expired). -# Default: 20 -# 0 (Disabled) -# -# WrongPass.MaxCount -# Number of login attemps with wrong password before the account or IP is banned -# Default: 0 (Never ban) -# -# WrongPass.BanTime -# Duration of the ban in seconds (0 means permanent ban) -# Default: 600 -# -# WrongPass.BanType -# Ban the IP or account on which login is attempted -# Default: 0 (Ban IP) -# 1 (Ban Account) -# -################################################################################################################### - -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;realmd" -LogsDir = "" -MaxPingTime = 30 -RealmServerPort = 3724 -BindIP = "0.0.0.0" -PidFile = "" -LogLevel = 0 -LogFile = "realmd.log" -LogTimestamp = 0 -LogFileLevel = 0 -UseProcessors = 0 -ProcessPriority = 1 -RealmsStateUpdateDelay = 20 -WrongPass.MaxCount = 0 -WrongPass.BanTime = 600 -WrongPass.BanType = 0 -LogColors = "" -EnableLogDB = 0 -DBLogLevel = 1 diff --git a/src/realmd/realmd.rc b/src/realmd/realmd.rc deleted file mode 100644 index bcd37f240c5..00000000000 --- a/src/realmd/realmd.rc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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 - */ - -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "windows.h" //"afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APPICON ICON "TrinityRealm.ico" - -///////////////////////////////////////////////////////////////////////////// -// Neutre (Par défaut système) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,6743,685 - PRODUCTVERSION 0,4,6743,685 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x0L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080004b0" - BEGIN - VALUE "FileDescription", "TrinityRealm" - VALUE "FileVersion", "0, 4, 6743, 685" - VALUE "InternalName", "TrinityRealm" - VALUE "LegalCopyright", "Copyright (C) 2008" - VALUE "OriginalFilename", "TrinityRealm.exe" - VALUE "ProductName", "TrinityRealm" - VALUE "ProductVersion", "0, 4, 6743, 685" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x800, 1200 - END -END -#endif diff --git a/src/realmd/resource.h b/src/realmd/resource.h deleted file mode 100644 index 7e7d8e4b76f..00000000000 --- a/src/realmd/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by TrinityCore.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif |