add support Qt-Secret

This commit is contained in:
Andrei Yankovich 2019-06-09 17:15:50 +03:00
parent 9fc5e6f66c
commit 2e4801b505
20 changed files with 433 additions and 77 deletions

3
.gitmodules vendored
View File

@ -2,3 +2,6 @@
path = QuasarAppLib
url = https://github.com/QuasarApp/QuasarAppLib.git
[submodule "SnakeServer/Qt-Secret"]
path = SnakeServer/Qt-Secret
url = git@github.com:QuasarApp/Qt-Secret.git

View File

@ -18,6 +18,7 @@ CONFIG(release, debug|release): {
LIBS += -L$$CLIENTPROTOCOL_LIB_OUTPUT_DIR -lClientProtocol
include($$PWD/ClientProtocolIncludes.pri)
include($$PWD/../Qt-Secret/src/Qt-Secret.pri)

View File

@ -39,12 +39,14 @@ CONFIG(release, debug|release): {
include($$PWD/../../QuasarAppLib/QuasarLib.pri)
include($$PWD/../../SnakeUtils/SnakeUtils.pri)
include($$PWD/../Qt-Secret/src/Qt-Secret.pri)
SOURCES += \
Objects/basenetworkobject.cpp \
Objects/map.cpp \
Objects/objdata.cpp \
Objects/pubkey.cpp \
Objects/snake.cpp \
clientprotocol.cpp \
client.cpp \
@ -53,6 +55,7 @@ SOURCES += \
Objects/login.cpp \
networkclasssize.cpp \
Objects/player.cpp \
rsakeyspool.cpp \
server.cpp \
factorynetobjects.cpp \
connectioninfo.cpp \
@ -63,6 +66,7 @@ HEADERS += \
Objects/basenetworkobject.h \
Objects/map.h \
Objects/objdata.h \
Objects/pubkey.h \
Objects/snake.h \
clientprotocol.h \
clientprotocol_global.h \
@ -72,6 +76,7 @@ HEADERS += \
networkclasssize.h \
client.h \
Objects/player.h \
rsakeyspool.h \
server.h \
cp.h \
config.h \

View File

@ -0,0 +1,58 @@
#include "pubkey.h"
#include "clientprotocol.h"
namespace ClientProtocol {
PubKey::PubKey() {
_class = static_cast<quint8>(Command::PubKey);
}
QRSAEncryption::Rsa PubKey::getTypeKey() const {
return typeKey;
}
void PubKey::setTypeKey(const QRSAEncryption::Rsa &value) {
typeKey = value;
}
QByteArray PubKey::getKey() const {
return key;
}
void PubKey::setKey(const QByteArray &value) {
key = value;
}
BaseNetworkObject *PubKey::create() const {
return new PubKey();
}
NetworkClassSize PubKey::classSize() const {
return BaseNetworkObject::classSize() +
QRSAEncryption::getBytesSize(typeKey) +
static_cast<unsigned int>(sizeof (int)) +
getTypeSize(typeKey);
}
QDataStream &PubKey::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << int(typeKey);
stream << key;
return stream;
}
QDataStream &PubKey::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
int _typeKey;
stream >> _typeKey;
typeKey = static_cast<QRSAEncryption::Rsa>(_typeKey);
stream >> key;
return stream;
}
bool PubKey::isValid() const {
return static_cast<quint32>(key.size()) == QRSAEncryption::getBytesSize(typeKey)
&& BaseNetworkObject::isValid();
}
}

View File

@ -0,0 +1,30 @@
#ifndef PUBKEY_H
#define PUBKEY_H
#include <qrsaencryption.h>
#include "basenetworkobject.h"
namespace ClientProtocol {
class PubKey: public BaseNetworkObject
{
private:
QRSAEncryption::Rsa typeKey;
QByteArray key;
public:
PubKey();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
QRSAEncryption::Rsa getTypeKey() const;
void setTypeKey(const QRSAEncryption::Rsa &value);
QByteArray getKey() const;
void setKey(const QByteArray &value);
};
}
#endif // PUBKEY_H

View File

@ -9,6 +9,7 @@
#include <QVariantMap>
#include <factorynetobjects.h>
#include <map.h>
#include <pubkey.h>
#include <snake.h>
#define DEFAULT_GAME_PORT 7777
@ -183,6 +184,12 @@ bool initClientProtockol() {
static_cast<quint8>(Command::Map))) {
return false;
}
if (!FactoryNetObjects::regType<PubKey>(
static_cast<quint8>(Command::PubKey))) {
return false;
}
return true;
}

View File

@ -28,7 +28,8 @@ enum class Command: quint8 {
GetItem = 0x06,
Player = 0x07,
Snake = 0x08,
Map = 0x09
Map = 0x09,
PubKey = 0x0a
};
bool isValidSize(quint8 type, unsigned int size);

View File

@ -1,14 +1,67 @@
#include "connectioninfo.h"
#include <QTcpSocket>
QString ConnectionInfo::getAddres() const
{
return addres;
namespace ClientProtocol {
int Connectioninfo::getKarma() const {
return karma;
}
ConnectionInfo::ConnectionInfo(const QString &addrrss) {
addres = addrrss;
void Connectioninfo::setKarma(int value) {
karma = value;
}
bool ConnectionInfo::operator ==(const ConnectionInfo &otherInfo) const {
return addres == otherInfo.addres;
RSAKeyPair Connectioninfo::getRSAKey() const {
return RSAKey;
}
void Connectioninfo::setRSAKey(const RSAKeyPair &value) {
RSAKey = value;
}
QTcpSocket *Connectioninfo::getSct() const {
return sct;
}
void Connectioninfo::setSct(QTcpSocket *value) {
sct = value;
}
void Connectioninfo::disconnect() {
if (sct) {
sct->close();
delete sct;
sct = nullptr;
}
}
void Connectioninfo::ban() {
karma = BANED_KARMA;
disconnect();
}
bool Connectioninfo::isBaned() const {
return karma < 1;
}
void Connectioninfo::unBan() {
karma = RESTORE_KARMA;
}
bool Connectioninfo::isValid() const {
return sct && !RSAKey.pub.isEmpty() && !RSAKey.priv.isEmpty();
}
Connectioninfo::Connectioninfo(QTcpSocket *tcp, int kar, RSAKeyPair keys) {
sct = tcp;
karma = kar;
RSAKey = keys;
}
Connectioninfo::~Connectioninfo() {
if (sct) {
sct->deleteLater();
}
}
}

View File

@ -1,17 +1,43 @@
#ifndef CONNECTIONINFO_H
#define CONNECTIONINFO_H
#include <QString>
#include "rsakeyspool.h"
class QTcpSocket;
namespace ClientProtocol {
#define NOT_VALID_CARMA 0xFF
#define DEFAULT_KARMA 100
#define RESTORE_KARMA 20
#define BANED_KARMA 0
class Connectioninfo {
QTcpSocket *sct = nullptr;
int karma = DEFAULT_KARMA;
RSAKeyPair RSAKey;
class ConnectionInfo
{
private:
QString addres = "";
public:
ConnectionInfo(const QString & addrrss);
bool operator == (const ConnectionInfo &otherInfo) const;
void disconnect();
QString getAddres() const;
void ban();
bool isBaned() const;
void unBan();
bool isValid() const;
Connectioninfo(QTcpSocket * tcp = nullptr,
int kar = NOT_VALID_CARMA,
RSAKeyPair keys = RSAKeyPair());
~Connectioninfo();
int getKarma() const;
void setKarma(int value);
RSAKeyPair getRSAKey() const;
void setRSAKey(const RSAKeyPair &value);
QTcpSocket *getSct() const;
void setSct(QTcpSocket *value);
};
}
#endif // CONNECTIONINFO_H

View File

@ -0,0 +1,27 @@
#include "rsakeyspool.h"
#include <QMutexLocker>
namespace ClientProtocol {
bool RSAKeysPool::take(QRSAEncryption::Rsa rsa, RSAKeyPair& res) {
QMutexLocker locker(&multithread);
if (pool.value(rsa).isEmpty()) {
emit sigKeyTaked();
return false;
}
res = pool.value(rsa).begin().value();
return true;
}
void RSAKeysPool::addNewKey(QRSAEncryption::Rsa rsa, const RSAKeyPair& key) {
QMutexLocker locker(&multithread);
pool[rsa].insert(static_cast<int>(time(nullptr)), key);
}
int RSAKeysPool::size(QRSAEncryption::Rsa rsa) const {
return pool.value(rsa).size();
}
}

View File

@ -0,0 +1,35 @@
#ifndef RSAKEYSPOOL_H
#define RSAKEYSPOOL_H
#include <QHash>
#include <QObject>
#include <qrsaencryption.h>
#include <QMutex>
#include <QMap>
namespace ClientProtocol {
struct RSAKeyPair {
QByteArray pub;
QByteArray priv;
};
typedef QMap<int, RSAKeyPair> KeysPool;
typedef QHash<QRSAEncryption::Rsa, KeysPool> PoolData;
class RSAKeysPool: public QObject {
Q_OBJECT
private:
PoolData pool;
QMutex multithread;
public:
bool take(QRSAEncryption::Rsa rsa, RSAKeyPair &res);
void addNewKey(QRSAEncryption::Rsa rsa, const RSAKeyPair& key);
int size(QRSAEncryption::Rsa rsa) const;
signals:
void sigKeyTaked();
};
}
#endif // RSAKEYSPOOL_H

View File

@ -2,6 +2,7 @@
#include "quasarapp.h"
#include <QTcpSocket>
#include <factorynetobjects.h>
#include <pubkey.h>
#include "clientprotocol.h"
namespace ClientProtocol {
@ -72,29 +73,45 @@ bool Server::sendPackage(Package &pkg, QTcpSocket * target) {
}
void Server::ban(quint32 target) {
_connections[target].karma = BANED_KARMA;
if (_connections[target].sct) {
_connections[target].sct->close();
}
_connections[target].ban();
}
void Server::unBan(quint32 target) {
_connections[target].karma = RESTORE_KARMA;
_connections[target].unBan();
}
void Server::registerSocket(QTcpSocket *socket) {
bool Server::registerSocket(QTcpSocket *socket) {
auto address = socket->peerAddress().toIPv4Address();
_connections[address].karma = DEFAULT_KARMA;
_connections[address].sct = socket;
if (_pool) {
QuasarAppUtils::Params::verboseLog("key pool is not inited", QuasarAppUtils::Error);
return false;
}
RSAKeyPair pair;
if (!_pool->take(QRSAEncryption::RSA_128, pair)) {
QuasarAppUtils::Params::verboseLog("key pool is empty", QuasarAppUtils::Error);
return false;
}
_connections[address] = Connectioninfo(socket, DEFAULT_KARMA,
pair);
connect(socket, &QTcpSocket::readyRead, this, &Server::avelableBytes);
connect(socket, &QTcpSocket::disconnected, this, &Server::handleDisconected);
if (!sendPubKey(socket, pair.pub)) {
QuasarAppUtils::Params::verboseLog("not sendet pub key to client"
"generate new key!", QuasarAppUtils::Error);
return false;
}
return true;
}
bool Server::changeKarma(quint32 addresss, int diff) {
auto objKarma = _connections.value(addresss).karma;
auto objKarma = _connections.value(addresss).getKarma();
if (objKarma >= NOT_VALID_CARMA) {
return false;
@ -104,28 +121,21 @@ bool Server::changeKarma(quint32 addresss, int diff) {
return false;
}
_connections[addresss].karma += diff;
_connections[addresss].setKarma(objKarma + diff);
return true;
}
bool Server::isBaned(const QTcpSocket * adr) const {
return _connections.value(adr->peerAddress().toIPv4Address()).karma < 1;
}
void Server::saveKarma() const {
}
bool Server::loadKarma() {
return false;
return _connections.value(adr->peerAddress().toIPv4Address()).isBaned();
}
int Server::connectionsCount() const {
int count = 0;
for (auto i : _connections) {
if (i.sct) {
if (!i.sct->isValid()) {
// log about warning
if (i.getSct()) {
if (!i.getSct()->isValid()) {
QuasarAppUtils::Params::verboseLog("connection count, findet not valid socket",
QuasarAppUtils::Warning);
}
count++;
@ -134,6 +144,28 @@ int Server::connectionsCount() const {
return count;
}
bool Server::sendPubKey(QTcpSocket * target, const QByteArray &pubKey) {
Package pcg;
PubKey pubkey;
pubkey.setKey(pubKey);
pubkey.setTypeKey(QRSAEncryption::RSA_128);
pubkey.setId(0);
if (!pubkey.isValid()) {
return false;
}
if (!(pcg.create(&pubkey, Type::Responke))) {
return false;
};
return sendPackage(pcg, target);
}
void Server::avelableBytes() {
auto client = dynamic_cast<QTcpSocket*>(sender());
@ -167,8 +199,7 @@ void Server::handleDisconected() {
unsigned int address = _sender->peerAddress().toIPv4Address();
if (_connections.contains(address)) {
_connections[address].sct = nullptr;
_sender->deleteLater();
_connections[address].disconnect();
} else {
QuasarAppUtils::Params::verboseLog("system error in void Server::handleDisconected()"
" address not valid",
@ -195,9 +226,10 @@ void Server::handleIncommingConnection() {
}
}
Server::Server(QObject *ptr) :
Server::Server(RSAKeysPool *pool, QObject *ptr) :
QTcpServer (ptr) {
_pool = pool;
connect(this, &Server::newConnection, this, &Server::handleIncommingConnection);
}
@ -234,7 +266,7 @@ void Server::badRequest(quint32 address) {
QuasarAppUtils::Error);
};
if (!sendPackage(pcg, client.sct)) {
if (!sendPackage(pcg, client.getSct())) {
return;
}
}
@ -258,7 +290,7 @@ QString Server::connectionState() const {
QStringList Server::baned() const {
QStringList list = {};
for (auto i = _connections.begin(); i != _connections.end(); ++i) {
if (i.value().karma <= 0) {
if (i.value().isBaned()) {
list.push_back(QHostAddress(i.key()).toString());
}
}
@ -266,15 +298,5 @@ QStringList Server::baned() const {
return list;
}
Connectioninfo::Connectioninfo(QTcpSocket *tcp, int kar) {
sct = tcp;
karma = kar;
}
Connectioninfo::~Connectioninfo() {
if (sct) {
sct->deleteLater();
}
}
}

View File

@ -4,28 +4,15 @@
#include "clientprotocol.h"
#include <QTcpServer>
#include "rsakeyspool.h"
#include "connectioninfo.h"
namespace ClientProtocol {
#define NOT_VALID_CARMA 0xFF
#define DEFAULT_KARMA 100
#define RESTORE_KARMA 20
#define BANED_KARMA 0
#define CRITICAL_ERROOR -50
#define LOGICK_ERROOR -20
#define REQUEST_ERROR -5
struct Connectioninfo {
QTcpSocket *sct = nullptr;
int karma;
Connectioninfo(QTcpSocket * tcp = nullptr,
int kar = NOT_VALID_CARMA);
~Connectioninfo();
};
class CLIENTPROTOCOLSHARED_EXPORT Server : public QTcpServer
{
@ -33,17 +20,17 @@ class CLIENTPROTOCOLSHARED_EXPORT Server : public QTcpServer
private:
Package _downloadPackage;
QHash<quint32, Connectioninfo> _connections;
// QHash<quint32, int> _karma;
RSAKeysPool * _pool = nullptr;
bool parsePackage(const Package &pkg, QTcpSocket * sender);
bool sendPackage(Package &pkg, QTcpSocket * target);
void registerSocket(QTcpSocket *socket);
bool registerSocket(QTcpSocket *socket);
bool changeKarma(quint32 addresss, int diff);
inline bool isBaned(const QTcpSocket *) const;
void saveKarma() const;
bool loadKarma();
int connectionsCount() const;
bool sendPubKey(QTcpSocket *target, const QByteArray &pubKey);
private slots:
void avelableBytes();
@ -51,7 +38,7 @@ private slots:
void handleIncommingConnection();
public:
explicit Server(QObject * ptr = nullptr);
explicit Server(RSAKeysPool * pool, QObject * ptr = nullptr);
~Server() override;
bool run(const QString& ip, unsigned short port);
void stop(bool reset = false);

1
SnakeServer/Qt-Secret Submodule

@ -0,0 +1 @@
Subproject commit 2f334e8d7b3507d66daac0349694402df7c6b6a2

View File

@ -25,6 +25,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
item.cpp \
keysreactor.cpp \
mainserver.cpp \
playerdbdata.cpp \
sqldbcache.cpp \
@ -41,6 +42,7 @@ CONFIG(release, debug|release): {
HEADERS += \
item.h \
keysreactor.h \
mainserver.h \
playerdbdata.h \
server_global.h \

View File

@ -0,0 +1,60 @@
#include "keysreactor.h"
ClientProtocol::RSAKeysPool *KeysReactor::getPool() {
return &_pool;
}
int KeysReactor::getPoolSize() const {
return _poolSize;
}
void KeysReactor::setPoolSize(int value) {
if (_poolSize != value) {
_poolSize = value;
handleGenerateNewKeys();
}
}
void KeysReactor::handleGenerateNewKeys() {
auto generatorFunc = [this] (QRSAEncryption::Rsa rsa) {
if (_mutexs[rsa]) {
return;
}
_mutexs[rsa] = true;
QByteArray pub, priv;
while (_poolSize > _pool.size(rsa)) {
_generator.generatePairKey(pub, priv, rsa);
_pool.addNewKey(rsa, {pub, priv});
}
_mutexs[rsa] = false;
return;
};
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_64);
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_128);
}
KeysReactor::KeysReactor(QObject * ptr):
QObject (ptr) {
_mutexs[QRSAEncryption::RSA_64] = false;
_mutexs[QRSAEncryption::RSA_128] = false;
handleGenerateNewKeys();
connect(&_pool, &ClientProtocol::RSAKeysPool::sigKeyTaked,
this, &KeysReactor::handleGenerateNewKeys);
}
KeysReactor::~KeysReactor() {
}

View File

@ -0,0 +1,33 @@
#ifndef KEYSREACTOR_H
#define KEYSREACTOR_H
#include <qrsaencryption.h>
#include <QtConcurrent>
#include <rsakeyspool.h>
#define DEFAULT_KEYPOOL_SIZE 10
class KeysReactor: public QObject
{
Q_OBJECT
private:
ClientProtocol::RSAKeysPool _pool;
QRSAEncryption _generator;
int _poolSize = DEFAULT_KEYPOOL_SIZE;
QHash<QRSAEncryption::Rsa, bool> _mutexs;
private slots:
void handleGenerateNewKeys();
public:
KeysReactor(QObject *ptr = nullptr);
~KeysReactor() override;
ClientProtocol::RSAKeysPool* getPool();
int getPoolSize() const;
void setPoolSize(int value);
};
#endif // KEYSREACTOR_H

View File

@ -1,3 +1,4 @@
#include "keysreactor.h"
#include "mainserver.h"
#include "sqldbcache.h"
#include <spserver.h>
@ -136,7 +137,10 @@ void MainServer::handleTerminalRequest(QVariantMap obj) {
MainServer::MainServer(QObject *ptr):
QObject (ptr) {
_serverDaemon = new ClientProtocol::Server(this);
_keyReactor = new KeysReactor();
_serverDaemon = new ClientProtocol::Server(_keyReactor->getPool(), this);
_terminalPort = new ServerProtocol::Server(this);
_db = new SqlDBCache();

View File

@ -13,7 +13,7 @@ namespace ClientProtocol {
class Server;
class BaseNetworkObject;
}
class KeysReactor;
class SqlDBCache;
class SERVERSHARED_EXPORT MainServer: public QObject
@ -23,7 +23,7 @@ private:
ServerProtocol::Server *_terminalPort = nullptr;
ClientProtocol::Server *_serverDaemon= nullptr;
SqlDBCache* _db = nullptr;
KeysReactor *_keyReactor = nullptr;
bool payItem(int player, int idItem);
bool sellItem(int player, int idItem);

View File

@ -4,6 +4,7 @@ CONFIG += ordered
SUBDIRS += \
ServerProtocol \
Qt-Secret \
ClientProtocol \
Terminal \
Server \