diff options
author | XTZGZoReX <none@none> | 2010-06-06 23:08:35 +0200 |
---|---|---|
committer | XTZGZoReX <none@none> | 2010-06-06 23:08:35 +0200 |
commit | a9f575a7eb2bc46d7548d787250c81060240fb01 (patch) | |
tree | 622473786c4ae01ce2899bed5dde4b8e5b5f4f32 /src | |
parent | f27daddd1b95616b7e68bc384eeffb3c62e9bdd2 (diff) |
* Delivering file deletions...
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/server/authserver/AuthCodes.cpp | 37 | ||||
-rw-r--r-- | src/server/authserver/AuthCodes.h | 97 | ||||
-rw-r--r-- | src/server/authserver/AuthSocket.cpp | 1069 | ||||
-rw-r--r-- | src/server/authserver/AuthSocket.h | 97 | ||||
-rw-r--r-- | src/server/authserver/RealmAcceptor.h | 52 | ||||
-rw-r--r-- | src/server/authserver/RealmList.cpp | 100 | ||||
-rw-r--r-- | src/server/authserver/RealmList.h | 79 | ||||
-rw-r--r-- | src/server/authserver/RealmSocket.cpp | 324 | ||||
-rw-r--r-- | src/server/authserver/RealmSocket.h | 85 | ||||
-rw-r--r-- | src/server/worldserver/CliRunnable.cpp | 445 | ||||
-rw-r--r-- | src/server/worldserver/CliRunnable.h | 35 | ||||
-rw-r--r-- | src/server/worldserver/RASocket.cpp | 265 | ||||
-rw-r--r-- | src/server/worldserver/RASocket.h | 68 | ||||
-rw-r--r-- | src/server/worldserver/WorldRunnable.cpp | 97 | ||||
-rw-r--r-- | src/server/worldserver/WorldRunnable.h | 35 |
15 files changed, 0 insertions, 2885 deletions
diff --git a/src/server/authserver/AuthCodes.cpp b/src/server/authserver/AuthCodes.cpp deleted file mode 100644 index 812949e0823..00000000000 --- a/src/server/authserver/AuthCodes.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "AuthCodes.h" - -namespace AuthHelper -{ - -bool IsPreBCAcceptedClientBuild(int build) -{ - int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) - { - if (build == accepted_versions[i]) - { - return true; - } - } - return false; -} - -bool IsPostBCAcceptedClientBuild(int build) -{ - int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) - { - if (build == accepted_versions[i]) - { - return true; - } - } - return false; -} - -bool IsAcceptedClientBuild(int build) -{ - return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); -} - -}; diff --git a/src/server/authserver/AuthCodes.h b/src/server/authserver/AuthCodes.h deleted file mode 100644 index eb6e4abfb08..00000000000 --- a/src/server/authserver/AuthCodes.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 AuthResult -{ - WOW_SUCCESS = 0x00, - WOW_FAIL_UNKNOWN0 = 0x01, ///< ? Unable to connect - WOW_FAIL_UNKNOWN1 = 0x02, ///< ? Unable to connect - WOW_FAIL_BANNED = 0x03, ///< This <game> account has been closed and is no longer available for use. Please go to <site>/banned.html for further information. - WOW_FAIL_UNKNOWN_ACCOUNT = 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 - WOW_FAIL_INCORRECT_PASSWORD = 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 - WOW_FAIL_ALREADY_ONLINE = 0x06, ///< This account is already logged into <game>. Please check the spelling and try again. - WOW_FAIL_NO_TIME = 0x07, ///< You have used up your prepaid time for this account. Please purchase more to continue playing - WOW_FAIL_DB_BUSY = 0x08, ///< Could not log in to <game> at this time. Please try again later. - WOW_FAIL_VERSION_INVALID = 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. - WOW_FAIL_VERSION_UPDATE = 0x0A, ///< Downloading - WOW_FAIL_INVALID_SERVER = 0x0B, ///< Unable to connect - WOW_FAIL_SUSPENDED = 0x0C, ///< This <game> account has been temporarily suspended. Please go to <site>/banned.html for further information - WOW_FAIL_FAIL_NOACCESS = 0x0D, ///< Unable to connect - WOW_SUCCESS_SURVEY = 0x0E, ///< Connected. - WOW_FAIL_PARENTCONTROL = 0x0F, ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at <site> - WOW_FAIL_LOCKED_ENFORCED = 0x10, ///< You have applied a lock to your account. You can change your locked status by calling your account lock phone number. - WOW_FAIL_TRIAL_ENDED = 0x11, ///< Your trial subscription has expired. Please visit <site> to upgrade your account. - WOW_FAIL_USE_BATTLENET = 0x12, ///< WOW_FAIL_OTHER This account is now attached to a Battle.net account. Please login with your Battle.net account email address and password. -}; - -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, -}; - -//multirealm supported versions: -//1.12.1 build 5875 -//1.12.2 build 6005 -//2.4.3 build 8606 -//3.1.3 build 9947 -//3.1.3 build 10146 Chinese build -//3.2.2a build 10505 -//3.3.0a build 11159 -//3.3.2 build 11403 -//3.3.3a build 11723 - -#define POST_BC_ACCEPTED_CLIENT_BUILD {11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} -#define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} - -#define POST_BC_EXP_FLAG 0x2 -#define PRE_BC_EXP_FLAG 0x1 -#define NO_VALID_EXP_FLAG 0x0 - -namespace AuthHelper -{ - bool IsAcceptedClientBuild(int build); - bool IsPostBCAcceptedClientBuild(int build); - bool IsPreBCAcceptedClientBuild(int build); -}; - -#endif diff --git a/src/server/authserver/AuthSocket.cpp b/src/server/authserver/AuthSocket.cpp deleted file mode 100644 index cc293097977..00000000000 --- a/src/server/authserver/AuthSocket.cpp +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 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 struct AUTH_LOGON_PROOF_C -{ - uint8 cmd; - uint8 A[32]; - uint8 M1[20]; - uint8 crc_hash[20]; - uint8 number_of_keys; - uint8 securityFlags; // 0x00-0x04 -} sAuthLogonProof_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_LOGON_PROOF_S_OLD -{ - uint8 cmd; - uint8 error; - uint8 M2[20]; - //uint32 unk1; - uint32 unk2; - //uint16 unk3; -} sAuthLogonProof_S_Old; - -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 ACE_Based::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(RealmSocket& socket) : socket_(socket) -{ - N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword(7); - _authed = false; - _accountSecurityLevel = SEC_PLAYER; -} - -/// Close patch file descriptor before leaving -AuthSocket::~AuthSocket(void) -{ -} - -/// Accept the connection and set the s random value for SRP6 -void AuthSocket::OnAccept(void) -{ - sLog.outBasic("Accepting connection from '%s'", socket().get_remote_address().c_str()); -} - -void AuthSocket::OnClose(void) -{ - sLog.outDebug("AuthSocket::OnClose"); -} - -/// Read the packet from the client -void AuthSocket::OnRead() -{ - uint8 _cmd; - while (1) - { - if (!socket().recv_soft((char *)&_cmd, 1)) - return; - - 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 recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); - - if (!(*this.*table[i].handler)()) - { - DEBUG_LOG("Command handler failed for cmd %u recv length %u", (uint32)_cmd, (uint32)socket().recv_len()); - return; - } - break; - } - } - - // Report unknown packets in the error log - if (i == AUTH_TOTAL_COMMANDS) - { - sLog.outError("[Auth] got unknown packet from '%s'", socket().get_remote_address().c_str()); - socket().shutdown(); - return; - } - } -} - -/// Make the SRP6 calculation from hash in dB -void AuthSocket::_SetVSFields(const std::string& rI) -{ - s.SetRand(s_BYTE_SIZE * 8); - - BigNumber I; - I.SetHexStr(rI.c_str()); - - // In case of leading zeros 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 (socket().recv_len() < 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); - - socket().recv((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()) || (socket().recv_len() < 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 - socket().recv((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); - - // 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); - - ByteBuffer pkt; - - _login = (const char*)ch->I; - _build = ch->build; - _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) + (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); - - ///- 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); - - _build = ch->build; - - 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(socket().get_remote_address().c_str()); - LoginDatabase.escape_string(address); - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); - if (result) - { - pkt << (uint8)WOW_FAIL_BANNED; - sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!", address.c_str ()); - } - else - { - ///- Get the account details from the account table - // No SQL injection (escaped user name) - - result = LoginDatabase.PQuery("SELECT a.sha_pass_hash,a.id,a.locked,a.last_ip,aa.gmlevel,a.v,a.s " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id) " - "WHERE a.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'", socket().get_remote_address().c_str()); - if (strcmp((*result)[3].GetString(),socket().get_remote_address().c_str())) - { - DEBUG_LOG("[AuthChallenge] Account IP differs"); - pkt << (uint8) WOW_FAIL_SUSPENDED; - 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_AutoPtr 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) WOW_FAIL_BANNED; - sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); - } - else - { - pkt << (uint8) WOW_FAIL_SUSPENDED; - sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); - } - } - else - { - ///- Get the password from the account table, upper it, and make the SRP6 calculation - std::string rI = (*result)[0].GetCppString(); - - ///- Don't calculate (v, s) if there are already some in the database - std::string databaseV = (*result)[5].GetCppString(); - std::string databaseS = (*result)[6].GetCppString(); - - sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); - - // multiply with 2, bytes are stored as hexstring - if (databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2) - _SetVSFields(rI); - else - { - s.SetHexStr(databaseS.c_str()); - v.SetHexStr(databaseV.c_str()); - } - - 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(WOW_SUCCESS); - - // B may be calculated < 32B so we force minimal 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), 32); - pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes - pkt.append(unk3.AsByteArray(16), 16); - uint8 securityFlags = 0; - pkt << uint8(securityFlags); // security flags (0x0...0x04) - - if (securityFlags & 0x01) // PIN input - { - pkt << uint32(0); - pkt << uint64(0) << uint64(0); // 16 bytes hash? - } - - if (securityFlags & 0x02) // Matrix input - { - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint8(0); - pkt << uint64(0); - } - - if (securityFlags & 0x04) // Security token input - pkt << uint8(1); - - 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)); - } - } - } - else //no account - { - pkt<< (uint8) WOW_FAIL_UNKNOWN_ACCOUNT; - } - } - - socket().send((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Logon Proof command handler -bool AuthSocket::_HandleLogonProof() -{ - DEBUG_LOG("Entering _HandleLogonProof"); - ///- Read the packet - sAuthLogonProof_C lp; - - if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) - return false; - - /// <ul><li> If the client has no valid version - if (_expversion == NO_VALID_EXP_FLAG) - { - ///- Check if we have the appropriate patch on the disk - - sLog.outDebug("Client with invalid version, patching is not implemented"); - socket().shutdown(); - return true; - } - /// </ul> - - ///- Continue the SRP6 calculation based on data received from the client - BigNumber A; - - A.SetBinary(lp.A, 32); - - // SRP safeguard: abort if A==0 - if (A.isZero()) - { - socket().shutdown(); - return true; - } - - 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), 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, socket().get_remote_address().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(); - - if (_expversion & POST_BC_EXP_FLAG)//2.4.3 and 3.1.3 clients (10146 is Chinese build for 3.1.3) - { - 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; - socket().send((char *)&proof, sizeof(proof)); - } - else - { - sAuthLogonProof_S_Old proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - //proof.unk1 = 0x00800000; - proof.unk2 = 0x00; - //proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); - } - - ///- Set _authed to true! - _authed = true; - } - else - { - char data[4]= { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0}; - socket().send(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_AutoPtr 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(socket().get_remote_address().c_str()); - 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); - } - } - } - } - } - - return true; -} - -/// Reconnect Challenge command handler -bool AuthSocket::_HandleReconnectChallenge() -{ - DEBUG_LOG("Entering _HandleReconnectChallenge"); - if (socket().recv_len() < 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); - - socket().recv((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()) || (socket().recv_len() < 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 - socket().recv((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_AutoPtr 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()); - socket().shutdown(); - return false; - } - - Field* fields = result->Fetch (); - K.SetHexStr (fields[0].GetString ()); - - ///- Sending response - ByteBuffer pkt; - pkt << (uint8) AUTH_RECONNECT_CHALLENGE; - pkt << (uint8) 0x00; - _reconnectProof.SetRand(16 * 8); - pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random - pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros - socket().send((char const*)pkt.contents(), pkt.size()); - return true; -} - -/// Reconnect Proof command handler -bool AuthSocket::_HandleReconnectProof() -{ - DEBUG_LOG("Entering _HandleReconnectProof"); - ///- Read the packet - sAuthReconnectProof_C lp; - if (!socket().recv((char *)&lp, sizeof(sAuthReconnectProof_C))) - return false; - - if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) - return false; - - 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 - socket().send((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()); - socket().shutdown(); - return false; - } -} - -/// %Realm List command handler -bool AuthSocket::_HandleRealmList() -{ - DEBUG_LOG("Entering _HandleRealmList"); - if (socket().recv_len() < 5) - return false; - - socket().recv_skip(5); - - ///- Get the user id (else close the connection) - // No SQL injection (escaped user name) - - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT id 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()); - socket().shutdown(); - return false; - } - - uint32 id = (*result)[0].GetUInt32(); - - ///- Update realm list if need - sRealmList->UpdateIfNeed(); - - ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) - ByteBuffer pkt; - - size_t RealmListSize = 0; - for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) - { - // don't work with realms which not compatible with the client - if (_expversion & POST_BC_EXP_FLAG) // 2.4.3 and 3.1.3 cliens - { - if (i->second.gamebuild != _build) - continue; - } - else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother - { - if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) - continue; - } - - 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(); - } - else - AmountOfCharacters = 0; - - uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - - pkt << i->second.icon; // realm type - if ( _expversion & POST_BC_EXP_FLAG )//only 2.4.3 and 3.1.3 cliens - 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 - if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 clients - pkt << (uint8) 0x2C; // unk, may be realm number/id? - else - pkt << (uint8) 0x0; //1.12.1 and 1.12.2 clients - - ++RealmListSize; - } - - if ( _expversion & POST_BC_EXP_FLAG )//2.4.3 and 3.1.3 cliens - { - pkt << (uint8) 0x10; - pkt << (uint8) 0x00; - }else{//1.12.1 and 1.12.2 clients - pkt << (uint8) 0x00; - pkt << (uint8) 0x02; - } - - // make a ByteBuffer which stores the RealmList's size - ByteBuffer RealmListSizeBuffer; - RealmListSizeBuffer << (uint32)0; - if (_expversion & POST_BC_EXP_FLAG) // only 2.4.3 and 3.1.3 cliens - RealmListSizeBuffer << (uint16)RealmListSize; - else - RealmListSizeBuffer << (uint32)RealmListSize; - - ByteBuffer hdr; - hdr << (uint8) REALM_LIST; - hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); - hdr.append(RealmListSizeBuffer); // append RealmList's size buffer - hdr.append(pkt); // append realms in the realmlist - - socket().send((char const*)hdr.contents(), hdr.size()); - - return true; -} - -/// Resume patch transfer -bool AuthSocket::_HandleXferResume() -{ - DEBUG_LOG("Entering _HandleXferResume"); - ///- Check packet length and patch existence - if (socket().recv_len() < 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; - socket().recv_skip(1); - socket().recv((char*)&start,sizeof(start)); - fseek(pPatch, start, 0); - - ACE_Based::Thread u(new PatcherRunnable(this)); - return true; -} - -/// Cancel patch transfer -bool AuthSocket::_HandleXferCancel() -{ - DEBUG_LOG("Entering _HandleXferCancel"); - - ///- Close and delete the socket - socket().recv_skip(1); //clear input buffer - - socket().shutdown(); - - 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 beginning of the patch file - socket().recv_skip(1); // clear input buffer - fseek(pPatch, 0, 0); - - ACE_Based::Thread u(new PatcherRunnable(this)); - return true; -} - -PatcherRunnable::PatcherRunnable(class AuthSocket * as) -{ - mySocket = as; -} - -/// Send content of patch file to the client -void PatcherRunnable::run() -{ -} - -/// 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/server/authserver/AuthSocket.h b/src/server/authserver/AuthSocket.h deleted file mode 100644 index bfd0fa4fdca..00000000000 --- a/src/server/authserver/AuthSocket.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 "RealmSocket.h" - -enum RealmFlags -{ - REALM_FLAG_NONE = 0x00, - REALM_FLAG_INVALID = 0x01, - REALM_FLAG_OFFLINE = 0x02, - REALM_FLAG_SPECIFYBUILD = 0x04, // client will show realm version in RealmList screen in form "RealmName (major.minor.revision.build)" - REALM_FLAG_UNK1 = 0x08, - REALM_FLAG_UNK2 = 0x10, - REALM_FLAG_RECOMMENDED = 0x20, // client checks pop == 600f - REALM_FLAG_NEW = 0x40, // client checks pop == 200f - REALM_FLAG_FULL = 0x80 // client checks pop == 400f -}; - -/// Handle login commands -class AuthSocket: public RealmSocket::Session -{ - public: - const static int s_BYTE_SIZE = 32; - - AuthSocket(RealmSocket& socket); - virtual ~AuthSocket(void); - - virtual void OnRead(void); - virtual void OnAccept(void); - virtual void OnClose(void); - - 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; - ACE_Thread_Mutex patcherLock; - - private: - RealmSocket& socket_; - RealmSocket& socket(void) { return socket_; } - - 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; - uint8 _expversion; - AccountTypes _accountSecurityLevel; -}; -#endif -/// @} diff --git a/src/server/authserver/RealmAcceptor.h b/src/server/authserver/RealmAcceptor.h deleted file mode 100644 index 5e243ea915b..00000000000 --- a/src/server/authserver/RealmAcceptor.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 __REALMACCEPTOR_H__ -#define __REALMACCEPTOR_H__ - -#include <ace/Acceptor.h> -#include <ace/SOCK_Acceptor.h> - -#include "RealmSocket.h" -#include "AuthSocket.h" - -class RealmAcceptor : public ACE_Acceptor<RealmSocket, ACE_SOCK_Acceptor> -{ - public: - RealmAcceptor(void) { } - virtual ~RealmAcceptor(void) { } - - protected: - virtual int make_svc_handler(RealmSocket *&sh) - { - if (sh == 0) - ACE_NEW_RETURN(sh, RealmSocket, -1); - - sh->reactor(reactor()); - sh->set_session(new AuthSocket(*sh)); - return 0; - } -}; - -#endif /* __REALMACCEPTOR_H__ */ diff --git a/src/server/authserver/RealmList.cpp b/src/server/authserver/RealmList.cpp deleted file mode 100644 index 1e989c36c5d..00000000000 --- a/src/server/authserver/RealmList.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 "Database/DatabaseEnv.h" - - -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, uint32 build) -{ - ///- Create new if not exist or update existed - Realm& realm = m_realms[name]; - - realm.m_ID = ID; - realm.name = name; - 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(); - realm.gamebuild = build; -} - -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_AutoPtr result = LoginDatabase.Query("SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild 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(), fields[9].GetUInt32()); - if (init) - sLog.outString("Added realm \"%s\".", fields[1].GetString()); - } while(result->NextRow()); - } -} diff --git a/src/server/authserver/RealmList.h b/src/server/authserver/RealmList.h deleted file mode 100644 index b29b561c797..00000000000 --- a/src/server/authserver/RealmList.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 <ace/Singleton.h> -#include <ace/Null_Mutex.h> -#include "Common.h" - -/// Storage object for a realm -struct Realm -{ - std::string address; - std::string name; - uint8 icon; - uint8 color; - uint8 timezone; - uint32 m_ID; - AccountTypes allowedSecurityLevel; - float populationLevel; - uint32 gamebuild; -}; - -/// Storage object for the list of realms on the server -class RealmList -{ - public: - // Null_Mutex is safe because the singleton initialized before the acceptor initialized(another place where the singleton called) - static RealmList* instance() { return ACE_Singleton<RealmList, ACE_Null_Mutex>::instance(); } - - typedef std::map<std::string, Realm> RealmMap; - - RealmList(); - ~RealmList() {} - - void Initialize(uint32 updateInterval); - - void UpdateIfNeed(); - - void AddRealm(Realm NewRealm) {m_realms[NewRealm.name] = NewRealm;} - - 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, uint32 build); - private: - RealmMap m_realms; ///< Internal map of realms - uint32 m_UpdateInterval; - time_t m_NextUpdateTime; -}; - -#define sRealmList RealmList::instance() - -#endif -/// @} diff --git a/src/server/authserver/RealmSocket.cpp b/src/server/authserver/RealmSocket.cpp deleted file mode 100644 index 7eb96cb96f8..00000000000 --- a/src/server/authserver/RealmSocket.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 "RealmSocket.h" - -#include "Log.h" - -#include <ace/OS_NS_string.h> -#include <ace/INET_Addr.h> -#include <ace/SString.h> - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -RealmSocket::Session::Session(void) -{ -} - -RealmSocket::Session::~Session(void) -{ -} - -RealmSocket::RealmSocket(void): - session_(NULL), - input_buffer_(4096), - remote_address_() -{ - reference_counting_policy().value( - ACE_Event_Handler::Reference_Counting_Policy::ENABLED); - - msg_queue()->high_water_mark(8*1024*1024); - msg_queue()->low_water_mark(8*1024*1024); - -} - -RealmSocket::~RealmSocket(void) -{ - if (msg_queue()) - msg_queue()->close(); - - // delete RealmSocketObject must never be called from our code. - closing_ = true; - - if (session_) - delete session_; - - peer().close(); -} - -int RealmSocket::open(void * arg) -{ - ACE_INET_Addr addr; - - if (peer ().get_remote_addr (addr) == -1) - { - sLog.outError ("RealmSocket::open: peer ().get_remote_addr errno = %s", ACE_OS::strerror (errno)); - return -1; - } - - remote_address_ = addr.get_host_addr(); - - // Register with ACE Reactor - if (Base::open(arg) == -1) - return -1; - - if (session_ != NULL) - { - session_->OnAccept(); - } - - // reactor takes care of the socket from now on - remove_reference(); - - return 0; -} - -int RealmSocket::close(int) -{ - shutdown(); - - closing_ = true; - - remove_reference(); - - return 0; -} - -const ACE_CString& RealmSocket::get_remote_address(void) const -{ - return remote_address_; -} - -size_t RealmSocket::recv_len(void) const -{ - return input_buffer_.length(); -} - -bool RealmSocket::recv_soft(char *buf, size_t len) -{ - if (input_buffer_.length() < len) - return false; - - ACE_OS::memcpy(buf, input_buffer_.rd_ptr(), len); - - return true; -} - -bool RealmSocket::recv(char *buf, size_t len) -{ - bool ret = recv_soft(buf, len); - - if (ret) - recv_skip(len); - - return ret; -} - -void RealmSocket::recv_skip(size_t len) -{ - input_buffer_.rd_ptr(len); -} - -ssize_t RealmSocket::noblk_send(ACE_Message_Block &message_block) -{ - const size_t len = message_block.length(); - - if (len == 0) - return -1; - - // Try to send the message directly. - ssize_t n = peer().send(message_block.rd_ptr(), len, MSG_NOSIGNAL); - - if (n < 0) - { - if (errno == EWOULDBLOCK) - // Blocking signal - return 0; - else - // Error happened - return -1; - } - else if (n == 0) - { - // Can this happen ? - return -1; - } - - // return bytes transmitted - return n; -} - -bool RealmSocket::send(const char *buf, size_t len) -{ - if (buf == NULL || len == 0) - return true; - - ACE_Data_Block db( - len, - ACE_Message_Block::MB_DATA, - (const char*)buf, - 0, - 0, - ACE_Message_Block::DONT_DELETE, - 0); - - ACE_Message_Block message_block( - &db, - ACE_Message_Block::DONT_DELETE, - 0); - - message_block.wr_ptr(len); - - if (msg_queue()->is_empty()) - { - // Try to send it directly. - ssize_t n = noblk_send(message_block); - - if (n < 0) - return false; - else if (n == len) - return true; - - // fall down - message_block.rd_ptr((size_t)n); - } - - ACE_Message_Block *mb = message_block.clone(); - - if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - { - mb->release(); - return false; - } - - if (reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK) == -1) - return false; - - return true; -} - -int RealmSocket::handle_output(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) -{ - if (closing_) - return -1; - - ACE_Message_Block *mb = 0; - - if (msg_queue()->is_empty()) - { - reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK); - return 0; - } - - if (msg_queue()->dequeue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - return -1; - - ssize_t n = noblk_send(*mb); - - if (n < 0) - { - mb->release(); - return -1; - } - else if (n == mb->length()) - { - mb->release(); - return 1; - } - else - { - mb->rd_ptr(n); - - if (msg_queue()->enqueue_head(mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) - { - mb->release(); - return -1; - } - - return 0; - } - - ACE_NOTREACHED(return -1); -} - -int RealmSocket::handle_close(ACE_HANDLE h, ACE_Reactor_Mask /*m*/) -{ - // As opposed to WorldSocket::handle_close, we don't need locks here. - - closing_ = true; - - if (h == ACE_INVALID_HANDLE) - peer ().close_writer (); - - if (session_ != NULL) - { - session_->OnClose(); - } - - return 0; -} - -int RealmSocket::handle_input(ACE_HANDLE /*= ACE_INVALID_HANDLE*/) -{ - if (closing_) - return -1; - - const ssize_t space = input_buffer_.space(); - - ssize_t n = peer().recv(input_buffer_.wr_ptr(), space); - - if (n < 0) - { - return errno == EWOULDBLOCK ? 0 : -1; - } - else if (n == 0) - { - // EOF - return -1; - } - - input_buffer_.wr_ptr((size_t)n); - - if (session_ != NULL) - { - session_->OnRead(); - - input_buffer_.crunch(); - } - - // return 1 in case there is more data to read from OS - return n == space ? 1 : 0; -} - - -void RealmSocket::set_session(Session* session) -{ - if (session_ != NULL) - delete session_; - - session_ = session; -} - diff --git a/src/server/authserver/RealmSocket.h b/src/server/authserver/RealmSocket.h deleted file mode 100644 index 13be8327533..00000000000 --- a/src/server/authserver/RealmSocket.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 __REALMSOCKET_H__ -#define __REALMSOCKET_H__ - -#include <ace/Basic_Types.h> -#include <ace/Synch_Traits.h> -#include <ace/Svc_Handler.h> -#include <ace/SOCK_Stream.h> -#include <ace/Message_Block.h> -#include <ace/Basic_Types.h> - -class RealmSocket : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -{ - private: - typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> Base; - - public: - class Session - { - public: - Session(void); - virtual ~Session(void); - - virtual void OnRead(void) = 0; - virtual void OnAccept(void) = 0; - virtual void OnClose(void) = 0; - }; - - RealmSocket(void); - virtual ~RealmSocket(void); - - size_t recv_len(void) const; - bool recv_soft(char *buf, size_t len); - bool recv(char *buf, size_t len); - void recv_skip(size_t len); - - bool send(const char *buf, size_t len); - - const ACE_CString& get_remote_address(void) const; - - virtual int open(void *); - - virtual int close(int); - - virtual int handle_input(ACE_HANDLE = ACE_INVALID_HANDLE); - virtual int handle_output(ACE_HANDLE = ACE_INVALID_HANDLE); - - virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, - ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); - - void set_session(Session* session); - - private: - ssize_t noblk_send(ACE_Message_Block &message_block); - - private: - ACE_Message_Block input_buffer_; - Session* session_; - ACE_CString remote_address_; -}; - -#endif /* __REALMSOCKET_H__ */ diff --git a/src/server/worldserver/CliRunnable.cpp b/src/server/worldserver/CliRunnable.cpp deleted file mode 100644 index b39faf694db..00000000000 --- a/src/server/worldserver/CliRunnable.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -/// @{ -/// \file - -#include "Common.h" -#include "ObjectMgr.h" -#include "World.h" -#include "WorldSession.h" -#include "Config/ConfigEnv.h" - -#include "AccountMgr.h" -#include "Chat.h" -#include "CliRunnable.h" -#include "Language.h" -#include "Log.h" -#include "MapManager.h" -#include "Player.h" -#include "Util.h" - -#if PLATFORM != WINDOWS -#include <readline/readline.h> -#include <readline/history.h> - -char * command_finder(const char* text, int state) -{ - static int idx,len; - const char* ret; - ChatCommand *cmd = ChatHandler::getCommandTable(); - - if(!state) - { - idx = 0; - len = strlen(text); - } - - while(ret = cmd[idx].Name) - { - if(!cmd[idx].AllowConsole) - { - idx++; - continue; - } - - idx++; - //printf("Checking %s \n", cmd[idx].Name); - if (strncmp(ret, text, len) == 0) - return strdup(ret); - if(cmd[idx].Name == NULL) - break; - } - - return ((char*)NULL); -} - -char ** cli_completion(const char * text, int start, int end) -{ - char ** matches; - matches = (char**)NULL; - - if(start == 0) - matches = rl_completion_matches((char*)text,&command_finder); - else - rl_bind_key('\t',rl_abort); - return (matches); -} -#endif - -void utf8print(const char* str) -{ -#if PLATFORM == PLATFORM_WINDOWS - wchar_t wtemp_buf[6000]; - size_t wtemp_len = 6000-1; - if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) - return; - - char temp_buf[6000]; - CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); - printf(temp_buf); -#else -{ - va_list v; - vprintf(str, v); - va_end(v); - fflush(stdout); -} -#endif -} - -/// Delete a user account and all associated characters in this realm -/// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account -bool ChatHandler::HandleAccountDeleteCommand(const char* args) -{ - if(!*args) - return false; - - ///- Get the account name from the command line - char *account_name_str=strtok ((char*)args," "); - if (!account_name_str) - return false; - - std::string account_name = account_name_str; - if(!AccountMgr::normalizeString(account_name)) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - uint32 account_id = accmgr.GetId(account_name); - if(!account_id) - { - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - /// Commands not recommended call from chat, but support anyway - /// can delete only for account with less security - /// This is also reject self apply in fact - if(HasLowerSecurityAccount (NULL,account_id,true)) - return false; - - AccountOpResult result = accmgr.DeleteAccount(account_id); - switch(result) - { - case AOR_OK: - PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); - break; - case AOR_NAME_NOT_EXIST: - PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); - SetSentErrorMessage(true); - return false; - case AOR_DB_INTERNAL_ERROR: - PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -bool ChatHandler::HandleCharacterDeleteCommand(const char* args) -{ - if(!*args) - return false; - - char *character_name_str = strtok((char*)args," "); - if(!character_name_str) - return false; - - std::string character_name = character_name_str; - if(!normalizePlayerName(character_name)) - return false; - - uint64 character_guid; - uint32 account_id; - - Player *player = objmgr.GetPlayer(character_name.c_str()); - if(player) - { - character_guid = player->GetGUID(); - account_id = player->GetSession()->GetAccountId(); - player->GetSession()->KickPlayer(); - } - else - { - character_guid = objmgr.GetPlayerGUIDByName(character_name); - if(!character_guid) - { - PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); - } - - std::string account_name; - accmgr.GetName (account_id,account_name); - - Player::DeleteFromDB(character_guid, account_id, true); - PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); - return true; -} - -/// Exit the realm -bool ChatHandler::HandleServerExitCommand(const char* /*args*/) -{ - SendSysMessage(LANG_COMMAND_EXIT); - World::StopNow(SHUTDOWN_EXIT_CODE); - return true; -} - -/// Display info on users currently in the realm -bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/) -{ - ///- Get the list of accounts ID logged to the realm - QueryResult_AutoPtr resultDB = CharacterDatabase.Query("SELECT name,account,map,zone FROM characters WHERE online > 0"); - if (!resultDB) - { - SendSysMessage(LANG_ACCOUNT_LIST_EMPTY); - return true; - } - - ///- Display the list of account/characters online - SendSysMessage(LANG_ACCOUNT_LIST_BAR_HEADER); - SendSysMessage(LANG_ACCOUNT_LIST_HEADER); - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - - ///- Circle through accounts - do - { - Field *fieldsDB = resultDB->Fetch(); - std::string name = fieldsDB[0].GetCppString(); - uint32 account = fieldsDB[1].GetUInt32(); - - ///- Get the username, last IP and GM level of each account - // No SQL injection. account is uint32. - QueryResult_AutoPtr resultLogin = - LoginDatabase.PQuery("SELECT a.username, a.last_ip, aa.gmlevel, a.expansion " - "FROM account a " - "LEFT JOIN account_access aa " - "ON (a.id = aa.id) " - "WHERE a.id = '%u'", account); - if(resultLogin) - { - Field *fieldsLogin = resultLogin->Fetch(); - PSendSysMessage(LANG_ACCOUNT_LIST_LINE, - fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsDB[2].GetInt32(),fieldsDB[3].GetInt32(),fieldsLogin[3].GetUInt32(),fieldsLogin[2].GetUInt32()); - } - else - PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); - - }while(resultDB->NextRow()); - - SendSysMessage(LANG_ACCOUNT_LIST_BAR); - return true; -} - -/// Create an account -bool ChatHandler::HandleAccountCreateCommand(const char* args) -{ - if(!*args) - return false; - - ///- %Parse the command line arguments - char *szAcc = strtok((char*)args, " "); - char *szPassword = strtok(NULL, " "); - if(!szAcc || !szPassword) - return false; - - // normalized in accmgr.CreateAccount - std::string account_name = szAcc; - std::string password = szPassword; - - AccountOpResult result = accmgr.CreateAccount(account_name, password); - switch(result) - { - case AOR_OK: - PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); - break; - case AOR_NAME_TOO_LONG: - SendSysMessage(LANG_ACCOUNT_TOO_LONG); - SetSentErrorMessage(true); - return false; - case AOR_NAME_ALREDY_EXIST: - SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); - SetSentErrorMessage(true); - return false; - case AOR_DB_INTERNAL_ERROR: - PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); - SetSentErrorMessage(true); - return false; - default: - PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); - SetSentErrorMessage(true); - return false; - } - - return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args) -{ - if(!*args) - return false; - - char *NewLevel = strtok((char*)args, " "); - if (!NewLevel) - return false; - - sLog.SetLogFileLevel(NewLevel); - return true; -} - -/// Set the level of logging -bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) -{ - if(!*args) - return false; - - char *NewLevel = strtok((char*)args, " "); - if (!NewLevel) - return false; - - sLog.SetLogLevel(NewLevel); - return true; -} - -/// set diff time record interval -bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) -{ - if(!*args) - return false; - - char *NewTimeStr = strtok((char*)args, " "); - if(!NewTimeStr) - return false; - - int32 NewTime =atoi(NewTimeStr); - if(NewTime < 0) - return false; - - sWorld.SetRecordDiffInterval(NewTime); - printf( "Record diff every %u ms\n", NewTime); - return true; -} - -/// @} - -#ifdef linux -// Non-blocking keypress detector, when return pressed, return 1, else always return 0 -int kb_hit_return() -{ - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); -} -#endif - -/// %Thread start -void CliRunnable::run() -{ - ///- Init new SQL thread for the world database (one connection call enough) - WorldDatabase.ThreadStart(); // let thread do safe mySQL requests - - char commandbuf[256]; - - ///- Display the list of available CLI functions then beep - sLog.outString(""); - #if PLATFORM != WINDOWS - rl_attempted_completion_function = cli_completion; - #endif - if(sConfig.GetBoolDefault("BeepAtStart", true)) - printf("\a"); // \a = Alert - - // print this here the first time - // later it will be printed after command queue updates - printf("TC>"); - - ///- As long as the World is running (no World::m_stopEvent), get the command line and handle it - while (!World::IsStopped()) - { - fflush(stdout); - - char *command_str ; // = fgets(commandbuf,sizeof(commandbuf),stdin); - - #if PLATFORM == WINDOWS - command_str = fgets(commandbuf,sizeof(commandbuf),stdin); - #else - command_str = readline("TC>"); - rl_bind_key('\t',rl_complete); - #endif - if (command_str != NULL) - { - for (int x=0; command_str[x]; x++) - if(command_str[x]=='\r'||command_str[x]=='\n') - { - command_str[x]=0; - break; - } - - if(!*command_str) - { - #if PLATFORM == WINDOWS - printf("TC>"); - #endif - continue; - } - - std::string command; - if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 - { - #if PLATFORM == WINDOWS - printf("TC>"); - #endif - continue; - } - fflush(stdout); - sWorld.QueueCliCommand(&utf8print,command.c_str()); - #if PLATFORM != WINDOWS - add_history(command.c_str()); - #endif - - } - else if (feof(stdin)) - { - World::StopNow(SHUTDOWN_EXIT_CODE); - } - - } - - ///- End the database thread - WorldDatabase.ThreadEnd(); // free mySQL thread resources -} diff --git a/src/server/worldserver/CliRunnable.h b/src/server/worldserver/CliRunnable.h deleted file mode 100644 index 9f990b2b469..00000000000 --- a/src/server/worldserver/CliRunnable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -/// @{ -/// \file - -#ifndef __CLIRUNNABLE_H -#define __CLIRUNNABLE_H - -/// Command Line Interface handling thread -class CliRunnable : public ACE_Based::Runnable -{ - public: - void run(); -}; -#endif -/// @} diff --git a/src/server/worldserver/RASocket.cpp b/src/server/worldserver/RASocket.cpp deleted file mode 100644 index 32c16d9980f..00000000000 --- a/src/server/worldserver/RASocket.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -*/ - -#include "Common.h" -#include "Config/ConfigEnv.h" -#include "Database/DatabaseEnv.h" -#include "AccountMgr.h" -#include "Log.h" -#include "RASocket.h" -#include "Util.h" -#include "World.h" - -/// \todo Make this thread safe if in the future 2 admins should be able to log at the same time. -SOCKET r; - -#define dropclient {Sendf("I'm busy right now, come back later."); \ - SetCloseAndDelete(); \ - return; \ - } - -uint32 iSession=0; ///< Session number (incremented each time a new connection is made) -unsigned int iUsers=0; ///< Number of active administrators - -typedef int(* pPrintf)(const char*,...); - -void ParseCommand(CliCommandHolder::Print*, char*command); - -/// RASocket constructor -RASocket::RASocket(ISocketHandler &h): TcpSocket(h) -{ - - ///- Increment the session number - iSess =iSession++ ; - - ///- Get the config parameters - bSecure = sConfig.GetBoolDefault( "RA.Secure", true ); - iMinLevel = sConfig.GetIntDefault( "RA.MinLevel", 3 ); - - ///- Initialize buffer and data - iInputLength=0; - buff=new char[RA_BUFF_SIZE]; - stage=NONE; -} - -/// RASocket destructor -RASocket::~RASocket() -{ - ///- Delete buffer and decrease active admins count - delete [] buff; - - sLog.outRemote("Connection was closed.\n"); - - if(stage==OK) - iUsers--; -} - -/// Accept an incoming connection -void RASocket::OnAccept() -{ - std::string ss=GetRemoteAddress(); - sLog.outRemote("Incoming connection from %s.\n",ss.c_str()); - ///- If there is already an active admin, drop the connection - if(iUsers) - dropclient - - ///- Else print Motd - Sendf("%s\r\n",sWorld.GetMotd()); -} - -/// Read data from the network -void RASocket::OnRead() -{ - ///- Read data and check input length - TcpSocket::OnRead(); - - unsigned int sz=ibuf.GetLength(); - if(iInputLength+sz>=RA_BUFF_SIZE) - { - sLog.outRemote("Input buffer overflow, possible DOS attack.\n"); - SetCloseAndDelete(); - return; - } - - ///- If there is already an active admin (other than you), drop the connection - if(stage!=OK && iUsers) - dropclient - - char *inp = new char [sz+1]; - ibuf.Read(inp,sz); - - /// \todo Can somebody explain this 'Linux bugfix'? - if(stage==NONE) - if(sz>4) //linux remote telnet - if(memcmp(inp ,"USER ",5)) - { - delete [] inp;return; - printf("lin bugfix"); - } //linux bugfix - - ///- Discard data after line break or line feed - bool gotenter=false; - unsigned int y=0; - for (; y<sz; y++) - if(inp[y]=='\r'||inp[y]=='\n') - { - gotenter=true; - break; - } - - //No buffer overflow (checked above) - memcpy(&buff[iInputLength],inp,y); - iInputLength+=y; - delete [] inp; - if(gotenter) - { - - buff[iInputLength]=0; - iInputLength=0; - switch(stage) - { - /// <ul> <li> If the input is 'USER <username>' - case NONE: - if(!memcmp(buff,"USER ",5)) //got "USER" cmd - { - szLogin=&buff[5]; - - ///- Get the password from the account table - std::string login = szLogin; - - ///- Convert Account name to Upper Format - AccountMgr::normalizeString(login); - - ///- Escape the Login to allow quotes in names - LoginDatabase.escape_string(login); - - QueryResult_AutoPtr result = LoginDatabase.PQuery("SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = '%s'",login.c_str ()); - - ///- If the user is not found, deny access - if(!result) - { - Sendf("-No such user.\r\n"); - sLog.outRemote("User %s does not exist.\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - else - { - Field *fields = result->Fetch(); - - //szPass=fields[0].GetString(); - - ///- if gmlevel is too low, deny access - if(fields[1].GetUInt32()<iMinLevel || fields[1].GetUInt32() == NULL) - { - Sendf("-Not enough privileges.\r\n"); - sLog.outRemote("User %s has no privilege.\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - else if(fields[2].GetInt32() != -1) - { - ///- if RealmID isn't -1, deny access - Sendf("-Not enough privileges.\r\n"); - sLog.outRemote("User %s has to be assigned on all realms (with RealmID = '-1').\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - else - { - stage=LG; - } - } - } - break; - ///<li> If the input is 'PASS <password>' (and the user already gave his username) - case LG: - if(!memcmp(buff,"PASS ",5)) //got "PASS" cmd - { //login+pass ok - ///- If password is correct, increment the number of active administrators - std::string login = szLogin; - std::string pw = &buff[5]; - - AccountMgr::normalizeString(login); - AccountMgr::normalizeString(pw); - LoginDatabase.escape_string(login); - LoginDatabase.escape_string(pw); - - QueryResult_AutoPtr check = LoginDatabase.PQuery( - "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT('%s',':','%s'))", - login.c_str(), login.c_str(), pw.c_str()); - - if(check) - { - r=GetSocket(); - stage=OK; - ++iUsers; - - Sendf("+Logged in.\r\n"); - sLog.outRemote("User %s has logged in.\n",szLogin.c_str()); - Sendf("TC>"); - } - else - { - ///- Else deny access - Sendf("-Wrong pass.\r\n"); - sLog.outRemote("User %s has failed to log in.\n",szLogin.c_str()); - if(bSecure)SetCloseAndDelete(); - } - } - break; - ///<li> If user is logged, parse and execute the command - case OK: - if(strlen(buff)) - { - sLog.outRemote("Got '%s' cmd.\n",buff); - sWorld.QueueCliCommand(&RASocket::zprint , buff); - } - else - Sendf("TC>"); - break; - ///</ul> - }; - - } -} - -/// Output function -void RASocket::zprint( const char * szText ) -{ - if( !szText ) - return; - - #ifdef RA_CRYPT - - char *megabuffer=strdup(szText); - unsigned int sz=strlen(megabuffer); - Encrypt(megabuffer,sz); - send(r,megabuffer,sz,0); - delete [] megabuffer; - - #else - - unsigned int sz=strlen(szText); - send(r,szText,sz,0); - - #endif -} diff --git a/src/server/worldserver/RASocket.h b/src/server/worldserver/RASocket.h deleted file mode 100644 index 5c13724f90d..00000000000 --- a/src/server/worldserver/RASocket.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -/// @{ -/// \file - -#ifndef _RASOCKET_H -#define _RASOCKET_H - -#include "sockets/TcpSocket.h" - -#include "Common.h" - -#define RA_BUFF_SIZE 1024 - -class ISocketHandler; - -/// Remote Administration socket -class RASocket: public TcpSocket -{ - public: - - RASocket(ISocketHandler& h); - ~RASocket(); - - void OnAccept(); - void OnRead(); - - private: - - char * buff; - std::string szLogin; - uint32 iSess; - unsigned int iInputLength; - bool bLog; - bool bSecure; //kick on wrong pass, non exist. user, user with no priv - //will protect from DOS, bruteforce attacks - //some 'smart' protection must be added for more security - uint8 iMinLevel; - enum - { - NONE, //initial value - LG, //only login was entered - OK, //both login and pass were given, and they are correct and user have enough priv. - }stage; - - static void zprint( const char * szText ); -}; -#endif -/// @} diff --git a/src/server/worldserver/WorldRunnable.cpp b/src/server/worldserver/WorldRunnable.cpp deleted file mode 100644 index c674ddbc06f..00000000000 --- a/src/server/worldserver/WorldRunnable.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -*/ - -#include "Common.h" -#include "ObjectAccessor.h" -#include "World.h" -#include "WorldSocketMgr.h" -#include "Database/DatabaseEnv.h" - -#include "BattleGroundMgr.h" -#include "MapManager.h" -#include "Timer.h" -#include "WorldRunnable.h" - -#define WORLD_SLEEP_CONST 50 - -#ifdef WIN32 -#include "ServiceWin32.h" -extern int m_ServiceStatus; -#endif - -/// Heartbeat for the World -void WorldRunnable::run() -{ - ///- Init new SQL thread for the world database - WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough) - - sWorld.InitResultQueue(); - - uint32 realCurrTime = 0; - uint32 realPrevTime = getMSTime(); - - uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST - - ///- While we have not World::m_stopEvent, update the world - while (!World::IsStopped()) - { - ++World::m_worldLoopCounter; - realCurrTime = getMSTime(); - - uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime); - - sWorld.Update( diff ); - realPrevTime = realCurrTime; - - // diff (D0) include time of previous sleep (d0) + tick time (t0) - // we want that next d1 + t1 == WORLD_SLEEP_CONST - // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement - // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 - if (diff <= WORLD_SLEEP_CONST+prevSleepTime) - { - prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; - ACE_Based::Thread::Sleep(prevSleepTime); - } - else - prevSleepTime = 0; - - #ifdef WIN32 - if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); - while (m_ServiceStatus == 2) Sleep(1000); - #endif - } - - sWorld.KickAll(); // save and kick all players - sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call - - // unload battleground templates before different singletons destroyed - sBattleGroundMgr.DeleteAllBattleGrounds(); - - sWorldSocketMgr->StopNetwork(); - - MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory) - - ///- End the database thread - WorldDatabase.ThreadEnd(); // free mySQL thread resources -} diff --git a/src/server/worldserver/WorldRunnable.h b/src/server/worldserver/WorldRunnable.h deleted file mode 100644 index f14ee021f36..00000000000 --- a/src/server/worldserver/WorldRunnable.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * Copyright (C) 2008-2010 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 Trinityd -/// @{ -/// \file - -#ifndef __WORLDRUNNABLE_H -#define __WORLDRUNNABLE_H - -/// Heartbeat thread for the World -class WorldRunnable : public ACE_Based::Runnable -{ - public: - void run(); -}; -#endif -/// @} |