Starting gsasl integration to perform challenge response authentication. Note that gsasl 1.3 is required (previous versions are not supported). Authentication is currently broken.
This commit is contained in:
@@ -676,12 +676,13 @@ ClientStateStartSession::Enter(boost::shared_ptr<ClientThread> client)
|
||||
netInit->requestedVersion.minor = NET_VERSION_MINOR;
|
||||
netInit->login.present = login_PR_authenticatedLogin;
|
||||
AuthenticatedLogin_t *authLogin = &netInit->login.choice.authenticatedLogin;
|
||||
OCTET_STRING_fromBuf(&authLogin->playerName,
|
||||
// TODO
|
||||
/* OCTET_STRING_fromBuf(&authLogin->playerName,
|
||||
context.GetPlayerName().c_str(),
|
||||
context.GetPlayerName().length());
|
||||
OCTET_STRING_fromBuf(&authLogin->password,
|
||||
context.GetPassword().c_str(),
|
||||
context.GetPassword().length());
|
||||
context.GetPassword().length());*/
|
||||
//context.GetPassword();
|
||||
string avatarFile = client->GetQtToolsInterface().stringFromUtf8(context.GetAvatarFile());
|
||||
if (!avatarFile.empty())
|
||||
|
||||
@@ -87,14 +87,14 @@ ServerGame::GetName() const
|
||||
return m_name;
|
||||
}
|
||||
|
||||
db_id
|
||||
DB_id
|
||||
ServerGame::GetDBId() const
|
||||
{
|
||||
return m_dbId;
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::SetDBId(db_id newId)
|
||||
ServerGame::SetDBId(DB_id newId)
|
||||
{
|
||||
m_dbId = newId;
|
||||
}
|
||||
|
||||
@@ -326,11 +326,6 @@ ServerGameStateInit::HandleNewSession(boost::shared_ptr<ServerGame> server, Sess
|
||||
{
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
||||
}
|
||||
// Check whether the client supports the current game.
|
||||
else if ((size_t)server->GetGameData().maxNumberOfPlayers > session.sessionData->GetMaxNumPlayers())
|
||||
{
|
||||
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (session.playerData->GetUniqueId() == server->GetAdminPlayerId())
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <gsasl.h>
|
||||
|
||||
#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby.
|
||||
|
||||
@@ -110,7 +111,7 @@ public:
|
||||
// TODO
|
||||
}
|
||||
|
||||
virtual void PlayerLoginSuccess(unsigned requestId, db_id dbPlayerId)
|
||||
virtual void PlayerLoginSuccess(unsigned requestId, DB_id dbPlayerId)
|
||||
{
|
||||
m_server.AuthenticationSuccess(requestId, dbPlayerId);
|
||||
}
|
||||
@@ -120,7 +121,7 @@ public:
|
||||
m_server.AuthenticationFailure(requestId);
|
||||
}
|
||||
|
||||
virtual void CreateGameSuccess(unsigned requestId, db_id gameId)
|
||||
virtual void CreateGameSuccess(unsigned requestId, DB_id gameId)
|
||||
{
|
||||
m_server.SetGameDBId((u_int32_t)requestId, gameId);
|
||||
}
|
||||
@@ -136,7 +137,7 @@ private:
|
||||
|
||||
ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ServerIrcBotCallback &ircBotCb, ConfigFile *playerConfig, AvatarManager &avatarManager,
|
||||
boost::shared_ptr<boost::asio::io_service> ioService)
|
||||
: m_ioService(ioService), m_gui(gui), m_ircBotCb(ircBotCb), m_avatarManager(avatarManager),
|
||||
: m_ioService(ioService), m_authContext(NULL), m_gui(gui), m_ircBotCb(ircBotCb), m_avatarManager(avatarManager),
|
||||
m_playerConfig(playerConfig), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1),
|
||||
m_statDataChanged(false), m_removeGameTimer(*ioService), m_removePlayerTimer(*ioService),
|
||||
m_sessionTimeoutTimer(*ioService), m_avatarCleanupTimer(*ioService),
|
||||
@@ -608,13 +609,16 @@ ServerLobbyThread::GetNextGameId()
|
||||
void
|
||||
ServerLobbyThread::Main()
|
||||
{
|
||||
InitChatCleaner();
|
||||
// Start database engine.
|
||||
m_database->Start();
|
||||
// Register all timers.
|
||||
RegisterTimers();
|
||||
try
|
||||
{
|
||||
InitAuthContext();
|
||||
|
||||
InitChatCleaner();
|
||||
// Start database engine.
|
||||
m_database->Start();
|
||||
// Register all timers.
|
||||
RegisterTimers();
|
||||
|
||||
boost::asio::io_service::work ioWork(*m_ioService);
|
||||
m_ioService->run(); // Will only be aborted asynchronously.
|
||||
|
||||
@@ -630,6 +634,8 @@ ServerLobbyThread::Main()
|
||||
CancelTimers();
|
||||
// Stop database engine.
|
||||
m_database->Stop();
|
||||
|
||||
ClearAuthContext();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -684,6 +690,30 @@ ServerLobbyThread::CancelTimers()
|
||||
m_avatarLockTimer.cancel();
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::InitAuthContext()
|
||||
{
|
||||
int res = gsasl_init(&m_authContext);
|
||||
if (res != GSASL_OK)
|
||||
throw ServerException(__FILE__, __LINE__, ERR_NET_GSASL_INIT_FAILED, 0);
|
||||
|
||||
if (!gsasl_server_support_p(m_authContext, "SCRAM-SHA-1"))
|
||||
{
|
||||
gsasl_done(m_authContext);
|
||||
throw ServerException(__FILE__, __LINE__, ERR_NET_GSASL_NO_SCRAM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::ClearAuthContext()
|
||||
{
|
||||
if (m_authContext)
|
||||
{
|
||||
gsasl_done(m_authContext);
|
||||
m_authContext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::InitChatCleaner()
|
||||
{
|
||||
@@ -876,25 +906,20 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const InitMessage
|
||||
SessionError(session, ERR_NET_VERSION_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
session.sessionData->SetMaxNumPlayers(MAX_NUMBER_OF_PLAYERS);
|
||||
|
||||
string playerName;
|
||||
string password;
|
||||
string authData;
|
||||
MD5Buf avatarMD5;
|
||||
bool guestUser = false;
|
||||
if (initMessage.login.present == login_PR_anonymousLogin)
|
||||
{
|
||||
const AnonymousLogin_t *anonLogin = &initMessage.login.choice.anonymousLogin;
|
||||
playerName = string((const char *)anonLogin->playerName.buf, anonLogin->playerName.size);
|
||||
if (anonLogin->avatar)
|
||||
memcpy(avatarMD5.data, anonLogin->avatar->buf, MD5_DATA_SIZE);
|
||||
playerName = "guest001"; // TODO
|
||||
guestUser = true;
|
||||
}
|
||||
else if (initMessage.login.present == login_PR_authenticatedLogin)
|
||||
{
|
||||
const AuthenticatedLogin_t *authLogin = &initMessage.login.choice.authenticatedLogin;
|
||||
playerName = string((const char *)authLogin->playerName.buf, authLogin->playerName.size);
|
||||
password = string((const char *)authLogin->password.buf, authLogin->password.size);
|
||||
authData = string((const char *)authLogin->clientUserData.buf, authLogin->clientUserData.size);
|
||||
if (authLogin->avatar)
|
||||
memcpy(avatarMD5.data, authLogin->avatar->buf, MD5_DATA_SIZE);
|
||||
}
|
||||
@@ -947,7 +972,7 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const InitMessage
|
||||
if (guestUser)
|
||||
InitAfterLogin(session);
|
||||
else
|
||||
AuthenticatePlayer(session, password);
|
||||
AuthenticatePlayer(session, authData);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1273,7 +1298,7 @@ ServerLobbyThread::AuthenticatePlayer(SessionWrapper session, const std::string
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::AuthenticationSuccess(unsigned playerId, db_id dbPlayerId)
|
||||
ServerLobbyThread::AuthenticationSuccess(unsigned playerId, DB_id dbPlayerId)
|
||||
{
|
||||
InitAfterLogin(m_sessionManager.GetSessionByUniquePlayerId(playerId, true));
|
||||
}
|
||||
@@ -1774,7 +1799,7 @@ ServerLobbyThread::GetCallback()
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::SetGameDBId(u_int32_t gameId, db_id gameDBId)
|
||||
ServerLobbyThread::SetGameDBId(u_int32_t gameId, DB_id gameDBId)
|
||||
{
|
||||
boost::shared_ptr<ServerGame> game = InternalGetGameFromId(gameId);
|
||||
if (game)
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
SessionData::SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> sock, SessionId id, SessionDataCallback &cb)
|
||||
: m_socket(sock), m_id(id), m_gameId(0), m_state(SessionData::Init), m_readyFlag(false),
|
||||
m_wantsLobbyMsg(true), m_activityTimeoutNoticeSent(false), m_callback(cb),
|
||||
m_maxNumPlayers(0)
|
||||
m_wantsLobbyMsg(true), m_activityTimeoutNoticeSent(false), m_callback(cb)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -171,17 +170,3 @@ SessionData::GetAutoDisconnectTimerElapsedSec() const
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
return m_autoDisconnectTimer.elapsed().total_seconds();
|
||||
}
|
||||
|
||||
unsigned
|
||||
SessionData::GetMaxNumPlayers() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
return m_maxNumPlayers;
|
||||
}
|
||||
|
||||
void
|
||||
SessionData::SetMaxNumPlayers(unsigned numPlayers)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_maxNumPlayers = numPlayers;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user