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:
@@ -46,7 +46,7 @@
|
||||
// "2. Can I use OpenSSL with GPL software?"
|
||||
// http://www.openssl.org/support/faq.html#LEGAL2
|
||||
//
|
||||
#if defined (_WIN32) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#define HAVE_OPENSSL
|
||||
#endif
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ ServerDBGeneric::AsyncPlayerLogin(unsigned requestId, const string &/*playerName
|
||||
}
|
||||
|
||||
void
|
||||
ServerDBGeneric::PlayerLogout(db_id /*playerId*/)
|
||||
ServerDBGeneric::PlayerLogout(DB_id /*playerId*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -66,11 +66,11 @@ ServerDBGeneric::AsyncCreateGame(unsigned requestId, const string &/*gameName*/)
|
||||
}
|
||||
|
||||
void
|
||||
ServerDBGeneric::SetGamePlayerPlace(db_id /*gameId*/, db_id /*playerId*/, unsigned /*place*/)
|
||||
ServerDBGeneric::SetGamePlayerPlace(DB_id /*gameId*/, DB_id /*playerId*/, unsigned /*place*/)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ServerDBGeneric::EndGame(db_id /*gameId*/)
|
||||
ServerDBGeneric::EndGame(DB_id /*gameId*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef unsigned db_id;
|
||||
typedef unsigned DB_id;
|
||||
#define DB_ID_INVALID 0
|
||||
|
||||
// Callback operations are posted using the io service,
|
||||
@@ -38,10 +38,10 @@ public:
|
||||
|
||||
virtual void QueryError(const std::string &error) = 0;
|
||||
|
||||
virtual void PlayerLoginSuccess(unsigned requestId, db_id playerId) = 0;
|
||||
virtual void PlayerLoginSuccess(unsigned requestId, DB_id playerId) = 0;
|
||||
virtual void PlayerLoginFailed(unsigned requestId) = 0;
|
||||
|
||||
virtual void CreateGameSuccess(unsigned requestId, db_id gameId) = 0;
|
||||
virtual void CreateGameSuccess(unsigned requestId, DB_id gameId) = 0;
|
||||
virtual void CreateGameFailed(unsigned requestId) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ public:
|
||||
virtual void Stop();
|
||||
|
||||
virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName, const std::string &secretString);
|
||||
virtual void PlayerLogout(db_id playerId);
|
||||
virtual void PlayerLogout(DB_id playerId);
|
||||
|
||||
virtual void AsyncCreateGame(unsigned requestId, const std::string &gameName);
|
||||
virtual void SetGamePlayerPlace(db_id gameId, db_id playerId, unsigned place);
|
||||
virtual void EndGame(db_id gameId);
|
||||
virtual void SetGamePlayerPlace(DB_id gameId, DB_id playerId, unsigned place);
|
||||
virtual void EndGame(DB_id gameId);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<boost::asio::io_service> m_ioService;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
typedef std::list<db_id> db_list;
|
||||
typedef std::list<DB_id> db_list;
|
||||
|
||||
class ServerDBInterface
|
||||
{
|
||||
@@ -39,11 +39,11 @@ public:
|
||||
virtual void Stop() = 0;
|
||||
|
||||
virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName, const std::string &secretString) = 0;
|
||||
virtual void PlayerLogout(db_id playerId) = 0;
|
||||
virtual void PlayerLogout(DB_id playerId) = 0;
|
||||
|
||||
virtual void AsyncCreateGame(unsigned requestId, const std::string &gameName) = 0;
|
||||
virtual void SetGamePlayerPlace(db_id gameId, db_id playerId, unsigned place) = 0;
|
||||
virtual void EndGame(db_id gameId) = 0;
|
||||
virtual void SetGamePlayerPlace(DB_id gameId, DB_id playerId, unsigned place) = 0;
|
||||
virtual void EndGame(DB_id gameId) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ public:
|
||||
u_int32_t GetId() const;
|
||||
const std::string &GetName() const;
|
||||
|
||||
db_id GetDBId() const;
|
||||
void SetDBId(db_id newId);
|
||||
DB_id GetDBId() const;
|
||||
void SetDBId(DB_id newId);
|
||||
|
||||
void AddSession(SessionWrapper session);
|
||||
void RemovePlayer(unsigned playerId, unsigned errorCode);
|
||||
@@ -155,7 +155,7 @@ private:
|
||||
ServerGameState *m_curState;
|
||||
|
||||
const u_int32_t m_id;
|
||||
db_id m_dbId;
|
||||
DB_id m_dbId;
|
||||
const std::string m_name;
|
||||
const std::string m_password;
|
||||
ConfigFile *m_playerConfig;
|
||||
|
||||
@@ -48,6 +48,7 @@ class ChatCleanerManager;
|
||||
class ServerDBInterface;
|
||||
struct GameData;
|
||||
class Game;
|
||||
struct Gsasl;
|
||||
|
||||
class ServerLobbyThread : public Thread, public boost::enable_shared_from_this<ServerLobbyThread>
|
||||
{
|
||||
@@ -93,7 +94,7 @@ public:
|
||||
u_int32_t GetNextGameId();
|
||||
ServerCallback &GetCallback();
|
||||
|
||||
void SetGameDBId(u_int32_t gameId, db_id gameDBId);
|
||||
void SetGameDBId(u_int32_t gameId, DB_id gameDBId);
|
||||
|
||||
AvatarManager &GetAvatarManager();
|
||||
|
||||
@@ -120,6 +121,8 @@ protected:
|
||||
virtual void Main();
|
||||
void RegisterTimers();
|
||||
void CancelTimers();
|
||||
void InitAuthContext();
|
||||
void ClearAuthContext();
|
||||
void InitChatCleaner();
|
||||
|
||||
void HandleRead(const boost::system::error_code &ec, SessionId sessionId, size_t bytesRead);
|
||||
@@ -137,7 +140,7 @@ protected:
|
||||
void InitAfterLogin(SessionWrapper session);
|
||||
void EstablishSession(SessionWrapper session);
|
||||
void AuthenticatePlayer(SessionWrapper session, const std::string &password);
|
||||
void AuthenticationSuccess(unsigned playerId, db_id dbPlayerId);
|
||||
void AuthenticationSuccess(unsigned playerId, DB_id dbPlayerId);
|
||||
void AuthenticationFailure(unsigned playerId);
|
||||
void RequestPlayerAvatar(SessionWrapper session);
|
||||
void TimerRemoveGame(const boost::system::error_code &ec);
|
||||
@@ -195,6 +198,8 @@ private:
|
||||
SessionManager m_sessionManager;
|
||||
SessionManager m_gameSessionManager;
|
||||
|
||||
Gsasl *m_authContext;
|
||||
|
||||
TimerClientAddressMap m_timerAvatarClientAddressMap;
|
||||
mutable boost::mutex m_timerAvatarClientAddressMapMutex;
|
||||
|
||||
|
||||
@@ -72,9 +72,6 @@ public:
|
||||
void MarkActivityNotice();
|
||||
unsigned GetAutoDisconnectTimerElapsedSec() const;
|
||||
|
||||
unsigned GetMaxNumPlayers() const;
|
||||
void SetMaxNumPlayers(unsigned numPlayers);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<boost::asio::ip::tcp::socket> m_socket;
|
||||
const SessionId m_id;
|
||||
@@ -88,7 +85,6 @@ private:
|
||||
bool m_activityTimeoutNoticeSent;
|
||||
boost::timers::portable::microsec_timer m_autoDisconnectTimer;
|
||||
SessionDataCallback &m_callback;
|
||||
unsigned m_maxNumPlayers;
|
||||
|
||||
mutable boost::mutex m_dataMutex;
|
||||
};
|
||||
|
||||
@@ -84,6 +84,8 @@
|
||||
#define ERR_NET_INTERNAL_GAME_ERROR 130
|
||||
#define ERR_NET_DEALER_NOT_FOUND 131
|
||||
#define ERR_NET_AVATAR_UPLOAD_BLOCKED 132
|
||||
#define ERR_NET_GSASL_INIT_FAILED 133
|
||||
#define ERR_NET_GSASL_NO_SCRAM 134
|
||||
|
||||
#define ERR_IRC_INTERNAL 151
|
||||
#define ERR_IRC_CONNECT_FAILED 152
|
||||
|
||||
+15
-1
@@ -45,12 +45,26 @@ PlayerData::GetName() const
|
||||
}
|
||||
|
||||
void
|
||||
PlayerData::SetName(const std::string &name)
|
||||
PlayerData::SetName(const string &name)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
string
|
||||
PlayerData::GetPassword() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
return m_password;
|
||||
}
|
||||
|
||||
void
|
||||
PlayerData::SetPassword(const string &password)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_dataMutex);
|
||||
m_password = password;
|
||||
}
|
||||
|
||||
string
|
||||
PlayerData::GetAvatarFile() const
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <core/crypthelper.h>
|
||||
#include <db/serverdbcallback.h>
|
||||
|
||||
class SessionData;
|
||||
|
||||
@@ -78,6 +79,8 @@ public:
|
||||
|
||||
std::string GetName() const;
|
||||
void SetName(const std::string &name);
|
||||
std::string GetPassword() const;
|
||||
void SetPassword(const std::string &password);
|
||||
std::string GetAvatarFile() const;
|
||||
void SetAvatarFile(const std::string &avatarFile);
|
||||
MD5Buf GetAvatarMD5() const;
|
||||
@@ -98,8 +101,10 @@ public:
|
||||
|
||||
private:
|
||||
const unsigned m_uniqueId;
|
||||
DB_id m_dbId;
|
||||
int m_number;
|
||||
std::string m_name;
|
||||
std::string m_password;
|
||||
std::string m_avatarFile;
|
||||
MD5Buf m_avatarMD5;
|
||||
PlayerType m_type;
|
||||
|
||||
Reference in New Issue
Block a user