gcontini
2019-11-23 f5106362b82b035dcd8e487d755316e886de3440
signature verified, tests
31个文件已修改
6个文件已添加
4 文件已重命名
5个文件已删除
1645 ■■■■ 已修改文件
.travis.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CMakeLists.txt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cmake/Findlcc.cmake 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/datatypes.h 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/licensecc.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/CMakeLists.txt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/CMakeLists.txt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/LicenseReader.cpp 209 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/LicenseReader.hpp 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/api/datatypes.h 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/EventRegistry.cpp 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/EventRegistry.h 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/base.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/ini/CMakeLists.txt 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/license++.cpp 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/licensecc.cpp 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/limits/license_verifier.cpp 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/limits/license_verifier.hpp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ApplicationFolder.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarData.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ExternalDefinition.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorFactory.hpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/CMakeLists.txt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/openssl/signature_verifier.cpp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os.c 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/signature_verifier.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/signature_verifier.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/pc-identifiers.c 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/pc-identifiers.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/licensecc_properties.h.in 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/licensecc_properties_test.h.in 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/CMakeLists.txt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/CMakeLists.txt 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/date_test.cpp 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/generate-license.cpp 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/generate-license.h 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/hijiaking_test.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/signature_verifier_test.cpp 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/standard-license_test.cpp 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/volid_test.cpp 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/CMakeLists.txt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/LicenseReader_test.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/license_verifier_test.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/verifier_test.cpp 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.travis.yml
@@ -94,6 +94,7 @@
             - mingw-w64-tools 
             - mingw-w64-x86-64-dev 
             - wine-development
             - wine32-development
     before_script:
        - mkdir build
        - cd build
CMakeLists.txt
@@ -29,7 +29,7 @@
#find lcc executable or build it.
find_package(lcc REQUIRED) 
#Not sure about this. My system doesn't support binfmt misc
#My system doesn't support binfmt misc
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" ) AND CMAKE_CROSSCOMPILING AND NOT DEFINED CMAKE_CROSSCOMPILING_EMULATOR )
    SET(CMAKE_CROSSCOMPILING_EMULATOR "wine")    
ENDIF()
@@ -39,7 +39,7 @@
    target_architecture( TARGET_ARCHITECTURE )
    message(STATUS "architecture detected: ${TARGET_ARCHITECTURE}")
    
    #Boost > 3.15 handle the /MD flag more nicely than this
    #cmake > 3.15 handle the /MD flag more nicely than this
    if(${STATIC_RUNTIME})
        string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
        string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
@@ -89,7 +89,7 @@
    endif(NOT MINGW)
