1.4.10 updates
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user