1.4.10 updates

This commit is contained in:
WolverinDEV
2020-02-28 11:24:07 +01:00
parent 2b929fd3c0
commit 0d456eea5d
48 changed files with 2267 additions and 781 deletions
+146 -82
View File
@@ -22,6 +22,8 @@ inline void generate(char* buffer, size_t length){
buffer[index] = rand();
}
#define _str(x) #x
#define TEST_PROTOCOL_STATE(expected) \
if(client->protocol.state != protocol::expected) { \
error = "invalid protocol state"; \
@@ -37,21 +39,23 @@ if(packet.data.length() < (expected)) { \
#define PARSE_PROTO(class, var) \
ts::proto::license::class var; \
if(!var.ParseFromString(packet.data)) { \
error = "invalid data!"; \
error = "invalid data (" _str(class) ")!"; \
return false; \
}
#define CRYPT_KEY_LENGTH 32
bool LicenseServer::handleHandshake(shared_ptr<ConnectedClient>& client, protocol::packet& packet, std::string &error) {
TEST_PROTOCOL_STATE(HANDSCAKE);
TEST_PROTOCOL_STATE(HANDSCHAKE);
ENSURE_PACKET_SIZE(4);
if((uint8_t) packet.data[0] != 0xC0 || (uint8_t) packet.data[1] != 0xFF || (uint8_t) packet.data[2] != 0xEE) {
error = "invalid magic!";
return false;
}
if((uint8_t) packet.data[3] != LICENSE_PROT_VERSION) {
error = "invalid version!";
return false;
client->protocol.version = (uint8_t) packet.data[3];
if(client->protocol.version < 2 || client->protocol.version > 3) {
error = "unsupported version";
return false;
}
bool manager = false;
@@ -67,7 +71,7 @@ bool LicenseServer::handleHandshake(shared_ptr<ConnectedClient>& client, protoco
size_t buffer_index = 0;
buffer[buffer_index++] = 0xAF;
buffer[buffer_index++] = 0xFE;
buffer[buffer_index++] = LICENSE_PROT_VERSION;
buffer[buffer_index++] = client->protocol.version;
le2be16(CRYPT_KEY_LENGTH, buffer, buffer_index, &buffer_index);
memcpy(&buffer[buffer_index], buffer_cryptkey, CRYPT_KEY_LENGTH);
buffer_index += CRYPT_KEY_LENGTH;
@@ -134,94 +138,129 @@ std::string string_to_hex(const std::string& input)
}
bool LicenseServer::handleServerValidation(shared_ptr<ConnectedClient> &client, protocol::packet &packet, std::string &error) {
TEST_PROTOCOL_STATE(SERVER_VALIDATION);
if(client->protocol.state != protocol::LICENSE_UPGRADE) /* server may wants to verify new license */
TEST_PROTOCOL_STATE(SERVER_VALIDATION);
PARSE_PROTO(ServerValidation, pkt);
shared_ptr<License> remoteLicense = nullptr;
if(pkt.licensed() && !pkt.has_license()) {
//TODO shutdown server
std::shared_ptr<License> remote_license{nullptr};
if(pkt.licensed() && (!pkt.has_license() || !pkt.has_license_info())) {
error = "invalid/missing license data";
return false;
}
if(!pkt.has_info()) {
error = "invalid data or missing data";
return false;
}
if(pkt.has_license()){ //Client has license
remoteLicense = readLocalLicence(pkt.license(), error);
if(!remoteLicense) {
error = "Could not read remote key: " + error;
if(pkt.licensed()){ //Client has license
remote_license = readLocalLicence(pkt.license(), error);
if(!remote_license) {
error = "could not parse license (" + error + ")";
return false;
};
logMessage(LOG_GENERAL, "[CLIENT][{}] Got remote license. Registered to {}. Key: {} (0x{})", client->address(), remoteLicense->owner(), base64::encode(remoteLicense->key()), string_to_hex(remoteLicense->key()));
client->key = remoteLicense->key();
} else { }
if(pkt.licensed() && !pkt.has_license_info()) {
error = "Invalid content!";
return false;
}
logMessage(LOG_GENERAL, "[CLIENT][{}] Got remote license. Registered to {}. Key: {} (0x{})", client->address(), remote_license->owner(), base64::encode(remote_license->key()), string_to_hex(remote_license->key()));
client->key = remote_license->key();
}
logMessage(LOG_GENERAL, "[CLIENT][{}] Got some server information. TeaSpeak-Version: {} uname: {}", client->address(), pkt.info().version(), pkt.info().uname());
ts::proto::license::LicenseResponse response;
//Forces
ts::proto::license::LicenseResponse response{};
client->unique_identifier = pkt.info().has_unique_id() ? pkt.info().unique_id() : client->address();
if(remoteLicense && pkt.licensed()) {
auto info = this->manager->licenseInfo(remoteLicense->key());
if(remote_license) {
auto info = this->manager->query_license_info(remote_license->key());
if(!info) {
response.mutable_blacklist()->set_reason("License hasn't been found.");
response.set_invalid_reason("license has not been found");
response.set_valid(false);
/*
logMessage(LOG_GENERAL, "[CLIENT][{}] Unknown license! Adding it to database!", client->address());
auto db_info = make_shared<LicenseInfo>();
db_info->start = system_clock::now();
db_info->end = remoteLicense->end();
db_info->last_name = "unknown";
db_info->first_name = "unknown";
db_info->username = remoteLicense->owner();
db_info->email = "unknonw@unknown";
db_info->creation = system_clock::now();
db_info->type = remoteLicense->data.type;
this->manager->registerLicense(remoteLicense->key(), db_info, "teaforo-fix");
info = this->manager->licenseInfo(remoteLicense->key());
if(!info) {
error = "could not insert key!";
return false;
}
*/
logMessage(LOG_GENERAL, "[CLIENT][{}] Remote license hasn't been found in database. Shutting down server!", client->address());
} else {
response.set_update_pending(info->upgrade_id > 0);
client->key_pending_upgrade = info->upgrade_id;
if(info->deleted) {
response.mutable_blacklist()->set_reason("License has been deleted.");
response.set_invalid_reason("license has been deleted");
response.set_valid(false);
logMessage(LOG_GENERAL, "[CLIENT][{}] Remote license has been deleted! Shutting down server!", client->address());
} else {
fill_info(response.mutable_license_info(), info, remoteLicense->data.licenceKey);
response.set_valid(info->isValid());
fill_info(response.mutable_license_info(), info, remote_license->data.licenceKey);
auto is_invalid = !info->isValid();
if(is_invalid) {
response.set_invalid_reason("license is invalid");
response.set_valid(false);
} else {
response.set_valid(true);
}
}
}
this->manager->logRequest(remoteLicense->key(), client->unique_identifier, client->address(), pkt.info().version(), response.valid());
this->manager->logRequest(remote_license->key(), client->unique_identifier, client->address(), pkt.info().version(), response.valid());
} else {
response.set_valid(true);
}
if(response.valid())
response.mutable_blacklist()->set_state(ts::proto::license::VALID);
else {
if(!response.has_license_info())
fill_info(response.mutable_license_info(), nullptr, ""); /* "Hack" for old clients which require a license. Else the server would not be stopped */
response.mutable_blacklist()->set_state(ts::proto::license::BLACKLISTED); /* "Hack" for all old clients */
client->invalid_license = true;
if(client->protocol.version == 2) {
if(response.valid())
response.mutable_blacklist()->set_state(ts::proto::license::VALID);
else {
response.mutable_blacklist()->set_reason(response.invalid_reason());
response.mutable_blacklist()->set_state(ts::proto::license::BLACKLISTED); /* "Hack" for all old clients */
if(!response.has_license_info()) fill_info(response.mutable_license_info(), nullptr, ""); /* "Hack" for old clients which require a license. Else the server would not be stopped */
client->invalid_license = true;
}
} else {
if(!response.has_blacklist())
response.mutable_blacklist()->set_state(ts::proto::license::VALID);
}
client->invalid_license = !response.valid();
client->sendPacket(protocol::packet{protocol::PACKET_SERVER_VALIDATION_RESPONSE, response});
client->protocol.state = protocol::PROPERTY_ADJUSTMENT;
return true;
}
bool LicenseServer::handlePacketLicenseUpgrade(shared_ptr<ConnectedClient> &client, license::protocol::packet &packet,
std::string &error) {
TEST_PROTOCOL_STATE(PROPERTY_ADJUSTMENT);
PARSE_PROTO(RequestLicenseUpgrade, pkt);
if(!client->key_pending_upgrade) {
error = "no update pending";
return false;
}
ts::proto::license::LicenseUpgradeResponse response;
auto license_upgrade = this->manager->query_license_upgrade(client->key_pending_upgrade);
response.set_valid(false);
if(license_upgrade) {
if(!license_upgrade->valid) {
response.set_error_message("upgrade has been invalidated");
} else if(license_upgrade->is_expired()) {
response.set_error_message("upgrade has been expired");
} else if(license_upgrade->not_yet_available()) {
response.set_error_message("upgrade is not yet active.");
} else {
response.set_valid(true);
response.set_license_key(license_upgrade->license_key);
}
this->manager->log_license_upgrade_attempt(license_upgrade->upgrade_id, response.valid(), client->unique_identifier, client->address());
logMessage(LOG_GENERAL, "[CLIENT][{}] Client requested license upgrade {}. Result: {}", client->key_pending_upgrade, response.valid() ? "granted" : "denied (" + response.error_message() + ")");
} else {
response.set_error_message("failed to find upgrade");
}
client->sendPacket(protocol::packet{protocol::PACKET_SERVER_LICENSE_UPGRADE_RESPONSE, response});
client->protocol.state = protocol::LICENSE_UPGRADE;
return true;
}
bool LicenseServer::handlePacketPropertyUpdate(shared_ptr<ConnectedClient> &client, protocol::packet &packet, std::string &error) {
TEST_PROTOCOL_STATE(PROPERTY_ADJUSTMENT);
if(client->protocol.state != protocol::LICENSE_UPGRADE) /* LICENSE_UPGRADE could be skipped */
TEST_PROTOCOL_STATE(PROPERTY_ADJUSTMENT);
if(client->invalid_license) {
ts::proto::license::PropertyUpdateResponse response;
response.set_accepted(true);
@@ -330,33 +369,58 @@ bool LicenseServer::handlePacketLicenseCreate(shared_ptr<ConnectedClient> &clien
TEST_PROTOCOL_STATE(MANAGER_CONNECTED);
PARSE_PROTO(LicenseCreateRequest, pkt);
logMessage(LOG_GENERAL, "[MANAGER][" + client->address() + "] Register new license to {} {} ({}). E-Mail: {}", pkt.issuer_first_name(), pkt.issuer_last_name(), pkt.issuer_username(), pkt.issuer_email());
auto old_license = pkt.has_old_key() ? hex::hex(pkt.old_key()) : "none";
logMessage(LOG_GENERAL, "[MANAGER][" + client->address() + "] Register new license to {} {} ({}). E-Mail: {}. Old license: {}", pkt.issuer_first_name(), pkt.issuer_last_name(), pkt.issuer_username(), pkt.issuer_email(), old_license);
ts::proto::license::LicenseCreateResponse response;
auto old_key_id{0};
ts::proto::license::LicenseCreateResponse response{};
if(pkt.has_old_key()) {
old_key_id = this->manager->key_id_cache()->get_key_id_from_key(pkt.old_key());
if(old_key_id == 0) {
response.set_error("failed to find old license key in database");
goto _send_response;
}
}
auto db_info = make_shared<LicenseInfo>();
db_info->start = system_clock::time_point() + milliseconds(pkt.begin());
db_info->end = system_clock::time_point() + milliseconds(pkt.end());
db_info->last_name = pkt.issuer_last_name();
db_info->first_name = pkt.issuer_first_name();
db_info->username = pkt.issuer_username();
db_info->email = pkt.issuer_email();
db_info->creation = system_clock::now();
db_info->type = static_cast<LicenseType>(pkt.type());
{
auto db_info = make_shared<LicenseInfo>();
db_info->start = system_clock::time_point() + milliseconds(pkt.begin());
db_info->end = system_clock::time_point() + milliseconds(pkt.end());
db_info->last_name = pkt.issuer_last_name();
db_info->first_name = pkt.issuer_first_name();
db_info->username = pkt.issuer_username();
db_info->email = pkt.issuer_email();
db_info->creation = system_clock::now();
db_info->type = static_cast<LicenseType>(pkt.type());
auto license = license::createLocalLicence(db_info->type, db_info->end, db_info->first_name + db_info->last_name);
auto parsed_license = license::readLocalLicence(license, error);
if(!parsed_license) {
response.set_error("failed to register license (parse)");
} else {
auto license = license::createLocalLicence(db_info->type, db_info->end, db_info->first_name + db_info->last_name);
auto parsed_license = license::readLocalLicence(license, error);
if(!parsed_license) {
response.set_error("failed to register license (parse)");
} else {
if(!this->manager->register_license(parsed_license->key(), db_info, client->username)) {
response.set_error("failed to register license");
goto _send_response;
}
if(!this->manager->registerLicense(parsed_license->key(), db_info, client->username)) {
response.set_error("failed to register license");
} else {
fill_info(response.mutable_license(), db_info, parsed_license->key());
response.set_exported_key(license);
}
}
if(old_key_id) {
auto new_key_id = this->manager->key_id_cache()->get_key_id_from_key(parsed_license->key());
if(!new_key_id) {
response.set_error("failed to find new license in database");
goto _send_response;
}
if(!this->manager->register_license_upgrade(old_key_id, new_key_id, std::chrono::system_clock::now(), db_info->end, license)) {
response.set_error("failed to register license upgrade");
goto _send_response;
}
}
fill_info(response.mutable_license(), db_info, parsed_license->key());
response.set_exported_key(license);
}
}
_send_response:
client->sendPacket(protocol::packet{protocol::PACKET_SERVER_LICENSE_CREATE_RESPONSE, response});
return true;
}
@@ -368,7 +432,7 @@ bool LicenseServer::handlePacketLicenseList(shared_ptr<ConnectedClient> &client,
proto::license::LicenseListResponse response;
response.set_end(false);
for(const auto& info : this->manager->listLicenses(pkt.offset(), pkt.count())) {
for(const auto& info : this->manager->list_licenses(pkt.offset(), pkt.count())) {
auto entry = response.add_entries();
fill_info(entry, info.second, info.first);
}
@@ -382,7 +446,7 @@ bool LicenseServer::handlePacketLicenseDelete(shared_ptr<ConnectedClient> &clien
PARSE_PROTO(LicenseDeleteRequest, pkt);
proto::license::LicenseDeleteResponse response;
response.set_succeed(this->manager->deleteLicense(pkt.key(), pkt.full()));
response.set_succeed(this->manager->delete_license(pkt.key(), pkt.full()));
client->sendPacket(protocol::packet{protocol::PACKET_CLIENT_DELETE_RESPONSE, response});
return true;