endif(UNIX)
#initialize project
#load the current project from files or find it from environment variables or create a default one
set(LCC_INCLUDE_DIR "${LCC_PROJECTS_BASE_DIR}/${LCC_PROJECT_NAME}/include/${PROJECT_NAME}/${LCC_PROJECT_NAME}" )
set(LCC_PROJECT_PUBLIC_KEY "${LCC_INCLUDE_DIR}/public_key.h" )
@@ -101,10 +101,10 @@
  COMMENT "generating ${LCC_PROJECT_PUBLIC_KEY}"
  USES_TERMINAL
)
add_custom_target(project_initialize DEPENDS "${LCC_PROJECT_PUBLIC_KEY}" "${LCC_PROJECT_PRIVATE_KEY}")
include_directories( ${LCC_INCLUDE_DIR} ${CMAKE_BINARY_DIR} )
include_directories( ${LCC_INCLUDE_DIR} ${CMAKE_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/include")
message( STATUS "C compiler        : " ${CMAKE_C_COMPILER})
message( STATUS "C compiler flags  : " ${CMAKE_C_FLAGS})
@@ -133,7 +133,7 @@
        message(STATUS "Compiler architecture: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
endif()
SET( Boost_USE_STATIC_LIBS ON )
find_package(Boost REQUIRED COMPONENTS date_time unit_test_framework program_options system filesystem)
find_package(Boost REQUIRED COMPONENTS unit_test_framework system filesystem)
#if boost is found enable tests
IF(Boost_FOUND)
@@ -141,9 +141,6 @@
    IF(BUILD_TESTING)
        SET(BUILDNAME "${BUILDNAME}" CACHE STRING "Name of build on the dashboard")
        MARK_AS_ADVANCED(BUILDNAME)
        add_definitions(-DBOOST_ALL_NO_LIB) #Disable Boost Microsoft magic, all dependencies are handled by cmake
        add_definitions(-DBOOST_LIB_DIAGNOSTIC) #Check it is really disabled
        include_directories(${Boost_INCLUDE_DIRS})
        add_subdirectory(test)
    ENDIF(BUILD_TESTING)
ELSE(Boost_FOUND)
cmake/Findlcc.cmake
@@ -49,7 +49,7 @@
if(LCC_LOCATION)
    # First search the PATH and specific locations.
    find_program(LCC_EXECUTABLE
      NAMES ${lcc_names} HINTS ${LCC_LOCATION} DOC "lcc command line client")
    NAMES ${lcc_names} HINTS ${LCC_LOCATION} DOC "lcc command line client")
    FIND_PACKAGE_HANDLE_STANDARD_ARGS(lcc FOUND_VAR LCC_FOUND
                                       REQUIRED_VARS LCC_EXECUTABLE 
                                       FAIL_MESSAGE "Error finding lcc executable. variable LCC_LOCATION non set correctly.")
@@ -78,7 +78,6 @@
        endif()
        add_subdirectory("${PROJECT_SOURCE_DIR}/extern/license-generator")
    ENDIF(NOT lcc_FOUND)
    set(LCC_EXECUTABLE $<TARGET_FILE:license_generator::lcc>)
ENDIF(LCC_LOCATION)
include/licensecc/datatypes.h
New file
@@ -0,0 +1,132 @@
#ifndef DATATYPES_H_
#define DATATYPES_H_
#include <licensecc_properties.h>
#ifdef __cplusplus
extern "C" {
#endif
// definition of size_t
#include <stdlib.h>
#include <stdint.h>
#ifndef _MSC_VER
#include <stdbool.h>
#endif
#ifdef __unix__
#define DllExport
#ifndef MAX_PATH
#define MAX_PATH 1024
#endif
#else
#include <windows.h>
#define DllExport __declspec(dllexport)
#endif
typedef enum {
    LICENSE_OK = 0,  // OK
    LICENSE_FILE_NOT_FOUND = 1,  // license file not found
    LICENSE_SERVER_NOT_FOUND = 2,  // license server can't be contacted
    ENVIRONMENT_VARIABLE_NOT_DEFINED = 3,  // environment variable not defined
    FILE_FORMAT_NOT_RECOGNIZED = 4,  // license file has invalid format (not .ini file)
    LICENSE_MALFORMED = 5,  // some mandatory field are missing, or data can't be fully read.
    PRODUCT_NOT_LICENSED = 6,  // this product was not licensed
    PRODUCT_EXPIRED = 7,
    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_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 enum {
    LOCAL,
    REMOTE  // remote licenses are not supported now.
} LICENSE_TYPE;
typedef enum { SVRT_INFO, SVRT_WARN, SVRT_ERROR } SEVERITY;
typedef struct {
    SEVERITY severity;
    EVENT_TYPE event_type;
    /**
     * 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;
    /**
     * 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;
/**
 * Informations on the software requiring the license
 */
typedef struct {
    char version[16];  // software version in format xxxx.xxxx.xxxx
    char project_name[16];  // name of the project (must correspond to the name in the license)
    uint32_t magic;  // reserved
} CallerInformations;
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 AUDIT_EVENT_NUM are reported.
     */
    AuditEvent status[AUDIT_EVENT_NUM];
    /**
     * Eventual expiration date of the software,
     * can be '\0' if the software don't expire
     * */
    char expiry_date[11];
    unsigned int days_left;
    bool has_expiry;
    bool linked_to_pc;
    LICENSE_TYPE license_type;  // Local or Remote
    /* A string of character inserted into the license understood
     * by the calling application.
     * '\0' if the application didn't specify one */
    char proprietary_data[PROPRIETARY_DATA_SIZE + 1];
    int license_version;  // license file version
} LicenseInfo;
/**
 * Enum to select a specific pc identification_strategy. DEFAULT Should be used
 * in most cases.
 */
typedef enum {
    DEFAULT,
    ETHERNET,
    IP_ADDRESS,
    DISK_NUM,
    DISK_LABEL,
    PLATFORM_SPECIFIC,
    STRATEGY_UNKNOWN
} IDENTIFICATION_STRATEGY;
#ifdef __cplusplus
}
#endif
#endif
include/licensecc/licensecc.h
File was renamed from src/library/api/license++.h
@@ -27,8 +27,6 @@
/**
 * This method is used to request the use of one license for a product.
 * In case of local license it's used to check if the product is licensed.
 * [In case of network licenses this will decrease the count of the available
 *  licenses]
 *
 * @return LICENSE_OK(0) if successful. Other values if there are errors.
 * @param productName[in]
@@ -39,8 +37,8 @@
 * @param license[out] optional, can be NULL, if set it will return extra informations about the license.
 */
EVENT_TYPE acquire_license(const char * productName,
        const LicenseLocation* licenseLocation, LicenseInfo* license);
EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
                           LicenseInfo* license_out);
/**
 * Do nothing for now, useful for network licenses.
src/CMakeLists.txt
@@ -1,11 +1,7 @@
add_subdirectory("library")
configure_file (
    "templates/licensecc_properties_test.h.in"
    "${CMAKE_BINARY_DIR}/licensecc_properties_test.h"
)
configure_file (
    "templates/licensecc_properties.h.in"
    "${LCC_INCLUDE_DIR}/licensecc_properties.h"
)
#for no reason overwrite it (maybe it's manually customized)
IF(NOT EXISTS "${LCC_INCLUDE_DIR}/licensecc_properties.h")
    configure_file ("templates/licensecc_properties.h.in"
        "${LCC_INCLUDE_DIR}/licensecc_properties.h")
ENDIF(NOT EXISTS "${LCC_INCLUDE_DIR}/licensecc_properties.h")
src/library/.gitignore
File was deleted
src/library/CMakeLists.txt
@@ -1,18 +1,18 @@
add_subdirectory("os")
add_subdirectory("base")
add_subdirectory("ini")
add_subdirectory("locate")
ADD_LIBRARY(licensecc_static STATIC
    license++.cpp
    licensecc.cpp
    LicenseReader.cpp
    pc-identifiers.c
    limits/license_verifier.cpp
    ini/ConvertUTF.c
)
target_link_libraries(
     licensecc_static
     ini
     locators
     os
     base
src/library/LicenseReader.cpp
@@ -6,9 +6,9 @@
 */
#ifdef _WIN32
# pragma warning(disable: 4786)
#pragma warning(disable : 4786)
#else
# include <unistd.h>
#include <unistd.h>
#endif
#include <cstring>
@@ -24,7 +24,9 @@
#include <public_key.h>
#include <licensecc_properties.h>
#include <licensecc/licensecc.h>
#include "base/base.h"
#include "pc-identifiers.h"
#include "LicenseReader.hpp"
#include "base/StringUtils.h"
@@ -33,93 +35,17 @@
namespace license {
const char *FullLicenseInfo::UNUSED_TIME = "0000-00-00";
FullLicenseInfo::FullLicenseInfo(const string &source, const string &product, const string &license_signature)
    : source(source),
      m_project(product),  //
      license_signature(license_signature) {}
FullLicenseInfo::FullLicenseInfo(const string &source, const string &product,
        const string &license_signature, int licenseVersion, string from_date,
        string to_date, const string &client_signature,
        unsigned int from_sw_version, unsigned int to_sw_version,
        const string &extra_data) :
        source(source), product(product), //
        license_signature(license_signature), license_version(licenseVersion), //
        from_date(from_date), to_date(to_date), //
        has_expiry(to_date != UNUSED_TIME), //
        from_sw_version(from_sw_version), to_sw_version(to_sw_version), //
        has_versions(
                from_sw_version != UNUSED_SOFTWARE_VERSION
                        || to_sw_version != UNUSED_SOFTWARE_VERSION), //
        client_signature(client_signature), has_client_sig(
                client_signature.length() > 0), //
        extra_data(extra_data) {
}
LicenseReader::LicenseReader(const LicenseLocation *licenseLocation) : licenseLocation(licenseLocation) {}
bool FullLicenseInfo::validate(int sw_version,
        EventRegistry &eventRegistryOut) {
    os_initialize();
    const FUNCTION_RETURN sigVer = verifySignature(printForSign().c_str(),
            license_signature.c_str());
    bool is_valid = (sigVer == FUNC_RET_OK);
    if (is_valid) {
        eventRegistryOut.addEvent(SIGNATURE_VERIFIED, source);
    } else {
        eventRegistryOut.addEvent(LICENSE_CORRUPTED, source);
    }
    if (has_expiry) {
        cout<<source<<endl;
        const time_t now = time(nullptr);
        if (expires_on() < now) {
/*
            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) {
            /*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);
        eventRegistryOut.addEvent(event, source);
        is_valid = is_valid && (event == LICENSE_OK);
    }
    return is_valid;
}
void FullLicenseInfo::toLicenseInfo(LicenseInfo *license) const {
    if (license != nullptr) {
        strncpy(license->proprietary_data, extra_data.c_str(),
        PROPRIETARY_DATA_SIZE);
        license->linked_to_pc = has_client_sig;
        license->has_expiry = has_expiry;
        if (!has_expiry) {
            license->expiry_date[0] = '\0';
            license->days_left = 999999;
        } else {
            strncpy(license->expiry_date, to_date.c_str(), 11);
            const double secs = difftime(seconds_from_epoch(to_date.c_str()),
                    time(nullptr));
            license->days_left = round(secs / (60 * 60 * 24));
        }
    }
}
LicenseReader::LicenseReader(const LicenseLocation* licenseLocation) :
        licenseLocation(licenseLocation) {
}
EventRegistry LicenseReader::readLicenses(const string &product,
        vector<FullLicenseInfo> &licenseInfoOut) {
EventRegistry LicenseReader::readLicenses(const string &product, vector<FullLicenseInfo> &licenseInfoOut) {
    vector<string> diskFiles;
    vector<unique_ptr<locate::LocatorStrategy>> locator_strategies;
    FUNCTION_RETURN ret = locate::LocatorFactory::get_active_strategies(
            locator_strategies, licenseLocation);
    FUNCTION_RETURN ret = locate::LocatorFactory::get_active_strategies(locator_strategies, licenseLocation);
    EventRegistry eventRegistry;
    if (ret != FUNC_RET_OK) {
        eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND);
@@ -129,19 +55,17 @@
    bool atLeastOneLicenseComplete = false;
    for (unique_ptr<locate::LocatorStrategy> &locator : locator_strategies) {
        vector<string> licenseLocations = locator->license_locations(
                eventRegistry);
        vector<string> licenseLocations = locator->license_locations(eventRegistry);
        if (licenseLocations.size() == 0) {
            continue;
        }
        CSimpleIniA ini;
        for (auto it = licenseLocations.begin(); it != licenseLocations.end();
                it++) {
        for (auto it = licenseLocations.begin(); it != licenseLocations.end(); it++) {
            ini.Reset();
            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,     *it);
                eventRegistry.addEvent(FILE_FORMAT_NOT_RECOGNIZED, *it);
                continue;
            }
            const char *productNamePtr = product.c_str();
@@ -150,7 +74,7 @@
                eventRegistry.addEvent(PRODUCT_NOT_LICENSED, *it);
                continue;
            } else {
                eventRegistry.addEvent(PRODUCT_FOUND,     *it);
                eventRegistry.addEvent(PRODUCT_FOUND, *it);
            }
            /*
             *  sw_version_from = (optional int)
@@ -158,37 +82,18 @@
             *  from_date = YYYY-MM-DD (optional)
             *  to_date  = YYYY-MM-DD (optional)
             *  client_signature = XXXX-XXXX-XXXX-XXXX (optional string 16)
             *  license_signature = XXXXXXXXXX (mandatory, 1024)
             *  sig = XXXXXXXXXX (mandatory, 1024)
             *  application_data = xxxxxxxxx (optional string 16)
             */
            const char *license_signature = ini.GetValue(productNamePtr,
                    "license_signature", nullptr);
            long license_version = ini.GetLongValue(productNamePtr,
                    "license_version", -1);
            if (license_signature != nullptr && license_version > 0) {
                const string from_date = trim_copy(
                        ini.GetValue(productNamePtr, "from_date",
                                FullLicenseInfo::UNUSED_TIME));
                const string to_date = trim_copy(
                        ini.GetValue(productNamePtr, "to_date",
                                FullLicenseInfo::UNUSED_TIME));
                string client_signature = trim_copy(
                        ini.GetValue(productNamePtr, "client_signature", ""));
                /*client_signature.erase(
                 std::remove(client_signature.begin(), client_signature.end(), '-'),
                 client_signature.end());*/
                const int from_sw_version = ini.GetLongValue(productNamePtr,
                        "from_sw_version",
                        FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
                const int to_sw_version = ini.GetLongValue(productNamePtr,
                        "to_sw_version",
                        FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
                string extra_data = trim_copy(
                        ini.GetValue(productNamePtr, "extra_data", ""));
                FullLicenseInfo licInfo(*it, product, license_signature,
                        (int) license_version, from_date, to_date,
                        client_signature, from_sw_version, to_sw_version,
                        extra_data);
            const char *license_signature = ini.GetValue(productNamePtr, "sig", nullptr);
            long license_version = ini.GetLongValue(productNamePtr, "lic_ver", -1);
            if (license_signature != nullptr && license_version == 200) {
                CSimpleIniA::TNamesDepend keys;
                ini.GetAllKeys(productNamePtr, keys);
                FullLicenseInfo licInfo(*it, product, license_signature);
                for (auto &it : keys) {
                    licInfo.m_limits[it.pItem] = ini.GetValue(productNamePtr, it.pItem, nullptr);
                }
                licenseInfoOut.push_back(licInfo);
                atLeastOneLicenseComplete = true;
            } else {
@@ -202,69 +107,21 @@
    return eventRegistry;
}
LicenseReader::~LicenseReader() {
}
LicenseReader::~LicenseReader() {}
string FullLicenseInfo::printForSign() const {
    ostringstream oss;
    oss << toupper_copy(trim_copy(this->product));
    //oss << SHARED_RANDOM;
    if (has_client_sig) {
        oss << trim_copy(this->client_signature);
    oss << toupper_copy(trim_copy(m_project));
    for (auto &it : m_limits) {
        if (it.first != LICENSE_VERSION && it.first != LICENSE_SIGNATURE) {
            oss << trim_copy(it.first) << trim_copy(it.second);
        }
    }
    if (has_versions) {
        oss << "|" << this->from_sw_version << "-" << this->to_sw_version;
    }
    if (has_expiry) {
        oss << "|" << this->from_date << "|" << this->to_date;
    }
    if (this->extra_data.length() > 0) {
        oss << "|" << extra_data;
    }
#ifdef _DEBUG
    cout << "[" << oss.str() << "]" << endl;
#endif
    return oss.str();
}
void FullLicenseInfo::printAsIni(ostream &a_ostream) const {
    CSimpleIniA ini;
    string result;
    const string product = toupper_copy(trim_copy(this->product));
    CSimpleIniA::StreamWriter sw(a_ostream);
    ini.SetLongValue(product.c_str(), "license_version",
    PROJECT_INT_VERSION);
    ini.SetValue(product.c_str(), "license_signature",
            this->license_signature.c_str());
    if (has_client_sig) {
        ini.SetValue(product.c_str(), "client_signature",
                this->client_signature.c_str());
    }
    if (has_versions) {
        ini.SetLongValue(product.c_str(), "from_sw_version", from_sw_version);
        ini.SetLongValue(product.c_str(), "to_sw_version", to_sw_version);
    }
    if (this->from_date != UNUSED_TIME) {
        ini.SetValue(product.c_str(), "from_date", from_date.c_str());
    }
    if (this->to_date != UNUSED_TIME) {
        ini.SetValue(product.c_str(), "to_date", to_date.c_str());
    }
    if (this->extra_data.length() > 0) {
        ini.SetValue(product.c_str(), "extra_data", this->extra_data.c_str());
    }
    ini.Save(sw);
}
time_t FullLicenseInfo::expires_on() const {
    return seconds_from_epoch(this->to_date.c_str());
}
time_t FullLicenseInfo::valid_from() const {
    return seconds_from_epoch(this->from_date.c_str());
}
}
}  // namespace license
src/library/LicenseReader.hpp
@@ -11,7 +11,8 @@
#include <ctime>
#define SI_SUPPORT_IOSTREAMS
#include "api/datatypes.h"
#include <licensecc/datatypes.h>
#include "base/EventRegistry.h"
#include "os/os.h"
#include "ini/SimpleIni.h"
@@ -20,37 +21,14 @@
class FullLicenseInfo {
public:
    std::string source;
    std::string product;
    std::string license_signature;
    int license_version;
    std::string from_date;
    std::string to_date;
    bool has_expiry;
    unsigned int from_sw_version;
    unsigned int to_sw_version;
    bool has_versions;
    std::string client_signature;
    bool has_client_sig;
    std::string extra_data;
    const std::string license_signature;
    const std::string source;
    const std::string m_project;
    std::map<std::string, std::string> m_limits;
    static const char* UNUSED_TIME;
    static const unsigned int UNUSED_SOFTWARE_VERSION = 0;
    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 std::string& extra_data = "");
    FullLicenseInfo(const std::string& source, const std::string& product, const std::string& license_signature);
    std::string printForSign() const;
    void printAsIni(std::ostream & a_ostream) const;
    void toLicenseInfo(LicenseInfo* license) const;
    bool validate(int sw_version, EventRegistry& eventRegistryOut);
    time_t expires_on() const;
    time_t valid_from() const;
    operator LicenseInfo() const;
};
/**
@@ -74,11 +52,11 @@
class LicenseReader {
private:
    const LicenseLocation* licenseLocation;
public:
    LicenseReader(const LicenseLocation* licenseLocation);
    EventRegistry readLicenses(const std::string &product,
            std::vector<FullLicenseInfo>& licenseInfoOut);
    EventRegistry readLicenses(const std::string& product, std::vector<FullLicenseInfo>& licenseInfoOut);
    virtual ~LicenseReader();
};
}
}  // namespace license
#endif /* LICENSEREADER_H_ */
src/library/api/datatypes.h
File was deleted
src/library/base/EventRegistry.cpp
@@ -17,50 +17,42 @@
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 } };
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::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;
}
ostream& operator<<(std::ostream &out, const EventRegistry &er) {
    out << string("EventReg[step:") << er.current_validation_step
            << ",events:{";
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 << "[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());
    logs.insert(logs.end(), eventRegistry.logs.begin(), eventRegistry.logs.end());
}
AuditEvent const* EventRegistry::getLastFailure() const {
const AuditEvent *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
    // 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) {
        for (const auto &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
            const AuditEvent &currentLog = logs[mostAdvLogIter.second];
            if (currentLog.severity == SVRT_ERROR) {
                result = &(currentLog);
@@ -81,13 +73,11 @@
    return result;
}
void EventRegistry::addEvent(EVENT_TYPE event,
        const std::string &licenseLocationId) {
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) {
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());
@@ -104,7 +94,7 @@
        strncpy(audit.param2, info, 255);
    }
    logs.push_back(audit);
//udpate the status of the log
    // udpate the status of the log
    if (successEvent) {
        int step = eventIterator->second;
        if (step > current_validation_step) {
@@ -113,23 +103,19 @@
        }
        if (step == current_validation_step) {
            mostAdvancedLogIdx_by_LicenseId[audit.license_reference] =
                    logs.size() - 1;
            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;
    } else if (mostAdvancedLogIdx_by_LicenseId.find(audit.license_reference) != mostAdvancedLogIdx_by_LicenseId.end()) {
        mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = logs.size() - 1;
    }
}
bool EventRegistry::turnWarningsIntoErrors() {
    bool eventFound = false;
    if (mostAdvancedLogIdx_by_LicenseId.size() > 0) {
        for (auto const &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
        for (const auto &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
            AuditEvent &currentLog = logs[mostAdvLogIter.second];
            if (currentLog.severity == SVRT_WARN
                    || currentLog.severity == SVRT_ERROR) {
            if (currentLog.severity == SVRT_WARN || currentLog.severity == SVRT_ERROR) {
                currentLog.severity = SVRT_ERROR;
                eventFound = true;
            }
@@ -158,13 +144,10 @@
}
void EventRegistry::exportLastEvents(AuditEvent *auditEvents, int nlogs) {
    const int sizeToCopy = min(nlogs, (int) logs.size());
    const int sizeToCopy = min(nlogs, (int)logs.size());
    std::copy(logs.end() - sizeToCopy, logs.end(), auditEvents);
}
bool EventRegistry::isGood() const {
    return getLastFailure() == nullptr;
}
bool EventRegistry::isGood() const { return getLastFailure() == nullptr; }
}
}  // namespace license
src/library/base/EventRegistry.h
@@ -8,7 +8,8 @@
#ifndef EVENTREGISTRY_H_
#define EVENTREGISTRY_H_
#include "../api/datatypes.h"
#include <licensecc/datatypes.h>
#include <vector>
#include <map>
#include <set>
@@ -22,21 +23,21 @@
 */
class EventRegistry {
private:
    friend EventRegistry& operator<<(EventRegistry&, AuditEvent&);
    friend EventRegistry& operator<<(EventRegistry&, EventRegistry&);
    friend std::ostream & operator << (std::ostream &out, const EventRegistry &er);
    friend EventRegistry &operator<<(EventRegistry &, AuditEvent &);
    friend EventRegistry &operator<<(EventRegistry &, EventRegistry &);
    friend std::ostream &operator<<(std::ostream &out, const EventRegistry &er);
    std::vector<AuditEvent> logs;
    /**
     * For every license keep track of the events who progressed most
     * in the validation process
     */
    std::map<std::string,size_t> mostAdvancedLogIdx_by_LicenseId;
    std::map<std::string, size_t> mostAdvancedLogIdx_by_LicenseId;
    int current_validation_step;
public:
    EventRegistry();
    //operator <<
    // operator <<
    void append(const EventRegistry &eventRegistry);
    /**
     * Turn the event warning for the license with the most advanced status
@@ -50,11 +51,10 @@
     * for the license with the most advanced status.
     * @return NULL if no failures are found.
     */
    AuditEvent const* getLastFailure() const;
    const AuditEvent *getLastFailure() const;
    void addEvent(EVENT_TYPE event, const std::string &licenseLocationId);
    void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr,
            const char *info = nullptr);
    void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr, const char *info = nullptr);
    void exportLastEvents(AuditEvent *auditEvents, int nlogs);
};
}
}  // namespace license
#endif /* EVENTREGISTRY_H_ */
src/library/base/base.h
@@ -9,12 +9,12 @@
#include <limits.h>
#define DllExport
#ifndef MAX_PATH
    #define MAX_PATH PATH_MAX
#define MAX_PATH PATH_MAX
#endif
#else //windows
#else  // windows
#include <windows.h>
#define DllExport  __declspec( dllexport )
#define DllExport __declspec(dllexport)
#ifndef __cplusplus
#ifndef _MSC_VER
@@ -22,21 +22,31 @@
#else
typedef int bool;
#define false 0
#define true -1
#define true - 1
#endif
#endif
#endif
/* #define _DEBUG */
#define cmin(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a < _b ? _a : _b; })
// license file parameters
#define PARAM_EXPIRY_DATE "valid-to"
#define PARAM_BEGIN_DATE "valid-from"
#define PARAM_VERSION_FROM "start-version"
#define PARAM_CLIENT_SIGNATURE "client-signature"
#define PARAM_VERSION_TO "end-version"
#define PARAM_EXTRA_DATA "extra-data"
// license file extra entries
#define LICENSE_SIGNATURE "sig"
#define LICENSE_VERSION "lic_ver"
typedef enum  {
    FUNC_RET_OK, FUNC_RET_NOT_AVAIL, FUNC_RET_ERROR, FUNC_RET_BUFFER_TOO_SMALL
} FUNCTION_RETURN;
typedef enum { FUNC_RET_OK, FUNC_RET_NOT_AVAIL, FUNC_RET_ERROR, FUNC_RET_BUFFER_TOO_SMALL } FUNCTION_RETURN;
#define cmin(a, b)              \
    ({                          \
        __typeof__(a) _a = (a); \
        __typeof__(b) _b = (b); \
        _a < _b ? _a : _b;      \
    })
#ifdef __cplusplus
}
src/library/ini/CMakeLists.txt
File was deleted
src/library/license++.cpp
File was deleted
src/library/licensecc.cpp
New file
@@ -0,0 +1,99 @@
//============================================================================
// Name        : license-manager-cpp.cpp
// Author      :
// Version     :
// Copyright   : BSD
//============================================================================
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <licensecc/datatypes.h>
#include <licensecc/licensecc.h>
#include "limits/license_verifier.hpp"
#include "LicenseReader.hpp"
using namespace std;
void print_error(char out_buffer[256], LicenseInfo* licenseInfo) {}
void identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char chbuffer[PC_IDENTIFIER_SIZE + 1]) {}
static void mergeLicenses(const vector<LicenseInfo>& licenses, LicenseInfo* license_out) {
    if (license_out != nullptr) {
        int days_left = -1;
        for (auto it = licenses.begin(); it != licenses.end(); it++) {
            // choose the license that expires later...
            if (!it->has_expiry) {
                *license_out = *it;
                break;
            } else if (days_left < it->days_left) {
                *license_out = *it;
                days_left = it->days_left;
            }
        }
    }
}
EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
                           LicenseInfo* license_out) {
    license::LicenseReader lr = license::LicenseReader(licenseLocation);
    vector<license::FullLicenseInfo> licenses;
    string project;
    if (callerInformation != nullptr && strlen(callerInformation->project_name) > 0) {
        project = string(callerInformation->project_name);
    } else {
        project = string(LCC_PROJECT_NAME);
    }
    license::EventRegistry er = lr.readLicenses(string(project), licenses);
    EVENT_TYPE result;
    if (licenses.size() > 0) {
        vector<LicenseInfo> licenses_with_errors;
        vector<LicenseInfo> licenses_ok;
        license::LicenseVerifier verifier(er);
        for (auto it = licenses.begin(); it != licenses.end(); it++) {
            FUNCTION_RETURN signatureValid = verifier.verify_signature(*it);
            if (signatureValid == FUNC_RET_OK) {
                if (verifier.verify_limits(*it) == FUNC_RET_OK) {
                    licenses_ok.push_back(verifier.toLicenseInfo(*it));
                } else {
                    licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
                }
            } else {
                licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
            }
        }
        if (licenses_ok.size() > 0) {
            er.turnErrorsIntoWarnings();
            result = LICENSE_OK;
            mergeLicenses(licenses_ok, license_out);
        } else {
            er.turnWarningsIntoErrors();
            result = er.getLastFailure()->event_type;
            mergeLicenses(licenses_with_errors, license_out);
        }
    } else {
        er.turnWarningsIntoErrors();
        result = er.getLastFailure()->event_type;
        if (license_out != nullptr) {
            license_out->proprietary_data[0] = '\0';
            license_out->linked_to_pc = false;
            license_out->days_left = 0;
        }
    }
#ifdef _DEBUG
    cout << er << endl;
#endif
    if (license_out != nullptr) {
        er.exportLastEvents(license_out->status, AUDIT_EVENT_NUM);
    }
    return result;
}
EVENT_TYPE confirm_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
EVENT_TYPE release_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
src/library/limits/license_verifier.cpp
New file
@@ -0,0 +1,100 @@
/*
 * LicenseVerifier.cpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#include <cmath>
#include <algorithm>
#include "license_verifier.hpp"
#include "../os/signature_verifier.h"
#include "../base/StringUtils.h"
#include "../pc-identifiers.h"
namespace license {
using namespace std;
LicenseVerifier::LicenseVerifier(EventRegistry& er) : m_event_registry(er) {}
LicenseVerifier::~LicenseVerifier() {}
FUNCTION_RETURN LicenseVerifier::verify_signature(const FullLicenseInfo& licInfo) {
    const string licInfoData(licInfo.printForSign());
    FUNCTION_RETURN ret = license::verify_signature(licInfoData, licInfo.license_signature);
    if (ret == FUNC_RET_OK) {
        m_event_registry.addEvent(SIGNATURE_VERIFIED, licInfo.source);
    } else {
        m_event_registry.addEvent(LICENSE_CORRUPTED, licInfo.source);
    }
    return ret;
}
// TODO: split in different classes
FUNCTION_RETURN LicenseVerifier::verify_limits(const FullLicenseInfo& licInfo) {
    bool is_valid = true;
    const time_t now = time(nullptr);
    auto expiry = licInfo.m_limits.find(PARAM_EXPIRY_DATE);
    if (expiry != licInfo.m_limits.end()) {
        if (seconds_from_epoch(expiry->second.c_str()) < now) {
            /*
                        eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                                string("Expired on: " + this->to_date).c_str());*/
            m_event_registry.addEvent(PRODUCT_EXPIRED, licInfo.source.c_str(), ("Expired " + expiry->second).c_str());
            is_valid = false;
        }
    }
    auto start_date = licInfo.m_limits.find(PARAM_BEGIN_DATE);
    if (is_valid && start_date != licInfo.m_limits.end()) {
        if (seconds_from_epoch(start_date->second.c_str()) > now) {
            /*eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                    string("Valid from " + this->from_date).c_str());*/
            m_event_registry.addEvent(PRODUCT_EXPIRED, licInfo.source.c_str(),
                                      ("Valid from " + start_date->second).c_str());
            is_valid = false;
        }
    }
    auto client_sig = licInfo.m_limits.find(PARAM_CLIENT_SIGNATURE);
    if (is_valid && client_sig != licInfo.m_limits.end()) {
        PcSignature str_code;
        strncpy(str_code, client_sig->second.c_str(), sizeof(str_code) - 1);
        const EVENT_TYPE event = validate_pc_signature(str_code);
        m_event_registry.addEvent(event, licInfo.source);
        is_valid = is_valid && (event == LICENSE_OK);
    }
    return is_valid ? FUNC_RET_OK : FUNC_RET_ERROR;
}
LicenseInfo LicenseVerifier::toLicenseInfo(const FullLicenseInfo& fullLicInfo) const {
    LicenseInfo info;
    info.license_type = LOCAL;
    auto expiry = fullLicInfo.m_limits.find(PARAM_EXPIRY_DATE);
    if (expiry != fullLicInfo.m_limits.end()) {
        strncpy(info.expiry_date, expiry->second.c_str(), sizeof(info.expiry_date));
        info.has_expiry = true;
        const double secs = difftime(seconds_from_epoch(expiry->second.c_str()), time(nullptr));
        info.days_left = max((int)round(secs / (60 * 60 * 24)), 0);
    } else {
        info.has_expiry = false;
        info.days_left = 9999;
        info.expiry_date[0] = '\0';
    }
    auto start_date = fullLicInfo.m_limits.find(PARAM_BEGIN_DATE);
    if (start_date != fullLicInfo.m_limits.end()) {
    }
    auto client_sig = fullLicInfo.m_limits.find(PARAM_CLIENT_SIGNATURE);
    info.linked_to_pc = (client_sig != fullLicInfo.m_limits.end());
    auto proprietary_data = fullLicInfo.m_limits.find(PARAM_EXTRA_DATA);
    if (proprietary_data != fullLicInfo.m_limits.end()) {
        strncpy(info.proprietary_data, proprietary_data->second.c_str(), PROPRIETARY_DATA_SIZE);
    }
    return info;
}
} /* namespace license */
src/library/limits/license_verifier.hpp
New file
@@ -0,0 +1,29 @@
/*
 * LicenseVerifier.hpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#ifndef SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_
#define SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_
#include "../base/EventRegistry.h"
#include "../LicenseReader.hpp"
namespace license {
class LicenseVerifier {
private:
    EventRegistry& m_event_registry;
public:
    LicenseVerifier(EventRegistry& er);
    FUNCTION_RETURN verify_signature(const FullLicenseInfo& licInfo);
    FUNCTION_RETURN verify_limits(const FullLicenseInfo& licInfo);
    LicenseInfo toLicenseInfo(const FullLicenseInfo& fullLicInfo) const;
    virtual ~LicenseVerifier();
};
} /* namespace license */
#endif /* SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_ */
src/library/locate/ApplicationFolder.cpp
@@ -8,10 +8,9 @@
#include <sstream>
#include <string>
//B#include <build_properties.h>
#include <licensecc/datatypes.h>
#include "../base/logger.h"
#include "../api/datatypes.h"
#include "../base/base.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
src/library/locate/EnvironmentVarData.cpp
@@ -6,6 +6,7 @@
 */
