From 8fef68f3311f9f9fe683967d4be1a97381e7ba2a Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 17 Jul 2017 11:24:39 +0200 Subject: [PATCH] New license parsing, according to fancy flowchart --- src/controller/controller_license.cpp | 54 ++++++++++++++++++++------- src/controller/controller_license.h | 2 +- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/controller/controller_license.cpp b/src/controller/controller_license.cpp index 3a5fc964..651c84ba 100644 --- a/src/controller/controller_license.cpp +++ b/src/controller/controller_license.cpp @@ -16,6 +16,8 @@ namespace Controller{ uint64_t exitDelay = 0; static JSON::Value currentLicense; static uint64_t lastCheck = 0; + static int32_t timeOffset = 0; + static bool everContactedServer = false; const JSON::Value & getLicense(){ return currentLicense; @@ -41,17 +43,19 @@ namespace Controller{ } bool isLicensed(){ - uint64_t now = Util::epoch(); + uint64_t now = Util::epoch() + timeOffset; #if DEBUG >= DLVL_DEVEL INFO_MSG("Verifying license against %llu: %s", now, currentLicense.toString().c_str()); #endif + //Print messages for user, if any if (currentLicense.isMember("user_msg") && currentLicense["user_msg"].asStringRef().size()){ 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()){ return false;//license is expired } + //Check release/version if (RELEASE != currentLicense["release"].asStringRef() || PACKAGE_VERSION != currentLicense["version"].asStringRef()){ FAIL_MSG("Could not verify license"); return false; @@ -62,10 +66,10 @@ namespace Controller{ bool checkLicense(){ if (!conf.is_active){return true;} - if (!currentLicense.isMember("interval")){ - currentLicense["interval"] = 3600ll; + INFO_MSG("Checking license validity"); + if(!everContactedServer && !isLicensed()){ + updateLicense("&expired=1"); } - INFO_MSG("Checking license time"); if(!isLicensed()){ FAIL_MSG("Not licensed, shutting down"); if (currentLicense.isMember("delay") && currentLicense["delay"].asInt()){ @@ -137,6 +141,7 @@ namespace Controller{ } if (http.Read(updrConn.Received().get())){ response = JSON::fromString(http.body); + everContactedServer = true; break; //break out of while loop } } @@ -144,11 +149,11 @@ namespace Controller{ updrConn.close(); //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]; if (strlen(SUPER_SECRET) >= 32){ parseKey(SUPER_SECRET SUPER_SECRET + 7,aesKey,16); @@ -169,15 +174,33 @@ namespace Controller{ //verify checksum if (deCrypted.size() < 33 || Secure::md5(deCrypted.substr(32)) != deCrypted.substr(0,32)){ WARN_MSG("Could not decode license"); - Storage.removeMember("license"); return; } - currentLicense = JSON::fromString(deCrypted.substr(32)); - if (RELEASE != currentLicense["release"].asStringRef() || PACKAGE_VERSION != currentLicense["version"].asStringRef()){ + JSON::Value newLicense = JSON::fromString(deCrypted.substr(32)); + if (RELEASE != newLicense["release"].asStringRef() || PACKAGE_VERSION != newLicense["version"].asStringRef()){ FAIL_MSG("Could not verify license"); 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. if (currentLicense["store"].asBool()){ if (Storage["license"].asStringRef() != input){ @@ -190,13 +213,18 @@ namespace Controller{ void licenseLoop(void * np){ while (conf.is_active){ - if (Util::epoch() - lastCheck > currentLicense["interval"].asInt()){ - updateLicense(); + uint64_t interval = currentLicense["interval"].asInt(); + if (Util::epoch() - lastCheck > (interval?interval:3600)){ + if (interval){ + updateLicense(); + } checkLicense(); } Util::sleep(1000);//sleep a bit } - updateLicense("&shutdown=1"); + if (everContactedServer){ + updateLicense("&shutdown=1"); + } } } diff --git a/src/controller/controller_license.h b/src/controller/controller_license.h index 05020b53..592cf648 100644 --- a/src/controller/controller_license.h +++ b/src/controller/controller_license.h @@ -10,7 +10,7 @@ namespace Controller{ bool checkLicense(); //Call from Mainloop. void updateLicense(const std::string & extra = ""); //retrieves update from license server 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