diff --git a/protocol.md b/protocol.md
index 7239f91..f911cf1 100644
--- a/protocol.md
+++ b/protocol.md
@@ -190,11 +190,16 @@ Communication between the master server and clients will be done over a WebSocke
2 |
+ Port |
+ Packed Unsigned Short |
+
+
+ 3 |
License |
Text |
- 3 |
+ 4 |
Secret |
Blob (512b) |
@@ -219,7 +224,7 @@ Communication between the master server and clients will be done over a WebSocke
2 |
- Port |
+ Max Users |
Packed Unsigned Short |
@@ -477,16 +482,18 @@ TODO: MAKE THIS SECTION NOT LOOK LIKE SHIT
### Master / Slave
#### M -> S (ID 2)
-100: KEY SIZE WAS INCORRECT
+0x100: KEY SIZE WAS INCORRECT
-101: COULD NOT PARSE KEY
+0x101: COULD NOT PARSE KEY
#### M -> S (ID 4)
-100: MAX AUTH ATTEMPTS REACHED
+0x100: MAX AUTH ATTEMPTS REACHED
-101: LICENSE DATA INCORRECT
+0x101: LICENSE DATA INCORRECT
-102: LICENSE LIMIT REACHED
+0x102: LICENSE LIMIT REACHED
+
+0x200: NOT AUTHORIZED TO PERFORM ACTION
### Master / Client
diff --git a/server/hard_schema.db-journal b/server/hard_schema.db-journal
new file mode 100644
index 0000000..927d431
Binary files /dev/null and b/server/hard_schema.db-journal differ
diff --git a/server/src/db/_init_sql.hpp b/server/src/db/_init_sql.hpp
index be4a662..bf01e89 100644
--- a/server/src/db/_init_sql.hpp
+++ b/server/src/db/_init_sql.hpp
@@ -9,7 +9,13 @@ const char* _mem_db_sql =
"`NAME` TEXT NOT NULL,"
"`LICENSE` TEXT NOT NULL,"
"`IP_ADDR` TEXT NOT NULL,"
- "`PORT` INTEGER NOT NULL"
+ "`PORT` INTEGER NOT NULL,"
+ "`USERS` INTEGER NOT NULL DEFAULT 0,"
+ "`MAX_USERS` INTEGER NOT NULL DEFAULT 0"
+ ");\n"
+
+ "CREATE UNIQUE INDEX `UIX_SERVER_LICENSES` ON `SERVER_LICENSES` ("
+ "`KEY_ID`, `SECRET`"
");\n";
const char* _hard_db_init_migration_sql =
diff --git a/server/src/hosts/master.hpp b/server/src/hosts/master.hpp
index ef4a46b..faded2b 100644
--- a/server/src/hosts/master.hpp
+++ b/server/src/hosts/master.hpp
@@ -50,6 +50,8 @@ private:
bool AuthenticationFailure
(const std::string& packetId, uint16_t errorCode);
+ bool NotAuthorized(const std::string& packetId);
+
enum SlaveToMasterId {
kInitAttempt = 1,
kAuthentication,
diff --git a/server/src/hosts/master_intra.cpp b/server/src/hosts/master_intra.cpp
index bc31f3b..8fd3bc9 100644
--- a/server/src/hosts/master_intra.cpp
+++ b/server/src/hosts/master_intra.cpp
@@ -98,11 +98,13 @@ bool sosc::MasterIntra::Process(const db::QueryList* queries) {
bool sosc::MasterIntra::InitAttempt(sosc::Packet &pck) {
if(!pck.Check(1, key.key_size_bytes))
- return this->Close(Packet(kEncryptionError, { "\x01" }));
+ return this->Close(
+ Packet(kEncryptionError, { net::htonv(0x100) }));
Packet response;
if(!this->key.ParseRequest(pck, &response, kKeyExchange))
- return this->Close(Packet(kEncryptionError, { "\x02" }));
+ return this->Close(
+ Packet(kEncryptionError, { net::htonv(0x101) }));
this->sock.Send(response);
}
@@ -112,39 +114,43 @@ bool sosc::MasterIntra::Authentication(sosc::Packet &pck) {
return true;
std::string packetId = BYTESTR(kAuthentication);
- if(!pck.Check(3, PCK_ANY, PCK_ANY, 512))
+ if(!pck.Check(4, PCK_ANY, 2, PCK_ANY, 512))
return this->Close();
db::Query* query = this->queries->at(QRY_LICENSE_CHECK);
query->Reset();
- query->BindText(pck[1], 0);
- query->BindBlob(pck[2], 1);
+ query->BindText(pck[2], 0);
+ query->BindBlob(pck[3], 1);
if(query->ScalarInt32() == 0)
- return AuthenticationFailure(packetId, 2);
+ return AuthenticationFailure(packetId, 0x101);
_ctx.license_check_mtx.lock();
int limit;
query = this->queries->at(QRY_LICENSE_LIMIT);
query->Reset();
- query->BindText(pck[1], 0);
+ query->BindText(pck[2], 0);
if((limit = query->ScalarInt32()) != 0) {
query = this->queries->at(QRY_LICENSE_ACTIVE_COUNT);
query->Reset();
- query->BindText(pck[1], 0);
+ query->BindText(pck[2], 0);
if(query->ScalarInt32() < limit) {
_ctx.license_check_mtx.unlock();
- return AuthenticationFailure(packetId, 3);
+ return AuthenticationFailure(packetId, 0x102);
}
}
query = this->queries->at(QRY_SERVER_LIST_ADD);
query->Reset();
- query->BindText(pck[0], pck[1], );
+ query->BindText(pck[0], 0);
+ query->BindText(pck[2], 1);
+ query->BindText(this->sock.GetIpAddress(), 2);
+ query->BindInt32(net::ntohv(pck[1]), 3);
query->NonQuery();
_ctx.license_check_mtx.unlock();
+ this->license = pck[2];
this->authed = true;
return true;
}
@@ -159,13 +165,26 @@ bool sosc::MasterIntra::AuthenticationFailure
return true;
} else {
return this->Close(
- Packet(kNegativeAck, { packetId, net::htonv(1) })
+ Packet(kNegativeAck, { packetId, net::htonv(0x100) })
);
}
}
-bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck) {
+bool sosc::MasterIntra::NotAuthorized(const std::string &packetId) {
+ return this->Close(
+ Packet(kNegativeAck, { packetId, net::htonv(0x200) })
+ );
+}
+bool sosc::MasterIntra::StatusUpdate(sosc::Packet &pck) {
+ std::string packetId = BYTESTR(kStatusUpdate);
+ if(!this->authed)
+ return this->NotAuthorized(packetId);
+
+ if(!pck.Check(2, 2, 2))
+ return this->Close();
+
+
}
bool sosc::MasterIntra::Close() {