#include "EnvironmentVarData.hpp"
#include <licensecc/datatypes.h>
#include <licensecc_properties.h>
#include <cstdlib>
@@ -13,7 +14,6 @@
#include <string>
#include <vector>
#include "../api/datatypes.h"
#include "../base/base64.h"
#include "../base/EventRegistry.h"
#include "../base/StringUtils.h"
src/library/locate/ExternalDefinition.cpp
@@ -10,7 +10,8 @@
#include <string>
#include <vector>
#include "../api/datatypes.h"
#include <licensecc/datatypes.h>
#include "../base/base64.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
src/library/locate/LocatorFactory.hpp
@@ -4,9 +4,9 @@
#include <cstddef>
#include <string>
#include <vector>
#include <licensecc/datatypes.h>
#include "../base/base.h"
#include "../api/datatypes.h"
#include "LocatorStrategy.hpp"
namespace license {
src/library/os/CMakeLists.txt
@@ -1,6 +1,6 @@
IF(UNIX)
    ADD_LIBRARY(os STATIC
        linux/verifier.cpp
        openssl/signature_verifier.cpp
        os.c
        os-linux.c
        network_id.c)
@@ -8,14 +8,15 @@
    target_link_libraries(
         os
         base
         OpenSSL::Crypto
         OpenSSL::Crypto
         ${EXTERNAL_LIBS}
         ${CMAKE_DL_LIBS}
         ##ZLIB::ZLIB
    )
    
ELSE(UNIX)
    ADD_LIBRARY(os STATIC
        windows/verifier.cpp
        windows/signature_verifier.cpp
        os.c
        os-win.c)
src/library/os/openssl/signature_verifier.cpp
File was renamed from src/library/os/linux/verifier.cpp
@@ -12,7 +12,7 @@
#include <public_key.h>
#include "../verifier.hpp"
#include "../signature_verifier.h"
namespace license {
#include "../../base/logger.h"
@@ -26,7 +26,7 @@
    }
}
Verifier::Verifier() {
static void initialize() {
    static int initialized = 0;
    if (initialized == 0) {
        initialized = 1;
@@ -36,13 +36,14 @@
    }
}
FUNCTION_RETURN Verifier::verifySignature(const std::string& stringToVerify, const std::string& signatureB64) {
FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64) {
    EVP_MD_CTX* mdctx = NULL;
    const unsigned char pubKey[] = PUBLIC_KEY;
    int func_ret = 0;
    initialize();
    BIO* bio = BIO_new_mem_buf((void*)(pubKey), PUBLIC_KEY_LEN);
    RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);
    BIO* bio = BIO_new_mem_buf((void*)(pubKey), sizeof(pubKey));
    RSA* rsa = d2i_RSAPublicKey_bio(bio, NULL);
    BIO_free(bio);
    if (rsa == NULL) {
        LOG_ERROR("Error reading public key");
@@ -97,9 +98,6 @@
    free_resources(pkey, mdctx);
    return result;
}
Verifier::~Verifier() {
}
} /* namespace license */
src/library/os/os.c
@@ -6,7 +6,7 @@
#ifdef __linux__
#include <openssl/pem.h>
/*
static void free_resources(EVP_PKEY* pkey, EVP_MD_CTX* mdctx) {
    if (pkey) {
        EVP_PKEY_free(pkey);
@@ -14,8 +14,8 @@
    if (mdctx) {
        EVP_MD_CTX_destroy(mdctx);
    }
}
}*/
/*
FUNCTION_RETURN verifySignature(const char* stringToVerify,
        const char* signatureB64) {
    EVP_MD_CTX *mdctx = NULL;
@@ -37,7 +37,7 @@
     RSA *key = 0;
     PEM_read_bio_RSAPublicKey(bo, &key, 0, 0);
     BIO_free(bo);*/
