gcontini
2020-01-01 9d7cd404cc2d09c82b65be4828be0ac74eca20a7
cleanup & new api
8个文件已修改
233 ■■■■■ 已修改文件
include/licensecc/datatypes.h 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/licensecc.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/licensecc.cpp 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/date_test.cpp 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/standard-license_test.cpp 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/volid_test.cpp 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/LicenseLocator_test.cpp 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/LicenseReader_test.cpp 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/datatypes.h
@@ -26,6 +26,8 @@
#define PC_IDENTIFIER_SIZE 19
#define PROPRIETARY_DATA_SIZE 16
#define AUDIT_EVENT_NUM 5
#define API_LICENSE_DATA_LENGTH 1024 * 4
#define API_VERSION_LENGTH 16
typedef enum {
    LICENSE_OK = 0,  // OK
@@ -62,6 +64,22 @@
    char param2[256];
} AuditEvent;
typedef enum {
    /**
     * A list of absolute path separated by ';' containing the eventual location
     * of the license files. Can be NULL.
     */
    LICENSE_PATH,
    /**
     * The license is provided as plain data
     */
    LICENSE_PLAIN_DATA,
    /**
     * The license is encoded
     */
    LICENSE_ENCODED
} LICENSE_DATA_TYPE;
/**
 * This structure contains informations on the raw license data. Software authors
 * can specify the location of the license file or its full content.
@@ -70,25 +88,23 @@
 * 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;
    LICENSE_DATA_TYPE license_data_type;
    char licenseData[API_LICENSE_DATA_LENGTH];
} LicenseLocation;
/**
 * Informations on the software requiring the license
 */
typedef struct {
    char version[16];  // software version in format xxxx.xxxx.xxxx
    char version[API_VERSION_LENGTH];  // software version in format xxxx[.xxxx.xxxx] //TODO
    char project_name[16];  // name of the project (must correspond to the name in the license)
    uint32_t magic;  // reserved
    /**
     * this number passed in by the application must correspond to the magic number used when compiling the library.
     * See cmake parameter -DLCC_PROJECT_MAGIC_NUM and licensecc_properties.h macro VERIFY_MAGIC
     */
    unsigned int magic;
} CallerInformations;
typedef struct {
    /**
     * Detailed reason of success/failure. Reasons for a failure can be
@@ -117,13 +133,13 @@
 * in most cases.
 */
typedef enum {
    STRATEGY_DEFAULT,
    STRATEGY_ETHERNET,
    STRATEGY_IP_ADDRESS,
    STRATEGY_DISK_NUM,
    STRATEGY_DISK_LABEL,
    STRATEGY_PLATFORM_SPECIFIC,
    STRATEGY_UNKNOWN
    STRATEGY_DEFAULT = -1,
    STRATEGY_ETHERNET = 0,
    STRATEGY_IP_ADDRESS = 1,
    STRATEGY_DISK_NUM = 1,
    STRATEGY_DISK_LABEL = 2,
    STRATEGY_PLATFORM_SPECIFIC = 3,
    STRATEGY_UNKNOWN = -2
} IDENTIFICATION_STRATEGY;
#ifdef __cplusplus
include/licensecc/licensecc.h
@@ -2,8 +2,8 @@
#define LICENSEPP_H_
/*
 * This include file is the public api di License++
*/
 * This include file is the public api di Licensecc
 */
#ifdef __cplusplus
extern "C" {
#endif
@@ -20,7 +20,7 @@
 * This method calculate the pc identifier. The string has to be shown
 * to the user in order to calculate the license.
 */
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* identifier_out, size_t bufSize);
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* identifier_out, size_t* bufSize);
/**
 * This method is used to request the use of one license for a product.
src/library/licensecc.cpp
@@ -25,12 +25,14 @@
using namespace std;
void print_error(char out_buffer[256], LicenseInfo* licenseInfo) {}
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t bufSize) {
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t* bufSize) {
    FUNCTION_RETURN result = FUNC_RET_BUFFER_TOO_SMALL;
    if (bufSize >= sizeof(PcSignature)) {
    if (*bufSize >= sizeof(PcSignature)) {
        PcSignature identifier_out;
        result = generate_user_pc_signature(identifier_out, pc_id_method);
        strncpy(chbuffer, identifier_out, bufSize);
        strncpy(chbuffer, identifier_out, *bufSize);
    } else {
        *bufSize = sizeof(PcSignature);
    }
    return result == FUNC_RET_OK;
}
@@ -69,16 +71,20 @@
        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);
        for (auto full_lic_info_it = licenses.begin(); full_lic_info_it != licenses.end(); full_lic_info_it++) {
            if (callerInformation != nullptr) {
                full_lic_info_it->m_magic = callerInformation->magic;
            }
            const FUNCTION_RETURN signatureValid = verifier.verify_signature(*full_lic_info_it);
            LicenseInfo licInfo = verifier.toLicenseInfo(*full_lic_info_it);
            if (signatureValid == FUNC_RET_OK) {
                if (verifier.verify_limits(*it) == FUNC_RET_OK) {
                    licenses_ok.push_back(verifier.toLicenseInfo(*it));
                if (verifier.verify_limits(*full_lic_info_it) == FUNC_RET_OK) {
                    licenses_ok.push_back(licInfo);
                } else {
                    licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
                    licenses_with_errors.push_back(licInfo);
                }
            } else {
                licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
                licenses_with_errors.push_back(licInfo);
            }
        }
        if (licenses_ok.size() > 0) {
test/functional/date_test.cpp
@@ -24,10 +24,10 @@
    const string licLocation = generate_license("not_expired.lic", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    LicenseLocation location = {LICENSE_PATH};
    std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
    const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
@@ -41,11 +41,10 @@
    const string licLocation = generate_license("expired", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = nullptr;
    LicenseLocation location = {LICENSE_PATH};
    std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
    BOOST_TEST_MESSAGE("before acquire license");
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
    BOOST_CHECK_EQUAL(result, PRODUCT_EXPIRED);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
test/functional/standard-license_test.cpp
@@ -18,17 +18,34 @@
using namespace std;
/**
 * Test a generic license with no expiry neither client id.
 * Test a generic license with no expiry neither client id. The license is read from file
 */
