issue #64 , issue #56 (part)
Code review and refactoring:
Incompatible api changes (removed possibility to specify environment
variable name)
Part of issue #56 License retrieval has been made more flexible. License
verification is still waiting
issue #64 Add possibility to read the full license content from an
environment variable.
| | |
| | | *.so |
| | | *.dylib |
| | | |
| | | #Visual studio files |
| | | .vs |
| | | |
| | | # Compiled Static libraries |
| | | *.lai |
| | | *.la |
| | |
| | | |
| | | * **Use a clear and descriptive title** for the issue to identify the problem. |
| | | * **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how are you using Open License Manager. |
| | | * **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or licenses, which can cause the bug. If you're providing code snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). The best way to report a bug is to **design a test** to demonstrate it. |
| | | * **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or licenses, which can cause the bug. If you're providing code snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). |
| | | * **Provide a boost unit test to demonstrate the bug**. The best way to report a bug, and to have it fixed **forever** is to design a test to demonstrate it. |
| | | * **If you're reporting that Open License Manager crashed**, include a crash dump and the associated message. |
| | | * **Label the issue as bug.** |
| | | |
| | |
| | | |
| | | ##### Don't |
| | | * Don't reformat the code following your personal likes, it introduce a lot of "noise" and makes very hard to merge. |
| | | * Very large pull requests with few comments, no corresponding issue will probably be rejected. |
| | | * We understand that the project is still in a very alpha stage and a rearrangement is needed, however we would like to discuss it with you before we take project changing decision. |
| | | * We can't break current functionality, user established habits without documenting the change. |
| | | * Very large pull requests with few comments, no corresponding issue explaining what's it about will probably be rejected. |
| | | * We understand that the project is still in a very alpha stage and a rearrangement is needed, however we would like to discuss it with you before we take project changing decision. Please contact the project maintainer at `contini.mailing[AT]gmail.com` if you have time and plan to do a large contribution. |
| | | * Even it it's in alpha stage it's used ( _by some really courageous people!_ ) in production. We can't break current functionality, user established habits without documenting the change. |
| | | |
| | | |
| | |
| | | [](https://travis-ci.org/open-license-manager/open-license-manager) |
| | | [](http://github.com/badges/stability-badges)[](https://opensource.org/licenses/BSD-3-Clause) |
| | | |
| | | A copy protection, licensing software written in C/C++ for Windows and Linux. |
| | | A copy protection, licensing software written in C++ for Windows and Linux (with a simple C api for use in C projects). |
| | | |
| | | It allows to protect the software you develop from unauthorized copies, |
| | | limit the usage in time, to a specific set of machines, or prevent the usage in |
| | |
| | | #include <map> |
| | | #include "api/license++.h" |
| | | #include "pc-identifiers.h" |
| | | #include "ini/SimpleIni.h" |
| | | |
| | | using namespace std; |
| | | |
| | | int main(int argc, char *argv[]) |
| | | { |
| | | map<EVENT_TYPE, string> stringByEventType; |
| | | stringByEventType[LICENSE_OK ] = "OK "; |
| | | stringByEventType[LICENSE_FILE_NOT_FOUND ] = "license file not found "; |
| | | stringByEventType[LICENSE_SERVER_NOT_FOUND ] = "license server can't be contacted "; |
| | | stringByEventType[ENVIRONMENT_VARIABLE_NOT_DEFINED] = "environment variable not defined "; |
| | | stringByEventType[FILE_FORMAT_NOT_RECOGNIZED ] = "license file has invalid format (not .ini file) "; |
| | | stringByEventType[LICENSE_MALFORMED ] = "some mandatory field are missing, or data can't be fully read. "; |
| | | stringByEventType[PRODUCT_NOT_LICENSED ] = "this product was not licensed "; |
| | | stringByEventType[PRODUCT_EXPIRED ] = "license expired "; |
| | | stringByEventType[LICENSE_CORRUPTED ] = "license signature didn't match with current license "; |
| | | stringByEventType[IDENTIFIERS_MISMATCH ] = "Calculated identifier and the one provided in license didn't match"; |
| | | stringByEventType[LICENSE_FILE_FOUND ] = "license file not found "; |
| | | stringByEventType[LICENSE_VERIFIED ] = "license verified "; |
| | | |
| | | const string licLocation("example.lic"); |
| | | |
| | | LicenseInfo licenseInfo; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | EVENT_TYPE result = acquire_license("example", licenseLocation, &licenseInfo); |
| | | PcSignature signature; |
| | | FUNCTION_RETURN generate_ok = generate_user_pc_signature(signature, DEFAULT); |
| | | int main(int argc, char *argv[]) { |
| | | map<EVENT_TYPE, string> stringByEventType; |
| | | stringByEventType[LICENSE_OK] = "OK "; |
| | | stringByEventType[LICENSE_FILE_NOT_FOUND] = "license file not found "; |
| | | stringByEventType[LICENSE_SERVER_NOT_FOUND] = "license server can't be contacted "; |
| | | stringByEventType[ENVIRONMENT_VARIABLE_NOT_DEFINED] = "environment variable not defined "; |
| | | stringByEventType[FILE_FORMAT_NOT_RECOGNIZED] = "license file has invalid format (not .ini file) "; |
| | | stringByEventType[LICENSE_MALFORMED] = "some mandatory field are missing, or data can't be fully read. "; |
| | | stringByEventType[PRODUCT_NOT_LICENSED] = "this product was not licensed "; |
| | | stringByEventType[PRODUCT_EXPIRED] = "license expired "; |
| | | stringByEventType[LICENSE_CORRUPTED] = "license signature didn't match with current license "; |
| | | stringByEventType[IDENTIFIERS_MISMATCH] = "Calculated identifier and the one provided in license didn't match"; |
| | | |
| | | if (result == LICENSE_OK && licenseInfo.linked_to_pc) { |
| | | CSimpleIniA ini; |
| | | SI_Error rc = ini.LoadFile(licLocation.c_str()); |
| | | string IDinLicense = ini.GetValue("example", "client_signature", ""); |
| | | if (IDinLicense == "") { |
| | | cout << "No client signature in license file, generate license with -s <id>"; |
| | | LicenseInfo licenseInfo; |
| | | EVENT_TYPE result = acquire_license("example", nullptr, &licenseInfo); |
| | | |
| | | if (result == LICENSE_OK) { |
| | | //for this example we want to link the license to the execution hardware. |
| | | if (licenseInfo.linked_to_pc) { |
| | | cout |
| | | << "No client signature in license file, generate license with -s <id>"; |
| | | result = IDENTIFIERS_MISMATCH; |
| | | } else if (IDinLicense != signature) { |
| | | result = IDENTIFIERS_MISMATCH; |
| | | } else { |
| | | cout << "license OK" << endl; |
| | | } |
| | | } |
| | | if (result != LICENSE_OK) { |
| | | cout << "license ERROR :" << endl; |
| | | cout << " " << stringByEventType[result].c_str() << endl; |
| | | if (result == IDENTIFIERS_MISMATCH) { |
| | | PcSignature signature; |
| | | FUNCTION_RETURN generate_ok = generate_user_pc_signature(signature, |
| | | DEFAULT); |
| | | cout << "the pc signature is :" << endl; |
| | | cout << " " << signature << endl; |
| | | } |
| | | } |
| | | |
| | | if (result != LICENSE_OK) { |
| | | cout << "license ERROR :" << endl; |
| | | cout << " " << stringByEventType[result].c_str() << endl; |
| | | cout << "the pc signature is :" << endl; |
| | | cout << " " << signature << endl; |
| | | } |
| | | else |
| | | cout << "license OK" << endl; |
| | | return result; |
| | | } |
| | |
| | | ini |
| | | locators |
| | | os |
| | | base |
| | | ) |
| | | |
| | | install(TARGETS licensecc_static ARCHIVE DESTINATION lib) |
| | |
| | | extra_data(extra_data) { |
| | | } |
| | | |
| | | EventRegistry FullLicenseInfo::validate(int sw_version) { |
| | | EventRegistry er; |
| | | bool FullLicenseInfo::validate(int sw_version, |
| | | EventRegistry &eventRegistryOut) { |
| | | os_initialize(); |
| | | const FUNCTION_RETURN sigVer = verifySignature(printForSign().c_str(), |
| | | license_signature.c_str()); |
| | | const bool sigVerified = sigVer == FUNC_RET_OK; |
| | | if (sigVerified) { |
| | | er.addEvent(LICENSE_VERIFIED, SVRT_INFO); |
| | | bool is_valid = (sigVer == FUNC_RET_OK); |
| | | if (is_valid) { |
| | | eventRegistryOut.addEvent(SIGNATURE_VERIFIED, source); |
| | | } else { |
| | | er.addEvent(LICENSE_CORRUPTED, SVRT_ERROR); |
| | | eventRegistryOut.addEvent(LICENSE_CORRUPTED, source); |
| | | } |
| | | if (has_expiry) { |
| | | cout<<source<<endl; |
| | | const time_t now = time(nullptr); |
| | | if (expires_on() < now) { |
| | | er.addEvent(PRODUCT_EXPIRED, SVRT_ERROR, ""); |
| | | /* |
| | | eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(), |
| | | string("Expired on: " + this->to_date).c_str());*/ |
| | | eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),nullptr); |
| | | is_valid = false; |
| | | } |
| | | if (valid_from() > now) { |
| | | er.addEvent(PRODUCT_EXPIRED, SVRT_ERROR); |
| | | /*eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(), |
| | | string("Valid from " + this->from_date).c_str());*/ |
| | | eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),nullptr); |
| | | is_valid = false; |
| | | } |
| | | } |
| | | if (has_client_sig) { |
| | | PcSignature str_code; |
| | | strncpy(str_code, client_signature.c_str(), sizeof(str_code) - 1); |
| | | const EVENT_TYPE event = validate_pc_signature(str_code); |
| | | if (event != LICENSE_OK) { |
| | | er.addEvent(event, SVRT_ERROR); |
| | | } |
| | | eventRegistryOut.addEvent(event, source); |
| | | is_valid = is_valid && (event == LICENSE_OK); |
| | | } |
| | | return er; |
| | | return is_valid; |
| | | } |
| | | |
| | | void FullLicenseInfo::toLicenseInfo(LicenseInfo *license) const { |
| | |
| | | } |
| | | } |
| | | |
| | | LicenseReader::LicenseReader(const LicenseLocation &licenseLocation) : |
| | | LicenseReader::LicenseReader(const LicenseLocation* licenseLocation) : |
| | | licenseLocation(licenseLocation) { |
| | | } |
| | | |
| | |
| | | vector<FullLicenseInfo> &licenseInfoOut) { |
| | | vector<string> diskFiles; |
| | | vector<unique_ptr<locate::LocatorStrategy>> locator_strategies; |
| | | FUNCTION_RETURN ret = locate::LocatorFactory::getActiveStrategies( |
| | | locator_strategies, licenseLocation.licenseFileLocation); |
| | | FUNCTION_RETURN ret = locate::LocatorFactory::get_active_strategies( |
| | | locator_strategies, licenseLocation); |
| | | EventRegistry eventRegistry; |
| | | if (ret != FUNC_RET_OK) { |
| | | eventRegistry.addError(LICENSE_FILE_NOT_FOUND); |
| | | eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND); |
| | | eventRegistry.turnWarningsIntoErrors(); |
| | | return eventRegistry; |
| | | } |
| | | |
| | | if (!eventRegistry.isGood()) { |
| | | return eventRegistry; |
| | | } |
| | | bool atLeastOneFileFound = false; |
| | | bool atLeastOneFileRecognized = false; |
| | | bool atLeastOneProductLicensed = false; |
| | | bool atLeastOneLicenseComplete = false; |
| | | for (unique_ptr<locate::LocatorStrategy>& locator : locator_strategies) { |
| | | vector<string> licenseLocations = locator->licenseLocations( |
| | | for (unique_ptr<locate::LocatorStrategy> &locator : locator_strategies) { |
| | | vector<string> licenseLocations = locator->license_locations( |
| | | eventRegistry); |
| | | if (licenseLocations.size() == 0) { |
| | | continue; |
| | | } |
| | | atLeastOneFileFound = true; |
| | | CSimpleIniA ini; |
| | | for (auto it = licenseLocations.begin(); it != licenseLocations.end(); |
| | | it++) { |
| | | ini.Reset(); |
| | | string license = locator->retrieveLicense((*it).c_str()); |
| | | string license = locator->retrieve_license_content((*it).c_str()); |
| | | const SI_Error rc = ini.LoadData(license.c_str(), license.size()); |
| | | if (rc < 0) { |
| | | eventRegistry.addEvent(FILE_FORMAT_NOT_RECOGNIZED, SVRT_WARN, |
| | | *it); |
| | | eventRegistry.addEvent(FILE_FORMAT_NOT_RECOGNIZED, *it); |
| | | continue; |
| | | } else { |
| | | atLeastOneFileRecognized = true; |
| | | } |
| | | const char *productNamePtr = product.c_str(); |
| | | const int sectionSize = ini.GetSectionSize(productNamePtr); |
| | | if (sectionSize <= 0) { |
| | | eventRegistry.addEvent(PRODUCT_NOT_LICENSED, SVRT_WARN, *it); |
| | | eventRegistry.addEvent(PRODUCT_NOT_LICENSED, *it); |
| | | continue; |
| | | } else { |
| | | atLeastOneProductLicensed = true; |
| | | eventRegistry.addEvent(PRODUCT_FOUND, *it); |
| | | } |
| | | /* |
| | | * sw_version_from = (optional int) |
| | |
| | | licenseInfoOut.push_back(licInfo); |
| | | atLeastOneLicenseComplete = true; |
| | | } else { |
| | | eventRegistry.addEvent(LICENSE_MALFORMED, SVRT_WARN, *it); |
| | | eventRegistry.addEvent(LICENSE_MALFORMED, *it); |
| | | } |
| | | } |
| | | } |
| | | if (!atLeastOneFileFound) { |
| | | eventRegistry.turnEventIntoError(ENVIRONMENT_VARIABLE_NOT_DEFINED); |
| | | eventRegistry.turnEventIntoError(LICENSE_FILE_NOT_FOUND); |
| | | } else if (!atLeastOneFileRecognized) { |
| | | eventRegistry.turnEventIntoError(FILE_FORMAT_NOT_RECOGNIZED); |
| | | } else if (!atLeastOneProductLicensed) { |
| | | eventRegistry.turnEventIntoError(PRODUCT_NOT_LICENSED); |
| | | } else if (!atLeastOneLicenseComplete) { |
| | | eventRegistry.turnEventIntoError(LICENSE_MALFORMED); |
| | | if (!atLeastOneLicenseComplete) { |
| | | eventRegistry.turnWarningsIntoErrors(); |
| | | } |
| | | return eventRegistry; |
| | | } |
| | |
| | | * LicenseReader.h |
| | | * |
| | | * Created on: Mar 30, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef LICENSEREADER_H_ |
| | | #define LICENSEREADER_H_ |
| | | #include <string> |
| | | #include <ctime> |
| | | |
| | | #define SI_SUPPORT_IOSTREAMS |
| | | #include "api/datatypes.h" |
| | | #include "base/EventRegistry.h" |
| | | #include "os/os.h" |
| | | #include "locate/LocatorStrategy.hpp" |
| | | #define SI_SUPPORT_IOSTREAMS |
| | | #include "ini/SimpleIni.h" |
| | | #include <string> |
| | | #include <ctime> |
| | | namespace license { |
| | | |
| | | using namespace std; |
| | | namespace license { |
| | | |
| | | class FullLicenseInfo { |
| | | public: |
| | | string source; |
| | | string product; |
| | | string license_signature; |
| | | std::string source; |
| | | std::string product; |
| | | std::string license_signature; |
| | | int license_version; |
| | | string from_date; |
| | | string to_date; |
| | | std::string from_date; |
| | | std::string to_date; |
| | | bool has_expiry; |
| | | unsigned int from_sw_version; |
| | | unsigned int to_sw_version; |
| | | bool has_versions; |
| | | string client_signature; |
| | | std::string client_signature; |
| | | bool has_client_sig; |
| | | string extra_data; |
| | | std::string extra_data; |
| | | |
| | | static const char* UNUSED_TIME; |
| | | static const unsigned int UNUSED_SOFTWARE_VERSION = 0; |
| | | |
| | | FullLicenseInfo(const string& source, const string& product, |
| | | const string& license_signature, int licenseVersion, |
| | | string from_date = UNUSED_TIME, |
| | | string to_date = UNUSED_TIME, // |
| | | const string& client_signature = "", // |
| | | FullLicenseInfo(const std::string& source, const std::string& product, |
| | | const std::string& license_signature, int licenseVersion, |
| | | std::string from_date = UNUSED_TIME, |
| | | std::string to_date = UNUSED_TIME, // |
| | | const std::string& client_signature = "", // |
| | | unsigned int from_sw_version = UNUSED_SOFTWARE_VERSION, |
| | | unsigned int to_sw_version = UNUSED_SOFTWARE_VERSION, |
| | | const string& extra_data = ""); |
| | | string printForSign() const; |
| | | void printAsIni(ostream & a_ostream) const; |
| | | const std::string& extra_data = ""); |
| | | std::string printForSign() const; |
| | | void printAsIni(std::ostream & a_ostream) const; |
| | | void toLicenseInfo(LicenseInfo* license) const; |
| | | EventRegistry validate(int sw_version); |
| | | bool validate(int sw_version, EventRegistry& eventRegistryOut); |
| | | time_t expires_on() const; |
| | | time_t valid_from() const; |
| | | }; |
| | |
| | | * sw_version_to = (optional int) |
| | | * from_date = YYYY-MM-DD (optional) |
| | | * to_date = YYYY-MM-DD (optional) |
| | | * client_signature = XXXXXXXX (optional string 16) |
| | | * client_signature = XXXXXXXX (optional std::string 16) |
| | | * license_signature = XXXXXXXXXX (mandatory, 1024) |
| | | * application_data = xxxxxxxxx (optional string 16) |
| | | * application_data = xxxxxxxxx (optional std::string 16) |
| | | * license_version = 100 (mandatory int) |
| | | * </pre> |
| | | */ |
| | | class LicenseReader { |
| | | private: |
| | | const LicenseLocation licenseLocation; |
| | | const LicenseLocation* licenseLocation; |
| | | public: |
| | | LicenseReader(const LicenseLocation& licenseLocation); |
| | | EventRegistry readLicenses(const string &product, |
| | | vector<FullLicenseInfo>& licenseInfoOut); |
| | | LicenseReader(const LicenseLocation* licenseLocation); |
| | | EventRegistry readLicenses(const std::string &product, |
| | | std::vector<FullLicenseInfo>& licenseInfoOut); |
| | | virtual ~LicenseReader(); |
| | | }; |
| | | } |
| | |
| | | |
| | | #ifdef __unix__ |
| | | #define DllExport |
| | | #ifndef MAX_PATH |
| | | #define MAX_PATH 1024 |
| | | #endif |
| | | #else |
| | | #include <windows.h> |
| | | #define DllExport __declspec( dllexport ) |
| | | #endif |
| | | |
| | | |
| | | #define PC_IDENTIFIER_SIZE 18 |
| | | #define PROPRIETARY_DATA_SIZE 16 |
| | | #define AUDIT_EVENT_NUM 5 |
| | | |
| | | #define LICENESE_INT_VERSION 110 |
| | | #define LICENSEPP_VERSION "1.1.0" |
| | |
| | | LICENSE_CORRUPTED = 8, //License signature didn't match with current license |
| | | IDENTIFIERS_MISMATCH = 9, //Calculated identifier and the one provided in license didn't match |
| | | |
| | | LICENSE_FILE_FOUND = 100, |
| | | LICENSE_VERIFIED = 101 |
| | | LICENSE_SPECIFIED = 100, //license location was specified |
| | | LICENSE_FOUND = 101, //License file has been found or license data has been located |
| | | PRODUCT_FOUND = 102, //License has been loaded and the declared product has been found |
| | | SIGNATURE_VERIFIED = 103 |
| | | |
| | | } EVENT_TYPE; |
| | | |
| | |
| | | typedef struct { |
| | | SEVERITY severity; |
| | | EVENT_TYPE event_type; |
| | | char param1[256]; |
| | | /** |
| | | * License file name or location where the license is stored. |
| | | */ |
| | | char license_reference[MAX_PATH]; |
| | | char param2[256]; |
| | | } AuditEvent; |
| | | |
| | | /** |
| | | * This structure contains informations on the raw license data. Software authors |
| | | * can specify the location of the license file or its full content. |
| | | * |
| | | * Can be NULL, in this case OpenLicenseManager will try to figure out the |
| | | * license file location on its own. |
| | | */ |
| | | typedef struct { |
| | | /** |
| | | * A list of absolute path separated by ';' containing the eventual location |
| | | * of the license files. Can be NULL. |
| | | */ |
| | | const char *licenseFileLocation; |
| | | const char *environmentVariableName; |
| | | bool openFileNearModule; |
| | | /** |
| | | * The application can provide the full license content through this string. |
| | | * It can be both in encoded form (base64) or in plain. It's optional. |
| | | */ |
| | | const char *licenseData; |
| | | } LicenseLocation; |
| | | |
| | | typedef struct { |
| | | /** |
| | | * Detailed reason of success/failure. Reasons for a failure can be |
| | | * multiple (for instance, license expired and signature not verified). |
| | | * Only the last 5 are reported. |
| | | * Only the last AUDIT_EVENT_NUM are reported. |
| | | */ |
| | | AuditEvent status[5]; |
| | | AuditEvent status[AUDIT_EVENT_NUM]; |
| | | /** |
| | | * Eventual expiration date of the software, |
| | | * can be '\0' if the software don't expire |
| | |
| | | |
| | | /* |
| | | * This include file is the public api di License++ |
| | | * You should include this file if your software don't plan to use |
| | | * the part of the library dealing with features. |
| | | * Otherwise licensepp-features.h should be included. |
| | | */ |
| | | */ |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | #ifdef __unix__ |
| | | #define DllExport |
| | | #ifndef MAX_PATH |
| | | #define MAX_PATH 1024 |
| | | #endif |
| | | #else |
| | | #include <windows.h> |
| | | #define DllExport __declspec( dllexport ) |
| | | #endif |
| | | |
| | | #include "datatypes.h" |
| | |
| | | */ |
| | | |
| | | EVENT_TYPE acquire_license(const char * productName, |
| | | LicenseLocation licenseLocation, LicenseInfo* license); |
| | | const LicenseLocation* licenseLocation, LicenseInfo* license); |
| | | |
| | | /** |
| | | * Do nothing for now, useful for network licenses. |
| | |
| | | * license. |
| | | */ |
| | | EVENT_TYPE confirm_license(char * featureName, |
| | | LicenseLocation licenseLocation); |
| | | LicenseLocation* licenseLocation); |
| | | /** |
| | | * Do nothing for now, useful for network licenses. |
| | | */ |
| | |
| | | StringUtils.cpp |
| | | FileUtils.cpp |
| | | logger.c |
| | | base64.c |
| | | ) |
| | | |
| | | add_dependencies( base public_key ) |
| | |
| | | * EventRegistry.cpp |
| | | * |
| | | * Created on: Mar 30, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #include "EventRegistry.h" |
| | | #include <cstddef> |
| | | #include <string.h> |
| | | #include <algorithm> |
| | | #include <map> |
| | | #include <iostream> |
| | | |
| | | #include "EventRegistry.h" |
| | | #define LIC_ID_NOT_DEFINED "UNDEF" |
| | | |
| | | namespace license { |
| | | using namespace std; |
| | | |
| | | const map<EVENT_TYPE, int> PROGRESS_BY_EVENT_TYPE = { { LICENSE_SPECIFIED, 0 }, |
| | | { LICENSE_FOUND, 1 }, { PRODUCT_FOUND, 2 }, { SIGNATURE_VERIFIED, 3 }, { |
| | | LICENSE_OK, 4 } }; |
| | | |
| | | EventRegistry::EventRegistry() { |
| | | current_validation_step = -1; |
| | | } |
| | | |
| | | EventRegistry& operator<<(EventRegistry& eventRegistry, |
| | | AuditEvent& securityEvent) { |
| | | EventRegistry& operator<<(EventRegistry &eventRegistry, |
| | | AuditEvent &securityEvent) { |
| | | eventRegistry.logs.push_back(securityEvent); |
| | | return eventRegistry; |
| | | } |
| | | |
| | | EventRegistry& operator<<(EventRegistry& eventRegistry1, |
| | | EventRegistry& otherRegistry) { |
| | | EventRegistry& operator<<(EventRegistry &eventRegistry1, |
| | | EventRegistry &otherRegistry) { |
| | | eventRegistry1.append(otherRegistry); |
| | | return eventRegistry1; |
| | | } |
| | | |
| | | void EventRegistry::append(const EventRegistry& eventRegistry) { |
| | | ostream& operator<<(std::ostream &out, const EventRegistry &er) { |
| | | out << string("EventReg[step:") << er.current_validation_step |
| | | << ",events:{"; |
| | | for (auto &it : er.logs) { |
| | | out << "[ev:" << it.event_type << ",sev:" << it.severity << "ref:" |
| | | << it.license_reference << "]"; |
| | | } |
| | | out << "]"; |
| | | return out; |
| | | } |
| | | |
| | | void EventRegistry::append(const EventRegistry &eventRegistry) { |
| | | logs.insert(logs.end(), eventRegistry.logs.begin(), |
| | | eventRegistry.logs.end()); |
| | | } |
| | | |
| | | void EventRegistry::turnLastEventIntoError() { |
| | | if (logs.size() > 0) { |
| | | logs.back().severity = SVRT_ERROR; |
| | | AuditEvent const* EventRegistry::getLastFailure() const { |
| | | const AuditEvent *result = nullptr; |
| | | if (logs.size() == 0) { |
| | | return result; |
| | | } |
| | | //try to find a failure between the licenses who progressed the most |
| | | if (mostAdvancedLogIdx_by_LicenseId.size() > 0) { |
| | | for (auto const &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) { |
| | | const AuditEvent ¤tLog = logs[mostAdvLogIter.second]; |
| | | if (currentLog.severity == SVRT_ERROR) { |
| | | result = &(currentLog); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (result == nullptr) { |
| | | auto it = logs.end(); |
| | | do { |
| | | --it; |
| | | if (it->severity == SVRT_ERROR) { |
| | | result = &(*it); |
| | | break; |
| | | } |
| | | } while (it != logs.begin()); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | void EventRegistry::addEvent(EVENT_TYPE event, |
| | | const std::string &licenseLocationId) { |
| | | addEvent(event, licenseLocationId.c_str(), nullptr); |
| | | } |
| | | |
| | | void EventRegistry::addEvent(EVENT_TYPE event, const char *licenseLocationId, |
| | | const char *info) { |
| | | AuditEvent audit; |
| | | auto eventIterator = PROGRESS_BY_EVENT_TYPE.find(event); |
| | | bool successEvent = (eventIterator != PROGRESS_BY_EVENT_TYPE.end()); |
| | | audit.severity = successEvent ? SVRT_INFO : SVRT_WARN; |
| | | audit.event_type = event; |
| | | if (licenseLocationId == nullptr) { |
| | | strcpy(audit.license_reference, LIC_ID_NOT_DEFINED); |
| | | } else { |
| | | strncpy(audit.license_reference, licenseLocationId, MAX_PATH); |
| | | } |
| | | if (info == nullptr) { |
| | | audit.param2[0] = '\0'; |
| | | } else { |
| | | strncpy(audit.param2, info, 255); |
| | | } |
| | | logs.push_back(audit); |
| | | //udpate the status of the log |
| | | if (successEvent) { |
| | | int step = eventIterator->second; |
| | | if (step > current_validation_step) { |
| | | mostAdvancedLogIdx_by_LicenseId.clear(); |
| | | current_validation_step = step; |
| | | } |
| | | |
| | | if (step == current_validation_step) { |
| | | mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = |
| | | logs.size() - 1; |
| | | } |
| | | } else if (mostAdvancedLogIdx_by_LicenseId.find(audit.license_reference) |
| | | != mostAdvancedLogIdx_by_LicenseId.end()) { |
| | | mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = logs.size() |
| | | - 1; |
| | | } |
| | | } |
| | | |
| | | bool EventRegistry::turnEventIntoError(EVENT_TYPE event) { |
| | | bool EventRegistry::turnWarningsIntoErrors() { |
| | | bool eventFound = false; |
| | | for (auto it = logs.begin(); it != logs.end(); ++it) { |
| | | if (it->event_type == event) { |
| | | it->severity = SVRT_ERROR; |
| | | eventFound = true; |
| | | if (mostAdvancedLogIdx_by_LicenseId.size() > 0) { |
| | | for (auto const &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) { |
| | | AuditEvent ¤tLog = logs[mostAdvLogIter.second]; |
| | | if (currentLog.severity == SVRT_WARN |
| | | || currentLog.severity == SVRT_ERROR) { |
| | | currentLog.severity = SVRT_ERROR; |
| | | eventFound = true; |
| | | } |
| | | } |
| | | } |
| | | if (!eventFound) { |
| | | for (auto it = logs.begin(); it != logs.end(); ++it) { |
| | | if (it->severity == SVRT_WARN) { |
| | | it->severity = SVRT_ERROR; |
| | | eventFound = true; |
| | | } |
| | | } |
| | | } |
| | | return eventFound; |
| | | } |
| | | |
| | | AuditEvent const * EventRegistry::getLastFailure() const { |
| | | const AuditEvent* result = nullptr; |
| | | if (logs.size() == 0) { |
| | | return result; |
| | | } |
| | | auto it = logs.end(); |
| | | do { |
| | | --it; |
| | | if (it->severity == SVRT_ERROR) { |
| | | result = &(*it); |
| | | break; |
| | | } |
| | | } while (it != logs.begin()); |
| | | return result; |
| | | |
| | | } |
| | | |
| | | bool EventRegistry::isGood() const { |
| | | bool isGood = true; |
| | | for (auto it = logs.begin(); it != logs.end(); ++it) { |
| | | if (it->severity == SVRT_ERROR) { |
| | | isGood = false; |
| | | break; |
| | | } |
| | | } |
| | | return isGood; |
| | | } |
| | | |
| | | void EventRegistry::addError(EVENT_TYPE event) { |
| | | this->addEvent(event, SVRT_ERROR); |
| | | } |
| | | |
| | | void EventRegistry::addEvent(EVENT_TYPE event, SEVERITY severity) { |
| | | AuditEvent audit; |
| | | audit.severity = severity; |
| | | audit.event_type = event; |
| | | audit.param1[0] = '\0'; |
| | | audit.param2[0] = '\0'; |
| | | logs.push_back(audit); |
| | | } |
| | | |
| | | void EventRegistry::addEvent(EVENT_TYPE event, SEVERITY severity, |
| | | const string& eventParameter) { |
| | | AuditEvent audit; |
| | | audit.severity = severity; |
| | | audit.event_type = event; |
| | | strncpy(audit.param1, eventParameter.c_str(), 255); |
| | | audit.param2[0] = '\0'; |
| | | logs.push_back(audit); |
| | | } |
| | | |
| | | bool EventRegistry::turnErrosIntoWarnings() { |
| | | bool EventRegistry::turnErrorsIntoWarnings() { |
| | | bool eventFound = false; |
| | | for (auto it = logs.begin(); it != logs.end(); ++it) { |
| | | if (it->severity == SVRT_ERROR) { |
| | |
| | | return eventFound; |
| | | } |
| | | |
| | | void EventRegistry::exportLastEvents(AuditEvent* auditEvents, int nlogs) { |
| | | void EventRegistry::exportLastEvents(AuditEvent *auditEvents, int nlogs) { |
| | | const int sizeToCopy = min(nlogs, (int) logs.size()); |
| | | std::copy(logs.begin(), logs.begin() + sizeToCopy, auditEvents); |
| | | std::copy(logs.end() - sizeToCopy, logs.end(), auditEvents); |
| | | } |
| | | |
| | | bool EventRegistry::isGood() const { |
| | | return getLastFailure() == nullptr; |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | * EventRegistry.h |
| | | * |
| | | * Created on: Mar 30, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef EVENTREGISTRY_H_ |
| | |
| | | |
| | | #include "../api/datatypes.h" |
| | | #include <vector> |
| | | #include <map> |
| | | #include <set> |
| | | #include <string> |
| | | |
| | | namespace license { |
| | | |
| | | /* |
| | | AuditEvent error_event_builder(EVENT_TYPE event); |
| | | AuditEvent audit_event_builder(EVENT_TYPE event, SEVERITY severity); |
| | | AuditEvent audit_event_builder(EVENT_TYPE event, SEVERITY severity, |
| | | const string& eventParameter);*/ |
| | | |
| | | /** |
| | | * Tracks the events relative to a license and provide explanation regarding |
| | | * failures to verify licenses. |
| | | */ |
| | | class EventRegistry { |
| | | private: |
| | | friend EventRegistry& operator<<(EventRegistry&, AuditEvent&); |
| | | friend EventRegistry& operator<<(EventRegistry&, EventRegistry&); |
| | | //TODO change into map |
| | | friend std::ostream & operator << (std::ostream &out, const EventRegistry &er); |
| | | |
| | | std::vector<AuditEvent> logs; |
| | | //Forbid copy |
| | | //EventRegistry(const EventRegistry& that) = delete; |
| | | /** |
| | | * For every license keep track of the events who progressed most |
| | | * in the validation process |
| | | */ |
| | | std::map<std::string,int> mostAdvancedLogIdx_by_LicenseId; |
| | | int current_validation_step; |
| | | |
| | | public: |
| | | EventRegistry(); |
| | | //operator << |
| | | void append(const EventRegistry &eventRegistry); |
| | | void turnLastEventIntoError(); |
| | | bool turnEventIntoError(EVENT_TYPE event); |
| | | bool turnErrosIntoWarnings(); |
| | | /** |
| | | * Turn the event warning for the license with the most advanced status |
| | | * into an error. |
| | | */ |
| | | bool turnWarningsIntoErrors(); |
| | | bool turnErrorsIntoWarnings(); |
| | | bool isGood() const; |
| | | /** |
| | | * Return the last failure (event with warn or error status) |
| | | * for the license with the most advanced status. |
| | | * @return NULL if no failures are found. |
| | | */ |
| | | AuditEvent const* getLastFailure() const; |
| | | bool isGood() const; |
| | | |
| | | void addError(EVENT_TYPE event); |
| | | void addEvent(EVENT_TYPE event, SEVERITY severity); |
| | | void addEvent(EVENT_TYPE event, SEVERITY severity, |
| | | const std::string &eventParameter); |
| | | void addEvent(EVENT_TYPE event, const std::string &licenseLocationId); |
| | | void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr, |
| | | const char *info = nullptr); |
| | | void exportLastEvents(AuditEvent *auditEvents, int nlogs); |
| | | |
| | | }; |
| | | } |
| | | #endif /* EVENTREGISTRY_H_ */ |
| | |
| | | #include <string> |
| | | #include <cerrno> |
| | | #include <iostream> |
| | | #include <algorithm> |
| | | #include <algorithm> |
| | | |
| | | #include "FileUtils.hpp" |
| | | |
| | | namespace license { |
| | | using namespace std; |
| | | |
| | | vector<string> filter_existing_files(const vector<string> &fileList) { |
| | | vector<string> filter_existing_files(const vector<string> &fileList, |
| | | EventRegistry& registry,const char* extraData) { |
| | | vector<string> existingFiles; |
| | | for (auto it = fileList.begin(); it != fileList.end(); it++) { |
| | | registry.addEvent(LICENSE_SPECIFIED,it->c_str(), extraData); |
| | | ifstream f(it->c_str()); |
| | | if (f.good()) { |
| | | existingFiles.push_back(*it); |
| | | registry.addEvent(LICENSE_FOUND,it->c_str(),extraData); |
| | | } else { |
| | | registry.addEvent(LICENSE_FILE_NOT_FOUND,it->c_str(), extraData); |
| | | } |
| | | f.close(); |
| | | } |
| | |
| | | return (dotpos == 0 ? path : path.substr(0, dotpos)); |
| | | } else if(pathsep_pos >= dotpos +1) { |
| | | return path; |
| | | } |
| | | } |
| | | return path.substr(0, dotpos); |
| | | } |
| | | |
| | |
| | | * FileUtils.h |
| | | * |
| | | * Created on: Apr 8, 2019 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef FILEUTILS_H_ |
| | | #define FILEUTILS_H_ |
| | | #include <string> |
| | | #include <vector> |
| | | #include "EventRegistry.h" |
| | | |
| | | namespace license { |
| | | |
| | | std::vector<std::string> filter_existing_files(const std::vector<std::string>& fileList); |
| | | std::vector<std::string> filter_existing_files(const std::vector<std::string>& fileList,EventRegistry& registry, const char* extraData); |
| | | std::string get_file_contents(const char *filename,size_t max_size); |
| | | std::string remove_extension(const std::string& path); |
| | | |
| | |
| | | * StringUtils.cpp |
| | | * |
| | | * Created on: Apr 8, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #include <cctype> //toupper |
| | | #include "StringUtils.h" |
| | | #include <iostream> |
| | | #include <string> |
| | | #include <sstream> |
| | | #include <cstring> |
| | | #include <algorithm> |
| | | #include <stdexcept> |
| | | #include <regex> |
| | | #include "StringUtils.h" |
| | | |
| | | #ifdef _WIN32 |
| | | #include <time.h> //mktime under windows |
| | |
| | | namespace license { |
| | | using namespace std; |
| | | |
| | | string trim_copy(const string& string_to_trim) { |
| | | string trim_copy(const string &string_to_trim) { |
| | | std::string::const_iterator it = string_to_trim.begin(); |
| | | while (it != string_to_trim.end() && isspace(*it)) |
| | | it++; |
| | |
| | | return std::string(it, rit.base()); |
| | | } |
| | | |
| | | string toupper_copy(const string& lowercase) { |
| | | string toupper_copy(const string &lowercase) { |
| | | string cp(lowercase); |
| | | std::transform(cp.begin(), cp.end(), cp.begin(), (int (*)(int))toupper); |
| | | std::transform(cp.begin(), cp.end(), cp.begin(), (int (*)(int)) toupper); |
| | | return cp; |
| | | } |
| | | |
| | | time_t seconds_from_epoch(const char* timeString) { |
| | | time_t seconds_from_epoch(const char *timeString) { |
| | | int year, month, day; |
| | | tm tm; |
| | | if (strlen(timeString) == 8) { |
| | |
| | | throw invalid_argument("Date not recognized"); |
| | | } |
| | | } else if (strlen(timeString) == 10) { |
| | | const int nfield = sscanf(timeString, "%4d-%2d-%2d", &year, &month, &day); |
| | | const int nfield = sscanf(timeString, "%4d-%2d-%2d", &year, &month, |
| | | &day); |
| | | if (nfield != 3) { |
| | | const int nfield = sscanf(timeString, "%4d/%2d/%2d", &year, &month, &day); |
| | | const int nfield = sscanf(timeString, "%4d/%2d/%2d", &year, &month, |
| | | &day); |
| | | if (nfield != 3) { |
| | | throw invalid_argument("Date not recognized"); |
| | | } |
| | | } |
| | | } else{ |
| | | } else { |
| | | throw invalid_argument("Date not recognized"); |
| | | } |
| | | tm.tm_isdst = -1; |
| | |
| | | return mktime(&tm); |
| | | } |
| | | |
| | | |
| | | const vector<string> split_string(const string& licensePositions,char splitchar) { |
| | | const vector<string> split_string(const string &licensePositions, |
| | | char splitchar) { |
| | | std::stringstream streamToSplit(licensePositions); |
| | | std::string segment; |
| | | std::vector<string> seglist; |
| | |
| | | return seglist; |
| | | } |
| | | |
| | | const static regex iniSection("\\[.*?\\]"); |
| | | const static regex b64( |
| | | "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"); |
| | | |
| | | FILE_FORMAT identify_format(const string &license) { |
| | | FILE_FORMAT result = UNKNOWN; |
| | | if (regex_match(license, b64)) { |
| | | result = BASE64; |
| | | } else if (regex_search(license, iniSection)) { |
| | | result = INI; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } /* namespace license */ |
| | |
| | | * StringUtils.h |
| | | * |
| | | * Created on: Apr 8, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef STRINGUTILS_H_ |
| | | #define STRINGUTILS_H_ |
| | | |
| | | #include <bits/types/time_t.h> |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | |
| | | /** |
| | | * Split a string on a given character |
| | | */ |
| | | const vector<string> split_string(const string& licensePositions, const char splitchar); |
| | | const vector<string> split_string(const string& stringToBeSplit, const char splitchar); |
| | | |
| | | typedef enum { |
| | | INI, BASE64, UNKNOWN |
| | | } FILE_FORMAT; |
| | | |
| | | FILE_FORMAT identify_format(const string& license); |
| | | |
| | | } |
| | | |
| | | /* namespace license */ |
New file |
| | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | |
| | | const static char* b64 = |
| | | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| | | |
| | | // maps A=>0,B=>1.. |
| | | const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40 |
| | | 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50 |
| | | 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60 |
| | | 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70 |
| | | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80 |
| | | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90 |
| | | 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100 |
| | | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110 |
| | | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120 |
| | | 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250 |
| | | 0, 0, 0, 0, 0, 0, }; // This array has 255 elements |
| | | |
| | | //review api |
| | | char* base64(const void* binaryData, int len, int *flen) { |
| | | const unsigned char* bin = (const unsigned char*) binaryData; |
| | | char* res; |
| | | |
| | | int rc = 0; // result counter |
| | | int byteNo; // I need this after the loop |
| | | |
| | | int modulusLen = len % 3; |
| | | int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0. |
| | | |
| | | *flen = 4 * (len + pad) / 3; |
| | | res = (char*) malloc(*flen + 1); // and one for the null |
| | | if (!res) { |
| | | puts("ERROR: base64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (byteNo = 0; byteNo <= len - 3; byteNo += 3) { |
| | | unsigned char BYTE0 = bin[byteNo]; |
| | | unsigned char BYTE1 = bin[byteNo + 1]; |
| | | unsigned char BYTE2 = bin[byteNo + 2]; |
| | | res[rc++] = b64[BYTE0 >> 2]; |
| | | res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)]; |
| | | res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)]; |
| | | res[rc++] = b64[0x3f & BYTE2]; |
| | | } |
| | | |
| | | if (pad == 2) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[(0x3 & bin[byteNo]) << 4]; |
| | | res[rc++] = '='; |
| | | res[rc++] = '='; |
| | | } else if (pad == 1) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)]; |
| | | res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2]; |
| | | res[rc++] = '='; |
| | | } |
| | | |
| | | res[rc] = 0; // NULL TERMINATOR! ;) |
| | | return res; |
| | | } |
| | | |
| | | unsigned char* unbase64(const char* ascii, int len, int *flen) { |
| | | const unsigned char *safeAsciiPtr = (const unsigned char*) ascii; |
| | | unsigned char *bin; |
| | | int cb = 0; |
| | | int charNo; |
| | | int pad = 0; |
| | | |
| | | if (len < 2) { // 2 accesses below would be OOB. |
| | | // catch empty string, return NULL as result. |
| | | puts( |
| | | "ERROR: You passed an invalid base64 string (too short). You get NULL back."); |
| | | *flen = 0; |
| | | return 0; |
| | | } |
| | | if (safeAsciiPtr[len - 1] == '=') |
| | | ++pad; |
| | | if (safeAsciiPtr[len - 2] == '=') |
| | | ++pad; |
| | | |
| | | *flen = 3 * len / 4 - pad; |
| | | bin = (unsigned char*) malloc(*flen); |
| | | if (!bin) { |
| | | puts("ERROR: unbase64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | int D = unb64[safeAsciiPtr[charNo + 3]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | bin[cb++] = (C << 6) | (D); |
| | | } |
| | | |
| | | if (pad == 1) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | } else if (pad == 2) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | } |
| | | |
| | | return bin; |
| | | } |
| | |
| | | #ifndef BASE64_H |
| | | #define BASE64_H |
| | | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | const static char* b64 = |
| | | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| | | unsigned char* unbase64(const char* ascii, int len, int *flen); |
| | | char* base64(const void* binaryData, int len, int *flen); |
| | | |
| | | // maps A=>0,B=>1.. |
| | | const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40 |
| | | 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50 |
| | | 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60 |
| | | 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70 |
| | | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80 |
| | | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90 |
| | | 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100 |
| | | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110 |
| | | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120 |
| | | 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250 |
| | | 0, 0, 0, 0, 0, 0, }; // This array has 255 elements |
| | | |
| | | // Converts binary data of length=len to base64 characters. |
| | | // Length of the resultant string is stored in flen |
| | | // (you must pass pointer flen). |
| | | char* base64(const void* binaryData, int len, int *flen) { |
| | | const unsigned char* bin = (const unsigned char*) binaryData; |
| | | char* res; |
| | | |
| | | int rc = 0; // result counter |
| | | int byteNo; // I need this after the loop |
| | | |
| | | int modulusLen = len % 3; |
| | | int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0. |
| | | |
| | | *flen = 4 * (len + pad) / 3; |
| | | res = (char*) malloc(*flen + 1); // and one for the null |
| | | if (!res) { |
| | | puts("ERROR: base64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (byteNo = 0; byteNo <= len - 3; byteNo += 3) { |
| | | unsigned char BYTE0 = bin[byteNo]; |
| | | unsigned char BYTE1 = bin[byteNo + 1]; |
| | | unsigned char BYTE2 = bin[byteNo + 2]; |
| | | res[rc++] = b64[BYTE0 >> 2]; |
| | | res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)]; |
| | | res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)]; |
| | | res[rc++] = b64[0x3f & BYTE2]; |
| | | } |
| | | |
| | | if (pad == 2) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[(0x3 & bin[byteNo]) << 4]; |
| | | res[rc++] = '='; |
| | | res[rc++] = '='; |
| | | } else if (pad == 1) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)]; |
| | | res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2]; |
| | | res[rc++] = '='; |
| | | } |
| | | |
| | | res[rc] = 0; // NULL TERMINATOR! ;) |
| | | return res; |
| | | #ifdef __cplusplus |
| | | } |
| | | |
| | | unsigned char* unbase64(const char* ascii, int len, int *flen) { |
| | | const unsigned char *safeAsciiPtr = (const unsigned char*) ascii; |
| | | unsigned char *bin; |
| | | int cb = 0; |
| | | int charNo; |
| | | int pad = 0; |
| | | |
| | | if (len < 2) { // 2 accesses below would be OOB. |
| | | // catch empty string, return NULL as result. |
| | | puts( |
| | | "ERROR: You passed an invalid base64 string (too short). You get NULL back."); |
| | | *flen = 0; |
| | | return 0; |
| | | } |
| | | if (safeAsciiPtr[len - 1] == '=') |
| | | ++pad; |
| | | if (safeAsciiPtr[len - 2] == '=') |
| | | ++pad; |
| | | |
| | | *flen = 3 * len / 4 - pad; |
| | | bin = (unsigned char*) malloc(*flen); |
| | | if (!bin) { |
| | | puts("ERROR: unbase64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | int D = unb64[safeAsciiPtr[charNo + 3]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | bin[cb++] = (C << 6) | (D); |
| | | } |
| | | |
| | | if (pad == 1) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | } else if (pad == 2) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | } |
| | | |
| | | return bin; |
| | | } |
| | | |
| | | #endif |
| | | #endif |
| | |
| | | //============================================================================ |
| | | // Name : license-manager-cpp.cpp |
| | | // Author : |
| | | // Author : |
| | | // Version : |
| | | // Copyright : BSD |
| | | //============================================================================ |
| | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <cstring> |
| | | #include <iostream> |
| | | |
| | | #include "api/license++.h" |
| | | |
| | |
| | | } |
| | | |
| | | EVENT_TYPE acquire_license(const char * product, |
| | | LicenseLocation licenseLocation, LicenseInfo* license) { |
| | | const LicenseLocation* licenseLocation, LicenseInfo* licenseInfoOut) { |
| | | license::LicenseReader lr = license::LicenseReader(licenseLocation); |
| | | vector<license::FullLicenseInfo> licenses; |
| | | license::EventRegistry er = lr.readLicenses(string(product), licenses); |
| | |
| | | vector<license::FullLicenseInfo> licenses_with_errors; |
| | | vector<license::FullLicenseInfo> licenses_ok; |
| | | for (auto it = licenses.begin(); it != licenses.end(); it++) { |
| | | license::EventRegistry validation_er = it->validate(0); |
| | | if (validation_er.isGood()) { |
| | | bool valid = it->validate(0,er); |
| | | if (valid) { |
| | | licenses_ok.push_back(*it); |
| | | } else { |
| | | licenses_with_errors.push_back(*it); |
| | | } |
| | | er.append(validation_er); |
| | | } |
| | | if (licenses_ok.size() > 0) { |
| | | er.turnErrosIntoWarnings(); |
| | | er.turnErrorsIntoWarnings(); |
| | | result = LICENSE_OK; |
| | | mergeLicenses(licenses_ok, license); |
| | | mergeLicenses(licenses_ok, licenseInfoOut); |
| | | } else { |
| | | er.turnWarningsIntoErrors(); |
| | | result = er.getLastFailure()->event_type; |
| | | mergeLicenses(licenses_with_errors, license); |
| | | mergeLicenses(licenses_with_errors, licenseInfoOut); |
| | | } |
| | | |
| | | } else { |
| | | er.turnWarningsIntoErrors(); |
| | | result = er.getLastFailure()->event_type; |
| | | } |
| | | if (license != nullptr) { |
| | | er.exportLastEvents(license->status, 5); |
| | | #ifdef _DEBUG |
| | | cout << er <<endl; |
| | | #endif |
| | | if (licenseInfoOut != nullptr) { |
| | | er.exportLastEvents(licenseInfoOut->status, AUDIT_EVENT_NUM); |
| | | } |
| | | return result; |
| | | } |
| | |
| | | namespace locate { |
| | | using namespace std; |
| | | |
| | | |
| | | |
| | | ApplicationFolder::ApplicationFolder() : |
| | | LocatorStrategy("ApplicationFolder") { |
| | | |
| | | } |
| | | |
| | | ApplicationFolder::~ApplicationFolder() { |
| | | } |
| | | |
| | | const vector<string> ApplicationFolder::licenseLocations( |
| | | EventRegistry &eventRegistry) const { |
| | | const vector<string> ApplicationFolder::license_locations( |
| | | EventRegistry &eventRegistry) { |
| | | vector<string> diskFiles; |
| | | char fname[MAX_PATH] = { 0 }; |
| | | const FUNCTION_RETURN fret = getModuleName(fname); |
| | |
| | | ifstream f(temptativeLicense.c_str()); |
| | | if (f.good()) { |
| | | diskFiles.push_back(temptativeLicense); |
| | | eventRegistry.addEvent((EVENT_TYPE) LICENSE_FILE_FOUND, |
| | | (SEVERITY) SVRT_INFO, temptativeLicense); |
| | | eventRegistry.addEvent(LICENSE_FOUND, temptativeLicense.c_str()); |
| | | } else { |
| | | eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND, SVRT_WARN, |
| | | temptativeLicense); |
| | | eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND, temptativeLicense.c_str()); |
| | | } |
| | | f.close(); |
| | | } else { |
| | |
| | | class ApplicationFolder: public LocatorStrategy { |
| | | public: |
| | | ApplicationFolder(); |
| | | virtual const std::vector<std::string> licenseLocations(EventRegistry& eventRegistry) const; |
| | | virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistry); |
| | | virtual ~ApplicationFolder(); |
| | | }; |
| | | |
| | |
| | | */ |
| | | |
| | | #include "EnvironmentVarData.hpp" |
| | | |
| | | #include <build_properties.h> |
| | | #include <cstdlib> |
| | | #include <regex> |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | #include "../api/datatypes.h" |
| | | #include "../base/base64.h" |
| | | #include "../base/EventRegistry.h" |
| | | #include "../base/StringUtils.h" |
| | | |
| | | namespace license { |
| | | namespace locate { |
| | | |
| | |
| | | EnvironmentVarData::~EnvironmentVarData() { |
| | | } |
| | | |
| | | const vector<string> EnvironmentVarData::licenseLocations( |
| | | EventRegistry &eventRegistry) const { |
| | | const vector<string> EnvironmentVarData::license_locations( |
| | | EventRegistry &eventRegistry) { |
| | | vector<string> diskFiles; |
| | | |
| | | char *env_var_value = getenv(LICENSE_DATA_ENV_VAR); |
| | | if (env_var_value != nullptr && env_var_value[0] != '\0') { |
| | | eventRegistry.addEvent(LICENSE_SPECIFIED, LICENSE_LOCATION_ENV_VAR); |
| | | FILE_FORMAT licenseFormat = identify_format(env_var_value); |
| | | if (licenseFormat == UNKNOWN) { |
| | | eventRegistry.addEvent(LICENSE_MALFORMED, LICENSE_LOCATION_ENV_VAR); |
| | | } else { |
| | | diskFiles.push_back(LICENSE_LOCATION_ENV_VAR); |
| | | isBase64 = (licenseFormat == BASE64); |
| | | } |
| | | } else { |
| | | eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED, |
| | | LICENSE_LOCATION_ENV_VAR); |
| | | } |
| | | return diskFiles; |
| | | } |
| | | |
| | | const std::string EnvironmentVarData::retrieveLicense(const std::string &licenseLocation) const{ |
| | | return ""; |
| | | const std::string EnvironmentVarData::retrieve_license_content( |
| | | const std::string &licenseLocation) const { |
| | | string tmpVal = getenv(LICENSE_LOCATION_ENV_VAR); |
| | | if (isBase64) { |
| | | int flen = 0; |
| | | unsigned char *raw = unbase64(tmpVal.c_str(), tmpVal.length(), &flen); |
| | | string str = string(reinterpret_cast<char*>(raw)); |
| | | free(raw); |
| | | return str; |
| | | } |
| | | return tmpVal; |
| | | } |
| | | |
| | | } |
| | |
| | | namespace locate { |
| | | class EnvironmentVarData: public LocatorStrategy { |
| | | private: |
| | | bool isBase64 = false; |
| | | |
| | | public: |
| | | EnvironmentVarData(); |
| | | virtual const std::vector<std::string> licenseLocations(EventRegistry& eventRegistr) const; |
| | | virtual const std::string retrieveLicense(const std::string &licenseLocation) const; |
| | | virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistr); |
| | | virtual const std::string retrieve_license_content(const std::string &licenseLocation) const; |
| | | virtual ~EnvironmentVarData(); |
| | | }; |
| | | |
| | |
| | | EnvironmentVarLocation::~EnvironmentVarLocation() { |
| | | } |
| | | |
| | | const vector<string> EnvironmentVarLocation::licenseLocations( |
| | | EventRegistry &eventRegistry) const { |
| | | const vector<string> EnvironmentVarLocation::license_locations( |
| | | EventRegistry &eventRegistry) { |
| | | vector<string> licenseFileFoundWithEnvVariable; |
| | | |
| | | const string varName(LICENSE_LOCATION_ENV_VAR); |
| | |
| | | if (env_var_value != nullptr && env_var_value[0] != '\0') { |
| | | const vector<string> declared_positions = license::split_string( |
| | | string(env_var_value), ';'); |
| | | vector<string> existing_pos = license::filter_existing_files( |
| | | declared_positions); |
| | | if (existing_pos.size() > 0) { |
| | | for (auto it = existing_pos.begin(); it != existing_pos.end(); |
| | | ++it) { |
| | | licenseFileFoundWithEnvVariable.push_back(*it); |
| | | eventRegistry.addEvent(LICENSE_FILE_FOUND, SVRT_INFO, *it); |
| | | } |
| | | } else { |
| | | eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND, SVRT_WARN, |
| | | env_var_value); |
| | | } |
| | | licenseFileFoundWithEnvVariable = license::filter_existing_files( |
| | | declared_positions, eventRegistry, LICENSE_LOCATION_ENV_VAR); |
| | | } else { |
| | | eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED, SVRT_WARN); |
| | | eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED); |
| | | } |
| | | } |
| | | return licenseFileFoundWithEnvVariable; |
| | |
| | | |
| | | public: |
| | | EnvironmentVarLocation(); |
| | | virtual const std::vector<std::string> licenseLocations(EventRegistry& eventRegistry) const; |
| | | virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistry); |
| | | virtual ~EnvironmentVarLocation(); |
| | | }; |
| | | |
| | |
| | | * Author: Gabriele Contini |
| | | */ |
| | | |
| | | #include "../base/StringUtils.h" |
| | | #include <stdlib.h> |
| | | #include <cstring> |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | #include "../api/datatypes.h" |
| | | #include "../base/base64.h" |
| | | #include "../base/EventRegistry.h" |
| | | #include "../base/FileUtils.hpp" |
| | | #include "../base/StringUtils.h" |
| | | |
| | | #include "ExternalDefinition.hpp" |
| | | |
| | | namespace license { |
| | | namespace locate { |
| | | using namespace std; |
| | | |
| | | ExternalDefinition::ExternalDefinition(const char *location) : |
| | | ExternalDefinition::ExternalDefinition(const LicenseLocation *location) : |
| | | LocatorStrategy("ExternalDefinition"), m_location(location) { |
| | | } |
| | | |
| | | ExternalDefinition::~ExternalDefinition() { |
| | | } |
| | | |
| | | const std::vector<std::string> ExternalDefinition::licenseLocations( |
| | | EventRegistry &eventRegistry) const { |
| | | const vector<string> declared_positions = license::split_string(m_location, |
| | | ';'); |
| | | const vector<string> existing_pos = license::filter_existing_files( |
| | | declared_positions); |
| | | if (existing_pos.size() > 0) { |
| | | for (auto it = existing_pos.begin(); it != existing_pos.end(); ++it) { |
| | | eventRegistry.addEvent(LICENSE_FILE_FOUND, SVRT_INFO, *it); |
| | | const std::vector<std::string> ExternalDefinition::license_locations( |
| | | EventRegistry &eventRegistry) { |
| | | vector<string> existing_pos; |
| | | if (m_location->licenseData != nullptr |
| | | && m_location->licenseData[0] != '\0') { |
| | | eventRegistry.addEvent(LICENSE_SPECIFIED, get_strategy_name()); |
| | | FILE_FORMAT licenseFormat = identify_format(m_location->licenseData); |
| | | |
| | | if (licenseFormat == UNKNOWN) { |
| | | eventRegistry.addEvent(LICENSE_MALFORMED, get_strategy_name()); |
| | | } else { |
| | | existing_pos.push_back(get_strategy_name()); |
| | | licenseDataIsBase64 = (licenseFormat == BASE64); |
| | | } |
| | | } else { |
| | | eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND, SVRT_WARN, m_location); |
| | | } |
| | | if (m_location->licenseFileLocation != nullptr |
| | | && strlen(m_location->licenseFileLocation) > 0) { |
| | | const vector<string> declared_positions = license::split_string( |
| | | m_location->licenseFileLocation, ';'); |
| | | existing_pos = license::filter_existing_files(declared_positions, |
| | | eventRegistry, get_strategy_name().c_str()); |
| | | } |
| | | return existing_pos; |
| | | } |
| | | |
| | | const std::string ExternalDefinition::retrieve_license_content( |
| | | const std::string &licenseLocation) const { |
| | | if (licenseLocation == get_strategy_name()) { |
| | | if (licenseDataIsBase64) { |
| | | int flen = 0; |
| | | unsigned char *raw = unbase64(m_location->licenseData, |
| | | strlen(m_location->licenseData), &flen); |
| | | string str = string(reinterpret_cast<char*>(raw)); |
| | | free(raw); |
| | | return str; |
| | | } else { |
| | | return m_location->licenseData; |
| | | } |
| | | } else { |
| | | return LocatorStrategy::retrieve_license_content(licenseLocation); |
| | | } |
| | | } |
| | | |
| | | } /* namespace locate */ |
| | | } /* namespace license */ |
| | |
| | | |
| | | class ExternalDefinition: public LocatorStrategy { |
| | | private: |
| | | const std::string m_location; |
| | | const LicenseLocation* m_location; |
| | | bool licenseDataIsBase64 = false; |
| | | public: |
| | | ExternalDefinition(const char* location); |
| | | virtual const std::vector<std::string> licenseLocations(EventRegistry& eventRegistry) const; |
| | | ExternalDefinition(const LicenseLocation* location); |
| | | virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistry); |
| | | virtual const std::string retrieve_license_content(const std::string &licenseLocation) const; |
| | | virtual ~ExternalDefinition(); |
| | | }; |
| | | |
| | |
| | | #include "LocatorStrategy.hpp" |
| | | #include "LocatorFactory.hpp" |
| | | #include "ApplicationFolder.hpp" |
| | | //#include "EnvironmentVarData.hpp" |
| | | #include "EnvironmentVarData.hpp" |
| | | #include "EnvironmentVarLocation.hpp" |
| | | #include "ExternalDefinition.hpp" |
| | | |
| | | namespace license { |
| | | namespace locate { |
| | | |
| | | using namespace std; |
| | | |
| | | FUNCTION_RETURN LocatorFactory::getActiveStrategies( |
| | | vector<unique_ptr<LocatorStrategy>> &strategies, |
| | | const char *locationHint) { |
| | | FUNCTION_RETURN LocatorFactory::get_active_strategies( |
| | | std::vector<std::unique_ptr<LocatorStrategy>> &strategies, |
| | | const LicenseLocation *locationHint) { |
| | | #if(FIND_LICENSE_NEAR_MODULE) |
| | | strategies.push_back( |
| | | unique_ptr<LocatorStrategy>( |
| | | std::unique_ptr<LocatorStrategy>( |
| | | (LocatorStrategy*) new ApplicationFolder())); |
| | | #endif |
| | | #if(FIND_LICENSE_WITH_ENV_VAR) |
| | | strategies.push_back( |
| | | unique_ptr<LocatorStrategy>( |
| | | std::unique_ptr<LocatorStrategy>( |
| | | (LocatorStrategy*) new EnvironmentVarLocation())); |
| | | // strategies.push_back( |
| | | // unique_ptr<LocatorStrategy>( |
| | | // (LocatorStrategy*) new EnvironmentVarData())); |
| | | strategies.push_back( |
| | | std::unique_ptr<LocatorStrategy>( |
| | | (LocatorStrategy*) new EnvironmentVarData())); |
| | | #endif |
| | | if (locationHint != nullptr) { |
| | | strategies.push_back( |
| | | unique_ptr<LocatorStrategy>( |
| | | std::unique_ptr<LocatorStrategy>( |
| | | (LocatorStrategy*) new ExternalDefinition(locationHint))); |
| | | } |
| | | return strategies.size() > 0 ? FUNC_RET_OK : FUNC_RET_NOT_AVAIL; |
| | |
| | | #include <vector> |
| | | |
| | | #include "../base/base.h" |
| | | #include "../api/datatypes.h" |
| | | #include "LocatorStrategy.hpp" |
| | | |
| | | namespace license { |
| | |
| | | } |
| | | public: |
| | | |
| | | static FUNCTION_RETURN getActiveStrategies( |
| | | static FUNCTION_RETURN get_active_strategies( |
| | | std::vector<std::unique_ptr<LocatorStrategy>> &strategiesOut, |
| | | const char *locationHint); |
| | | const LicenseLocation *locationHint); |
| | | |
| | | }; |
| | | |
| | |
| | | namespace locate { |
| | | using namespace std; |
| | | |
| | | const string LocatorStrategy::retrieveLicense( |
| | | const string LocatorStrategy::retrieve_license_content( |
| | | const string &licenseLocation) const { |
| | | return get_file_contents(licenseLocation.c_str(), MAX_LICENSE_LENGTH); |
| | | } |
| | |
| | | virtual const std::string get_strategy_name() const { |
| | | return m_strategy_name; |
| | | } |
| | | |
| | | virtual const std::vector<std::string> licenseLocations( |
| | | EventRegistry &eventRegistry) const = 0; |
| | | /** |
| | | * Try to find licenses |
| | | * @param eventRegistry |
| | | * @return |
| | | * A list of identifiers for call retrieve_license_content. |
| | | */ |
| | | virtual const std::vector<std::string> license_locations( |
| | | EventRegistry &eventRegistry) = 0; |
| | | |
| | | /** |
| | | * Default implementation is to retrieve the license from file. |
| | | * Subclasses may override it. |
| | | * @param licenseLocation |
| | | * @param licenseLocationId |
| | | * String that identifies the license. It is usually the file name |
| | | * but can be whatever is understood by the class |
| | | * @return |
| | | * a string containing the license data in INI format. |
| | | */ |
| | | virtual const std::string retrieveLicense( |
| | | const std::string &licenseLocation) const; |
| | | virtual const std::string retrieve_license_content( |
| | | const std::string &licenseLocationId) const; |
| | | inline virtual ~LocatorStrategy() { |
| | | } |
| | | }; |
| | |
| | | * os-dependent.hpp |
| | | * |
| | | * Created on: Mar 29, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef OS_DEPENDENT_HPP_ |
| | |
| | | |
| | | FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64); |
| | | |
| | | #ifdef _WIN32 |
| | | #define SETENV(VAR,VAL) _putenv_s(VAR, VAL); |
| | | #define UNSETENV(P) _putenv_s(P, ""); |
| | | #else |
| | | #define SETENV(VAR,VAL) setenv(VAR, VAL, 1); |
| | | #define UNSETENV(P) unsetenv(P); |
| | | #endif |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | |
| | | /*
|
| | | * CryptoHelperWindows.cpp
|
| | | *
|
| | | * Created on: Sep 14, 2014
|
| | | *
|
| | | */
|
| | |
|
| | | #include <sstream> |
| | | #include <vector>
|
| | | #include <string>
|
| | | #include "CryptoHelperWindows.h"
|
| | | // The RSA public-key key exchange algorithm
|
| | | #define ENCRYPT_ALGORITHM CALG_RSA_SIGN
|
| | | // The high order WORD 0x0200 (decimal 512)
|
| | | // determines the key length in bits.
|
| | | #define KEYLENGTH 0x02000000
|
| | | #pragma comment(lib, "crypt32.lib")
|
| | |
|
| | | namespace license {
|
| | |
|
| | | CryptoHelperWindows::CryptoHelperWindows() {
|
| | | m_hCryptProv = NULL;
|
| | | m_hCryptKey = NULL;
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, 0)) {
|
| | | // If the key container cannot be opened, try creating a new
|
| | | // container by specifying a container name and setting the
|
| | | // CRYPT_NEWKEYSET flag.
|
| | | DWORD lastError = GetLastError();
|
| | | printf("Error in CryptAcquireContext (1) 0x%08x \n", lastError);
|
| | | if (NTE_BAD_KEYSET == lastError) {
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
|
| | | printf("Warn in CryptAcquireContext: acquiring new user keyset failed 0x%08x, trying less secure mackine keyset \n", GetLastError());
|
| | | //maybe access to protected storage disabled. Try with machine keys (less secure)
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) {
|
| | | printf("Error in CryptAcquireContext (2) 0x%08x \n", GetLastError());
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)) {
|
| | | printf("Error in CryptAcquireContext (3): acquiring new keyset(machine) failed 0x%08x \n", GetLastError());
|
| | | throw logic_error("");
|
| | | }
|
| | | }
|
| | | }
|
| | | } else {
|
| | | printf(" Error in CryptAcquireContext (4) 0x%08x \n", lastError);
|
| | | throw logic_error("");
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | /**
|
| | | This method calls the CryptGenKey function to get a handle to an
|
| | |
|
| | | exportable key-pair. The key-pair is generated with the RSA public-key
|
| | | key exchange algorithm using Microsoft Enhanced Cryptographic Provider.
|
| | | */
|
| | | void CryptoHelperWindows::generateKeyPair() {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | // If the handle to key container is NULL, fail.
|
| | | if (m_hCryptProv == NULL)
|
| | | throw logic_error("Cryptocontext not correctly initialized");
|
| | | // Release a previously acquired handle to key-pair.
|
| | | if (m_hCryptKey)
|
| | | m_hCryptKey = NULL;
|
| | | // Call the CryptGenKey method to get a handle
|
| | | // to a new exportable key-pair.
|
| | | if (!CryptGenKey(m_hCryptProv, ENCRYPT_ALGORITHM,
|
| | | KEYLENGTH | CRYPT_EXPORTABLE, &m_hCryptKey)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error generating keys ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | //double check the key is really generated
|
| | | if(m_hCryptKey == NULL) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error generating keys (2)")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | }
|
| | |
|
| | | /* This method calls the CryptExportKey function to get the Public key
|
| | | in a string suitable for C source inclusion.
|
| | | */
|
| | | const string CryptoHelperWindows::exportPublicKey() const {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | DWORD dwBlobLen;
|
| | | BYTE *pbKeyBlob = nullptr;
|
| | | stringstream ss;
|
| | | // If the handle to key container is NULL, fail.
|
| | | if (m_hCryptKey == NULL)
|
| | | throw logic_error("call GenerateKey first.");
|
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PUBLICKEYBLOB, 0, nullptr, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error calculating size of public key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) {
|
| | | throw logic_error(string("Out of memory exporting public key "));
|
| | | }
|
| | | // Do the actual exporting into the key BLOB.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) {
|
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error exporting public key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++) {
|
| | | if (i != 0) {
|
| | | ss << ", ";
|
| | | if (i % 10 == 0) {
|
| | | ss << "\\" << endl << "\t";
|
| | | }
|
| | | }
|
| | | ss << to_string(static_cast<long long>(pbKeyBlob[i]));
|
| | | }
|
| | | delete pbKeyBlob;
|
| | | }
|
| | | return ss.str();
|
| | | }
|
| | |
|
| | | CryptoHelperWindows::~CryptoHelperWindows() {
|
| | | if (m_hCryptProv) {
|
| | | CryptReleaseContext(m_hCryptProv, 0);
|
| | | m_hCryptProv = NULL;
|
| | | }
|
| | | if (m_hCryptKey)
|
| | | m_hCryptKey = NULL;
|
| | | }
|
| | |
|
| | | //--------------------------------------------------------------------
|
| | | // This method calls the CryptExportKey function to get the Private key
|
| | | // in a byte array. The byte array is allocated on the heap and the size
|
| | | // of this is returned to the caller. The caller is responsible for releasing // this memory using a delete call.
|
| | | //--------------------------------------------------------------------
|
| | | const string CryptoHelperWindows::exportPrivateKey() const {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | DWORD dwBlobLen;
|
| | | BYTE *pbKeyBlob;
|
| | | stringstream ss;
|
| | | // If the handle to key container is NULL, fail.
|
| | | if (m_hCryptKey == NULL)
|
| | | throw logic_error(string("call GenerateKey first."));
|
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PRIVATEKEYBLOB, 0, nullptr, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error calculating size of private key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) {
|
| | | throw logic_error(string("Out of memory exporting private key "));
|
| | | }
|
| | |
|
| | | // Do the actual exporting into the key BLOB.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) {
|
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error exporting private key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++) {
|
| | | if (i != 0) {
|
| | | ss << ", ";
|
| | | if (i % 15 == 0) {
|
| | | ss << "\\" << endl << "\t";
|
| | | }
|
| | | }
|
| | | ss << to_string(static_cast<long long>(pbKeyBlob[i]));
|
| | | }
|
| | | delete pbKeyBlob;
|
| | | }
|
| | | return ss.str();
|
| | | }
|
| | |
|
| | | void CryptoHelperWindows::printHash(HCRYPTHASH *hHash) const {
|
| | | BYTE *pbHash;
|
| | | DWORD dwHashLen;
|
| | | DWORD dwHashLenSize = sizeof(DWORD);
|
| | | char *hashStr;
|
| | | unsigned int i;
|
| | |
|
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE*) &dwHashLen,
|
| | | &dwHashLenSize, 0)) {
|
| | | pbHash = (BYTE*) malloc(dwHashLen);
|
| | | hashStr = (char*) malloc(dwHashLen * 2 + 1);
|
| | | if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) {
|
| | | for (i = 0; i < dwHashLen; i++) {
|
| | | sprintf(&hashStr[i * 2], "%02x", pbHash[i]);
|
| | | }
|
| | | printf("hash To be signed: %s \n", hashStr);
|
| | | }
|
| | | free(pbHash);
|
| | | free(hashStr);
|
| | | }
|
| | | }
|
| | |
|
| | | const string CryptoHelperWindows::signString(const void *privateKey,
|
| | | size_t pklen, const string &license) const {
|
| | | BYTE *pbBuffer = (BYTE*) license.c_str();
|
| | | const DWORD dwBufferLen = (DWORD) strlen((char*) pbBuffer);
|
| | | HCRYPTHASH hHash;
|
| | |
|
| | | HCRYPTKEY hKey;
|
| | | BYTE *pbSignature;
|
| | | DWORD dwSigLen;
|
| | | DWORD strLen;
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Acquire a cryptographic provider context handle.
|
| | |
|
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE*) privateKey, (DWORD) pklen,
|
| | | 0, 0, &hKey)) {
|
| | | throw logic_error(
|
| | | string("Error in importing the PrivateKey ")
|
| | | + to_string(static_cast<long long>(GetLastError())));
|
| | | }
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Create the hash object.
|
| | |
|
| | | if (CryptCreateHash(m_hCryptProv, CALG_SHA1, 0, 0, &hHash)) {
|
| | | printf("Hash object created. \n");
|
| | | } else {
|
| | | CryptDestroyKey(hKey);
|
| | | throw logic_error(string("Error during CryptCreateHash."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Compute the cryptographic hash of the buffer.
|
| | |
|
| | | if (CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) {
|
| | | #ifdef _DEBUG
|
| | | printf("Length of data to be hashed: %d \n", dwBufferLen);
|
| | | printHash(&hHash);
|
| | | #endif |
| | | } else {
|
| | | throw logic_error(string("Error during CryptHashData."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Determine the size of the signature and allocate memory.
|
| | |
|
| | | dwSigLen = 0;
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, nullptr, &dwSigLen)) {
|
| | | printf("Signature length %d found.\n", dwSigLen);
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptSignHash."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Allocate memory for the signature buffer.
|
| | |
|
| | | if (pbSignature = (BYTE*) malloc(dwSigLen)) {
|
| | | printf("Memory allocated for the signature.\n");
|
| | | } else {
|
| | | throw logic_error(string("Out of memory."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Sign the hash object.
|
| | |
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, pbSignature,
|
| | | &dwSigLen)) {
|
| | | printf("pbSignature is the signature length. %d\n", dwSigLen);
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptSignHash."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Destroy the hash object.
|
| | |
|
| | | CryptDestroyHash(hHash);
|
| | | CryptDestroyKey(hKey);
|
| | |
|
| | | CryptBinaryToString(pbSignature, dwSigLen,
|
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &strLen);
|
| | | vector<char> buffer(strLen);
|
| | | CryptBinaryToString(pbSignature, dwSigLen,
|
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &buffer[0], &strLen);
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // In the second phase, the hash signature is verified.
|
| | | // This would most often be done by a different user in a
|
| | | // separate program. The hash, signature, and the PUBLICKEYBLOB
|
| | | // would be read from a file, an email message,
|
| | | // or some other source.
|
| | |
|
| | | // Here, the original pbBuffer, pbSignature, szDescription.
|
| | | // pbKeyBlob, and their lengths are used.
|
| | |
|
| | | // The contents of the pbBuffer must be the same data
|
| | | // that was originally signed.
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Get the public key of the user who created the digital signature
|
| | | // and import it into the CSP by using CryptImportKey. This returns
|
| | | // a handle to the public key in hPubKey.
|
| | |
|
| | | /*if (CryptImportKey(
|
| | | hProv,
|
| | | pbKeyBlob,
|
| | | dwBlobLen,
|
| | | 0,
|
| | | 0,
|
| | | &hPubKey))
|
| | | {
|
| | | printf("The key has been imported.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Public key import failed.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Create a new hash object.
|
| | |
|
| | | if (CryptCreateHash(
|
| | | hProv,
|
| | | CALG_MD5,
|
| | | 0,
|
| | | 0,
|
| | | &hHash))
|
| | | {
|
| | | printf("The hash object has been recreated. \n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Error during CryptCreateHash.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Compute the cryptographic hash of the buffer.
|
| | |
|
| | | if (CryptHashData(
|
| | | hHash,
|
| | | pbBuffer,
|
| | | dwBufferLen,
|
| | | 0))
|
| | | {
|
| | | printf("The new hash has been created.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Error during CryptHashData.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Validate the digital signature.
|
| | |
|
| | | if (CryptVerifySignature(
|
| | | hHash,
|
| | | pbSignature,
|
| | | dwSigLen,
|
| | | hPubKey,
|
| | | NULL,
|
| | | 0))
|
| | | {
|
| | | printf("The signature has been verified.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | printf("Signature not validated!\n");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Free memory to be used to store signature.
|
| | |
|
| | |
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Destroy the hash object.
|
| | |
|
| | |
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Release the provider handle.
|
| | |
|
| | | /*if (hProv)
|
| | | CryptReleaseContext(hProv, 0);*/
|
| | | if (pbSignature) {
|
| | | free(pbSignature);
|
| | | }
|
| | | return string(&buffer[0]);
|
| | | }
|
| | | } /* namespace license */
|
| | | /* |
| | | * CryptoHelperWindows.cpp |
| | | * |
| | | * Created on: Sep 14, 2014 |
| | | * |
| | | */ |
| | | |
| | | #include <sstream> |
| | | #include <vector> |
| | | #include <string> |
| | | #include "CryptoHelperWindows.h" |
| | | // The RSA public-key key exchange algorithm |
| | | #define ENCRYPT_ALGORITHM CALG_RSA_SIGN |
| | | // The high order WORD 0x0200 (decimal 512) |
| | | // determines the key length in bits. |
| | | #define KEYLENGTH 0x02000000 |
| | | #pragma comment(lib, "crypt32.lib") |
| | | |
| | | namespace license { |
| | | |
| | | CryptoHelperWindows::CryptoHelperWindows() { |
| | | m_hCryptProv = NULL; |
| | | m_hCryptKey = NULL; |
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, 0)) { |
| | | // If the key container cannot be opened, try creating a new |
| | | // container by specifying a container name and setting the |
| | | // CRYPT_NEWKEYSET flag. |
| | | DWORD lastError = GetLastError(); |
| | | printf("Error in CryptAcquireContext (1) 0x%08x \n", lastError); |
| | | if (NTE_BAD_KEYSET == lastError) { |
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, CRYPT_NEWKEYSET)) { |
| | | printf("Warn in CryptAcquireContext: acquiring new user keyset failed 0x%08x, trying less secure mackine keyset \n", GetLastError()); |
| | | //maybe access to protected storage disabled. Try with machine keys (less secure) |
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) { |
| | | printf("Error in CryptAcquireContext (2) 0x%08x \n", GetLastError()); |
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)) { |
| | | printf("Error in CryptAcquireContext (3): acquiring new keyset(machine) failed 0x%08x \n", GetLastError()); |
| | | throw logic_error(""); |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | printf(" Error in CryptAcquireContext (4) 0x%08x \n", lastError); |
| | | throw logic_error(""); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | This method calls the CryptGenKey function to get a handle to an |
| | | |
| | | exportable key-pair. The key-pair is generated with the RSA public-key |
| | | key exchange algorithm using Microsoft Enhanced Cryptographic Provider. |
| | | */ |
| | | void CryptoHelperWindows::generateKeyPair() { |
| | | HRESULT hr = S_OK; |
| | | DWORD dwErrCode; |
| | | // If the handle to key container is NULL, fail. |
| | | if (m_hCryptProv == NULL) |
| | | throw logic_error("Cryptocontext not correctly initialized"); |
| | | // Release a previously acquired handle to key-pair. |
| | | if (m_hCryptKey) |
| | | m_hCryptKey = NULL; |
| | | // Call the CryptGenKey method to get a handle |
| | | // to a new exportable key-pair. |
| | | if (!CryptGenKey(m_hCryptProv, ENCRYPT_ALGORITHM, |
| | | KEYLENGTH | CRYPT_EXPORTABLE, &m_hCryptKey)) { |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error generating keys ") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } |
| | | //double check the key is really generated |
| | | if(m_hCryptKey == NULL) { |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error generating keys (2)") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } |
| | | } |
| | | |
| | | /* This method calls the CryptExportKey function to get the Public key |
| | | in a string suitable for C source inclusion. |
| | | */ |
| | | const string CryptoHelperWindows::exportPublicKey() const { |
| | | HRESULT hr = S_OK; |
| | | DWORD dwErrCode; |
| | | DWORD dwBlobLen; |
| | | BYTE *pbKeyBlob = nullptr; |
| | | stringstream ss; |
| | | // If the handle to key container is NULL, fail. |
| | | if (m_hCryptKey == NULL) |
| | | throw logic_error("call GenerateKey first."); |
| | | // This call here determines the length of the key |
| | | // blob. |
| | | if (!CryptExportKey(m_hCryptKey, |
| | | NULL, PUBLICKEYBLOB, 0, nullptr, &dwBlobLen)) { |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error calculating size of public key ") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } |
| | | // Allocate memory for the pbKeyBlob. |
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) { |
| | | throw logic_error(string("Out of memory exporting public key ")); |
| | | } |
| | | // Do the actual exporting into the key BLOB. |
| | | if (!CryptExportKey(m_hCryptKey, |
| | | NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { |
| | | delete pbKeyBlob; |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error exporting public key ") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } else { |
| | | ss << "\t"; |
| | | for (unsigned int i = 0; i < dwBlobLen; i++) { |
| | | if (i != 0) { |
| | | ss << ", "; |
| | | if (i % 10 == 0) { |
| | | ss << "\\" << endl << "\t"; |
| | | } |
| | | } |
| | | ss << to_string(static_cast<long long>(pbKeyBlob[i])); |
| | | } |
| | | delete pbKeyBlob; |
| | | } |
| | | return ss.str(); |
| | | } |
| | | |
| | | CryptoHelperWindows::~CryptoHelperWindows() { |
| | | if (m_hCryptProv) { |
| | | CryptReleaseContext(m_hCryptProv, 0); |
| | | m_hCryptProv = NULL; |
| | | } |
| | | if (m_hCryptKey) |
| | | m_hCryptKey = NULL; |
| | | } |
| | | |
| | | //-------------------------------------------------------------------- |
| | | // This method calls the CryptExportKey function to get the Private key |
| | | // in a byte array. The byte array is allocated on the heap and the size |
| | | // of this is returned to the caller. The caller is responsible for releasing // this memory using a delete call. |
| | | //-------------------------------------------------------------------- |
| | | const string CryptoHelperWindows::exportPrivateKey() const { |
| | | HRESULT hr = S_OK; |
| | | DWORD dwErrCode; |
| | | DWORD dwBlobLen; |
| | | BYTE *pbKeyBlob; |
| | | stringstream ss; |
| | | // If the handle to key container is NULL, fail. |
| | | if (m_hCryptKey == NULL) |
| | | throw logic_error(string("call GenerateKey first.")); |
| | | // This call here determines the length of the key |
| | | // blob. |
| | | if (!CryptExportKey(m_hCryptKey, |
| | | NULL, PRIVATEKEYBLOB, 0, nullptr, &dwBlobLen)) { |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error calculating size of private key ") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } |
| | | // Allocate memory for the pbKeyBlob. |
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) { |
| | | throw logic_error(string("Out of memory exporting private key ")); |
| | | } |
| | | |
| | | // Do the actual exporting into the key BLOB. |
| | | if (!CryptExportKey(m_hCryptKey, |
| | | NULL, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { |
| | | delete pbKeyBlob; |
| | | dwErrCode = GetLastError(); |
| | | throw logic_error( |
| | | string("Error exporting private key ") |
| | | + to_string(static_cast<long long>(dwErrCode))); |
| | | } else { |
| | | ss << "\t"; |
| | | for (unsigned int i = 0; i < dwBlobLen; i++) { |
| | | if (i != 0) { |
| | | ss << ", "; |
| | | if (i % 15 == 0) { |
| | | ss << "\\" << endl << "\t"; |
| | | } |
| | | } |
| | | ss << to_string(static_cast<long long>(pbKeyBlob[i])); |
| | | } |
| | | delete pbKeyBlob; |
| | | } |
| | | return ss.str(); |
| | | } |
| | | |
| | | void CryptoHelperWindows::printHash(HCRYPTHASH *hHash) const { |
| | | BYTE *pbHash; |
| | | DWORD dwHashLen; |
| | | DWORD dwHashLenSize = sizeof(DWORD); |
| | | char *hashStr; |
| | | unsigned int i; |
| | | |
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE*) &dwHashLen, |
| | | &dwHashLenSize, 0)) { |
| | | pbHash = (BYTE*) malloc(dwHashLen); |
| | | hashStr = (char*) malloc(dwHashLen * 2 + 1); |
| | | if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { |
| | | for (i = 0; i < dwHashLen; i++) { |
| | | sprintf(&hashStr[i * 2], "%02x", pbHash[i]); |
| | | } |
| | | printf("hash To be signed: %s \n", hashStr); |
| | | } |
| | | free(pbHash); |
| | | free(hashStr); |
| | | } |
| | | } |
| | | |
| | | const string CryptoHelperWindows::signString(const void *privateKey, |
| | | size_t pklen, const string &license) const { |
| | | BYTE *pbBuffer = (BYTE*) license.c_str(); |
| | | const DWORD dwBufferLen = (DWORD) strlen((char*) pbBuffer); |
| | | HCRYPTHASH hHash; |
| | | |
| | | HCRYPTKEY hKey; |
| | | BYTE *pbSignature; |
| | | DWORD dwSigLen; |
| | | DWORD strLen; |
| | | |
| | | //------------------------------------------------------------------- |
| | | // Acquire a cryptographic provider context handle. |
| | | |
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE*) privateKey, (DWORD) pklen, |
| | | 0, 0, &hKey)) { |
| | | throw logic_error( |
| | | string("Error in importing the PrivateKey ") |
| | | + to_string(static_cast<long long>(GetLastError()))); |
| | | } |
| | | |
| | | //------------------------------------------------------------------- |
| | | // Create the hash object. |
| | | |
| | | if (CryptCreateHash(m_hCryptProv, CALG_SHA1, 0, 0, &hHash)) { |
| | | printf("Hash object created. \n"); |
| | | } else { |
| | | CryptDestroyKey(hKey); |
| | | throw logic_error(string("Error during CryptCreateHash.")); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Compute the cryptographic hash of the buffer. |
| | | |
| | | if (CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) { |
| | | #ifdef _DEBUG |
| | | printf("Length of data to be hashed: %d \n", dwBufferLen); |
| | | printHash(&hHash); |
| | | #endif |
| | | } else { |
| | | throw logic_error(string("Error during CryptHashData.")); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Determine the size of the signature and allocate memory. |
| | | |
| | | dwSigLen = 0; |
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, nullptr, &dwSigLen)) { |
| | | printf("Signature length %d found.\n", dwSigLen); |
| | | } else { |
| | | throw logic_error(string("Error during CryptSignHash.")); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Allocate memory for the signature buffer. |
| | | |
| | | if (pbSignature = (BYTE*) malloc(dwSigLen)) { |
| | | printf("Memory allocated for the signature.\n"); |
| | | } else { |
| | | throw logic_error(string("Out of memory.")); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Sign the hash object. |
| | | |
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, pbSignature, |
| | | &dwSigLen)) { |
| | | printf("pbSignature is the signature length. %d\n", dwSigLen); |
| | | } else { |
| | | throw logic_error(string("Error during CryptSignHash.")); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Destroy the hash object. |
| | | |
| | | CryptDestroyHash(hHash); |
| | | CryptDestroyKey(hKey); |
| | | |
| | | CryptBinaryToString(pbSignature, dwSigLen, |
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &strLen); |
| | | vector<char> buffer(strLen); |
| | | CryptBinaryToString(pbSignature, dwSigLen, |
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &buffer[0], &strLen); |
| | | |
| | | //------------------------------------------------------------------- |
| | | // In the second phase, the hash signature is verified. |
| | | // This would most often be done by a different user in a |
| | | // separate program. The hash, signature, and the PUBLICKEYBLOB |
| | | // would be read from a file, an email message, |
| | | // or some other source. |
| | | |
| | | // Here, the original pbBuffer, pbSignature, szDescription. |
| | | // pbKeyBlob, and their lengths are used. |
| | | |
| | | // The contents of the pbBuffer must be the same data |
| | | // that was originally signed. |
| | | |
| | | //------------------------------------------------------------------- |
| | | // Get the public key of the user who created the digital signature |
| | | // and import it into the CSP by using CryptImportKey. This returns |
| | | // a handle to the public key in hPubKey. |
| | | |
| | | /*if (CryptImportKey( |
| | | hProv, |
| | | pbKeyBlob, |
| | | dwBlobLen, |
| | | 0, |
| | | 0, |
| | | &hPubKey)) |
| | | { |
| | | printf("The key has been imported.\n"); |
| | | } |
| | | else |
| | | { |
| | | MyHandleError("Public key import failed."); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Create a new hash object. |
| | | |
| | | if (CryptCreateHash( |
| | | hProv, |
| | | CALG_MD5, |
| | | 0, |
| | | 0, |
| | | &hHash)) |
| | | { |
| | | printf("The hash object has been recreated. \n"); |
| | | } |
| | | else |
| | | { |
| | | MyHandleError("Error during CryptCreateHash."); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Compute the cryptographic hash of the buffer. |
| | | |
| | | if (CryptHashData( |
| | | hHash, |
| | | pbBuffer, |
| | | dwBufferLen, |
| | | 0)) |
| | | { |
| | | printf("The new hash has been created.\n"); |
| | | } |
| | | else |
| | | { |
| | | MyHandleError("Error during CryptHashData."); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Validate the digital signature. |
| | | |
| | | if (CryptVerifySignature( |
| | | hHash, |
| | | pbSignature, |
| | | dwSigLen, |
| | | hPubKey, |
| | | NULL, |
| | | 0)) |
| | | { |
| | | printf("The signature has been verified.\n"); |
| | | } |
| | | else |
| | | { |
| | | printf("Signature not validated!\n"); |
| | | } |
| | | //------------------------------------------------------------------- |
| | | // Free memory to be used to store signature. |
| | | |
| | | |
| | | |
| | | //------------------------------------------------------------------- |
| | | // Destroy the hash object. |
| | | |
| | | |
| | | |
| | | //------------------------------------------------------------------- |
| | | // Release the provider handle. |
| | | |
| | | /*if (hProv) |
| | | CryptReleaseContext(hProv, 0);*/ |
| | | if (pbSignature) { |
| | | free(pbSignature); |
| | | } |
| | | return string(&buffer[0]); |
| | | } |
| | | } /* namespace license */ |
| | |
| | | /*
|
| | | * CryptoHelperWindows.h
|
| | | *
|
| | | * Created on: Sep 14, 2014
|
| | | *
|
| | | */
|
| | |
|
| | | #ifndef CRYPTOHELPERWINDOWS_H_
|
| | | #define CRYPTOHELPERWINDOWS_H_
|
| | |
|
| | | //#define _WIN32_WINNT 0x0400
|
| | | #include <windows.h>
|
| | | #include <wincrypt.h>
|
| | | #include <tchar.h>
|
| | | #include <string>
|
| | | #include "../CryptoHelper.h"
|
| | |
|
| | |
|
| | |
|
| | | namespace license {
|
| | | using namespace std;
|
| | |
|
| | | class CryptoHelperWindows: public CryptoHelper {
|
| | | private :
|
| | | void acquireContext();
|
| | | // Handle to the cryptography provider.
|
| | | HCRYPTPROV m_hCryptProv;
|
| | | // Handle to the cryptography key.
|
| | | HCRYPTKEY m_hCryptKey;
|
| | | void printHash(HCRYPTHASH* hHash) const;
|
| | | public:
|
| | | CryptoHelperWindows();
|
| | |
|
| | | virtual void generateKeyPair();
|
| | | virtual const string exportPrivateKey() const;
|
| | | virtual const string exportPublicKey() const;
|
| | |
|
| | | virtual const string signString(const void* privateKey, size_t pklen,
|
| | | const string& license) const;
|
| | |
|
| | | virtual ~CryptoHelperWindows();
|
| | | };
|
| | |
|
| | | } /* namespace license */
|
| | |
|
| | | #endif /* CRYPTOHELPERWINDOWS_H_ */
|
| | | /* |
| | | * CryptoHelperWindows.h |
| | | * |
| | | * Created on: Sep 14, 2014 |
| | | * |
| | | */ |
| | | |
| | | #ifndef CRYPTOHELPERWINDOWS_H_ |
| | | #define CRYPTOHELPERWINDOWS_H_ |
| | | |
| | | //#define _WIN32_WINNT 0x0400 |
| | | #include <windows.h> |
| | | #include <wincrypt.h> |
| | | #include <tchar.h> |
| | | #include <string> |
| | | #include "../CryptoHelper.h" |
| | | |
| | | |
| | | |
| | | namespace license { |
| | | using namespace std; |
| | | |
| | | class CryptoHelperWindows: public CryptoHelper { |
| | | private : |
| | | void acquireContext(); |
| | | // Handle to the cryptography provider. |
| | | HCRYPTPROV m_hCryptProv; |
| | | // Handle to the cryptography key. |
| | | HCRYPTKEY m_hCryptKey; |
| | | void printHash(HCRYPTHASH* hHash) const; |
| | | public: |
| | | CryptoHelperWindows(); |
| | | |
| | | virtual void generateKeyPair(); |
| | | virtual const string exportPrivateKey() const; |
| | | virtual const string exportPublicKey() const; |
| | | |
| | | virtual const string signString(const void* privateKey, size_t pklen, |
| | | const string& license) const; |
| | | |
| | | virtual ~CryptoHelperWindows(); |
| | | }; |
| | | |
| | | } /* namespace license */ |
| | | |
| | | #endif /* CRYPTOHELPERWINDOWS_H_ */ |
| | |
| | | target_link_libraries( |
| | | license_generator_lib |
| | | tools_base |
| | | base |
| | | licensecc_static |
| | | $<$<CONFIG:Debug>:${Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG}> |
| | | $<$<NOT:$<CONFIG:Debug>>:${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE}> |
| | |
| | | #include <build_properties.h> |
| | | #include <private-key.h> |
| | | #include "license-generator.h" |
| | | #include "../base_lib/CryptoHelper.h" |
| | | |
| | | #include <stddef.h> |
| | | #include <stdlib.h> |
| | | #include <stdio.h> |
| | | #include <cerrno> |
| | | #include <cstdio> |
| | | #include <cstring> |
| | | #include <ctime> |
| | | #include <fstream> |
| | | #include <iomanip> |
| | | #include <iostream> |
| | | #include <string.h> |
| | | #include <iostream> |
| | | #include <string.h> |
| | | #include <boost/date_time.hpp> |
| | | #include <iterator> |
| | | #include <map> |
| | | #include <memory> |
| | | #include <regex> |
| | | #include <sstream> |
| | | #include <stdexcept> |
| | | #include <string> |
| | | #include <vector> |
| | | #include <boost/program_options.hpp> |
| | | #include <boost/algorithm/string.hpp> |
| | | #include <boost/unordered_map.hpp> |
| | | #include <boost/assign.hpp> |
| | | #include <fstream> |
| | | #include <regex> |
| | | #include <boost/filesystem.hpp> |
| | | |
| | | namespace fs = boost::filesystem; |
| | | namespace bt = boost::posix_time; |
| | | #include <private-key.h> |
| | | #include <build_properties.h> |
| | | #include "../../library/base/base64.h" |
| | | #include "../base_lib/CryptoHelper.h" |
| | | |
| | | //namespace fs = boost::filesystem; |
| | | //namespace bt = boost::posix_time; |
| | | namespace po = boost::program_options; |
| | | |
| | | using namespace std; |
| | | |
| | | namespace license { |
| | | |
| | | void LicenseGenerator::printHelp(const char* prog_name, |
| | | const po::options_description& options) { |
| | | void LicenseGenerator::printHelp(const char *prog_name, |
| | | const po::options_description &options) { |
| | | cout << endl; |
| | | cout << prog_name << " Version " << PROJECT_VERSION << endl << ". Usage:" |
| | | << endl; |
| | |
| | | |
| | | po::options_description LicenseGenerator::configureProgramOptions() { |
| | | po::options_description common("General options"); |
| | | common.add_options() |
| | | ("help,h", "print help message and exit.") |
| | | ("verbose,v", "print more information.") |
| | | ("output,o", po::value<string>(), "Output file name. If not specified the " |
| | | "license will be printed in standard output") |
| | | ; |
| | | common.add_options()("help,h", "print help message and exit.") // |
| | | ("verbose,v", "print more information.")// |
| | | |
| | | ("output,o", po::value<string>(), "Output file name. If not specified the " |
| | | "license will be printed to standard output"); |
| | | po::options_description licenseGeneration("License Generation"); |
| | | licenseGeneration.add_options() |
| | | ("private_key,p", po::value<string>(), |
| | | licenseGeneration.add_options()("private_key,p", po::value<string>(), |
| | | "Specify an alternate file for the primary key to be used. " |
| | | "If not specified the internal primary key will be used.") |
| | | ("begin_date,b", po::value<string>(), |
| | | "If not specified the internal primary key will be used.")( |
| | | "begin_date,b", po::value<string>(), |
| | | "Specify the start of the validity for this license. " |
| | | " Format YYYYMMDD. If not specified defaults to today") |
| | | ("expire_date,e", po::value<string>(), |
| | | " Format YYYYMMDD. If not specified defaults to today")( |
| | | "expire_date,e", po::value<string>(), |
| | | "Specify the expire date for this license. " |
| | | " Format YYYYMMDD. If not specified the license won't expire") |
| | | ("client_signature,s", po::value<string>(), |
| | | " Format YYYYMMDD. If not specified the license won't expire")( |
| | | "client_signature,s", po::value<string>(), |
| | | "The signature of the pc that requires the license. " |
| | | "It should be in the format XXXX-XXXX-XXXX-XXXX." |
| | | " If not specified the license " |
| | | "won't be linked to a specific pc.") |
| | | ("start_version,t", po::value<unsigned int>()->default_value(0 |
| | | "won't be linked to a specific pc.")("start_version,t", |
| | | po::value<unsigned int>()->default_value(0 |
| | | /*FullLicenseInfo.UNUSED_SOFTWARE_VERSION*/, "All Versions"), |
| | | "Specify the first version of the software this license apply to.") |
| | | ("end_version,n", po::value<unsigned int>()->default_value(0 |
| | | "Specify the first version of the software this license apply to.")( |
| | | "end_version,n", po::value<unsigned int>()->default_value(0 |
| | | /*FullLicenseInfo.UNUSED_SOFTWARE_VERSION*/, "All Versions"), |
| | | "Specify the last version of the software this license apply to.") |
| | | ("extra_data,x", po::value<string>(), "Specify extra data to be included into the license") |
| | | ; |
| | | "Specify the last version of the software this license apply to.")( |
| | | "extra_data,x", po::value<string>(), |
| | | "Specify extra data to be included into the license"); |
| | | po::options_description visibleOptions; |
| | | visibleOptions.add(common).add(licenseGeneration); |
| | | return visibleOptions; |
| | | } |
| | | |
| | | vector<FullLicenseInfo> LicenseGenerator::parseLicenseInfo( |
| | | const po::variables_map& vm) { |
| | | const po::variables_map &vm) { |
| | | string begin_date = FullLicenseInfo::UNUSED_TIME; |
| | | string end_date = FullLicenseInfo::UNUSED_TIME; |
| | | if (vm.count("expire_date")) { |
| | |
| | | if (vm.count("client_signature")) { |
| | | client_signature = vm["client_signature"].as<string>(); |
| | | cout << "cli sig:" << client_signature; |
| | | regex e("[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}"); |
| | | regex e( |
| | | "[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}"); |
| | | cout << "\nregex:"; |
| | | if (!regex_match(client_signature, e)) { |
| | | cerr << endl << "Client signature not recognized: " |
| | | << client_signature |
| | | << " Please enter a valid signature in format XXXX-XXXX-XXXX-XXXX" |
| | | << endl; |
| | | << client_signature |
| | | << " Please enter a valid signature in format XXXX-XXXX-XXXX-XXXX" |
| | | << endl; |
| | | exit(2); |
| | | } |
| | | } |
| | |
| | | return licInfo; |
| | | } |
| | | |
| | | void LicenseGenerator::generateAndOutputLicenses(const po::variables_map& vm, |
| | | ostream& outputFile) { |
| | | void LicenseGenerator::generateAndOutputLicenses(const po::variables_map &vm, |
| | | ostream &outputFile) { |
| | | vector<FullLicenseInfo> licenseInfo = parseLicenseInfo(vm); |
| | | const unique_ptr<CryptoHelper> helper = CryptoHelper::getInstance(); |
| | | const unsigned char pkey[] = PRIVATE_KEY; |
| | | const size_t len = sizeof(pkey); |
| | | for (auto it = licenseInfo.begin(); it != licenseInfo.end(); ++it) { |
| | | const string license = it->printForSign(); |
| | | const string signature = helper->signString((const void *)pkey,len,license); |
| | | const string signature = helper->signString((const void*) pkey, len, |
| | | license); |
| | | it->license_signature = signature; |
| | | it->printAsIni(outputFile); |
| | | } |
| | | } |
| | | |
| | | void LicenseGenerator::generateB64Licenses(const po::variables_map &vm, |
| | | ostream &outputFile) { |
| | | std::ostringstream tempStream; |
| | | generateAndOutputLicenses(vm, tempStream); |
| | | |
| | | std::string str = tempStream.str(); |
| | | const char *chr = str.c_str(); |
| | | int finalLenght; |
| | | char *encoded = base64(chr, str.length(), &finalLenght); |
| | | outputFile.write(encoded, finalLenght); |
| | | free(encoded); |
| | | } |
| | | |
| | | int LicenseGenerator::generateLicense(int argc, const char **argv) { |
| | |
| | | fstream ofstream(fname, std::ios::out | std::ios::app); |
| | | if (!ofstream.is_open()) { |
| | | cerr << "can't open file [" << fname << "] for output." << endl |
| | | << " error: " << strerror( errno); |
| | | << " error: " << strerror(errno) << endl; |
| | | exit(3); |
| | | } |
| | | generateAndOutputLicenses(vm, ofstream); |
| | | if (vm.count("base64")) { |
| | | generateB64Licenses(vm, ofstream); |
| | | } else { |
| | | generateAndOutputLicenses(vm, ofstream); |
| | | } |
| | | ofstream.close(); |
| | | } else { |
| | | generateAndOutputLicenses(vm, cout); |
| | | if (vm.count("base64")) { |
| | | generateB64Licenses(vm, cout); |
| | | } else { |
| | | generateAndOutputLicenses(vm, cout); |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | |
| | | const std::string formats[] = { "%4u-%2u-%2u", "%4u/%2u/%2u", "%4u%2u%2u" }; |
| | | const size_t formats_n = 3; |
| | | |
| | | string LicenseGenerator::normalize_date(const std::string& sDate) { |
| | | if(sDate.size()<8) |
| | | string LicenseGenerator::normalize_date(const std::string &sDate) { |
| | | if (sDate.size() < 8) |
| | | throw invalid_argument("Date string too small for known formats"); |
| | | unsigned int year, month, day; |
| | | bool found = false; |
| | | for (size_t i = 0; i < formats_n && !found; ++i) { |
| | | const int chread = sscanf(sDate.c_str(),formats[i].c_str(),&year,&month,&day); |
| | | if(chread==3) { |
| | | const int chread = sscanf(sDate.c_str(), formats[i].c_str(), &year, |
| | | &month, &day); |
| | | if (chread == 3) { |
| | | found = true; |
| | | break; |
| | | } |
| | | } |
| | | if(!found) |
| | | if (!found) |
| | | throw invalid_argument("Date string did not match a known format"); |
| | | ostringstream oss; |
| | | oss << year << "-" << setfill('0') << std::setw(2) << month << "-" << setfill('0') << std::setw(2) << day; |
| | | oss << year << "-" << setfill('0') << std::setw(2) << month << "-" |
| | | << setfill('0') << std::setw(2) << day; |
| | | return oss.str(); |
| | | } |
| | | } |
| | |
| | | * LicenseSigner.h |
| | | * |
| | | * Created on: Apr 6, 2014 |
| | | * |
| | | * |
| | | */ |
| | | |
| | | #ifndef LICENSE_GENERATOR_H_ |
| | | #define LICENSE_GENERATOR_H_ |
| | | |
| | | #include <boost/program_options.hpp> |
| | | |
| | | #include "../../library/LicenseReader.hpp" |
| | | |
| | | namespace license { |
| | |
| | | class LicenseGenerator { |
| | | private: |
| | | LicenseGenerator(); |
| | | |
| | | static void printHelp(const char* prog_name, const po::options_description& options); |
| | | static po::options_description configureProgramOptions(); |
| | | static vector<FullLicenseInfo> parseLicenseInfo(const po::variables_map& vm); |
| | | static std::vector<FullLicenseInfo> parseLicenseInfo(const po::variables_map& vm); |
| | | static void generateAndOutputLicenses(const po::variables_map& vm, |
| | | ostream& outputFile); |
| | | static string normalize_date(const std::string& s); |
| | | std::ostream& outputFile); |
| | | static void generateB64Licenses(const po::variables_map& vm, |
| | | std::ostream& outputFile); |
| | | static std::string normalize_date(const std::string& s); |
| | | public: |
| | | /** |
| | | * Available options: |
| | |
| | | ) |
| | | |
| | | add_executable( |
| | | standard_license_test |
| | | test_standard_license |
| | | standard-license_test.cpp |
| | | ) |
| | | |
| | | target_link_libraries( |
| | | standard_license_test |
| | | test_standard_license |
| | | licensecc_static |
| | | license_generator_snippet |
| | | ${Boost_LIBRARIES} |
| | |
| | | |
| | | IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING) |
| | | #binfmt_misc doesn't work in my system :( |
| | | ADD_TEST(NAME standard_license_test COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/standard_license_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_standard_license COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_date COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_volid COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ELSE() |
| | | ADD_TEST(NAME standard_license_test COMMAND standard_license_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ADD_TEST(NAME test_volid COMMAND test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) |
| | | ENDIF() |
| | |
| | | /* */ |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", licenseLocation, |
| | | licenseLocation.licenseData = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, |
| | | &license); |
| | | BOOST_CHECK_EQUAL(result, LICENSE_OK); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, true); |
| | |
| | | /* */ |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", licenseLocation, |
| | | licenseLocation.licenseData = nullptr; |
| | | BOOST_TEST_MESSAGE("before acquire license"); |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, |
| | | &license); |
| | | BOOST_CHECK_EQUAL(result, PRODUCT_EXPIRED); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, true); |
| | |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule=false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | licenseLocation.licenseData = ""; |
| | | EVENT_TYPE result = acquire_license("TEST", |
| | | licenseLocation, & license); |
| | | BOOST_CHECK_EQUAL(result, LICENSE_OK); |
| | |
| | | #define BOOST_TEST_MODULE standard_license_test |
| | | //#define BOOST_TEST_MAIN |
| | | //#define BOOST_TEST_DYN_LINK |
| | | #define BOOST_TEST_MODULE test_standard_license |
| | | |
| | | #include <boost/test/unit_test.hpp> |
| | | #include "../../src/tools/license-generator/license-generator.h" |
| | | #include "../../src/library/api/license++.h" |
| | |
| | | #include <boost/filesystem.hpp> |
| | | #include "../../src/library/ini/SimpleIni.h" |
| | | #include "generate-license.h" |
| | | #include "../../src/library/base/FileUtils.hpp" |
| | | |
| | | namespace test { |
| | | namespace fs = boost::filesystem; |
| | | using namespace license; |
| | | using namespace std; |
| | | |
| | | namespace test { |
| | | |
| | | BOOST_AUTO_TEST_CASE( standard_lic_file ) { |
| | | const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_license.lic"); |
| | |
| | | /* */ |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", licenseLocation, |
| | | licenseLocation.licenseData = nullptr; |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, |
| | | &license); |
| | | BOOST_CHECK_EQUAL(result, LICENSE_OK); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, false); |
| | | BOOST_CHECK_EQUAL(license.linked_to_pc, false); |
| | | } |
| | | |
| | | /** |
| | | * Pass the license data to the application. |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( b64_environment_variable ) { |
| | | const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_env_license.lic"); |
| | | const vector<string> extraArgs; |
| | | generate_license(licLocation, extraArgs); |
| | | const string licensestr(license::get_file_contents(licLocation.c_str(), MAX_LICENSE_LENGTH)); |
| | | /* */ |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.licenseFileLocation = nullptr; |
| | | licenseLocation.licenseData = licensestr.c_str(); |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, |
| | | &license); |
| | | BOOST_CHECK_EQUAL(result, LICENSE_OK); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, false); |
| | |
| | | |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", licenseLocation, |
| | | licenseLocation.licenseData = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, |
| | | &license); |
| | | BOOST_CHECK_EQUAL(result, IDENTIFIERS_MISMATCH); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, false); |
| | |
| | | |
| | | LicenseInfo license; |
| | | LicenseLocation licenseLocation; |
| | | licenseLocation.openFileNearModule = false; |
| | | licenseLocation.licenseFileLocation = licLocation.c_str(); |
| | | licenseLocation.environmentVariableName = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", licenseLocation, &license); |
| | | licenseLocation.licenseData = ""; |
| | | const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, &license); |
| | | BOOST_CHECK_EQUAL(result, LICENSE_OK); |
| | | BOOST_CHECK_EQUAL(license.has_expiry, false); |
| | | BOOST_CHECK_EQUAL(license.linked_to_pc, true); |
| | |
| | | ADD_TEST(NAME test_license_locator COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_license_locator) |
| | | ELSE() |
| | | ADD_TEST(NAME test_license_locator COMMAND test_license_locator) |
| | | ENDIF() |
| | | |
| | | ### LicenseLocator tests |
| | | add_executable( |
| | | test_event_registry |
| | | EventRegistry_test.cpp |
| | | ) |
| | | |
| | | target_link_libraries( |
| | | test_event_registry |
| | | base |
| | | ${Boost_LIBRARIES} |
| | | ) |
| | | |
| | | IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING) |
| | | ADD_TEST(NAME test_event_registry COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_event_registry) |
| | | ELSE() |
| | | ADD_TEST(NAME test_event_registry COMMAND test_event_registry) |
| | | ENDIF() |
New file |
| | |
| | | #define BOOST_TEST_MODULE "test_event_registry" |
| | | |
| | | #include <iostream> |
| | | #include <iterator> |
| | | |
| | | #include <fstream> |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | #include <boost/filesystem.hpp> |
| | | #include <boost/optional.hpp> |
| | | #include <boost/test/unit_test.hpp> |
| | | #include <stdlib.h> |
| | | #include <cstdio> |
| | | |
| | | #include <build_properties.h> |
| | | |
| | | #include "../../src/library/base/EventRegistry.h" |
| | | |
| | | namespace test { |
| | | |
| | | using namespace std; |
| | | using namespace license; |
| | | |
| | | /** |
| | | * The error reported is for the license that advanced most in the validation process |
| | | * |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( test_most_advanced_license_error ) { |
| | | EventRegistry er; |
| | | er.addEvent(LICENSE_SPECIFIED, "lic2"); |
| | | er.addEvent(LICENSE_FOUND, "lic1"); |
| | | er.addEvent(LICENSE_CORRUPTED, "lic1"); |
| | | er.turnWarningsIntoErrors(); |
| | | const AuditEvent *event = er.getLastFailure(); |
| | | BOOST_CHECK_MESSAGE(event != nullptr, "An error is detected"); |
| | | BOOST_CHECK_MESSAGE(string("lic1") == event->license_reference, "Error is for lic1"); |
| | | BOOST_CHECK_MESSAGE(LICENSE_CORRUPTED == event->event_type, "Error is for LICENSE_CORRUPTED"); |
| | | } |
| | | |
| | | } //namespace test |
| | |
| | | #include <cstdio> |
| | | |
| | | #include <build_properties.h> |
| | | |
| | | #include "../../src/library/os/os.h" |
| | | #include "../../src/library/base/EventRegistry.h" |
| | | #include "../../src/library/locate/ApplicationFolder.hpp" |
| | | #include "../../src/library/locate/EnvironmentVarLocation.hpp" |
| | |
| | | |
| | | license::EventRegistry registry; |
| | | ApplicationFolder applicationFolder; |
| | | vector<string> licenseInfos = applicationFolder.licenseLocations(registry); |
| | | vector<string> licenseInfos = applicationFolder.license_locations(registry); |
| | | BOOST_CHECK(registry.isGood()); |
| | | BOOST_REQUIRE_EQUAL(1, licenseInfos.size()); |
| | | string currentLocation = licenseInfos[0]; |
| | | BOOST_CHECK_MESSAGE(equivalent(path(referenceLicenseFileName),path(currentLocation)), |
| | | "file " +currentLocation + "found at expected location"); |
| | | string licenseRealContent = applicationFolder.retrieveLicense( |
| | | string licenseRealContent = applicationFolder.retrieve_license_content( |
| | | currentLocation); |
| | | src.seekg(0, ios::beg); |
| | | std::string referenceContent((std::istreambuf_iterator<char>(src)), |
| | |
| | | std::string referenceContent((std::istreambuf_iterator<char>(src)), |
| | | std::istreambuf_iterator<char>()); |
| | | license::EventRegistry registry; |
| | | ExternalDefinition externalDefinition(applicationDefinedString); |
| | | vector<string> licenseInfos = externalDefinition.licenseLocations(registry); |
| | | const LicenseLocation licLocation({applicationDefinedString,nullptr}); |
| | | ExternalDefinition externalDefinition(&licLocation); |
| | | vector<string> licenseInfos = externalDefinition.license_locations(registry); |
| | | BOOST_CHECK(registry.isGood()); |
| | | BOOST_CHECK_EQUAL(1, licenseInfos.size()); |
| | | string currentLocation = licenseInfos[0]; |
| | | BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0, |
| | | "file found at expected location"); |
| | | string licenseRealContent = externalDefinition.retrieveLicense( |
| | | string licenseRealContent = externalDefinition.retrieve_license_content( |
| | | currentLocation); |
| | | BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, |
| | | "File content is same"); |
| | | } |
| | | |
| | | /** |
| | | * The license file doesn't exist. Chech that the locator reports the right error |
| | | * The license file doesn't exist. Check that the locator reports the right error |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( external_definition_not_found ) { |
| | | const char *applicationDefinedString = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist"; |
| | | license::EventRegistry registry; |
| | | ExternalDefinition externalDefinition(applicationDefinedString); |
| | | vector<string> licenseInfos = externalDefinition.licenseLocations(registry); |
| | | const LicenseLocation licLocation({applicationDefinedString,nullptr}); |
| | | ExternalDefinition externalDefinition(&licLocation); |
| | | vector<string> licenseInfos = externalDefinition.license_locations(registry); |
| | | |
| | | BOOST_CHECK_MESSAGE(registry.isGood(), |
| | | "No fatal error for now, only warnings"); |
| | | registry.turnEventIntoError(LICENSE_FILE_NOT_FOUND); |
| | | registry.turnWarningsIntoErrors(); |
| | | BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected"); |
| | | BOOST_CHECK_EQUAL(0, licenseInfos.size()); |
| | | BOOST_CHECK_MESSAGE( |
| | |
| | | license::EventRegistry registry; |
| | | |
| | | EnvironmentVarLocation envVarLocationStrategy; |
| | | vector<string> licenseInfos = envVarLocationStrategy.licenseLocations( |
| | | vector<string> licenseInfos = envVarLocationStrategy.license_locations( |
| | | registry); |
| | | BOOST_CHECK(registry.isGood()); |
| | | BOOST_CHECK_EQUAL(1, licenseInfos.size()); |
| | | string currentLocation = licenseInfos[0]; |
| | | BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0, |
| | | "file found at expected location"); |
| | | string licenseRealContent = envVarLocationStrategy.retrieveLicense( |
| | | string licenseRealContent = envVarLocationStrategy.retrieve_license_content( |
| | | currentLocation); |
| | | BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, |
| | | "File content is same"); |
| | | #ifdef _WIN32 |
| | | _putenv_s(LICENSE_LOCATION_ENV_VAR, ""); |
| | | #else |
| | | unsetenv(LICENSE_LOCATION_ENV_VAR); |
| | | #endif |
| | | |
| | | UNSETENV(LICENSE_LOCATION_ENV_VAR); |
| | | } |
| | | |
| | | /** |
| | |
| | | BOOST_AUTO_TEST_CASE( environment_var_location_not_found ) { |
| | | const char *environment_variable_value = |
| | | PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist"; |
| | | #ifdef _WIN32 |
| | | _putenv_s(LICENSE_LOCATION_ENV_VAR, environment_variable_value); |
| | | #else |
| | | setenv(LICENSE_LOCATION_ENV_VAR, environment_variable_value, 1); |
| | | #endif |
| | | SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value); |
| | | |
| | | license::EventRegistry registry; |
| | | EnvironmentVarLocation envVarLocationStrategy; |
| | | vector<string> licenseInfos = envVarLocationStrategy.licenseLocations( |
| | | vector<string> licenseInfos = envVarLocationStrategy.license_locations( |
| | | registry); |
| | | BOOST_CHECK_MESSAGE(registry.isGood(), |
| | | "No fatal error for now, only warnings"); |
| | | registry.turnEventIntoError(LICENSE_FILE_NOT_FOUND); |
| | | registry.turnWarningsIntoErrors(); |
| | | BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected"); |
| | | BOOST_CHECK_EQUAL(0, licenseInfos.size()); |
| | | BOOST_CHECK_MESSAGE( |
| | | registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND, |
| | | "Error detected"); |
| | | #ifdef _WIN32 |
| | | _putenv_s(LICENSE_LOCATION_ENV_VAR, ""); |
| | | #else |
| | | unsetenv(LICENSE_LOCATION_ENV_VAR); |
| | | #endif |
| | | UNSETENV(LICENSE_LOCATION_ENV_VAR); |
| | | } |
| | | |
| | | /** |
| | | * The license file doesn't exist. Check that the locator reports the right error |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( environment_var_location_not_defined ) { |
| | | #ifdef _WIN32 |
| | | _putenv_s(LICENSE_LOCATION_ENV_VAR, ""); |
| | | #else |
| | | unsetenv(LICENSE_LOCATION_ENV_VAR); |
| | | #endif |
| | | UNSETENV(LICENSE_LOCATION_ENV_VAR); |
| | | license::EventRegistry registry; |
| | | EnvironmentVarLocation environmentVarLocation; |
| | | vector<string> licenseInfos = environmentVarLocation.licenseLocations( |
| | | vector<string> licenseInfos = environmentVarLocation.license_locations( |
| | | registry); |
| | | |
| | | BOOST_CHECK_MESSAGE(registry.isGood(), |
| | | "No fatal error for now, only warnings"); |
| | | registry.turnEventIntoError(ENVIRONMENT_VARIABLE_NOT_DEFINED); |
| | | registry.turnWarningsIntoErrors(); |
| | | BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected"); |
| | | BOOST_CHECK_EQUAL(0, licenseInfos.size()); |
| | | BOOST_CHECK_MESSAGE( |
| | |
| | | #define BOOST_TEST_MODULE "test_license_reader" |
| | | #include <boost/assert.hpp> |
| | | #include <boost/test/tools/old/interface.hpp> |
| | | #include <boost/test/unit_test_suite.hpp> |
| | | #include <iostream> |
| | | #include <vector> |
| | | |
| | | #include "../../src/library/api/datatypes.h" |
| | | #include "../../src/library/base/EventRegistry.h" |
| | | #include "../../src/library/os/os.h" |
| | | |
| | | |
| | | #include <boost/test/unit_test.hpp> |
| | | #include <stdlib.h> |
| | |
| | | #include <build_properties.h> |
| | | #include "../../src/library/LicenseReader.hpp" |
| | | |
| | | namespace test { |
| | | using namespace license; |
| | | |
| | | using namespace std; |
| | | /** |
| | | * Read license at fixed location |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( read_single_file ) { |
| | | const char *licLocation = PROJECT_TEST_SRC_DIR "/library/test_reader.ini"; |
| | | const char *licLocation = PROJECT_TEST_SRC_DIR "/library/test_reader.ini"; |
| | | |
| | | const LicenseLocation location = { licLocation, nullptr, false }; |
| | | LicenseReader licenseReader(location); |
| | | const LicenseLocation location = { licLocation, nullptr }; |
| | | LicenseReader licenseReader(&location); |
| | | vector<FullLicenseInfo> licenseInfos; |
| | | const EventRegistry registry = licenseReader.readLicenses("PrODUCT", |
| | | licenseInfos); |
| | |
| | | BOOST_CHECK_EQUAL(1, licenseInfos.size()); |
| | | } |
| | | |
| | | /** |
| | | * Test the error return if the product code is not found in the license |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( product_not_licensed ) { |
| | | const char *licLocation = |
| | | PROJECT_TEST_SRC_DIR "/library/test_reader.ini"; |
| | | const LicenseLocation location = { licLocation, nullptr, false }; |
| | | LicenseReader licenseReader(location); |
| | | const LicenseLocation location = { licLocation, nullptr }; |
| | | LicenseReader licenseReader(&location); |
| | | vector<FullLicenseInfo> licenseInfos; |
| | | const EventRegistry registry = licenseReader.readLicenses("PRODUCT-NOT", |
| | | licenseInfos); |
| | |
| | | registry.getLastFailure()->event_type); |
| | | } |
| | | |
| | | /** |
| | | * Test the error code if the license file is specified but doesn't exists |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( file_not_found ) { |
| | | const char *licLocation = PROJECT_TEST_SRC_DIR "/library/not_found.ini"; |
| | | //const char * envName = "MYVAR"; |
| | | const LicenseLocation location = { licLocation, nullptr, false }; |
| | | LicenseReader licenseReader(location); |
| | | const LicenseLocation location = { licLocation, nullptr }; |
| | | LicenseReader licenseReader(&location); |
| | | vector<FullLicenseInfo> licenseInfos; |
| | | const EventRegistry registry = licenseReader.readLicenses("PRODUCT", |
| | | licenseInfos); |
| | |
| | | registry.getLastFailure()->event_type); |
| | | } |
| | | |
| | | /** |
| | | * Test the error code if the license default environment variable isn't specified |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( env_var_not_defined ) { |
| | | const char *envName = "MYVAR"; |
| | | const LicenseLocation location = { nullptr, envName, false }; |
| | | LicenseReader licenseReader(location); |
| | | UNSETENV(LICENSE_LOCATION_ENV_VAR); |
| | | const LicenseLocation location = { nullptr, nullptr }; |
| | | LicenseReader licenseReader(&location); |
| | | vector<FullLicenseInfo> licenseInfos; |
| | | const EventRegistry registry = licenseReader.readLicenses("PRODUCT", |
| | | licenseInfos); |
| | |
| | | registry.getLastFailure()->event_type); |
| | | } |
| | | |
| | | /** |
| | | * Test the error code if the license default environment variable is |
| | | * specified but points to a non existent file. |
| | | */ |
| | | BOOST_AUTO_TEST_CASE( env_var_point_to_wrong_file ) { |
| | | const char *environment_variable_value = |
| | | PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist"; |
| | | SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value) |
| | | |
| | | const LicenseLocation location = { nullptr, nullptr }; |
| | | LicenseReader licenseReader(&location); |
| | | vector<FullLicenseInfo> licenseInfos; |
| | | const EventRegistry registry = licenseReader.readLicenses("PRODUCT", |
| | | licenseInfos); |
| | | cout << registry << endl; |
| | | BOOST_CHECK(!registry.isGood()); |
| | | BOOST_CHECK_EQUAL(0, licenseInfos.size()); |
| | | BOOST_ASSERT(registry.getLastFailure()!=NULL); |
| | | BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND, |
| | | registry.getLastFailure()->event_type); |
| | | UNSETENV(LICENSE_LOCATION_ENV_VAR); |
| | | } |
| | | } /* namespace test*/ |