TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
RASession Class Reference

#include <RASession.h>

Public Member Functions

 RASession (tcp::socket &&socket)
 
void Start ()
 
const std::string GetRemoteIpAddress () const
 
unsigned short GetRemotePort () const
 

Private Member Functions

int Send (const char *data)
 
std::string ReadString ()
 
bool CheckAccessLevel (const std::string &user)
 
bool CheckPassword (const std::string &user, const std::string &pass)
 
bool ProcessCommand (std::string &command)
 

Static Private Member Functions

static void CommandPrint (void *callbackArg, const char *text)
 
static void CommandFinished (void *callbackArg, bool)
 

Private Attributes

tcp::socket _socket
 
boost::asio::streambuf _readBuffer
 
boost::asio::streambuf _writeBuffer
 
std::promise< void > * _commandExecuting
 

Constructor & Destructor Documentation

RASession::RASession ( tcp::socket &&  socket)
inline
36  : _socket(std::move(socket)), _commandExecuting(nullptr)
37  {
38  }
tcp::socket _socket
Definition: RASession.h:55
std::promise< void > * _commandExecuting
Definition: RASession.h:58

Member Function Documentation

bool RASession::CheckAccessLevel ( const std::string &  user)
private
123 {
124  std::string safeUser = user;
125 
126  Utf8ToUpperOnlyLatin(safeUser);
127 
129  stmt->setString(0, safeUser);
130  PreparedQueryResult result = LoginDatabase.Query(stmt);
131 
132  if (!result)
133  {
134  TC_LOG_INFO("commands.ra", "User %s does not exist in database", user.c_str());
135  return false;
136  }
137 
138  Field* fields = result->Fetch();
139 
140  if (fields[1].GetUInt8() < sConfigMgr->GetIntDefault("RA.MinLevel", 3))
141  {
142  TC_LOG_INFO("commands.ra", "User %s has no privilege to login", user.c_str());
143  return false;
144  }
145  else if (fields[2].GetInt32() != -1)
146  {
147  TC_LOG_INFO("commands.ra", "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str());
148  return false;
149  }
150 
151  return true;
152 }
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: QueryResult.h:107
Class used to access individual fields of database query result.
Definition: Field.h:56
#define sConfigMgr
Definition: Config.h:61
void setString(const uint8 index, const std::string &value)
Definition: PreparedStatement.cpp:187
Definition: PreparedStatement.h:74
LoginDatabaseWorkerPool LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
Definition: LoginDatabase.h:91
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
Definition: Util.cpp:498

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool RASession::CheckPassword ( const std::string &  user,
const std::string &  pass 
)
private
155 {
156  std::string safe_user = user;
157  Utf8ToUpperOnlyLatin(safe_user);
158 
159  std::string safe_pass = pass;
160  Utf8ToUpperOnlyLatin(safe_pass);
161 
162  std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass);
163 
165 
166  stmt->setString(0, safe_user);
167  stmt->setString(1, hash);
168 
169  PreparedQueryResult result = LoginDatabase.Query(stmt);
170 
171  if (!result)
172  {
173  TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str());
174  return false;
175  }
176 
177  return true;
178 }
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: QueryResult.h:107
#define hash
Definition: private_namespace.h:186
Definition: LoginDatabase.h:85
void setString(const uint8 index, const std::string &value)
Definition: PreparedStatement.cpp:187
static std::string CalculateShaPassHash(std::string const &name, std::string const &password)
Definition: AccountMgr.cpp:378
Definition: PreparedStatement.h:74
LoginDatabaseWorkerPool LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
QueryResult Query(const char *sql, T *connection=nullptr)
Definition: DatabaseWorkerPool.cpp:113
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
Definition: Util.cpp:498

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void RASession::CommandFinished ( void *  callbackArg,
bool   
)
staticprivate
217 {
218  RASession* session = static_cast<RASession*>(callbackArg);
219  session->_commandExecuting->set_value();
220 }
Definition: RASession.h:33
std::promise< void > * _commandExecuting
Definition: RASession.h:58

+ Here is the caller graph for this function:

void RASession::CommandPrint ( void *  callbackArg,
const char *  text 
)
staticprivate
208 {
209  if (!text || !*text)
210  return;
211 
212  RASession* session = static_cast<RASession*>(callbackArg);
213  session->Send(text);
214 }
int Send(const char *data)
Definition: RASession.cpp:93
Definition: RASession.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const std::string RASession::GetRemoteIpAddress ( ) const
inline
42 { return _socket.remote_endpoint().address().to_string(); }
tcp::socket _socket
Definition: RASession.h:55

+ Here is the caller graph for this function:

