More work on gsasl authentication.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -18,16 +18,21 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include <net/sessiondata.h>
|
||||
#include <gsasl.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
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_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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<boost::asio::ip::tcp::socket> 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<boost::asio::ip::tcp::socket> 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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user