/*
//RSA* rsa = EVP_PKEY_get1_RSA( key );
//RSA * pubKey = d2i_RSA_PUBKEY(NULL, <der encoded byte stream pointer>, <num bytes>);
    unsigned char buffer[512];
@@ -52,7 +52,6 @@
    BIO_free_all(biosig);
    /* Create the Message Digest Context */
    if (!(mdctx = EVP_MD_CTX_create())) {
        free_resources(pkey, mdctx);
        LOG_ERROR("Error creating context");
@@ -79,7 +78,7 @@
    free_resources(pkey, mdctx);
    return result;
}
}*/
#else
src/library/os/os.h
@@ -77,7 +77,7 @@
VIRTUALIZATION getVirtualization();
void os_initialize();
FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64);
// FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64);
#ifdef _WIN32
#define SETENV(VAR,VAL) _putenv_s(VAR, VAL);
src/library/os/signature_verifier.h
File was renamed from src/library/os/verifier.hpp
@@ -13,13 +13,7 @@
namespace license {
class Verifier {
public:
    Verifier();
    FUNCTION_RETURN verifySignature(const std::string& stringToVerify, const std::string& signatureB64);
    ~Verifier();
};
FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64);
} /* namespace license */
src/library/os/windows/signature_verifier.cpp
File was renamed from src/library/os/windows/verifier.cpp
@@ -1,7 +1,7 @@
/*
 * verifier.cpp
 *
 *  Created on: Nov 15, 2019
 *  Created on: Nov 16, 2019
 *      Author: devel
 */
