diff options
-rw-r--r-- | src/server/worldserver/RemoteAccess/RARunnable.cpp | 58 | ||||
-rw-r--r-- | src/server/worldserver/RemoteAccess/RARunnable.h | 2 | ||||
-rwxr-xr-x | src/server/worldserver/RemoteAccess/RASocket.cpp | 407 |
3 files changed, 235 insertions, 232 deletions
diff --git a/src/server/worldserver/RemoteAccess/RARunnable.cpp b/src/server/worldserver/RemoteAccess/RARunnable.cpp index dbf5a209ed9..87ddd4cb43a 100644 --- a/src/server/worldserver/RemoteAccess/RARunnable.cpp +++ b/src/server/worldserver/RemoteAccess/RARunnable.cpp @@ -35,59 +35,59 @@ RARunnable::RARunnable() : m_Reactor(NULL) { - ACE_Reactor_Impl* imp = 0; + ACE_Reactor_Impl* imp = 0; #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) - imp = new ACE_Dev_Poll_Reactor(); + imp = new ACE_Dev_Poll_Reactor(); - imp->max_notify_iterations (128); - imp->restart (1); + imp->max_notify_iterations (128); + imp->restart (1); #else - imp = new ACE_TP_Reactor(); - imp->max_notify_iterations (128); + imp = new ACE_TP_Reactor(); + imp->max_notify_iterations (128); #endif - m_Reactor = new ACE_Reactor (imp, 1); + m_Reactor = new ACE_Reactor (imp, 1); } RARunnable::~RARunnable() { - delete m_Reactor; + delete m_Reactor; } void RARunnable::run() { - if (!sConfig.GetBoolDefault("Ra.Enable", false)) - return; + if (!sConfig.GetBoolDefault("Ra.Enable", false)) + return; - ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor; + ACE_Acceptor<RASocket, ACE_SOCK_ACCEPTOR> acceptor; - uint16 raport = sConfig.GetIntDefault("Ra.Port", 3443); - std::string stringip = sConfig.GetStringDefault("Ra.IP", "0.0.0.0"); + uint16 raport = sConfig.GetIntDefault("Ra.Port", 3443); + std::string stringip = sConfig.GetStringDefault("Ra.IP", "0.0.0.0"); - ACE_INET_Addr listen_addr(raport, stringip.c_str()); + ACE_INET_Addr listen_addr(raport, stringip.c_str()); - if (acceptor.open(listen_addr, m_Reactor) == -1) - { - sLog.outError("Trinity RA can not bind to port %d on %s", raport, stringip.c_str()); - return; - } + if (acceptor.open(listen_addr, m_Reactor) == -1) + { + sLog.outError("Trinity RA can not bind to port %d on %s", raport, stringip.c_str()); + return; + } - sLog.outString("Starting Trinity RA on port %d on %s", raport, stringip.c_str()); + sLog.outString("Starting Trinity RA on port %d on %s", raport, stringip.c_str()); - while (!World::IsStopped()) - { - // don't be too smart to move this outside the loop - // the run_reactor_event_loop will modify interval - ACE_Time_Value interval(0, 100000); + while (!World::IsStopped()) + { + // don't be too smart to move this outside the loop + // the run_reactor_event_loop will modify interval + ACE_Time_Value interval(0, 100000); - if (m_Reactor->run_reactor_event_loop(interval) == -1) - break; - } + if (m_Reactor->run_reactor_event_loop(interval) == -1) + break; + } - sLog.outStaticDebug("Trinity RA thread exiting"); + sLog.outStaticDebug("Trinity RA thread exiting"); } diff --git a/src/server/worldserver/RemoteAccess/RARunnable.h b/src/server/worldserver/RemoteAccess/RARunnable.h index 62ffe595ff1..85e1dd516a0 100644 --- a/src/server/worldserver/RemoteAccess/RARunnable.h +++ b/src/server/worldserver/RemoteAccess/RARunnable.h @@ -34,7 +34,7 @@ public: void run(); private: - ACE_Reactor* m_Reactor; + ACE_Reactor* m_Reactor; }; diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp index 4d3e6542692..6b073e060d7 100755 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ b/src/server/worldserver/RemoteAccess/RASocket.cpp @@ -28,10 +28,11 @@ #include "RASocket.h" #include "Util.h" #include "World.h" +#include "SHA1.h" RASocket::RASocket() { - iMinLevel = sConfig.GetIntDefault("RA.MinLevel", 3); + iMinLevel = sConfig.GetIntDefault("RA.MinLevel", 3); } RASocket::~RASocket() @@ -40,289 +41,291 @@ RASocket::~RASocket() int RASocket::open(void *) { - ACE_INET_Addr remote_addr; + ACE_INET_Addr remote_addr; - if (peer().get_remote_addr(remote_addr) == -1) - { - sLog.outError("RASocket::open: peer().get_remote_addr error is %s", ACE_OS::strerror(errno)); - return -1; - } + if (peer().get_remote_addr(remote_addr) == -1) + { + sLog.outError("RASocket::open: peer().get_remote_addr error is %s", ACE_OS::strerror(errno)); + return -1; + } - sLog.outRemote("Incoming connection from %s", remote_addr.get_host_addr()); + sLog.outRemote("Incoming connection from %s", remote_addr.get_host_addr()); - return activate(); + return activate(); } int RASocket::handle_close(ACE_HANDLE, ACE_Reactor_Mask) { - sLog.outRemote("Closing connection"); - peer().close_reader(); - wait(); - destroy(); - return 0; + sLog.outRemote("Closing connection"); + peer().close_reader(); + wait(); + destroy(); + return 0; } int RASocket::send(const std::string& line) { - return peer().send(line.c_str(), line.length()) == line.length() ? 0 : -1; + return peer().send(line.c_str(), line.length()) == line.length() ? 0 : -1; } int RASocket::recv_line(ACE_Message_Block& buffer) { - char byte; - for (;;) - { - ssize_t n = peer().recv(&byte, sizeof(byte)); - - if (n < 0) - { - return -1; - } - - if (n == 0) - { - // EOF, connection was closed - errno = ECONNRESET; - return -1; - } - - ACE_ASSERT(n == sizeof(byte)); - - if (byte == '\n') - break; - else if (byte == '\r') /* Ignore CR */ - continue; - else if (buffer.copy(&byte, sizeof(byte)) == -1) - return -1; - } - - const char null_term = '\0'; - if (buffer.copy(&null_term, sizeof(null_term)) == -1) - return -1; - - return 0; + char byte; + for (;;) + { + ssize_t n = peer().recv(&byte, sizeof(byte)); + + if (n < 0) + { + return -1; + } + + if (n == 0) + { + // EOF, connection was closed + errno = ECONNRESET; + return -1; + } + + ACE_ASSERT(n == sizeof(byte)); + + if (byte == '\n') + break; + else if (byte == '\r') /* Ignore CR */ + continue; + else if (buffer.copy(&byte, sizeof(byte)) == -1) + return -1; + } + + const char null_term = '\0'; + if (buffer.copy(&null_term, sizeof(null_term)) == -1) + return -1; + + return 0; } int RASocket::recv_line(std::string& out_line) { - char buf[4096]; + char buf[4096]; - ACE_Data_Block db(sizeof (buf), - ACE_Message_Block::MB_DATA, - buf, - 0, - 0, - ACE_Message_Block::DONT_DELETE, - 0); + ACE_Data_Block db(sizeof (buf), + ACE_Message_Block::MB_DATA, + buf, + 0, + 0, + ACE_Message_Block::DONT_DELETE, + 0); - ACE_Message_Block message_block(&db, - ACE_Message_Block::DONT_DELETE, - 0); + ACE_Message_Block message_block(&db, + ACE_Message_Block::DONT_DELETE, + 0); - if (recv_line(message_block) == -1) - { - sLog.outRemote("Recv error %s", ACE_OS::strerror(errno)); - return -1; - } + if (recv_line(message_block) == -1) + { + sLog.outRemote("Recv error %s", ACE_OS::strerror(errno)); + return -1; + } - out_line = message_block.rd_ptr(); + out_line = message_block.rd_ptr(); - return 0; + return 0; } int RASocket::process_command(const std::string& command) { - if (command.length() == 0) - return 0; - - sLog.outRemote("Got command: %s", command.c_str()); - - // handle quit, exit and logout commands to terminate connection - if (command == "quit" || command == "exit" || command == "logout") { - (void) send("Bye\r\n"); - return -1; - } - - CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASocket::zprint, &RASocket::commandFinished); - sWorld.QueueCliCommand(cmd); - - // wait for result - ACE_Message_Block* mb; - for (;;) - { - if (getq(mb) == -1) - return -1; - - if (mb->msg_type() == ACE_Message_Block::MB_BREAK) - { - mb->release(); - break; - } - - if (peer().send(mb->rd_ptr(), mb->length()) != mb->length()) - { - mb->release(); - return -1; - } - - mb->release(); - } - - return 0; + if (command.length() == 0) + return 0; + + sLog.outRemote("Got command: %s", command.c_str()); + + // handle quit, exit and logout commands to terminate connection + if (command == "quit" || command == "exit" || command == "logout") { + (void) send("Bye\r\n"); + return -1; + } + + CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASocket::zprint, &RASocket::commandFinished); + sWorld.QueueCliCommand(cmd); + + // wait for result + ACE_Message_Block* mb; + for (;;) + { + if (getq(mb) == -1) + return -1; + + if (mb->msg_type() == ACE_Message_Block::MB_BREAK) + { + mb->release(); + break; + } + + if (peer().send(mb->rd_ptr(), mb->length()) != mb->length()) + { + mb->release(); + return -1; + } + + mb->release(); + } + + return 0; } int RASocket::check_access_level(const std::string& user) { - std::string safe_user = user; + std::string safe_user = user; - AccountMgr::normalizeString(safe_user); - LoginDatabase.escape_string(safe_user); + AccountMgr::normalizeString(safe_user); + LoginDatabase.escape_string(safe_user); - QueryResult 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'", safe_user.c_str()); + QueryResult 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'", safe_user.c_str()); - if (!result) - { - sLog.outRemote("User %s does not exist in database", user.c_str()); - return -1; - } + if (!result) + { + sLog.outRemote("User %s does not exist in database", user.c_str()); + return -1; + } - Field *fields = result->Fetch(); + Field *fields = result->Fetch(); - if (fields[1].GetUInt32() < iMinLevel) - { - sLog.outRemote("User %s has no privilege to login", user.c_str()); - return -1; - } - else if (fields[2].GetInt32() != -1) - { - sLog.outRemote("User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); - return -1; - } + if (fields[1].GetUInt32() < iMinLevel) + { + sLog.outRemote("User %s has no privilege to login", user.c_str()); + return -1; + } + else if (fields[2].GetInt32() != -1) + { + sLog.outRemote("User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); + return -1; + } - return 0; + return 0; } int RASocket::check_password(const std::string& user, const std::string& pass) { - std::string safe_user = user; - AccountMgr::normalizeString(safe_user); - LoginDatabase.escape_string(safe_user); + std::string safe_user = user; + AccountMgr::normalizeString(safe_user); + LoginDatabase.escape_string(safe_user); - std::string safe_pass = pass; - AccountMgr::normalizeString(safe_pass); - LoginDatabase.escape_string(safe_pass); + std::string safe_pass = pass; + AccountMgr::normalizeString(safe_pass); + LoginDatabase.escape_string(safe_pass); - QueryResult check = LoginDatabase.PQuery( - "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT('%s',':','%s'))", - safe_user.c_str(), safe_user.c_str(), safe_pass.c_str()); + std::string hash = sAccountMgr.CalculateShaPassHash(safe_user, safe_pass); - if (!check) - { - sLog.outRemote("Wrong password for user: %s", user.c_str()); - return -1; - } + QueryResult check = LoginDatabase.PQuery( + "SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash = '%s'", + safe_user.c_str(), hash.c_str()); - return 0; + if (!check) + { + sLog.outRemote("Wrong password for user: %s", user.c_str()); + return -1; + } + + return 0; } int RASocket::authenticate() { - if (send(std::string("Username: ")) == -1) - return -1; + if (send(std::string("Username: ")) == -1) + return -1; - std::string user; - if (recv_line(user) == -1) - return -1; + std::string user; + if (recv_line(user) == -1) + return -1; - if (send(std::string("Password: ")) == -1) - return -1; + if (send(std::string("Password: ")) == -1) + return -1; - std::string pass; - if (recv_line(pass) == -1) - return -1; + std::string pass; + if (recv_line(pass) == -1) + return -1; - sLog.outRemote("Login attempt for user: %s", user.c_str()); + sLog.outRemote("Login attempt for user: %s", user.c_str()); - if (check_access_level(user) == -1) - return -1; + if (check_access_level(user) == -1) + return -1; - if (check_password(user, pass) == -1) - return -1; + if (check_password(user, pass) == -1) + return -1; - sLog.outRemote("User login: %s", user.c_str()); + sLog.outRemote("User login: %s", user.c_str()); - return 0; + return 0; } int RASocket::svc(void) { - if (send("Authentication required\r\n") == -1) - return -1; + if (send("Authentication required\r\n") == -1) + return -1; - if (authenticate() == -1) - { - (void) send("Authentication failed\r\n"); - return -1; - } + if (authenticate() == -1) + { + (void) send("Authentication failed\r\n"); + return -1; + } - // send motd - if (send(std::string(sWorld.GetMotd()) + "\r\n") == -1) - return -1; + // send motd + if (send(std::string(sWorld.GetMotd()) + "\r\n") == -1) + return -1; - for(;;) - { - // show prompt - const char* tc_prompt = "TC> "; - if (peer().send(tc_prompt, strlen(tc_prompt)) != strlen(tc_prompt)) - return -1; + for(;;) + { + // show prompt + const char* tc_prompt = "TC> "; + if (peer().send(tc_prompt, strlen(tc_prompt)) != strlen(tc_prompt)) + return -1; - std::string line; + std::string line; - if (recv_line(line) == -1) - return -1; + if (recv_line(line) == -1) + return -1; - if (process_command(line) == -1) - return -1; - } + if (process_command(line) == -1) + return -1; + } - return 0; + return 0; } void RASocket::zprint(void* callbackArg, const char * szText) { - if (!szText || !callbackArg) - return; + if (!szText || !callbackArg) + return; - RASocket* socket = static_cast<RASocket*>(callbackArg); - size_t sz = strlen(szText); + RASocket* socket = static_cast<RASocket*>(callbackArg); + size_t sz = strlen(szText); - ACE_Message_Block* mb = new ACE_Message_Block(sz); - mb->copy(szText, sz); + ACE_Message_Block* mb = new ACE_Message_Block(sz); + mb->copy(szText, sz); - if (socket->putq(mb, const_cast<ACE_Time_Value*>(&ACE_Time_Value::zero)) == -1) - { - sLog.outRemote("Failed to enqueue message, queue is full or closed. Error is %s", ACE_OS::strerror(errno)); - mb->release(); - } + if (socket->putq(mb, const_cast<ACE_Time_Value*>(&ACE_Time_Value::zero)) == -1) + { + sLog.outRemote("Failed to enqueue message, queue is full or closed. Error is %s", ACE_OS::strerror(errno)); + mb->release(); + } } void RASocket::commandFinished(void* callbackArg, bool /*success*/) { - if (!callbackArg) - return; + if (!callbackArg) + return; - RASocket* socket = static_cast<RASocket*>(callbackArg); + RASocket* socket = static_cast<RASocket*>(callbackArg); - ACE_Message_Block* mb = new ACE_Message_Block(); + ACE_Message_Block* mb = new ACE_Message_Block(); - mb->msg_type(ACE_Message_Block::MB_BREAK); + mb->msg_type(ACE_Message_Block::MB_BREAK); - // the message is 0 size control message to tell that command output is finished - // hence we don't put timeout, because it shouldn't increase queue size and shouldn't block - if (socket->putq(mb) == -1) - { - // getting here is bad, command can't be marked as complete - sLog.outRemote("Failed to enqueue command end message. Error is %s", ACE_OS::strerror(errno)); - mb->release(); - } + // the message is 0 size control message to tell that command output is finished + // hence we don't put timeout, because it shouldn't increase queue size and shouldn't block + if (socket->putq(mb) == -1) + { + // getting here is bad, command can't be marked as complete + sLog.outRemote("Failed to enqueue command end message. Error is %s", ACE_OS::strerror(errno)); + mb->release(); + } } |