Gabriele Contini
2019-12-14 e2c2e9dc1a9a7f7eafff371cdf29bb731015238c
Merge pull request #69 from open-license-manager/feature/issue_licenses_42

Feature/issue licenses 42
50个文件已修改
20个文件已添加
5 文件已重命名
28个文件已删除
5219 ■■■■■ 已修改文件
.clang-format 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitmodules 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.travis.yml 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CMakeLists.txt 238 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CONTRIBUTING.md 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build/.gitkeep 补丁 | 查看 | 原始文档 | blame | 历史
cmake/Findlcc.cmake 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cmake/target_arch.cmake 补丁 | 查看 | 原始文档 | blame | 历史
cmake/toolchain-ubuntu-mingw64.cmake 补丁 | 查看 | 原始文档 | blame | 历史
cmake/utilities.cmake 补丁 | 查看 | 原始文档 | blame | 历史
example/CMakeLists.txt 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
example/example.cpp 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
extern/.gitkeep 补丁 | 查看 | 原始文档 | blame | 历史
extern/license-generator @ c40c09 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/datatypes.h 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/licensecc/licensecc.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
projects/.gitkeep 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
scripts/windows_download_boost.bat 补丁 | 查看 | 原始文档 | blame | 历史
src/CMakeLists.txt 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/build_properties.h.in 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/cmake/licensecc-config.cmake 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/CMakeLists.txt 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/LicenseReader.cpp 224 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/LicenseReader.hpp 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/api/datatypes.h 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/CMakeLists.txt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/EventRegistry.cpp 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/EventRegistry.h 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/StringUtils.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/StringUtils.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/base.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/base64.c 267 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/logger.c 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/logger.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/ini/CMakeLists.txt 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/license++.cpp 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/licensecc.cpp 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/limits/license_verifier.cpp 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/limits/license_verifier.hpp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ApplicationFolder.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ApplicationFolder.hpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/CMakeLists.txt 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarData.cpp 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarData.hpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarLocation.cpp 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarLocation.hpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ExternalDefinition.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorFactory.cpp 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorFactory.hpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorStrategy.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorStrategy.hpp 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/CMakeLists.txt 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/openssl/signature_verifier.cpp 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os-linux.c 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os-win.c 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os.c 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/signature_verifier.h 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/signature_verifier.cpp 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/pc-identifiers.c 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/pc-identifiers.h 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/licensecc_properties.h.in 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/licensecc_properties_test.h.in 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/public_key.inja 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/CMakeLists.txt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/CMakeLists.txt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/CryptoHelper.cpp 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/CryptoHelper.h 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/README.TXT 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/linux/CryptoHelperLinux.cpp 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/linux/CryptoHelperLinux.h 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/win/CryptoHelperWindows.cpp 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/base_lib/win/CryptoHelperWindows.h 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/bootstrap/CMakeLists.txt 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/bootstrap/bootstrap.cpp 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/license-generator/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/license-generator/CMakeLists.txt 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/license-generator/license-generator-main.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/license-generator/license-generator.cpp 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/license-generator/license-generator.h 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tools/pc-identifier/CMakeLists.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/CMakeLists.txt 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/CMakeLists.txt 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/date_test.cpp 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/generate-license.cpp 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/generate-license.h 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/hijiaking_test.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/signature_verifier_test.cpp 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/standard-license_test.cpp 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/volid_test.cpp 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/CMakeLists.txt 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/EventRegistry_test.cpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/LicenseLocator_test.cpp 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/LicenseReader_test.cpp 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/Os_Linux_test.cpp 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/license_verifier_test.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/test_reader.ini 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/license-generator/CMakeLists.txt 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/license-generator/license-generator_test.cpp 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.clang-format
New file
@@ -0,0 +1,12 @@
BasedOnStyle: Google
Language: Cpp
Standard: Cpp11
IndentWidth: 4
TabWidth: 4
ColumnLimit: 120
UseTab: Always
AccessModifierOffset: -4
AlignTrailingComments: false
FixNamespaceComments: true
SortIncludes: false
SortUsingDeclarations : true
.gitignore
@@ -18,7 +18,8 @@
/Testing
# Cmake generated files
build
build/*
!build/.gitkeep
#eclipse files
.cproject
@@ -26,3 +27,7 @@
.project
*.out
/Default/
projects/*
!projects/.gitkeep
.gitmodules
New file
@@ -0,0 +1,4 @@
[submodule "license-generator"]
    path = extern/license-generator
    url = https://github.com/open-license-manager/lcc-license-generator.git
    branch = develop
.travis.yml
@@ -61,30 +61,57 @@
             - libboost-system-dev
             - libboost-thread-dev
             - libboost-date-time-dev
             - lcov
     before_script:
         - mkdir build
         - cd build && cmake -DCMAKE_INSTALL_PREFIX=../../install -DCMAKE_BUILD_TYPE=Debug ..
     script: 
         - cmake --build . --target install
         - ctest
         - ctest -T memcheck
     after_success:
         # Create lcov report
         - lcov --capture --directory . --output-file coverage.info
         - lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter system-files
         - lcov --list coverage.info # debug info
         # Uploading report to CodeCov
         - bash <(curl -s https://codecov.io/bash) -f coverage.info || echo "Codecov did not collect coverage reports"
   - os: linux
     dist: bionic
     name: "CentOS-7 Docker"
     before_script: 
        - docker run --name centos7_toconfigure -v `pwd`:/root/open-license-manager centos:centos7 /bin/bash -c 
            "yum -y update && yum -y install install centos-release-scl &&
              yum -y install cmake boost boost-devel boost-static openssl openssl-devel glibc-static devtoolset-7-toolchain devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-valgrind-devel &&
              cd /root/open-license-manager && mkdir build && cd build &&
              CC=/opt/rh/devtoolset-7/root/usr/bin/gcc CXX=/opt/rh/devtoolset-7/root/usr/bin/g++ cmake .."
              yum -y install wget boost boost-devel boost-static openssl openssl-devel openssl-static glibc-static devtoolset-7-toolchain devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-valgrind-devel &&
              wget https://cmake.org/files/v3.11/cmake-3.11.0.tar.gz && tar zxvf cmake-3.11.0.tar.gz && cd cmake-3.11.0 &&
              export CC=/opt/rh/devtoolset-7/root/usr/bin/gcc && export CXX=/opt/rh/devtoolset-7/root/usr/bin/g++ &&
              ./bootstrap && make && make install && cd /root/open-license-manager/build && cmake .."
        - docker commit centos7_toconfigure centos7_configured
     script: 
        - docker run --name centos7_make -v `pwd`:/root/open-license-manager centos7_configured /bin/bash -c 
            "cd /root/open-license-manager/build && make && make install && VIRT_ENV=CONTAINER make test"
#   - os: linux
#     dist: bionic
#     name: "CentOS-8 Docker"
#     before_script:
#        - docker run --name centos8_toconfigure -v `pwd`:/root/open-license-manager centos:centos8 /bin/bash -c \
#            "yum -y update && yum -y groupinstall 'Development Tools' &&
#             yum -y install wget cmake boost boost-devel openssl-devel zlib-devel &&
#             dnf -y --enablerepo=PowerTools install boost-static &&
#             wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1d.tar.gz &&
#             tar xzf OpenSSL_1_1_1d.tar.gz && cd openssl-OpenSSL_1_1_1d &&
#             ./config && make -j 8 && make install &&
#             cd /root/open-license-manager/build && cmake .."
#        - docker commit centos8_toconfigure centos8_configured
#     script:
#        - docker run --name centos8_make -v `pwd`:/root/open-license-manager centos8_configured /bin/bash -c \
#            "cd /root/open-license-manager/build && make && make install && VIRT_ENV=CONTAINER make test"
   - os: linux
     dist: bionic
     name: "Ubuntu 18.04 - MinGW cross-compile for Windows x64"
     env:
        - CTEST_OUTPUT_ON_FAILURE=1
        - WINEARCH=win64
     addons:
        apt:
          packages:
@@ -93,9 +120,12 @@
             - mingw-w64 
             - mingw-w64-tools 
             - mingw-w64-x86-64-dev 
             - wine64-development
             - wine64-development-preloader
             - wine-development
             - wine64
             - p7zip-full
     before_script:
        - mkdir build
        - cd build
        - 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
@@ -104,21 +134,21 @@
        - ./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 ..
        - cmake -DCMAKE_TOOLCHAIN_FILE=../modules/toolchain-ubuntu-mingw64.cmake -DCMAKE_INSTALL_PREFIX=../../install -DBOOST_ROOT=$PWD/boost_1_71_0/dist  ..
        - wget --no-check-certificate https://bintray.com/vszakats/generic/download_file?file_path=openssl-1.0.2h-win64-mingw.7z -O openssl.7z
        - 7z x openssl.7z
        - cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain-ubuntu-mingw64.cmake -DCMAKE_INSTALL_PREFIX=../../install -DBOOST_ROOT=$PWD/boost_1_71_0/dist -DOPENSSL_ROOT_DIR=$PWD/openssl-1.0.2h-win64-mingw/ ..
   - os: windows
     name: "Widnows server 1803 - Visual Studio 15 2017 Win64 - (/MD)"
     before_script:
         - travis_wait 40 ./windows_download_boost.bat
         - cd "${TRAVIS_BUILD_DIR}"
         - mkdir build
         - cd build && cmake -G "Visual Studio 15 2017 Win64" -DBOOST_ROOT="C:/local/boost" ..
         - travis_wait 40 ./scripts/windows_download_boost.bat
         - cd "${TRAVIS_BUILD_DIR}/build"
         - cmake -G "Visual Studio 15 2017 Win64" -DBOOST_ROOT="C:/local/boost" ..
   - os: windows
     name: "Widnows server 1803 - Visual Studio 15 2017 Win64 - (/MT)"
     before_script:
         - travis_wait 40 ./windows_download_boost.bat
         - travis_wait 40 ./scripts/windows_download_boost.bat
         - cd "${TRAVIS_BUILD_DIR}"
         - mkdir build
         - cd build && cmake -G "Visual Studio 15 2017 Win64" -DBOOST_ROOT="C:/local/boost" -DSTATIC_RUNTIME=1 ..
          
   - os: windows
@@ -146,17 +176,17 @@
               dir 
           fi
         - cd "${TRAVIS_BUILD_DIR}"
         - mkdir build
         - cd build && cmake -G "MinGW Makefiles" --trace-expand -DBOOST_ROOT="C:/local/boost" -DBoost_ARCHITECTURE="-x64" -DCMAKE_CXX_COMPILER_ARCHITECTURE_ID="x64" -DCMAKE_SH="CMAKE_SH-NOTFOUND" ..
         - cd build && cmake -G "MinGW Makefiles" -DBOOST_ROOT="C:/local/boost" -DBoost_ARCHITECTURE="-x64" -DCMAKE_CXX_COMPILER_ARCHITECTURE_ID="x64" -DCMAKE_SH="CMAKE_SH-NOTFOUND" ..
     script:
         - travis_wait 20 cmake --build . --target install --config Release
         - ctest -C Release
env:
    - CTEST_OUTPUT_ON_FAILURE=1      
before_script:
    - mkdir build
    - cd build && cmake -DCMAKE_INSTALL_PREFIX=../../install ..
script: 
    - cmake --build . --target install --config Release
    - ctest -C Release
CMakeLists.txt
@@ -1,61 +1,67 @@
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)
#version variables, major and minor must be 1 character only
SET(LICENSECC_MAJOR_VERSION 1)
SET(LICENSECC_MINOR_VERSION 1)
SET(LICENSECC_PATCH_VERSION 0 CACHE STRING "License++ patch version string")
SET(LICENSECC_INT_VERSION "${LICENSECC_MAJOR_VERSION}${LICENSECC_MINOR_VERSION}${LICENSECC_PATCH_VERSION}")
SET(LICENSECC_VERSION "${LICENSECC_MAJOR_VERSION}.${LICENSECC_MINOR_VERSION}.${LICENSECC_PATCH_VERSION}")
SET(LICENSECC_SHORT_LICENSE "BSD Software License")
SET(CMAKE_DISABLE_SOURCE_CHANGES ON)
SET(CMAKE_DISABLE_SOURCE_CHANGES OFF) #keys are generated in the source tree by default
SET(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
SET(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "CMake verbose")
project (license++ C CXX )
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/")
IF(NOT LCC_PROJECT_NAME)
    message(WARNING "You should define a variable LCC_PROJECT_NAME containing the name of the software you want to add a license to."
        "A mock product named DEFAULT has been added for you.")
    set(LCC_PROJECT_NAME "DEFAULT" CACHE STRING "Project name (name of the software for which you want to issue a license)")
ENDIF(NOT LCC_PROJECT_NAME)
include(utilities)
if(CMAKE_BUILD_TYPE)
    string(TOLOWER ${CMAKE_BUILD_TYPE} _CMAKE_BUILD_TYPE)
    EVAL_CONDITION(RELEASE_BUILD ${_CMAKE_BUILD_TYPE} STREQUAL "release")
else(CMAKE_BUILD_TYPE)
    SET(RELEASE_BUILD 0)
endif(CMAKE_BUILD_TYPE)
#base folder where projects are stored (/projects)
IF(NOT LCC_PROJECTS_BASE_DIR)
    set(LCC_PROJECTS_BASE_DIR "${CMAKE_SOURCE_DIR}/projects")
ENDIF(NOT LCC_PROJECTS_BASE_DIR)
if(MSVC)
    SET(PLATFORM_LIBS "")
    include(target_arch)
    target_architecture( TARGET_ARCHITECTURE )
    message(STATUS "architecture detected: ${TARGET_ARCHITECTURE}")
cmake_policy(SET CMP0048 NEW)
project (licensecc
            VERSION 2.0.0
            DESCRIPTION "Copy protection and licensing library"
            LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
#find lcc executable or build it.
find_package(lcc REQUIRED)
#In case the build system doesn't support binfmt misc
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" ) AND CMAKE_CROSSCOMPILING AND NOT DEFINED CMAKE_CROSSCOMPILING_EMULATOR )
    SET(CMAKE_CROSSCOMPILING_EMULATOR "wine")
ENDIF()
SET (OPENSSL_USE_STATIC_LIBS ON)
find_package(OpenSSL COMPONENTS Crypto QUIET)
IF(OPENSSL_FOUND)
    MESSAGE(STATUS "Found openssl version ${OPENSSL_VERSION}")
ENDIF(OPENSSL_FOUND)
if(UNIX) #this is true for all the linux systems but not for cross compiling "linux->windows"
    IF(NOT OPENSSL_FOUND)
        MESSAGE(SEND_ERROR "Openssl required in Linux, please install it or specify -DOPENSSL_ROOT")
    ENDIF(NOT OPENSSL_FOUND)
    
    #Boost > 3.15 handle the /MD flag more nicely than this
    if(${STATIC_RUNTIME})
        string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
        string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
        string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
        string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
        SET(Boost_USE_STATIC_RUNTIME ON)
    endif(${STATIC_RUNTIME})
    #SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib ) #${CMAKE_FIND_LIBRARY_SUFFIXES}
    add_definitions("/D _CRT_SECURE_NO_WARNINGS")
else(MSVC)
    #GCC or Mingw
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -fmessage-length=0 -std=c++11 -Wuninitialized -fPIC") #-Wall
    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -fmessage-length=0 -Wall -Wuninitialized -fPIC")
    SET(CMAKE_EXE_LINKER_FLAGS  "-pthread -static-libstdc++")
    SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "-Wl,--strip-all -static-libstdc++") #-static
    #you need to "force" the change in cmake_install_prefix after the project keyword
    IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
        SET(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Install path prefix" FORCE)
    ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    if(MINGW)
        list(APPEND EXTERNAL_LIBS "-lcrypt32 -lws2_32 -liphlpapi")
        SET(CMAKE_EXE_LINKER_FLAGS "-static")
    endif(MINGW)
    #Zlib required when openssl version < 1.0.1f (centos 7)
    SET ( ZLIB_USE_STATIC_LIBS ON )
    find_package(ZLIB REQUIRED)
    list(APPEND EXTERNAL_LIBS ${ZLIB_LIBRARIES})
    MESSAGE(STATUS "Found zlib version ${ZLIB_VERSION} ")
    find_package(Threads)
    if(THREADS_HAVE_PTHREAD_ARG)
          list(APPEND EXTERNAL_LIBS "-pthread")
    else(THREADS_HAVE_PTHREAD_ARG)
        if(CMAKE_THREAD_LIBS_INIT)
               list(APPEND EXTERNAL_LIBS "${CMAKE_THREAD_LIBS_INIT}")
        endif()
    endif(THREADS_HAVE_PTHREAD_ARG)
    find_program( MEMORYCHECK_COMMAND valgrind )
    set( MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" )
    
    if(USE_DBUS_IDENTIFIER)
        FIND_PACKAGE(Dbus REQUIRED)
@@ -63,58 +69,50 @@
        include_directories(${DBUS_INCLUDE_DIR})
        include_directories(${DBUS_ARCH_INCLUDE_DIR})
        list(APPEND EXTERNAL_LIBS ${DBUS_LIBRARIES})
    endif(USE_DBUS_IDENTIFIER)
endif(MSVC)
if(UNIX) #this is true for all the linux systems but not for cross compiling
    #find a static version of openssl crypto library
    SET ( OPENSSL_USE_STATIC_LIBS ON )
    find_package(OpenSSL REQUIRED COMPONENTS Crypto)
    include_directories(${OPENSSL_INCLUDE_DIR})
    list(APPEND EXTERNAL_LIBS ${OPENSSL_CRYPTO_LIBRARY})
    MESSAGE(STATUS "Found openssl version ${OPENSSL_VERSION} ")
    #Zlib required when openssl version < 1.0.1f
    SET ( ZLIB_USE_STATIC_LIBS ON )
    find_package(ZLIB REQUIRED)
    list(APPEND EXTERNAL_LIBS ${ZLIB_LIBRARIES})
    MESSAGE(STATUS "Found zlib version ${ZLIB_VERSION} ")
    if(NOT MINGW)
         list(APPEND EXTERNAL_LIBS "-ldl")
    endif(NOT MINGW)
    find_program( MEMORYCHECK_COMMAND valgrind )
    set( MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" )
    endif(USE_DBUS_IDENTIFIER)
    set(main_lib_dest "lib/${PROJECT_NAME}")
else(UNIX)
    IF(NOT OPENSSL_FOUND)
        MESSAGE(STATUS "Openssl not found, configuring the library without it (running in wine not supported).")
    ENDIF(NOT OPENSSL_FOUND)
    if(MSVC)
        include(target_arch)
        target_architecture( TARGET_ARCHITECTURE )
        message(STATUS "architecture detected: ${TARGET_ARCHITECTURE}")
        #cmake > 3.15 handle the /MD flag more nicely than this
        if(${STATIC_RUNTIME})
            string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
            string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
            string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
            string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
            SET(Boost_USE_STATIC_RUNTIME ON)
        endif(${STATIC_RUNTIME})
        add_definitions("/D _CRT_SECURE_NO_WARNINGS")
    else(MSVC)
        if(MINGW)
            list(APPEND EXTERNAL_LIBS "-lcrypt32 -lbcrypt -lws2_32 -liphlpapi")
            SET(CMAKE_EXE_LINKER_FLAGS "-static")
        endif(MINGW)
    endif(MSVC)
    set(main_lib_dest "${PROJECT_NAME}")
endif(UNIX)
SET_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG>)
#initialize project
#load the current project from files or find it from environment variables or create a default one
set(LCC_INCLUDE_DIR "${LCC_PROJECTS_BASE_DIR}/${LCC_PROJECT_NAME}/include/${PROJECT_NAME}/${LCC_PROJECT_NAME}" )
set(LCC_PROJECT_PUBLIC_KEY "${LCC_INCLUDE_DIR}/public_key.h" )
set(LCC_PROJECT_PRIVATE_KEY "${LCC_PROJECTS_BASE_DIR}/${LCC_PROJECT_NAME}/private_key.rsa" )
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  SET(HAVE_64BIT_SIZE_T 1)
else(CMAKE_SIZEOF_VOID_P EQUAL 8)
  SET(HAVE_64BIT_SIZE_T 0)
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
#bug in cmake win32 - can't find boost compiled with mingw
if(WIN32 AND "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x")
    message(WARNING "WIN32 compiler does not specify CMAKE_CXX_COMPILER_ARCHITECTURE_ID -- filling in manually")
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x64")
    else()
        set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x86")
    endif()
    message(STATUS "Compiler architecture: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
endif()
SET( Boost_USE_STATIC_LIBS ON )
find_package(Boost REQUIRED COMPONENTS date_time unit_test_framework program_options system filesystem)
#set below in case of dynamic linking in debug.
#set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:BOOST_TEST_DYN_LINK>)
add_definitions(-DBOOST_ALL_NO_LIB) #Disable Boost Microsoft magic, all dependencies are handled by cmake
add_definitions(-DBOOST_LIB_DIAGNOSTIC) #Check it is really disabled
configure_file (
    "src/build_properties.h.in"
    "${CMAKE_BINARY_DIR}/build_properties.h"
add_custom_command(
  OUTPUT "${LCC_PROJECT_PUBLIC_KEY}" "${LCC_PROJECT_PRIVATE_KEY}"
  COMMAND license_generator::lcc project initialize -t "${PROJECT_SOURCE_DIR}/src/templates" -n "${LCC_PROJECT_NAME}" -p "${LCC_PROJECTS_BASE_DIR}"
  COMMENT "generating ${LCC_PROJECT_PUBLIC_KEY}"
  USES_TERMINAL
)
add_custom_target(project_initialize DEPENDS "${LCC_PROJECT_PUBLIC_KEY}" "${LCC_PROJECT_PRIVATE_KEY}")
include_directories( ${LCC_INCLUDE_DIR} ${CMAKE_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/include")
message( STATUS "C compiler        : " ${CMAKE_C_COMPILER})
message( STATUS "C compiler flags  : " ${CMAKE_C_FLAGS})
@@ -126,18 +124,42 @@
  message( STATUS "Build type        : " ${CMAKE_BUILD_TYPE})
endif(CMAKE_BUILD_TYPE)
message( STATUS "Install prefix    : " ${CMAKE_INSTALL_PREFIX})
#include build directory to find build_properties.h
include_directories(${CMAKE_BINARY_DIR})
message( STATUS "Project name      : " ${LCC_PROJECT_NAME} )
message( STATUS "Project base dir  : " ${LCC_PROJECTS_BASE_DIR}/${LCC_PROJECT_NAME} )
add_subdirectory(src)
INCLUDE(CTest)
ENABLE_TESTING()
IF(BUILD_TESTING)
  SET(BUILDNAME "${BUILDNAME}" CACHE STRING "Name of build on the dashboard")
  MARK_AS_ADVANCED(BUILDNAME)
ENDIF(BUILD_TESTING)
add_subdirectory(test)
#boost is required only for tests
#bug in cmake win32 - can't find boost compiled with mingw
if(WIN32 AND "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x")
    message(WARNING "WIN32 compiler does not specify CMAKE_CXX_COMPILER_ARCHITECTURE_ID -- filling in manually")
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x64")
    else()
        set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x86")
    endif()
        message(STATUS "Compiler architecture: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
endif()
SET( Boost_USE_STATIC_LIBS ON )
find_package(Boost COMPONENTS unit_test_framework system filesystem)
#if boost is found enable tests
IF(Boost_FOUND)
    INCLUDE(CTest)
    IF(BUILD_TESTING)
        SET(BUILDNAME "${BUILDNAME}" CACHE STRING "Name of build on the dashboard")
        MARK_AS_ADVANCED(BUILDNAME)
        add_subdirectory(test)
    ENDIF(BUILD_TESTING)
ELSE(Boost_FOUND)
    message(WARNING "Boost not found, disabling tests")
ENDIF(Boost_FOUND)
install(DIRECTORY ${LCC_INCLUDE_DIR} DESTINATION include/${PROJECT_NAME})
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
install(FILES src/cmake/licensecc-config.cmake DESTINATION ${main_lib_dest})
include(CMakePackageConfigHelpers)
write_basic_package_version_file(${CMAKE_BINARY_DIR}/licensecc-config-version.cmake COMPATIBILITY SameMajorVersion)
install(FILES ${CMAKE_BINARY_DIR}/licensecc-config-version.cmake DESTINATION ${main_lib_dest})
CONTRIBUTING.md
@@ -4,7 +4,7 @@
The following is a set of guidelines for contributing to Open License Manager and its packages, which are hosted in the [Open License Manager organization](https://github.com/open-license-manager) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
## How Can I Contribute?
## How to Contribute
### Reporting Bugs
@@ -12,30 +12,30 @@
Before creating bug reports, please [check the repository](https://github.com/open-license-manager/open-license-manager/issues) to see if the problem has already been reported. If it has **and the issue is still open**, add a comment to the existing issue instead of opening a new one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). 
#### How Do I Submit A (Good) Bug Report?
#### How to Submit A (Good) Bug Report
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Explain the problem and include additional details to help maintainers reproduce the problem:
* **Use a clear and descriptive title** for the issue to identify the problem.
* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how are you using Open License Manager.
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or licenses, which can cause the bug. If you're providing code snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
* **Provide a boost unit test to demonstrate the bug**. The best way to report a bug, and to have it fixed **forever** is to design a test to demonstrate it.
* **If you're reporting that Open License Manager crashed**, include a crash dump and the associated message.
* **Label the issue as bug.**
*  **Use a clear and descriptive title** for the issue to identify the problem.
*  **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how are you using Open License Manager.
*  **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or licenses, which can cause the bug. If you're providing code snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
*  **Provide a unit test to demonstrate the bug**. The best way to report a bug, and to have it fixed **forever** is to design a test to demonstrate it.
*  **If you're reporting that Open License Manager crashed**, include a crash dump and the associated message.
*  **Label the issue as bug.**
Provide more context by answering these questions:
* **Can you reproduce the problem using the example application?**
* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
* If the problem is related integrating Open License Manager with your application, **produce a minimal example to demonstrate it** Does the problem happen only with some license type? Does the problem only happen in Linux/Docker/Windows?
*  **Can you reproduce the problem using the example application?**
*  **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
*  If the problem is related integrating Open License Manager with your application, **produce a minimal example to demonstrate it** Does the problem happen only with some license type? Does the problem only happen in Linux/Docker/Windows?
Include details about your configuration and environment:
* **Update Open License Manager to the latest version** If possible try to pull the latest changes from `develop` branch.
* **What's the name and version of the OS you're using**?
* **What's the name and version of the compiler you're using**? Are you cross compiling?
* **What's are the `cmake` command line you used to generate your build scripts **?
* **Are you running Open License Manager in a virtual machine/docker?** If so, which VM software are you using and which operating systems and versions are used for the guest?
*  **Update Open License Manager to the latest version** If possible try to pull the latest changes from `develop` branch.
*  **What's the name and version of the OS you're using**?
*  **What's the name and version of the compiler you're using**? Are you cross compiling? If you're cross compiling specify the host and the target operating system.
*  **What's are the `cmake` command line you used to generate your build scripts**?
*  **Are you running Open License Manager in a virtual machine/docker?** If so, which VM software are you using and which operating systems and versions are used for the guest?
### Suggesting Enhancements
@@ -45,20 +45,20 @@
Please also check for the [current and planned features](https://github.com/open-license-manager/open-license-manager/wiki/features) in the wiki to see where the project is heading to.
#### How Do I Submit A (Good) Enhancement Suggestion?
#### How to submit a (Good) enhancement suggestion
Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). 
* **Use a clear and descriptive title** for the issue to identify the suggestion.
* **Provide a detailed description of the suggested enhancement** in as many details as possible.
* **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets of code which we could use, or reference to other libraries, algorithms, open source code.
* **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
* **Explain why this enhancement would be useful** to most Open License Manager users and isn't something that can or should be implemented.
* **List some other software protection where this enhancement exists.**
* **Specify the name and version of the OS you're proposing the enhancement for.** If applicable include all the environment informations: is this for running the application in a VM? in a Docker?
* **Label the issue as enhancement.**
*  **Use a clear and descriptive title** for the issue to identify the suggestion.
*  **Provide a detailed description of the suggested enhancement** in as many details as possible.
*  **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets of code which we could use, or reference to other libraries, algorithms, open source code.
*  **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
*  **Explain why this enhancement would be useful** to most Open License Manager users and isn't something that can or should be implemented.
*  **List some other software protection where this enhancement exists.**
*  **Specify the name and version of the OS you're proposing the enhancement for.** If applicable include all the environment informations: is this for running the application in a VM? in a Docker?
*  **Label the issue as enhancement.**
### Your First Code Contribution
### Your first code contribution
Unsure where to begin contributing to Open License Manager? You can start by looking through the [`good first issue`](https://github.com/open-license-manager/open-license-manager/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and [`help-wanted`](https://github.com/open-license-manager/open-license-manager/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) issues. 
@@ -72,16 +72,16 @@
Supposing you already know how to contribute to an open source project on GitHub (if you have doubts you can check this short [guide](https://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project) ), you're working on an existing issue the code is already committed on your fork. 
 * Ensure your feature branch is up to date with the `develop`, eventually merge the latest changes from the `develop` branch. This will help us save time.
 * ~~ Reformat the changed code using "clang-format" to keep consistent formatting style ~~ (not yet).
 * Prepare your pull request, in the pull request comment reference the issue the pull request will fix.
 * Check your pull request compiles and pass the checks on Travis CI
 * In the pull request comment reference the issue you want to fix.
*  Ensure your feature branch is up to date with the `develop`, eventually merge the latest changes from the `develop` branch. This will help us save time.
*  Reformat the changed code using "clang-format" to keep consistent formatting style. The style we use is in `.clang-format` at the base of the project.
*  Prepare your pull request, in the pull request comment reference the issue the pull request will fix.
*  Check your pull request compiles and pass the checks on Travis CI
*  In the pull request comment reference the issue you want to fix.
##### Don't
 * Don't reformat the code following your personal likes, it introduce a lot of "noise" and makes very hard to merge.
 * Very large pull requests with few comments, no corresponding issue explaining what's it about will probably be rejected.
    * We understand that the project is still in a very alpha stage and a rearrangement is needed, however we would like to discuss it with you before we take project changing decision. Please contact the project maintainer at `contini.mailing[AT]gmail.com` if you have time and plan to do a large contribution.
    * Even it it's in alpha stage it's used ( _by some really courageous people!_ ) in production. We can't break current functionality, user established habits without documenting the change.
*  Don't reformat the code following your personal likes, it introduce a lot of "noise" and makes very hard to merge. Use the clang-format style provided at the base of the project.
*  Very large pull requests with few comments, no corresponding issue explaining what's it about will probably be rejected.
    *  We understand that the project is still in beta stage, however we would like to discuss it with you before we take project changing decision. Please contact the project maintainer at `contini.mailing[AT]gmail.com` if you have time and plan to do a large contribution.
    *  Even it it's in beta stage it's used ( _by some really courageous people!_ ) in production. We can't break current functionality, user established habits without documenting the change.
  
README.md
@@ -1,63 +1,67 @@
# Open License Manager
[![Build Status](https://travis-ci.org/open-license-manager/open-license-manager.svg?branch=develop)](https://travis-ci.org/open-license-manager/open-license-manager)
[![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
A copy protection, licensing software written in C++ for Windows and Linux (with a simple C api for use in C projects).
[![Standard](https://img.shields.io/badge/c%2B%2B-11-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Build Status](https://travis-ci.org/open-license-manager/open-license-manager.svg?branch=develop)](https://travis-ci.org/open-license-manager/open-license-manager)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/62d6e1bb22d648bd85b6f3bc344a545a)](https://www.codacy.com/manual/gcontini/open-license-manager?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=open-license-manager/open-license-manager&amp;utm_campaign=Badge_Grade)
[![Github Issues](https://img.shields.io/github/issues/open-license-manager/open-license-manager)](http://github.com/open-license-manager/open-license-manager/issues)
It allows to protect the software you develop from unauthorized copies,
limit the usage in time, to a specific set of machines, or prevent the usage in 
virtualized environments. It is an Open License Manager that helps to keep your 
software closed :smirk: . A comprehensive [list of features](https://github.com/open-license-manager/open-license-manager/wiki/features), and their status is available in the project wiki.
## License
##License
The project is donated to the community. It comes with a very large freedom of use for everyone, and it will always be. 
It uses a [BSD 3 clauses](https://opensource.org/licenses/BSD-3-Clause) licensing schema, that allows free modification and inclusion in commercial software. 
## Project Structure
The software is made by 2 main sub-components:
 * a C library with no (or minimal) external dependencies (the part you have to integrate in your software).
 * a license generator written in C++ (allows you to generate a license).
*  a C++ library with a nice C api, `licensecc` with minimal (or no) external dependencies (the part you have to integrate in your software) that is the project you're currently in.
*  a license generator lcc-license-generator `lcc` for customizing the library and generate the licenses.
 
these modules are planned....
 * a license [backoffice](../../issues/7) in php (in order to handle multiple licenses).
 * a license debugger to be sent to the final customer when there are licensing problems.
 * a [log descriptor](../../issues/8) in order to decrypt logs generated by the license system.
You can notice 2 more sub-projects:
 * bootstrap: allows to generate private keys and modify the library on the fly after the downloading.
 * testing  : runs the tests (and publish the results on cdash)
The following modules are planned...
*  a license [backoffice](../../issues/7) in php (in order to handle multiple licenses).
*  a license debugger to be sent to the final customer when there are licensing problems.
*  a [log descriptor](../../issues/8) in order to decrypt logs generated by the license system.
# How to build
Below an overview of the basic build procedure, you can find detailed instructions for [linux](https://github.com/open-license-manager/open-license-manager/wiki/Build-the-library) or [windows](https://github.com/open-license-manager/open-license-manager/wiki/Build-the-library-win) in the wiki.
Below an overview of the basic build procedure, you can find detailed instructions for each [supported environment](https://github.com/open-license-manager/open-license-manager/wiki/Build-the-library) in the wiki.
## Prerequisites
*  Operating system: Linux(Ubuntu, CentOS), Windows
*  compilers       : GCC (Linux) MINGW (Linux cross compile for Windows), MINGW or MSVC (Windows)
*  tools           : cmake(>3.6), git, make/ninja(linux)
*  libs            : If target is Linux Openssl is required. Windows depends only on system libraries. Boost is necessary to build license generator and to run the tests but it's NOT a dependency of the final `licensecc` library.
## prerequisites
 * compilsers: GCC (Linux) MINGW (Linux cross compile for Windows), MINGW or MSVC (Windows)
 * tools/libs: cmake, boost. If target is linux openssl is necessary.
For a complete list of dependencies and supported environments see [the wiki](https://github.com/open-license-manager/open-license-manager/wiki/Dependencies)
```
git clone https://github.com/open-license-manager/open-license-manager.git
Clone the project. It has submodules, don't forget the `--recursive` option.
```console
git clone --recursive https://github.com/open-license-manager/open-license-manager.git
cd open-license-manager/
mkdir build
cd build
```
## on Linux
```
```console
cmake .. -DCMAKE_INSTALL_PREFIX=../install
make
make install
```
## on Windows (with MSVC 2015)
```
```console
cmake .. -G "Visual Studio 14 2015 Win64" -DBOOST_ROOT="{Folder where boost is}" -DCMAKE_INSTALL_PREFIX=../install
cmake --build . --target install --config Release
```
## cross compile with MINGW on Linux
```
```console
x86_64-w64-mingw32.static-cmake .. -DCMAKE_INSTALL_PREFIX=../install
make
make install
@@ -67,34 +71,21 @@
===========
## on Linux
```
```console
make test
```
## on Windows (MSVC)
```
```console
ctest -C Release
```
How to use
==========
This simple example shows how to integrate open-licence-manager into your project
The [examples](https://github.com/open-license-manager/examples) repository that shows various ways to integrate `open-licence-manager` into your project.
```
$ cd example
$ cmake .
$ make
$ ./example
license ERROR :
    license file not found
the pc signature is :
    Jaaa-aaaa-MG9F-ZhBB
$ ../install/bin/license_generator example -s Jaaa-aaaa-MG9F-ZhBB -o example.lic
$ ./example
licence OK
```
# How to contribute
The project is not dead but we take our time to answer. The best interaction you can have with us is through the issue system. Have a look to the [contribution guidelines](blob/develop/CONTRIBUTING.md)
The project is not dead but we take our time to answer. The best interaction you can have with us is through the issue system. Have a look to the [contribution guidelines](CONTRIBUTING.md)
We use [GitFlow](https://datasift.github.io/gitflow/IntroducingGitFlow.html) (or at least a subset of it). Remember to install the gitflow git plugin and use `develop` as default branch for your pull requests. 
build/.gitkeep
cmake/Findlcc.cmake
New file
@@ -0,0 +1,85 @@
# Distributed under the OSI-approved BSD 3-Clause License.
#[=======================================================================[.rst:
#Findlcc
#-------
#
#Find or build the lcc executable.
#
#Imported Targets
#^^^^^^^^^^^^^^^^
#
#This module provides the following imported targets, if found:
#
#``license_generator::lcc``
#  The lcc executable
#
#If lcc is not found this module will try to download it as a submodule
#Git must be installed.
#
#Input variables
#^^^^^^^^^^^^^^^^
#
#``LCC_LOCATION`` Hint for locating the lcc executable
#
#Result Variables
#^^^^^^^^^^^^^^^^
#
#This will define the following variables:
#
#``LCC_FOUND``
#  True if the system has the Foo library.
#``lcc_VERSION``
#
#Cache Variables
#^^^^^^^^^^^^^^^
#
#The following cache variables will also be set:
#
#``LCC_EXECUTABLE``
#  Path to the lcc executable.
#
#]=======================================================================]
set(lcc_names lcc lcc.exe)
set (failure_messge "Error finding lcc executable.")
find_package(PkgConfig)
if(LCC_LOCATION)
    find_package(lcc HINTS ${LCC_LOCATION} CONFIG) #try to find it without looping on this module
    if(NOT lcc_FOUND)
        find_program(LCC_EXECUTABLE
        NAMES ${lcc_names} HINTS ${LCC_LOCATION} DOC "lcc command line client")
        FIND_PACKAGE_HANDLE_STANDARD_ARGS(lcc FOUND_VAR LCC_FOUND
                                           REQUIRED_VARS LCC_EXECUTABLE
                                           FAIL_MESSAGE "Error finding lcc executable. variable LCC_LOCATION non set correctly.")
        add_executable(license_generator::lcc IMPORTED GLOBAL)
        set_property(TARGET license_generator::lcc PROPERTY IMPORTED_LOCATION ${LCC_EXECUTABLE})
    ENDIF(NOT lcc_FOUND)
ELSE(LCC_LOCATION)
    find_package(lcc HINTS ${CMAKE_BINARY_DIR} CONFIG) #try to find it without looping on this module
    IF(NOT lcc_FOUND)
        find_package(Git QUIET)
        if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
        # Update submodules as needed
            option(GIT_SUBMODULE "Check submodules during build" ON)
            if(GIT_SUBMODULE)
                message(STATUS "Submodule update")
                execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
                                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
                                RESULT_VARIABLE GIT_SUBMOD_RESULT)
                if(NOT GIT_SUBMOD_RESULT EQUAL "0")
                    set(failure_messge  "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
                endif()
            endif()
        endif()
        if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/license-generator/CMakeLists.txt")
            set(failure_messge  "All the options to find lcc executable failed. And i can't compile one from source GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
        endif()
        add_subdirectory("${PROJECT_SOURCE_DIR}/extern/license-generator")
        set(lcc_FOUND TRUE)
    ENDIF(NOT lcc_FOUND)
ENDIF(LCC_LOCATION)
cmake/target_arch.cmake
cmake/toolchain-ubuntu-mingw64.cmake
cmake/utilities.cmake
example/CMakeLists.txt
File was deleted
example/example.cpp
File was deleted
extern/.gitkeep
extern/license-generator
New file
@@ -0,0 +1 @@
Subproject commit c40c0951e77c012a1c4043182c88ae5fe185efea
include/licensecc/datatypes.h
New file
@@ -0,0 +1,133 @@
#ifndef DATATYPES_H_
#define DATATYPES_H_
#ifdef __cplusplus
extern "C" {
#endif
// definition of size_t
#include <stdlib.h>
#include <stdint.h>
#ifndef _MSC_VER
#include <stdbool.h>
#endif
#ifdef __unix__
#define DllExport
#ifndef MAX_PATH
#define MAX_PATH 1024
#endif
#else
#include <windows.h>
#define DllExport __declspec(dllexport)
#endif
// define api structure sizes
#define PC_IDENTIFIER_SIZE 19
#define PROPRIETARY_DATA_SIZE 16
#define AUDIT_EVENT_NUM 5
typedef enum {
    LICENSE_OK = 0,  // OK
    LICENSE_FILE_NOT_FOUND = 1,  // license file not found
    LICENSE_SERVER_NOT_FOUND = 2,  // license server can't be contacted
    ENVIRONMENT_VARIABLE_NOT_DEFINED = 3,  // environment variable not defined
    FILE_FORMAT_NOT_RECOGNIZED = 4,  // license file has invalid format (not .ini file)
    LICENSE_MALFORMED = 5,  // some mandatory field are missing, or data can't be fully read.
    PRODUCT_NOT_LICENSED = 6,  // this product was not licensed
    PRODUCT_EXPIRED = 7,
    LICENSE_CORRUPTED = 8,  // License signature didn't match with current license
    IDENTIFIERS_MISMATCH = 9,  // Calculated identifier and the one provided in license didn't match
    LICENSE_SPECIFIED = 100,  // license location was specified
    LICENSE_FOUND = 101,  // License file has been found or license data has been located
    PRODUCT_FOUND = 102,  // License has been loaded and the declared product has been found
    SIGNATURE_VERIFIED = 103
} EVENT_TYPE;
typedef enum {
    LOCAL,
    REMOTE  // remote licenses are not supported now.
} LICENSE_TYPE;
typedef enum { SVRT_INFO, SVRT_WARN, SVRT_ERROR } SEVERITY;
typedef struct {
    SEVERITY severity;
    EVENT_TYPE event_type;
    /**
     * License file name or location where the license is stored.
     */
    char license_reference[MAX_PATH];
    char param2[256];
} AuditEvent;
/**
 * This structure contains informations on the raw license data. Software authors
 * can specify the location of the license file or its full content.
 *
 * Can be NULL, in this case OpenLicenseManager will try to figure out the
 * license file location on its own.
 */
typedef struct {
    /**
     * A list of absolute path separated by ';' containing the eventual location
     * of the license files. Can be NULL.
     */
    const char *licenseFileLocation;
    /**
     * The application can provide the full license content through this string.
     * It can be both in encoded form (base64) or in plain. It's optional.
     */
    const char *licenseData;
} LicenseLocation;
/**
 * Informations on the software requiring the license
 */
typedef struct {
    char version[16];  // software version in format xxxx.xxxx.xxxx
    char project_name[16];  // name of the project (must correspond to the name in the license)
    uint32_t magic;  // reserved
} CallerInformations;
typedef struct {
    /**
     * Detailed reason of success/failure. Reasons for a failure can be
     * multiple (for instance, license expired and signature not verified).
     * Only the last AUDIT_EVENT_NUM are reported.
     */
    AuditEvent status[AUDIT_EVENT_NUM];
    /**
     * Eventual expiration date of the software,
     * can be '\0' if the software don't expire
     * */
    char expiry_date[11];
    unsigned int days_left;
    bool has_expiry;
    bool linked_to_pc;
    LICENSE_TYPE license_type;  // Local or Remote
    /* A string of character inserted into the license understood
     * by the calling application.
     * '\0' if the application didn't specify one */
    char proprietary_data[PROPRIETARY_DATA_SIZE + 1];
    int license_version;  // license file version
} LicenseInfo;
/**
 * Enum to select a specific pc identification_strategy. DEFAULT Should be used
 * in most cases.
 */
typedef enum {
    STRATEGY_DEFAULT,
    STRATEGY_ETHERNET,
    STRATEGY_IP_ADDRESS,
    STRATEGY_DISK_NUM,
    STRATEGY_DISK_LABEL,
    STRATEGY_PLATFORM_SPECIFIC,
    STRATEGY_UNKNOWN
} IDENTIFICATION_STRATEGY;
#ifdef __cplusplus
}
#endif
#endif
include/licensecc/licensecc.h
File was renamed from src/library/api/license++.h
@@ -20,15 +20,11 @@
 * This method calculate the pc identifier. The string has to be shown
 * to the user in order to calculate the license.
 */
void identify_pc(IDENTIFICATION_STRATEGY pc_id_method,
        char chbuffer[PC_IDENTIFIER_SIZE + 1]);
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* identifier_out, size_t bufSize);
/**
 * This method is used to request the use of one license for a product.
 * In case of local license it's used to check if the product is licensed.
 * [In case of network licenses this will decrease the count of the available
 *  licenses]
 *
 * @return LICENSE_OK(0) if successful. Other values if there are errors.
 * @param productName[in]
@@ -39,8 +35,8 @@
 * @param license[out] optional, can be NULL, if set it will return extra informations about the license.
 */
EVENT_TYPE acquire_license(const char * productName,
        const LicenseLocation* licenseLocation, LicenseInfo* license);
EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
                           LicenseInfo* license_out);
/**
 * Do nothing for now, useful for network licenses.
projects/.gitkeep
New file
@@ -0,0 +1 @@
t
scripts/windows_download_boost.bat
src/CMakeLists.txt
@@ -1,4 +1,7 @@
add_subdirectory("library")
add_subdirectory("tools")
#for no reason overwrite it (maybe it's manually customized)
IF(NOT EXISTS "${LCC_INCLUDE_DIR}/licensecc_properties.h")
    configure_file ("templates/licensecc_properties.h.in"
        "${LCC_INCLUDE_DIR}/licensecc_properties.h")
ENDIF(NOT EXISTS "${LCC_INCLUDE_DIR}/licensecc_properties.h")
src/build_properties.h.in
File was deleted
src/cmake/licensecc-config.cmake
New file
@@ -0,0 +1,38 @@
# licensecc-config.cmake - package configuration file
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(licensecc_FIND_COMPONENTS)
    foreach(component ${licensecc_FIND_COMPONENTS})
        set(cmakefile "${SELF_DIR}/${component}/cmake/licensecc.cmake")
        if(EXISTS "${cmakefile}")
            include("${cmakefile}")
            set(${component}_FOUND true CACHE BOOL "Licensecc ${component} present")
        else(EXISTS "${cmakefile}")
            set(${component}_FOUND false CACHE BOOL "Licensecc ${component} present")
            message( WARNING "Component ${component} declared but not found." )
        endif(EXISTS "${cmakefile}")
        mark_as_advanced(${component}_FOUND)
    endforeach(component)
else(licensecc_FIND_COMPONENTS)
    if(LCC_PROJECT_NAME)
        if(EXISTS "${SELF_DIR}/${LCC_PROJECT_NAME}/cmake/licensecc.cmake")
            include("${SELF_DIR}/${LCC_PROJECT_NAME}/cmake/licensecc.cmake")
            set(${LCC_PROJECT_NAME}_FOUND true CACHE BOOL "Licensecc ${LCC_PROJECT_NAME} present")
        else()
            message( WARNING "Variable LCC_PROJECT_NAME declared but project ${LCC_PROJECT_NAME} not found.")
        endif()
        mark_as_advanced(${LCC_PROJECT_NAME}_FOUND)
    else(LCC_PROJECT_NAME)
        if(PROJECT_NAME AND (EXISTS "${SELF_DIR}/${PROJECT_NAME}/cmake/licensecc.cmake"))
            include("${SELF_DIR}/${PROJECT_NAME}/cmake/licensecc.cmake")
            set(${PROJECT_NAME}_FOUND true CACHE BOOL "Licensecc ${PROJECT_NAME} present")
            mark_as_advanced(${PROJECT_NAME}_FOUND)
        endif()
    endif(LCC_PROJECT_NAME)
endif(licensecc_FIND_COMPONENTS)
get_property(COMPILE_DEF TARGET licensecc::licensecc_static PROPERTY INTERFACE_COMPILE_DEFINITIONS)
if("HAS_OPENSSL" IN_LIST COMPILE_DEF AND NOT OpenSSL_FOUND)
    #message( VERBOSE "Trying to find openssl (required by the target)")
    SET ( OPENSSL_USE_STATIC_LIBS ON )
    find_package(OpenSSL REQUIRED COMPONENTS Crypto)
endif()
src/library/.gitignore
File was deleted
src/library/CMakeLists.txt
@@ -1,25 +1,35 @@
add_subdirectory("os")
add_subdirectory("base")
add_subdirectory("ini")
add_subdirectory("locate")
ADD_LIBRARY(licensecc_static STATIC
    license++.cpp
    licensecc.cpp
    LicenseReader.cpp
    pc-identifiers.c
    limits/license_verifier.cpp
    ini/ConvertUTF.c
)
target_link_libraries(
     licensecc_static
     ini
     locators
     os
     base
add_subdirectory("locate")
add_subdirectory("os")
define_property(TARGET PROPERTY WITH_OPENSSL BRIEF_DOCS "need openssl to compile" FULL_DOCS "ff")
IF(UNIX OR OPENSSL_FOUND)
    target_compile_definitions(licensecc_static PUBLIC HAS_OPENSSL)
    set_target_properties(licensecc_static PROPERTIES WITH_OPENSSL 1)
    target_link_libraries(licensecc_static PUBLIC base OpenSSL::Crypto ${EXTERNAL_LIBS} ${CMAKE_DL_LIBS})
ELSE(UNIX OR OPENSSL_FOUND)
    set_target_properties(licensecc_static PROPERTIES WITH_OPENSSL 0)
    target_link_libraries(licensecc_static PUBLIC base ${EXTERNAL_LIBS})
ENDIF(UNIX OR OPENSSL_FOUND)
target_include_directories(licensecc_static
    INTERFACE
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../include>
)
install(TARGETS licensecc_static ARCHIVE DESTINATION lib)
install(FILES api/datatypes.h api/license++.h DESTINATION include/api)
install(FILES base/base.h DESTINATION include/base)
install(FILES pc-identifiers.h DESTINATION include/)
install(FILES ini/SimpleIni.h ini/ConvertUTF.h DESTINATION include/ini)
add_library(licensecc::licensecc_static ALIAS licensecc_static)
install(TARGETS licensecc_static EXPORT licensecc
    ARCHIVE DESTINATION ${main_lib_dest}/${LCC_PROJECT_NAME})
install(EXPORT licensecc NAMESPACE licensecc:: DESTINATION  ${main_lib_dest}/${LCC_PROJECT_NAME}/cmake)
export(EXPORT licensecc NAMESPACE licensecc:: FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.cmake)
src/library/LicenseReader.cpp
@@ -6,9 +6,9 @@
 */
#ifdef _WIN32
# pragma warning(disable: 4786)
#pragma warning(disable : 4786)
#else
# include <unistd.h>
#include <unistd.h>
#endif
#include <cstring>
@@ -22,103 +22,30 @@
#include <stdlib.h>
#include <math.h>
#include <public_key.h>
#include <licensecc_properties.h>
#include <licensecc/licensecc.h>
#include "base/base.h"
#include "pc-identifiers.h"
#include "build_properties.h"
#include "public-key.h"
#include "LicenseReader.hpp"
#include "base/StringUtils.h"
#include "base/logger.h"
#include "locate/LocatorFactory.hpp"
namespace license {
using namespace std;
const char *FullLicenseInfo::UNUSED_TIME = "0000-00-00";
FullLicenseInfo::FullLicenseInfo(const string &source, const string &product, const string &license_signature)
    : source(source),
      m_project(product),  //
      license_signature(license_signature) {}
FullLicenseInfo::FullLicenseInfo(const string &source, const string &product,
        const string &license_signature, int licenseVersion, string from_date,
        string to_date, const string &client_signature,
        unsigned int from_sw_version, unsigned int to_sw_version,
        const string &extra_data) :
        source(source), product(product), //
        license_signature(license_signature), license_version(licenseVersion), //
        from_date(from_date), to_date(to_date), //
        has_expiry(to_date != UNUSED_TIME), //
        from_sw_version(from_sw_version), to_sw_version(to_sw_version), //
        has_versions(
                from_sw_version != UNUSED_SOFTWARE_VERSION
                        || to_sw_version != UNUSED_SOFTWARE_VERSION), //
        client_signature(client_signature), has_client_sig(
                client_signature.length() > 0), //
        extra_data(extra_data) {
}
LicenseReader::LicenseReader(const LicenseLocation *licenseLocation) : licenseLocation(licenseLocation) {}
bool FullLicenseInfo::validate(int sw_version,
        EventRegistry &eventRegistryOut) {
    os_initialize();
    const FUNCTION_RETURN sigVer = verifySignature(printForSign().c_str(),
            license_signature.c_str());
    bool is_valid = (sigVer == FUNC_RET_OK);
    if (is_valid) {
        eventRegistryOut.addEvent(SIGNATURE_VERIFIED, source);
    } else {
        eventRegistryOut.addEvent(LICENSE_CORRUPTED, source);
    }
    if (has_expiry) {
        cout<<source<<endl;
        const time_t now = time(nullptr);
        if (expires_on() < now) {
/*
            eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                    string("Expired on: " + this->to_date).c_str());*/
            eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),nullptr);
            is_valid = false;
        }
        if (valid_from() > now) {
            /*eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                    string("Valid from " + this->from_date).c_str());*/
            eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),nullptr);
            is_valid = false;
        }
    }
    if (has_client_sig) {
        PcSignature str_code;
        strncpy(str_code, client_signature.c_str(), sizeof(str_code) - 1);
        const EVENT_TYPE event = validate_pc_signature(str_code);
        eventRegistryOut.addEvent(event, source);
        is_valid = is_valid && (event == LICENSE_OK);
    }
    return is_valid;
}
void FullLicenseInfo::toLicenseInfo(LicenseInfo *license) const {
    if (license != nullptr) {
        strncpy(license->proprietary_data, extra_data.c_str(),
        PROPRIETARY_DATA_SIZE);
        license->linked_to_pc = has_client_sig;
        license->has_expiry = has_expiry;
        if (!has_expiry) {
            license->expiry_date[0] = '\0';
            license->days_left = 999999;
        } else {
            strncpy(license->expiry_date, to_date.c_str(), 11);
            const double secs = difftime(seconds_from_epoch(to_date.c_str()),
                    time(nullptr));
            license->days_left = round(secs / (60 * 60 * 24));
        }
    }
}
LicenseReader::LicenseReader(const LicenseLocation* licenseLocation) :
        licenseLocation(licenseLocation) {
}
EventRegistry LicenseReader::readLicenses(const string &product,
        vector<FullLicenseInfo> &licenseInfoOut) {
    vector<string> diskFiles;
EventRegistry LicenseReader::readLicenses(const string &product, vector<FullLicenseInfo> &licenseInfoOut) const {
    vector<unique_ptr<locate::LocatorStrategy>> locator_strategies;
    FUNCTION_RETURN ret = locate::LocatorFactory::get_active_strategies(
            locator_strategies, licenseLocation);
    FUNCTION_RETURN ret = locate::LocatorFactory::get_active_strategies(locator_strategies, licenseLocation);
    EventRegistry eventRegistry;
    if (ret != FUNC_RET_OK) {
        eventRegistry.addEvent(LICENSE_FILE_NOT_FOUND);
@@ -127,29 +54,28 @@
    }
    bool atLeastOneLicenseComplete = false;
    const string product_up = toupper_copy(product);
    const char *productNamePtr = product_up.c_str();
    for (unique_ptr<locate::LocatorStrategy> &locator : locator_strategies) {
        vector<string> licenseLocations = locator->license_locations(
                eventRegistry);
        vector<string> licenseLocations = locator->license_locations(eventRegistry);
        if (licenseLocations.size() == 0) {
            continue;
        }
        CSimpleIniA ini;
        for (auto it = licenseLocations.begin(); it != licenseLocations.end();
                it++) {
        for (auto it = licenseLocations.begin(); it != licenseLocations.end(); it++) {
            ini.Reset();
            string license = locator->retrieve_license_content((*it).c_str());
            const string license = locator->retrieve_license_content((*it).c_str());
            const SI_Error rc = ini.LoadData(license.c_str(), license.size());
            if (rc < 0) {
                eventRegistry.addEvent(FILE_FORMAT_NOT_RECOGNIZED,     *it);
                eventRegistry.addEvent(FILE_FORMAT_NOT_RECOGNIZED, *it);
                continue;
            }
            const char *productNamePtr = product.c_str();
            const int sectionSize = ini.GetSectionSize(productNamePtr);
            if (sectionSize <= 0) {
                eventRegistry.addEvent(PRODUCT_NOT_LICENSED, *it);
                continue;
            } else {
                eventRegistry.addEvent(PRODUCT_FOUND,     *it);
                eventRegistry.addEvent(PRODUCT_FOUND, *it);
            }
            /*
             *  sw_version_from = (optional int)
@@ -157,37 +83,18 @@
             *  from_date = YYYY-MM-DD (optional)
             *  to_date  = YYYY-MM-DD (optional)
             *  client_signature = XXXX-XXXX-XXXX-XXXX (optional string 16)
             *  license_signature = XXXXXXXXXX (mandatory, 1024)
             *  sig = XXXXXXXXXX (mandatory, 1024)
             *  application_data = xxxxxxxxx (optional string 16)
             */
            const char *license_signature = ini.GetValue(productNamePtr,
                    "license_signature", nullptr);
            long license_version = ini.GetLongValue(productNamePtr,
                    "license_version", -1);
            if (license_signature != nullptr && license_version > 0) {
                const string from_date = trim_copy(
                        ini.GetValue(productNamePtr, "from_date",
                                FullLicenseInfo::UNUSED_TIME));
                const string to_date = trim_copy(
                        ini.GetValue(productNamePtr, "to_date",
                                FullLicenseInfo::UNUSED_TIME));
                string client_signature = trim_copy(
                        ini.GetValue(productNamePtr, "client_signature", ""));
                /*client_signature.erase(
                 std::remove(client_signature.begin(), client_signature.end(), '-'),
                 client_signature.end());*/
                const int from_sw_version = ini.GetLongValue(productNamePtr,
                        "from_sw_version",
                        FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
                const int to_sw_version = ini.GetLongValue(productNamePtr,
                        "to_sw_version",
                        FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
                string extra_data = trim_copy(
                        ini.GetValue(productNamePtr, "extra_data", ""));
                FullLicenseInfo licInfo(*it, product, license_signature,
                        (int) license_version, from_date, to_date,
                        client_signature, from_sw_version, to_sw_version,
                        extra_data);
            const char *license_signature = ini.GetValue(productNamePtr, LICENSE_SIGNATURE, nullptr);
            long license_version = ini.GetLongValue(productNamePtr, LICENSE_VERSION, -1);
            if (license_signature != nullptr && license_version == 200) {
                CSimpleIniA::TNamesDepend keys;
                ini.GetAllKeys(productNamePtr, keys);
                FullLicenseInfo licInfo(*it, product, license_signature);
                for (auto &it : keys) {
                    licInfo.m_limits[it.pItem] = ini.GetValue(productNamePtr, it.pItem, nullptr);
                }
                licenseInfoOut.push_back(licInfo);
                atLeastOneLicenseComplete = true;
            } else {
@@ -201,70 +108,21 @@
    return eventRegistry;
}
LicenseReader::~LicenseReader() {
}
LicenseReader::~LicenseReader() {}
string FullLicenseInfo::printForSign() const {
    ostringstream oss;
    oss << toupper_copy(trim_copy(this->product));
    oss << SHARED_RANDOM
    ;
    if (has_client_sig) {
        oss << trim_copy(this->client_signature);
    oss << toupper_copy(trim_copy(m_project));
    for (auto &it : m_limits) {
        if (it.first != LICENSE_VERSION && it.first != LICENSE_SIGNATURE) {
            oss << trim_copy(it.first) << trim_copy(it.second);
        }
    }
    if (has_versions) {
        oss << "|" << this->from_sw_version << "-" << this->to_sw_version;
    }
    if (has_expiry) {
        oss << "|" << this->from_date << "|" << this->to_date;
    }
    if (this->extra_data.length() > 0) {
        oss << "|" << extra_data;
    }
#ifdef _DEBUG
    cout << "[" << oss.str() << "]" << endl;
    cout << "license to sign [" << oss.str() << "]" << endl;
#endif
    return oss.str();
}
void FullLicenseInfo::printAsIni(ostream &a_ostream) const {
    CSimpleIniA ini;
    string result;
    const string product = toupper_copy(trim_copy(this->product));
    CSimpleIniA::StreamWriter sw(a_ostream);
    ini.SetLongValue(product.c_str(), "license_version",
    PROJECT_INT_VERSION);
    ini.SetValue(product.c_str(), "license_signature",
            this->license_signature.c_str());
    if (has_client_sig) {
        ini.SetValue(product.c_str(), "client_signature",
                this->client_signature.c_str());
    }
    if (has_versions) {
        ini.SetLongValue(product.c_str(), "from_sw_version", from_sw_version);
        ini.SetLongValue(product.c_str(), "to_sw_version", to_sw_version);
    }
    if (this->from_date != UNUSED_TIME) {
        ini.SetValue(product.c_str(), "from_date", from_date.c_str());
    }
    if (this->to_date != UNUSED_TIME) {
        ini.SetValue(product.c_str(), "to_date", to_date.c_str());
    }
    if (this->extra_data.length() > 0) {
        ini.SetValue(product.c_str(), "extra_data", this->extra_data.c_str());
    }
    ini.Save(sw);
}
time_t FullLicenseInfo::expires_on() const {
    return seconds_from_epoch(this->to_date.c_str());
}
time_t FullLicenseInfo::valid_from() const {
    return seconds_from_epoch(this->from_date.c_str());
}
}
}  // namespace license
src/library/LicenseReader.hpp
@@ -11,7 +11,8 @@
#include <ctime>
#define SI_SUPPORT_IOSTREAMS
#include "api/datatypes.h"
#include <licensecc/datatypes.h>
#include "base/EventRegistry.h"
#include "os/os.h"
#include "ini/SimpleIni.h"
@@ -20,37 +21,14 @@
class FullLicenseInfo {
public:
    std::string source;
    std::string product;
    std::string license_signature;
    int license_version;
    std::string from_date;
    std::string to_date;
    bool has_expiry;
    unsigned int from_sw_version;
    unsigned int to_sw_version;
    bool has_versions;
    std::string client_signature;
    bool has_client_sig;
    std::string extra_data;
    const std::string license_signature;
    const std::string source;
    const std::string m_project;
    std::map<std::string, std::string> m_limits;
    static const char* UNUSED_TIME;
    static const unsigned int UNUSED_SOFTWARE_VERSION = 0;
    FullLicenseInfo(const std::string& source, const std::string& product,
            const std::string& license_signature, int licenseVersion,
            std::string from_date = UNUSED_TIME,
            std::string to_date = UNUSED_TIME, //
            const std::string& client_signature = "", //
            unsigned int from_sw_version = UNUSED_SOFTWARE_VERSION,
            unsigned int to_sw_version = UNUSED_SOFTWARE_VERSION,
            const std::string& extra_data = "");
    FullLicenseInfo(const std::string& source, const std::string& product, const std::string& license_signature);
    std::string printForSign() const;
    void printAsIni(std::ostream & a_ostream) const;
    void toLicenseInfo(LicenseInfo* license) const;
    bool validate(int sw_version, EventRegistry& eventRegistryOut);
    time_t expires_on() const;
    time_t valid_from() const;
    operator LicenseInfo() const;
};
/**
@@ -74,11 +52,11 @@
class LicenseReader {
private:
    const LicenseLocation* licenseLocation;
public:
    LicenseReader(const LicenseLocation* licenseLocation);
    EventRegistry readLicenses(const std::string &product,
            std::vector<FullLicenseInfo>& licenseInfoOut);
    EventRegistry readLicenses(const std::string& product, std::vector<FullLicenseInfo>& licenseInfoOut) const;
    virtual ~LicenseReader();
};
}
}  // namespace license
#endif /* LICENSEREADER_H_ */
src/library/api/datatypes.h
File was deleted
src/library/base/.gitignore
File was deleted
src/library/base/CMakeLists.txt
@@ -6,6 +6,7 @@
    base64.c
)
add_dependencies( base public_key )
add_dependencies( base project_initialize )
install(TARGETS base ARCHIVE DESTINATION lib)
install(TARGETS base EXPORT licensecc ARCHIVE DESTINATION lib/${PROJECT_NAME}/${LCC_PROJECT_NAME})
src/library/base/EventRegistry.cpp
@@ -17,50 +17,42 @@
namespace license {
using namespace std;
const map<EVENT_TYPE, int> PROGRESS_BY_EVENT_TYPE = { { LICENSE_SPECIFIED, 0 },
        { LICENSE_FOUND, 1 }, { PRODUCT_FOUND, 2 }, { SIGNATURE_VERIFIED, 3 }, {
                LICENSE_OK, 4 } };
const map<EVENT_TYPE, int> PROGRESS_BY_EVENT_TYPE = {
    {LICENSE_SPECIFIED, 0}, {LICENSE_FOUND, 1}, {PRODUCT_FOUND, 2}, {SIGNATURE_VERIFIED, 3}, {LICENSE_OK, 4}};
EventRegistry::EventRegistry() {
    current_validation_step = -1;
}
EventRegistry::EventRegistry() { current_validation_step = -1; }
EventRegistry& operator<<(EventRegistry &eventRegistry,
        AuditEvent &securityEvent) {
EventRegistry &operator<<(EventRegistry &eventRegistry, AuditEvent &securityEvent) {
    eventRegistry.logs.push_back(securityEvent);
    return eventRegistry;
}
EventRegistry& operator<<(EventRegistry &eventRegistry1,
        EventRegistry &otherRegistry) {
EventRegistry &operator<<(EventRegistry &eventRegistry1, EventRegistry &otherRegistry) {
    eventRegistry1.append(otherRegistry);
    return eventRegistry1;
}
ostream& operator<<(std::ostream &out, const EventRegistry &er) {
    out << string("EventReg[step:") << er.current_validation_step
            << ",events:{";
ostream &operator<<(std::ostream &out, const EventRegistry &er) {
    out << string("EventReg[step:") << er.current_validation_step << ",events:{";
    for (auto &it : er.logs) {
        out << "[ev:" << it.event_type << ",sev:" << it.severity << "ref:"
                << it.license_reference << "]";
        out << "[ev:" << it.event_type << ",sev:" << it.severity << "ref:" << it.license_reference << "]";
    }
    out << "]";
    return out;
}
void EventRegistry::append(const EventRegistry &eventRegistry) {
    logs.insert(logs.end(), eventRegistry.logs.begin(),
            eventRegistry.logs.end());
    logs.insert(logs.end(), eventRegistry.logs.begin(), eventRegistry.logs.end());
}
AuditEvent const* EventRegistry::getLastFailure() const {
const AuditEvent *EventRegistry::getLastFailure() const {
    const AuditEvent *result = nullptr;
    if (logs.size() == 0) {
        return result;
    }
    //try to find a failure between the licenses who progressed the most
    // try to find a failure between the licenses who progressed the most
    if (mostAdvancedLogIdx_by_LicenseId.size() > 0) {
        for (auto const &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
        for (const auto &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
            const AuditEvent &currentLog = logs[mostAdvLogIter.second];
            if (currentLog.severity == SVRT_ERROR) {
                result = &(currentLog);
@@ -81,13 +73,11 @@
    return result;
}
void EventRegistry::addEvent(EVENT_TYPE event,
        const std::string &licenseLocationId) {
void EventRegistry::addEvent(EVENT_TYPE event, const std::string &licenseLocationId) {
    addEvent(event, licenseLocationId.c_str(), nullptr);
}
void EventRegistry::addEvent(EVENT_TYPE event, const char *licenseLocationId,
        const char *info) {
void EventRegistry::addEvent(EVENT_TYPE event, const char *licenseLocationId, const char *info) {
    AuditEvent audit;
    auto eventIterator = PROGRESS_BY_EVENT_TYPE.find(event);
    bool successEvent = (eventIterator != PROGRESS_BY_EVENT_TYPE.end());
@@ -104,7 +94,7 @@
        strncpy(audit.param2, info, 255);
    }
    logs.push_back(audit);
//udpate the status of the log
    // udpate the status of the log
    if (successEvent) {
        int step = eventIterator->second;
        if (step > current_validation_step) {
@@ -113,23 +103,19 @@
        }
        if (step == current_validation_step) {
            mostAdvancedLogIdx_by_LicenseId[audit.license_reference] =
                    logs.size() - 1;
            mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = logs.size() - 1;
        }
    } else if (mostAdvancedLogIdx_by_LicenseId.find(audit.license_reference)
            != mostAdvancedLogIdx_by_LicenseId.end()) {
        mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = logs.size()
                - 1;
    } else if (mostAdvancedLogIdx_by_LicenseId.find(audit.license_reference) != mostAdvancedLogIdx_by_LicenseId.end()) {
        mostAdvancedLogIdx_by_LicenseId[audit.license_reference] = logs.size() - 1;
    }
}
bool EventRegistry::turnWarningsIntoErrors() {
    bool eventFound = false;
    if (mostAdvancedLogIdx_by_LicenseId.size() > 0) {
        for (auto const &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
        for (const auto &mostAdvLogIter : mostAdvancedLogIdx_by_LicenseId) {
            AuditEvent &currentLog = logs[mostAdvLogIter.second];
            if (currentLog.severity == SVRT_WARN
                    || currentLog.severity == SVRT_ERROR) {
            if (currentLog.severity == SVRT_WARN || currentLog.severity == SVRT_ERROR) {
                currentLog.severity = SVRT_ERROR;
                eventFound = true;
            }
@@ -158,13 +144,10 @@
}
void EventRegistry::exportLastEvents(AuditEvent *auditEvents, int nlogs) {
    const int sizeToCopy = min(nlogs, (int) logs.size());
    const int sizeToCopy = min(nlogs, (int)logs.size());
    std::copy(logs.end() - sizeToCopy, logs.end(), auditEvents);
}
bool EventRegistry::isGood() const {
    return getLastFailure() == nullptr;
}
bool EventRegistry::isGood() const { return getLastFailure() == nullptr; }
}
}  // namespace license
src/library/base/EventRegistry.h
@@ -8,7 +8,8 @@
#ifndef EVENTREGISTRY_H_
#define EVENTREGISTRY_H_
#include "../api/datatypes.h"
#include <licensecc/datatypes.h>
#include <vector>
#include <map>
#include <set>
@@ -22,21 +23,21 @@
 */
class EventRegistry {
private:
    friend EventRegistry& operator<<(EventRegistry&, AuditEvent&);
    friend EventRegistry& operator<<(EventRegistry&, EventRegistry&);
    friend std::ostream & operator << (std::ostream &out, const EventRegistry &er);
    friend EventRegistry &operator<<(EventRegistry &, AuditEvent &);
    friend EventRegistry &operator<<(EventRegistry &, EventRegistry &);
    friend std::ostream &operator<<(std::ostream &out, const EventRegistry &er);
    std::vector<AuditEvent> logs;
    /**
     * For every license keep track of the events who progressed most
     * in the validation process
     */
    std::map<std::string,size_t> mostAdvancedLogIdx_by_LicenseId;
    std::map<std::string, size_t> mostAdvancedLogIdx_by_LicenseId;
    int current_validation_step;
public:
    EventRegistry();
    //operator <<
    // operator <<
    void append(const EventRegistry &eventRegistry);
    /**
     * Turn the event warning for the license with the most advanced status
@@ -50,11 +51,10 @@
     * for the license with the most advanced status.
     * @return NULL if no failures are found.
     */
    AuditEvent const* getLastFailure() const;
    const AuditEvent *getLastFailure() const;
    void addEvent(EVENT_TYPE event, const std::string &licenseLocationId);
    void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr,
            const char *info = nullptr);
    void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr, const char *info = nullptr);
    void exportLastEvents(AuditEvent *auditEvents, int nlogs);
};
}
}  // namespace license
#endif /* EVENTREGISTRY_H_ */
src/library/base/StringUtils.cpp
@@ -24,13 +24,13 @@
string trim_copy(const string &string_to_trim) {
    std::string::const_iterator it = string_to_trim.begin();
    while (it != string_to_trim.end() && isspace(*it))
        it++;
    while (it != string_to_trim.end() && isspace(*it)) {
        ++it;
    }
    std::string::const_reverse_iterator rit = string_to_trim.rbegin();
    while (rit.base() != it && isspace(*rit))
        rit++;
    while (rit.base() != it && isspace(*rit)) {
        ++rit;
    }
    return std::string(it, rit.base());
}
src/library/base/StringUtils.h
@@ -12,7 +12,6 @@
#include <vector>
namespace license {
using namespace std;
/**
 * Eliminate whitespace from both sides of a string and returns a copy
@@ -20,23 +19,22 @@
 * @param string_to_trim
 * @return the trimmed string
 */
string trim_copy(const string& string_to_trim);
std::string trim_copy(const std::string& string_to_trim);
string toupper_copy(const string& lowercase);
std::string toupper_copy(const std::string& lowercase);
time_t seconds_from_epoch(const char* s);
/**
 * Split a string on a given character
 */
const vector<string> split_string(const string& stringToBeSplit, const char splitchar);
const std::vector<std::string> split_string(const std::string& stringToBeSplit, const char splitchar);
typedef enum {
    INI, BASE64, UNKNOWN
} FILE_FORMAT;
FILE_FORMAT identify_format(const string& license);
FILE_FORMAT identify_format(const std::string& license);
}
/* namespace license */
src/library/base/base.h
@@ -9,12 +9,12 @@
#include <limits.h>
#define DllExport
#ifndef MAX_PATH
    #define MAX_PATH PATH_MAX
#define MAX_PATH PATH_MAX
#endif
#else //windows
#else  // windows
#include <windows.h>
#define DllExport  __declspec( dllexport )
#define DllExport __declspec(dllexport)
#ifndef __cplusplus
#ifndef _MSC_VER
@@ -22,21 +22,31 @@
#else
typedef int bool;
#define false 0
#define true -1
#define true - 1
#endif
#endif
#endif
/* #define _DEBUG */
#define cmin(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a < _b ? _a : _b; })
// license file parameters
#define PARAM_EXPIRY_DATE "valid-to"
#define PARAM_BEGIN_DATE "valid-from"
#define PARAM_VERSION_FROM "start-version"
#define PARAM_CLIENT_SIGNATURE "client-signature"
#define PARAM_VERSION_TO "end-version"
#define PARAM_EXTRA_DATA "extra-data"
// license file extra entries
#define LICENSE_SIGNATURE "sig"
#define LICENSE_VERSION "lic_ver"
typedef enum  {
    FUNC_RET_OK, FUNC_RET_NOT_AVAIL, FUNC_RET_ERROR, FUNC_RET_BUFFER_TOO_SMALL
} FUNCTION_RETURN;
typedef enum { FUNC_RET_OK, FUNC_RET_NOT_AVAIL, FUNC_RET_ERROR, FUNC_RET_BUFFER_TOO_SMALL } FUNCTION_RETURN;
#define cmin(a, b)              \
    ({                          \
        __typeof__(a) _a = (a); \
        __typeof__(b) _b = (b); \
        _a < _b ? _a : _b;      \
    })
#ifdef __cplusplus
}
src/library/base/base64.c
@@ -1,133 +1,134 @@
#include <stdio.h>
#include <stdlib.h>
const static char* b64 =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// maps A=>0,B=>1..
const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40
        0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50
        54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60
        0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70
        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90
        25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100
        29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110
        39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120
        49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250
        0, 0, 0, 0, 0, 0, }; // This array has 255 elements
//review api
char* base64(const void* binaryData, int len, int *flen) {
    const unsigned char* bin = (const unsigned char*) binaryData;
    char* res;
    int rc = 0; // result counter
    int byteNo; // I need this after the loop
    int modulusLen = len % 3;
    int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0.
    *flen = 4 * (len + pad) / 3;
    res = (char*) malloc(*flen + 1); // and one for the null
    if (!res) {
        puts("ERROR: base64 could not allocate enough memory.");
        puts("I must stop because I could not get enough");
        return 0;
    }
    for (byteNo = 0; byteNo <= len - 3; byteNo += 3) {
        unsigned char BYTE0 = bin[byteNo];
        unsigned char BYTE1 = bin[byteNo + 1];
        unsigned char BYTE2 = bin[byteNo + 2];
        res[rc++] = b64[BYTE0 >> 2];
        res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)];
        res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)];
        res[rc++] = b64[0x3f & BYTE2];
    }
    if (pad == 2) {
        res[rc++] = b64[bin[byteNo] >> 2];
        res[rc++] = b64[(0x3 & bin[byteNo]) << 4];
        res[rc++] = '=';
        res[rc++] = '=';
    } else if (pad == 1) {
        res[rc++] = b64[bin[byteNo] >> 2];
        res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)];
        res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2];
        res[rc++] = '=';
    }
    res[rc] = 0; // NULL TERMINATOR! ;)
    return res;
}
unsigned char* unbase64(const char* ascii, int len, int *flen) {
    const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
    unsigned char *bin;
    int cb = 0;
    int charNo;
    int pad = 0;
    if (len < 2) { // 2 accesses below would be OOB.
        // catch empty string, return NULL as result.
        puts(
                "ERROR: You passed an invalid base64 string (too short). You get NULL back.");
        *flen = 0;
        return 0;
    }
    if (safeAsciiPtr[len - 1] == '=')
        ++pad;
    if (safeAsciiPtr[len - 2] == '=')
        ++pad;
    *flen = 3 * len / 4 - pad;
    bin = (unsigned char*) malloc(*flen);
    if (!bin) {
        puts("ERROR: unbase64 could not allocate enough memory.");
        puts("I must stop because I could not get enough");
        return 0;
    }
    for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        int C = unb64[safeAsciiPtr[charNo + 2]];
        int D = unb64[safeAsciiPtr[charNo + 3]];
        bin[cb++] = (A << 2) | (B >> 4);
        bin[cb++] = (B << 4) | (C >> 2);
        bin[cb++] = (C << 6) | (D);
    }
    if (pad == 1) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        int C = unb64[safeAsciiPtr[charNo + 2]];
        bin[cb++] = (A << 2) | (B >> 4);
        bin[cb++] = (B << 4) | (C >> 2);
    } else if (pad == 2) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        bin[cb++] = (A << 2) | (B >> 4);
    }
    return bin;
}
#include <stdio.h>
#include <stdlib.h>
const static char* b64 =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// maps A=>0,B=>1..
const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40
        0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50
        54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60
        0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70
        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90
        25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100
        29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110
        39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120
        49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250
        0, 0, 0, 0, 0, 0, }; // This array has 255 elements
//review api
char* base64(const void* binaryData, int len, int *flen) {
    const unsigned char* bin = (const unsigned char*) binaryData;
    char* res;
    int rc = 0; // result counter
    int byteNo; // I need this after the loop
    int modulusLen = len % 3;
    int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0.
    *flen = 4 * (len + pad) / 3;
    res = (char*) malloc(*flen + 1); // and one for the null
    if (!res) {
        puts("ERROR: base64 could not allocate enough memory.");
        puts("I must stop because I could not get enough");
        return 0;
    }
    for (byteNo = 0; byteNo <= len - 3; byteNo += 3) {
        unsigned char BYTE0 = bin[byteNo];
        unsigned char BYTE1 = bin[byteNo + 1];
        unsigned char BYTE2 = bin[byteNo + 2];
        res[rc++] = b64[BYTE0 >> 2];
        res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)];
        res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)];
        res[rc++] = b64[0x3f & BYTE2];
    }
    if (pad == 2) {
        res[rc++] = b64[bin[byteNo] >> 2];
        res[rc++] = b64[(0x3 & bin[byteNo]) << 4];
        res[rc++] = '=';
        res[rc++] = '=';
    } else if (pad == 1) {
        res[rc++] = b64[bin[byteNo] >> 2];
        res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)];
        res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2];
        res[rc++] = '=';
    }
    res[rc] = 0; // NULL TERMINATOR! ;)
    return res;
}
//FIXME!
unsigned char* unbase64(const char* ascii, int len, int *flen) {
    const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
    unsigned char *bin;
    int cb = 0;
    int charNo;
    int pad = 0;
    if (len < 2) { // 2 accesses below would be OOB.
        // catch empty string, return NULL as result.
        puts(
                "ERROR: You passed an invalid base64 string (too short). You get NULL back.");
        *flen = 0;
        return 0;
    }
    if (safeAsciiPtr[len - 1] == '=')
        ++pad;
    if (safeAsciiPtr[len - 2] == '=')
        ++pad;
    *flen = 3 * len / 4 - pad;
    bin = (unsigned char*) malloc(*flen);
    if (!bin) {
        puts("ERROR: unbase64 could not allocate enough memory.");
        puts("I must stop because I could not get enough");
        return 0;
    }
    for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        int C = unb64[safeAsciiPtr[charNo + 2]];
        int D = unb64[safeAsciiPtr[charNo + 3]];
        bin[cb++] = (A << 2) | (B >> 4);
        bin[cb++] = (B << 4) | (C >> 2);
        bin[cb++] = (C << 6) | (D);
    }
    if (pad == 1) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        int C = unb64[safeAsciiPtr[charNo + 2]];
        bin[cb++] = (A << 2) | (B >> 4);
        bin[cb++] = (B << 4) | (C >> 2);
    } else if (pad == 2) {
        int A = unb64[safeAsciiPtr[charNo]];
        int B = unb64[safeAsciiPtr[charNo + 1]];
        bin[cb++] = (A << 2) | (B >> 4);
    }
    return bin;
}
src/library/base/logger.c
@@ -26,7 +26,7 @@
static void getLogFname(char* logpath) {
#ifdef __unix__
    char const *folder = getenv("TMPDIR");
    const char *folder = getenv("TMPDIR");
    if (folder == 0) {
        folder = "/tmp";
    }
@@ -42,10 +42,10 @@
}
void _log(const char* format, ...) {
    char logpath[MAX_PATH];
    va_list args;
    char * buffer;
    if (logFile == NULL) {
        char logpath[MAX_PATH];
        getLogFname(logpath);
        logFile = fopen(logpath, "a");
        if (logFile == NULL) {
src/library/base/logger.h
@@ -3,6 +3,7 @@
#ifndef LOG_DISABLED
#include <errno.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
src/library/ini/CMakeLists.txt
File was deleted
src/library/license++.cpp
File was deleted
src/library/licensecc.cpp
New file
@@ -0,0 +1,109 @@
//============================================================================
// Name        : license-manager-cpp.cpp
// Author      :
// Version     :
// Copyright   : BSD
//============================================================================
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <licensecc/datatypes.h>
#include <licensecc/licensecc.h>
#include <licensecc_properties.h>
#include "limits/license_verifier.hpp"
#include "LicenseReader.hpp"
#include "pc-identifiers.h"
using namespace std;
void print_error(char out_buffer[256], LicenseInfo* licenseInfo) {}
bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t bufSize) {
    FUNCTION_RETURN result = FUNC_RET_BUFFER_TOO_SMALL;
    if (bufSize >= sizeof(PcSignature)) {
        PcSignature identifier_out;
        result = generate_user_pc_signature(identifier_out, pc_id_method);
        strncpy(chbuffer, identifier_out, bufSize);
    }
    return result == FUNC_RET_OK;
}
static void mergeLicenses(const vector<LicenseInfo>& licenses, LicenseInfo* license_out) {
    if (license_out != nullptr) {
        int days_left = INT_MIN;
        for (auto it = licenses.begin(); it != licenses.end(); it++) {
            // choose the license that expires later...
            if (!it->has_expiry) {
                *license_out = *it;
                break;
            } else if (days_left < (int)it->days_left) {
                *license_out = *it;
                days_left = it->days_left;
            }
        }
    }
}
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;
    if (callerInformation != nullptr && strlen(callerInformation->project_name) > 0) {
        project = string(callerInformation->project_name);
    } else {
        project = string(LCC_PROJECT_NAME);
    }
    license::EventRegistry er = lr.readLicenses(string(project), licenses);
    EVENT_TYPE result;
    if (licenses.size() > 0) {
        vector<LicenseInfo> licenses_with_errors;
        vector<LicenseInfo> licenses_ok;
        license::LicenseVerifier verifier(er);
        for (auto it = licenses.begin(); it != licenses.end(); it++) {
            FUNCTION_RETURN signatureValid = verifier.verify_signature(*it);
            if (signatureValid == FUNC_RET_OK) {
                if (verifier.verify_limits(*it) == FUNC_RET_OK) {
                    licenses_ok.push_back(verifier.toLicenseInfo(*it));
                } else {
                    licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
                }
            } else {
                licenses_with_errors.push_back(verifier.toLicenseInfo(*it));
            }
        }
        if (licenses_ok.size() > 0) {
            er.turnErrorsIntoWarnings();
            result = LICENSE_OK;
            mergeLicenses(licenses_ok, license_out);
        } else {
            er.turnWarningsIntoErrors();
            result = er.getLastFailure()->event_type;
            mergeLicenses(licenses_with_errors, license_out);
        }
    } else {
        er.turnWarningsIntoErrors();
        result = er.getLastFailure()->event_type;
        if (license_out != nullptr) {
            license_out->proprietary_data[0] = '\0';
            license_out->linked_to_pc = false;
            license_out->days_left = 0;
        }
    }
#ifdef _DEBUG
    cout << er << endl;
#endif
    if (license_out != nullptr) {
        er.exportLastEvents(license_out->status, AUDIT_EVENT_NUM);
    }
    return result;
}
EVENT_TYPE confirm_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
EVENT_TYPE release_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
src/library/limits/license_verifier.cpp
New file
@@ -0,0 +1,100 @@
/*
 * LicenseVerifier.cpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#include <cmath>
#include <algorithm>
#include "license_verifier.hpp"
#include "../os/signature_verifier.h"
#include "../base/StringUtils.h"
#include "../pc-identifiers.h"
namespace license {
using namespace std;
LicenseVerifier::LicenseVerifier(EventRegistry& er) : m_event_registry(er) {}
LicenseVerifier::~LicenseVerifier() {}
FUNCTION_RETURN LicenseVerifier::verify_signature(const FullLicenseInfo& licInfo) {
    const string licInfoData(licInfo.printForSign());
    FUNCTION_RETURN ret = license::verify_signature(licInfoData, licInfo.license_signature);
    if (ret == FUNC_RET_OK) {
        m_event_registry.addEvent(SIGNATURE_VERIFIED, licInfo.source);
    } else {
        m_event_registry.addEvent(LICENSE_CORRUPTED, licInfo.source);
    }
    return ret;
}
// TODO: split in different classes
FUNCTION_RETURN LicenseVerifier::verify_limits(const FullLicenseInfo& licInfo) {
    bool is_valid = true;
    const time_t now = time(nullptr);
    auto expiry = licInfo.m_limits.find(PARAM_EXPIRY_DATE);
    if (expiry != licInfo.m_limits.end()) {
        if (seconds_from_epoch(expiry->second.c_str()) < now) {
            /*
                        eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                                string("Expired on: " + this->to_date).c_str());*/
            m_event_registry.addEvent(PRODUCT_EXPIRED, licInfo.source.c_str(), ("Expired " + expiry->second).c_str());
            is_valid = false;
        }
    }
    auto start_date = licInfo.m_limits.find(PARAM_BEGIN_DATE);
    if (is_valid && start_date != licInfo.m_limits.end()) {
        if (seconds_from_epoch(start_date->second.c_str()) > now) {
            /*eventRegistryOut.addEvent(PRODUCT_EXPIRED, source.c_str(),
                    string("Valid from " + this->from_date).c_str());*/
            m_event_registry.addEvent(PRODUCT_EXPIRED, licInfo.source.c_str(),
                                      ("Valid from " + start_date->second).c_str());
            is_valid = false;
        }
    }
    auto client_sig = licInfo.m_limits.find(PARAM_CLIENT_SIGNATURE);
    if (is_valid && client_sig != licInfo.m_limits.end()) {
        PcSignature str_code;
        strncpy(str_code, client_sig->second.c_str(), sizeof(str_code) - 1);
        const EVENT_TYPE event = validate_pc_signature(str_code);
        m_event_registry.addEvent(event, licInfo.source);
        is_valid = is_valid && (event == LICENSE_OK);
    }
    return is_valid ? FUNC_RET_OK : FUNC_RET_ERROR;
}
LicenseInfo LicenseVerifier::toLicenseInfo(const FullLicenseInfo& fullLicInfo) const {
    LicenseInfo info;
    info.license_type = LOCAL;
    auto expiry = fullLicInfo.m_limits.find(PARAM_EXPIRY_DATE);
    if (expiry != fullLicInfo.m_limits.end()) {
        strncpy(info.expiry_date, expiry->second.c_str(), sizeof(info.expiry_date));
        info.has_expiry = true;
        const double secs = difftime(seconds_from_epoch(expiry->second.c_str()), time(nullptr));
        info.days_left = max((int)round(secs / (60 * 60 * 24)), 0);
    } else {
        info.has_expiry = false;
        info.days_left = 9999;
        info.expiry_date[0] = '\0';
    }
    auto start_date = fullLicInfo.m_limits.find(PARAM_BEGIN_DATE);
    if (start_date != fullLicInfo.m_limits.end()) {
    }
    auto client_sig = fullLicInfo.m_limits.find(PARAM_CLIENT_SIGNATURE);
    info.linked_to_pc = (client_sig != fullLicInfo.m_limits.end());
    auto proprietary_data = fullLicInfo.m_limits.find(PARAM_EXTRA_DATA);
    if (proprietary_data != fullLicInfo.m_limits.end()) {
        strncpy(info.proprietary_data, proprietary_data->second.c_str(), PROPRIETARY_DATA_SIZE);
    }
    return info;
}
} /* namespace license */
src/library/limits/license_verifier.hpp
New file
@@ -0,0 +1,29 @@
/*
 * LicenseVerifier.hpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#ifndef SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_
#define SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_
#include "../base/EventRegistry.h"
#include "../LicenseReader.hpp"
namespace license {
class LicenseVerifier {
private:
    EventRegistry& m_event_registry;
public:
    LicenseVerifier(EventRegistry& er);
    FUNCTION_RETURN verify_signature(const FullLicenseInfo& licInfo);
    FUNCTION_RETURN verify_limits(const FullLicenseInfo& licInfo);
    LicenseInfo toLicenseInfo(const FullLicenseInfo& fullLicInfo) const;
    virtual ~LicenseVerifier();
};
} /* namespace license */
#endif /* SRC_LIBRARY_LIMITS_LICENSEVERIFIER_HPP_ */
src/library/locate/ApplicationFolder.cpp
@@ -7,37 +7,33 @@
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <build_properties.h>
#include <licensecc/datatypes.h>
#include <licensecc_properties.h>
#include "../base/logger.h"
#include "../api/datatypes.h"
#include "../base/base.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
#include "../os/os.h"
#include "ApplicationFolder.hpp"
#include <iostream>
namespace license {
namespace locate {
using namespace std;
ApplicationFolder::ApplicationFolder() :
        LocatorStrategy("ApplicationFolder") {
}
ApplicationFolder::ApplicationFolder() : LocatorStrategy("ApplicationFolder") {}
ApplicationFolder::~ApplicationFolder() {
}
ApplicationFolder::~ApplicationFolder() {}
const vector<string> ApplicationFolder::license_locations(
        EventRegistry &eventRegistry) {
const vector<string> ApplicationFolder::license_locations(EventRegistry &eventRegistry) {
    vector<string> diskFiles;
    char fname[MAX_PATH] = { 0 };
    char fname[MAX_PATH] = {0};
    const FUNCTION_RETURN fret = getModuleName(fname);
    if (fret == FUNC_RET_OK) {
        const string module_name = remove_extension(fname);
        const string temptativeLicense = string(module_name) + ".lic";
        const string temptativeLicense = string(module_name) + LICENSE_FILE_EXTENSION;
        ifstream f(temptativeLicense.c_str());
        if (f.good()) {
            diskFiles.push_back(temptativeLicense);
@@ -52,5 +48,5 @@
    return diskFiles;
}
}
}  // namespace locate
} /* namespace license */
src/library/locate/ApplicationFolder.hpp
@@ -15,14 +15,14 @@
namespace license {
namespace locate {
class ApplicationFolder: public LocatorStrategy {
class ApplicationFolder : public LocatorStrategy {
public:
    ApplicationFolder();
    virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistry);
    const virtual std::vector<std::string> license_locations(EventRegistry& eventRegistry);
    virtual ~ApplicationFolder();
};
}
}  // namespace locate
} /* namespace license */
#endif /* SRC_LIBRARY_RETRIEVERS_APPLICATIONFOLDER_H_ */
src/library/locate/CMakeLists.txt
@@ -1,18 +1,9 @@
ADD_LIBRARY(locators STATIC
    ApplicationFolder.cpp
    EnvironmentVarLocation.cpp
    EnvironmentVarData.cpp
    ExternalDefinition.cpp
    LocatorStrategy.cpp
    LocatorFactory.cpp
)
add_dependencies( locators os base )
target_link_libraries(
     locators
     os
     base
target_sources(licensecc_static PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/ApplicationFolder.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/EnvironmentVarLocation.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/EnvironmentVarData.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/ExternalDefinition.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/LocatorStrategy.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/LocatorFactory.cpp
)
src/library/locate/EnvironmentVarData.cpp
@@ -6,14 +6,14 @@
 */
#include "EnvironmentVarData.hpp"
#include <licensecc/datatypes.h>
#include <build_properties.h>
#include <licensecc_properties.h>
#include <cstdlib>
#include <regex>
#include <string>
#include <vector>
#include "../api/datatypes.h"
#include "../base/base64.h"
#include "../base/EventRegistry.h"
#include "../base/StringUtils.h"
@@ -23,15 +23,11 @@
using namespace std;
EnvironmentVarData::EnvironmentVarData() :
        LocatorStrategy("EnvironmentVarData") {
}
EnvironmentVarData::EnvironmentVarData() : LocatorStrategy("EnvironmentVarData") {}
EnvironmentVarData::~EnvironmentVarData() {
}
EnvironmentVarData::~EnvironmentVarData() {}
const vector<string> EnvironmentVarData::license_locations(
        EventRegistry &eventRegistry) {
const vector<string> EnvironmentVarData::license_locations(EventRegistry &eventRegistry) {
    vector<string> diskFiles;
    char *env_var_value = getenv(LICENSE_DATA_ENV_VAR);
    if (env_var_value != nullptr && env_var_value[0] != '\0') {
@@ -44,24 +40,22 @@
            isBase64 = (licenseFormat == BASE64);
        }
    } else {
        eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED,
        LICENSE_LOCATION_ENV_VAR);
        eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED, LICENSE_LOCATION_ENV_VAR);
    }
    return diskFiles;
}
const std::string EnvironmentVarData::retrieve_license_content(
        const std::string &licenseLocation) const {
const std::string EnvironmentVarData::retrieve_license_content(const std::string &licenseLocation) const {
    string tmpVal = getenv(LICENSE_LOCATION_ENV_VAR);
    if (isBase64) {
        int flen = 0;
        unsigned char *raw = unbase64(tmpVal.c_str(), tmpVal.length(), &flen);
        string str = string(reinterpret_cast<char*>(raw));
        string str = string(reinterpret_cast<char *>(raw));
        free(raw);
        return str;
    }
    return tmpVal;
}
}
}
}  // namespace locate
}  // namespace license
src/library/locate/EnvironmentVarData.hpp
@@ -12,18 +12,18 @@
namespace license {
namespace locate {
class EnvironmentVarData: public LocatorStrategy {
class EnvironmentVarData : public LocatorStrategy {
private:
    bool isBase64 = false;
public:
    EnvironmentVarData();
    virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistr);
    virtual const std::string retrieve_license_content(const std::string &licenseLocation) const;
    const virtual std::vector<std::string> license_locations(EventRegistry& eventRegistr);
    const virtual std::string retrieve_license_content(const std::string& licenseLocation) const;
    virtual ~EnvironmentVarData();
};
}
}
}  // namespace locate
}  // namespace license
#endif
src/library/locate/EnvironmentVarLocation.cpp
@@ -5,7 +5,7 @@
 *      Author: Gabriele Contini
 */
#include <build_properties.h>
#include <licensecc_properties.h>
#include "../base/FileUtils.hpp"
#include "../base/StringUtils.h"
@@ -15,26 +15,21 @@
namespace locate {
using namespace std;
EnvironmentVarLocation::EnvironmentVarLocation() :
        LocatorStrategy("EnvironmentVarLocation") {
}
EnvironmentVarLocation::EnvironmentVarLocation() : LocatorStrategy("EnvironmentVarLocation") {}
EnvironmentVarLocation::~EnvironmentVarLocation() {
}
EnvironmentVarLocation::~EnvironmentVarLocation() {}
const vector<string> EnvironmentVarLocation::license_locations(
        EventRegistry &eventRegistry) {
const vector<string> EnvironmentVarLocation::license_locations(EventRegistry &eventRegistry) {
    vector<string> licenseFileFoundWithEnvVariable;
    const string varName(LICENSE_LOCATION_ENV_VAR);
    if (varName.length() > 0) {
        //var name is defined in header files.
        // var name is defined in header files.
        char *env_var_value = getenv(LICENSE_LOCATION_ENV_VAR);
        if (env_var_value != nullptr && env_var_value[0] != '\0') {
            const vector<string> declared_positions = license::split_string(
                    string(env_var_value), ';');
            licenseFileFoundWithEnvVariable = license::filter_existing_files(
                    declared_positions, eventRegistry, LICENSE_LOCATION_ENV_VAR);
            const vector<string> declared_positions = license::split_string(string(env_var_value), ';');
            licenseFileFoundWithEnvVariable =
                license::filter_existing_files(declared_positions, eventRegistry, LICENSE_LOCATION_ENV_VAR);
        } else {
            eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED);
        }
@@ -42,5 +37,5 @@
    return licenseFileFoundWithEnvVariable;
}
}
}
}  // namespace locate
}  // namespace license
src/library/locate/EnvironmentVarLocation.hpp
@@ -13,15 +13,14 @@
namespace license {
namespace locate {
class EnvironmentVarLocation: public LocatorStrategy {
class EnvironmentVarLocation : public LocatorStrategy {
public:
    EnvironmentVarLocation();
    virtual const std::vector<std::string> license_locations(EventRegistry& eventRegistry);
    const virtual std::vector<std::string> license_locations(EventRegistry& eventRegistry);
    virtual ~EnvironmentVarLocation();
};
}
}
}  // namespace locate
}  // namespace license
#endif /* SRC_LIBRARY_LOCATE_ENVIRONMENTVARLOCATION_H_ */
src/library/locate/ExternalDefinition.cpp
@@ -10,7 +10,8 @@
#include <string>
#include <vector>
#include "../api/datatypes.h"
#include <licensecc/datatypes.h>
#include "../base/base64.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
src/library/locate/LocatorFactory.cpp
@@ -5,8 +5,6 @@
 *      Author: Gabriele Contini
 */
#include "build_properties.h"
#include "LocatorStrategy.hpp"
#include "LocatorFactory.hpp"
#include "ApplicationFolder.hpp"
@@ -16,31 +14,24 @@
namespace license {
namespace locate {
static std::vector<std::unique_ptr<LocatorStrategy>> extra_strategies;
FUNCTION_RETURN LocatorFactory::get_active_strategies(
        std::vector<std::unique_ptr<LocatorStrategy>> &strategies,
        const LicenseLocation *locationHint) {
#if(FIND_LICENSE_NEAR_MODULE)
    strategies.push_back(
            std::unique_ptr<LocatorStrategy>(
                    (LocatorStrategy*) new ApplicationFolder()));
#endif
#if(FIND_LICENSE_WITH_ENV_VAR)
    strategies.push_back(
            std::unique_ptr<LocatorStrategy>(
                    (LocatorStrategy*) new EnvironmentVarLocation()));
    strategies.push_back(
            std::unique_ptr<LocatorStrategy>(
                    (LocatorStrategy*) new EnvironmentVarData()));
#endif
bool LocatorFactory::find_license_near_moduleb = FIND_LICENSE_NEAR_MODULE;
bool LocatorFactory::find_license_with_env_varb = FIND_LICENSE_WITH_ENV_VAR;
FUNCTION_RETURN LocatorFactory::get_active_strategies(std::vector<std::unique_ptr<LocatorStrategy>> &strategies,
                                                      const LicenseLocation *locationHint) {
    if (find_license_near_moduleb) {
        strategies.push_back(std::unique_ptr<LocatorStrategy>((LocatorStrategy *)new ApplicationFolder()));
    }
    if (find_license_with_env_varb) {
        strategies.push_back(std::unique_ptr<LocatorStrategy>((LocatorStrategy *)new EnvironmentVarLocation()));
        strategies.push_back(std::unique_ptr<LocatorStrategy>((LocatorStrategy *)new EnvironmentVarData()));
    }
    if (locationHint != nullptr) {
        strategies.push_back(
                std::unique_ptr<LocatorStrategy>(
                        (LocatorStrategy*) new ExternalDefinition(locationHint)));
        strategies.push_back(std::unique_ptr<LocatorStrategy>((LocatorStrategy *)new ExternalDefinition(locationHint)));
    }
    return strategies.size() > 0 ? FUNC_RET_OK : FUNC_RET_NOT_AVAIL;
}
}
}
}  // namespace locate
}  // namespace license
src/library/locate/LocatorFactory.hpp
@@ -4,9 +4,10 @@
#include <cstddef>
#include <string>
#include <vector>
#include <licensecc/datatypes.h>
#include <licensecc_properties.h>
#include "../base/base.h"
#include "../api/datatypes.h"
#include "LocatorStrategy.hpp"
namespace license {
@@ -14,16 +15,18 @@
class LocatorFactory {
private:
    static bool find_license_near_moduleb;
    static bool find_license_with_env_varb;
    inline LocatorFactory() {
    }
    inline ~LocatorFactory() {
    }
public:
    static FUNCTION_RETURN get_active_strategies(
            std::vector<std::unique_ptr<LocatorStrategy>> &strategiesOut,
            const LicenseLocation *locationHint);
    static void find_license_near_module(bool enable) { find_license_near_moduleb = enable; }
    static void find_license_with_env_var(bool enable) { find_license_with_env_varb = enable; }
};
}
src/library/locate/LocatorStrategy.cpp
@@ -5,7 +5,7 @@
 *      Author: Gabriele Contini
 */
#include <build_properties.h>
#include <licensecc_properties.h>
#include "../base/FileUtils.hpp"
#include "LocatorStrategy.hpp"
@@ -14,10 +14,9 @@
namespace locate {
using namespace std;
const string LocatorStrategy::retrieve_license_content(
        const string &licenseLocation) const {
const string LocatorStrategy::retrieve_license_content(const string &licenseLocation) const {
    return get_file_contents(licenseLocation.c_str(), MAX_LICENSE_LENGTH);
}
}
}
}  // namespace locate
}  // namespace license
src/library/locate/LocatorStrategy.hpp
@@ -16,29 +16,25 @@
 *
 * Usage:
 * <ol>
 * <li> call licenseLocations to get a list of available locations (the returned format is defined by the class, it's usually the file name)</li>
 * <li> iterate over the returned vector and call retrieveLicense to get the content of the license</li>
 * <li> call licenseLocations to get a list of available locations (the returned format is defined by the class, it's
 * usually the file name)</li> <li> iterate over the returned vector and call retrieveLicense to get the content of the
 * license</li>
 * </ol>
 */
class LocatorStrategy {
protected:
    const std::string m_strategy_name;
    inline LocatorStrategy(const std::string &strategyName) :
            m_strategy_name(strategyName) {
    }
public:
    inline LocatorStrategy(const std::string &strategyName) : m_strategy_name(strategyName) {}
    virtual const std::string get_strategy_name() const {
        return m_strategy_name;
    }
public:
    const virtual std::string get_strategy_name() const { return m_strategy_name; }
    /**
     * Try to find licenses
     * @param eventRegistry
     * @return
     * A list of identifiers for call retrieve_license_content.
     */
    virtual const std::vector<std::string> license_locations(
            EventRegistry &eventRegistry) = 0;
    const virtual std::vector<std::string> license_locations(EventRegistry &eventRegistry) = 0;
    /**
     * Default implementation is to retrieve the license from file.
@@ -49,12 +45,10 @@
     * @return
     *     a string containing the license data in INI format.
     */
    virtual const std::string retrieve_license_content(
            const std::string &licenseLocationId) const;
    inline virtual ~LocatorStrategy() {
    }
    const virtual std::string retrieve_license_content(const std::string &licenseLocationId) const;
    inline virtual ~LocatorStrategy() {}
};
}
}
}  // namespace locate
}  // namespace license
#endif
src/library/os/CMakeLists.txt
@@ -1,18 +1,17 @@
IF(WIN32)
    ADD_LIBRARY(os STATIC
        os.c
        os-win.c)
ELSE(WIN32)
    ADD_LIBRARY(os STATIC
        os.c
        os-linux.c
        network_id.c)
ENDIF(WIN32)
IF(UNIX OR OPENSSL_FOUND)
    IF(UNIX)
        target_sources(licensecc_static PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/openssl/signature_verifier.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/os-linux.c
            ${CMAKE_CURRENT_SOURCE_DIR}/network_id.c)
    ELSE(UNIX)
          target_sources(licensecc_static PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/openssl/signature_verifier.cpp
              ${CMAKE_CURRENT_SOURCE_DIR}/os-win.c)
    ENDIF(UNIX)
ELSE(UNIX OR OPENSSL_FOUND)
    target_sources(licensecc_static PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/windows/signature_verifier.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/os-win.c)
ENDIF(UNIX OR OPENSSL_FOUND)
target_link_libraries(
     os
     base
     ${EXTERNAL_LIBS}
)
install(TARGETS os ARCHIVE DESTINATION lib)
src/library/os/openssl/signature_verifier.cpp
New file
@@ -0,0 +1,107 @@
/*
 * verifier.cpp
 *
 *  Created on: Nov 16, 2019
 *      Author: GC
 */
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdlib.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include <public_key.h>
#include "../signature_verifier.h"
namespace license {
#include "../../base/logger.h"
static void free_resources(EVP_PKEY* pkey, EVP_MD_CTX* mdctx) {
    if (pkey) {
        EVP_PKEY_free(pkey);
    }
    if (mdctx) {
        EVP_MD_CTX_destroy(mdctx);
    }
}
static void initialize() {
    static int initialized = 0;
    if (initialized == 0) {
        initialized = 1;
        ERR_load_ERR_strings();
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
    }
}
FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64) {
    EVP_MD_CTX* mdctx = NULL;
    const unsigned char pubKey[] = PUBLIC_KEY;
    int func_ret = 0;
    initialize();
    BIO* bio = BIO_new_mem_buf((void*)(pubKey), sizeof(pubKey));
    RSA* rsa = d2i_RSAPublicKey_bio(bio, NULL);
    BIO_free(bio);
    if (rsa == NULL) {
        LOG_ERROR("Error reading public key");
        return FUNC_RET_ERROR;
    }
    EVP_PKEY* pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, rsa);
    /*BIO* bo = BIO_new(BIO_s_mem());
     BIO_write(bo, pubKey, strlen(pubKey));
     RSA *key = 0;
     PEM_read_bio_RSAPublicKey(bo, &key, 0, 0);
     BIO_free(bo);*/
    // RSA* rsa = EVP_PKEY_get1_RSA( key );
    // RSA * pubKey = d2i_RSA_PUBKEY(NULL, <der encoded byte stream pointer>, <num bytes>);
    unsigned char buffer[512];
    BIO* b64 = BIO_new(BIO_f_base64());
    BIO* encoded_signature = BIO_new_mem_buf((const void*)signatureB64.c_str(), signatureB64.size());
    BIO* biosig = BIO_push(b64, encoded_signature);
    BIO_set_flags(biosig, BIO_FLAGS_BASE64_NO_NL);  // Do not use newlines to flush buffer
    unsigned int len = BIO_read(biosig, (void*)buffer, signatureB64.size());
    // Can test here if len == decodeLen - if not, then return an error
    buffer[len] = 0;
    BIO_free_all(biosig);
    /* Create the Message Digest Context */
    if (!(mdctx = EVP_MD_CTX_create())) {
        free_resources(pkey, mdctx);
        LOG_ERROR("Error creating context");
        return FUNC_RET_ERROR;
    }
    if (1 != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey)) {
        LOG_ERROR("Error initializing digest");
        free_resources(pkey, mdctx);
        return FUNC_RET_ERROR;
    }
    func_ret = EVP_DigestVerifyUpdate(mdctx, (const void*)stringToVerify.c_str(), stringToVerify.size());
    if (1 != func_ret) {
        LOG_ERROR("Error verifying digest %d", func_ret);
        free_resources(pkey, mdctx);
        return FUNC_RET_ERROR;
    }
    FUNCTION_RETURN result;
    func_ret = EVP_DigestVerifyFinal(mdctx, buffer, len);
    if (1 != func_ret) {
        LOG_ERROR("Error verifying digest %d", func_ret);
    }
    result = (1 == func_ret ? FUNC_RET_OK : FUNC_RET_ERROR);
    free_resources(pkey, mdctx);
    return result;
}
} /* namespace license */
src/library/os/os-linux.c
@@ -22,15 +22,14 @@
 *@param uuid uuid as read in /dev/disk/by-uuid
 *@param buffer_out: unsigned char buffer[8] output buffer for result
 */
static void parseUUID(const char *uuid, unsigned char *buffer_out,
        unsigned int out_size) {
static void parseUUID(const char *uuid, unsigned char *buffer_out, unsigned int out_size) {
    size_t len;
    unsigned int i, j;
    char *hexuuid;
    unsigned char cur_character;
    //remove characters not in hex set
    // remove characters not in hex set
    len = strlen(uuid);
    hexuuid = (char*) malloc(sizeof(char) * strlen(uuid));
    hexuuid = (char *)malloc(sizeof(char) * strlen(uuid));
    memset(buffer_out, 0, out_size);
    memset(hexuuid, 0, sizeof(char) * strlen(uuid));
@@ -39,7 +38,7 @@
            hexuuid[j] = uuid[i];
            j++;
        } else {
            //skip
            // skip
            continue;
        }
    }
@@ -77,11 +76,11 @@
        tmpDrives = diskInfos;
    } else {
        maxDrives = MAX_UNITS;
        tmpDrives = (DiskInfo*) malloc(sizeof(DiskInfo) * maxDrives);
        tmpDrives = (DiskInfo *)malloc(sizeof(DiskInfo) * maxDrives);
    }
    memset(tmpDrives, 0, sizeof(DiskInfo) * maxDrives);
    statDrives = (__ino64_t*) malloc(maxDrives * sizeof(__ino64_t ));
    memset(statDrives, 0, sizeof(__ino64_t ) * maxDrives);
    statDrives = (__ino64_t *)malloc(maxDrives * sizeof(__ino64_t));
    memset(statDrives, 0, sizeof(__ino64_t) * maxDrives);
    aFile = setmntent("/proc/mounts", "r");
    if (aFile == NULL) {
@@ -93,12 +92,9 @@
    currentDrive = 0;
    while (NULL != (ent = getmntent(aFile))) {
        if ((strncmp(ent->mnt_type, "ext", 3) == 0
                || strncmp(ent->mnt_type, "xfs", 3) == 0
                || strncmp(ent->mnt_type, "vfat", 4) == 0
                || strncmp(ent->mnt_type, "ntfs", 4) == 0)
                && ent->mnt_fsname != NULL
                && strncmp(ent->mnt_fsname, "/dev/", 5) == 0) {
        if ((strncmp(ent->mnt_type, "ext", 3) == 0 || strncmp(ent->mnt_type, "xfs", 3) == 0 ||
             strncmp(ent->mnt_type, "vfat", 4) == 0 || strncmp(ent->mnt_type, "ntfs", 4) == 0) &&
            ent->mnt_fsname != NULL && strncmp(ent->mnt_fsname, "/dev/", 5) == 0) {
            if (stat(ent->mnt_fsname, &mount_stat) == 0) {
                drive_found = -1;
                for (i = 0; i < currentDrive; i++) {
@@ -108,9 +104,8 @@
                }
                if (drive_found == -1) {
                    LOG_DEBUG("mntent: %s %s %d\n", ent->mnt_fsname, ent->mnt_dir,
                            (unsigned long int)mount_stat.st_ino);
                    strncpy(tmpDrives[currentDrive].device, ent->mnt_fsname,
                            255 - 1);
                              (unsigned long int)mount_stat.st_ino);
                    strncpy(tmpDrives[currentDrive].device, ent->mnt_fsname, 255 - 1);
                    statDrives[currentDrive] = mount_stat.st_ino;
                    drive_found = currentDrive;
                    currentDrive++;
@@ -144,17 +139,12 @@
            if (stat(cur_dir, &sym_stat) == 0) {
                for (i = 0; i < currentDrive; i++) {
                    if (sym_stat.st_ino == statDrives[i]) {
                        parseUUID(dir->d_name, tmpDrives[i].disk_sn,
                                sizeof(tmpDrives[i].disk_sn));
                        parseUUID(dir->d_name, tmpDrives[i].disk_sn, sizeof(tmpDrives[i].disk_sn));
#ifdef _DEBUG
                        VALGRIND_CHECK_VALUE_IS_DEFINED(tmpDrives[i].device);
                        LOG_DEBUG("uuid %d %s %02x%02x%02x%02x\n", i,
                                tmpDrives[i].device,
                                tmpDrives[i].disk_sn[0],
                                tmpDrives[i].disk_sn[1],
                                tmpDrives[i].disk_sn[2],
                                tmpDrives[i].disk_sn[3]);
                        LOG_DEBUG("uuid %d %s %02x%02x%02x%02x\n", i, tmpDrives[i].device, tmpDrives[i].disk_sn[0],
                                  tmpDrives[i].disk_sn[1], tmpDrives[i].disk_sn[2], tmpDrives[i].disk_sn[3]);
#endif
                    }
                }
@@ -171,8 +161,7 @@
                    for (i = 0; i < currentDrive; i++) {
                        if (sym_stat.st_ino == statDrives[i]) {
                            strncpy(tmpDrives[i].label, dir->d_name, 255 - 1);
                            printf("label %d %s %s\n", i, tmpDrives[i].label,
                                    tmpDrives[i].device);
                            printf("label %d %s %s\n", i, tmpDrives[i].label, tmpDrives[i].device);
                        }
                    }
                }
@@ -202,30 +191,20 @@
    return result;
}
void os_initialize() {
    static int initialized = 0;
    if (initialized == 0) {
        initialized = 1;
        ERR_load_ERR_strings();
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
    }
}
void os_initialize() {}
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)
    );
    __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 };
    unsigned int cpuinfo[4] = {0, 0, 0, 0};
    _getCpuid(cpuinfo, 0);
    for (i = 0; i < 3; i++) {
        identifier[i * 2] = cpuinfo[i] & 0xFF;
@@ -234,11 +213,11 @@
    return FUNC_RET_OK;
}
//0=NO 1=Docker/Lxc
// 0=NO 1=Docker/Lxc
static int 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 };
    // 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};
    char proc_path[MAX_PATH], pidStr[64];
    pid_t pid = getpid();
    sprintf(pidStr, "%d", pid);
@@ -246,49 +225,47 @@
    strcat(proc_path, pidStr);
    strcat(proc_path, "/cgroup");
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;
    int result = 0;
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int result = 0;
    fp = fopen(proc_path, "r");
    if (fp == NULL) {
        return 0;
    }
    fp = fopen(proc_path, "r");
    if (fp == NULL) {
        return 0;
    }
    while ((read = getline(&line, &len, fp)) != -1 && result == 0) {
        //line[len]=0;
        //printf("Retrieved line of length %zu:\n", read);
        //printf("%s", line);
        if(strstr(line, "docker") != NULL || strstr(line, "lxc") != NULL) {
            result = 1;
        }
    }
    while ((read = getline(&line, &len, fp)) != -1 && result == 0) {
        // line[len]=0;
        // printf("Retrieved line of length %zu:\n", read);
        // printf("%s", line);
        if (strstr(line, "docker") != NULL || strstr(line, "lxc") != NULL) {
            result = 1;
        }
    }
    fclose(fp);
    if(line) free(line);
    fclose(fp);
    if (line) free(line);
    return result;
}
//0=NO 1=Docker/Lxc
static int checkLXC() {
    return (access("/var/run/systemd/container",F_OK)==0) ? 1:0;
}
// 0=NO 1=Docker/Lxc
static int checkLXC() { return (access("/var/run/systemd/container", F_OK) == 0) ? 1 : 0; }
VIRTUALIZATION getVirtualization() {
    VIRTUALIZATION result = NONE;
    int isContainer = checkContainerProc();
    if (isContainer == 1) {
        result = CONTAINER;
    } else if(checkLXC()){
    } else if (checkLXC()) {
        result = CONTAINER;
    }
    return result;
//http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
//
//bool rc = true;
    // http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
    //
    // bool rc = true;
    /*__asm__ (
     "push   %edx\n"
     "push   %ecx\n"
@@ -305,7 +282,7 @@
     "pop    %edx \n"
     );*/
    //systemd-detect-virt
    // systemd-detect-virt
    return NONE;
}
@@ -321,7 +298,7 @@
FUNCTION_RETURN getOsSpecificIdentifier(unsigned char identifier[6]) {
#if USE_DBUS
    char* dbus_id = dbus_get_local_machine_id();
    char *dbus_id = dbus_get_local_machine_id();
    if (dbus_id == NULL) {
        return FUNC_RET_ERROR;
    }
@@ -335,7 +312,7 @@
FUNCTION_RETURN getModuleName(char buffer[MAX_PATH]) {
    FUNCTION_RETURN result;
    char path[MAX_PATH] = { 0 };
    char path[MAX_PATH] = {0};
    char proc_path[MAX_PATH], pidStr[64];
    pid_t pid = getpid();
    sprintf(pidStr, "%d", pid);
src/library/os/os-win.c
@@ -47,7 +47,7 @@
    char szLogicalDrives[MAX_PATH] = { 0 };
    unsigned char buf[8] = "";
    FUNCTION_RETURN return_value;
    FUNCTION_RETURN return_value = FUNC_RET_NOT_AVAIL;
    const DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
    if (dwResult > 0 && dwResult <= MAX_PATH) {
src/library/os/os.c
File was deleted
src/library/os/os.h
@@ -77,7 +77,7 @@
VIRTUALIZATION getVirtualization();
void os_initialize();
FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64);
// FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64);
#ifdef _WIN32
#define SETENV(VAR,VAL) _putenv_s(VAR, VAL);
src/library/os/signature_verifier.h
New file
@@ -0,0 +1,20 @@
/*
 * verifier.hpp
 *
 *  Created on: Nov 16, 2019
 *      Author: GC
 */
#ifndef SRC_LIBRARY_OS_VERIFIER_HPP_
#define SRC_LIBRARY_OS_VERIFIER_HPP_
#include <string>
#include "../base/base.h"
namespace license {
FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64);
} /* namespace license */
#endif /* SRC_LIBRARY_OS_VERIFIER_HPP_ */
src/library/os/windows/signature_verifier.cpp
New file
@@ -0,0 +1,246 @@
/*
 * verifier.cpp
 *
 *  Created on: Nov 16, 2019
 *      Author: devel
 */
#include "../os.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <bcrypt.h>
#include <wincrypt.h>
#include <iphlpapi.h>
#include <windows.h>
#pragma comment(lib, "bcrypt.lib")
#include <public_key.h>
#include "../../base/logger.h"
#include "../../base/base64.h"
#include "../signature_verifier.h"
#define RSA_KEY_BITLEN 1024
namespace license {
using namespace std;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
static const void formatError(DWORD status, const char* description) {
    char msgBuffer[256];
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &msgBuffer[0],
                  sizeof(msgBuffer) - 1, nullptr);
    LOG_DEBUG("error %s : %s %h", description, msgBuffer, status);
}
#pragma pack(push, 1)
typedef struct {
    BCRYPT_RSAKEY_BLOB rsakey;
    BYTE pkExp[3];
    BYTE modulus[RSA_KEY_BITLEN / 8];
} PUBKEY_BLOB, *P_PUBKEY_BLOB;
#pragma pack(pop)
static BCRYPT_ALG_HANDLE openHashProvider() {
    DWORD status;
    BCRYPT_ALG_HANDLE hHashAlg = nullptr;
    if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hHashAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0))) {
        throw logic_error("Error opening hash provider");
    }
    return hHashAlg;
}
static DWORD hashData(BCRYPT_HASH_HANDLE& hHash, const string& data, PBYTE pbHash, DWORD hashDataLenght) {
    DWORD status;
    bool success = false;
    if (NT_SUCCESS(status = BCryptHashData(hHash, (BYTE*)data.c_str(), (ULONG)data.length(), 0))) {
        status = BCryptFinishHash(hHash, pbHash, hashDataLenght, 0);
    }
    return status;
}
static size_t read_length(uint8_t*& ptr) {
    uint8_t len = *ptr++;
    size_t result = 0;
    cout << (len & 0x80) << endl;
    if ((len & 0x80) > 0) {
        size_t blen = len & 0x7F;
        for (int i = 0; i < blen; i++) {
            result += (*(ptr++) << (i * 8));
        }
    } else {
        result = len;
    }
    return result;
}
static FUNCTION_RETURN read_sequence(uint8_t*& ptr) {
    uint8_t tag = *ptr++;
    if (tag != 0x30) {
        return FUNC_RET_ERROR;
    }
    read_length(ptr);
    return FUNC_RET_OK;
}
static FUNCTION_RETURN read_integer(uint8_t*& ptr, BYTE* location, const size_t expected_length) {
    uint8_t tag = *ptr++;
    if (tag != 0x02) {
        return FUNC_RET_ERROR;
    }
    size_t length = read_length(ptr);
    // skip the padding byte
    if (*ptr == 0) {
        length--;
        ptr++;
    }
    if (expected_length < length) {
        return FUNC_RET_ERROR;
    }
    for (int i = 0; i < length; i++) {
        location[i] = *(ptr++);
    }
    return FUNC_RET_OK;
}
static FUNCTION_RETURN readPublicKey(const BCRYPT_ALG_HANDLE sig_alg, BCRYPT_KEY_HANDLE* hKey) {
    FUNCTION_RETURN result = FUNC_RET_ERROR;
    DWORD status;
    PUBKEY_BLOB pubk;
    pubk.rsakey.Magic = BCRYPT_RSAPUBLIC_MAGIC;
    pubk.rsakey.BitLength = RSA_KEY_BITLEN;
    pubk.rsakey.cbPublicExp = 3;
    pubk.rsakey.cbModulus = RSA_KEY_BITLEN / 8;
    pubk.rsakey.cbPrime1 = 0;
    pubk.rsakey.cbPrime2 = 0;
    uint8_t pubKey[] = PUBLIC_KEY;
    uint8_t* pub_key_idx = &pubKey[0];
    read_sequence(pub_key_idx);
    read_integer(pub_key_idx, (BYTE*)&pubk.modulus, sizeof(pubk.modulus));
    read_integer(pub_key_idx, (BYTE*)&pubk.pkExp, sizeof(pubk.pkExp));
    if (NT_SUCCESS(status = BCryptImportKeyPair(sig_alg, nullptr, BCRYPT_RSAPUBLIC_BLOB, hKey, (PUCHAR)&pubk,
                                                sizeof(pubk), 0))) {
        result = FUNC_RET_OK;
    } else {
#ifdef _DEBUG
        formatError(status, "error importing public key");
#endif
    }
    return result;
}
static FUNCTION_RETURN verifyHash(const PBYTE pbHash, const DWORD hashDataLenght, const string& signatureBuffer) {
    BCRYPT_KEY_HANDLE phKey = nullptr;
    DWORD status;
    FUNCTION_RETURN result = FUNC_RET_ERROR;
    PBYTE pbSignature = nullptr;
    DWORD dwSigLen;
    BYTE* sigBlob = nullptr;
    BCRYPT_ALG_HANDLE hSignAlg = nullptr;
    // FIXME!!
    sigBlob = unbase64(signatureBuffer.c_str(), (int)signatureBuffer.size(), (int*)&dwSigLen);
    if (NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0))) {
        if ((result = readPublicKey(hSignAlg, &phKey)) == FUNC_RET_OK) {
            BCRYPT_PKCS1_PADDING_INFO paddingInfo;
            ZeroMemory(&paddingInfo, sizeof(paddingInfo));
            paddingInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM;
            if (NT_SUCCESS(status = BCryptVerifySignature(phKey, &paddingInfo, pbHash, hashDataLenght, sigBlob,
                                                          dwSigLen, BCRYPT_PAD_PKCS1))) {
                result = FUNC_RET_OK;
            } else {
                result = FUNC_RET_ERROR;
#ifdef _DEBUG
                formatError(status, "error verifying signature");
#endif
            }
        } else {
            LOG_DEBUG("Error reading public key");
        }
    } else {
        result = FUNC_RET_NOT_AVAIL;
#ifdef _DEBUG
        formatError(status, "error opening RSA provider");
#endif
    }
    if (phKey != nullptr) {
        BCryptDestroyKey(phKey);
    }
    if (hSignAlg != nullptr) {
        BCryptCloseAlgorithmProvider(hSignAlg, 0);
    }
    if (sigBlob) {
        free(sigBlob);
    }
    return result;
}
FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64) {
    BCRYPT_HASH_HANDLE hHash = nullptr;
    PBYTE pbHashObject = nullptr, pbHashData = nullptr;
    FUNCTION_RETURN result = FUNC_RET_ERROR;
    const HANDLE hProcessHeap = GetProcessHeap();
    // BCRYPT_ALG_HANDLE sig_alg = openSignatureProvider();
    BCRYPT_ALG_HANDLE hash_alg = openHashProvider();
    DWORD status;
    // calculate the size of the buffer to hold the hash object
    DWORD cbData = 0, cbHashObject = 0;
    // and the size to keep the hashed data
    DWORD cbHashDataLenght = 0;
    if (NT_SUCCESS(status = BCryptGetProperty(hash_alg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD),
                                              &cbData, 0)) &&
        NT_SUCCESS(status = BCryptGetProperty(hash_alg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHashDataLenght, sizeof(DWORD),
                                              &cbData, 0))) {
        // allocate the hash object on the heap
        pbHashObject = (PBYTE)HeapAlloc(hProcessHeap, 0, cbHashObject);
        pbHashData = (PBYTE)HeapAlloc(hProcessHeap, 0, cbHashDataLenght);
        if (NULL != pbHashObject && nullptr != pbHashData) {
            if (NT_SUCCESS(status = BCryptCreateHash(hash_alg, &hHash, pbHashObject, cbHashObject, NULL, 0, 0))) {
                if (NT_SUCCESS(status = hashData(hHash, stringToVerify, pbHashData, cbHashDataLenght))) {
                    result = verifyHash(pbHashData, cbHashDataLenght, signatureB64);
                } else {
                    result = FUNC_RET_NOT_AVAIL;
#ifdef _DEBUG
                    formatError(status, "error hashing data");
#endif
                }
            } else {
                result = FUNC_RET_NOT_AVAIL;
#ifdef _DEBUG
                formatError(status, "error creating hash");
#endif
            }
        } else {
            result = FUNC_RET_BUFFER_TOO_SMALL;
            LOG_DEBUG("Error allocating memory");
        }
    } else {
        result = FUNC_RET_NOT_AVAIL;
#ifdef _DEBUG
        formatError(status, "**** Error returned by BCryptGetProperty");
#endif
    }
    if (hHash) {
        BCryptDestroyHash(hHash);
    }
    if (pbHashObject) {
        HeapFree(hProcessHeap, 0, pbHashObject);
    }
    if (pbHashData) {
        HeapFree(hProcessHeap, 0, pbHashData);
    }
    if (hash_alg != nullptr) {
        BCryptCloseAlgorithmProvider(hash_alg, 0);
    }
    return result;
}
} /* namespace license */
src/library/pc-identifiers.c
@@ -23,18 +23,15 @@
#endif
#endif
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, bool use_label);
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label);
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, int use_mac);
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac);
static FUNCTION_RETURN generate_default_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers) {
static FUNCTION_RETURN generate_default_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers) {
    size_t adapter_num, disk_num;
    FUNCTION_RETURN result_adapterInfos, result_diskinfos, function_return;
    unsigned int caller_identifiers, i, j, k, array_index;
    DiskInfo * diskInfoPtr;
    DiskInfo *diskInfoPtr;
    OsAdapterInfo *adapterInfoPtr;
    if (identifiers == NULL || *num_identifiers == 0) {
@@ -49,20 +46,17 @@
        *num_identifiers = disk_num * adapter_num;
        function_return = FUNC_RET_OK;
    } else {
        adapterInfoPtr = (OsAdapterInfo*) malloc(
                (*num_identifiers) * sizeof(OsAdapterInfo));
        adapterInfoPtr = (OsAdapterInfo *)malloc((*num_identifiers) * sizeof(OsAdapterInfo));
        adapter_num = *num_identifiers;
        result_adapterInfos = getAdapterInfos(adapterInfoPtr, &adapter_num);
        if (result_adapterInfos != FUNC_RET_OK
                && result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_adapterInfos != FUNC_RET_OK && result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
            free(adapterInfoPtr);
            return generate_disk_pc_id(identifiers, num_identifiers, false);
        }
        diskInfoPtr = (DiskInfo*) malloc((*num_identifiers) * sizeof(DiskInfo));
        diskInfoPtr = (DiskInfo *)malloc((*num_identifiers) * sizeof(DiskInfo));
        disk_num = *num_identifiers;
        result_diskinfos = getDiskInfos(diskInfoPtr, &disk_num);
        if (result_diskinfos != FUNC_RET_OK
                && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
            free(diskInfoPtr);
            free(adapterInfoPtr);
            return generate_ethernet_pc_id(identifiers, num_identifiers, true);
@@ -75,19 +69,18 @@
                array_index = i * adapter_num + j;
                if (array_index >= caller_identifiers) {
                    function_return = FUNC_RET_BUFFER_TOO_SMALL;
                    //sweet memories...
                    // sweet memories...
                    goto end;
                }
                for (k = 0; k < 6; k++)
                    identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2]
                            ^ adapterInfoPtr[j].mac_address[k + 2];
                    identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2] ^ adapterInfoPtr[j].mac_address[k + 2];
            }
        }
end:
    end:
#ifdef _MSC_VER
        *num_identifiers = min(*num_identifiers, adapter_num * disk_num);
        *num_identifiers = min(*num_identifiers, adapter_num * disk_num);
#else
        *num_identifiers = cmin(*num_identifiers, adapter_num * disk_num);
        *num_identifiers = cmin(*num_identifiers, adapter_num * disk_num);
#endif
        free(diskInfoPtr);
        free(adapterInfoPtr);
@@ -95,8 +88,7 @@
    return function_return;
}
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, int use_mac) {
static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac) {
    FUNCTION_RETURN result_adapterInfos;
    unsigned int j, k;
    OsAdapterInfo *adapterInfos;
@@ -104,56 +96,50 @@
    if (identifiers == NULL || *num_identifiers == 0) {
        result_adapterInfos = getAdapterInfos(NULL, &adapters);
        if (result_adapterInfos == FUNC_RET_OK
                || result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL) {
        if (result_adapterInfos == FUNC_RET_OK || result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL) {
            *num_identifiers = adapters;
            result_adapterInfos = FUNC_RET_OK;
        }
    } else {
        defined_adapters = adapters = *num_identifiers;
        adapterInfos = (OsAdapterInfo*) malloc(
                adapters * sizeof(OsAdapterInfo));
        adapterInfos = (OsAdapterInfo *)malloc(adapters * sizeof(OsAdapterInfo));
        result_adapterInfos = getAdapterInfos(adapterInfos, &adapters);
        if (result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL
                || result_adapterInfos == FUNC_RET_OK) {
        if (result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL || result_adapterInfos == FUNC_RET_OK) {
            for (j = 0; j < adapters; j++) {
                for (k = 0; k < 6; k++)
                    if (use_mac) {
                        identifiers[j][k] = adapterInfos[j].mac_address[k + 2];
                    } else {
                        //use ip
                        // use ip
                        if (k < 4) {
                            identifiers[j][k] = adapterInfos[j].ipv4_address[k];
                        } else {
                            //padding
                            // padding
                            identifiers[j][k] = 42;
                        }
                    }
            }
            result_adapterInfos = (
                    adapters > defined_adapters ?
                            FUNC_RET_BUFFER_TOO_SMALL : FUNC_RET_OK);
            result_adapterInfos = (adapters > defined_adapters ? FUNC_RET_BUFFER_TOO_SMALL : FUNC_RET_OK);
        }
        free(adapterInfos);
    }
    return result_adapterInfos;
}
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier * identifiers,
        unsigned int * num_identifiers, bool use_label) {
static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label) {
    size_t disk_num, available_disk_info = 0;
    FUNCTION_RETURN result_diskinfos;
    unsigned int i, j;
    int defined_identifiers;
    char firstChar;
    DiskInfo * diskInfos;
    DiskInfo *diskInfos;
    result_diskinfos = getDiskInfos(NULL, &disk_num);
    if (result_diskinfos != FUNC_RET_OK) {
        return result_diskinfos;
    }
    diskInfos = (DiskInfo*) malloc(disk_num * sizeof(DiskInfo));
    memset(diskInfos,0,disk_num * sizeof(DiskInfo));
    diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
    memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
    result_diskinfos = getDiskInfos(diskInfos, &disk_num);
    if (result_diskinfos != FUNC_RET_OK) {
        free(diskInfos);
@@ -178,15 +164,13 @@
    for (i = 0; i < disk_num; i++) {
        if (use_label) {
            if (diskInfos[i].label[0] != 0) {
                memset(identifiers[j], 0, sizeof(PcIdentifier)); //!!!!!!!
                strncpy((char*)identifiers[j], diskInfos[i].label,
                        sizeof(PcIdentifier));
                memset(identifiers[j], 0, sizeof(PcIdentifier));  //!!!!!!!
                strncpy((char *)identifiers[j], diskInfos[i].label, sizeof(PcIdentifier));
                j++;
            }
        } else {
            if (diskInfos[i].disk_sn[0] != 0) {
                memcpy(identifiers[j], &diskInfos[i].disk_sn[2],
                        sizeof(PcIdentifier));
                memcpy(identifiers[j], &diskInfos[i].disk_sn[2], sizeof(PcIdentifier));
                j++;
            }
        }
@@ -211,43 +195,42 @@
 * @return
 */
FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers,
        unsigned int * array_size, IDENTIFICATION_STRATEGY strategy) {
FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, IDENTIFICATION_STRATEGY strategy) {
    FUNCTION_RETURN result;
    unsigned int i, j;
    const unsigned int original_array_size = *array_size;
    unsigned char strategy_num;
    switch (strategy) {
    case DEFAULT:
        result = generate_default_pc_id(identifiers, array_size);
        break;
    case ETHERNET:
        result = generate_ethernet_pc_id(identifiers, array_size, true);
        break;
    case IP_ADDRESS:
        result = generate_ethernet_pc_id(identifiers, array_size, false);
        break;
    case DISK_NUM:
        result = generate_disk_pc_id(identifiers, array_size, false);
        break;
    case DISK_LABEL:
        result = generate_disk_pc_id(identifiers, array_size, true);
        break;
    default:
        return FUNC_RET_ERROR;
        case 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
            // encode strategy in the first three bits of the pc_identifier
            identifiers[i][0] = (identifiers[i][0] & 15) | strategy_num;
        }
        //fill array if larger
        // fill array if larger
        for (i = *array_size; i < original_array_size; i++) {
            identifiers[i][0] = STRATEGY_UNKNOWN << 5;
            for (j = 1; j < sizeof(PcIdentifier); j++) {
                identifiers[i][j] = 42; //padding
                identifiers[i][j] = 42;  // padding
            }
        }
    }
@@ -255,36 +238,33 @@
}
char *MakeCRC(char *BitString) {
    static char Res[3];                                 // CRC Result
    static char Res[3];  // CRC Result
    char CRC[2];
    int i;
    char DoInvert;
    for (i = 0; i < 2; ++i)
        CRC[i] = 0;                    // Init before calculation
    for (i = 0; i < 2; ++i) CRC[i] = 0;  // Init before calculation
    for (i = 0; i < strlen(BitString); ++i) {
        DoInvert = ('1' == BitString[i]) ^ CRC[1];         // XOR required?
        DoInvert = ('1' == BitString[i]) ^ CRC[1];  // XOR required?
        CRC[1] = CRC[0];
        CRC[0] = DoInvert;
    }
    for (i = 0; i < 2; ++i)
        Res[1 - i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
    Res[2] = 0;                                         // Set string terminator
    for (i = 0; i < 2; ++i) Res[1 - i] = CRC[i] ? '1' : '0';  // Convert binary to ASCII
    Res[2] = 0;  // Set string terminator
    return (Res);
}
FUNCTION_RETURN encode_pc_id(PcIdentifier identifier1, PcIdentifier identifier2,
        PcSignature pc_identifier_out) {
    //TODO base62 encoding, now uses base64
FUNCTION_RETURN encode_pc_id(PcIdentifier identifier1, PcIdentifier identifier2, PcSignature pc_identifier_out) {
    // TODO base62 encoding, now uses base64
    PcIdentifier concat_identifiers[2];
    char* b64_data = NULL;
    char *b64_data = NULL;
    int b64_size = 0;
    const size_t concatIdentifiersSize = sizeof(PcIdentifier) * 2;
    //concat_identifiers = (PcIdentifier *) malloc(concatIdentifiersSize);
    // concat_identifiers = (PcIdentifier *) malloc(concatIdentifiersSize);
    memcpy(&concat_identifiers[0], identifier1, sizeof(PcIdentifier));
    memcpy(&concat_identifiers[1], identifier2, sizeof(PcIdentifier));
    b64_data = base64(concat_identifiers, concatIdentifiersSize, &b64_size);
@@ -292,21 +272,17 @@
        free(b64_data);
        return FUNC_RET_BUFFER_TOO_SMALL;
    }
    sprintf(pc_identifier_out, "%.4s-%.4s-%.4s-%.4s", &b64_data[0],
            &b64_data[4], &b64_data[8], &b64_data[12]);
    //free(concat_identifiers);
    sprintf(pc_identifier_out, "%.4s-%.4s-%.4s-%.4s", &b64_data[0], &b64_data[4], &b64_data[8], &b64_data[12]);
    // free(concat_identifiers);
    free(b64_data);
    return FUNC_RET_OK;
}
FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) {
    return FUNC_RET_OK;
}
FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) { return FUNC_RET_OK; }
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out,
        IDENTIFICATION_STRATEGY strategy) {
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, IDENTIFICATION_STRATEGY strategy) {
    FUNCTION_RETURN result;
    PcIdentifier* identifiers;
    PcIdentifier *identifiers;
    unsigned int req_buffer_size = 0;
    result = generate_pc_id(NULL, &req_buffer_size, strategy);
    if (result != FUNC_RET_OK) {
@@ -316,8 +292,7 @@
        return FUNC_RET_ERROR;
    }
    req_buffer_size = req_buffer_size < 2 ? 2 : req_buffer_size;
    identifiers = (PcIdentifier *) malloc(
            sizeof(PcIdentifier) * req_buffer_size);
    identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * req_buffer_size);
    memset(identifiers, 0, sizeof(PcIdentifier) * req_buffer_size);
    result = generate_pc_id(identifiers, &req_buffer_size, strategy);
    if (result != FUNC_RET_OK) {
@@ -343,40 +318,38 @@
 * @param str_code: the code in the string format XXXX-XXXX-XXXX-XXXX
 * @return
 */
static FUNCTION_RETURN decode_pc_id(PcIdentifier identifier1_out,
        PcIdentifier identifier2_out, PcSignature pc_signature_in) {
    //TODO base62 encoding, now uses base64
static FUNCTION_RETURN decode_pc_id(PcIdentifier identifier1_out, PcIdentifier identifier2_out,
                                    PcSignature pc_signature_in) {
    // TODO base62 encoding, now uses base64
    unsigned char * concat_identifiers = NULL;
    unsigned char *concat_identifiers = NULL;
    char base64ids[17];
    int identifiers_size;
    sscanf(pc_signature_in, "%4s-%4s-%4s-%4s", &base64ids[0], &base64ids[4],
            &base64ids[8], &base64ids[12]);
    sscanf(pc_signature_in, "%4s-%4s-%4s-%4s", &base64ids[0], &base64ids[4], &base64ids[8], &base64ids[12]);
    concat_identifiers = unbase64(base64ids, 16, &identifiers_size);
    if (identifiers_size > sizeof(PcIdentifier) * 2) {
        free(concat_identifiers);
        return FUNC_RET_BUFFER_TOO_SMALL;
    }
    memcpy(identifier1_out, concat_identifiers, sizeof(PcIdentifier));
    memcpy(identifier2_out, concat_identifiers + sizeof(PcIdentifier),
            sizeof(PcIdentifier));
    memcpy(identifier2_out, concat_identifiers + sizeof(PcIdentifier), sizeof(PcIdentifier));
    free(concat_identifiers);
    return FUNC_RET_OK;
}
static IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
    return (IDENTIFICATION_STRATEGY) identifier[0] >> 5;
    return (IDENTIFICATION_STRATEGY)identifier[0] >> 5;
}
EVENT_TYPE validate_pc_signature(PcSignature str_code) {
    PcIdentifier user_identifiers[2];
    FUNCTION_RETURN result;
    IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
    PcIdentifier* calculated_identifiers = NULL;
    PcIdentifier *calculated_identifiers = NULL;
    unsigned int calc_identifiers_size = 0;
    int i = 0, j = 0;
    //bool found;
    // bool found;
#ifdef _DEBUG
    printf("Comparing pc identifiers: \n");
#endif
@@ -385,14 +358,14 @@
        return result;
    }
    previous_strategy_id = STRATEGY_UNKNOWN;
    //found = false;
    // found = false;
    for (i = 0; i < 2; i++) {
        current_strategy_id = strategy_from_pc_id(user_identifiers[i]);
        if (current_strategy_id == STRATEGY_UNKNOWN && previous_strategy_id == STRATEGY_UNKNOWN && i==1) {
        if (current_strategy_id == STRATEGY_UNKNOWN && previous_strategy_id == STRATEGY_UNKNOWN && i == 1) {
            free(calculated_identifiers);
            printf("Comparing pc identifiers: %d %d %d %s\n",current_strategy_id,previous_strategy_id,i, str_code);
            printf("Comparing pc identifiers: %d %d %d %s\n", current_strategy_id, previous_strategy_id, i, str_code);
            return LICENSE_MALFORMED;
        } else if (current_strategy_id == STRATEGY_UNKNOWN ){
        } else if (current_strategy_id == STRATEGY_UNKNOWN) {
            continue;
        }
        if (current_strategy_id != previous_strategy_id) {
@@ -401,23 +374,22 @@
            }
            previous_strategy_id = current_strategy_id;
            generate_pc_id(NULL, &calc_identifiers_size, current_strategy_id);
            calculated_identifiers = (PcIdentifier *) malloc(
                    sizeof(PcIdentifier) * calc_identifiers_size);
            calculated_identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * calc_identifiers_size);
            memset(calculated_identifiers, 0, sizeof(PcIdentifier) * calc_identifiers_size);
            generate_pc_id(calculated_identifiers, &calc_identifiers_size,
                    current_strategy_id);
            generate_pc_id(calculated_identifiers, &calc_identifiers_size, current_strategy_id);
        }
        //maybe skip the byte 0
        // maybe skip the byte 0
        for (j = 0; j < calc_identifiers_size; j++) {
#ifdef _DEBUG
            printf("generated id: %02x%02x%02x%02x%02x%02x index %d, user_supplied id %02x%02x%02x%02x%02x%02x idx: %d\n",
                    calculated_identifiers[j][0], calculated_identifiers[j][1], calculated_identifiers[j][2],
                    calculated_identifiers[j][3], calculated_identifiers[j][4], calculated_identifiers[j][5], j,
                    user_identifiers[i][0], user_identifiers[i][1], user_identifiers[i][2], user_identifiers[i][3], user_identifiers[i][4], user_identifiers[i][5], i);
            printf(
                "generated id: %02x%02x%02x%02x%02x%02x index %d, user_supplied id %02x%02x%02x%02x%02x%02x idx: %d\n",
                calculated_identifiers[j][0], calculated_identifiers[j][1], calculated_identifiers[j][2],
                calculated_identifiers[j][3], calculated_identifiers[j][4], calculated_identifiers[j][5], j,
                user_identifiers[i][0], user_identifiers[i][1], user_identifiers[i][2], user_identifiers[i][3],
                user_identifiers[i][4], user_identifiers[i][5], i);
#endif
            if (!memcmp(user_identifiers[i], calculated_identifiers[j],
                    sizeof(PcIdentifier))) {
            if (!memcmp(user_identifiers[i], calculated_identifiers[j], sizeof(PcIdentifier))) {
                free(calculated_identifiers);
                return LICENSE_OK;
            }
src/library/pc-identifiers.h
@@ -2,12 +2,13 @@
 * pc-identifiers.h
 *
 *  Created on: Apr 16, 2014
 *
 *
 */
#ifndef PC_IDENTIFIERS_H_
#define PC_IDENTIFIERS_H_
#include "api/datatypes.h"
#include <licensecc/datatypes.h>
#include "base/base.h"
#ifdef __cplusplus
@@ -15,7 +16,7 @@
#endif
typedef unsigned char PcIdentifier[6];
typedef char PcSignature[21];
typedef char PcSignature[PC_IDENTIFIER_SIZE + 1];
FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers, unsigned int * array_size,
        IDENTIFICATION_STRATEGY strategy);
@@ -29,8 +30,7 @@
 * @param strategy
 * @return
 */
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out,
        IDENTIFICATION_STRATEGY strategy);
FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, IDENTIFICATION_STRATEGY strategy);
#ifdef __cplusplus
}
src/templates/licensecc_properties.h.in
New file
@@ -0,0 +1,17 @@
#ifndef BUILD_PROPERTIES_H_
#define BUILD_PROPERTIES_H_
#define LCC_PROJECT_NAME "@LCC_PROJECT_NAME@"
//License retrieval configuration
#define FIND_LICENSE_NEAR_MODULE true
#define FIND_LICENSE_WITH_ENV_VAR false
#define LICENSE_FILE_EXTENSION ".lic"
#define LICENSE_LOCATION_ENV_VAR "LICENSE_LOCATION"
#define LICENSE_DATA_ENV_VAR "LICENSE_DATA"
//Internal data structures limits
#define MAX_LICENSE_LENGTH 256*1024
#endif
src/templates/licensecc_properties_test.h.in
New file
@@ -0,0 +1,27 @@
#ifndef BUILD_PROPERTIES_TEST_H_
#define BUILD_PROPERTIES_TEST_H_
//Build locations and parameters for tests
#define PROJECT_BINARY_DIR "@CMAKE_BINARY_DIR@"
#define PROJECT_SRC_DIR "@CMAKE_CURRENT_LIST_DIR@"
#define PROJECT_BASE_DIR "@CMAKE_SOURCE_DIR@"
#define PROJECT_TEST_SRC_DIR "@CMAKE_SOURCE_DIR@/test"
#define PROJECT_TEST_TEMP_DIR "@CMAKE_BINARY_DIR@/Testing/Temporary"
#define BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#define LCC_EXE "$<TARGET_FILE:license_generator::lcc>"
#define LCC_TEST_LICENSES_PROJECT "@CMAKE_BINARY_DIR@/Testing/Temporary/@LCC_PROJECT_NAME@"
#define LCC_LICENSES_BASE LCC_TEST_LICENSES_PROJECT "/licenses"
#define LCC_PROJECTS_BASE_DIR "@LCC_PROJECTS_BASE_DIR@"
#define LCC_PROJECT_PRIVATE_KEY "@LCC_PROJECT_PRIVATE_KEY@"
/*
 * command line parameters
 */
#define PARAM_BASE64 "base64"
#define PARAM_LICENSE_OUTPUT "output-file-name"
#define PARAM_PRODUCT_NAME "product-name"
#define PARAM_PROJECT_FOLDER "project-folder"
#define PARAM_PRIMARY_KEY "primary-key"
#endif
src/templates/public_key.inja
New file
@@ -0,0 +1,10 @@
#ifndef PUBLIC_KEY_H_
#define PUBLIC_KEY_H_
#define PRODUCT_NAME {{ product_name }}
#define PUBLIC_KEY {\
{%for i in public_key%}{% if loop.index1 > 1 %},{% endif %}{{ i }}{%endfor%}\
}
#define PUBLIC_KEY_LEN {{ public_key_len }}
#endif
src/tools/CMakeLists.txt
File was deleted
src/tools/base_lib/CMakeLists.txt
File was deleted
src/tools/base_lib/CryptoHelper.cpp
File was deleted
src/tools/base_lib/CryptoHelper.h
File was deleted
src/tools/base_lib/README.TXT
File was deleted
src/tools/base_lib/linux/CryptoHelperLinux.cpp
File was deleted
src/tools/base_lib/linux/CryptoHelperLinux.h
File was deleted
src/tools/base_lib/win/CryptoHelperWindows.cpp
File was deleted
src/tools/base_lib/win/CryptoHelperWindows.h
File was deleted
src/tools/bootstrap/CMakeLists.txt
File was deleted
src/tools/bootstrap/bootstrap.cpp
File was deleted
src/tools/license-generator/.gitignore
File was deleted
src/tools/license-generator/CMakeLists.txt
File was deleted
src/tools/license-generator/license-generator-main.cpp
File was deleted
src/tools/license-generator/license-generator.cpp
File was deleted
src/tools/license-generator/license-generator.h
File was deleted
src/tools/pc-identifier/CMakeLists.txt
File was deleted
test/CMakeLists.txt
@@ -1,8 +1,17 @@
#if we're here boost has been found
include_directories(${Boost_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(-DBOOST_ALL_NO_LIB) #Disable Boost Microsoft magic, all dependencies are handled by cmake
add_definitions(-DBOOST_LIB_DIAGNOSTIC) #Check it is really disabled
include_directories(${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
link_directories ( ${Boost_LIBRARY_DIR} )
configure_file (
    "${CMAKE_CURRENT_SOURCE_DIR}/../src/templates/licensecc_properties_test.h.in"
    "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp"
)
file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/include/$<CONFIG>/licensecc_properties_test.h"
        INPUT "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp")
include_directories ( ${CMAKE_BINARY_DIR}/include/$<CONFIG> )
add_subdirectory(library)
add_subdirectory(license-generator)
add_subdirectory(functional)
test/functional/CMakeLists.txt
@@ -4,7 +4,7 @@
target_link_libraries(
    license_generator_snippet
     license_generator_lib
     ${Boost_LIBRARIES}
)
add_executable(
@@ -32,6 +32,19 @@
)
add_executable(
 test_signature_verifier
 signature_verifier_test.cpp
)
target_link_libraries(
 test_signature_verifier
 licensecc_static
 license_generator_snippet
 ${Boost_LIBRARIES}
)
add_executable(
 test_volid
 volid_test.cpp
)
@@ -44,15 +57,9 @@
)
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING)
#binfmt_misc doesn't work in my system :(
    ADD_TEST(NAME test_standard_license COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    ADD_TEST(NAME test_date COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    ADD_TEST(NAME test_volid COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ELSE()
    ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
    ADD_TEST(NAME test_volid COMMAND test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ENDIF()
ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_signature_verifier COMMAND test_signature_verifier WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_volid COMMAND test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
test/functional/date_test.cpp
@@ -1,11 +1,12 @@
#define BOOST_TEST_MODULE date_test
#define BOOST_TEST_MODULE test_date
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include <build_properties.h>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
@@ -13,44 +14,43 @@
using namespace license;
using namespace std;
namespace license {
namespace test {
BOOST_AUTO_TEST_CASE( license_not_expired ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/not_expired.lic");
BOOST_AUTO_TEST_CASE(license_not_expired) {
    vector<string> extraArgs;
    extraArgs.push_back("-e");
    extraArgs.push_back("2050-10-10");
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("not_expired.lic", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
    BOOST_CHECK_GT(license.days_left, 0);
}
BOOST_AUTO_TEST_CASE( license_expired ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/expired.lic");
    remove(licLocation.c_str());
BOOST_AUTO_TEST_CASE(license_expired) {
    vector<string> extraArgs;
    extraArgs.push_back("-e");
    extraArgs.push_back("2013-10-10");
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("expired", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = nullptr;
    BOOST_TEST_MESSAGE("before acquire license");
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, PRODUCT_EXPIRED);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
    BOOST_CHECK_EQUAL(license.days_left, 0);
}
}
}  // namespace test
}  // namespace license
test/functional/generate-license.cpp
@@ -6,36 +6,81 @@
 */
#include <boost/test/unit_test.hpp>
#include <build_properties.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <sstream>
#include <fstream>
#include <iostream>
#include "../../src/tools/license-generator/license-generator.h"
#include <licensecc_properties_test.h>
#include "../../src/library/base/base.h"
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
void generate_license(const string& fname, const vector<string>& other_args) {
    remove(fname.c_str());
    const int argc = 4+other_args.size();
    const char** argv = new const char*[argc + 1];
    unsigned int i=0;
    argv[i++] = "lic-generator";
    for(;i<=other_args.size();i++){
        argv[i] = other_args[i-1].c_str();
namespace license {
namespace test {
string generate_license(const string& license_name, const vector<string>& other_args) {
    fs::path lcc_exe(LCC_EXE);
    BOOST_REQUIRE_MESSAGE(fs::is_regular_file(lcc_exe), "License generator not found: " LCC_EXE);
    fs::path licenses_base(LCC_LICENSES_BASE);
    if (!fs::exists(licenses_base)) {
        BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string());
    }
    argv[i++] = "-o";
    argv[i++] = fname.c_str();
    argv[i++] = "TEST";
    const int retCode = LicenseGenerator::generateLicense(argc, argv);
    delete[] (argv);
    const string license_name_norm = boost::ends_with(license_name, ".lic") ? license_name : (license_name + ".lic");
    const fs::path license_fname(licenses_base / license_name_norm);
    const string license_fname_s = license_fname.string();
    remove(license_fname_s.c_str());
    stringstream ss;
    ss << LCC_EXE << " license issue";
    ss << " --" PARAM_PRIMARY_KEY " " << LCC_PROJECT_PRIVATE_KEY;
    ss << " --" PARAM_LICENSE_OUTPUT " " << license_fname_s;
    ss << " --" PARAM_PROJECT_FOLDER " " << LCC_TEST_LICENSES_PROJECT;
    for (int i = 0; i < other_args.size(); i++) {
        ss << " " << other_args[i];
    }
    cout << "executing :" << ss.str() << endl;
    const int retCode = std::system(ss.str().c_str());
    BOOST_CHECK_EQUAL(retCode, 0);
    BOOST_ASSERT(fs::exists(fname));
    BOOST_ASSERT(fs::exists(license_fname));
    CSimpleIniA ini;
    const SI_Error rc = ini.LoadFile(fname.c_str());
    BOOST_CHECK_GE(rc,0);
    const int sectionSize = ini.GetSectionSize("TEST");
    BOOST_CHECK_GT(sectionSize,0);
    const SI_Error rc = ini.LoadFile(license_fname.c_str());
    BOOST_CHECK_GE(rc, 0);
    const int sectionSize = ini.GetSectionSize("DEFAULT");
    BOOST_CHECK_GT(sectionSize, 0);
    return license_fname.string();
}
string sign_data(const string& data, const string& test_name) {
    fs::path lcc_exe(LCC_EXE);
    BOOST_REQUIRE_MESSAGE(fs::is_regular_file(lcc_exe), "License generator not found: " LCC_EXE);
    fs::path licenses_base(LCC_LICENSES_BASE);
    if (!fs::exists(licenses_base)) {
        BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string());
    }
    const fs::path outputFile(fs::path(PROJECT_TEST_TEMP_DIR) / (test_name + ".tmp"));
    const string output_file_s = outputFile.string();
    remove(output_file_s.c_str());
    stringstream ss;
    ss << LCC_EXE << " test sign";
    ss << " --" PARAM_PRIMARY_KEY " " << LCC_PROJECT_PRIVATE_KEY;
    ss << " -d " << data;
    ss << " -o " << output_file_s;
    cout << "executing :" << ss.str() << endl;
    const int retCode = std::system(ss.str().c_str());
    BOOST_CHECK_EQUAL(retCode, 0);
    BOOST_ASSERT(fs::exists(outputFile));
    std::ifstream ifs(output_file_s.c_str());
    std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
    return content;
}
}  // namespace test
}  // namespace license
test/functional/generate-license.h
@@ -1,5 +1,11 @@
#include<string>
#include<vector>
#include <string>
#include <vector>
using namespace std;
void generate_license(const string& fname, const vector<string>& other_args);
namespace license {
namespace test {
std::string generate_license(const std::string& fname, const std::vector<std::string>& other_args);
std::string sign_data(const std::string& data, const std::string& test_name);
}  // namespace test
}  // namespace license
test/functional/hijiaking_test.cpp
@@ -5,7 +5,7 @@
#include <boost/test/unit_test.hpp>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
test/functional/signature_verifier_test.cpp
New file
@@ -0,0 +1,46 @@
/*
 * LicenseVerifier_test.cpp
 *
 *  Created on: Nov 17, 2019
 *      Author: GC
 */
#define BOOST_TEST_MODULE test_signature_verifier
#include <boost/test/unit_test.hpp>
#include <licensecc_properties_test.h>
#include <licensecc_properties.h>
#include "../../src/library/os/signature_verifier.h"
#include "generate-license.h"
namespace license {
namespace test {
using namespace std;
BOOST_AUTO_TEST_CASE(verify_signature_ok) {
    const string test_data("test_data");
    const string signature = sign_data(test_data, string("verify_signature"));
    FUNCTION_RETURN result = license::verify_signature(test_data, signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_OK, "signature verified");
}
BOOST_AUTO_TEST_CASE(verify_signature_data_mismatch) {
    const string test_data("test_data");
    const string signature = sign_data(test_data, string("verify_signature"));
    FUNCTION_RETURN result = license::verify_signature(string("other data"), signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
}
BOOST_AUTO_TEST_CASE(verify_signature_modified) {
    const string test_data("test_data");
    string signature = sign_data(test_data, string("verify_signature"));
    signature[2] = signature[2] + 1;
    FUNCTION_RETURN result = license::verify_signature(test_data, signature);
    BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
}
}  // namespace test
} /* namespace license */
test/functional/standard-license_test.cpp
@@ -3,29 +3,32 @@
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <build_properties.h>
#include <licensecc/licensecc.h>
#include <licensecc_properties_test.h>
#include <licensecc_properties.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/base/FileUtils.hpp"
namespace license {
namespace test {
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
BOOST_AUTO_TEST_CASE( standard_lic_file ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_license.lic");
/**
 * Test a generic license with no expiry neither client id.
 */
BOOST_AUTO_TEST_CASE(test_generic_license) {
    const vector<string> extraArgs;
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("standard_license", extraArgs);
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = nullptr;
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
@@ -34,36 +37,38 @@
/**
 * Pass the license data to the application.
 */
BOOST_AUTO_TEST_CASE( b64_environment_variable ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_env_license.lic");
    const vector<string> extraArgs;
    generate_license(licLocation, extraArgs);
    const string licensestr(license::get_file_contents(licLocation.c_str(), MAX_LICENSE_LENGTH));
    /* */
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = nullptr;
    licenseLocation.licenseData = licensestr.c_str();
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
}
BOOST_AUTO_TEST_CASE( pc_identifier ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/pc_identifier.lic");
    const vector<string> extraArgs = { "-s", "Jaaa-aaaa-MG9F-ZhB1" };
    generate_license(licLocation, extraArgs);
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
            &license);
    BOOST_CHECK_EQUAL(result, IDENTIFIERS_MISMATCH);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
// BOOST_AUTO_TEST_CASE( b64_environment_variable ) {
//    const string licLocation(PROJECT_TEST_TEMP_DIR "/standard_env_license.lic");
//    const vector<string> extraArgs;
//    generate_license(licLocation, extraArgs);
//    const string licensestr(license::get_file_contents(licLocation.c_str(), MAX_LICENSE_LENGTH));
//    /* */
//    LicenseInfo license;
//    LicenseLocation licenseLocation;
//    licenseLocation.licenseFileLocation = nullptr;
//    licenseLocation.licenseData = licensestr.c_str();
//    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
//            &license);
//    BOOST_CHECK_EQUAL(result, LICENSE_OK);
//    BOOST_CHECK_EQUAL(license.has_expiry, false);
//    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
//}
//
// BOOST_AUTO_TEST_CASE( pc_identifier ) {
//    const string licLocation(PROJECT_TEST_TEMP_DIR "/pc_identifier.lic");
//    const vector<string> extraArgs = { "-s", "Jaaa-aaaa-MG9F-ZhB1" };
//    generate_license(licLocation, extraArgs);
//
//    LicenseInfo license;
//    LicenseLocation licenseLocation;
//    licenseLocation.licenseFileLocation = licLocation.c_str();
//    licenseLocation.licenseData = "";
//    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation,
//            &license);
//    BOOST_CHECK_EQUAL(result, IDENTIFIERS_MISMATCH);
//    BOOST_CHECK_EQUAL(license.has_expiry, false);
//    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
//}
}
}
}  // namespace license
test/functional/volid_test.cpp
@@ -2,25 +2,30 @@
#include <boost/test/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <cstring>
#include "../../src/tools/license-generator/license-generator.h"
#include "../../src/library/api/license++.h"
#include <build_properties.h>
#include <boost/filesystem.hpp>
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/licensecc.h>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/pc-identifiers.h"
#include "../../src/library/os/os.h"
#include "generate-license.h"
namespace fs = boost::filesystem;
using namespace license;
using namespace std;
namespace license {
namespace test {
BOOST_AUTO_TEST_CASE( default_volid_lic_file ) {
    const string licLocation(PROJECT_TEST_TEMP_DIR "/volid_license.lic");
    PcSignature identifier_out;
    const IDENTIFICATION_STRATEGY strategy = IDENTIFICATION_STRATEGY::ETHERNET;
    const IDENTIFICATION_STRATEGY strategy = IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET;
    BOOST_TEST_CHECKPOINT("Before generate");
    const FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out,
            strategy);
@@ -31,13 +36,13 @@
    extraArgs.push_back("-s");
    extraArgs.push_back(identifier_out);
    BOOST_TEST_CHECKPOINT("Before generate license");
    generate_license(licLocation, extraArgs);
    const string licLocation = generate_license("volid_license", extraArgs);
    LicenseInfo license;
    LicenseLocation licenseLocation;
    licenseLocation.licenseFileLocation = licLocation.c_str();
    licenseLocation.licenseData = "";
    const EVENT_TYPE result = acquire_license("TEST", &licenseLocation, &license);
    const EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &license);
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, false);
    BOOST_CHECK_EQUAL(license.linked_to_pc, true);
@@ -67,7 +72,7 @@
    size_t disk_num;
    getDiskInfos(NULL, &disk_num);
    if (disk_num >0) {
        strategies = { DEFAULT, DISK_NUM, DISK_LABEL };
        strategies = {STRATEGY_DEFAULT, STRATEGY_DISK_NUM, STRATEGY_DISK_LABEL};
    } else {
        BOOST_TEST_CHECKPOINT("if no disk default strategy fails see #49");
        //strategies = { DEFAULT };
@@ -76,7 +81,7 @@
    size_t adapters;
    getAdapterInfos(nullptr, &adapters);
    if(adapters > 0){
        strategies.push_back(ETHERNET);
        strategies.push_back(STRATEGY_ETHERNET);
    }
    size_t num_strategies = strategies.size();
@@ -136,3 +141,5 @@
    }
}
}  // namespace test
}  // namespace license
test/library/CMakeLists.txt
@@ -9,12 +9,7 @@
 ${Boost_LIBRARIES}
)
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING)
#binfmt_misc doesn't work in my system :(
    ADD_TEST(NAME test_license_reader COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_license_reader)
ELSE()
    ADD_TEST(NAME test_license_reader COMMAND test_license_reader)
ENDIF()
ADD_TEST(NAME test_license_reader COMMAND test_license_reader)
IF(WIN32)
#test windows
@@ -26,13 +21,12 @@
    target_link_libraries(
         test_os_linux
         os
         licensecc_static
         ${Boost_LIBRARIES}
    )
    ADD_TEST(NAME test_os_linux COMMAND test_os_linux)
ENDIF(WIN32)
### LicenseLocator tests
add_executable(
@@ -42,16 +36,11 @@
target_link_libraries(
 test_license_locator
 locators
 licensecc_static
 ${Boost_LIBRARIES}
)
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING)
#binfmt_misc doesn't work in my system :(
    ADD_TEST(NAME test_license_locator COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_license_locator)
ELSE()
    ADD_TEST(NAME test_license_locator COMMAND test_license_locator)
ENDIF()
ADD_TEST(NAME test_license_locator COMMAND test_license_locator)
### LicenseLocator tests
add_executable(
@@ -65,8 +54,4 @@
 ${Boost_LIBRARIES}
)
IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING)
    ADD_TEST(NAME test_event_registry COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/test_event_registry)
ELSE()
    ADD_TEST(NAME test_event_registry COMMAND test_event_registry)
ENDIF()
ADD_TEST(NAME test_event_registry COMMAND test_event_registry)
test/library/EventRegistry_test.cpp
@@ -13,8 +13,6 @@
#include <stdlib.h>
#include <cstdio>
#include <build_properties.h>
#include "../../src/library/base/EventRegistry.h"
namespace test {
@@ -26,7 +24,7 @@
 * The error reported is for the license that advanced most in the validation process
 *
 */
BOOST_AUTO_TEST_CASE( test_most_advanced_license_error ) {
BOOST_AUTO_TEST_CASE(test_most_advanced_license_error) {
    EventRegistry er;
    er.addEvent(LICENSE_SPECIFIED, "lic2");
    er.addEvent(LICENSE_FOUND, "lic1");
@@ -38,4 +36,4 @@
    BOOST_CHECK_MESSAGE(LICENSE_CORRUPTED == event->event_type, "Error is for LICENSE_CORRUPTED");
}
}  //namespace test
}  // namespace test
test/library/LicenseLocator_test.cpp
@@ -11,7 +11,8 @@
#include <boost/test/unit_test.hpp>
#include <stdlib.h>
#include <build_properties.h>
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include "../../src/library/os/os.h"
#include "../../src/library/base/EventRegistry.h"
@@ -26,32 +27,30 @@
using namespace std;
using namespace boost::filesystem;
static boost::optional<path> find_file(const path& dir_path, const path& file_name) {
static boost::optional<path> find_file(const path &dir_path, const path &file_name) {
    const recursive_directory_iterator end;
    const auto it = find_if(recursive_directory_iterator(dir_path), end,
        [&file_name](const directory_entry& e) {
            return e.path().filename() == file_name;
        });
                            [&file_name](const directory_entry &e) { return e.path().filename() == file_name; });
    return it == end ? boost::optional<path>() : it->path();
}
/*****************************************************************************
 * Application Folder tests
 *****************************************************************************/
BOOST_AUTO_TEST_CASE( read_license_near_module ) {
BOOST_AUTO_TEST_CASE(read_license_near_module) {
    const string testExeFolder = PROJECT_BINARY_DIR "/test/library";
    bool exeFileFound = false;
    string referenceExeFileName;
    string referenceLicenseFileName;
    //Verify we're pointing the correct executable, in windows isn't clear where it's built
    // Verify we're pointing the correct executable, in windows isn't clear where it's built
#ifdef _WIN32
    boost::optional<path> exeLocation(find_file(path(testExeFolder), path(BOOST_TEST_MODULE ".exe")));
    exeFileFound = exeLocation.has_value();
    if (exeFileFound) {
        referenceExeFileName = exeLocation.get().string();
        referenceLicenseFileName = referenceExeFileName.replace(referenceExeFileName.find(BOOST_TEST_MODULE ".exe"),
            string(BOOST_TEST_MODULE ".exe").size(), BOOST_TEST_MODULE ".lic");
        referenceLicenseFileName =
            referenceExeFileName.replace(referenceExeFileName.find(BOOST_TEST_MODULE ".exe"),
                                         string(BOOST_TEST_MODULE ".exe").size(), BOOST_TEST_MODULE ".lic");
    }
#else
    referenceExeFileName = testExeFolder + "/" + BOOST_TEST_MODULE;
@@ -61,7 +60,7 @@
#endif
    BOOST_WARN_MESSAGE(!exeFileFound, "File [" + referenceExeFileName + "] NOT found");
    if (exeFileFound) {
        //copy test license near module
        // copy test license near module
        std::ifstream src(MOCK_LICENSE, std::ios::binary);
        std::ofstream dst(referenceLicenseFileName, std::ios::binary);
        dst << src.rdbuf();
@@ -73,15 +72,12 @@
        BOOST_CHECK(registry.isGood());
        BOOST_REQUIRE_EQUAL(1, licenseInfos.size());
        string currentLocation = licenseInfos[0];
        BOOST_CHECK_MESSAGE(equivalent(path(referenceLicenseFileName),path(currentLocation)),
            "file " +currentLocation + "found at expected location");
        string licenseRealContent = applicationFolder.retrieve_license_content(
            currentLocation);
        BOOST_CHECK_MESSAGE(equivalent(path(referenceLicenseFileName), path(currentLocation)),
                            "file " + currentLocation + "found at expected location");
        string licenseRealContent = applicationFolder.retrieve_license_content(currentLocation);
        src.seekg(0, ios::beg);
        std::string referenceContent((std::istreambuf_iterator<char>(src)),
            std::istreambuf_iterator<char>());
        BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0,
            "File content is same");
        std::string referenceContent((std::istreambuf_iterator<char>(src)), std::istreambuf_iterator<char>());
        BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, "File content is same");
        remove(referenceLicenseFileName.c_str());
    }
}
@@ -90,126 +86,101 @@
 * External_Definition tests
 *****************************************************************************/
BOOST_AUTO_TEST_CASE( external_definition ) {
    //an application can define multiple license locations separated by ';'
    const char *applicationDefinedString =
    MOCK_LICENSE ";/this/one/doesnt/exist";
BOOST_AUTO_TEST_CASE(external_definition) {
    // an application can define multiple license locations separated by ';'
    const char *applicationDefinedString = MOCK_LICENSE ";/this/one/doesnt/exist";
    //read test license
    // read test license
    std::ifstream src(MOCK_LICENSE, std::ios::binary);
    std::string referenceContent((std::istreambuf_iterator<char>(src)),
            std::istreambuf_iterator<char>());
    std::string referenceContent((std::istreambuf_iterator<char>(src)), std::istreambuf_iterator<char>());
    license::EventRegistry registry;
    const LicenseLocation licLocation={applicationDefinedString,nullptr};
    const LicenseLocation licLocation = {applicationDefinedString, nullptr};
    ExternalDefinition externalDefinition(&licLocation);
    vector<string> licenseInfos = externalDefinition.license_locations(registry);
    BOOST_CHECK(registry.isGood());
    BOOST_CHECK_EQUAL(1, licenseInfos.size());
    string currentLocation = licenseInfos[0];
    BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0,
            "file found at expected location");
    string licenseRealContent = externalDefinition.retrieve_license_content(
            currentLocation);
    BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0,
            "File content is same");
    BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0, "file found at expected location");
    string licenseRealContent = externalDefinition.retrieve_license_content(currentLocation);
    BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, "File content is same");
}
/**
 * The license file doesn't exist. Check that the locator reports the right error
 */
BOOST_AUTO_TEST_CASE( external_definition_not_found ) {
BOOST_AUTO_TEST_CASE(external_definition_not_found) {
    const char *applicationDefinedString = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
    license::EventRegistry registry;
    const LicenseLocation licLocation = { applicationDefinedString,nullptr };
    const LicenseLocation licLocation = {applicationDefinedString, nullptr};
    ExternalDefinition externalDefinition(&licLocation);
    vector<string> licenseInfos = externalDefinition.license_locations(registry);
    BOOST_CHECK_MESSAGE(registry.isGood(),
            "No fatal error for now, only warnings");
    BOOST_CHECK_MESSAGE(registry.isGood(), "No fatal error for now, only warnings");
    registry.turnWarningsIntoErrors();
    BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected");
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_CHECK_MESSAGE(
            registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND,
            "Error detected");
    BOOST_CHECK_MESSAGE(registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND, "Error detected");
}
/*****************************************************************************
 * EnvironmentVarLocation tests
 *****************************************************************************/
BOOST_AUTO_TEST_CASE( environment_var_location ) {
    //an application can define multiple license locations separated by ';'
    const char *environment_variable_value =
    MOCK_LICENSE ";/this/one/doesnt/exist";
BOOST_AUTO_TEST_CASE(environment_var_location) {
    // an application can define multiple license locations separated by ';'
    const char *environment_variable_value = MOCK_LICENSE ";/this/one/doesnt/exist";
#ifdef _WIN32
    _putenv_s(LICENSE_LOCATION_ENV_VAR, environment_variable_value);
#else
    setenv(LICENSE_LOCATION_ENV_VAR, environment_variable_value, 1);
#endif
    //read test license
    // read test license
    std::ifstream src(MOCK_LICENSE, std::ios::binary);
    std::string referenceContent((std::istreambuf_iterator<char>(src)),
            std::istreambuf_iterator<char>());
    std::string referenceContent((std::istreambuf_iterator<char>(src)), std::istreambuf_iterator<char>());
    license::EventRegistry registry;
    EnvironmentVarLocation envVarLocationStrategy;
    vector<string> licenseInfos = envVarLocationStrategy.license_locations(
            registry);
    vector<string> licenseInfos = envVarLocationStrategy.license_locations(registry);
    BOOST_CHECK(registry.isGood());
    BOOST_CHECK_EQUAL(1, licenseInfos.size());
    string currentLocation = licenseInfos[0];
    BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0,
            "file found at expected location");
    string licenseRealContent = envVarLocationStrategy.retrieve_license_content(
            currentLocation);
    BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0,
            "File content is same");
    BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0, "file found at expected location");
    string licenseRealContent = envVarLocationStrategy.retrieve_license_content(currentLocation);
    BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, "File content is same");
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
}
/**
 * The license file doesn't exist. Check that the locator reports the right error
 */
BOOST_AUTO_TEST_CASE( environment_var_location_not_found ) {
    const char *environment_variable_value =
    PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
    SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value);
BOOST_AUTO_TEST_CASE(environment_var_location_not_found) {
    const char *environment_variable_value = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
    SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value);
    license::EventRegistry registry;
    EnvironmentVarLocation envVarLocationStrategy;
    vector<string> licenseInfos = envVarLocationStrategy.license_locations(
            registry);
    BOOST_CHECK_MESSAGE(registry.isGood(),
            "No fatal error for now, only warnings");
    vector<string> licenseInfos = envVarLocationStrategy.license_locations(registry);
    BOOST_CHECK_MESSAGE(registry.isGood(), "No fatal error for now, only warnings");
    registry.turnWarningsIntoErrors();
    BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected");
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_CHECK_MESSAGE(
            registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND,
            "Error detected");
    BOOST_CHECK_MESSAGE(registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND, "Error detected");
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
}
/**
 * The license file doesn't exist. Check that the locator reports the right error
 */
BOOST_AUTO_TEST_CASE( environment_var_location_not_defined ) {
BOOST_AUTO_TEST_CASE(environment_var_location_not_defined) {
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
    license::EventRegistry registry;
    EnvironmentVarLocation environmentVarLocation;
    vector<string> licenseInfos = environmentVarLocation.license_locations(
            registry);
    vector<string> licenseInfos = environmentVarLocation.license_locations(registry);
    BOOST_CHECK_MESSAGE(registry.isGood(),
            "No fatal error for now, only warnings");
    BOOST_CHECK_MESSAGE(registry.isGood(), "No fatal error for now, only warnings");
    registry.turnWarningsIntoErrors();
    BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected");
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_CHECK_MESSAGE(
            registry.getLastFailure()->event_type
                    == ENVIRONMENT_VARIABLE_NOT_DEFINED, "Error detected");
    BOOST_CHECK_MESSAGE(registry.getLastFailure()->event_type == ENVIRONMENT_VARIABLE_NOT_DEFINED, "Error detected");
}
}  //namespace test
}  // namespace test
test/library/LicenseReader_test.cpp
@@ -5,29 +5,29 @@
#include <vector>
#include <stdlib.h>
#include "../../src/library/api/datatypes.h"
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include <licensecc/datatypes.h>
#include "../../src/library/base/EventRegistry.h"
#include "../../src/library/os/os.h"
#include <build_properties.h>
#include "../../src/library/locate/LocatorFactory.hpp"
#include "../../src/library/LicenseReader.hpp"
namespace license {
namespace test {
using namespace license;
using namespace std;
/**
 * Read license at fixed location
 * Read license at application provided location
 */
BOOST_AUTO_TEST_CASE( read_single_file ) {
BOOST_AUTO_TEST_CASE(read_single_file) {
    const char *licLocation = PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    const LicenseLocation location = { licLocation, nullptr };
    const LicenseLocation location = {licLocation, nullptr};
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PrODUCT",
            licenseInfos);
    const EventRegistry registry = licenseReader.readLicenses("PrODUCT", licenseInfos);
    BOOST_CHECK(registry.isGood());
    BOOST_CHECK_EQUAL(1, licenseInfos.size());
}
@@ -35,76 +35,74 @@
/**
 * Test the error return if the product code is not found in the license
 */
BOOST_AUTO_TEST_CASE( product_not_licensed ) {
    const char *licLocation =
    PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    const LicenseLocation location = { licLocation, nullptr };
BOOST_AUTO_TEST_CASE(product_not_licensed) {
    const char *licLocation = PROJECT_TEST_SRC_DIR "/library/test_reader.ini";
    const LicenseLocation location = {licLocation, nullptr};
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT-NOT",
            licenseInfos);
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT-NOT", licenseInfos);
    BOOST_CHECK(!registry.isGood());
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_ASSERT(registry.getLastFailure()!=NULL);
    BOOST_CHECK_EQUAL(PRODUCT_NOT_LICENSED,
            registry.getLastFailure()->event_type);
    BOOST_ASSERT(registry.getLastFailure() != NULL);
    BOOST_CHECK_EQUAL(PRODUCT_NOT_LICENSED, registry.getLastFailure()->event_type);
}
/**
 * Test the error code if the license file is specified but doesn't exists
 */
BOOST_AUTO_TEST_CASE( file_not_found ) {
BOOST_AUTO_TEST_CASE(file_not_found) {
    const char *licLocation = PROJECT_TEST_SRC_DIR "/library/not_found.ini";
    //const char * envName = "MYVAR";
    const LicenseLocation location = { licLocation, nullptr };
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(false);
    const LicenseLocation location = {licLocation, nullptr};
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT",
            licenseInfos);
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
    BOOST_CHECK(!registry.isGood());
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_ASSERT(registry.getLastFailure()!=NULL);
    BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND,
            registry.getLastFailure()->event_type);
    BOOST_ASSERT(registry.getLastFailure() != NULL);
    BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND, registry.getLastFailure()->event_type);
}
/**
 * Test the error code if the license default environment variable isn't specified
 */
BOOST_AUTO_TEST_CASE( env_var_not_defined ) {
BOOST_AUTO_TEST_CASE(env_var_not_defined) {
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
    const LicenseLocation location = { nullptr, nullptr };
    const LicenseLocation location = {nullptr, nullptr};
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(true);
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT",
            licenseInfos);
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
    BOOST_CHECK(!registry.isGood());
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_ASSERT(registry.getLastFailure()!=NULL);
    BOOST_CHECK_EQUAL(ENVIRONMENT_VARIABLE_NOT_DEFINED,
            registry.getLastFailure()->event_type);
    BOOST_ASSERT(registry.getLastFailure() != NULL);
    BOOST_CHECK_MESSAGE((ENVIRONMENT_VARIABLE_NOT_DEFINED == registry.getLastFailure()->event_type),
                        "error as expected");
}
/**
 * Test the error code if the license default environment variable is
 * specified but points to a non existent file.
 */
BOOST_AUTO_TEST_CASE( env_var_point_to_wrong_file ) {
    const char *environment_variable_value =
    PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
BOOST_AUTO_TEST_CASE(env_var_point_to_wrong_file) {
    const char *environment_variable_value = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
    SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value)
    locate::LocatorFactory::find_license_near_module(false);
    locate::LocatorFactory::find_license_with_env_var(true);
    const LicenseLocation location = { nullptr, nullptr };
    const LicenseLocation location = {nullptr, nullptr};
    LicenseReader licenseReader(&location);
    vector<FullLicenseInfo> licenseInfos;
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT",
            licenseInfos);
    const EventRegistry registry = licenseReader.readLicenses("PRODUCT", licenseInfos);
    cout << registry << endl;
    BOOST_CHECK(!registry.isGood());
    BOOST_CHECK_EQUAL(0, licenseInfos.size());
    BOOST_ASSERT(registry.getLastFailure()!=NULL);
    BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND,
            registry.getLastFailure()->event_type);
    BOOST_ASSERT(registry.getLastFailure() != NULL);
    BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND, registry.getLastFailure()->event_type);
    UNSETENV(LICENSE_LOCATION_ENV_VAR);
}
} /* namespace test*/
}  // namespace test
}  // namespace license
test/library/Os_Linux_test.cpp
@@ -1,73 +1,70 @@
#define BOOST_TEST_MODULE os_linux_test
#include <boost/test/unit_test.hpp>
#include "../../src/library/os/os.h"
#include <build_properties.h>
#include <string>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <licensecc_properties.h>
#include <licensecc_properties_test.h>
#include "../../src/library/os/os.h"
using namespace std;
BOOST_AUTO_TEST_CASE( read_disk_id ) {
BOOST_AUTO_TEST_CASE(read_disk_id) {
    VIRTUALIZATION virt = getVirtualization();
    if(virt == NONE || virt == VM) {
        DiskInfo * diskInfos = NULL;
    if (virt == NONE || virt == VM) {
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;
        FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size);
        BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
        BOOST_CHECK_GT(disk_info_size, 0);
        diskInfos = (DiskInfo*) malloc(sizeof(DiskInfo) * disk_info_size);
        diskInfos = (DiskInfo *)malloc(sizeof(DiskInfo) * disk_info_size);
        result = getDiskInfos(diskInfos, &disk_info_size);
        BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
        BOOST_CHECK_GT(strlen(diskInfos[0].device), 0);
        BOOST_CHECK_GT(strlen(diskInfos[0].label), 0);
        BOOST_CHECK_GT(diskInfos[0].disk_sn[0], 0);
        free(diskInfos);
    } else if(virt == CONTAINER){
        //docker or lxc diskInfo is not meaningful
        DiskInfo * diskInfos = NULL;
    } else if (virt == CONTAINER) {
        // docker or lxc diskInfo is not meaningful
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;
        FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size);
        BOOST_CHECK_EQUAL(result, FUNC_RET_NOT_AVAIL);
    }
}
BOOST_AUTO_TEST_CASE( read_network_adapters ) {
    OsAdapterInfo * adapter_info = NULL;
BOOST_AUTO_TEST_CASE(read_network_adapters) {
    OsAdapterInfo *adapter_info = NULL;
    size_t adapter_info_size = 0;
    FUNCTION_RETURN result = getAdapterInfos(NULL, &adapter_info_size);
    BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
    BOOST_CHECK_GT(adapter_info_size, 0);
    adapter_info = (OsAdapterInfo*) malloc(
            sizeof(OsAdapterInfo) * adapter_info_size);
    adapter_info = (OsAdapterInfo *)malloc(sizeof(OsAdapterInfo) * adapter_info_size);
    result = getAdapterInfos(adapter_info, &adapter_info_size);
    BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
    for (size_t i = 0; i < adapter_info_size; i++) {
        cout << "Interface found: " << string(adapter_info[i].description)
                << endl;
        cout << "Interface found: " << string(adapter_info[i].description) << endl;
        BOOST_CHECK_GT(strlen(adapter_info[i].description), 0);
        //lo mac address is always 0 but it has ip
        //other interfaces may not be connected
        // lo mac address is always 0 but it has ip
        // other interfaces may not be connected
        if (string(adapter_info[i].description) == "lo") {
            BOOST_CHECK_NE(adapter_info[i].ipv4_address[0], 0);
        } else {
            bool mac_is_0 = true;
            for(int j=0;j<6;j++){
                mac_is_0 = mac_is_0 && (adapter_info[i].mac_address[j]==0);
            for (int j = 0; j < 6; j++) {
                mac_is_0 = mac_is_0 && (adapter_info[i].mac_address[j] == 0);
            }
            BOOST_CHECK_MESSAGE( !mac_is_0,
                    "Mac address for interface " << adapter_info[i].description << " is 0");
            BOOST_CHECK_MESSAGE(!mac_is_0, "Mac address for interface " << adapter_info[i].description << " is 0");
        }
    }
    free(adapter_info);
}
BOOST_AUTO_TEST_CASE( get_cpuid ) {
    BOOST_CHECK_EQUAL(1, 1);
}
BOOST_AUTO_TEST_CASE(get_cpuid) { BOOST_CHECK_EQUAL(1, 1); }
//To test if virtualization is detected correctly define an env variable VIRT_ENV
//otherwise the test is skipped
BOOST_AUTO_TEST_CASE( test_virtualization ) {
// To test if virtualization is detected correctly define an env variable VIRT_ENV
// otherwise the test is skipped
BOOST_AUTO_TEST_CASE(test_virtualization) {
    const char *env = getenv("VIRT_ENV");
    if (env != NULL) {
        if (strcmp(env, "CONTAINER") == 0) {
@@ -83,4 +80,3 @@
        }
    }
}
test/library/license_verifier_test.cpp
New file
@@ -0,0 +1,10 @@
/*
 * LicenseVerifier_test.cpp
 *
 *  Created on: Nov 20, 2019
 *      Author: devel
 */
#include "LicenseVerifier.hpp"
namespace license {} /* namespace license */
test/library/test_reader.ini
@@ -1,3 +1,3 @@
[PRODUCT]
license_version = 100
license_signature = qAz
lic_ver = 200
sig = qAz
test/license-generator/CMakeLists.txt
File was deleted
test/license-generator/license-generator_test.cpp
File was deleted