BOOST_AUTO_TEST_CASE(test_generic_license) {
BOOST_AUTO_TEST_CASE(test_generic_license_read_file) {
    const vector<string> 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(nullptr, &licenseLocation, &license);
    LicenseLocation location = {LICENSE_PATH};
    std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
    const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
}
/**
 * Test a generic license with no expiry neither client id. The license is passed in trhough the licenseData structure.
 */
BOOST_AUTO_TEST_CASE(test_read_license_data) {
    const vector<string> extraArgs;
    const fs::path licLocation = fs::path(generate_license("standard_license1", extraArgs));
    string license_data;
    // load the license string
    fs::load_string_file(licLocation, license_data);
    LicenseInfo license;
    LicenseLocation location = {LICENSE_PLAIN_DATA};
    std::copy(license_data.begin(), license_data.end(), location.licenseData);
    const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
test/functional/volid_test.cpp
@@ -22,13 +22,12 @@
namespace license {
namespace test {
BOOST_AUTO_TEST_CASE( default_volid_lic_file ) {
BOOST_AUTO_TEST_CASE(default_volid_lic_file) {
    PcSignature identifier_out;
    const IDENTIFICATION_STRATEGY strategy = IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET;
    BOOST_TEST_CHECKPOINT("Before generate");
    const FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out,
            strategy);
    const FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out, strategy);
    BOOST_TEST_CHECKPOINT("After generate signature");
    BOOST_ASSERT(generate_ok == FUNCTION_RETURN::FUNC_RET_OK);
    cout << "Identifier:" << identifier_out << endl;
@@ -39,25 +38,22 @@
    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(nullptr, &licenseLocation, &license);
    LicenseLocation location = {LICENSE_PATH};
    std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
    const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
}
static void generate_reference_file(const string &idfileLocation,
        IDENTIFICATION_STRATEGY strategies[], int num_strategies) {
static void generate_reference_file(const string &idfileLocation, IDENTIFICATION_STRATEGY strategies[],
                                    int num_strategies) {
    ofstream idfile(idfileLocation);
    PcSignature identifier_out;
    for (int i = 0; i < num_strategies; i++) {
        FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out,
                strategies[i]);
        FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out, strategies[i]);
        if (generate_ok != FUNC_RET_OK) {
            BOOST_ERROR(
                    "Generating identifier for strategy " << strategies[i] << " failed with: " << generate_ok);
            BOOST_ERROR("Generating identifier for strategy " << strategies[i] << " failed with: " << generate_ok);
            idfile << "0000-0000-0000-0000" << endl;
            BOOST_ASSERT(generate_ok == FUNC_RET_OK);
        } else
@@ -71,69 +67,61 @@
    std::vector<IDENTIFICATION_STRATEGY> strategies;
    size_t disk_num;
    getDiskInfos(NULL, &disk_num);
    if (disk_num >0) {
    if (disk_num > 0) {
        strategies = {STRATEGY_DEFAULT, STRATEGY_DISK_NUM, STRATEGY_DISK_LABEL};
    } else {
        BOOST_TEST_CHECKPOINT("if no disk default strategy fails see #49");
        //strategies = { DEFAULT };
        // strategies = { DEFAULT };
        strategies = {};
    }
    size_t adapters;
    getAdapterInfos(nullptr, &adapters);
    if(adapters > 0){
    if (adapters > 0) {
        strategies.push_back(STRATEGY_ETHERNET);
    }
    size_t num_strategies = strategies.size();
    if(num_strategies == 0) {
        //see issue #49 can't use default
    if (num_strategies == 0) {
        // see issue #49 can't use default
        return;
    }
    std::ifstream test_idfile_exist(idfileLocation);
    if (!test_idfile_exist.good()) {
        generate_reference_file(idfileLocation, strategies.data(),
                strategies.size());
        generate_reference_file(idfileLocation, strategies.data(), strategies.size());
    } else {
        std::istream_iterator<string> start(test_idfile_exist), end;
        std::vector<string> reference_signatures(start, end);
        test_idfile_exist.close();
        if (reference_signatures.size() != num_strategies
                || std::find(reference_signatures.begin(),
                        reference_signatures.end(), "0000-0000-0000-0000")
                        != reference_signatures.end())
        if (reference_signatures.size() != num_strategies ||
            std::find(reference_signatures.begin(), reference_signatures.end(), "0000-0000-0000-0000") !=
                reference_signatures.end())
            generate_reference_file(idfileLocation, strategies.data(), num_strategies);
    }
    std::ifstream is(idfileLocation);
    std::istream_iterator<string> start(is), end;
    std::vector<string> reference_signatures(start, end);
    BOOST_TEST_CHECKPOINT(
            "Generating current signatures and comparing with past");
    BOOST_TEST_CHECKPOINT("Generating current signatures and comparing with past");
    for (int i = 0; i < num_strategies; i++) {
        PcSignature generated_identifier;
        FUNCTION_RETURN generate_ok = generate_user_pc_signature(
                generated_identifier, strategies[i]);
        FUNCTION_RETURN generate_ok = generate_user_pc_signature(generated_identifier, strategies[i]);
        BOOST_ASSERT(generate_ok == FUNCTION_RETURN::FUNC_RET_OK);
        if (generate_ok != FUNC_RET_OK) {
            BOOST_ERROR(
                    "Generating identifier for strategy " << strategies[i] << " failed with: " << generate_ok);
            BOOST_ERROR("Generating identifier for strategy " << strategies[i] << " failed with: " << generate_ok);
            continue;
        }
        if (reference_signatures[i] != generated_identifier) {
            string message = string("pc signature compare fail: strategy: ")
                    + to_string(static_cast<long long>(strategies[i]))
                    + " generated: [" + generated_identifier + "] reference: ["
                    + reference_signatures[i] + "]";
            string message = string("pc signature compare fail: strategy: ") +
                             to_string(static_cast<long long>(strategies[i])) + " generated: [" + generated_identifier +
                             "] reference: [" + reference_signatures[i] + "]";
            BOOST_ERROR(message);
        }
    }
    BOOST_TEST_CHECKPOINT("Verifying signatures");
    for (int j = 0; j < 100; j++) {
        for (unsigned int i = 0; i < reference_signatures.size(); i++) {
            if (reference_signatures[i] == "0000-0000-0000-0000")
                continue;
            if (reference_signatures[i] == "0000-0000-0000-0000") continue;
            PcSignature pcsig;
            strncpy(pcsig, reference_signatures[i].c_str(),
                    sizeof(PcSignature) - 1);
            strncpy(pcsig, reference_signatures[i].c_str(), sizeof(PcSignature) - 1);
            EVENT_TYPE val_result = validate_pc_signature(pcsig);
            BOOST_TEST_CHECKPOINT("Verifying signature: ");
            BOOST_CHECK_EQUAL(val_result, LICENSE_OK);
test/library/LicenseLocator_test.cpp
@@ -1,10 +1,11 @@
#define BOOST_TEST_MODULE "test_license_locator"
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <iostream>
#include <iterator>
#include <cstdio>
#include <fstream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
@@ -88,13 +89,14 @@
BOOST_AUTO_TEST_CASE(external_definition) {
    // an application can define multiple license locations separated by ';'
    const char *applicationDefinedString = MOCK_LICENSE ";/this/one/doesnt/exist";
    string applicationDefinedString = MOCK_LICENSE ";/this/one/doesnt/exist";
    // read test license
    std::ifstream src(MOCK_LICENSE, std::ios::binary);
    std::string referenceContent((std::istreambuf_iterator<char>(src)), std::istreambuf_iterator<char>());
    license::EventRegistry registry;
    const LicenseLocation licLocation = {applicationDefinedString, nullptr};
    LicenseLocation licLocation = {LICENSE_PATH};
    std::copy(applicationDefinedString.begin(), applicationDefinedString.end(), licLocation.licenseData);
    ExternalDefinition externalDefinition(&licLocation);
    vector<string> licenseInfos = externalDefinition.license_locations(registry);
    BOOST_CHECK(registry.isGood());
@@ -109,9 +111,10 @@
 * 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";
    string applicationDefinedString = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
    license::EventRegistry registry;
    const LicenseLocation licLocation = {applicationDefinedString, nullptr};
    LicenseLocation licLocation = {LICENSE_PATH};
    std::copy(applicationDefinedString.begin(), applicationDefinedString.end(), licLocation.licenseData);
    ExternalDefinition externalDefinition(&licLocation);
    vector<string> licenseInfos = externalDefinition.license_locations(registry);
test/library/LicenseReader_test.cpp
@@ -1,4 +1,7 @@
#define BOOST_TEST_MODULE "test_license_reader"
#define __STDC_WANT_LIB_EXT1__ 1
#include <string>
#include <boost/test/unit_test.hpp>
#include <iostream>
@@ -22,10 +25,11 @@
 * Read license at application provided location
 */
BOOST_AUTO_TEST_CASE(read_single_file) {
    const char *licLocation = PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    string location = PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    const LicenseLocation location = {licLocation, nullptr};
    LicenseReader licenseReader(&location);
    LicenseLocation licLocation = {LICENSE_PATH};
    std::copy(location.begin(), location.end(), licLocation.licenseData);
    LicenseReader licenseReader(&licLocation);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PrODUCT", licenseInfos);
    BOOST_CHECK(registry.isGood());
@@ -36,9 +40,10 @@
 * 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};
    LicenseReader licenseReader(&location);
    string location = PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    LicenseLocation licLocation = {LICENSE_PATH};
    std::copy(location.begin(), location.end(), licLocation.licenseData);
    LicenseReader licenseReader(&licLocation);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT-NOT", licenseInfos);
    BOOST_CHECK(!registry.isGood());
@@ -51,11 +56,12 @@
 * 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";
    string licLocation = PROJECT_TEST_SRC_DIR "/library/not_found.ini";
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(false);
    const LicenseLocation location = {licLocation, nullptr};
    LicenseLocation location = {LICENSE_PATH};
    std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
@@ -70,10 +76,9 @@
 */
BOOST_AUTO_TEST_CASE(env_var_not_defined) {
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
    const LicenseLocation location = {nullptr, nullptr};
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(true);
    LicenseReader licenseReader(&location);
    LicenseReader licenseReader(nullptr);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
    BOOST_CHECK(!registry.isGood());
@@ -93,8 +98,7 @@
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(true);
    const LicenseLocation location = {nullptr, nullptr};
    LicenseReader licenseReader(&location);
    LicenseReader licenseReader(nullptr);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
    cout << registry << endl;