gcontini
2020-04-25 e047dbe884f5288943d5ba2f8843a078d647d7ef
first docker & vm detection
20个文件已修改
3个文件已添加
1个文件已删除
617 ■■■■ 已修改文件
.travis.yml 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/datatypes.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/licensecc.h 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/inspector/inspector.cpp 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/base64.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/default_strategy.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier.cpp 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier.hpp 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier_facade.cpp 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/licensecc.cpp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/CMakeLists.txt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/cpu_info.hpp 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/cpu_info_common.cpp 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/dmi_info.hpp 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/execution_environment.hpp 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/execution_environment_common.cpp 81 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/dmi_info.cpp 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/execution_environment.cpp 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/os_linux.cpp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/dmi_info.cpp 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/execution_environment.cpp 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/hw_identifier/hw_identifier_test.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/os/execution_environment_test.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/os_linux_test.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.travis.yml
@@ -134,10 +134,10 @@
             - p7zip-full
     before_script:
        - cd build
        - wget -c https://github.com/boostorg/boost/archive/boost-1.71.0.tar.gz
        - tar xzf boost-1.71.0.tar.gz
        - wget -c https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.bz2
        - tar xjf boost_1_71_0.tar.bz2
        - sudo ln -s /usr/bin/x86_64-w64-mingw32-g++ /usr/local/bin/g++-mingw
        - cd boost-boost-1.71.0
        - cd boost_1_71_0
        - ./bootstrap.sh
        - travis_wait 30 ./b2 toolset=gcc-mingw target-os=windows address-model=64 --with-date_time --with-test --with-filesystem --with-program_options --with-regex --with-serialization --with-system runtime-link=static --prefix=./dist release install
        - cd ..
@@ -177,11 +177,10 @@
               echo "Boost already installed"
           else
               echo "Boost not cached, compiling it"
               wget -q https://github.com/boostorg/boost/archive/boost-1.68.0.tar.gz
               wget -q https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.7z
               echo "Boost downloaded"
               7z x boost-1.68.0.tar.gz
               7z x boost-1.68.0.tar
               cd "boost-boost-1.68.0"
               travis_wait 20 7z x boost_1_68_0.7z -oC:/local
               cd "C:/local/boost_1_68_0"
               ./bootstrap.bat gcc 
               travis_wait 40 ./b2.exe -d0 --with-date_time --with-test --with-filesystem --with-program_options --with-regex --with-serialization --with-system runtime-link=static toolset=gcc --prefix=${TRAVIS_BUILD_DIR}/boost-mingw install
               echo "Boost installed"
