the boob will swarm your flat lands

This commit is contained in:
malloc 2018-05-14 17:45:56 -05:00
parent 4d1894066c
commit 8310d31ae2
6 changed files with 127 additions and 19 deletions

View file

@ -185,8 +185,18 @@ Communication between the master server and clients will be done over a WebSocke
</thead> </thead>
<tr> <tr>
<td class="center">1</td> <td class="center">1</td>
<td>Client Key</td> <td>Server Name</td>
<td>Big Int</td> <td>Text</td>
</tr>
<tr>
<td class="center">2</td>
<td>License</td>
<td>Text</td>
</tr>
<tr>
<td class="center">3</td>
<td>Secret</td>
<td>Blob (512b)</td>
</tr> </tr>
</table> </table>
@ -472,9 +482,11 @@ TODO: MAKE THIS SECTION NOT LOOK LIKE SHIT
0x02: COULD NOT PARSE KEY 0x02: COULD NOT PARSE KEY
#### M -> S (ID 4) #### M -> S (ID 4)
0x01: LICENSE DATA INCORRECT 0x01: MAX AUTH ATTEMPTS REACHED
0x02: LICENSE LIMIT REACHED 0x02: LICENSE DATA INCORRECT
0x03: LICENSE LIMIT REACHED
### Master / Client ### Master / Client

View file

