Teaspeak-Server/license/shared/License.cpp
2019-09-14 12:06:48 +02:00

102 lines
3.8 KiB
C++

#include <google/protobuf/message.h>
#include <misc/base64.h>
//#define NO_OPEN_SSL
#include <misc/digest.h>
#include <cstring>
#include <cassert>
#include "crypt.h"
#include "License.h"
using namespace std;
using namespace std::chrono;
inline void generate(char* buffer, size_t length){
for(int index = 0; index < length; index++)
buffer[index] = rand();
}
namespace license {
std::string LicenseTypeNames[] = LT_NAMES;
std::shared_ptr<License> readLocalLicence(const std::string& buffer, std::string& error){
string bbuffer = base64::decode(buffer);
if(bbuffer.length() < sizeof(License)) {
error = "invalid size";
return nullptr;
}
auto license = static_cast<License *>(malloc(sizeof(License)));
memcpy(license, bbuffer.data(), sizeof(License));
if(license->header.version != LICENSE_VERSION){
error = "invalid version (" + to_string(license->header.version) + ")";
return nullptr;
}
xorBuffer(&((char*) license)[sizeof(License::header)], sizeof(License::data), license->header.cryptKey, sizeof(license->header.cryptKey));
auto hash = digest::sha1(reinterpret_cast<const char *>(&license->data), sizeof(license->data));
uint64_t checkSum = 0;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
checkSum += (uint8_t) hash[i] << (i % 8);
if((checkSum ^ *(uint64_t*) &license->header.cryptKey) != MAGIC_NUMER) {
error = "invalid check sum";
return nullptr;
}
return shared_ptr<License>(license, [](License* l){
if(l) free(l);
});
}
std::string exportLocalLicense(const std::shared_ptr<License>& ref){
auto copy = static_cast<License *>(malloc(sizeof(License)));
memcpy(copy, ref.get(), sizeof(License));
auto hash = digest::sha1(reinterpret_cast<const char *>(&copy->data), sizeof(copy->data));
uint64_t checkSum = 0;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
checkSum += (uint8_t) hash[i] << (i % 8);
checkSum ^= MAGIC_NUMER;
generate(const_cast<char *>(copy->header.cryptKey), sizeof(copy->header.cryptKey));
*(uint64_t*) &copy->header.cryptKey = checkSum;
xorBuffer(&((char*) copy)[sizeof(License::header)], sizeof(License::data), copy->header.cryptKey, sizeof(copy->header.cryptKey));
auto result = base64_encode((const char*) copy, sizeof(License));
free(copy);
return result;
}
std::string createLocalLicence(LicenseType type, std::chrono::system_clock::time_point until, std::string licenseOwner){
auto license = shared_ptr<License>(static_cast<License *>(malloc(sizeof(License))), [](License* l) { if(l) free(l); });
assert(licenseOwner.length() < sizeof(license->data.licenceOwner));
license->header.version = LICENSE_VERSION;
generate(const_cast<char *>(license->data.licenceKey), sizeof(license->data.licenceKey));
generate(const_cast<char *>(license->data.licenceOwner), sizeof(license->data.licenceOwner)); //Crap data :)
license->data.type = type;
license->data.endTimestamp = duration_cast<milliseconds>(until.time_since_epoch()).count();
memcpy((void *) license->data.licenceOwner, licenseOwner.c_str(), strlen(licenseOwner.c_str()) + 1); //Copy the string into it
return exportLocalLicense(license);
}
const char *exceptions::LicenseException::what() const throw() {
return this->errorMessage.c_str();
}
protocol::packet::packet(PacketType packetId, const ::google::protobuf::Message& message) {
this->header.packetId = packetId;
this->data = message.SerializeAsString();
}
protocol::packet::packet(license::protocol::PacketType packetId, nullptr_t) {
this->header.packetId = packetId;
this->data = "";
}
}