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:
lotodore
2009-10-11 09:20:17 +00:00
parent fe627fe6f5
commit 1f7f045d15
18 changed files with 123 additions and 100 deletions
+16 -18
View File
@@ -295,36 +295,34 @@ win32 {
INCLUDEPATH += ../SDL/include/SDL \
../SDL_mixer/include \
../GnuTLS/include \
../gsasl/include \
../curl/include \
../zlib
LIBPATH += ../boost/stage/lib \
../GnuTLS/lib \
../curl/lib \
../zlib
../GnuTLS/lib \
../gsasl/lib \
../curl/lib \
../SDL/lib \
../SDL_mixer/lib \
../zlib
LIBS += -lpokerth_lib \
-lpokerth_db \
-lpokerth_protocol
win32-msvc2005 {
LIBPATH += Release/lib \
../SDL/VisualC/SDL/Release \
../SDL/VisualC/SDLmain/Release \
../SDL_mixer/VisualC/Release
# LIBPATH += Debug/lib ../SDL/VisualC/SDL/Debug ../SDL/VisualC/SDLmain/Debug ../SDL_mixer/VisualC/Debug
LIBS += -llibgnutls-openssl \
-llibgcrypt
LIBS += -llibcurl
debug:LIBPATH += Debug/lib
release:LIBPATH += Release/lib
win32-msvc2008 {
LIBS += -llibgnutls-openssl-26 \
-llibgcrypt-11 \
-llibgsasl-7 \
-llibcurl
}
win32-g++ {
debug:LIBPATH += Debug/lib
release:LIBPATH += Release/lib
LIBPATH += ../SDL/lib \
../SDL_mixer/lib
LIBS += -lgnutls-openssl \
-lgnutls \
-lgcrypt \
-ltasn1 \
-lgpg-error
-lgpg-error \
-lgsasl
LIBS += -lcurl
LIBS += -lz
LIBS += -llibboost_thread-mgw44-mt
+11 -14
View File
@@ -115,29 +115,26 @@ win32 {
DEFINES += CURL_STATICLIB
DEFINES += _WIN32_WINNT=0x0501
DEPENDPATH += src/net/win32/ src/core/win32
INCLUDEPATH += ../boost/ ../GnuTLS/include
INCLUDEPATH += ../boost/ ../GnuTLS/include ../gsasl/include
SOURCES += src/core/win32/convhelper.cpp
LIBPATH += ../boost/stage/lib ../GnuTLS/lib ../curl/lib ../zlib
LIBPATH += ../boost/stage/lib ../GnuTLS/lib ../gsasl/lib ../curl/lib ../zlib
LIBS += -lpokerth_lib -lpokerth_db -lpokerth_protocol
win32-msvc2005 {
LIBPATH += Release/lib
#LIBPATH += Debug/lib
LIBS += -llibgnutls-openssl -llibgcrypt
LIBS += -llibcurl
debug:LIBPATH += Debug/lib
release:LIBPATH += Release/lib
win32-msvc2008 {
LIBS += -llibgnutls-openssl-26 \
-llibgcrypt-11 \
-llibgsasl-7 \
-llibcurl
}
win32-g++ {
debug {
LIBPATH += Debug/lib
}
release {
LIBPATH += Release/lib
}
LIBS += -lgnutls-openssl -lgnutls -lgcrypt -ltasn1 -lgpg-error
LIBS += -lgnutls-openssl -lgnutls -lgcrypt -ltasn1 -lgpg-error -lgsasl
LIBS += -lcurl
LIBS += -lz
LIBS += -llibboost_thread-mgw44-mt
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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*/)
{
}
+3 -3
View File
@@ -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;
};
+3 -3
View File
@@ -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;
+4 -4
View File
@@ -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
+3 -2
View File
@@ -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())
+2 -2
View File
@@ -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;
}
-5
View File
@@ -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 -19
View File
@@ -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)
+1 -16
View File
@@ -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;
}
+3 -3
View File
@@ -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;
+7 -2
View File
@@ -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;
-4
View File
@@ -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;
};
+2
View File
@@ -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
View File
@@ -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
{
+5
View File
@@ -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;