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(); +    }  }  | 