@ -14,6 +14,7 @@ namespace sosc {
namespace db { namespace db {
class Query; class Query;
typedef std::vector<Query*> QueryList;
class ResultSet { class ResultSet {
public: public:

View file

@ -10,6 +10,8 @@
#include "../db/database.hpp" #include "../db/database.hpp"
#include <vector>
namespace sosc { namespace sosc {
/** MASTER -> CLIENT **/ /** MASTER -> CLIENT **/
@ -36,7 +38,7 @@ protected:
class MasterIntra { class MasterIntra {
public: public:
explicit MasterIntra(const IntraClient& client); explicit MasterIntra(const IntraClient& client);
bool Process(); bool Process(const db::QueryList* queries);
bool Close(); bool Close();
bool Close(const Packet& message); bool Close(const Packet& message);
@ -45,6 +47,9 @@ private:
bool Authentication(Packet& pck); bool Authentication(Packet& pck);
bool StatusUpdate(Packet& pck); bool StatusUpdate(Packet& pck);
bool AuthenticationFailure
(const std::string& packetId, uint16_t errorCode);
enum SlaveToMasterId { enum SlaveToMasterId {
kInitAttempt = 1, kInitAttempt = 1,
kAuthentication, kAuthentication,
@ -66,13 +71,21 @@ private:
int auth_attempts; int auth_attempts;
const int MAX_AUTH_ATTEMPTS = 3; const int MAX_AUTH_ATTEMPTS = 3;
std::string license; std::string license;
const db::QueryList* queries;
}; };
class MasterIntraPool : public Pool<MasterIntra> { class MasterIntraPool : public Pool<MasterIntra> {
public:
MasterIntraPool();
protected: protected:
bool ProcessClient(MasterIntra& client) override { bool ProcessClient(MasterIntra& client) override {
return client.Process(); return client.Process(&this->queries);
} }
void Stop() override;
private:
db::QueryList queries;
}; };
} }

View file

@ -1,5 +1,43 @@
#include "master.hpp" #include "master.hpp"
#include "../db/database.hpp" #include "../db/database.hpp"
#include <mutex>
static struct {
std::mutex license_check_mtx;
} _ctx;
/** MASTERINTRAPOOL CODE **/
sosc::MasterIntraPool::MasterIntraPool() {
#define QRY_LICENSE_CHECK 0
this->queries.push_back(new db::Query(
"SELECT COUNT(*) FROM SERVER_LICENSES "
"WHERE KEY_ID = ? AND SECRET = ?"
));
#define QRY_LICENSE_LIMIT 1
this->queries.push_back(new db::Query(
"SELECT ALLOWANCE FROM SERVER_LICENSES WHERE KEY_ID = ?"
));
#define QRY_LICENSE_ACTIVE_COUNT 2
this->queries.push_back(new db::Query(
"SELECT COUNT(*) FROM SERVER_LIST WHERE LICENSE = ?"
, DB_USE_MEMORY));
#define QRY_LICENSE_
}
void sosc::MasterIntraPool::Stop() {
Pool<MasterIntra>::Stop();
for(auto& query : this->queries) {
query->Close();
delete query;
}
}
/** MASTERINTRA CODE **/
sosc::MasterIntra::MasterIntra(const IntraClient& client) { sosc::MasterIntra::MasterIntra(const IntraClient& client) {
this->sock = client; this->sock = client;
@ -7,7 +45,7 @@ sosc::MasterIntra::MasterIntra(const IntraClient& client) {
this->auth_attempts = 0; this->auth_attempts = 0;
} }
bool sosc::MasterIntra::Process() { bool sosc::MasterIntra::Process(const db::QueryList* queries) {
Packet pck; Packet pck;
int status = this->sock.Receive(&pck); int status = this->sock.Receive(&pck);
if(status == PCK_ERR) if(status == PCK_ERR)
@ -15,6 +53,7 @@ bool sosc::MasterIntra::Process() {
else if(status == PCK_MORE) else if(status == PCK_MORE)
return true; return true;
this->queries = queries;
switch(pck.GetId()) { switch(pck.GetId()) {
case kInitAttempt: case kInitAttempt:
return this->InitAttempt(pck); return this->InitAttempt(pck);
@ -27,7 +66,8 @@ bool sosc::MasterIntra::Process() {
} }
} }
bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck) { bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck)
{
if(!pck.Check(1, key.key_size_bytes)) if(!pck.Check(1, key.key_size_bytes))
return this->Close(Packet(kEncryptionError, { "\x01" })); return this->Close(Packet(kEncryptionError, { "\x01" }));
@ -38,24 +78,62 @@ bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck) {
this->sock.Send(response); this->sock.Send(response);
} }
bool sosc::MasterIntra::Authentication(sosc::Packet &pck) { bool sosc::MasterIntra::Authentication(sosc::Packet &pck)
{
if(this->authed) if(this->authed)
return true; return true;
if(!pck.Check(2, PCK_ANY, 512)) std::string packetId = BYTESTR(kAuthentication);
return this->Close(Packet(kNegativeAck, { "\x01" })); if(!pck.Check(3, PCK_ANY, PCK_ANY, 512))
return this->Close();
db::Query = db::Query::ScalarInt32( db::Query* query = this->queries->at(QRY_LICENSE_CHECK);
"SELECT COUNT(*) FROM SERVER_LICENSES " query->Reset();
"WHERE KEY_ID = ? AND SECRET = ?" query->BindText(pck[1], 0);
); query->BindBlob(pck[2], 1);
if(query->ScalarInt32() == 0)
return AuthenticationFailure(packetId, 2);
if(isValid > 0) { _ctx.license_check_mtx.lock();
int limit;
query = this->queries->at(QRY_LICENSE_LIMIT);
query->Reset();
query->BindText(pck[1], 0);
if((limit = query->ScalarInt32()) != 0) {
query = this->queries->at(QRY_LICENSE_ACTIVE_COUNT);
query->Reset();
query->BindText(pck[1], 0);
if(query->ScalarInt32() < limit) {
_ctx.license_check_mtx.unlock();
return AuthenticationFailure(packetId, 3);
}
}
_ctx.license_check_mtx.unlock();
this->authed = true;
return true;
}
bool sosc::MasterIntra::AuthenticationFailure
(const std::string& packetId, uint16_t errorCode)
{
if(++this->auth_attempts < MAX_AUTH_ATTEMPTS) {
this->sock.Send(
Packet(kNegativeAck, { packetId , net::htonv(errorCode) })
);
return true;
} else {
return this->Close(
Packet(kNegativeAck, { packetId, net::htonv<uint16_t>(1) })
);
} }
} }
bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck) { bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck)
{
} }

View file

@ -40,7 +40,7 @@ public:
return this->is_open; return this->is_open;
} }
void Stop(); virtual void Stop();
protected: protected:
virtual bool ProcessClient(T& client) = 0; virtual bool ProcessClient(T& client) = 0;
private: private:

View file

@ -10,6 +10,10 @@
#undef TOSTR #undef TOSTR
#define TOSTR(X) std::to_string(X) #define TOSTR(X) std::to_string(X)
#undef bytestr
#undef BYTESTR
#define BYTESTR(X) std::string(1, X)
namespace sosc { namespace sosc {
namespace str { namespace str {
std::string trim (std::string str); std::string trim (std::string str);