Initial release of client ID generation.

This commit is contained in:
woogerboy21 2015-08-05 10:15:49 -04:00
parent 44d757f691
commit 52db13a1ca
14 changed files with 246 additions and 186 deletions

View file

@ -1,4 +1,4 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker * * Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@gmx.net * * brukie@gmx.net *
* * * *
@ -32,6 +32,9 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QDebug> #include <QDebug>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include "QtNetwork/QNetworkInterface"
#include <QCryptographicHash>
#include "main.h" #include "main.h"
#include "window_main.h" #include "window_main.h"
@ -97,6 +100,19 @@ bool settingsValid()
!settingsCache->getPicsPath().isEmpty(); !settingsCache->getPicsPath().isEmpty();
} }
void generateClientID()
{
QString macList;
foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
{
if (interface.hardwareAddress() != "")
if (interface.hardwareAddress() != "00:00:00:00:00:00:00:E0")
macList += interface.hardwareAddress() + ".";
}
QString strClientID = QCryptographicHash::hash(macList.toUtf8(), QCryptographicHash::Sha1).toHex().right(15);
settingsCache->setClientID(strClientID);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
@ -204,6 +220,9 @@ int main(int argc, char *argv[])
QIcon icon(":/resources/appicon.svg"); QIcon icon(":/resources/appicon.svg");
ui.setWindowIcon(icon); ui.setWindowIcon(icon);
generateClientID(); //generate the users client id
qDebug() << "ClientID In Cache: " << settingsCache->getClientID();
ui.show(); ui.show();
qDebug("main(): ui.show() finished"); qDebug("main(): ui.show() finished");

View file

@ -14,6 +14,7 @@ extern const QString translationPrefix;
extern QString translationPath; extern QString translationPath;
void installNewTranslator(); void installNewTranslator();
void generateClientID();
bool settingsValid(); bool settingsValid();

View file

@ -10,6 +10,7 @@
#include "pb/response_activate.pb.h" #include "pb/response_activate.pb.h"
#include "pb/server_message.pb.h" #include "pb/server_message.pb.h"
#include "pb/event_server_identification.pb.h" #include "pb/event_server_identification.pb.h"
#include "settingscache.h"
static const unsigned int protocolVersion = 14; static const unsigned int protocolVersion = 14;
@ -108,7 +109,7 @@ void RemoteClient::doLogin()
Command_Login cmdLogin; Command_Login cmdLogin;
cmdLogin.set_user_name(userName.toStdString()); cmdLogin.set_user_name(userName.toStdString());
cmdLogin.set_password(password.toStdString()); cmdLogin.set_password(password.toStdString());
cmdLogin.set_clientid(settingsCache->getClientID().toStdString());
PendingCommand *pend = prepareSessionCommand(cmdLogin); PendingCommand *pend = prepareSessionCommand(cmdLogin);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response))); connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response)));
sendCommand(pend); sendCommand(pend);
@ -243,6 +244,7 @@ void RemoteClient::doConnectToServer(const QString &hostname, unsigned int port,
userName = _userName; userName = _userName;
password = _password; password = _password;
QString clientid = settingsCache->getClientID();
lastHostname = hostname; lastHostname = hostname;
lastPort = port; lastPort = port;

View file

@ -85,9 +85,7 @@ SettingsCache::SettingsCache()
masterVolume = settings->value("sound/mastervolume", 100).toInt(); masterVolume = settings->value("sound/mastervolume", 100).toInt();
cardInfoViewMode = settings->value("cards/cardinfoviewmode", 0).toInt(); cardInfoViewMode = settings->value("cards/cardinfoviewmode", 0).toInt();
highlightWords = settings->value("personal/highlightWords", QString()).toString(); highlightWords = settings->value("personal/highlightWords", QString()).toString();
gameDescription = settings->value("game/gamedescription","").toString(); gameDescription = settings->value("game/gamedescription","").toString();
maxPlayers = settings->value("game/maxplayers", 2).toInt(); maxPlayers = settings->value("game/maxplayers", 2).toInt();
gameTypes = settings->value("game/gametypes","").toString(); gameTypes = settings->value("game/gametypes","").toString();
@ -97,6 +95,8 @@ SettingsCache::SettingsCache()
spectatorsNeedPassword = settings->value("game/spectatorsneedpassword", false).toBool(); spectatorsNeedPassword = settings->value("game/spectatorsneedpassword", false).toBool();
spectatorsCanTalk = settings->value("game/spectatorscantalk", false).toBool(); spectatorsCanTalk = settings->value("game/spectatorscantalk", false).toBool();
spectatorsCanSeeEverything = settings->value("game/spectatorscanseeeverything", false).toBool(); spectatorsCanSeeEverything = settings->value("game/spectatorscanseeeverything", false).toBool();
clientID = settings->value("personal/clientid", "notset").toString();
} }
void SettingsCache::setCardInfoViewMode(const int _viewMode) { void SettingsCache::setCardInfoViewMode(const int _viewMode) {
@ -424,6 +424,12 @@ void SettingsCache::setPixmapCacheSize(const int _pixmapCacheSize)
emit pixmapCacheSizeChanged(pixmapCacheSize); emit pixmapCacheSizeChanged(pixmapCacheSize);
} }
void SettingsCache::setClientID(QString _clientID)
{
clientID = _clientID;
settings->setValue("personal/clientid", clientID);
}
QStringList SettingsCache::getCountries() const QStringList SettingsCache::getCountries() const
{ {
static QStringList countries = QStringList() static QStringList countries = QStringList()

View file

@ -79,6 +79,7 @@ private:
QString picUrlHq; QString picUrlHq;
QString picUrlFallback; QString picUrlFallback;
QString picUrlHqFallback; QString picUrlHqFallback;
QString clientID;
bool attemptAutoConnect; bool attemptAutoConnect;
int pixmapCacheSize; int pixmapCacheSize;
bool scaleCards; bool scaleCards;
@ -169,6 +170,8 @@ public:
bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } bool getSpectatorsCanTalk() const { return spectatorsCanTalk; }
bool getSpectatorsCanSeeEverything() const { return spectatorsCanSeeEverything; } bool getSpectatorsCanSeeEverything() const { return spectatorsCanSeeEverything; }
int getKeepAlive() const { return keepalive; } int getKeepAlive() const { return keepalive; }
void setClientID(QString clientID);
QString getClientID() { return clientID; }
public slots: public slots:
void setMainWindowGeometry(const QByteArray &_mainWindowGeometry); void setMainWindowGeometry(const QByteArray &_mainWindowGeometry);
void setLang(const QString &_lang); void setLang(const QString &_lang);

View file

@ -35,6 +35,7 @@ message Response {
RespActivationAccepted = 31; // Server accepted a reg user activation token RespActivationAccepted = 31; // Server accepted a reg user activation token
RespActivationFailed = 32; // Server didn't accept a reg user activation token RespActivationFailed = 32; // Server didn't accept a reg user activation token
RespRegistrationAcceptedNeedsActivation = 33; // Server accepted cient registration, but it will need token activation RespRegistrationAcceptedNeedsActivation = 33; // Server accepted cient registration, but it will need token activation
RespClientIDRequired = 34; // Server require's client to generate and send its client id before allowing access
} }
enum ResponseType { enum ResponseType {
JOIN_ROOM = 1000; JOIN_ROOM = 1000;

View file

@ -43,6 +43,7 @@ message Command_Login {
} }
optional string user_name = 1; optional string user_name = 1;
optional string password = 2; optional string password = 2;
optional string clientid = 3;
} }
message Command_Message { message Command_Message {

View file

@ -103,7 +103,7 @@ Server_DatabaseInterface *Server::getDatabaseInterface() const
return databaseInterfaces.value(QThread::currentThread()); return databaseInterfaces.value(QThread::currentThread());
} }
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft) AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid)
{ {
if (name.size() > 35) if (name.size() > 35)
name = name.left(35); name = name.left(35);
@ -123,6 +123,8 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
databaseInterface->lockSessionTables(); databaseInterface->lockSessionTables();
if (authState == PasswordRight) { if (authState == PasswordRight) {
// verify that new session would not cause problems with older existing session
if (users.contains(name) || databaseInterface->userSessionExists(name)) { if (users.contains(name) || databaseInterface->userSessionExists(name)) {
qDebug("Login denied: would overwrite old session"); qDebug("Login denied: would overwrite old session");
databaseInterface->unlockSessionTables(); databaseInterface->unlockSessionTables();
@ -168,6 +170,15 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true));
locker.unlock(); locker.unlock();
// check if client id exists (older client compatibility)
if (clientid.isEmpty()){
// client id is empty, either out dated client or client has been modified
}
else {
// update users database table with client id
databaseInterface->updateUsersClientID(name, clientid);
}
se = Server_ProtocolHandler::prepareSessionEvent(event); se = Server_ProtocolHandler::prepareSessionEvent(event);
sendIsl_SessionEvent(*se); sendIsl_SessionEvent(*se);
delete se; delete se;

View file

@ -44,7 +44,7 @@ public:
Server(bool _threaded, QObject *parent = 0); Server(bool _threaded, QObject *parent = 0);
~Server(); ~Server();
void setThreaded(bool _threaded) { threaded = _threaded; } void setThreaded(bool _threaded) { threaded = _threaded; }
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft); AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft, QString &clientid);
const QMap<int, Server_Room *> &getRooms() { return rooms; } const QMap<int, Server_Room *> &getRooms() { return rooms; }

View file

@ -41,6 +41,7 @@ public:
virtual bool getRequireRegistration() { return false; } virtual bool getRequireRegistration() { return false; }
virtual bool registerUser(const QString & /* userName */, const QString & /* realName */, ServerInfo_User_Gender const & /* gender */, const QString & /* password */, const QString & /* emailAddress */, const QString & /* country */, bool /* active = false */) { return false; } virtual bool registerUser(const QString & /* userName */, const QString & /* realName */, ServerInfo_User_Gender const & /* gender */, const QString & /* password */, const QString & /* emailAddress */, const QString & /* country */, bool /* active = false */) { return false; }
virtual bool activateUser(const QString & /* userName */, const QString & /* token */) { return false; } virtual bool activateUser(const QString & /* userName */, const QString & /* token */) { return false; }
virtual void updateUsersClientID(const QString & /* userName */, const QString & /* userClientID */) { }
enum LogMessage_TargetType { MessageTargetRoom, MessageTargetGame, MessageTargetChat, MessageTargetIslRoom }; enum LogMessage_TargetType { MessageTargetRoom, MessageTargetGame, MessageTargetChat, MessageTargetIslRoom };
virtual void logMessage(const int /* senderId */, const QString & /* senderName */, const QString & /* senderIp */, const QString & /* logMessage */, LogMessage_TargetType /* targetType */, const int /* targetId */, const QString & /* targetName */) { }; virtual void logMessage(const int /* senderId */, const QString & /* senderName */, const QString & /* senderIp */, const QString & /* logMessage */, LogMessage_TargetType /* targetType */, const int /* targetId */, const QString & /* targetName */) { };

View file

@ -381,11 +381,12 @@ Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cm
Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc) Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc)
{ {
QString userName = QString::fromStdString(cmd.user_name()).simplified(); QString userName = QString::fromStdString(cmd.user_name()).simplified();
QString clientid = QString::fromStdString(cmd.clientid()).simplified();
if (userName.isEmpty() || (userInfo != 0)) if (userName.isEmpty() || (userInfo != 0))
return Response::RespContextError; return Response::RespContextError;
QString reasonStr; QString reasonStr;
int banSecondsLeft = 0; int banSecondsLeft = 0;
AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft); AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft, clientid);
switch (res) { switch (res) {
case UserIsBanned: { case UserIsBanned: {
Response_Login *re = new Response_Login; Response_Login *re = new Response_Login;

View file

@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_schema_version` (
PRIMARY KEY (`version`) PRIMARY KEY (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO cockatrice_schema_version VALUES(1); INSERT INTO cockatrice_schema_version VALUES(3);
CREATE TABLE IF NOT EXISTS `cockatrice_decklist_files` ( CREATE TABLE IF NOT EXISTS `cockatrice_decklist_files` (
`id` int(7) unsigned zerofill NOT NULL auto_increment, `id` int(7) unsigned zerofill NOT NULL auto_increment,
@ -83,6 +83,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` (
`registrationDate` datetime NOT NULL, `registrationDate` datetime NOT NULL,
`active` tinyint(1) NOT NULL, `active` tinyint(1) NOT NULL,
`token` binary(16) NOT NULL, `token` binary(16) NOT NULL,
`clientid` varchar(15) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`), UNIQUE KEY `name` (`name`),
KEY `token` (`token`), KEY `token` (`token`),

View file

@ -828,3 +828,16 @@ int Servatrice_DatabaseInterface::getActiveUserCount()
return userCount; return userCount;
} }
void Servatrice_DatabaseInterface::updateUsersClientID(const QString &userName, const QString &userClientID)
{
if (!checkSql())
return;
QSqlQuery *query = prepareQuery("update {prefix}_users set clientid = :clientid where name = :username");
query->bindValue(":clientid", userClientID);
query->bindValue(":username", userName);
execSqlQuery(query);
}

View file

@ -9,7 +9,7 @@
#include "server.h" #include "server.h"
#include "server_database_interface.h" #include "server_database_interface.h"
#define DATABASE_SCHEMA_VERSION 2 #define DATABASE_SCHEMA_VERSION 3
class Servatrice; class Servatrice;
@ -72,7 +72,7 @@ public:
bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender, bool registerUser(const QString &userName, const QString &realName, ServerInfo_User_Gender const &gender,
const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false); const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false);
bool activateUser(const QString &userName, const QString &token); bool activateUser(const QString &userName, const QString &token);
void updateUsersClientID(const QString &userName, const QString &userClientID);
void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage,
LogMessage_TargetType targetType, const int targetId, const QString &targetName); LogMessage_TargetType targetType, const int targetId, const QString &targetName);
bool changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword); bool changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword);