From 9afdac17dcc8956fd795797bfc5b6e1c09285342 Mon Sep 17 00:00:00 2001 From: Gabriele Contini <contini.mailing@gmail.com> Date: 周日, 08 3月 2020 21:27:16 +0800 Subject: [PATCH] Issues #14 and #6 --- src/library/locate/ExternalDefinition.cpp | 6 src/library/os/linux/execution_environment.cpp | 34 src/library/os/execution_environment_common.cpp | 53 ++ src/library/hw_identifier/hw_identifier_facade.cpp | 8 src/library/os/os.h | 4 src/library/os/windows/isvm/BIOSReader.cpp | 121 ++++ src/library/os/windows/network.cpp | 113 ++++ src/inspector/inspector.cpp | 2 src/library/hw_identifier/hw_identifier.hpp | 6 src/library/hw_identifier/identification_strategy.hpp | 2 src/library/os/CMakeLists.txt | 19 src/library/hw_identifier/hw_identifier.cpp | 6 src/library/base/CMakeLists.txt | 2 src/library/locate/LocatorStrategy.cpp | 2 src/library/os/windows/isvm/Native.cpp | 437 ++++++++++++++++ src/library/os/cpu_info.hpp | 6 src/library/os/execution_environment.hpp | 25 src/library/os/cpu_info_common.cpp | 2 test/functional/CMakeLists.txt | 10 test/functional/standard-license_test.cpp | 3 src/library/os/windows/isvm/main.cpp | 51 + src/library/base/file_utils.hpp | 0 src/library/base/file_utils.cpp | 2 src/library/locate/ApplicationFolder.cpp | 2 src/library/os/windows/isvm/BIOSReader.h | 22 test/functional/date_test.cpp | 2 src/library/os/windows/cpu_info.cpp | 48 + src/library/os/windows/execution_environment.cpp | 39 + src/library/os/windows/isvm/Native.h | 18 /dev/null | 1 doc/snippets/hardware.cpp | 266 ++++++++++ src/library/hw_identifier/disk_strategy.cpp | 19 src/library/locate/EnvironmentVarLocation.cpp | 2 src/library/os/linux/network.cpp | 20 doc/CREDITS.md | 9 src/library/os/windows/signature_verifier.cpp | 9 src/library/hw_identifier/ethernet.cpp | 2 src/library/os/windows/os-win.c | 134 ---- src/library/hw_identifier/default_strategy.cpp | 8 test/library/Os_Linux_test.cpp | 21 src/library/os/linux/cpu_info.cpp | 3 test/functional/crack_test.cpp | 3 42 files changed, 1,312 insertions(+), 230 deletions(-) diff --git a/build/.gitkeep b/build/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/build/.gitkeep +++ /dev/null diff --git a/doc/CREDITS.md b/doc/CREDITS.md index 918606c..74b8e5e 100644 --- a/doc/CREDITS.md +++ b/doc/CREDITS.md @@ -1,7 +1,10 @@ -The following code has been used in OpenLicenseManager. Many thanks to the authors +The following open source code has been used in OpenLicenseManager. +Thanks to every one of the authors of such projects. Without you open license manager would never have been completed. -======================================================== +## isVM +Thanks for the great smbios parsing code. It saved me days. + isvm : https://github.com/0of/isvm The MIT License (MIT) @@ -25,5 +28,5 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -============================= + diff --git a/doc/snippets/hardware.cpp b/doc/snippets/hardware.cpp new file mode 100644 index 0000000..bf4e0be --- /dev/null +++ b/doc/snippets/hardware.cpp @@ -0,0 +1,266 @@ +/********************* physical_processors.cpp ***************************** +* Author: Agner Fog +* Date created: 2019-10-29 +* Last modified: 2019-11-25 +* Version: 1.02 beta +* Project: vector class library +* Description: Detect number of physical and logical processors on CPU chip. +* Compile for C++11 or later +* +* (c) Copyright 2019 Agner Fog. +* Apache License version 2.0 or later. +******************************************************************************* +Some modern CPUs can run two threads in each CPU core when simultaneous +multithreading (SMT, called hyperthreading by Intel) is enabled. + +The number of physical processors is the number of CPU cores. +The number of logical processors is the same number multiplied by the number of +threads that can run simultaneously in each CPU core. + +Simultaneous multithreading will slow down performance when two CPU-intensive +threads running in the same physical processor (CPU core) are competing for the +same resources. Therefore, the optimal number of threads for CPU-intensive +tasks is most likely to be the number of physical processors. + +Tasks that are less CPU-intensive but limited by RAM access, disk access, +network, etc. may get an advantage by running as many threads as the number of +logical processors. This will be double the number of physical processors when +simultaneous multithreading is enabled. + +The physicalProcessors function detects the number of physical processors and +logical processors on an x86 computer. This is useful for determining the +optimal number of threads. + + +Note: There are several problems in detecting the number of physical processors: + +1. The CPUID instruction on Intel CPUs will return a wrong number of logical + processors when SMT (hyperthreading) is disabled. It may be necessary to + compare the number of processors returned by the CPUID instruction with the + number of processors reported by the operating system to detect if SMT is + enabled (AMD processors do not have this problem). + +2. It is necessary to rely on system functions to detect if there is more than + one CPU chip installed. It is assumed that the status of SMT is the same on + all CPU chips in a system. + +3. The behavior of VIA processors is undocumented. + +4. This function is not guaranteed to work on future CPUs. It may need updating + when new CPUs with different configurations or different CPUID functionality + appear. +******************************************************************************/ + +#include <thread> // std::thread functions + +#ifdef _MSC_VER +#include <intrin.h> // __cpuidex intrinsic function available on microsoft compilers +#endif + +// Define interface to CPUID instruction. +// input: leaf = eax, subleaf = ecx +// output: output[0] = eax, output[1] = ebx, output[2] = ecx, output[3] = edx +static inline void cpuid(int output[4], int leaf, int subleaf = 0) { +#if defined(__GNUC__) || defined(__clang__) // use inline assembly, Gnu/AT&T syntax + int a, b, c, d; + __asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(leaf), "c"(subleaf) : ); + output[0] = a; + output[1] = b; + output[2] = c; + output[3] = d; + +#elif defined (_MSC_VER) // Microsoft compiler, intrin.h included + __cpuidex(output, leaf, subleaf); // intrinsic function for CPUID + +#else // unknown platform. try inline assembly with masm/intel syntax + __asm { + mov eax, leaf + mov ecx, subleaf + cpuid; + mov esi, output + mov[esi], eax + mov[esi + 4], ebx + mov[esi + 8], ecx + mov[esi + 12], edx + } +#endif +} + +// Function prototype: +int physicalProcessors(int * logical_processors = 0); + + +// Find the number of physical and logical processors supported by CPU +// Parameter: +// logical_processors: an optional pointer to an integer that will receive the number of logical processors. +// Return value: number of physical processors +int physicalProcessors(int * logical_processors) { + int vendor = 0; // CPU vendor: 1 = Intel, 2 = AMD, 3 = VIA, 0 = other + int logicalProc = 1; // number of logical processor cores + int physicalProc = 1; // number of physical processor cores + int procPerCore = 1; // logical cores per physical core + bool hyperthreadingSupported = false; // CPU supports hyperthreading / simultaneous multithreading + int systemProcessors = std::thread::hardware_concurrency(); // number of processors reported by operating system + + int abcd[4] = { 0,0,0,0 }; // CPUID output + cpuid(abcd, 0); // CPUID function 0 + + int maxLeaf = abcd[0]; // maximum eax input for CPUID + if (abcd[2] == 0x6C65746E) { // last 4 chars of "GenuineIntel" + vendor = 1; + } + else if (abcd[2] == 0x444D4163) { // last 4 chars of "AuthenticAMD" + vendor = 2; + } + else if (abcd[2] == 0x736C7561) { // last 4 chars of "CentaurHauls" + vendor = 3; + } + + if (maxLeaf >= 1) { + cpuid(abcd, 1); + if (abcd[3] & (1 << 28)) { // hyperthreading supported + hyperthreadingSupported = true; + } + } + + if (vendor == 1) { + ////////////////// + // Intel // + ////////////////// + + int hyper = 0; // hyperthreading status: 0 = unknown, 1 = disabled, 2 = enabled + if (maxLeaf >= 0xB) { // leaf 0xB or 0x1F: Extended Topology Enumeration + int num = 0xB; + // if (maxLeaf >= 0x1F) num = 0x1F; + + for (int c = 0; c < 5; c++) { + cpuid(abcd, num, c); // enumeration level c + int type = (abcd[2] >> 8) & 0xFF;// enumeration type at level c + if (type == 1) { // SMT level + procPerCore = abcd[1] & 0xFFFF; + } + else if (type >= 2) { // core level + logicalProc = abcd[1] & 0xFFFF; + } + else if (type == 0) break; + // There are more types/levels to consider if we use num = 0x1F. We may need + // to fix this in the future if CPUs with more complex configurations appear + } + physicalProc = logicalProc / procPerCore; + + // The number of performance monitor registers depends on hyperthreading status + // on Intel CPUs with performance monitoring version 3 or 4 + cpuid(abcd, 0xA, 0); // performance monitor counters information + int perfVersion = abcd[0] & 0xFF; // performance monitoring version + int perfNum = (abcd[0] >> 8) & 0xFF; // number of performance monitoring registers + if (perfVersion == 3 || perfVersion == 4) { + if (perfNum == 4) { + hyper = 2; // 4 performance registers when hyperthreading enabled + } + else if (perfNum == 8) { // 8 performance registers when hyperthreading disabled + hyper = 1; + procPerCore = 1; + logicalProc = physicalProc; // reduce the number of logical processors when hyperthreading is disabled + } + // hyper remains 0 in all other cases, indicating unknown status + } + } + else if (maxLeaf >= 4) { // CPUID function 4: cache parameters and cores + cpuid(abcd, 4); + logicalProc = (abcd[0] >> 26) + 1; + if (hyperthreadingSupported) { + // number of logical processors per core is not known. Assume 2 if hyperthreading supported + procPerCore = 2; + } + physicalProc = logicalProc / procPerCore; + } + else { + // no information. Assume 1 processor + } + if (systemProcessors > logicalProc) { + // Multiple CPU chips. Assume that chips are identical with respect to hypethreading + physicalProc = systemProcessors * physicalProc / logicalProc; + logicalProc = systemProcessors; + } + else if (logicalProc > systemProcessors && systemProcessors > 0 && hyper == 0) { + // Hyperthreading is disabled + logicalProc = systemProcessors; + physicalProc = systemProcessors; + } + } + else if (vendor == 2) { + + ////////////////// + // AMD // + ////////////////// + + cpuid(abcd, 0x80000000); // AMD specific CPUID functions + int maxLeaf8 = abcd[0] & 0xFFFF; // maximum eax 0x8000.... input for CPUID + + if (maxLeaf8 >= 8) { + cpuid(abcd, 0x80000008); + logicalProc = (abcd[2] & 0xFF) + 1; + + if (maxLeaf8 >= 0x1E) { + cpuid(abcd, 0x8000001E); + procPerCore = ((abcd[1] >> 8) & 0x03) + 1; + // procPerCore = 2 if simultaneous multithreading is enabled, 1 if disabled + } + else { + if (hyperthreadingSupported) { + procPerCore = 2; + } + else { + procPerCore = 1; + } + } + physicalProc = logicalProc / procPerCore; + } + else if (hyperthreadingSupported) { + // number of logical processors per core is not known. Assume 2 if SMT supported + logicalProc = 2; + physicalProc = 1; + } + if (systemProcessors > logicalProc) { + // Multiple CPU chips. Assume that chips are identical with respect to SMT + physicalProc = systemProcessors * physicalProc / logicalProc; + logicalProc = systemProcessors; + } + } + else { + + ////////////////////////////// + // VIA or unknown CPU // + ////////////////////////////// + + // The behavior of VIA processors is undocumented! It is not known how to detect threads on a VIA processor + physicalProc = logicalProc = systemProcessors; + if (hyperthreadingSupported && physicalProc > 1) { + physicalProc /= 2; + } + } + if (logical_processors) { + // return logical_processors if pointer is not null + *logical_processors = logicalProc; + } + return physicalProc; +} + +/* Uncomment this for testing: + +#include <stdio.h> + +int main() { + + int logicalProc = 0; + int physicalProc = physicalProcessors(&logicalProc); + + printf("\nlogical processors: %i", logicalProc); + printf("\nphysical processors: %i", physicalProc); + printf("\nlogical processors per core: %i", logicalProc / physicalProc); + int sysproc = std::thread::hardware_concurrency(); + printf("\nsystem processors: %i", sysproc); + + return 0; +} +*/ \ No newline at end of file diff --git a/src/inspector/inspector.cpp b/src/inspector/inspector.cpp index ee3a483..9ae38f5 100644 --- a/src/inspector/inspector.cpp +++ b/src/inspector/inspector.cpp @@ -37,7 +37,7 @@ } int main(int argc, char* argv[]) { - license::CpuInfo cpu; + license::os::CpuInfo cpu; cout << "CpuVendor :" << cpu.vendor() << endl; cout << "Virtual machine:" << cpu.cpu_virtual() << endl; cout << "Cpu model : 0x" << std::hex << ((long)cpu.model()) << std::dec << endl; diff --git a/src/library/base/CMakeLists.txt b/src/library/base/CMakeLists.txt index 5bed712..f0f9588 100644 --- a/src/library/base/CMakeLists.txt +++ b/src/library/base/CMakeLists.txt @@ -1,7 +1,7 @@ ADD_LIBRARY(base OBJECT EventRegistry.cpp StringUtils.cpp - FileUtils.cpp + file_utils.cpp base64.cpp logger.c ) diff --git a/src/library/base/FileUtils.cpp b/src/library/base/file_utils.cpp similarity index 98% rename from src/library/base/FileUtils.cpp rename to src/library/base/file_utils.cpp index f8fcc20..221cd77 100644 --- a/src/library/base/FileUtils.cpp +++ b/src/library/base/file_utils.cpp @@ -11,7 +11,7 @@ #include <iostream> #include <algorithm> -#include "FileUtils.hpp" +#include "file_utils.hpp" namespace license { using namespace std; diff --git a/src/library/base/FileUtils.hpp b/src/library/base/file_utils.hpp similarity index 100% rename from src/library/base/FileUtils.hpp rename to src/library/base/file_utils.hpp diff --git a/src/library/hw_identifier/default_strategy.cpp b/src/library/hw_identifier/default_strategy.cpp index a770512..da21f20 100644 --- a/src/library/hw_identifier/default_strategy.cpp +++ b/src/library/hw_identifier/default_strategy.cpp @@ -14,16 +14,16 @@ namespace hw_identifier { static vector<LCC_API_IDENTIFICATION_STRATEGY> available_strategies() { - ExecutionEnvironment exec; - VIRTUALIZATION virtualization = exec.getVirtualization(); + os::ExecutionEnvironment exec; + os::VIRTUALIZATION virtualization = exec.getVirtualization(); vector<LCC_API_IDENTIFICATION_STRATEGY> strategy_to_try; - if (virtualization == CONTAINER) { + if (virtualization == os::CONTAINER) { if (exec.is_docker()) { strategy_to_try = LCC_DOCKER_STRATEGIES; } else { strategy_to_try = LCC_LXC_STRATEGIES; } - } else if (virtualization == VM) { + } else if (virtualization == os::VM) { if (exec.is_cloud()) { strategy_to_try = LCC_CLOUD_STRATEGIES; } else { diff --git a/src/library/hw_identifier/disk_strategy.cpp b/src/library/hw_identifier/disk_strategy.cpp index cec5da8..4fe212e 100644 --- a/src/library/hw_identifier/disk_strategy.cpp +++ b/src/library/hw_identifier/disk_strategy.cpp @@ -14,10 +14,10 @@ static FUNCTION_RETURN generate_disk_pc_id(vector<array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA>> &v_disk_id, bool use_id) { - size_t disk_num, available_disk_info = 0; + size_t disk_num = 0; + size_t available_disk_info = 0; FUNCTION_RETURN result_diskinfos; unsigned int i; - DiskInfo *diskInfos; result_diskinfos = getDiskInfos(nullptr, &disk_num); if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) { @@ -26,13 +26,14 @@ if (disk_num == 0) { return FUNC_RET_NOT_AVAIL; } - - diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo)); + size_t mem = disk_num * sizeof(DiskInfo); + DiskInfo *diskInfos = (DiskInfo *)malloc(mem); if (diskInfos == nullptr) { return FUNC_RET_NOT_AVAIL; } - memset(diskInfos, 0, disk_num * sizeof(DiskInfo)); + memset(diskInfos, 0, mem); result_diskinfos = getDiskInfos(diskInfos, &disk_num); + if (result_diskinfos != FUNC_RET_OK) { free(diskInfos); return result_diskinfos; @@ -46,17 +47,19 @@ return FUNC_RET_NOT_AVAIL; } v_disk_id.reserve(available_disk_info); + //FIXME use preferred drive. for (i = 0; i < disk_num; i++) { array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> a_disk_id; + a_disk_id.fill(0); if (use_id) { if (diskInfos[i].disk_sn[0] != 0) { - memcpy(&a_disk_id[0], &diskInfos[i].disk_sn[2], a_disk_id.size()); + size_t size = min(a_disk_id.size(), sizeof(&diskInfos[i].disk_sn)); + memcpy(&a_disk_id[0], diskInfos[i].disk_sn, size); v_disk_id.push_back(a_disk_id); } } else { if (diskInfos[i].label[0] != 0) { - a_disk_id.fill(0); - strncpy((char *)&a_disk_id[0], diskInfos[i].label, a_disk_id.size()); + strncpy((char *)&a_disk_id[0], diskInfos[i].label, a_disk_id.size()-1); v_disk_id.push_back(a_disk_id); } } diff --git a/src/library/hw_identifier/ethernet.cpp b/src/library/hw_identifier/ethernet.cpp index 1d923e6..ce1d6de 100644 --- a/src/library/hw_identifier/ethernet.cpp +++ b/src/library/hw_identifier/ethernet.cpp @@ -32,7 +32,7 @@ } for (auto &it : adapters) { - unsigned int k, data_len, data_byte; + unsigned int k, data_len; array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> identifier; data_len = use_ip ? sizeof(os::OsAdapterInfo::ipv4_address) : sizeof(os::OsAdapterInfo::mac_address); diff --git a/src/library/hw_identifier/hw_identifier.cpp b/src/library/hw_identifier/hw_identifier.cpp index b0d31f8..5c163e7 100644 --- a/src/library/hw_identifier/hw_identifier.cpp +++ b/src/library/hw_identifier/hw_identifier.cpp @@ -47,16 +47,16 @@ } } -void HwIdentifier::set_virtual_environment(VIRTUALIZATION virt) { +void HwIdentifier::set_virtual_environment(os::VIRTUALIZATION virt) { // 110000 0x30 m_data[0] = (m_data[0] & ~0x30) | virt << 4; } -void HwIdentifier::set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail) { +void HwIdentifier::set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail) { m_data[0] = (m_data[0] & ~0x0F) | virtualization_detail; } -void HwIdentifier::set_cloud_provider(CLOUD_PROVIDER cloud_provider) { +void HwIdentifier::set_cloud_provider(os::CLOUD_PROVIDER cloud_provider) { m_data[0] = (m_data[0] & ~0x0F) | cloud_provider | 0x08; } diff --git a/src/library/hw_identifier/hw_identifier.hpp b/src/library/hw_identifier/hw_identifier.hpp index d7cec0e..56d3716 100644 --- a/src/library/hw_identifier/hw_identifier.hpp +++ b/src/library/hw_identifier/hw_identifier.hpp @@ -53,9 +53,9 @@ void set_identification_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy); LCC_API_IDENTIFICATION_STRATEGY get_identification_strategy() const; void set_use_environment_var(bool use_env_var); - void set_virtual_environment(VIRTUALIZATION virtualization); - void set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail); - void set_cloud_provider(CLOUD_PROVIDER cloud_provider); + 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; diff --git a/src/library/hw_identifier/hw_identifier_facade.cpp b/src/library/hw_identifier/hw_identifier_facade.cpp index 45abb5d..755eb75 100644 --- a/src/library/hw_identifier/hw_identifier_facade.cpp +++ b/src/library/hw_identifier/hw_identifier_facade.cpp @@ -57,16 +57,16 @@ if (result != FUNC_RET_OK) { /// FIXME } - ExecutionEnvironment exec; - VIRTUALIZATION virtualization = exec.getVirtualization(); + 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 != NONE) { + if (virtualization != os::NONE) { bool isCloud = exec.is_cloud(); if (isCloud) { pc_id.set_cloud_provider(exec.getCloudProvider()); } else { - CpuInfo cpu; + os::CpuInfo cpu; pc_id.set_virtualization(cpu.getVirtualizationDetail()); } } diff --git a/src/library/hw_identifier/identification_strategy.hpp b/src/library/hw_identifier/identification_strategy.hpp index ad3e2de..22ded81 100644 --- a/src/library/hw_identifier/identification_strategy.hpp +++ b/src/library/hw_identifier/identification_strategy.hpp @@ -11,7 +11,7 @@ #include <licensecc/datatypes.h> #include <licensecc_properties.h> #include <vector> -#include <bits/unique_ptr.h> +#include <memory> #include "../base/base.h" #include "hw_identifier.hpp" diff --git a/src/library/hw_identifier/pc-identifiers.c b/src/library/hw_identifier/pc-identifiers.c deleted file mode 100644 index 55ec2ba..0000000 --- a/src/library/hw_identifier/pc-identifiers.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * pc-identifiers.c - * - * Created on: Apr 16, 2014 - * - */ -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "../os/os.h" -#include "pc-identifiers.h" -#include "../base/base64.h" -#include "../base/base.h" -#ifdef __linux__ -#include <stdbool.h> -#include <valgrind/memcheck.h> -#else -#ifdef __MINGW32__ -#include <windows.h> -#else -#include <Windows.h> -#endif -#endif - -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_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; - OsAdapterInfo *adapterInfoPtr; - - if (identifiers == NULL || *num_identifiers == 0) { - result_adapterInfos = getAdapterInfos(NULL, &adapter_num); - if ((result_adapterInfos != FUNC_RET_OK) || (adapter_num == 0)) { - return generate_disk_pc_id(identifiers, num_identifiers, false); - } - result_diskinfos = getDiskInfos(NULL, &disk_num); - if ((result_diskinfos != FUNC_RET_OK) || (disk_num == 0)) { - return generate_ethernet_pc_id(identifiers, num_identifiers, true); - } - *num_identifiers = disk_num * adapter_num; - function_return = FUNC_RET_OK; - } else { - 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) { - free(adapterInfoPtr); - return generate_disk_pc_id(identifiers, num_identifiers, false); - } - 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) { - free(diskInfoPtr); - free(adapterInfoPtr); - return generate_ethernet_pc_id(identifiers, num_identifiers, true); - } - function_return = FUNC_RET_OK; - - caller_identifiers = *num_identifiers; - for (i = 0; i < disk_num; i++) { - for (j = 0; j < adapter_num; j++) { - array_index = i * adapter_num + j; - if (array_index >= caller_identifiers) { - function_return = FUNC_RET_BUFFER_TOO_SMALL; - goto end; - } - for (k = 0; k < 6; k++) - identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2] ^ adapterInfoPtr[j].mac_address[k + 2]; - } - } - end: -#ifdef _MSC_VER - *num_identifiers = min(*num_identifiers, adapter_num * disk_num); -#else - *num_identifiers = cmin(*num_identifiers, adapter_num * disk_num); -#endif - free(diskInfoPtr); - free(adapterInfoPtr); - } - return function_return; -} - -static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac) { - return FUNC_RET_NOT_AVAIL; -} - -/** - * - * Calculates all the possible identifiers for the current machine, for the - * given calculation strategy requested. Pc identifiers are more than one, - * for instance a machine with more than one disk and one network interface has - * usually multiple identifiers. - * - * First 4 bit of each pc identifier are reserved 3 for the type of strategy - * used in calculation and 1 for parity checks (not implemented here) - * - * @param identifiers - * @param array_size - * @param - * @return - */ - -FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, LCC_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 STRATEGY_DEFAULT: - result = generate_default_pc_id(identifiers, array_size); - break; - case STRATEGY_ETHERNET: - result = generate_ethernet_pc_id(identifiers, array_size, true); - break; - case STRATEGY_IP_ADDRESS: - result = generate_ethernet_pc_id(identifiers, array_size, false); - break; - case STRATEGY_DISK_NUM: - result = generate_disk_pc_id(identifiers, array_size, false); - break; - case STRATEGY_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 - identifiers[i][0] = (identifiers[i][0] & 15) | strategy_num; - } - // 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 - } - } - } - return result; -} - -char *MakeCRC(char *BitString) { - static char Res[3]; // CRC Result - char CRC[2]; - int i; - - for (i = 0; i < 2; ++i) CRC[i] = 0; // Init before calculation - - for (i = 0; i < strlen(BitString); ++i) { - char 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 - - return (Res); -} - -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; - int b64_size = 0; - const size_t concatIdentifiersSize = sizeof(PcIdentifier) * 2; - // 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); - if (b64_size > sizeof(PcSignature)) { - 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); - free(b64_data); - 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, LCC_IDENTIFICATION_STRATEGY strategy) { - FUNCTION_RETURN result; - PcIdentifier *identifiers; - unsigned int req_buffer_size = 0; - result = generate_pc_id(NULL, &req_buffer_size, strategy); - if (result != FUNC_RET_OK) { - return result; - } - if (req_buffer_size == 0) { - return FUNC_RET_ERROR; - } - req_buffer_size = req_buffer_size < 2 ? 2 : 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) { - free(identifiers); - return result; - } -#ifdef __linux__ - VALGRIND_CHECK_VALUE_IS_DEFINED(identifiers[0]); - VALGRIND_CHECK_VALUE_IS_DEFINED(identifiers[1]); -#endif - result = encode_pc_id(identifiers[0], identifiers[1], identifier_out); -#ifdef __linux__ - VALGRIND_CHECK_VALUE_IS_DEFINED(identifier_out); -#endif - free(identifiers); - return result; -} - -/** - * Extract the two pc identifiers from the user provided code. - * @param identifier1_out - * @param identifier2_out - * @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 - - 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]); - 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)); - free(concat_identifiers); - return FUNC_RET_OK; -} - -static LCC_IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) { - return (LCC_IDENTIFICATION_STRATEGY)identifier[0] >> 5; -} - -LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code) { - PcIdentifier user_identifiers[2]; - FUNCTION_RETURN result; - LCC_IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id; - PcIdentifier *calculated_identifiers = NULL; - unsigned int calc_identifiers_size = 0; - int i = 0, j = 0; - // bool found; -#ifdef _DEBUG - printf("Comparing pc identifiers: \n"); -#endif - result = decode_pc_id(user_identifiers[0], user_identifiers[1], str_code); - if (result != FUNC_RET_OK) { - return result; - } - previous_strategy_id = STRATEGY_UNKNOWN; - // 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) { - free(calculated_identifiers); - 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) { - continue; - } - if (current_strategy_id != previous_strategy_id) { - if (calculated_identifiers != NULL) { - free(calculated_identifiers); - } - 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); - memset(calculated_identifiers, 0, sizeof(PcIdentifier) * calc_identifiers_size); - generate_pc_id(calculated_identifiers, &calc_identifiers_size, current_strategy_id); - } - // 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); - -#endif - if (!memcmp(user_identifiers[i], calculated_identifiers[j], sizeof(PcIdentifier))) { - free(calculated_identifiers); - return LICENSE_OK; - } - } - } - free(calculated_identifiers); - return IDENTIFIERS_MISMATCH; -} diff --git a/src/library/hw_identifier/pc-identifiers.h b/src/library/hw_identifier/pc-identifiers.h deleted file mode 100644 index d7d3b14..0000000 --- a/src/library/hw_identifier/pc-identifiers.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * pc-identifiers.h - * - * Created on: Apr 16, 2014 - * - */ - -#ifndef PC_IDENTIFIERS_H_ -#define PC_IDENTIFIERS_H_ - -#include <licensecc/datatypes.h> - -#ifdef __cplusplus -extern "C" { -#endif -#include "../base/base.h" - -typedef char PcSignature[LCC_API_PC_IDENTIFIER_SIZE + 1]; - -FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers, unsigned int * array_size, - LCC_IDENTIFICATION_STRATEGY strategy); - -LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code); - -/** - * Generates an UserPcIdentifier. - * - * @param identifier_out - * @param strategy - * @return - */ -FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, LCC_IDENTIFICATION_STRATEGY strategy); - -#ifdef __cplusplus -} -#endif -#endif /* PC_IDENTIFIERS_H_ */ diff --git a/src/library/locate/ApplicationFolder.cpp b/src/library/locate/ApplicationFolder.cpp index b13fedd..8bc7f5a 100644 --- a/src/library/locate/ApplicationFolder.cpp +++ b/src/library/locate/ApplicationFolder.cpp @@ -15,9 +15,9 @@ #include "../base/logger.h" #include "../base/base.h" #include "../base/EventRegistry.h" -#include "../base/FileUtils.hpp" #include "../os/os.h" #include "ApplicationFolder.hpp" +#include "../base/file_utils.hpp" namespace license { namespace locate { diff --git a/src/library/locate/EnvironmentVarLocation.cpp b/src/library/locate/EnvironmentVarLocation.cpp index 070ad8d..e74228a 100644 --- a/src/library/locate/EnvironmentVarLocation.cpp +++ b/src/library/locate/EnvironmentVarLocation.cpp @@ -7,9 +7,9 @@ #include <licensecc_properties.h> -#include "../base/FileUtils.hpp" #include "../base/StringUtils.h" #include "EnvironmentVarLocation.hpp" +#include "../base/file_utils.hpp" namespace license { namespace locate { diff --git a/src/library/locate/ExternalDefinition.cpp b/src/library/locate/ExternalDefinition.cpp index 7add948..a5309de 100644 --- a/src/library/locate/ExternalDefinition.cpp +++ b/src/library/locate/ExternalDefinition.cpp @@ -9,19 +9,19 @@ #include <cstring> #include <string> #include <vector> - +#include <stdexcept> #include <licensecc/datatypes.h> #include "../base/base64.h" #include "../base/EventRegistry.h" -#include "../base/FileUtils.hpp" #include "../base/StringUtils.h" #include "ExternalDefinition.hpp" +#include "../base/file_utils.hpp" namespace license { namespace locate { -using namespace std; + using namespace std; ExternalDefinition::ExternalDefinition(const LicenseLocation *location) : LocatorStrategy("ExternalDefinition"), m_location(location) {} diff --git a/src/library/locate/LocatorStrategy.cpp b/src/library/locate/LocatorStrategy.cpp index 5e64648..04c722d 100644 --- a/src/library/locate/LocatorStrategy.cpp +++ b/src/library/locate/LocatorStrategy.cpp @@ -7,8 +7,8 @@ #include <licensecc_properties.h> -#include "../base/FileUtils.hpp" #include "LocatorStrategy.hpp" +#include "../base/file_utils.hpp" namespace license { namespace locate { diff --git a/src/library/os/CMakeLists.txt b/src/library/os/CMakeLists.txt index 986550f..c22b806 100644 --- a/src/library/os/CMakeLists.txt +++ b/src/library/os/CMakeLists.txt @@ -2,6 +2,7 @@ IF(UNIX) add_library(os OBJECT openssl/signature_verifier.cpp + execution_environment_common.cpp linux/execution_environment.cpp cpu_info_common.cpp linux/cpu_info.cpp @@ -9,11 +10,25 @@ linux/os-linux.c) ELSE(UNIX) add_library(os OBJECT - cpu_info_common.cpp openssl/signature_verifier.cpp windows/os-win.c) + cpu_info_common.cpp windows/cpu_info.cpp + openssl/signature_verifier.cpp + execution_environment_common.cpp windows/execution_environment.cpp + windows/isvm/Native.cpp + windows/isvm/BIOSReader.cpp + windows/os-win.c + windows/network.cpp) ENDIF(UNIX) ELSE(UNIX OR OPENSSL_FOUND) +#windows no openssl add_library(os OBJECT - cpu_info_common.cpp windows/signature_verifier.cpp windows/os-win.c) + cpu_info_common.cpp + windows/cpu_info.cpp + windows/signature_verifier.cpp + execution_environment_common.cpp windows/execution_environment.cpp + windows/isvm/Native.cpp + windows/isvm/BIOSReader.cpp + windows/os-win.c + windows/network.cpp) ENDIF(UNIX OR OPENSSL_FOUND) if(CODE_COVERAGE AND UNIX) diff --git a/src/library/os/cpu_info.hpp b/src/library/os/cpu_info.hpp index 04da89b..662e181 100644 --- a/src/library/os/cpu_info.hpp +++ b/src/library/os/cpu_info.hpp @@ -9,7 +9,7 @@ #define SRC_LIBRARY_OS_CPU_INFO_H_ #include <string> namespace license { - +namespace os { typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, V_XEN, KVM, HV, V_OTHER } VIRTUALIZATION_DETAIL; /** @@ -32,6 +32,6 @@ VIRTUALIZATION_DETAIL getVirtualizationDetail() const; }; -} /* namespace license */ - +} // namespace os +} // namespace license #endif /* SRC_LIBRARY_OS_CPU_INFO_H_ */ diff --git a/src/library/os/cpu_info_common.cpp b/src/library/os/cpu_info_common.cpp index d75ccf1..119b77e 100644 --- a/src/library/os/cpu_info_common.cpp +++ b/src/library/os/cpu_info_common.cpp @@ -8,6 +8,7 @@ #include "cpu_info.hpp" namespace license { +namespace os { using namespace std; const unordered_map<string, VIRTUALIZATION_DETAIL> virtual_cpu_names{ @@ -39,4 +40,5 @@ } return result; } +} // namespace os } // namespace license diff --git a/src/library/os/execution_environment.hpp b/src/library/os/execution_environment.hpp index ce3fb63..bc503fb 100644 --- a/src/library/os/execution_environment.hpp +++ b/src/library/os/execution_environment.hpp @@ -8,10 +8,15 @@ #ifndef SRC_LIBRARY_OS_VIRTUALIZATION_HPP_ #define SRC_LIBRARY_OS_VIRTUALIZATION_HPP_ +#include <string> + namespace license { +namespace os { typedef enum { NONE, CONTAINER, VM } VIRTUALIZATION; + typedef enum { + PROV_UNKNOWN, ON_PREMISE, GOOGLE_CLOUD, AZURE_CLOUD, @@ -25,17 +30,23 @@ ALI_CLOUD } CLOUD_PROVIDER; - class ExecutionEnvironment { +private: + std::string sys_vendor; + std::string bios_vendor; + std::string bios_description; + //detect if it's a kind of container technology (docker or lxc) + bool is_container() const; public: - ExecutionEnvironment(){}; - virtual ~ExecutionEnvironment(){}; - VIRTUALIZATION getVirtualization(); - bool is_cloud(); - bool is_docker(); - CLOUD_PROVIDER getCloudProvider(); + ExecutionEnvironment(); + ~ExecutionEnvironment(){}; + VIRTUALIZATION getVirtualization() const; + bool is_cloud() const; + bool is_docker() const; + CLOUD_PROVIDER getCloudProvider() const; }; +} // namespace os } // namespace license #endif /* SRC_LIBRARY_OS_VIRTUALIZATION_HPP_ */ diff --git a/src/library/os/execution_environment_common.cpp b/src/library/os/execution_environment_common.cpp new file mode 100644 index 0000000..9fa2a38 --- /dev/null +++ b/src/library/os/execution_environment_common.cpp @@ -0,0 +1,53 @@ +/* + * + * Created on: Feb 23, 2020 + * Author: GC + */ + +#include <stdio.h> +#include <string.h> +#include <unordered_map> +#include <array> + +#include "../base/base.h" +#include "cpu_info.hpp" +#include "execution_environment.hpp" + +namespace license { +namespace os { +using namespace std; + +VIRTUALIZATION ExecutionEnvironment::getVirtualization() const { + VIRTUALIZATION result; + CpuInfo cpuInfo; + bool isContainer = is_container(); + if (isContainer) { + result = CONTAINER; + } else if (cpuInfo.cpu_virtual() || is_cloud()) { + result = VM; + } else { + result = NONE; + } + return result; +} + +bool ExecutionEnvironment::is_cloud() const { return getCloudProvider() != ON_PREMISE; } + +// TODO test and azure +CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() const { + CLOUD_PROVIDER result = PROV_UNKNOWN; + 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 (sys_vendor.find("GOOGLE") != string::npos || bios_description.find("GOOGLE") != string::npos) { + result = GOOGLE_CLOUD; + } else if (bios_vendor.find("AWS") != string::npos || bios_description.find("AMAZON") != string::npos || + sys_vendor.find("AWS") != string::npos) { + result = AWS; + } + } + return result; +} +} // namespace os +} // namespace license diff --git a/src/library/os/linux/cpu_info.cpp b/src/library/os/linux/cpu_info.cpp index 4b5ff85..b052a03 100644 --- a/src/library/os/linux/cpu_info.cpp +++ b/src/library/os/linux/cpu_info.cpp @@ -11,6 +11,7 @@ #include "../cpu_info.hpp" namespace license { +namespace os { using namespace std; struct CPUVendorID { @@ -52,5 +53,5 @@ CPUVendorID vendorID{.ebx = ebx, .edx = edx, .ecx = ecx}; return vendorID.toString(); } - +} // namespace os } /* namespace license */ diff --git a/src/library/os/linux/execution_environment.cpp b/src/library/os/linux/execution_environment.cpp index bbddd75..9aad864 100644 --- a/src/library/os/linux/execution_environment.cpp +++ b/src/library/os/linux/execution_environment.cpp @@ -17,8 +17,10 @@ #include "../../base/base.h" #include "../cpu_info.hpp" #include "../execution_environment.hpp" +#include "../../base/file_utils.hpp" namespace license { +namespace os { using namespace std; // 0=NO 1=Docker/2=Lxc @@ -80,26 +82,24 @@ return result; } -VIRTUALIZATION ExecutionEnvironment::getVirtualization() { - VIRTUALIZATION result; - CpuInfo cpuInfo; - bool isContainer = checkContainerProc() != 0 || checkSystemdContainer() != 0; - if (isContainer) { - result = CONTAINER; - } else if (cpuInfo.cpu_virtual() || is_cloud()) { - result = VM; - } else { - result = NONE; +ExecutionEnvironment::ExecutionEnvironment() { + try { + bios_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256); + } catch (...) { } - return result; + try { + bios_description = get_file_contents("/sys/class/dmi/id/modalias", 256); + } catch (...) { + } + try { + sys_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256); + } catch (...) { + } } -bool ExecutionEnvironment::is_cloud() { return getCloudProvider() != ON_PREMISE; } +bool ExecutionEnvironment::is_container() const { return (checkContainerProc() != 0 || checkSystemdContainer() != 0); } -bool ExecutionEnvironment::is_docker() { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); } +bool ExecutionEnvironment::is_docker() const { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); } -CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() { - // TODO -} - +} // namespace os } // namespace license diff --git a/src/library/os/linux/network.cpp b/src/library/os/linux/network.cpp index e456989..475463b 100644 --- a/src/library/os/linux/network.cpp +++ b/src/library/os/linux/network.cpp @@ -23,7 +23,6 @@ #include <ifaddrs.h> #include <linux/if_link.h> #include <netpacket/packet.h> -#include <string.h> #include <stdio.h> #include <unordered_map> @@ -35,25 +34,6 @@ namespace os { using namespace std; -/** - * - * @param ifnames - * @param ifname - * @param ifnames_max - * @return - */ - -static int ifname_position(char *ifnames, char *ifname, int ifnames_max) { - int i, position; - position = -1; - for (i = 0; i < ifnames_max; i++) { - if (strcmp(ifname, &ifnames[i * NI_MAXHOST]) == 0) { - position = i; - break; - } - } - return position; -} /** * diff --git a/src/library/os/os.h b/src/library/os/os.h index 9fda7c7..00abae2 100644 --- a/src/library/os/os.h +++ b/src/library/os/os.h @@ -26,10 +26,10 @@ typedef struct { int id; - char device[255]; + char device[MAX_PATH]; unsigned char disk_sn[8]; char label[255]; - bool preferred; + int preferred; } DiskInfo; FUNCTION_RETURN getDiskInfos(DiskInfo* diskInfos, size_t* disk_info_size); diff --git a/src/library/os/windows/.gitignore b/src/library/os/windows/.gitignore deleted file mode 100644 index f3d0437..0000000 --- a/src/library/os/windows/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/isvm/ diff --git a/src/library/os/windows/cpu_info.cpp b/src/library/os/windows/cpu_info.cpp new file mode 100644 index 0000000..192e178 --- /dev/null +++ b/src/library/os/windows/cpu_info.cpp @@ -0,0 +1,48 @@ +/* + * cpu_info.cpp + * + * Created on: Dec 14, 2019 + * Author: devel + */ + + +#include <intrin.h> +#include <string> +#include <unordered_set> +#include "../cpu_info.hpp" + +namespace license { +namespace os { +using namespace std; + +CpuInfo::CpuInfo() {} + +CpuInfo::~CpuInfo() {} +/** + * Detect Virtual machine using hypervisor bit. + * @return true if the cpu hypervisor bit is set to 1 + */ +bool CpuInfo::is_hypervisor_set() const { + int cpui[4] = {0}; + __cpuid(cpui, 0x1); + + return ((cpui[2] >> 31) & 1); +} + +uint32_t CpuInfo::model() const { + int cpui[4] = {0}; + __cpuid(cpui, 0x1); + // ax bits 0-3 stepping,4-7 model,8-11 family id,12-13 processor type + // 14-15 reserved, 16-19 extended model, 20-27 extended family, 27-31 reserved + // bx bits 0-7 brand index + return (cpui[0] & 0x3FFF) | (cpui[0] & 0x3FF8000) >> 2 | (cpui[1] & 0xff) << 24; +} + +string CpuInfo::vendor() const { + // hypervisor flag false, try to get the vendor name, see if it's a virtual cpu + int cpui[4] = {0}; + __cpuid(cpui, 0x0); + return string(reinterpret_cast<const char *>(cpui), 12); +} +} // namespace os +} /* namespace license */ diff --git a/src/library/os/windows/execution_environment.cpp b/src/library/os/windows/execution_environment.cpp new file mode 100644 index 0000000..86513d5 --- /dev/null +++ b/src/library/os/windows/execution_environment.cpp @@ -0,0 +1,39 @@ +/* + * virtualization.cpp + * + * Created on: Dec 15, 2019 + * Author: GC + */ +#include <sys/stat.h> +#include <fstream> +#include <iostream> +#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" + +namespace license { +namespace os { +using namespace std; + +ExecutionEnvironment::ExecutionEnvironment() { + if (InitEntryPoints()) { + BIOSReader reader; + SystemInformation info = reader.readSystemInfo(); + sys_vendor = toupper_copy(info.Manufacturer); + bios_vendor = toupper_copy(info.ProductName); + bios_description = toupper_copy(info.SysVersion) + toupper_copy(info.family); + } +} + +//TODO +bool ExecutionEnvironment::is_docker() const { return false; } +//TODO +bool ExecutionEnvironment::is_container() const { return is_docker(); } +} // namespace os +} // namespace license diff --git a/src/library/os/windows/isvm/BIOSReader.cpp b/src/library/os/windows/isvm/BIOSReader.cpp new file mode 100644 index 0000000..5d1b146 --- /dev/null +++ b/src/library/os/windows/isvm/BIOSReader.cpp @@ -0,0 +1,121 @@ +#include "BIOSReader.h" + +#include <cstdint> + +#include "Native.h" + +struct smbios_structure_header { + uint8_t type; + uint8_t length; + uint16_t handle; +}; + +// +// System information +// +struct smbios_type_1 { + struct smbios_structure_header header; + uint8_t manufacturer_str; + uint8_t product_name_str; + uint8_t version_str; + uint8_t serial_number_str; + uint8_t uuid[16]; + uint8_t wake_up_type; + uint8_t sku_number_str; + uint8_t family_str; +}; + +#define _TYPE_COUNT1 6 + +#define _CONCATE(x, y) x##y +#define CONCATE(x, y) _CONCATE(x, y) +#define TYPE_COUNT(t) CONCATE(_TYPE_COUNT, t) + +// +// Windows +// +#include <Windows.h> +#include <tchar.h> + +int8_t *parse_smbiod_content(int8_t *addr, int8_t **indexes, int32_t *count) { + //! ignore 0 + int8_t parsed_count = 0; + int8_t *raw_addr = addr; + + //! first one + if (indexes) *indexes = raw_addr; + + bool reach_terminal = false; + + while (true) { + if (0 == *raw_addr++) { + if (reach_terminal) + break; + else { + ++parsed_count; + + if (count && parsed_count < *count) { + if (indexes) *(indexes + parsed_count) = raw_addr; + } + + reach_terminal = true; + } + } else { + reach_terminal = false; + continue; + } + } + + if (count) *count = parsed_count; + + return raw_addr; +} + +void read_smbios_type_1(int8_t *addr, SystemInformation *info) { + smbios_type_1 *t1 = (smbios_type_1 *)addr; + + int32_t offset = ((0x0F) & (t1->header.length >> 4)) * 16 + (t1->header.length & 0x0F); + + int8_t *string_addr[TYPE_COUNT(1)] = {0}; + + int32_t count = TYPE_COUNT(1); + parse_smbiod_content((int8_t *)t1 + offset, string_addr, &count); + + if (0 != t1->manufacturer_str) + info->Manufacturer = (std::string::traits_type::char_type *)string_addr[t1->manufacturer_str - 1]; + + if (0 != t1->product_name_str) + info->ProductName = (std::string::traits_type::char_type *)string_addr[t1->product_name_str - 1]; + + if (0 != t1->serial_number_str) + info->SerialNum = (std::string::traits_type::char_type *)string_addr[t1->serial_number_str - 1]; + + if (0 != t1->version_str) + info->SysVersion = (std::string::traits_type::char_type *)string_addr[t1->version_str - 1]; + + if (0 != t1->family_str) info->family = (std::string::traits_type::char_type *)string_addr[t1->family_str - 1]; +} + +SystemInformation BIOSReader::readSystemInfo() { + SystemInformation info; + + uint32_t size = 0; + RawSMBIOSData *data = (RawSMBIOSData *)(LocateSMBIOS(&size)); + + if (NULL == data || 0 == size) return info; + + smbios_structure_header *header = (smbios_structure_header *)(data->SMBIOSTableData); + + while (NULL != header) { + if (1 == header->type) { + read_smbios_type_1((int8_t *)header, &info); + header = NULL; //! stop + } else { + int32_t offset = ((0x0F) & (header->length >> 4)) * 16 + (header->length & 0x0F); + header = (smbios_structure_header *)parse_smbiod_content((int8_t *)header + offset, NULL, NULL); + } + } + + free(data); + return info; +} diff --git a/src/library/os/windows/isvm/BIOSReader.h b/src/library/os/windows/isvm/BIOSReader.h new file mode 100644 index 0000000..4fcfb05 --- /dev/null +++ b/src/library/os/windows/isvm/BIOSReader.h @@ -0,0 +1,22 @@ +#ifndef BIOSREADER_H +#define BIOSREADER_H + +#include <string> + +class SystemInformation +{ +public: + std::string Manufacturer; + std::string ProductName; + std::string SysVersion; + std::string SerialNum; + std::string family; +}; + +class BIOSReader +{ +public: + SystemInformation readSystemInfo(); +}; + +#endif diff --git a/src/library/os/windows/isvm/Native.cpp b/src/library/os/windows/isvm/Native.cpp new file mode 100644 index 0000000..99fbf8f --- /dev/null +++ b/src/library/os/windows/isvm/Native.cpp @@ -0,0 +1,437 @@ +#include "Native.h" + +#include <tchar.h> + +typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; // windbgkd + +typedef LONG NTSTATUS; +#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) + +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; +#ifdef MIDL_PASS + [size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT * Buffer; +#else // MIDL_PASS + PWSTR Buffer; +#endif // MIDL_PASS +} UNICODE_STRING; +typedef UNICODE_STRING *PUNICODE_STRING; + +typedef enum _SECTION_INHERIT +{ + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT; + +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_VALID_ATTRIBUTES 0x000001F2L + +static bool bIsWindowsXPLater = false; +static DWORD dwPageSize = 0; + +#ifdef _UNICODE +#define GetVersionExProc "GetVersionExW" +#else +#define GetVersionExProc "GetVersionExA" +#endif + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR + PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE +} OBJECT_ATTRIBUTES; +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +typedef struct SMBIOSEntryPoint +{ + char EntryPointString[4]; + uint8_t Checksum; + uint8_t Length; + uint8_t MajorVersion; + uint8_t MinorVersion; + uint16_t MaxStructureSize; + uint8_t EntryPointRevision; + char FormattedArea[5]; + char EntryPointString2[5]; + uint8_t Checksum2; + uint16_t TableLength; + uint32_t TableAddress; + uint16_t NumberOfStructures; + uint8_t BCDRevision; +} SMBIOSEntryPoint, *PSMBIOSEntryPoint; + +#define InitializeObjectAttributes( p, n, a, r, s ) { \ + (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ + (p)->RootDirectory = r; \ + (p)->Attributes = a; \ + (p)->ObjectName = n; \ + (p)->SecurityDescriptor = s; \ + (p)->SecurityQualityOfService = NULL; \ +} + +NTSTATUS(WINAPI *NtUnmapViewOfSection)( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress + ); + +NTSTATUS(WINAPI *NtOpenSection)( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + +NTSTATUS(WINAPI *NtMapViewOfSection)( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset, /* optional */ + IN OUT PULONG ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect + ); + +VOID(WINAPI *RtlInitUnicodeString)( + IN OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString + ); + +ULONG(WINAPI *RtlNtStatusToDosError) ( + IN NTSTATUS Status + ); + +UINT(WINAPI *Win32GetSystemFirmwareTable)( + _In_ DWORD FirmwareTableProviderSignature, + _In_ DWORD FirmwareTableID, + _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer, + _In_ DWORD BufferSize); + +BOOL(WINAPI *Win32GetVersionEx)( + _Inout_ LPOSVERSIONINFO lpVersionInfo + ); + +VOID(WINAPI *Win32GetSystemInfo)( + _Out_ LPSYSTEM_INFO lpSystemInfo + ); + +BOOL(WINAPI *Win32VirtualProtect)( + _In_ LPVOID lpAddress, + _In_ SIZE_T dwSize, + _In_ DWORD flNewProtect, + _Out_ PDWORD lpflOldProtect + ); + +//---------------------------------------------------------------------- +// +// PrintError +// +// Formats an error message for the last error +// +// Mark Russinovich +// Systems Internals +// http://www.sysinternals.com +//---------------------------------------------------------------------- +void PrintError(char *message, NTSTATUS status) +{ + char *errMsg; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, RtlNtStatusToDosError(status), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&errMsg, 0, NULL); + LocalFree(errMsg); +} + +//-------------------------------------------------------- +// +// UnmapPhysicalMemory +// + +// Maps a view of a section. +// +// Mark Russinovich +// Systems Internals +// http://www.sysinternals.com +//-------------------------------------------------------- +static VOID UnmapPhysicalMemory(PVOID Address) +{ + NTSTATUS status; + + status = NtUnmapViewOfSection((HANDLE)-1, Address); + if (!NT_SUCCESS(status)) + { + PrintError("Unable to unmap view", status); + } +} + + +//-------------------------------------------------------- +// +// MapPhysicalMemory +// +// Maps a view of a section. +// +// Mark Russinovich +// Systems Internals +// http://www.sysinternals.com +//-------------------------------------------------------- +static BOOLEAN MapPhysicalMemory(HANDLE PhysicalMemory, + PVOID Address, PDWORD Length, + PVOID *VirtualAddress) +{ + NTSTATUS ntStatus; + PHYSICAL_ADDRESS viewBase; + char error[256]; + + viewBase.QuadPart = (ULONGLONG)(Address); + ntStatus = NtMapViewOfSection(PhysicalMemory, + (HANDLE)-1, + VirtualAddress, + 0L, *Length, + &viewBase, + Length, + ViewShare, + 0, + PAGE_READONLY); + + if (!NT_SUCCESS(ntStatus)) { + + PrintError(error, ntStatus); + return FALSE; + } + + return TRUE; +} + + +//-------------------------------------------------------- +// +// OpensPhysicalMemory +// +// This function opens the physical memory device. It +// uses the native API since +// +// Mark Russinovich +// Systems Internals +// http://www.sysinternals.com +//-------------------------------------------------------- +static HANDLE OpenPhysicalMemory() +{ + NTSTATUS status; + HANDLE physmem; + UNICODE_STRING physmemString; + OBJECT_ATTRIBUTES attributes; + WCHAR physmemName[] = L"\\device\\physicalmemory"; + + RtlInitUnicodeString(&physmemString, physmemName); + + InitializeObjectAttributes(&attributes, &physmemString, + OBJ_CASE_INSENSITIVE, NULL, NULL); + status = NtOpenSection(&physmem, SECTION_MAP_READ, &attributes); + + if (!NT_SUCCESS(status)) + { + PrintError("Could not open \\device\\physicalmemory", status); + return NULL; + } + + return physmem; +} + +static PVOID MapPhysicalMemoryWithBase(HANDLE hPhyHandle, PVOID pBase, PDWORD pLen, PVOID *pVirtualBase) +{ + DWORD dwOffset = (ULONGLONG)pBase % dwPageSize; + DWORD dwLen = *pLen + dwOffset; + + PVOID pVAddr = NULL; + + if (MapPhysicalMemory(hPhyHandle, pBase, &dwLen, &pVAddr)) + { + *pVirtualBase = pVAddr; + *pLen = dwLen; + + return (PBYTE)pVAddr + dwOffset; + } + else + { + return NULL; + } +} + +bool InitEntryPoints() +{ + Win32GetVersionEx = decltype(Win32GetVersionEx)(GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), GetVersionExProc)); + if (!Win32GetVersionEx) + return false; + + Win32GetSystemInfo = decltype(Win32GetSystemInfo)(GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), "GetSystemInfo")); + if (!Win32GetSystemInfo) + return false; + + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if (!Win32GetVersionEx(&osvi)) + return false; + + bIsWindowsXPLater = ((osvi.dwMajorVersion > 5) || ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion > 1))); + + SYSTEM_INFO sysinfo; + ::ZeroMemory(&sysinfo, sizeof (SYSTEM_INFO)); + Win32GetSystemInfo(&sysinfo); + + dwPageSize = sysinfo.dwPageSize; + + if (bIsWindowsXPLater) + { + Win32GetSystemFirmwareTable = decltype(Win32GetSystemFirmwareTable)(GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetSystemFirmwareTable")); + if (!Win32GetSystemFirmwareTable) + return false; + } + else + { + Win32VirtualProtect = decltype(Win32VirtualProtect)(GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "VirtualProtect")); + if (!Win32VirtualProtect) + return false; + + RtlInitUnicodeString = (decltype(RtlInitUnicodeString))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlInitUnicodeString")); + if (!RtlInitUnicodeString) + return false; + + NtUnmapViewOfSection = (decltype(NtUnmapViewOfSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtUnmapViewOfSection")); + if (!NtUnmapViewOfSection) + return false; + + NtOpenSection = (decltype(NtOpenSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtOpenSection")); + if (!NtOpenSection) + return false; + + NtMapViewOfSection = (decltype(NtMapViewOfSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtMapViewOfSection")); + if (!NtMapViewOfSection) + return false; + + RtlNtStatusToDosError = (decltype(RtlNtStatusToDosError))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlNtStatusToDosError")); + if (!NtMapViewOfSection) + return false; + } + + return true; +} + +void *LocateSMBIOS(uint32_t *smbios_size) +{ + void *buf = NULL; + if (bIsWindowsXPLater) + { + uint32_t size = 0; + size = Win32GetSystemFirmwareTable('RSMB', 0, buf, size); + if (0 == size) + { + return NULL; + } + + buf = malloc(size); + if (buf) + { + if (0 == Win32GetSystemFirmwareTable('RSMB', 0, buf, size)) + { + free(buf); + buf = NULL; + } + else + { + *smbios_size = size; + } + } + } + else + { + HANDLE hPhysMem = OpenPhysicalMemory(); + if (NULL == hPhysMem) + return NULL; + + DWORD dwReadLen = 0x10000; + DWORD dwActualLen = dwReadLen; + PVOID pBaseVAddr = NULL; + PVOID pVAddr = MapPhysicalMemoryWithBase(hPhysMem, (PVOID)0xF0000, &dwActualLen, &pBaseVAddr); + if (!pVAddr) + { + ::CloseHandle(hPhysMem); + return NULL; + } + + DWORD dwReadOffset = 0; + + PBYTE pbVAddr = (PBYTE)pVAddr; + PBYTE pbGuardVAddr = pbVAddr + dwReadLen; + + while (pbVAddr < pbGuardVAddr) + { + if (pbVAddr[0] == '_' && pbVAddr[1] == 'S' && pbVAddr[2] == 'M' && pbVAddr[3] == '_') + { + break; + } + + pbVAddr += 16; + } + + //! no SMBIOS found + if (pbVAddr >= pbGuardVAddr) + { + UnmapPhysicalMemory(pVAddr); + ::CloseHandle(hPhysMem); + + return NULL; + } + + PSMBIOSEntryPoint pEntryPoint = (PSMBIOSEntryPoint)pbVAddr; + + RawSMBIOSData *pData = (RawSMBIOSData *)::malloc(pEntryPoint->TableLength + sizeof(RawSMBIOSData)); + PVOID pTableBaseVAddr = NULL; + if (NULL != pData) + { + DWORD dwTableLen = pEntryPoint->TableLength; + PVOID pTableVAddr = MapPhysicalMemoryWithBase(hPhysMem, (PVOID)pEntryPoint->TableAddress, &dwTableLen, &pTableBaseVAddr); + if (!pTableVAddr) + { + UnmapPhysicalMemory(pBaseVAddr); + ::CloseHandle(hPhysMem); + return NULL; + } + + pData->Used20CallingMethod = 0; + pData->DmiRevision = 0; + pData->SMBIOSMajorVersion = pEntryPoint->MajorVersion; + pData->SMBIOSMinorVersion = pEntryPoint->MinorVersion; + pData->Length = pEntryPoint->TableLength; + + ::memcpy(pData->SMBIOSTableData, (PVOID)pTableVAddr, pEntryPoint->TableLength); + *smbios_size = pEntryPoint->TableLength; + } + + if (NULL != pTableBaseVAddr) + UnmapPhysicalMemory(pTableBaseVAddr); + if (NULL != pBaseVAddr) + UnmapPhysicalMemory(pBaseVAddr); + + ::CloseHandle(hPhysMem); + + buf = pData; + } + + return buf; +} diff --git a/src/library/os/windows/isvm/Native.h b/src/library/os/windows/isvm/Native.h new file mode 100644 index 0000000..5124c8d --- /dev/null +++ b/src/library/os/windows/isvm/Native.h @@ -0,0 +1,18 @@ +#pragma once + +#include <stdint.h> +#include <Windows.h> + +struct RawSMBIOSData +{ + BYTE Used20CallingMethod; + BYTE SMBIOSMajorVersion; + BYTE SMBIOSMinorVersion; + BYTE DmiRevision; + DWORD Length; + BYTE SMBIOSTableData[]; +}; + +bool InitEntryPoints(); +void *LocateSMBIOS(uint32_t *smbios_size); + diff --git a/src/library/os/windows/isvm/main.cpp b/src/library/os/windows/isvm/main.cpp new file mode 100644 index 0000000..105c105 --- /dev/null +++ b/src/library/os/windows/isvm/main.cpp @@ -0,0 +1,51 @@ +#include "intrin.h" + +#include <iostream> +#include "BIOSReader.h" +#include "Native.h" + +int _tmain(int argc, _TCHAR* argv[]) +{ + int cpui[4] = { 0 }; + __cpuid(cpui, 0x1); + + if ((cpui[2] >> 31) & 1) + { + std::cout << "Inside virual machine!"; + return 1; + } + + if (InitEntryPoints()) + { + BIOSReader reader; + SystemInformation info = reader.readSystemInfo(); + + const char *vmVendors[] = + { + "VMware", "Microsoft Corporation", "Virtual Machine", "innotek GmbH", "PowerVM", "Bochs", "KVM" + }; + + const int count = _countof(vmVendors); + for (int i = 0; i != count; ++i) + { + const char *vendor = vmVendors[i]; + + if (std::string::npos != info.Manufacturer.find(vendor) || + std::string::npos != info.ProductName.find(vendor) || + std::string::npos != info.SerialNum.find(vendor)) + { + std::cout << "Inside virual machine!"; + return 1; + } + } + } + else + { + return -1; + } + + std::cout << "Inside host machine!"; + + return 0; +} + diff --git a/src/library/os/windows/network.cpp b/src/library/os/windows/network.cpp new file mode 100644 index 0000000..fd111aa --- /dev/null +++ b/src/library/os/windows/network.cpp @@ -0,0 +1,113 @@ +/** + * @file network_id.c + * @date 16 Sep 2014 + * @brief File containing network interface detection functions for Windows. + * + * The only public function of this module is #getAdapterInfos(OsAdapterInfo *, + * size_t *), other functions are either static or inline. + * + * Responsibility of this module is to fill OsAdapterInfo structures, in a predictable way (skip loopback/vpn interfaces) + */ + +#ifdef _MSC_VER +#include <Windows.h> +#endif +#include <iphlpapi.h> +#include <unordered_map> +#include <stdio.h> +#pragma comment(lib, "IPHLPAPI.lib") + +#include "../../base/StringUtils.h" +#include "../../base/logger.h" +#include "../network.hpp" + +namespace license { +namespace os { +using namespace std; + +static int translate(char ipStringIn[16], unsigned char ipv4[4]) { + size_t index = 0; + + char *str2 = ipStringIn; /* save the pointer */ + while (*str2) { + if (isdigit((unsigned char)*str2)) { + ipv4[index] *= 10; + ipv4[index] += *str2 - '0'; + } else { + index++; + } + str2++; + } + return 0; +} +/** + * + * @param adapterInfos + * @param adapter_info_size + * @return + */ +FUNCTION_RETURN getAdapterInfos(vector<OsAdapterInfo> &adapterInfos) { + unordered_map<string, OsAdapterInfo> adapterByName; + FUNCTION_RETURN f_return = FUNC_RET_OK; + DWORD dwStatus; + int adapter_info_size; + PIP_ADAPTER_INFO pAdapterInfo; + DWORD dwBufLen = sizeof(IP_ADAPTER_INFO); + + unsigned int i = 3; + do { + pAdapterInfo = (PIP_ADAPTER_INFO)malloc(dwBufLen); + dwStatus = GetAdaptersInfo( // Call GetAdapterInfo + pAdapterInfo, // [out] buffer to receive data + &dwBufLen // [in] size of receive data buffer + ); + if (dwStatus != NO_ERROR && pAdapterInfo != nullptr) { + free(pAdapterInfo); + pAdapterInfo = nullptr; + } + } while (dwStatus == ERROR_BUFFER_OVERFLOW && i-- > 0); + + if (dwStatus == ERROR_BUFFER_OVERFLOW) { + return FUNC_RET_ERROR; + } + + adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO); + if (adapter_info_size == 0) { + return FUNC_RET_NOT_AVAIL; + } + + PIP_ADAPTER_INFO pAdapter = pAdapterInfo; + i = 0; + FUNCTION_RETURN result = FUNC_RET_OK; + while (pAdapter) { + OsAdapterInfo ai = {}; + strncpy(ai.description, pAdapter->Description, + min(sizeof(ai.description), MAX_ADAPTER_DESCRIPTION_LENGTH)); + memcpy(ai.mac_address, pAdapter->Address, 8); + translate(pAdapter->IpAddressList.IpAddress.String, ai.ipv4_address); + ai.type = IFACE_TYPE_ETHERNET; + i++; + pAdapter = pAdapter->Next; + if (i == adapter_info_size) { + result = FUNC_RET_BUFFER_TOO_SMALL; + break; + } + adapterByName[string(ai.description)] = ai; + } + free(pAdapterInfo); + + // FIXME sort by eth , enps, wlan + if (adapterByName.size() == 0) { + f_return = FUNC_RET_NOT_AVAIL; + } else { + f_return = FUNC_RET_OK; + adapterInfos.reserve(adapterByName.size()); + for (auto &it : adapterByName) { + adapterInfos.push_back(it.second); + } + } + return f_return; +} + +} // namespace os +} // namespace license diff --git a/src/library/os/windows/os-win.c b/src/library/os/windows/os-win.c index aa6c5f3..ef56baf 100644 --- a/src/library/os/windows/os-win.c +++ b/src/library/os/windows/os-win.c @@ -1,17 +1,15 @@ -#ifdef _MSC_VER +/*#ifdef _MSC_VER #include <Windows.h> -#endif -#include "../base/logger.h" -#include "os.h" +#endif*/ +#include "../../base/logger.h" +#include "../os.h" + +#include <licensecc/datatypes.h> #include <iphlpapi.h> #include <stdio.h> #pragma comment(lib, "IPHLPAPI.lib") unsigned char* unbase64(const char* ascii, int len, int *flen); - -FUNCTION_RETURN getOsSpecificIdentifier(unsigned char identifier[6]) { - return FUNC_RET_NOT_AVAIL; -} FUNCTION_RETURN getMachineName(unsigned char identifier[6]) { FUNCTION_RETURN result = FUNC_RET_ERROR; @@ -34,15 +32,14 @@ #define MAX_UNITS 30 //bug check return with diskinfos == null func_ret_ok FUNCTION_RETURN getDiskInfos(DiskInfo * diskInfos, size_t * disk_info_size) { - DWORD FileMaxLen; + DWORD fileMaxLen; int ndrives = 0; - DWORD FileFlags; - char volName[_MAX_FNAME], FileSysName[_MAX_FNAME]; + DWORD fileFlags; + char volName[MAX_PATH], fileSysName[MAX_PATH]; DWORD volSerial = 0; const DWORD dwSize = MAX_PATH; - char szLogicalDrives[MAX_PATH] = { 0 }; - unsigned char buf[8] = ""; + FUNCTION_RETURN return_value = FUNC_RET_NOT_AVAIL; const DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives); @@ -56,22 +53,21 @@ UINT driveType = GetDriveType(szSingleDrive); if (driveType == DRIVE_FIXED) { BOOL success = GetVolumeInformation(szSingleDrive, volName, MAX_PATH, - &volSerial, &FileMaxLen, &FileFlags, FileSysName, + &volSerial, &fileMaxLen, &fileFlags, fileSysName, MAX_PATH); if (success) { LOG_INFO("drive : %s", szSingleDrive); LOG_INFO("Volume Name : %s", volName); LOG_INFO("Volume Serial : 0x%x", volSerial); - LOG_DEBUG("Max file length : %d", FileMaxLen); - LOG_DEBUG("Filesystem : %s", FileSysName); + LOG_DEBUG("Max file length : %d", fileMaxLen); + LOG_DEBUG("Filesystem : %s", fileSysName); if (diskInfos != NULL) { if (ndrives < (int)*disk_info_size) { diskInfos[ndrives].id = ndrives; - strncpy(diskInfos[ndrives].device, volName, MAX_PATH); - strncpy(diskInfos[ndrives].label, FileSysName, MAX_PATH); - memcpy(diskInfos[ndrives].disk_sn, &buf, sizeof(buf)); + strncpy(diskInfos[ndrives].device, volName, min(MAX_PATH,sizeof(volName))-1); + strncpy(diskInfos[ndrives].label, fileSysName,min(sizeof(diskInfos[ndrives].label), sizeof(fileSysName)) - 1); memcpy(diskInfos[ndrives].disk_sn, &volSerial, sizeof(DWORD)); - diskInfos[ndrives].preferred = (strncmp(szSingleDrive, "C", 1) != 0); + diskInfos[ndrives].preferred = (szSingleDrive[0] == 'C'); } else { return_value = FUNC_RET_BUFFER_TOO_SMALL; } @@ -100,79 +96,6 @@ return return_value; } -static int translate(char ipStringIn[16], unsigned char ipv4[4]) { - size_t index = 0; - - char* str2 = ipStringIn; /* save the pointer */ - while (*str2) { - if (isdigit((unsigned char) *str2)) { - ipv4[index] *= 10; - ipv4[index] += *str2 - '0'; - } else { - index++; - } - str2++; - } - return 0; -} - -//http://stackoverflow.com/questions/18046063/mac-address-using-c -//TODO: count only interfaces with type (MIB_IF_TYPE_ETHERNET IF_TYPE_IEEE80211) -FUNCTION_RETURN getAdapterInfos(OsAdapterInfo * adapterInfos, - size_t * adapter_info_size) { - DWORD dwStatus; - PIP_ADAPTER_INFO pAdapterInfo; - //IP_ADAPTER_INFO AdapterInfo[20]; // Allocate information for up to 16 NICs - DWORD dwBufLen = sizeof(IP_ADAPTER_INFO); //10 * sizeof(IP_ADAPTER_INFO); // Save the memory size of buffer - - unsigned int i = 3; - do { - pAdapterInfo = (PIP_ADAPTER_INFO) malloc(dwBufLen); - dwStatus = GetAdaptersInfo( // Call GetAdapterInfo - pAdapterInfo, // [out] buffer to receive data - &dwBufLen // [in] size of receive data buffer - ); - if (dwStatus != NO_ERROR) { - free(pAdapterInfo); - pAdapterInfo = NULL; - } - } while (dwStatus == ERROR_BUFFER_OVERFLOW && i-- > 0); - - if (dwStatus == ERROR_BUFFER_OVERFLOW) { - return FUNC_RET_ERROR; - } - - if (adapterInfos == NULL || *adapter_info_size == 0) { - *adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO); - if (pAdapterInfo != NULL){ - free(pAdapterInfo); - } - return FUNC_RET_OK; - } - - *adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO); - memset(adapterInfos, 0, dwBufLen); - PIP_ADAPTER_INFO pAdapter = pAdapterInfo; - i = 0; - FUNCTION_RETURN result = FUNC_RET_OK; - while (pAdapter) { - strncpy(adapterInfos[i].description, pAdapter->Description, - min(sizeof(adapterInfos->description), - MAX_ADAPTER_DESCRIPTION_LENGTH)); - memcpy(adapterInfos[i].mac_address, pAdapter->Address, 8); - translate(pAdapter->IpAddressList.IpAddress.String, - adapterInfos[i].ipv4_address); - adapterInfos[i].type = IFACE_TYPE_ETHERNET; - i++; - pAdapter = pAdapter->Next; - if (i == *adapter_info_size) { - result = FUNC_RET_BUFFER_TOO_SMALL; - break; - } - } - free(pAdapterInfo); - return result; -} FUNCTION_RETURN getModuleName(char buffer[MAX_PATH]) { FUNCTION_RETURN result = FUNC_RET_OK; @@ -183,29 +106,4 @@ return result; } -// TODO: remove unused -static void printHash(HCRYPTHASH* hHash) { - DWORD dwHashLen; - DWORD dwHashLenSize = sizeof(DWORD); - - if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *) &dwHashLen, - &dwHashLenSize, 0)) { - BYTE* pbHash = (BYTE*)malloc(dwHashLen); - char* hashStr = (char*)malloc(dwHashLen * 2 + 1); - if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { - for (unsigned int i = 0; i < dwHashLen; i++) { - sprintf(&hashStr[i * 2], "%02x", pbHash[i]); - } LOG_DEBUG("Hash to verify: %s", hashStr); - } - free(pbHash); - free(hashStr); - } -} - -/** - * Not implemented yet. - */ -VIRTUALIZATION getVirtualization() { - return NONE; -} diff --git a/src/library/os/windows/signature_verifier.cpp b/src/library/os/windows/signature_verifier.cpp index 6e9b62d..a47c7dd 100644 --- a/src/library/os/windows/signature_verifier.cpp +++ b/src/library/os/windows/signature_verifier.cpp @@ -136,12 +136,11 @@ DWORD status; FUNCTION_RETURN result = FUNC_RET_ERROR; PBYTE pbSignature = nullptr; - BYTE* sigBlob = nullptr; BCRYPT_ALG_HANDLE hSignAlg = nullptr; vector<uint8_t> signatureBlob = unbase64(signatureBuffer); DWORD dwSigLen = signatureBlob.size(); - sigBlob = &signatureBlob[0]; + BYTE* sigBlob = &signatureBlob[0]; if (NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0))) { if ((result = readPublicKey(hSignAlg, &phKey)) == FUNC_RET_OK) { @@ -174,9 +173,9 @@ if (hSignAlg != nullptr) { BCryptCloseAlgorithmProvider(hSignAlg, 0); } - if (sigBlob) { - free(sigBlob); - } + //if (sigBlob) { + // free(sigBlob); + //} return result; } diff --git a/test/functional/CMakeLists.txt b/test/functional/CMakeLists.txt index c081de9..6d2397b 100644 --- a/test/functional/CMakeLists.txt +++ b/test/functional/CMakeLists.txt @@ -46,11 +46,11 @@ ) -add_executable(test_it_pc_identifer hw_identifier_it_test.cpp) +add_executable(test_it_hw_identifier hw_identifier_it_test.cpp) -target_link_libraries(test_it_pc_identifer - licensecc_static +target_link_libraries(test_it_hw_identifier license_generator_snippet + licensecc_static Boost::unit_test_framework Boost::filesystem Boost::system @@ -59,8 +59,8 @@ add_executable(test_crack crack_test.cpp) target_link_libraries( test_crack - licensecc_static license_generator_snippet + licensecc_static Boost::unit_test_framework Boost::filesystem Boost::system @@ -68,7 +68,7 @@ ADD_TEST(NAME test_crack COMMAND test_crack WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -ADD_TEST(NAME test_it_pc_identifer COMMAND test_it_pc_identifer WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +ADD_TEST(NAME test_it_hw_identifier COMMAND test_it_hw_identifier 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}) diff --git a/test/functional/crack_test.cpp b/test/functional/crack_test.cpp index fcf6143..b427928 100644 --- a/test/functional/crack_test.cpp +++ b/test/functional/crack_test.cpp @@ -1,3 +1,4 @@ + #define BOOST_TEST_MODULE standard_license_test #include <boost/test/unit_test.hpp> @@ -9,7 +10,7 @@ #include <iostream> #include "../../src/library/ini/SimpleIni.h" #include "generate-license.h" -#include "../../src/library/base/FileUtils.hpp" +#include "../../src/library/base/file_utils.hpp" namespace license { namespace test { diff --git a/test/functional/date_test.cpp b/test/functional/date_test.cpp index 999331c..9638f1b 100644 --- a/test/functional/date_test.cpp +++ b/test/functional/date_test.cpp @@ -31,7 +31,7 @@ BOOST_CHECK_EQUAL(result, LICENSE_OK); BOOST_CHECK_EQUAL(license.has_expiry, true); BOOST_CHECK_EQUAL(license.linked_to_pc, false); - BOOST_CHECK_GT(license.days_left, 0); + BOOST_CHECK_GT(license.days_left, (unsigned int)0); } BOOST_AUTO_TEST_CASE(license_expired) { diff --git a/test/functional/standard-license_test.cpp b/test/functional/standard-license_test.cpp index 8bb45b1..4293d11 100644 --- a/test/functional/standard-license_test.cpp +++ b/test/functional/standard-license_test.cpp @@ -1,3 +1,4 @@ + #define BOOST_TEST_MODULE test_standard_license #include <boost/test/unit_test.hpp> @@ -9,7 +10,7 @@ #include "../../src/library/ini/SimpleIni.h" #include "generate-license.h" -#include "../../src/library/base/FileUtils.hpp" +#include "../../src/library/base/file_utils.hpp" using namespace std; namespace fs = boost::filesystem; diff --git a/test/library/Os_Linux_test.cpp b/test/library/Os_Linux_test.cpp index 21e94e0..5306bb0 100644 --- a/test/library/Os_Linux_test.cpp +++ b/test/library/Os_Linux_test.cpp @@ -10,13 +10,14 @@ #include "../../src/library/os/execution_environment.hpp" namespace license { -using namespace std; namespace test { +using namespace std; +using namespace os; BOOST_AUTO_TEST_CASE(read_disk_id) { - ExecutionEnvironment exec_env; - VIRTUALIZATION virt = exec_env.getVirtualization(); - if (virt == NONE || virt == VM) { + os::ExecutionEnvironment exec_env; + os::VIRTUALIZATION virt = exec_env.getVirtualization(); + if (virt == VIRTUALIZATION::NONE || virt == VIRTUALIZATION::VM) { DiskInfo *diskInfos = NULL; size_t disk_info_size = 0; FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size); @@ -29,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 == CONTAINER) { + } else if (virt == VIRTUALIZATION::CONTAINER) { // docker or lxc diskInfo is not meaningful DiskInfo *diskInfos = NULL; size_t disk_info_size = 0; @@ -42,16 +43,16 @@ // otherwise the test is skipped BOOST_AUTO_TEST_CASE(test_virtualization) { const char *env = getenv("VIRT_ENV"); - ExecutionEnvironment exec_env; + os::ExecutionEnvironment exec_env; if (env != NULL) { if (strcmp(env, "CONTAINER") == 0) { - VIRTUALIZATION virt = exec_env.getVirtualization(); - BOOST_CHECK_MESSAGE(virt == CONTAINER, "container detected"); + os::VIRTUALIZATION virt = exec_env.getVirtualization(); + BOOST_CHECK_MESSAGE(virt == VIRTUALIZATION::CONTAINER, "container detected"); } else if (strcmp(env, "VM") == 0) { BOOST_FAIL("check for vm not implemented"); } else if (strcmp(env, "NONE") == 0) { - VIRTUALIZATION virt = exec_env.getVirtualization(); - BOOST_CHECK_EQUAL(virt, NONE); + os::VIRTUALIZATION virt = exec_env.getVirtualization(); + BOOST_CHECK_EQUAL(virt, VIRTUALIZATION::NONE); } else { BOOST_FAIL(string("value ") + env + " not supported: VM,CONTAINER,NONE"); } -- Gitblit v1.9.1