src/library/pc-identifiers.c
@@ -23,18 +23,15 @@
#endif
#endif
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, bool use_label);
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label);
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, int use_mac);
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac);
static FUNCTION_RETURN generate_default_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers) {
static FUNCTION_RETURN generate_default_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers) {
    size_t adapter_num, disk_num;
    FUNCTION_RETURN result_adapterInfos, result_diskinfos, function_return;
    unsigned int caller_identifiers, i, j, k, array_index;
    DiskInfo * diskInfoPtr;
    DiskInfo *diskInfoPtr;
    OsAdapterInfo *adapterInfoPtr;
    if (identifiers == NULL || *num_identifiers == 0) {
@@ -49,20 +46,17 @@
        *num_identifiers = disk_num * adapter_num;
        function_return = FUNC_RET_OK;
    } else {
        adapterInfoPtr = (OsAdapterInfo*) malloc(
                (*num_identifiers) * sizeof(OsAdapterInfo));
        adapterInfoPtr = (OsAdapterInfo *)malloc((*num_identifiers) * sizeof(OsAdapterInfo));
        adapter_num = *num_identifiers;
        result_adapterInfos = getAdapterInfos(adapterInfoPtr, &adapter_num);
        if (result_adapterInfos != FUNC_RET_OK
                && result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_adapterInfos != FUNC_RET_OK && result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
            free(adapterInfoPtr);
            return generate_disk_pc_id(identifiers, num_identifiers, false);
        }
        diskInfoPtr = (DiskInfo*) malloc((*num_identifiers) * sizeof(DiskInfo));
        diskInfoPtr = (DiskInfo *)malloc((*num_identifiers) * sizeof(DiskInfo));
        disk_num = *num_identifiers;
        result_diskinfos = getDiskInfos(diskInfoPtr, &disk_num);
        if (result_diskinfos != FUNC_RET_OK
                && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
            free(diskInfoPtr);
            free(adapterInfoPtr);
            return generate_ethernet_pc_id(identifiers, num_identifiers, true);
@@ -75,19 +69,18 @@
                array_index = i * adapter_num + j;
                if (array_index >= caller_identifiers) {
                    function_return = FUNC_RET_BUFFER_TOO_SMALL;
                    //sweet memories...
                    // sweet memories...
                    goto end;
                }
                for (k = 0; k < 6; k++)
                    identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2]
                            ^ adapterInfoPtr[j].mac_address[k + 2];
                    identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2] ^ adapterInfoPtr[j].mac_address[k + 2];
            }
        }
end:
    end:
#ifdef _MSC_VER
        *num_identifiers = min(*num_identifiers, adapter_num * disk_num);
        *num_identifiers = min(*num_identifiers, adapter_num * disk_num);
#else
        *num_identifiers = cmin(*num_identifiers, adapter_num * disk_num);
        *num_identifiers = cmin(*num_identifiers, adapter_num * disk_num);
#endif
        free(diskInfoPtr);
        free(adapterInfoPtr);