include/licensecc/datatypes.h
@@ -126,6 +126,31 @@
    int license_version;  // license file version
} LicenseInfo;
typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, V_XEN, KVM, HV, V_OTHER } LCC_API_VIRTUALIZATION_DETAIL;
typedef enum {
    PROV_UNKNOWN = 0,
    ON_PREMISE = 1,
    GOOGLE_CLOUD = 2,
    AZURE_CLOUD = 3,
    AWS = 4,
    /**
     * "/sys/class/dmi/id/bios_vendor" SeaBIOS
     * "/sys/class/dmi/id/sys_vendor" Alibaba Cloud
     * modalias
     * "dmi:bvnSeaBIOS:bvrrel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org:bd04/01/2014:svnAlibabaCloud:pnAlibabaCloudECS:pvrpc-i440fx-2.1:cvnAlibabaCloud:ct1:cvrpc-i440fx-2.1:"
     */
    ALI_CLOUD = 5
} LCC_API_CLOUD_PROVIDER;
typedef enum { NONE, CONTAINER, VM } LCC_API_VIRTUALIZATION_SUMMARY;
typedef struct {
    LCC_API_CLOUD_PROVIDER cloud_provider;
    LCC_API_VIRTUALIZATION_SUMMARY virtualization;
    LCC_API_VIRTUALIZATION_DETAIL virtualization_detail;
} ExecutionEnvironmentInfo;
#ifdef __cplusplus
}
#endif
include/licensecc/licensecc.h
@@ -11,8 +11,6 @@
extern "C" {
#endif
#include <licensecc_properties.h>
#include "datatypes.h"
/**
@@ -39,15 +37,17 @@
 * wiki for more informations.
 * @param identifier_out[out] buffer where the identification string will be placed.
 * @param identifier_out[in-out] size of the buffer where the identification string will be placed.
 * @param execution_environment_info[out] if not null will contain the informations about the execution environment.
 */
bool identify_pc(LCC_API_HW_IDENTIFICATION_STRATEGY hw_id_method, char* identifier_out, size_t* buf_size);
bool identify_pc(LCC_API_HW_IDENTIFICATION_STRATEGY hw_id_method, char* identifier_out, size_t* buf_size,
                 ExecutionEnvironmentInfo* execution_environment_info);
/**
 * 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.
 *
 * @return ::LICENSE_OK(0) if successful. Other values if there are errors.
 *
 *
 * @param callerInformation[in]
 *             a vendor defined string containing the name of the product we want to request.
 * @param licenseLocation[in] otpional, can be NULL.
src/inspector/inspector.cpp
@@ -4,7 +4,7 @@
#include <licensecc/licensecc.h>
#include <fstream>
#include "../library/os/cpu_info.hpp"
#include "../library/os/execution_environment.hpp"
#include "../library/os/dmi_info.hpp"
using namespace std;
using namespace license::os;
@@ -23,8 +23,10 @@
                                                     {HV, "Microsoft Hypervisor"},
                                                     {V_OTHER, "Other type of vm"}};
const unordered_map<int, string> descByVirt = {
    {VIRTUALIZATION::NONE, "No virtualization"}, {VIRTUALIZATION::VM, "VM"}, {VIRTUALIZATION::CONTAINER, "Container"}};
const unordered_map<LCC_API_VIRTUALIZATION_SUMMARY, string> descByVirt = {
    {LCC_API_VIRTUALIZATION_SUMMARY::NONE, "No virtualization"},
    {LCC_API_VIRTUALIZATION_SUMMARY::VM, "VM"},
    {LCC_API_VIRTUALIZATION_SUMMARY::CONTAINER, "Container"}};
const unordered_map<int, string> stringByEventType = {
    {LICENSE_OK, "OK "},
@@ -53,31 +55,32 @@
}
int main(int argc, char* argv[]) {
    license::os::CpuInfo cpu;
    cout << "Cpu Vendor      :" << cpu.vendor() << endl;
    cout << "Cpu Brand       :" << cpu.brand() << endl;
    cout << "Cpu is hypervis.:" << cpu.cpu_virtual() << endl;
    cout << "Cpu model       :0x" << std::hex << ((long)cpu.model()) << std::dec << endl;
    cout << "Virt. detail cpu:" << descByVirtDetail.find(cpu.virtualization_details())->second << endl <<endl;
    ExecutionEnvironment execEnv;
    cout << "Running in cloud:" << execEnv.is_cloud() << endl;
    cout << "Docker          :" << execEnv.is_docker() << endl;
    cout << "other container :" << execEnv.is_container() << endl;
    cout << "Virtualiz. class:" << descByVirt.find(execEnv.getVirtualization())->second << endl;
    cout << "Bios vendor     :" << execEnv.bios_vendor() << endl;
    cout << "Bios description:" << execEnv.bios_description() << endl;
    cout << "System vendor   :" << execEnv.sys_vendor() << endl <<endl;
    char hw_identifier[LCC_API_PC_IDENTIFIER_SIZE + 1];
    size_t bufSize = LCC_API_PC_IDENTIFIER_SIZE + 1;
    ExecutionEnvironmentInfo exec_env_info;
    for (const auto& x : stringByStrategyId) {
        if (identify_pc(static_cast<LCC_API_HW_IDENTIFICATION_STRATEGY>(x.first), hw_identifier, &bufSize)) {
        if (identify_pc(static_cast<LCC_API_HW_IDENTIFICATION_STRATEGY>(x.first), hw_identifier, &bufSize,
                        &exec_env_info)) {
            std::cout << x.second << ':' << hw_identifier << std::endl;
        } else {
            std::cout << x.second << ": NA" << endl;
        }
    }
    cout << "Virtualiz. class :" << descByVirt.find(exec_env_info.virtualization)->second << endl;
    cout << "Virtualiz. detail:" << descByVirtDetail.find(exec_env_info.virtualization_detail)->second << endl;
    cout << "Cloud provider   :" << exec_env_info.cloud_provider << endl << "=============" << endl;
    ;
    license::os::CpuInfo cpu;
    cout << "Cpu Vendor       :" << cpu.vendor() << endl;
    cout << "Cpu Brand        :" << cpu.brand() << endl;
    cout << "Cpu hypervisor   :" << cpu.is_hypervisor_set() << endl;
    cout << "Cpu model        :0x" << std::hex << ((long)cpu.model()) << std::dec << endl;
    license::os::DmiInfo dmi_info;
    cout << "Bios vendor     :" << dmi_info.bios_vendor() << endl;
    cout << "Bios description:" << dmi_info.bios_description() << endl;
    cout << "System vendor   :" << dmi_info.sys_vendor() << endl << endl;
    if (argc == 2) {
        const string fname(argv[1]);
src/library/base/base64.cpp
@@ -39,7 +39,7 @@
};  // This array has 255 elements
// review api
void add_CR_if_needed(string& encodeBuffer, int lineLenght) {
static void add_CR_if_needed(string& encodeBuffer, int lineLenght) {
    if (lineLenght > 0 && ((encodeBuffer.size() + 1) % lineLenght) == 0) {
        encodeBuffer += '\n';
    }
src/library/hw_identifier/default_strategy.cpp
@@ -14,16 +14,16 @@
namespace hw_identifier {
static vector<LCC_API_HW_IDENTIFICATION_STRATEGY> available_strategies() {
    os::ExecutionEnvironment exec;
    os::VIRTUALIZATION virtualization = exec.getVirtualization();
    const os::ExecutionEnvironment exec;
    LCC_API_VIRTUALIZATION_SUMMARY virtualization = exec.virtualization();
    vector<LCC_API_HW_IDENTIFICATION_STRATEGY> strategy_to_try;
    if (virtualization == os::CONTAINER) {
    if (virtualization == LCC_API_VIRTUALIZATION_SUMMARY::CONTAINER) {
        if (exec.is_docker()) {
            strategy_to_try = LCC_DOCKER_STRATEGIES;
        } else {
            strategy_to_try = LCC_LXC_STRATEGIES;
        }
    } else if (virtualization == os::VM) {
    } else if (virtualization == LCC_API_VIRTUALIZATION_SUMMARY::VM) {
        if (exec.is_cloud()) {
            strategy_to_try = LCC_CLOUD_STRATEGIES;
        } else {
src/library/hw_identifier/hw_identifier.cpp
@@ -47,19 +47,6 @@
    }
}
void HwIdentifier::set_virtual_environment(os::VIRTUALIZATION virt) {
    // 110000 0x30
    m_data[0] = (m_data[0] & ~0x30) | virt << 4;
}
void HwIdentifier::set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail) {
    m_data[0] = (m_data[0] & ~0x0F) | virtualization_detail;
}
void HwIdentifier::set_cloud_provider(os::CLOUD_PROVIDER cloud_provider) {
    m_data[0] = (m_data[0] & ~0x0F) | cloud_provider | 0x08;
}
void HwIdentifier::set_data(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA>& data) {
    m_data[1] = (m_data[1] & (~0x1f)) | (data[0] & 0x1f);
    for (int i = 1; i < HW_IDENTIFIER_PROPRIETARY_DATA; i++) {
src/library/hw_identifier/hw_identifier.hpp
@@ -20,7 +20,7 @@
namespace license {
namespace hw_identifier {
#define HW_IDENTIFIER_PROPRIETARY_DATA 8
#define HW_IDENTIFIER_PROPRIETARY_DATA 7
/**
 * data[0]
@@ -28,16 +28,9 @@
 *
 * if bit 7 = 0
 * bit 6 = environment variable was used to generate pc_id
 * bit 5-4 = execution environment information (0=BARE_TO_METAL,1=VM,2=CONTAINER)
 * bit 3 = 0 on premise vm 1 = cloud
 * if on premise vm bits 2-1-0 are virtualization technology
 * if cloud vm bits 2-1-0 identify cloud provider
 *
 * if bit 7 = 1 hardware identifier is used to enable some flag that we don't want to show openly in the license
 * bit 6 = 1 enable magic file/registry key
 * ----
 * data[1] bit 7-6-5 define identification strategy.
 * data[1] bits 4-0, data[2-8] are hardware identifier proprietary strategy data.
 * bit 5-4-3 define identification strategy.
 * bit 2-1-0 unused (crc?)
 * data[1-7] are hardware identifier proprietary strategy data.
 */
class HwIdentifier {
@@ -53,9 +46,6 @@
    void set_identification_strategy(LCC_API_HW_IDENTIFICATION_STRATEGY strategy);
    LCC_API_HW_IDENTIFICATION_STRATEGY get_identification_strategy() const;
    void set_use_environment_var(bool use_env_var);
    void set_virtual_environment(os::VIRTUALIZATION virtualization);
    void set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail);
    void set_cloud_provider(os::CLOUD_PROVIDER cloud_provider);
    void set_data(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> &data);
    bool data_match(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> &data) const;
    std::string print() const;
src/library/hw_identifier/hw_identifier_facade.cpp
@@ -12,8 +12,6 @@
#include "../base/base.h"
#include "../base/logger.h"
#include "../os/cpu_info.hpp"
#include "../os/execution_environment.hpp"
#include "identification_strategy.hpp"
#include "hw_identifier.hpp"
@@ -56,19 +54,6 @@
    FUNCTION_RETURN result = strategy_ptr->generate_pc_id(pc_id);
    if (result != FUNC_RET_OK) {
        throw logic_error("strategy " + to_string(strategy_ptr->identification_strategy()) + " failed");
    }
    os::ExecutionEnvironment exec;
    os::VIRTUALIZATION virtualization = exec.getVirtualization();
    pc_id.set_virtual_environment(virtualization);
    pc_id.set_use_environment_var(use_env_var);
    if (virtualization != os::NONE) {
        bool isCloud = exec.is_cloud();
        if (isCloud) {
            pc_id.set_cloud_provider(exec.getCloudProvider());
        } else {
            os::CpuInfo cpu;
            pc_id.set_virtualization(cpu.virtualization_details());
        }
    }
    return pc_id.print();
}
src/library/licensecc.cpp
@@ -19,31 +19,37 @@
#include "base/logger.h"
#include "hw_identifier/hw_identifier_facade.hpp"
#include "os/execution_environment.hpp"
#include "limits/license_verifier.hpp"
#include "base/StringUtils.h"
#include "LicenseReader.hpp"
using namespace std;
void print_error(char out_buffer[LCC_API_ERROR_BUFFER_SIZE], LicenseInfo* licenseInfo) {}
bool identify_pc(LCC_API_HW_IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t* bufSize) {
bool identify_pc(LCC_API_HW_IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t* bufSize,
                 ExecutionEnvironmentInfo* execution_environment_info) {
    bool result = false;
    if (*bufSize > LCC_API_PC_IDENTIFIER_SIZE && chbuffer != nullptr) {
        try {
            string pc_id = license::hw_identifier::HwIdentifierFacade::generate_user_pc_signature(pc_id_method);
            const string pc_id = license::hw_identifier::HwIdentifierFacade::generate_user_pc_signature(pc_id_method);
            strncpy(chbuffer, pc_id.c_str(), *bufSize);
            result = true;
        } catch (const std::exception& ex) {
            LOG_ERROR("Error calculating hw_identifier: %s", ex.what());
#ifdef _DEBUG
                cout
                << "Error occurred: " << ex.what() << std::endl;
            cout << "Error occurred: " << ex.what() << std::endl;
#endif
        }
    } else {
        *bufSize = LCC_API_PC_IDENTIFIER_SIZE + 1;
    }
    if (execution_environment_info != nullptr) {
        const license::os::ExecutionEnvironment exec_env;
        execution_environment_info->cloud_provider = exec_env.cloud_provider();
        execution_environment_info->virtualization = exec_env.virtualization();
        execution_environment_info->virtualization_detail = exec_env.virtualization_detail();
    }
    return result;
}
@@ -64,8 +70,8 @@
    }
}
LCC_EVENT_TYPE acquire_license(const CallerInformations* callerInformation,
                                     const LicenseLocation* licenseLocation, LicenseInfo* license_out) {
LCC_EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
                               LicenseInfo* license_out) {
    const license::LicenseReader lr = license::LicenseReader(licenseLocation);
    vector<license::FullLicenseInfo> licenses;
    string project;
@@ -129,4 +135,3 @@
LCC_EVENT_TYPE confirm_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
LCC_EVENT_TYPE release_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
src/library/os/CMakeLists.txt
@@ -4,16 +4,18 @@
            openssl/signature_verifier.cpp
            execution_environment_common.cpp
            linux/execution_environment.cpp
            cpu_info_common.cpp
            linux/cpu_info.cpp
            linux/dmi_info.cpp
            linux/network.cpp
            linux/os_linux.cpp) 
    ELSE(UNIX)
        #windows and openssl
          add_library(os OBJECT 
          cpu_info_common.cpp windows/cpu_info.cpp
          windows/cpu_info.cpp
          windows/dmi_info.cpp
          openssl/signature_verifier.cpp 
        execution_environment_common.cpp windows/execution_environment.cpp
        execution_environment_common.cpp
        windows/execution_environment.cpp
          windows/isvm/Native.cpp
        windows/isvm/BIOSReader.cpp
          windows/os_win.cpp
@@ -23,10 +25,11 @@
ELSE(UNIX OR OPENSSL_FOUND)
#windows no openssl
    add_library(os OBJECT
        cpu_info_common.cpp
        windows/cpu_info.cpp
        windows/cpu_info.cpp
        windows/dmi_info.cpp
        windows/signature_verifier.cpp 
        execution_environment_common.cpp windows/execution_environment.cpp
        execution_environment_common.cpp
        windows/execution_environment.cpp
        windows/isvm/Native.cpp
        windows/isvm/BIOSReader.cpp
        windows/os_win.cpp
src/library/os/cpu_info.hpp
@@ -10,14 +10,12 @@
#include <string>
namespace license {
namespace os {
typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, V_XEN, KVM, HV, V_OTHER } VIRTUALIZATION_DETAIL;
/**
 * Cpu informations
 */
class CpuInfo {
private:
    bool is_hypervisor_set() const;
    const std::string m_vendor;
    const std::string m_brand;
public:
@@ -27,11 +25,10 @@
     * Detect Virtual machine using hypervisor bit or the cpu vendor name.
     * @return true if the cpu is detected to be a virtual cpu
     */
    bool cpu_virtual() const;
    uint32_t model() const;
    bool is_hypervisor_set() const;
    const std::string& vendor() const { return m_vendor; }
    const std::string& brand() const { return m_brand; }
    VIRTUALIZATION_DETAIL virtualization_details() const;
};
}  // namespace os
src/library/os/cpu_info_common.cpp
File was deleted
src/library/os/dmi_info.hpp
New file
@@ -0,0 +1,32 @@
/*
 * dmi_info.hpp
 *
 *  Created on: Apr 24, 2020
 *      Author: devel
 */
#ifndef SRC_LIBRARY_OS_DMI_INFO_HPP_
#define SRC_LIBRARY_OS_DMI_INFO_HPP_
#include <string>
namespace license {
namespace os {
class DmiInfo {
private:
    std::string m_sys_vendor;
    std::string m_bios_vendor;
    std::string m_bios_description;
public:
    DmiInfo();
    virtual ~DmiInfo(){};
    const std::string& bios_vendor() const { return m_bios_vendor; };
    const std::string& sys_vendor() const { return m_sys_vendor; };
    const std::string& bios_description() const { return m_bios_description; };
};
}  // namespace os
} /* namespace license */
#endif /* SRC_LIBRARY_OS_DMI_INFO_HPP_ */
src/library/os/execution_environment.hpp
@@ -9,6 +9,9 @@
#define SRC_LIBRARY_OS_VIRTUALIZATION_HPP_
#include <string>
#include <licensecc/datatypes.h>
#include "dmi_info.hpp"
#include "cpu_info.hpp"
namespace license {
namespace os {
@@ -19,42 +22,24 @@
    "VMware", "Microsoft Corporation", "Virtual Machine", "innotek GmbH", "PowerVM", "Bochs", "KVM"};
*/
typedef enum { NONE, CONTAINER, VM } VIRTUALIZATION;
typedef enum {
    PROV_UNKNOWN,
    ON_PREMISE,
    GOOGLE_CLOUD,
    AZURE_CLOUD,
    AWS,
    /**
     * "/sys/class/dmi/id/bios_vendor" SeaBIOS
     * "/sys/class/dmi/id/sys_vendor" Alibaba Cloud
     * modalias
     * "dmi:bvnSeaBIOS:bvrrel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org:bd04/01/2014:svnAlibabaCloud:pnAlibabaCloudECS:pvrpc-i440fx-2.1:cvnAlibabaCloud:ct1:cvrpc-i440fx-2.1:"
     */
    ALI_CLOUD
} CLOUD_PROVIDER;
enum CONTAINER_TYPE { NONE, DOCKER, LXC };
class ExecutionEnvironment {
private:
    std::string m_sys_vendor;
    std::string m_bios_vendor;
    std::string m_bios_description;
    const CpuInfo m_cpu_info;
    const DmiInfo m_dmi_info;
    const CONTAINER_TYPE m_container_type;
public:
    ExecutionEnvironment();
    ~ExecutionEnvironment(){};
    VIRTUALIZATION getVirtualization() const;
    LCC_API_VIRTUALIZATION_SUMMARY virtualization() const;
    bool is_cloud() const;
    bool is_docker() const;
    bool is_docker() const { return m_container_type != DOCKER; }
    // detect if it's a kind of container technology (docker or lxc)
    bool is_container() const;
    CLOUD_PROVIDER getCloudProvider() const;
    const std::string& bios_vendor() const { return m_bios_vendor; };
    const std::string& sys_vendor() const { return m_sys_vendor; };
    const std::string& bios_description() const { return m_bios_description; };
    // VIRTUALIZATION_DETAIL getVirtualizationDetail() const; //as reported by the bios
    bool is_container() const { return m_container_type != NONE; }
    LCC_API_CLOUD_PROVIDER cloud_provider() const;
    LCC_API_VIRTUALIZATION_DETAIL virtualization_detail() const;
};
}  // namespace os
src/library/os/execution_environment_common.cpp
@@ -8,6 +8,7 @@
#include <string.h>
#include <unordered_map>
#include <array>
#include <licensecc/datatypes.h>
#include "../base/base.h"
#include "cpu_info.hpp"
@@ -17,39 +18,83 @@
namespace os {
using namespace std;
VIRTUALIZATION ExecutionEnvironment::getVirtualization() const {
    VIRTUALIZATION result;
    CpuInfo cpuInfo;
const unordered_map<string, LCC_API_VIRTUALIZATION_DETAIL> virtual_cpu_names{
    {"bhyve bhyve ", V_OTHER}, {"KVM", KVM},       {"MICROSOFT", HV},        {" lrpepyh vr", HV},
    {"prl hyperv  ", V_OTHER}, {"VMWARE", VMWARE}, {"XenVMMXenVMM", V_XEN}, {"ACRNACRNACRN", V_OTHER},
    {"VBOX", VIRTUALBOX}};
const unordered_map<string, LCC_API_VIRTUALIZATION_DETAIL> vm_vendors{{"VMWARE", VMWARE},
                                                              {"MICROSOFT", HV},
                                                              {"VITRUAL MACHINE", V_OTHER},
                                                              {"INNOTEK GMBH", V_OTHER},
                                                              {"POWERVM", V_OTHER},
                                                              {"BOCHS", V_OTHER},
                                                              {"KVM", KVM}};
static LCC_API_VIRTUALIZATION_DETAIL find_in_map(const unordered_map<string, LCC_API_VIRTUALIZATION_DETAIL>& map, const string& data) {
    for (auto it : map) {
        if (data.find(it.first) != string::npos) {
            return it.second;
        }
    }
    return BARE_TO_METAL;
}
LCC_API_VIRTUALIZATION_SUMMARY ExecutionEnvironment::virtualization() const {
    LCC_API_VIRTUALIZATION_SUMMARY result;
    bool isContainer = is_container();
    if (isContainer) {
        result = CONTAINER;
    } else if (cpuInfo.cpu_virtual() || is_cloud()) {
        result = VM;
        result = LCC_API_VIRTUALIZATION_SUMMARY::CONTAINER;
    } else if (virtualization_detail() != BARE_TO_METAL || is_cloud()) {
        result = LCC_API_VIRTUALIZATION_SUMMARY::VM;
    } else {
        result = NONE;
        result = LCC_API_VIRTUALIZATION_SUMMARY::NONE;
    }
    return result;
}
LCC_API_VIRTUALIZATION_DETAIL ExecutionEnvironment::virtualization_detail() const {
    LCC_API_VIRTUALIZATION_DETAIL result = BARE_TO_METAL;
    const string bios_description = m_dmi_info.bios_description();
    const string bios_vendor = m_dmi_info.bios_vendor();
    const string sys_vendor = m_dmi_info.sys_vendor();
    if ((result = find_in_map(vm_vendors, bios_description)) == BARE_TO_METAL) {
        if ((result = find_in_map(vm_vendors, bios_vendor)) == BARE_TO_METAL) {
            if ((result = find_in_map(vm_vendors, sys_vendor)) == BARE_TO_METAL) {
                if ((result = find_in_map(virtual_cpu_names, m_cpu_info.vendor())) == BARE_TO_METAL) {
                    result = find_in_map(virtual_cpu_names, m_cpu_info.brand());
                }
            }
        }
    }
    if (result == BARE_TO_METAL && m_cpu_info.is_hypervisor_set()) {
        result = V_OTHER;
    }
    return result;
}
bool ExecutionEnvironment::is_cloud() const {
    CLOUD_PROVIDER prov = getCloudProvider();
    const LCC_API_CLOUD_PROVIDER prov = cloud_provider();
    return prov != ON_PREMISE && prov != PROV_UNKNOWN;
}
// TODO test and azure
CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() const {
    CLOUD_PROVIDER result = PROV_UNKNOWN;
    if (m_bios_description.size() > 0 || m_bios_vendor.size() > 0 || m_sys_vendor.size() > 0) {
        if (m_bios_vendor.find("SEABIOS") != string::npos || m_bios_description.find("ALIBABA") != string::npos ||
            m_sys_vendor.find("ALIBABA") != string::npos) {
LCC_API_CLOUD_PROVIDER ExecutionEnvironment::cloud_provider() const {
    LCC_API_CLOUD_PROVIDER result = PROV_UNKNOWN;
    const string bios_description = m_dmi_info.bios_description();
    const string bios_vendor = m_dmi_info.bios_vendor();
    const string sys_vendor = m_dmi_info.sys_vendor();
    if (bios_description.size() > 0 || bios_vendor.size() > 0 || sys_vendor.size() > 0) {
        if (bios_vendor.find("SEABIOS") != string::npos || bios_description.find("ALIBABA") != string::npos ||
            sys_vendor.find("ALIBABA") != string::npos) {
            result = ALI_CLOUD;
        } else if (m_sys_vendor.find("GOOGLE") != string::npos || m_bios_description.find("GOOGLE") != string::npos) {
        } else if (sys_vendor.find("GOOGLE") != string::npos || bios_description.find("GOOGLE") != string::npos) {
            result = GOOGLE_CLOUD;
        } else if (m_bios_vendor.find("AWS") != string::npos || m_bios_description.find("AMAZON") != string::npos ||
                   m_sys_vendor.find("AWS") != string::npos) {
        } else if (bios_vendor.find("AWS") != string::npos || bios_description.find("AMAZON") != string::npos ||
                   sys_vendor.find("AWS") != string::npos) {
            result = AWS;
        } else if (m_bios_description.find("HP-COMPAQ") != string::npos || m_bios_description.find("ASUS") ||
                   m_bios_description.find("DELL")) {
        } else if (bios_description.find("HP-COMPAQ") != string::npos || bios_description.find("ASUS") ||
                   bios_description.find("DELL")) {
            result = ON_PREMISE;
        }
    }
src/library/os/linux/dmi_info.cpp
New file
@@ -0,0 +1,35 @@
#include "../../base/file_utils.hpp"
#include "../../base/StringUtils.h"
#include "../dmi_info.hpp"
namespace license {
namespace os {
DmiInfo::DmiInfo() {
    try {
        m_bios_vendor = toupper_copy(trim_copy(get_file_contents("/sys/class/dmi/id/sys_vendor", 256)));
    } catch (...) {
    }
    try {
        m_bios_description = toupper_copy(trim_copy(get_file_contents("/sys/class/dmi/id/modalias", 256)));
        char last_char = m_bios_description[m_bios_description.length() - 1];
        if (last_char == '\r' || last_char == '\n') {
            m_bios_description = m_bios_description.erase(m_bios_description.length() - 1);
        }
    } catch (...) {
    }
    try {
        m_sys_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256);
        char last_char = m_sys_vendor[m_sys_vendor.length() - 2];
        if (last_char == '\r' || last_char == '\n') {
            m_sys_vendor = m_sys_vendor.erase(m_sys_vendor.length() - 1);
        }
    } catch (...) {
    }
}
}  // namespace os
}  // namespace license
src/library/os/linux/execution_environment.cpp
@@ -25,7 +25,7 @@
using namespace std;
// 0=NO 1=Docker/2=Lxc
static int checkContainerProc() {
static CONTAINER_TYPE checkContainerProc() {
    // in docer /proc/self/cgroups contains the "docker" or "lxc" string
    // https://stackoverflow.com/questions/23513045/how-to-check-if-a-process-is-running-inside-docker-container
    char path[MAX_PATH] = {0};
@@ -40,11 +40,11 @@
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int result = 0;
    CONTAINER_TYPE result = NONE;
    fp = fopen(proc_path, "r");
    if (fp == NULL) {
        return 0;
        return NONE;
    }
    while ((read = getline(&line, &len, fp)) != -1 && result == 0) {
@@ -52,10 +52,10 @@
        // printf("Retrieved line of length %zu:\n", read);
        // printf("%s", line);
        if (strstr(line, "docker") != NULL) {
            result = 1;
            result = DOCKER;
        }
        if (strstr(line, "lxc") != NULL) {
            result = 2;
            result = LXC;
        }
    }
@@ -65,17 +65,17 @@
}
// 0=NO 1=Docker/2=Lxc
static int checkSystemdContainer() {
static CONTAINER_TYPE checkSystemdContainer() {
    ifstream systemd_container("/var/run/systemd/container");
    int result = 0;
    CONTAINER_TYPE result = NONE;
    if (systemd_container.good()) {
        result = 1;
        result = DOCKER;
        for (string line; getline(systemd_container, line);) {
            if (line.find("docker") != string::npos) {
                result = 1;
                result = DOCKER;
                break;
            } else if (line.find("lxc") != string::npos) {
                result = 2;
                result = LXC;
                break;
            }
        }
@@ -83,33 +83,15 @@
    return result;
}
ExecutionEnvironment::ExecutionEnvironment() {
    try {
        m_bios_vendor = toupper_copy(trim_copy(get_file_contents("/sys/class/dmi/id/sys_vendor", 256)));
    } catch (...) {
static CONTAINER_TYPE get_container_type() {
    CONTAINER_TYPE result = checkContainerProc();
    if (result == NONE) {
        result = checkSystemdContainer();
    }
    try {
        m_bios_description = toupper_copy(trim_copy(get_file_contents("/sys/class/dmi/id/modalias", 256)));
        char last_char = m_bios_description[m_bios_description.length() - 1];
        if (last_char == '\r' || last_char == '\n') {
            m_bios_description = m_bios_description.erase(m_bios_description.length() - 1);
        }
    } catch (...) {
    }
    try {
        m_sys_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256);
        char last_char = m_sys_vendor[m_sys_vendor.length() - 2];
        if (last_char == '\r' || last_char == '\n') {
            m_sys_vendor = m_sys_vendor.erase(m_sys_vendor.length() - 1);
        }
    } catch (...) {
    }
    return result;
}
bool ExecutionEnvironment::is_container() const { return (checkContainerProc() != 0 || checkSystemdContainer() != 0); }
bool ExecutionEnvironment::is_docker() const { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); }
ExecutionEnvironment::ExecutionEnvironment() : m_container_type(get_container_type()) {}
}  // namespace os
}  // namespace license
src/library/os/linux/os_linux.cpp
@@ -175,27 +175,6 @@
    return result;
}
static void _getCpuid(unsigned int *p, unsigned int ax) {
    __asm __volatile(
        "movl %%ebx, %%esi\n\t"
        "cpuid\n\t"
        "xchgl %%ebx, %%esi"
        : "=a"(p[0]), "=S"(p[1]), "=c"(p[2]), "=d"(p[3])
        : "0"(ax));
}
FUNCTION_RETURN getCpuId(unsigned char identifier[6]) {
    unsigned int i;
    unsigned int cpuinfo[4] = {0, 0, 0, 0};
    _getCpuid(cpuinfo, 0);
    for (i = 0; i < 3; i++) {
        identifier[i * 2] = cpuinfo[i] & 0xFF;
        identifier[i * 2 + 1] = (cpuinfo[i] & 0xFF00) >> 8;
    }
    return FUNC_RET_OK;
}
FUNCTION_RETURN getMachineName(unsigned char identifier[6]) {
    static struct utsname u;
src/library/os/windows/dmi_info.cpp
New file
@@ -0,0 +1,26 @@
/*
 * dmi_info.cpp
 *
 *  Created on: Apr 24, 2020
 *      Author: devel
 */
#include <windows.h>
#include "isvm/BIOSReader.h"
#include "isvm/Native.h"
#include "../../base/StringUtils.h"
#include "../dmi_info.hpp"
namespace license {
namespace os {
DmiInfo::DmiInfo() {
    if (InitEntryPoints()) {
        BIOSReader reader;
        SystemInformation info = reader.readSystemInfo();
        m_sys_vendor = toupper_copy(info.Manufacturer);
        m_bios_vendor = toupper_copy(info.ProductName);
        m_bios_description = toupper_copy(info.SysVersion) + toupper_copy(info.family);
    }
}
}
} /* namespace license */
src/library/os/windows/execution_environment.cpp
@@ -11,10 +11,8 @@
#include <stdio.h>
#include <string>
#include "isvm/BIOSReader.h"
#include "isvm/Native.h"
#include "../../base/base.h"
#include "../../base/StringUtils.h"
#include "../cpu_info.hpp"
#include "../execution_environment.hpp"
@@ -22,65 +20,47 @@
namespace os {
using namespace std;
ExecutionEnvironment::ExecutionEnvironment() {
    if (InitEntryPoints()) {
        BIOSReader reader;
        SystemInformation info = reader.readSystemInfo();
        m_sys_vendor = toupper_copy(info.Manufacturer);
        m_bios_vendor = toupper_copy(info.ProductName);
        m_bios_description = toupper_copy(info.SysVersion) + toupper_copy(info.family);
    }
}
ExecutionEnvironment::ExecutionEnvironment() : m_container_type(CONTAINER_TYPE::NONE) {}
#define MAX_UNITS 20
int wine_container() {
DWORD fileMaxLen;
size_t ndrives = 0;
DWORD fileFlags;
char volName[MAX_PATH], fileSysName[MAX_PATH];
DWORD volSerial = 0;
const DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
CONTAINER_TYPE wine_container() {
    size_t ndrives = 0;
    const DWORD dwSize = MAX_PATH;
    char szLogicalDrives[MAX_PATH] = {0};
int result = 0;
const DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
if (dwResult > 0 && dwResult <= MAX_PATH) {
    char* szSingleDrive = szLogicalDrives;
    while (*szSingleDrive && ndrives < MAX_UNITS) {
        // get the next drive
        UINT driveType = GetDriveType(szSingleDrive);
        if (driveType == DRIVE_FIXED) {
            string name = szSingleDrive + string("/var/run/systemd/container");
            try {
                ifstream systemd_container(name);
                if (systemd_container.good()) {
                    result = 1;
                    for (string line; getline(systemd_container, line);) {
                        if (line.find("docker") != string::npos) {
                            result = 1;
                            break;
                        } else if (line.find("lxc") != string::npos) {
                            result = 2;
                            break;
    CONTAINER_TYPE result = CONTAINER_TYPE::NONE;
    const DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
    //FIXME! this code missed the increment in the loop...
    if (dwResult > 0 && dwResult <= MAX_PATH) {
        char* szSingleDrive = szLogicalDrives;
        while (*szSingleDrive && ndrives < MAX_UNITS) {
            // get the next drive
            UINT driveType = GetDriveType(szSingleDrive);
            if (driveType == DRIVE_FIXED) {
                string name = szSingleDrive + string("/var/run/systemd/container");
                try {
                    ifstream systemd_container(name);
                    if (systemd_container.good()) {
                        result = CONTAINER_TYPE::DOCKER;
                        for (string line; getline(systemd_container, line);) {
                            if (line.find("docker") != string::npos) {
                                result = CONTAINER_TYPE::DOCKER;
                                break;
                            } else if (line.find("lxc") != string::npos) {
                                result = CONTAINER_TYPE::LXC;
                                break;
                            }
                        }
                    }
                } catch (...) {
                    // no problem,we're just guessing
                }
            } catch (...) {
                //no problem,we're just guessing
            }
        }
    }
}
    return result;
}
bool ExecutionEnvironment::is_docker() const {
    // let's check we're not in linux under wine ;) ...
//int cont = wine_container();
    return false;
}
//TODO
bool ExecutionEnvironment::is_container() const { return is_docker(); }
}  // namespace os
}  // namespace license
test/library/hw_identifier/hw_identifier_test.cpp
@@ -28,7 +28,7 @@
 * Test get and set and compare hardware identifier data
 */
BOOST_AUTO_TEST_CASE(set_and_compare_data) {
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0xFF, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0xFF, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    HwIdentifier pc_id;
    pc_id.set_data(data);
    data[0] = data[0] & 0x1f;
@@ -38,7 +38,7 @@
 * Test get and set and compare hardware identifier data
 */
BOOST_AUTO_TEST_CASE(compare_wrong_data) {
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    HwIdentifier pc_id;
    pc_id.set_data(data);
    data[4] = 0;
@@ -49,7 +49,7 @@
 * Print a hardware identifier and read it from the same string, check the data matches
 */
BOOST_AUTO_TEST_CASE(print_and_read) {
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
    HwIdentifier pc_id;
    pc_id.set_data(data);
    pc_id.set_identification_strategy(LCC_API_HW_IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET);
test/library/os/execution_environment_test.cpp
@@ -23,19 +23,19 @@
    os::ExecutionEnvironment exec_env;
    bool docker = false;
    if (env != nullptr) {
        os::VIRTUALIZATION virt = exec_env.getVirtualization();
        LCC_API_VIRTUALIZATION_SUMMARY virt = exec_env.virtualization();
        if (strcmp(env, "CONTAINER") == 0 || (docker = (strcmp(env, "DOCKER") == 0))) {
            BOOST_CHECK_MESSAGE(virt == VIRTUALIZATION::CONTAINER, "container detected");
            BOOST_CHECK_MESSAGE(virt == LCC_API_VIRTUALIZATION_SUMMARY::CONTAINER, "container detected");
            BOOST_CHECK_MESSAGE(exec_env.is_container(), "container detected");
            if (docker) {
                BOOST_CHECK_MESSAGE(exec_env.is_docker(), "docker detected");
            }
        } else if (strcmp(env, "VM") == 0) {
            BOOST_CHECK_MESSAGE(virt == VIRTUALIZATION::VM, "VM detected");
            BOOST_CHECK_MESSAGE(virt == LCC_API_VIRTUALIZATION_SUMMARY::VM, "VM detected");
            BOOST_CHECK_MESSAGE(!exec_env.is_container(), "VM is not a container");
            BOOST_CHECK_MESSAGE(!exec_env.is_docker(), "VM is not a docker");
        } else if (strcmp(env, "NONE") == 0) {
            BOOST_CHECK_EQUAL(virt, VIRTUALIZATION::NONE);
            BOOST_CHECK_EQUAL(virt, LCC_API_VIRTUALIZATION_SUMMARY::NONE);
            BOOST_CHECK_MESSAGE(!exec_env.is_container(), "not a container");
            BOOST_CHECK_MESSAGE(!exec_env.is_docker(), "not a docker");
        } else {
test/library/os_linux_test.cpp
@@ -16,8 +16,8 @@
BOOST_AUTO_TEST_CASE(read_disk_id) {
    os::ExecutionEnvironment exec_env;
    os::VIRTUALIZATION virt = exec_env.getVirtualization();
    if (virt == VIRTUALIZATION::NONE || virt == VIRTUALIZATION::VM) {
    LCC_API_VIRTUALIZATION_SUMMARY virt = exec_env.virtualization();
    if (virt == LCC_API_VIRTUALIZATION_SUMMARY::NONE || virt == LCC_API_VIRTUALIZATION_SUMMARY::VM) {
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;
        FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size);
@@ -30,7 +30,7 @@
        BOOST_CHECK_GT(mstrnlen_s(diskInfos[0].label, sizeof diskInfos[0].label), 0);
        BOOST_CHECK_GT(diskInfos[0].disk_sn[0], 0);
        free(diskInfos);
    } else if (virt == VIRTUALIZATION::CONTAINER) {
    } else if (virt == LCC_API_VIRTUALIZATION_SUMMARY::CONTAINER) {
        // docker or lxc diskInfo is not meaningful
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;