diff --git a/src/db/common/serverdbgeneric.cpp b/src/db/common/serverdbgeneric.cpp index fc6d7717..1c65af79 100644 --- a/src/db/common/serverdbgeneric.cpp +++ b/src/db/common/serverdbgeneric.cpp @@ -49,7 +49,7 @@ ServerDBGeneric::Stop() } void -ServerDBGeneric::AsyncPlayerLogin(unsigned requestId, const string &/*playerName*/, const string &/*secretString*/) +ServerDBGeneric::AsyncPlayerLogin(unsigned requestId, const string &/*playerName*/) { m_ioService->post(boost::bind(&ServerDBCallback::PlayerLoginFailed, &m_callback, requestId)); } diff --git a/src/db/serverdbcallback.h b/src/db/serverdbcallback.h index 8fe06351..0a43a734 100644 --- a/src/db/serverdbcallback.h +++ b/src/db/serverdbcallback.h @@ -38,7 +38,7 @@ 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, const std::string &secret) = 0; virtual void PlayerLoginFailed(unsigned requestId) = 0; virtual void CreateGameSuccess(unsigned requestId, DB_id gameId) = 0; diff --git a/src/db/serverdbgeneric.h b/src/db/serverdbgeneric.h index 0ffd337b..2f68e5fc 100644 --- a/src/db/serverdbgeneric.h +++ b/src/db/serverdbgeneric.h @@ -38,7 +38,7 @@ public: virtual void Start(); virtual void Stop(); - virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName, const std::string &secretString); + virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName); virtual void PlayerLogout(DB_id playerId); virtual void AsyncCreateGame(unsigned requestId, const std::string &gameName); diff --git a/src/db/serverdbinterface.h b/src/db/serverdbinterface.h index 35e6348d..c4323924 100644 --- a/src/db/serverdbinterface.h +++ b/src/db/serverdbinterface.h @@ -38,7 +38,7 @@ public: virtual void Start() = 0; virtual void Stop() = 0; - virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName, const std::string &secretString) = 0; + virtual void AsyncPlayerLogin(unsigned requestId, const std::string &playerName) = 0; virtual void PlayerLogout(DB_id playerId) = 0; virtual void AsyncCreateGame(unsigned requestId, const std::string &gameName) = 0; diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 9b8abb29..9bd5d0d5 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -111,14 +111,14 @@ public: // TODO } - virtual void PlayerLoginSuccess(unsigned requestId, DB_id dbPlayerId) + virtual void PlayerLoginSuccess(unsigned requestId, DB_id dbPlayerId, const std::string &secret) { - m_server.AuthenticationSuccess(requestId, dbPlayerId); + m_server.UserValid(requestId, dbPlayerId, secret); } virtual void PlayerLoginFailed(unsigned requestId) { - m_server.AuthenticationFailure(requestId); + m_server.UserInvalid(requestId); } virtual void CreateGameSuccess(unsigned requestId, DB_id gameId) @@ -707,11 +707,8 @@ ServerLobbyThread::InitAuthContext() void ServerLobbyThread::ClearAuthContext() { - if (m_authContext) - { - gsasl_done(m_authContext); - m_authContext = NULL; - } + gsasl_done(m_authContext); + m_authContext = NULL; } void @@ -1294,17 +1291,17 @@ void ServerLobbyThread::AuthenticatePlayer(SessionWrapper session, const std::string &password) { assert(session.playerData); - m_database->AsyncPlayerLogin(session.playerData->GetUniqueId(), session.playerData->GetName(), password); + m_database->AsyncPlayerLogin(session.playerData->GetUniqueId(), session.playerData->GetName()); } void -ServerLobbyThread::AuthenticationSuccess(unsigned playerId, DB_id dbPlayerId) +ServerLobbyThread::UserValid(unsigned playerId, DB_id dbPlayerId, const string &dbSecret) { InitAfterLogin(m_sessionManager.GetSessionByUniquePlayerId(playerId, true)); } void -ServerLobbyThread::AuthenticationFailure(unsigned playerId) +ServerLobbyThread::UserInvalid(unsigned playerId) { SessionError(m_sessionManager.GetSessionByUniquePlayerId(playerId, true), ERR_NET_INVALID_PASSWORD); } diff --git a/src/net/common/sessiondata.cpp b/src/net/common/sessiondata.cpp index fb931756..60646526 100644 --- a/src/net/common/sessiondata.cpp +++ b/src/net/common/sessiondata.cpp @@ -18,16 +18,21 @@ ***************************************************************************/ #include +#include + +using namespace std; SessionData::SessionData(boost::shared_ptr 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_wantsLobbyMsg(true), m_activityTimeoutNoticeSent(false), m_callback(cb), + m_authSession(NULL), m_curAuthStep(0) { } SessionData::~SessionData() { m_callback.SignalSessionTerminated(m_id); + InternalClearAuthSession(); } SessionId @@ -71,6 +76,64 @@ SessionData::GetAsioSocket() return m_socket; } +bool +SessionData::CreateAuthSession(Gsasl *context, bool server, const string &userName, const string &password) +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_dataMutex); + InternalClearAuthSession(); + int errorCode; + if (server) + errorCode = gsasl_server_start(context, "SCRAM-SHA-1", &m_authSession); + else + errorCode = gsasl_client_start(context, "SCRAM-SHA-1", &m_authSession); + if (errorCode == GSASL_OK) + { + gsasl_property_set(m_authSession, GSASL_AUTHID, userName.c_str()); + gsasl_property_set(m_authSession, GSASL_PASSWORD, password.c_str()); + retVal = true; + } + return retVal; +} + +bool +SessionData::AuthStep(int stepNum, const std::string &inData, std::string &outData) +{ + bool retVal = false; + boost::mutex::scoped_lock lock(m_dataMutex); + if (m_authSession && stepNum == m_curAuthStep + 1) + { + m_curAuthStep = stepNum; + char *tmpOut; + size_t tmpOutSize; + int errorCode = gsasl_step(m_authSession, inData.c_str(), inData.length(), &tmpOut, &tmpOutSize); + if (errorCode == GSASL_NEEDS_MORE) + { + outData = string(tmpOut, tmpOutSize); + retVal = true; + } + else if (errorCode == GSASL_OK && stepNum != 1) + { + outData = string(tmpOut, tmpOutSize); + retVal = true; + InternalClearAuthSession(); + } + gsasl_free(tmpOut); + } + return retVal; +} + +void +SessionData::InternalClearAuthSession() +{ + if (m_authSession) + { + gsasl_finish(m_authSession); + m_authSession = NULL; + m_curAuthStep = 0; + } +} + void SessionData::SetReadyFlag() { diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index dd1616bd..49f61da5 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -140,8 +140,8 @@ 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 AuthenticationFailure(unsigned playerId); + void UserValid(unsigned playerId, DB_id dbPlayerId, const std::string &dbSecret); + void UserInvalid(unsigned playerId); void RequestPlayerAvatar(SessionWrapper session); void TimerRemoveGame(const boost::system::error_code &ec); void TimerRemovePlayer(const boost::system::error_code &ec); diff --git a/src/net/sessiondata.h b/src/net/sessiondata.h index 27d795f7..a331b499 100644 --- a/src/net/sessiondata.h +++ b/src/net/sessiondata.h @@ -36,6 +36,9 @@ typedef unsigned SessionId; #define SESSION_ID_INIT INVALID_SESSION #define SESSION_ID_GENERIC 0xFFFFFFFF +struct Gsasl; +struct Gsasl_session; + class SessionData { public: @@ -54,6 +57,9 @@ public: boost::shared_ptr GetAsioSocket(); + bool CreateAuthSession(Gsasl *context, bool server, const std::string &userName, const std::string &password); + bool AuthStep(int stepNum, const std::string &inData, std::string &outData); + void SetReadyFlag(); void ResetReadyFlag(); bool IsReady() const; @@ -72,6 +78,9 @@ public: void MarkActivityNotice(); unsigned GetAutoDisconnectTimerElapsedSec() const; +protected: + void InternalClearAuthSession(); + private: boost::shared_ptr m_socket; const SessionId m_id; @@ -85,6 +94,8 @@ private: bool m_activityTimeoutNoticeSent; boost::timers::portable::microsec_timer m_autoDisconnectTimer; SessionDataCallback &m_callback; + Gsasl_session *m_authSession; + int m_curAuthStep; mutable boost::mutex m_dataMutex; };