@@ -95,8 +88,7 @@
    return function_return;
}
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, int use_mac) {
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac) {
    FUNCTION_RETURN result_adapterInfos;
    unsigned int j, k;
    OsAdapterInfo *adapterInfos;
@@ -104,56 +96,50 @@
    if (identifiers == NULL || *num_identifiers == 0) {
        result_adapterInfos = getAdapterInfos(NULL, &adapters);
        if (result_adapterInfos == FUNC_RET_OK
                || result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_adapterInfos == FUNC_RET_OK || result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL) {
            *num_identifiers = adapters;
            result_adapterInfos = FUNC_RET_OK;
        }
    } else {
        defined_adapters = adapters = *num_identifiers;
        adapterInfos = (OsAdapterInfo*) malloc(
                adapters * sizeof(OsAdapterInfo));
        adapterInfos = (OsAdapterInfo *)malloc(adapters * sizeof(OsAdapterInfo));
        result_adapterInfos = getAdapterInfos(adapterInfos, &adapters);
        if (result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL
                || result_adapterInfos == FUNC_RET_OK) {
        if (result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL || result_adapterInfos == FUNC_RET_OK) {
            for (j = 0; j < adapters; j++) {
                for (k = 0; k < 6; k++)
                    if (use_mac) {
                        identifiers[j][k] = adapterInfos[j].mac_address[k + 2];
                    } else {
                        //use ip
                        // use ip
                        if (k < 4) {
                            identifiers[j][k] = adapterInfos[j].ipv4_address[k];
                        } else {
                            //padding
                            // padding
                            identifiers[j][k] = 42;
                        }
                    }
            }
            result_adapterInfos = (
                    adapters > defined_adapters ?
                            FUNC_RET_BUFFER_TOO_SMALL : FUNC_RET_OK);
            result_adapterInfos = (adapters > defined_adapters ? FUNC_RET_BUFFER_TOO_SMALL : FUNC_RET_OK);
        }
        free(adapterInfos);
    }
    return result_adapterInfos;
}
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, bool use_label) {
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label) {
    size_t disk_num, available_disk_info = 0;
    FUNCTION_RETURN result_diskinfos;
    unsigned int i, j;
    int defined_identifiers;
    char firstChar;
    DiskInfo * diskInfos;
    DiskInfo *diskInfos;
    result_diskinfos = getDiskInfos(NULL, &disk_num);
    if (result_diskinfos != FUNC_RET_OK) {
        return result_diskinfos;
    }
    diskInfos = (DiskInfo*) malloc(disk_num * sizeof(DiskInfo));
    memset(diskInfos,0,disk_num * sizeof(DiskInfo));
    diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
    memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
    result_diskinfos = getDiskInfos(diskInfos, &disk_num);
    if (result_diskinfos != FUNC_RET_OK) {
        free(diskInfos);
@@ -178,15 +164,13 @@
    for (i = 0; i < disk_num; i++) {
        if (use_label) {
            if (diskInfos[i].label[0] != 0) {
                memset(identifiers[j], 0, sizeof(PcIdentifier)); //!!!!!!!
                strncpy((char*)identifiers[j], diskInfos[i].label,
                        sizeof(PcIdentifier));
                memset(identifiers[j], 0, sizeof(PcIdentifier));  //!!!!!!!
                strncpy((char *)identifiers[j], diskInfos[i].label, sizeof(PcIdentifier));
                j++;
            }
        } else {
            if (diskInfos[i].disk_sn[0] != 0) {
                memcpy(identifiers[j], &diskInfos[i].disk_sn[2],
                        sizeof(PcIdentifier));
                memcpy(identifiers[j], &diskInfos[i].disk_sn[2], sizeof(PcIdentifier));
                j++;
            }
        }
@@ -211,43 +195,42 @@
 * @return
 */
FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers,
        unsigned int * array_size, IDENTIFICATION_STRATEGY strategy) {
FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, IDENTIFICATION_STRATEGY strategy) {
    FUNCTION_RETURN result;
    unsigned int i, j;
    const unsigned int original_array_size = *array_size;
    unsigned char strategy_num;
    switch (strategy) {
    case DEFAULT:
        result = generate_default_pc_id(identifiers, array_size);
        break;
    case ETHERNET:
        result = generate_ethernet_pc_id(identifiers, array_size, true);
        break;
    case IP_ADDRESS:
        result = generate_ethernet_pc_id(identifiers, array_size, false);
        break;
    case DISK_NUM:
        result = generate_disk_pc_id(identifiers, array_size, false);
        break;
    case DISK_LABEL:
        result = generate_disk_pc_id(identifiers, array_size, true);
        break;
    default:
        return FUNC_RET_ERROR;
        case DEFAULT:
            result = generate_default_pc_id(identifiers, array_size);
            break;
        case ETHERNET:
            result = generate_ethernet_pc_id(identifiers, array_size, true);
            break;
        case IP_ADDRESS:
            result = generate_ethernet_pc_id(identifiers, array_size, false);
            break;
        case DISK_NUM:
            result = generate_disk_pc_id(identifiers, array_size, false);
            break;
        case DISK_LABEL:
            result = generate_disk_pc_id(identifiers, array_size, true);
            break;
        default:
            return FUNC_RET_ERROR;
    }
    if (result == FUNC_RET_OK && identifiers != NULL) {
        strategy_num = strategy << 5;
        for (i = 0; i < *array_size; i++) {
            //encode strategy in the first three bits of the pc_identifier
            // encode strategy in the first three bits of the pc_identifier
            identifiers[i][0] = (identifiers[i][0] & 15) | strategy_num;
        }
        //fill array if larger
        // fill array if larger
        for (i = *array_size; i < original_array_size; i++) {
            identifiers[i][0] = STRATEGY_UNKNOWN << 5;
            for (j = 1; j < sizeof(PcIdentifier); j++) {
                identifiers[i][j] = 42; //padding
                identifiers[i][j] = 42;  // padding
            }
        }
    }
@@ -255,36 +238,33 @@
}
char *MakeCRC(char *BitString) {
    static char Res[3];                                 // CRC Result
    static char Res[3];  // CRC Result
    char CRC[2];
    int i;
    char DoInvert;
    for (i = 0; i < 2; ++i)
        CRC[i] = 0;                    // Init before calculation
    for (i = 0; i < 2; ++i) CRC[i] = 0;  // Init before calculation
    for (i = 0; i < strlen(BitString); ++i) {
        DoInvert = ('1' == BitString[i]) ^ CRC[1];         // XOR required?
        DoInvert = ('1' == BitString[i]) ^ CRC[1];  // XOR required?
        CRC[1] = CRC[0];
        CRC[0] = DoInvert;
    }
    for (i = 0; i < 2; ++i)
        Res[1 - i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
    Res[2] = 0;                                         // Set string terminator
    for (i = 0; i < 2; ++i) Res[1 - i] = CRC[i] ? '1' : '0';  // Convert binary to ASCII
    Res[2] = 0;  // Set string terminator
    return (Res);
}
FUNCTION_RETURN encode_pc_id(PcIdentifier identifier1, PcIdentifier identifier2,
        PcSignature pc_identifier_out) {
    //TODO base62 encoding, now uses base64
FUNCTION_RETURN encode_pc_id(PcIdentifier identifier1, PcIdentifier identifier2, PcSignature pc_identifier_out) {
    // TODO base62 encoding, now uses base64
    PcIdentifier concat_identifiers[2];
    char* b64_data = NULL;
    char *b64_data = NULL;
    int b64_size = 0;
    const size_t concatIdentifiersSize = sizeof(PcIdentifier) * 2;
    //concat_identifiers = (PcIdentifier *) malloc(concatIdentifiersSize);
    // concat_identifiers = (PcIdentifier *) malloc(concatIdentifiersSize);
    memcpy(&concat_identifiers[0], identifier1, sizeof(PcIdentifier));
    memcpy(&concat_identifiers[1], identifier2, sizeof(PcIdentifier));
    b64_data = base64(concat_identifiers, concatIdentifiersSize, &b64_size);
@@ -292,21 +272,17 @@
        free(b64_data);
        return FUNC_RET_BUFFER_TOO_SMALL;
    }
    sprintf(pc_identifier_out, "%.4s-%.4s-%.4s-%.4s", &b64_data[0],
            &b64_data[4], &b64_data[8], &b64_data[12]);
    //free(concat_identifiers);
    sprintf(pc_identifier_out, "%.4s-%.4s-%.4s-%.4s", &b64_data[0], &b64_data[4], &b64_data[8], &b64_data[12]);
    // free(concat_identifiers);
    free(b64_data);
    return FUNC_RET_OK;
}
FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) {
    return FUNC_RET_OK;
}
FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) { return FUNC_RET_OK; }
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out,
        IDENTIFICATION_STRATEGY strategy) {
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, IDENTIFICATION_STRATEGY strategy) {
    FUNCTION_RETURN result;
    PcIdentifier* identifiers;
    PcIdentifier *identifiers;
    unsigned int req_buffer_size = 0;
    result = generate_pc_id(NULL, &req_buffer_size, strategy);
    if (result != FUNC_RET_OK) {
@@ -316,8 +292,7 @@
        return FUNC_RET_ERROR;
    }
    req_buffer_size = req_buffer_size < 2 ? 2 : req_buffer_size;
    identifiers = (PcIdentifier *) malloc(
            sizeof(PcIdentifier) * req_buffer_size);
    identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * req_buffer_size);
    memset(identifiers, 0, sizeof(PcIdentifier) * req_buffer_size);
    result = generate_pc_id(identifiers, &req_buffer_size, strategy);
    if (result != FUNC_RET_OK) {
@@ -343,40 +318,38 @@
 * @param str_code: the code in the string format XXXX-XXXX-XXXX-XXXX
 * @return
 */
static FUNCTION_RETURN decode_pc_id(PcIdentifier identifier1_out,
        PcIdentifier identifier2_out, PcSignature pc_signature_in) {
    //TODO base62 encoding, now uses base64
static FUNCTION_RETURN decode_pc_id(PcIdentifier identifier1_out, PcIdentifier identifier2_out,
                                    PcSignature pc_signature_in) {
    // TODO base62 encoding, now uses base64
    unsigned char * concat_identifiers = NULL;
    unsigned char *concat_identifiers = NULL;
    char base64ids[17];
    int identifiers_size;
    sscanf(pc_signature_in, "%4s-%4s-%4s-%4s", &base64ids[0], &base64ids[4],
            &base64ids[8], &base64ids[12]);
    sscanf(pc_signature_in, "%4s-%4s-%4s-%4s", &base64ids[0], &base64ids[4], &base64ids[8], &base64ids[12]);
    concat_identifiers = unbase64(base64ids, 16, &identifiers_size);
    if (identifiers_size > sizeof(PcIdentifier) * 2) {
        free(concat_identifiers);
        return FUNC_RET_BUFFER_TOO_SMALL;
    }
    memcpy(identifier1_out, concat_identifiers, sizeof(PcIdentifier));
    memcpy(identifier2_out, concat_identifiers + sizeof(PcIdentifier),
            sizeof(PcIdentifier));
    memcpy(identifier2_out, concat_identifiers + sizeof(PcIdentifier), sizeof(PcIdentifier));
    free(concat_identifiers);
    return FUNC_RET_OK;
}
static IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
    return (IDENTIFICATION_STRATEGY) identifier[0] >> 5;
    return (IDENTIFICATION_STRATEGY)identifier[0] >> 5;
}
EVENT_TYPE validate_pc_signature(PcSignature str_code) {
    PcIdentifier user_identifiers[2];
    FUNCTION_RETURN result;
    IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
    PcIdentifier* calculated_identifiers = NULL;
    PcIdentifier *calculated_identifiers = NULL;
    unsigned int calc_identifiers_size = 0;
    int i = 0, j = 0;
    //bool found;
    // bool found;
#ifdef _DEBUG
    printf("Comparing pc identifiers: \n");
#endif
@@ -385,14 +358,14 @@
        return result;
    }
    previous_strategy_id = STRATEGY_UNKNOWN;
    //found = false;
    // found = false;
    for (i = 0; i < 2; i++) {
        current_strategy_id = strategy_from_pc_id(user_identifiers[i]);
        if (current_strategy_id == STRATEGY_UNKNOWN && previous_strategy_id == STRATEGY_UNKNOWN && i==1) {
        if (current_strategy_id == STRATEGY_UNKNOWN && previous_strategy_id == STRATEGY_UNKNOWN && i == 1) {
            free(calculated_identifiers);
            printf("Comparing pc identifiers: %d %d %d %s\n",current_strategy_id,previous_strategy_id,i, str_code);
            printf("Comparing pc identifiers: %d %d %d %s\n", current_strategy_id, previous_strategy_id, i, str_code);
            return LICENSE_MALFORMED;
        } else if (current_strategy_id == STRATEGY_UNKNOWN ){
        } else if (current_strategy_id == STRATEGY_UNKNOWN) {
            continue;
        }
        if (current_strategy_id != previous_strategy_id) {
@@ -401,23 +374,22 @@
            }
            previous_strategy_id = current_strategy_id;
            generate_pc_id(NULL, &calc_identifiers_size, current_strategy_id);
            calculated_identifiers = (PcIdentifier *) malloc(
                    sizeof(PcIdentifier) * calc_identifiers_size);
            calculated_identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * calc_identifiers_size);
            memset(calculated_identifiers, 0, sizeof(PcIdentifier) * calc_identifiers_size);
            generate_pc_id(calculated_identifiers, &calc_identifiers_size,
                    current_strategy_id);
            generate_pc_id(calculated_identifiers, &calc_identifiers_size, current_strategy_id);
        }
        //maybe skip the byte 0
        // maybe skip the byte 0
        for (j = 0; j < calc_identifiers_size; j++) {
#ifdef _DEBUG
            printf("generated id: %02x%02x%02x%02x%02x%02x index %d, user_supplied id %02x%02x%02x%02x%02x%02x idx: %d\n",
                    calculated_identifiers[j][0], calculated_identifiers[j][1], calculated_identifiers[j][2],
                    calculated_identifiers[j][3], calculated_identifiers[j][4], calculated_identifiers[j][5], j,
                    user_identifiers[i][0], user_identifiers[i][1], user_identifiers[i][2], user_identifiers[i][3], user_identifiers[i][4], user_identifiers[i][5], i);
            printf(
                "generated id: %02x%02x%02x%02x%02x%02x index %d, user_supplied id %02x%02x%02x%02x%02x%02x idx: %d\n",
                calculated_identifiers[j][0], calculated_identifiers[j][1], calculated_identifiers[j][2],
                calculated_identifiers[j][3], calculated_identifiers[j][4], calculated_identifiers[j][5], j,
                user_identifiers[i][0], user_identifiers[i][1], user_identifiers[i][2], user_identifiers[i][3],
                user_identifiers[i][4], user_identifiers[i][5], i);
#endif
            if (!memcmp(user_identifiers[i], calculated_identifiers[j],
                    sizeof(PcIdentifier))) {
            if (!memcmp(user_identifiers[i], calculated_identifiers[j], sizeof(PcIdentifier))) {
                free(calculated_identifiers);
                return LICENSE_OK;
            }
src/library/pc-identifiers.h
@@ -2,12 +2,13 @@
 * pc-identifiers.h
 *
 *  Created on: Apr 16, 2014
 *
 *
 */
#ifndef PC_IDENTIFIERS_H_
#define PC_IDENTIFIERS_H_
#include "api/datatypes.h"
#include <licensecc/datatypes.h>
#include "base/base.h"
#ifdef __cplusplus
src/templates/licensecc_properties.h.in
@@ -1,6 +1,7 @@
#ifndef BUILD_PROPERTIES_H_
#define BUILD_PROPERTIES_H_
#define LCC_PROJECT_NAME "@LCC_PROJECT_NAME@"
#define PROJECT_INT_VERSION @LICENSECC_INT_VERSION@
#define PROJECT_VERSION "@LICENSECC_VERSION@"
@@ -11,6 +12,11 @@
#define LICENSE_LOCATION_ENV_VAR "LICENSE_LOCATION"
#define LICENSE_DATA_ENV_VAR "LICENSE_DATA"
//define api structure sizes
#define PC_IDENTIFIER_SIZE 18
#define PROPRIETARY_DATA_SIZE 16
#define AUDIT_EVENT_NUM 5
//Internal data structures limits
#define MAX_LICENSE_LENGTH 256*1024
src/templates/licensecc_properties_test.h.in
@@ -8,6 +8,20 @@
#define PROJECT_TEST_SRC_DIR "@CMAKE_SOURCE_DIR@/test"
#define PROJECT_TEST_TEMP_DIR "@CMAKE_BINARY_DIR@/Testing/Temporary"
#define BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#define LCC_EXE "@LCC_EXECUTABLE@"
#define LCC_EXE "$<TARGET_FILE:license_generator::lcc>"
#define LCC_TEST_LICENSES_PROJECT "@CMAKE_BINARY_DIR@/Testing/Temporary/@LCC_PROJECT_NAME@"
#define LCC_LICENSES_BASE LCC_TEST_LICENSES_PROJECT "/licenses"
#define LCC_PROJECTS_BASE_DIR "@LCC_PROJECTS_BASE_DIR@"
#define LCC_PROJECT_PRIVATE_KEY "@LCC_PROJECT_PRIVATE_KEY@"
/*
 * command line parameters
 */
#define PARAM_BASE64 "base64"
#define PARAM_LICENSE_NAME "license-name"
#define PARAM_PRODUCT_NAME "product-name"
#define PARAM_PROJECT_FOLDER "project-folder"
#define PARAM_PRIMARY_KEY "primary-key"
#endif
test/CMakeLists.txt
@@ -1,7 +1,17 @@
#if we're here boost has been found
add_definitions(-DBOOST_ALL_NO_LIB) #Disable Boost Microsoft magic, all dependencies are handled by cmake
add_definitions(-DBOOST_LIB_DIAGNOSTIC) #Check it is really disabled
include_directories(${Boost_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
link_directories ( ${Boost_LIBRARY_DIR} )
configure_file (
    "${CMAKE_CURRENT_SOURCE_DIR}/../src/templates/licensecc_properties_test.h.in"
    "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp"
)
file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/licensecc_properties_test.h"
        INPUT "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp")
add_subdirectory(library)
#add_subdirectory(functional)
add_subdirectory(functional)
test/functional/CMakeLists.txt
@@ -32,6 +32,19 @@
)
add_executable(
 test_signature_verifier
 signature_verifier_test.cpp
)
target_link_libraries(
 test_signature_verifier
 licensecc_static
 license_generator_snippet
 ${Boost_LIBRARIES}
)
add_executable(
 test_volid
 volid_test.cpp
)
@@ -43,16 +56,10 @@
 ${Boost_LIBRARIES}
)
#set CROSSCOMPILING_EMULATOR
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING)
#binfmt_misc doesn't work in my system :(
    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 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()
ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_signature_verifier COMMAND test_signature_verifier WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_volid COMMAND test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
test/functional/date_test.cpp
@@ -3,9 +3,10 @@
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <build_properties.h>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
@@ -13,9 +14,10 @@
using namespace license;
using namespace std;
namespace license {
namespace test {
BOOST_AUTO_TEST_CASE( license_not_expired ) {
BOOST_AUTO_TEST_CASE(license_not_expired) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/not_expired.lic");
    vector<string> extraArgs;
    extraArgs.push_back("-e");
@@ -26,14 +28,13 @@
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
}
BOOST_AUTO_TEST_CASE( license_expired ) {
BOOST_AUTO_TEST_CASE(license_expired) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/expired.lic");
    remove(licLocation.c_str());
    vector<string> extraArgs;
@@ -46,11 +47,11 @@
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = nullptr;
    BOOST_TEST_MESSAGE("before acquire license");
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, PRODUCT_EXPIRED);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
}
}
}  // namespace test
}  // namespace license
test/functional/generate-license.cpp
@@ -6,36 +6,78 @@
 */
