New license parsing, according to fancy flowchart

This commit is contained in:
Thulinma 2017-07-17 11:24:39 +02:00
parent 20b3010e75
commit 8fef68f331
2 changed files with 42 additions and 14 deletions

View file

@ -16,6 +16,8 @@ namespace Controller{
uint64_t exitDelay = 0; uint64_t exitDelay = 0;
static JSON::Value currentLicense; static JSON::Value currentLicense;
static uint64_t lastCheck = 0; static uint64_t lastCheck = 0;
static int32_t timeOffset = 0;
static bool everContactedServer = false;
const JSON::Value & getLicense(){ const JSON::Value & getLicense(){
return currentLicense; return currentLicense;
@ -41,17 +43,19 @@ namespace Controller{
} }
bool isLicensed(){ bool isLicensed(){
uint64_t now = Util::epoch(); uint64_t now = Util::epoch() + timeOffset;
#if DEBUG >= DLVL_DEVEL #if DEBUG >= DLVL_DEVEL
INFO_MSG("Verifying license against %llu: %s", now, currentLicense.toString().c_str()); INFO_MSG("Verifying license against %llu: %s", now, currentLicense.toString().c_str());
#endif #endif
//Print messages for user, if any
if (currentLicense.isMember("user_msg") && currentLicense["user_msg"].asStringRef().size()){ if (currentLicense.isMember("user_msg") && currentLicense["user_msg"].asStringRef().size()){
WARN_MSG("%s", currentLicense["user_msg"].asStringRef().c_str()); WARN_MSG("%s", currentLicense["user_msg"].asStringRef().c_str());
} }
//The loop below is timechecker loop //Check time
if (!currentLicense.isMember("valid_from") || !currentLicense.isMember("valid_till") || now < currentLicense["valid_from"].asInt() || now > currentLicense["valid_till"].asInt()){ if (!currentLicense.isMember("valid_from") || !currentLicense.isMember("valid_till") || now < currentLicense["valid_from"].asInt() || now > currentLicense["valid_till"].asInt()){
return false;//license is expired return false;//license is expired
} }
//Check release/version
if (RELEASE != currentLicense["release"].asStringRef() || PACKAGE_VERSION != currentLicense["version"].asStringRef()){ if (RELEASE != currentLicense["release"].asStringRef() || PACKAGE_VERSION != currentLicense["version"].asStringRef()){
FAIL_MSG("Could not verify license"); FAIL_MSG("Could not verify license");
return false; return false;
@ -62,10 +66,10 @@ namespace Controller{
bool checkLicense(){ bool checkLicense(){
if (!conf.is_active){return true;} if (!conf.is_active){return true;}
if (!currentLicense.isMember("interval")){ INFO_MSG("Checking license validity");
currentLicense["interval"] = 3600ll; if(!everContactedServer && !isLicensed()){
updateLicense("&expired=1");
} }
INFO_MSG("Checking license time");
if(!isLicensed()){ if(!isLicensed()){
FAIL_MSG("Not licensed, shutting down"); FAIL_MSG("Not licensed, shutting down");
if (currentLicense.isMember("delay") && currentLicense["delay"].asInt()){ if (currentLicense.isMember("delay") && currentLicense["delay"].asInt()){
@ -137,6 +141,7 @@ namespace Controller{
} }
if (http.Read(updrConn.Received().get())){ if (http.Read(updrConn.Received().get())){
response = JSON::fromString(http.body); response = JSON::fromString(http.body);
everContactedServer = true;
break; //break out of while loop break; //break out of while loop
} }
} }
@ -144,11 +149,11 @@ namespace Controller{
updrConn.close(); updrConn.close();
//read license //read license
readLicense(response["lic_id"].asInt(), response["license"].asStringRef()); readLicense(response["lic_id"].asInt(), response["license"].asStringRef(), true);
} }
void readLicense(uint64_t licID, const std::string & input){ void readLicense(uint64_t licID, const std::string & input, bool fromServer){
char aesKey[16]; char aesKey[16];
if (strlen(SUPER_SECRET) >= 32){ if (strlen(SUPER_SECRET) >= 32){
parseKey(SUPER_SECRET SUPER_SECRET + 7,aesKey,16); parseKey(SUPER_SECRET SUPER_SECRET + 7,aesKey,16);
@ -169,15 +174,33 @@ namespace Controller{
//verify checksum //verify checksum
if (deCrypted.size() < 33 || Secure::md5(deCrypted.substr(32)) != deCrypted.substr(0,32)){ if (deCrypted.size() < 33 || Secure::md5(deCrypted.substr(32)) != deCrypted.substr(0,32)){
WARN_MSG("Could not decode license"); WARN_MSG("Could not decode license");
Storage.removeMember("license");
return; return;
} }
currentLicense = JSON::fromString(deCrypted.substr(32)); JSON::Value newLicense = JSON::fromString(deCrypted.substr(32));
if (RELEASE != currentLicense["release"].asStringRef() || PACKAGE_VERSION != currentLicense["version"].asStringRef()){ if (RELEASE != newLicense["release"].asStringRef() || PACKAGE_VERSION != newLicense["version"].asStringRef()){
FAIL_MSG("Could not verify license"); FAIL_MSG("Could not verify license");
return; return;
} }
if (fromServer){
uint64_t localTime = Util::epoch();
uint64_t remoteTime = newLicense["time"].asInt();
if (localTime > remoteTime + 60){
WARN_MSG("Your computer clock is %u seconds ahead! Please ensure your computer clock is set correctly.", localTime - remoteTime);
}
if (localTime < remoteTime - 60){
WARN_MSG("Your computer clock is %u seconds late! Please ensure your computer clock is set correctly.", remoteTime - localTime);
}
timeOffset = remoteTime - localTime;
if (newLicense.isMember("plid") && newLicense["plid"] != currentLicense["lic_id"]){
FAIL_MSG("Could not verify license ID");
return;
}
}
currentLicense = newLicense;
//Store license here. //Store license here.
if (currentLicense["store"].asBool()){ if (currentLicense["store"].asBool()){
if (Storage["license"].asStringRef() != input){ if (Storage["license"].asStringRef() != input){
@ -190,13 +213,18 @@ namespace Controller{
void licenseLoop(void * np){ void licenseLoop(void * np){
while (conf.is_active){ while (conf.is_active){
if (Util::epoch() - lastCheck > currentLicense["interval"].asInt()){ uint64_t interval = currentLicense["interval"].asInt();
if (Util::epoch() - lastCheck > (interval?interval:3600)){
if (interval){
updateLicense(); updateLicense();
}
checkLicense(); checkLicense();
} }
Util::sleep(1000);//sleep a bit Util::sleep(1000);//sleep a bit
} }
if (everContactedServer){
updateLicense("&shutdown=1"); updateLicense("&shutdown=1");
} }
}
} }

View file

@ -10,7 +10,7 @@ namespace Controller{
bool checkLicense(); //Call from Mainloop. bool checkLicense(); //Call from Mainloop.
void updateLicense(const std::string & extra = ""); //retrieves update from license server void updateLicense(const std::string & extra = ""); //retrieves update from license server
void licenseLoop(void * np); void licenseLoop(void * np);
void readLicense(uint64_t licId, const std::string & input); //checks/interprets license void readLicense(uint64_t licId, const std::string & input, bool fromServer = false); //checks/interprets license