aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Littow <sami.littow@qt.io>2022-11-22 14:00:11 +0200
committerSami Littow <sami.littow@qt.io>2022-11-22 16:19:09 +0200
commit13cea54d190d949f881c089eb8d3ffd04ced5981 (patch)
treeec1dd3dbd10a48389c382bd0cd8c5dd088c6be6f
parentd42382745b488415a60b3bfe94fadb2dc0bdc51c (diff)
Updated linux installer
Added support for mocwrapper leeway time - Occurs when server connection is broken - Requires server update
-rw-r--r--include/commonsetup.h1
-rw-r--r--include/licenser.h3
-rw-r--r--include/utils.h8
-rw-r--r--include/version.h3
-rw-r--r--jsonhandler.cpp2
-rw-r--r--licenser.cpp71
-rwxr-xr-xlinux_service_scripts/installer.sh4
-rw-r--r--utils.cpp32
8 files changed, 75 insertions, 49 deletions
diff --git a/include/commonsetup.h b/include/commonsetup.h
index 08f08e6..1622503 100644
--- a/include/commonsetup.h
+++ b/include/commonsetup.h
@@ -38,3 +38,4 @@
#define DAEMON_SETTINGS_FILE WORKING_DIR "/licd.ini"
#define LICENSE_FILE_BASE WORKING_DIR "/lic_"
#define SHA256_HASH_SIZE 32
+#define SECS_IN_HOUR 3600
diff --git a/include/licenser.h b/include/licenser.h
index fd413fe..ad7296c 100644
--- a/include/licenser.h
+++ b/include/licenser.h
@@ -76,7 +76,7 @@ private:
int parseIncoming(const std::string &incoming, RequestInfo &request);
int buildRequestJson(RequestInfo &request);
int parseAndSaveJsonReply(std::string &reply, const RequestInfo &request);
- bool checkLicenseExpiryDate(const std::string &licenseFile);
+ bool checkLicenseExpiryDate(std::string &reply, const RequestInfo &request);
bool isMocRenewalDue(const std::string &licenseFile);
void doHmacHashSha256(const std::string &payload, const std::string &secret, std::string &authKey);
int initDaemonSettings();
@@ -92,7 +92,6 @@ private:
{e_license_rejected, "No valid license acquired"},
{e_bad_connection, "No connection to server. Try again later."}
};
-
};
#ifndef __TIME_IMP
diff --git a/include/utils.h b/include/utils.h
index c541741..982e305 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -31,7 +31,7 @@
#define SYSTEM_ROOT "/"
#endif
#if __APPLE__ || __MACH__
- #define USER_SETTINGS_DIR "/something/else" // not supported yet
+ #define USER_SETTINGS_DIR ".local/share/Qt/" // not supported yet
#elif __linux__
#define USER_SETTINGS_DIR ".local/share/Qt/"
#endif
@@ -62,7 +62,13 @@ std::vector<std::string> getDirListing(const std::string &directory, const std::
* Other
*/
+// Time conversions
+std::string epochToString(time_t epochTime, const char* format = "%Y-%m-%d %H:%M:%S");
+time_t stringToEpoch(const char* theTime, const char* format = "%Y-%m-%d %H:%M:%S");
+
+// Find out host OS
std::string getOsName();
+
// Swap endian of any data
template <typename T> T swapEndian(T val)
{
diff --git a/include/version.h b/include/version.h
index 954b2ad..e5e7b67 100644
--- a/include/version.h
+++ b/include/version.h
@@ -6,7 +6,7 @@
#pragma once
#define DAEMON_VERSION_MAJOR "2"
-#define DAEMON_VERSION_MINOR "0.1"
+#define DAEMON_VERSION_MINOR "0.2"
#define DAEMON_VERSION DAEMON_VERSION_MAJOR "." DAEMON_VERSION_MINOR
#define LICD_SERVICE_DESCRIPTION "Qt Licensing service"
#define COPYRIGHT_TEXT "Copyright (C) 2022 The Qt Company Ltd"
@@ -19,4 +19,3 @@
#define MOCWRAPPER_VERSION_MAJOR DAEMON_VERSION_MAJOR
#define MOCWRAPPER_VERSION_MINOR DAEMON_VERSION_MINOR
#define MOCWRAPPER_VERSION MOCWRAPPER_VERSION_MAJOR "." MOCWRAPPER_VERSION_MINOR
-
diff --git a/jsonhandler.cpp b/jsonhandler.cpp
index 52185de..f46fd72 100644
--- a/jsonhandler.cpp
+++ b/jsonhandler.cpp
@@ -28,7 +28,7 @@ int JsonHandler::getInt(const std::string &item)
return std::stoi(m_items[item]);
}
catch (...) {
- return -1;
+ return INT16_MIN;
}
}
diff --git a/licenser.cpp b/licenser.cpp
index 202effb..142164d 100644
--- a/licenser.cpp
+++ b/licenser.cpp
@@ -52,7 +52,7 @@ int Licenser::listen()
std::cout << "Standard license renewal request\n";
// See if it's MOC who's calling us (special case)
if (request.appName == MOCWRAPPER_APP_NAME) {
- // More than 24hrs from last successful request?
+ // More than MOC_RENEWAL_INTERVAL from last successful request?
if (!isMocRenewalDue(request.licenseFile)) {
// No - Just send ok message and no further actions needed
reply = replyString[e_license_granted];
@@ -63,14 +63,7 @@ int Licenser::listen()
if (buildRequestJson(request) == 0) {
if (sendLicensingRequest(reply, request) != 0) {
// Bad server connection: Check the existing license file for expiry date
- if (!checkLicenseExpiryDate(request.licenseFile)) {
- // If expiry date is up or no license file found,
- // Send "Bad connection"
- reply = replyString[e_bad_connection];
- reply += m_http->error();
- } else {
- reply = replyString[e_license_granted];
- }
+ checkLicenseExpiryDate(reply, request);
} else {
parseAndSaveJsonReply(reply, request);
}
@@ -203,12 +196,11 @@ int Licenser::parseIncoming(const std::string &incoming, RequestInfo &request)
}
// Add user info to the license filename
- std::string file = settings->get("license_file_base");
- file += request.userId;
- file += "_";
- file += request.licenseId;
- file += settings->get("license_file_extension");
- request.licenseFile = file;
+ std::stringstream ss;
+ ss << WORKING_DIR << DIR_SEPARATOR
+ << settings->get("license_file_base") << request.userId
+ << "_" << request.licenseId << settings->get("license_file_extension");
+ request.licenseFile = ss.str();
return 0;
}
@@ -267,45 +259,56 @@ int Licenser::parseAndSaveJsonReply(std::string &reply, const RequestInfo &reque
json.add("last_timestamp", timeNow);
int result = utils::writeToFile(request.licenseFile, json.dump(4));
if (result != 0) {
- std::cout << "ERROR saving license file: " << strerror(result) << std::endl;
+ std::cout << "ERROR saving license file: '" << request.licenseFile << "': " << strerror(result) << std::endl;
}
return 0;
}
-bool Licenser::checkLicenseExpiryDate(const std::string &licenseFile)
+bool Licenser::checkLicenseExpiryDate(std::string &reply, const RequestInfo &request)
{
- std::cout << "Offline - checking validity from license file " << licenseFile << std::endl;
+ std::cout << "Offline - checking validity from license file " << request.licenseFile << std::endl;
// Open the license file
std::string data;
- if (utils::readFile(data, licenseFile) != 0) {
- std::cout << "No license file - rejecting license " <<licenseFile << std::endl;
+ if (utils::readFile(data, request.licenseFile) != 0) {
+ std::cout << "No license file - rejecting license " << request.licenseFile << std::endl;
+ reply = replyString[e_bad_connection];
return false;
}
JsonHandler license(data);
// Check license status
if (license.get("status") != "true") {
std::cout << "License status = false: Rejecting license\n";
+ reply = replyString[e_bad_connection];
return false;
}
-
// Expiry date
- std::string expiryDate = license.get("expiry_date");
-
+ std::string expDate = license.get("expiry_date");
+ std::time_t expEpoch = utils::stringToEpoch(expDate.c_str());
// Current date
- std::time_t t = std::time(0);
- std::tm *now = std::localtime(&t);
- std::stringstream current;
- current << (now->tm_year + 1900) << '-'
- << std::setfill('0') << std::setw(2) << (now->tm_mon + 1) << '-'
- << std::setfill('0') << std::setw(2) << now->tm_mday;
-
- // See if the time has expired
- if (current.str() > expiryDate) {
+ std::time_t current = std::time(0);
+ // See if the time has expire
+ if (current > expEpoch) {
// License expired
- std::cout << "License already expired at " << expiryDate << ", rejecting\n";
+ if (request.appName == MOCWRAPPER_APP_NAME) {
+ // For MOC, allow some leeway time
+ int leewayTimeLeft = expEpoch + (license.getInt("leeway_time") * SECS_IN_HOUR) - current;
+ std::cout << "Leeway time left: " << leewayTimeLeft << std::endl;
+ if (leewayTimeLeft > 0) {
+ std::stringstream ss;
+ ss << "Warning: No connection to server. "
+ << "Leeway time left: "
+ << std::fixed << std::setprecision(1)
+ << (float)leewayTimeLeft / (24 * SECS_IN_HOUR) << " days";
+ reply = ss.str();
+ return true;
+ }
+ }
+ std::cout << "License already expired at " << expDate << ", rejecting\n";
+ reply = replyString[e_license_rejected];
return false;
}
- std::cout << "License granted, expires at " << expiryDate << std::endl;
+ std::cout << "License granted, expires at " << expDate << std::endl;
+ reply = replyString[e_license_granted];
return true;
}
diff --git a/linux_service_scripts/installer.sh b/linux_service_scripts/installer.sh
index f0ba87f..404fb90 100755
--- a/linux_service_scripts/installer.sh
+++ b/linux_service_scripts/installer.sh
@@ -21,7 +21,7 @@ function create_install_dir {
function copy_files {
# Copy executables and .ini
- cp ${name} ${name}.ini qtlongterm mocwrapper licheck ${installdir}/
+ cp ${name} ${name}.ini qtlicensetool mocwrapper licheck ${installdir}/
if [ $? != 0 ]; then
exit_fail "Failed to copy files to $installdir"
fi
@@ -33,7 +33,7 @@ function copy_files {
fi
# Create a symlink for qtlongterm binary
- ln -s ${installdir}/qtlongterm /usr/bin/qtlongterm
+ ln -s ${installdir}/qtlicensetool /usr/bin/qtlicensetool
sync
}
diff --git a/utils.cpp b/utils.cpp
index 7bfd481..b60295b 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -80,23 +80,26 @@ int strToInt(const std::string &str)
std::string getUserHomeDir()
{
// Try to find current user's home
- std::string homedir;
+ const char* homedir;
#if __linux__ || __APPLE__ || __MACH__
// Linux and Mac
- if (getenv("HOME") != nullptr)
- homedir = getenv("HOME");
- if (homedir.length() == 0) {
+ homedir = std::getenv("PATH");
+ if (homedir == nullptr) {
homedir = getpwuid(getuid())->pw_dir;
}
#else
+ // Windows
homedir = getenv("HOMEPATH");
- homedir = SYSTEM_ROOT + homedir;
+ if (homedir != nullptr) {
+ homedir = SYSTEM_ROOT + homedir;
+ }
+
#endif
- if (&homedir == nullptr) {
+ if (homedir == nullptr) {
printf("ERROR Not able to determine user's home directory\n");
homedir = "";
}
- return homedir;
+ return std::string(homedir);
}
// Write data to the file
@@ -250,6 +253,21 @@ std::string getOsName()
#endif
}
+std::string epochToString(time_t epochTime, const char* format)
+{
+ char timestamp[64] = {0};
+ strftime(timestamp, sizeof(timestamp), format, localtime(&epochTime));
+ return timestamp;
+}
+
+time_t stringToEpoch(const char* theTime, const char* format)
+{
+ std::tm tmTime;
+ memset(&tmTime, 0, sizeof(tmTime));
+ strptime(theTime, format, &tmTime);
+ return mktime(&tmTime);
+}
+
/*
* App-specific utils here (not generic)
*/