#include <boost/test/unit_test.hpp>
#include <build_properties.h>
#include <boost/filesystem.hpp>
#include <sstream>
#include <iostream>
#include "../../src/tools/license-generator/license-generator.h"
#include <licensecc_properties_test.h>
#include "../../src/library/base/base.h"
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
void generate_license(const string& fname, const vector<string>& other_args) {
    remove(fname.c_str());
    const int argc = 4+other_args.size();
    const char** argv = new const char*[argc + 1];
    unsigned int i=0;
    argv[i++] = "lic-generator";
    for(;i<=other_args.size();i++){
        argv[i] = other_args[i-1].c_str();
namespace license {
namespace test {
string generate_license(const string& license_name, const vector<string>& other_args) {
    fs::path lcc_exe(LCC_EXE);
    BOOST_REQUIRE_MESSAGE(fs::is_regular_file(lcc_exe), "License generator not found: " LCC_EXE);
    fs::path licenses_base(LCC_LICENSES_BASE);
    if (!fs::exists(licenses_base)) {
        BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string());
    }
    argv[i++] = "-o";
    argv[i++] = fname.c_str();
    argv[i++] = "TEST";
    const int retCode = LicenseGenerator::generateLicense(argc, argv);
    delete[] (argv);
    fs::path license_fname(licenses_base / (license_name + ".lic"));
    remove(license_fname.c_str());
    stringstream ss;
    ss << LCC_EXE << " license issue";
    ss << " --" PARAM_PRIMARY_KEY " " << LCC_PROJECT_PRIVATE_KEY;
    ss << " --" PARAM_LICENSE_NAME " " << license_name;
    ss << " --" PARAM_PROJECT_FOLDER " " << LCC_TEST_LICENSES_PROJECT;
    for (int i = 0; i < other_args.size(); i++) {
        ss << " " << other_args[i];
    }
    cout << "executing :" << ss.str() << endl;
    const int retCode = std::system(ss.str().c_str());
    BOOST_CHECK_EQUAL(retCode, 0);
    BOOST_ASSERT(fs::exists(fname));
    BOOST_ASSERT(fs::exists(license_fname));
    CSimpleIniA ini;
    const SI_Error rc = ini.LoadFile(fname.c_str());
    BOOST_CHECK_GE(rc,0);
    const int sectionSize = ini.GetSectionSize("TEST");
    BOOST_CHECK_GT(sectionSize,0);
    const SI_Error rc = ini.LoadFile(license_fname.c_str());
    BOOST_CHECK_GE(rc, 0);
    const int sectionSize = ini.GetSectionSize("DEFAULT");
    BOOST_CHECK_GT(sectionSize, 0);
    return license_fname.string();
}
string sign_data(const string& data, const string& test_name) {
    fs::path lcc_exe(LCC_EXE);
    BOOST_REQUIRE_MESSAGE(fs::is_regular_file(lcc_exe), "License generator not found: " LCC_EXE);
    fs::path licenses_base(LCC_LICENSES_BASE);
    if (!fs::exists(licenses_base)) {
        BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string());
    }
    fs::path outputFile(fs::path(PROJECT_TEST_TEMP_DIR) / (test_name + ".tmp"));
    remove(outputFile.c_str());
    stringstream ss;
    ss << LCC_EXE << " test sign";
    ss << " --" PARAM_PRIMARY_KEY " " << LCC_PROJECT_PRIVATE_KEY;
    ss << " -d " << data;
    ss << " -o " << outputFile.string();
    cout << "executing :" << ss.str() << endl;
    const int retCode = std::system(ss.str().c_str());
    BOOST_CHECK_EQUAL(retCode, 0);
    BOOST_ASSERT(fs::exists(outputFile));
    std::ifstream ifs(outputFile.c_str());
    std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
    return content;
}
}  // namespace test
}  // namespace license
test/functional/generate-license.h
@@ -1,5 +1,11 @@
#include<string>
#include<vector>
#include <string>
#include <vector>
using namespace std;
void generate_license(const string& fname, const vector<string>& other_args);
namespace license {
namespace test {
std::string generate_license(const std::string& fname, const std::vector<std::string>& other_args);
std::string sign_data(const std::string& data, const std::string& test_name);
}  // namespace test
}  // namespace license
test/functional/hijiaking_test.cpp
@@ -5,7 +5,7 @@
#include <boost/test/unit_test.hpp>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
test/functional/signature_verifier_test.cpp
New file
@@ -0,0 +1,46 @@
/*
 * LicenseVerifier_test.cpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#define BOOST_TEST_MODULE test_signature_verifier
#include <boost/test/unit_test.hpp>
#include <licensecc_properties_test.h>
#include <licensecc_properties.h>
#include "../../src/library/os/signature_verifier.h"
#include "generate-license.h"
namespace license {
namespace test {
using namespace std;
BOOST_AUTO_TEST_CASE(verify_signature_ok) {
    const string test_data("test_data");
    const string signature = sign_data(test_data, string("verify_signature"));
    FUNCTION_RETURN result = license::verify_signature(test_data, signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_OK, "signature verified");
}
BOOST_AUTO_TEST_CASE(verify_signature_data_mismatch) {
    const string test_data("test_data");
    const string signature = sign_data(test_data, string("verify_signature"));
    FUNCTION_RETURN result = license::verify_signature(string("other data"), signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
}
BOOST_AUTO_TEST_CASE(verify_signature_modified) {
    const string test_data("test_data");
    string signature = sign_data(test_data, string("verify_signature"));
    signature[2] = signature[2] + 1;
    FUNCTION_RETURN result = license::verify_signature(test_data, signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
}
}  // namespace test
} /* namespace license */
test/functional/standard-license_test.cpp
@@ -3,29 +3,29 @@
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <build_properties.h>
#include <licensecc/licensecc.h>
#include <licensecc_properties_test.h>
#include <licensecc_properties.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/base/FileUtils.hpp"
namespace license {
namespace test {
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
BOOST_AUTO_TEST_CASE( standard_lic_file ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_license.lic");
    const vector<string> extraArgs;
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("standard_license", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = nullptr;
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
@@ -34,36 +34,38 @@
/**
 * 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);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
}
BOOST_AUTO_TEST_CASE( pc_identifier ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/pc_identifier.lic");
    const vector<string> extraArgs = { "-s", "Jaaa-aaaa-MG9F-ZhB1" };
    generate_license(licLocation, extraArgs);
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    BOOST_CHECK_EQUAL(result, IDENTIFIERS_MISMATCH);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
// 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);
//    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
//}
//
// BOOST_AUTO_TEST_CASE( pc_identifier ) {
//    const string licLocation(PROJECT_TEST_TEMP_DIR "/pc_identifier.lic");
//    const vector<string> extraArgs = { "-s", "Jaaa-aaaa-MG9F-ZhB1" };
//    generate_license(licLocation, extraArgs);
//
//    LicenseInfo license;
//    LicenseLocation licenseLocation;
//    licenseLocation.licenseFileLocation = licLocation.c_str();
//    licenseLocation.licenseData = "";
//    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
//            &license);
//    BOOST_CHECK_EQUAL(result, IDENTIFIERS_MISMATCH);
//    BOOST_CHECK_EQUAL(license.has_expiry, false);
//    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
//}
}
}
}  // namespace license
test/functional/volid_test.cpp
@@ -2,23 +2,27 @@
#include <boost/test/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <cstring>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <boost/filesystem.hpp>
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/pc-identifiers.h"
#include "../../src/library/os/os.h"
#include "generate-license.h"
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
namespace license {
namespace test {
BOOST_AUTO_TEST_CASE( default_volid_lic_file ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/volid_license.lic");
    PcSignature identifier_out;
    const IDENTIFICATION_STRATEGY strategy = IDENTIFICATION_STRATEGY::ETHERNET;
@@ -32,13 +36,13 @@
    extraArgs.push_back("-s");
    extraArgs.push_back(identifier_out);
    BOOST_TEST_CHECKPOINT("Before generate license");
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("volid_license", extraArgs);
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
@@ -137,3 +141,5 @@
    }
}
}  // namespace test
}  // namespace license
test/library/CMakeLists.txt
@@ -70,17 +70,3 @@
ELSE()
    ADD_TEST(NAME test_event_registry COMMAND test_event_registry)
ENDIF()
### verifier tests
add_executable(
 test_verifier
 verifier_test.cpp
)
target_link_libraries(
 test_verifier
 base
 ${Boost_LIBRARIES}
)
ADD_TEST(NAME test_verifier COMMAND test_verfier)
test/library/LicenseReader_test.cpp
@@ -7,8 +7,8 @@
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/datatypes.h>
#include "../../src/library/api/datatypes.h"
#include "../../src/library/base/EventRegistry.h"
#include "../../src/library/os/os.h"
#include "../../src/library/LicenseReader.hpp"
test/library/license_verifier_test.cpp
New file
@@ -0,0 +1,10 @@
/*
 * LicenseVerifier_test.cpp
 *
 *  Created on: Nov 20, 2019
 *      Author: devel
 */
#include "LicenseVerifier.hpp"
namespace license {} /* namespace license */
test/library/verifier_test.cpp
File was deleted