unsigned short RASession::GetRemotePort ( ) const
inline
43 { return _socket.remote_endpoint().port(); }
tcp::socket _socket
Definition: RASession.h:55
bool RASession::ProcessCommand ( std::string &  command)
private
181 {
182  if (command.length() == 0)
183  return true;
184 
185  TC_LOG_INFO("commands.ra", "Received command: %s", command.c_str());
186 
187  // handle quit, exit and logout commands to terminate connection
188  if (command == "quit" || command == "exit" || command == "logout")
189  {
190  Send("Bye\r\n");
191  return true;
192  }
193 
194  // Obtain a new promise per command
195  delete _commandExecuting;
196  _commandExecuting = new std::promise<void>();
197 
199  sWorld->QueueCliCommand(cmd);
200 
201  // Wait for the command to finish
202  _commandExecuting->get_future().wait();
203 
204  return false;
205 }
int Send(const char *data)
Definition: RASession.cpp:93
static void CommandPrint(void *callbackArg, const char *text)
Definition: RASession.cpp:207
#define sWorld
Definition: World.h:887
Storage class for commands issued for delayed execution.
Definition: World.h:507
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
std::promise< void > * _commandExecuting
Definition: RASession.h:58
static void CommandFinished(void *callbackArg, bool)
Definition: RASession.cpp:216

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string RASession::ReadString ( )
private
103 {
104  boost::system::error_code error;
105  size_t read = boost::asio::read_until(_socket, _readBuffer, "\r\n", error);
106  if (!read)
107  {
108  _socket.close();
109  return "";
110  }
111 
112  std::string line;
113  std::istream is(&_readBuffer);
114  std::getline(is, line);
115 
116  if (*line.rbegin() == '\r')
117  line.erase(line.length() - 1);
118 
119  return line;
120 }
boost::asio::streambuf _readBuffer
Definition: RASession.h:56
tcp::socket _socket
Definition: RASession.h:55

+ Here is the caller graph for this function:

int RASession::Send ( const char *  data)
private
94 {
95  std::ostream os(&_writeBuffer);
96  os << data;
97  size_t written = _socket.send(_writeBuffer.data());
98  _writeBuffer.consume(written);
99  return written;
100 }
tcp::socket _socket
Definition: RASession.h:55
boost::asio::streambuf _writeBuffer
Definition: RASession.h:57

+ Here is the caller graph for this function:

void RASession::Start ( )
33 {
34  // wait 1 second for active connections to send negotiation request
35  for (int counter = 0; counter < 10 && _socket.available() == 0; counter++)
36  std::this_thread::sleep_for(std::chrono::milliseconds(100));
37 
38  // Check if there are bytes available, if they are, then the client is requesting the negotiation
39  if (_socket.available() > 0)
40  {
41  // Handle subnegotiation
42  boost::array<char, 1024> buf;
43  _socket.read_some(boost::asio::buffer(buf));
44 
45  // Send the end-of-negotiation packet
46  uint8 const reply[2] = { 0xFF, 0xF0 };
47  _socket.write_some(boost::asio::buffer(reply));
48  }
49 
50  Send("Authentication Required\r\n");
51  Send("Username: ");
52 
53  std::string username = ReadString();
54 
55  if (username.empty())
56  return;
57 
58  TC_LOG_INFO("commands.ra", "Accepting RA connection from user %s (IP: %s)", username.c_str(), GetRemoteIpAddress().c_str());
59 
60  Send("Password: ");
61 
62  std::string password = ReadString();
63  if (password.empty())
64  return;
65 
66  if (!CheckAccessLevel(username) || !CheckPassword(username, password))
67  {
68  Send("Authentication failed\r\n");
69  _socket.close();
70  return;
71  }
72 
73  TC_LOG_INFO("commands.ra", "User %s (IP: %s) authenticated correctly to RA", username.c_str(), GetRemoteIpAddress().c_str());
74 
75  // Authentication successful, send the motd
76  for (std::string const& line : sWorld->GetMotd())
77  Send(line.c_str());
78  Send("\r\n");
79 
80  // Read commands
81  for (;;)
82  {
83  Send("TC>");
84  std::string command = ReadString();
85 
86  if (ProcessCommand(command))
87  break;
88  }
89 
90  _socket.close();
91 }
int Send(const char *data)
Definition: RASession.cpp:93
const std::string GetRemoteIpAddress() const
Definition: RASession.h:42
#define sWorld
Definition: World.h:887
bool CheckPassword(const std::string &user, const std::string &pass)
Definition: RASession.cpp:154
bool ProcessCommand(std::string &command)
Definition: RASession.cpp:180
float milliseconds()
Definition: units.h:92
bool CheckAccessLevel(const std::string &user)
Definition: RASession.cpp:122
uint8_t uint8
Definition: Define.h:152
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
std::string ReadString()
Definition: RASession.cpp:102
tcp::socket _socket
Definition: RASession.h:55

+ Here is the call graph for this function:

Member Data Documentation

std::promise<void>* RASession::_commandExecuting
private
boost::asio::streambuf RASession::_readBuffer
private
tcp::socket RASession::_socket
private
boost::asio::streambuf RASession::_writeBuffer
private

The documentation for this class was generated from the following files: