From e2c2e9dc1a9a7f7eafff371cdf29bb731015238c Mon Sep 17 00:00:00 2001 From: Gabriele Contini <gcontini@users.noreply.github.com> Date: 周六, 14 12月 2019 13:56:41 +0800 Subject: [PATCH] Merge pull request #69 from open-license-manager/feature/issue_licenses_42 --- src/library/locate/EnvironmentVarData.hpp | 10 src/cmake/licensecc-config.cmake | 38 scripts/windows_download_boost.bat | 0 src/library/pc-identifiers.h | 10 src/library/limits/license_verifier.cpp | 100 + src/library/os/os-linux.c | 135 - src/library/os/os.h | 2 src/templates/licensecc_properties_test.h.in | 27 CMakeLists.txt | 238 ++- src/library/locate/EnvironmentVarLocation.hpp | 9 src/library/locate/LocatorStrategy.cpp | 9 src/library/pc-identifiers.c | 200 +-- test/functional/generate-license.h | 14 test/functional/CMakeLists.txt | 29 extern/license-generator | 1 src/library/os/openssl/signature_verifier.cpp | 107 + test/functional/hijiaking_test.cpp | 2 src/library/locate/LocatorFactory.hpp | 9 src/library/locate/ApplicationFolder.cpp | 22 src/templates/licensecc_properties.h.in | 17 test/library/LicenseLocator_test.cpp | 125 - CONTRIBUTING.md | 70 test/functional/volid_test.cpp | 27 README.md | 73 extern/.gitkeep | 0 src/library/licensecc.cpp | 109 + test/library/license_verifier_test.cpp | 10 src/library/LicenseReader.cpp | 224 --- src/library/locate/CMakeLists.txt | 23 test/library/Os_Linux_test.cpp | 56 src/library/locate/ExternalDefinition.cpp | 3 .gitignore | 7 .gitmodules | 4 src/library/limits/license_verifier.hpp | 29 test/functional/generate-license.cpp | 89 + .clang-format | 12 cmake/utilities.cmake | 0 src/library/locate/EnvironmentVarData.cpp | 26 src/library/base/base64.c | 267 ++-- src/library/locate/LocatorStrategy.hpp | 28 src/library/os/CMakeLists.txt | 33 src/library/base/CMakeLists.txt | 5 test/functional/signature_verifier_test.cpp | 46 test/library/CMakeLists.txt | 25 build/.gitkeep | 0 src/library/base/EventRegistry.h | 20 src/library/base/base.h | 34 src/library/os/os-win.c | 2 src/library/locate/ApplicationFolder.hpp | 6 .travis.yml | 68 src/library/locate/LocatorFactory.cpp | 39 test/functional/standard-license_test.cpp | 83 cmake/toolchain-ubuntu-mingw64.cmake | 0 cmake/Findlcc.cmake | 85 + test/CMakeLists.txt | 15 test/library/EventRegistry_test.cpp | 6 src/library/base/StringUtils.cpp | 12 src/library/CMakeLists.txt | 42 src/templates/public_key.inja | 10 src/library/base/logger.c | 4 test/functional/date_test.cpp | 32 src/library/base/EventRegistry.cpp | 63 test/library/LicenseReader_test.cpp | 88 cmake/target_arch.cmake | 0 src/library/base/logger.h | 1 /dev/null | 37 src/library/locate/EnvironmentVarLocation.cpp | 25 src/library/LicenseReader.hpp | 44 src/library/base/StringUtils.h | 10 projects/.gitkeep | 1 src/library/os/windows/signature_verifier.cpp | 246 ++++ src/CMakeLists.txt | 7 include/licensecc/datatypes.h | 133 ++ src/library/os/signature_verifier.h | 20 test/library/test_reader.ini | 4 include/licensecc/licensecc.h | 10 76 files changed, 2,100 insertions(+), 1,317 deletions(-) diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..84ec03b --- /dev/null +++ b/.clang-format @@ -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 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7165b6c..6f0748c 100644 --- a/.gitignore +++ b/.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 + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3372773 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "license-generator"] + path = extern/license-generator + url = https://github.com/open-license-manager/lcc-license-generator.git + branch = develop diff --git a/.travis.yml b/.travis.yml index 8c0456d..ff9cbd1 100644 --- a/.travis.yml +++ b/.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 - + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 411c2c2..a7543e6 100644 --- a/CMakeLists.txt +++ b/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}) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 32db051..df84870 100644 --- a/CONTRIBUTING.md +++ b/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. \ No newline at end of file diff --git a/README.md b/README.md index 72838b4..c10ad1c 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,67 @@ # Open License Manager -[](https://travis-ci.org/open-license-manager/open-license-manager) -[](http://github.com/badges/stability-badges)[](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). + +[](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) +[](http://github.com/badges/stability-badges) +[](https://opensource.org/licenses/BSD-3-Clause) +[](https://travis-ci.org/open-license-manager/open-license-manager) +[](https://www.codacy.com/manual/gcontini/open-license-manager?utm_source=github.com&utm_medium=referral&utm_content=open-license-manager/open-license-manager&utm_campaign=Badge_Grade) +[](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. diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/build/.gitkeep diff --git a/cmake/Findlcc.cmake b/cmake/Findlcc.cmake new file mode 100644 index 0000000..bc994eb --- /dev/null +++ b/cmake/Findlcc.cmake @@ -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) + + diff --git a/modules/target_arch.cmake b/cmake/target_arch.cmake similarity index 100% rename from modules/target_arch.cmake rename to cmake/target_arch.cmake diff --git a/modules/toolchain-ubuntu-mingw64.cmake b/cmake/toolchain-ubuntu-mingw64.cmake similarity index 100% rename from modules/toolchain-ubuntu-mingw64.cmake rename to cmake/toolchain-ubuntu-mingw64.cmake diff --git a/modules/utilities.cmake b/cmake/utilities.cmake similarity index 100% rename from modules/utilities.cmake rename to cmake/utilities.cmake diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt deleted file mode 100644 index 87016f4..0000000 --- a/example/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -cmake_minimum_required(VERSION 2.8.11) - -link_directories ( "${CMAKE_CURRENT_SOURCE_DIR}/../install/lib" ) -include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/../install/include" ) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - -if(MSVC) -SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib ) -else(MSVC) -set(CMAKE_FIND_LIBRARY_SUFFIXES .a .so) -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s -Wl,--exclude-libs,liblicensecc_static.a") -find_package(OpenSSL REQUIRED) -endif(MSVC) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - -add_executable(example example.cpp) - -target_link_libraries(example licensecc_static os base tools_base) - -if(NOT MSVC) -target_link_libraries(example crypto pthread dl z) -endif(NOT MSVC) - -if(MINGW) -target_link_libraries(example iphlpapi) -endif(MINGW) diff --git a/example/example.cpp b/example/example.cpp deleted file mode 100644 index 2379d6a..0000000 --- a/example/example.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include <iostream> -#include <map> -#include "api/license++.h" -#include "pc-identifiers.h" - -using namespace std; - -int main(int argc, char *argv[]) { - map<EVENT_TYPE, string> stringByEventType; - stringByEventType[LICENSE_OK] = "OK "; - stringByEventType[LICENSE_FILE_NOT_FOUND] = "license file not found "; - stringByEventType[LICENSE_SERVER_NOT_FOUND] = "license server can't be contacted "; - stringByEventType[ENVIRONMENT_VARIABLE_NOT_DEFINED] = "environment variable not defined "; - stringByEventType[FILE_FORMAT_NOT_RECOGNIZED] = "license file has invalid format (not .ini file) "; - stringByEventType[LICENSE_MALFORMED] = "some mandatory field are missing, or data can't be fully read. "; - stringByEventType[PRODUCT_NOT_LICENSED] = "this product was not licensed "; - stringByEventType[PRODUCT_EXPIRED] = "license expired "; - stringByEventType[LICENSE_CORRUPTED] = "license signature didn't match with current license "; - stringByEventType[IDENTIFIERS_MISMATCH] = "Calculated identifier and the one provided in license didn't match"; - - LicenseInfo licenseInfo; - EVENT_TYPE result = acquire_license("example", nullptr, &licenseInfo); - - if (result == LICENSE_OK) { - //for this example we want to link the license to the execution hardware. - if (licenseInfo.linked_to_pc) { - cout - << "No client signature in license file, generate license with -s <id>"; - result = IDENTIFIERS_MISMATCH; - } else { - cout << "license OK" << endl; - } - } - if (result != LICENSE_OK) { - cout << "license ERROR :" << endl; - cout << " " << stringByEventType[result].c_str() << endl; - if (result == IDENTIFIERS_MISMATCH) { - PcSignature signature; - FUNCTION_RETURN generate_ok = generate_user_pc_signature(signature, - DEFAULT); - cout << "the pc signature is :" << endl; - cout << " " << signature << endl; - } - } - - return result; -} diff --git a/extern/.gitkeep b/extern/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/extern/.gitkeep diff --git a/extern/license-generator b/extern/license-generator new file mode 160000 index 0000000..c40c095 --- /dev/null +++ b/extern/license-generator @@ -0,0 +1 @@ +Subproject commit c40c0951e77c012a1c4043182c88ae5fe185efea diff --git a/include/licensecc/datatypes.h b/include/licensecc/datatypes.h new file mode 100644 index 0000000..7a95afb --- /dev/null +++ b/include/licensecc/datatypes.h @@ -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 diff --git a/src/library/api/license++.h b/include/licensecc/licensecc.h similarity index 82% rename from src/library/api/license++.h rename to include/licensecc/licensecc.h index ef1fbb6..353eba8 100644 --- a/src/library/api/license++.h +++ b/include/licensecc/licensecc.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. diff --git a/projects/.gitkeep b/projects/.gitkeep new file mode 100644 index 0000000..32f64f4 --- /dev/null +++ b/projects/.gitkeep @@ -0,0 +1 @@ +t \ No newline at end of file diff --git a/windows_download_boost.bat b/scripts/windows_download_boost.bat similarity index 100% rename from windows_download_boost.bat rename to scripts/windows_download_boost.bat diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1fb9b67..02e47aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,7 @@ add_subdirectory("library") -add_subdirectory("tools") - \ No newline at end of file +#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") \ No newline at end of file diff --git a/src/build_properties.h.in b/src/build_properties.h.in deleted file mode 100644 index a15ef5e..0000000 --- a/src/build_properties.h.in +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BUILD_PROPERTIES_H_ -#define BUILD_PROPERTIES_H_ - -//License retrieval configuration -#define FIND_LICENSE_NEAR_MODULE 1 -#define FIND_LICENSE_WITH_ENV_VAR 1 - -#define LICENSE_LOCATION_ENV_VAR "LICENSE_LOCATION" -#define LICENSE_DATA_ENV_VAR "LICENSE_DATA" - -//Internal data structures limits -#define MAX_LICENSE_LENGTH 256*1024 - -//Build locations and parameters -#define PROJECT_INT_VERSION @LICENSECC_INT_VERSION@ -#define PROJECT_VERSION "@LICENSECC_VERSION@" -#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@" - -#endif diff --git a/src/cmake/licensecc-config.cmake b/src/cmake/licensecc-config.cmake new file mode 100644 index 0000000..92909bb --- /dev/null +++ b/src/cmake/licensecc-config.cmake @@ -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() \ No newline at end of file diff --git a/src/library/.gitignore b/src/library/.gitignore deleted file mode 100644 index e9abf22..0000000 --- a/src/library/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/Licensepp.h diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt index 0589736..a9f75d8 100644 --- a/src/library/CMakeLists.txt +++ b/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) diff --git a/src/library/LicenseReader.cpp b/src/library/LicenseReader.cpp index 84de09d..7390f3c 100644 --- a/src/library/LicenseReader.cpp +++ b/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 diff --git a/src/library/LicenseReader.hpp b/src/library/LicenseReader.hpp index 661bd05..bad939e 100644 --- a/src/library/LicenseReader.hpp +++ b/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_ */ diff --git a/src/library/api/datatypes.h b/src/library/api/datatypes.h deleted file mode 100644 index 439f477..0000000 --- a/src/library/api/datatypes.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef DATATYPES_H_ -#define DATATYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -//definition of size_t -#include <stdlib.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 PC_IDENTIFIER_SIZE 18 -#define PROPRIETARY_DATA_SIZE 16 -#define AUDIT_EVENT_NUM 5 - -#define LICENESE_INT_VERSION 110 -#define LICENSEPP_VERSION "1.1.0" - -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; - -typedef struct { - /** - * Detailed reason of success/failure. Reasons for a failure can be - * multiple (for instance, license expired and signature not verified). - * Only the last AUDIT_EVENT_NUM are reported. - */ - AuditEvent status[AUDIT_EVENT_NUM]; - /** - * Eventual expiration date of the software, - * can be '\0' if the software don't expire - * */ - char expiry_date[11]; - unsigned int days_left;bool has_expiry;bool linked_to_pc; - LICENSE_TYPE license_type; // Local or Remote - /* A string of character inserted into the license understood - * by the calling application. - * '\0' if the application didn't specify one */ - char proprietary_data[PROPRIETARY_DATA_SIZE + 1]; - int license_version; //license file version -} LicenseInfo; - -/** - * Enum to select a specific pc identification_strategy. DEFAULT Should be used - * in most cases. - */ -typedef enum { - DEFAULT, - ETHERNET, - IP_ADDRESS, - DISK_NUM, - DISK_LABEL, - PLATFORM_SPECIFIC, - STRATEGY_UNKNOWN -} IDENTIFICATION_STRATEGY; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/library/base/.gitignore b/src/library/base/.gitignore deleted file mode 100644 index 28988b3..0000000 --- a/src/library/base/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/public-key.h diff --git a/src/library/base/CMakeLists.txt b/src/library/base/CMakeLists.txt index 0a61fdf..9eedd07 100644 --- a/src/library/base/CMakeLists.txt +++ b/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}) + diff --git a/src/library/base/EventRegistry.cpp b/src/library/base/EventRegistry.cpp index ec9d4c1..920e735 100644 --- a/src/library/base/EventRegistry.cpp +++ b/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 ¤tLog = 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 ¤tLog = 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 diff --git a/src/library/base/EventRegistry.h b/src/library/base/EventRegistry.h index af5389b..23a53a5 100644 --- a/src/library/base/EventRegistry.h +++ b/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_ */ diff --git a/src/library/base/StringUtils.cpp b/src/library/base/StringUtils.cpp index cf9da96..d09bfe9 100644 --- a/src/library/base/StringUtils.cpp +++ b/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()); } diff --git a/src/library/base/StringUtils.h b/src/library/base/StringUtils.h index 8134349..41f303a 100644 --- a/src/library/base/StringUtils.h +++ b/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 */ diff --git a/src/library/base/base.h b/src/library/base/base.h index 898688f..978298d 100644 --- a/src/library/base/base.h +++ b/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 } diff --git a/src/library/base/base64.c b/src/library/base/base64.c index 4d17d33..1e1ea5b 100644 --- a/src/library/base/base64.c +++ b/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; +} diff --git a/src/library/base/logger.c b/src/library/base/logger.c index a6dc5f3..30db85d 100644 --- a/src/library/base/logger.c +++ b/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) { diff --git a/src/library/base/logger.h b/src/library/base/logger.h index c9dae04..4a516e4 100644 --- a/src/library/base/logger.h +++ b/src/library/base/logger.h @@ -3,6 +3,7 @@ #ifndef LOG_DISABLED #include <errno.h> +#include <string.h> #ifdef __cplusplus extern "C" { #endif diff --git a/src/library/ini/CMakeLists.txt b/src/library/ini/CMakeLists.txt deleted file mode 100644 index b08ac95..0000000 --- a/src/library/ini/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -ADD_LIBRARY(ini STATIC - ConvertUTF.c -) - -target_link_libraries( - ini -) - diff --git a/src/library/license++.cpp b/src/library/license++.cpp deleted file mode 100644 index b702d51..0000000 --- a/src/library/license++.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//============================================================================ -// Name : license-manager-cpp.cpp -// Author : -// Version : -// Copyright : BSD -//============================================================================ - -#include <fstream> -#include <stdio.h> -#include <stdlib.h> -#include <cstring> -#include <iostream> - -#include "api/license++.h" - -#include "LicenseReader.hpp" - -using namespace std; -void print_error(char out_buffer[256], LicenseInfo* licenseInfo) { - -} - -void identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char chbuffer[PC_IDENTIFIER_SIZE + 1]) { - -} - -static void mergeLicenses(vector<license::FullLicenseInfo> licenses, - LicenseInfo* license) { - if (license != nullptr) { - time_t curLicense_exp = 0; - for (auto it = licenses.begin(); it != licenses.end(); it++) { - //choose the license that expires later... - if (!it->has_expiry) { - it->toLicenseInfo(license); - break; - } else if (curLicense_exp < it->expires_on()) { - curLicense_exp = it->expires_on(); - it->toLicenseInfo(license); - } - } - } -} - -EVENT_TYPE acquire_license(const char * product, - const LicenseLocation* licenseLocation, LicenseInfo* licenseInfoOut) { - license::LicenseReader lr = license::LicenseReader(licenseLocation); - vector<license::FullLicenseInfo> licenses; - license::EventRegistry er = lr.readLicenses(string(product), licenses); - EVENT_TYPE result; - if (licenses.size() > 0) { - vector<license::FullLicenseInfo> licenses_with_errors; - vector<license::FullLicenseInfo> licenses_ok; - for (auto it = licenses.begin(); it != licenses.end(); it++) { - bool valid = it->validate(0,er); - if (valid) { - licenses_ok.push_back(*it); - } else { - licenses_with_errors.push_back(*it); - } - } - if (licenses_ok.size() > 0) { - er.turnErrorsIntoWarnings(); - result = LICENSE_OK; - mergeLicenses(licenses_ok, licenseInfoOut); - } else { - er.turnWarningsIntoErrors(); - result = er.getLastFailure()->event_type; - mergeLicenses(licenses_with_errors, licenseInfoOut); - } - - } else { - er.turnWarningsIntoErrors(); - result = er.getLastFailure()->event_type; - } -#ifdef _DEBUG - cout << er <<endl; -#endif - if (licenseInfoOut != nullptr) { - er.exportLastEvents(licenseInfoOut->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; -} diff --git a/src/library/licensecc.cpp b/src/library/licensecc.cpp new file mode 100644 index 0000000..8860311 --- /dev/null +++ b/src/library/licensecc.cpp @@ -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; } diff --git a/src/library/limits/license_verifier.cpp b/src/library/limits/license_verifier.cpp new file mode 100644 index 0000000..a3fefdd --- /dev/null +++ b/src/library/limits/license_verifier.cpp @@ -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 */ diff --git a/src/library/limits/license_verifier.hpp b/src/library/limits/license_verifier.hpp new file mode 100644 index 0000000..339f2de --- /dev/null +++ b/src/library/limits/license_verifier.hpp @@ -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_ */ diff --git a/src/library/locate/ApplicationFolder.cpp b/src/library/locate/ApplicationFolder.cpp index b1fb0e3..8741988 100644 --- a/src/library/locate/ApplicationFolder.cpp +++ b/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 */ diff --git a/src/library/locate/ApplicationFolder.hpp b/src/library/locate/ApplicationFolder.hpp index 649d8da..3e2163d 100644 --- a/src/library/locate/ApplicationFolder.hpp +++ b/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_ */ diff --git a/src/library/locate/CMakeLists.txt b/src/library/locate/CMakeLists.txt index 4314fbd..4382448 100644 --- a/src/library/locate/CMakeLists.txt +++ b/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 ) diff --git a/src/library/locate/EnvironmentVarData.cpp b/src/library/locate/EnvironmentVarData.cpp index 616b948..6e47d21 100644 --- a/src/library/locate/EnvironmentVarData.cpp +++ b/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 diff --git a/src/library/locate/EnvironmentVarData.hpp b/src/library/locate/EnvironmentVarData.hpp index 5698975..2709c9c 100644 --- a/src/library/locate/EnvironmentVarData.hpp +++ b/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 diff --git a/src/library/locate/EnvironmentVarLocation.cpp b/src/library/locate/EnvironmentVarLocation.cpp index a904b9a..5615482 100644 --- a/src/library/locate/EnvironmentVarLocation.cpp +++ b/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 diff --git a/src/library/locate/EnvironmentVarLocation.hpp b/src/library/locate/EnvironmentVarLocation.hpp index b2f9b6a..636b827 100644 --- a/src/library/locate/EnvironmentVarLocation.hpp +++ b/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_ */ diff --git a/src/library/locate/ExternalDefinition.cpp b/src/library/locate/ExternalDefinition.cpp index ec0428f..78b9825 100644 --- a/src/library/locate/ExternalDefinition.cpp +++ b/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" diff --git a/src/library/locate/LocatorFactory.cpp b/src/library/locate/LocatorFactory.cpp index 1b45752..9b77b06 100644 --- a/src/library/locate/LocatorFactory.cpp +++ b/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 diff --git a/src/library/locate/LocatorFactory.hpp b/src/library/locate/LocatorFactory.hpp index 6f1cd30..9a1f22c 100644 --- a/src/library/locate/LocatorFactory.hpp +++ b/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; } }; } diff --git a/src/library/locate/LocatorStrategy.cpp b/src/library/locate/LocatorStrategy.cpp index e1319b2..8bde5f1 100644 --- a/src/library/locate/LocatorStrategy.cpp +++ b/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 diff --git a/src/library/locate/LocatorStrategy.hpp b/src/library/locate/LocatorStrategy.hpp index 278c6a3..2cfc1e5 100644 --- a/src/library/locate/LocatorStrategy.hpp +++ b/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 diff --git a/src/library/os/CMakeLists.txt b/src/library/os/CMakeLists.txt index 45b1cd5..e9e74df 100644 --- a/src/library/os/CMakeLists.txt +++ b/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) diff --git a/src/library/os/openssl/signature_verifier.cpp b/src/library/os/openssl/signature_verifier.cpp new file mode 100644 index 0000000..700210b --- /dev/null +++ b/src/library/os/openssl/signature_verifier.cpp @@ -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 */ diff --git a/src/library/os/os-linux.c b/src/library/os/os-linux.c index 1b78283..861bb19 100644 --- a/src/library/os/os-linux.c +++ b/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); diff --git a/src/library/os/os-win.c b/src/library/os/os-win.c index c67e5af..eab2f28 100644 --- a/src/library/os/os-win.c +++ b/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) { diff --git a/src/library/os/os.c b/src/library/os/os.c deleted file mode 100644 index ad4803b..0000000 --- a/src/library/os/os.c +++ /dev/null @@ -1,196 +0,0 @@ -#include "os.h" -#include "../base/logger.h" -#include "public-key.h" -#include <stdio.h> - -#ifdef __linux__ - -#include <openssl/pem.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); - } -} - -FUNCTION_RETURN verifySignature(const char* stringToVerify, - const char* signatureB64) { - EVP_MD_CTX *mdctx = NULL; - const char *pubKey = PUBLIC_KEY; - int func_ret = 0; - - BIO* bio = BIO_new_mem_buf((void*) (pubKey), strlen(pubKey)); - RSA *rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, 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((void *) signatureB64, - strlen(signatureB64)); - 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, strlen(signatureB64)); -//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; - } - int en = strlen(stringToVerify); - func_ret = EVP_DigestVerifyUpdate(mdctx, stringToVerify, en); - 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; -} - -#else - -#include <iphlpapi.h> -#include <windows.h> -#pragma comment(lib, "IPHLPAPI.lib") - -unsigned char* unbase64(const char* ascii, int len, int *flen); - -static void printHash(HCRYPTHASH* hHash) { - BYTE *pbHash; - DWORD dwHashLen; - DWORD dwHashLenSize = sizeof(DWORD); - char* hashStr; - unsigned int i; - - if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *) &dwHashLen, - &dwHashLenSize, 0)) { - pbHash = (BYTE*) malloc(dwHashLen); - hashStr = (char*) malloc(dwHashLen * 2 + 1); - if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { - for (i = 0; i < dwHashLen; i++) { - sprintf(&hashStr[i * 2], "%02x", pbHash[i]); - } LOG_DEBUG("Hash to verify: %s", hashStr); - } - free(pbHash); - free(hashStr); - } -} - -FUNCTION_RETURN verifySignature(const char* stringToVerify, - const char* signatureB64) { - //-------------------------------------------------------------------- - // Declare variables. - // - // hProv: Cryptographic service provider (CSP). This example - // uses the Microsoft Enhanced Cryptographic - // Provider. - // hKey: Key to be used. In this example, you import the - // key as a PLAINTEXTKEYBLOB. - // dwBlobLen: Length of the plaintext key. - // pbKeyBlob: Pointer to the exported key. - BYTE pubKey[] = PUBLIC_KEY; - - HCRYPTPROV hProv = 0; - HCRYPTKEY hKey = 0; - HCRYPTHASH hHash = 0; - DWORD dwSigLen; - BYTE* sigBlob; - - //-------------------------------------------------------------------- - // Acquire a handle to the CSP. - - if (!CryptAcquireContext(&hProv, - NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - // If the key container cannot be opened, try creating a new - // container by specifying a container name and setting the - // CRYPT_NEWKEYSET flag. - LOG_INFO("Error in AcquireContext 0x%08x \n", GetLastError()); - if (NTE_BAD_KEYSET == (long)GetLastError()) { - if (!CryptAcquireContext(&hProv, "license++verify", - MS_ENHANCED_PROV, PROV_RSA_FULL, - CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) { - LOG_ERROR("Error in AcquireContext 0x%08x \n", GetLastError()); - return FUNC_RET_ERROR; - } - } else { - LOG_ERROR(" Error in AcquireContext 0x%08x \n", GetLastError()); - return FUNC_RET_ERROR; - } - } - - // Use the CryptImportKey function to import the PLAINTEXTKEYBLOB - // BYTE array into the key container. The function returns a - // pointer to an HCRYPTKEY variable that contains the handle of - // the imported key. - if (!CryptImportKey(hProv, &pubKey[0], sizeof(pubKey), 0, 0, &hKey)) { - LOG_ERROR("Error 0x%08x in importing the PublicKey \n", GetLastError()); - return FUNC_RET_ERROR; - } - - if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { - LOG_DEBUG("Hash object created."); - } else { - LOG_ERROR("Error in hash creation 0x%08x ", GetLastError()); - CryptReleaseContext(hProv, 0); - return FUNC_RET_ERROR; - } - - if (!CryptHashData(hHash, (const BYTE*)stringToVerify, (DWORD) strlen(stringToVerify), 0)) { - LOG_ERROR("Error in hashing data 0x%08x ", GetLastError()); - CryptDestroyHash(hHash); - CryptReleaseContext(hProv, 0); - return FUNC_RET_ERROR; - } -#ifdef _DEBUG - LOG_DEBUG("Lenght %d, hashed Data: [%s]", strlen(stringToVerify), stringToVerify); - printHash(&hHash); -#endif - sigBlob = unbase64(signatureB64, (int) strlen(signatureB64), (int*)&dwSigLen); - LOG_DEBUG("raw signature lenght %d", dwSigLen); - if (!CryptVerifySignature(hHash, sigBlob, dwSigLen, hKey, NULL, 0)) { - LOG_ERROR("Signature not validated! 0x%08x ", GetLastError()); - free(sigBlob); - CryptDestroyHash(hHash); - CryptReleaseContext(hProv, 0); - return FUNC_RET_ERROR; - } - CryptDestroyHash(hHash); - free(sigBlob); - CryptReleaseContext(hProv, 0); - return FUNC_RET_OK; -} -#endif diff --git a/src/library/os/os.h b/src/library/os/os.h index 1371786..f32ca92 100644 --- a/src/library/os/os.h +++ b/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); diff --git a/src/library/os/signature_verifier.h b/src/library/os/signature_verifier.h new file mode 100644 index 0000000..4dfe1d0 --- /dev/null +++ b/src/library/os/signature_verifier.h @@ -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_ */ diff --git a/src/library/os/windows/signature_verifier.cpp b/src/library/os/windows/signature_verifier.cpp new file mode 100644 index 0000000..677e698 --- /dev/null +++ b/src/library/os/windows/signature_verifier.cpp @@ -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 */ diff --git a/src/library/pc-identifiers.c b/src/library/pc-identifiers.c index 0f39760..0edb7ef 100644 --- a/src/library/pc-identifiers.c +++ b/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; } diff --git a/src/library/pc-identifiers.h b/src/library/pc-identifiers.h index 2d36da8..2eb0d56 100644 --- a/src/library/pc-identifiers.h +++ b/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 } diff --git a/src/templates/licensecc_properties.h.in b/src/templates/licensecc_properties.h.in new file mode 100644 index 0000000..c1af888 --- /dev/null +++ b/src/templates/licensecc_properties.h.in @@ -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 diff --git a/src/templates/licensecc_properties_test.h.in b/src/templates/licensecc_properties_test.h.in new file mode 100644 index 0000000..69cf35d --- /dev/null +++ b/src/templates/licensecc_properties_test.h.in @@ -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 diff --git a/src/templates/public_key.inja b/src/templates/public_key.inja new file mode 100644 index 0000000..8867e4c --- /dev/null +++ b/src/templates/public_key.inja @@ -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 \ No newline at end of file diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt deleted file mode 100644 index 34da47f..0000000 --- a/src/tools/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -enable_language(CXX) -add_subdirectory("base_lib") -add_subdirectory("bootstrap") -add_subdirectory("pc-identifier") -add_subdirectory("license-generator") - - \ No newline at end of file diff --git a/src/tools/base_lib/CMakeLists.txt b/src/tools/base_lib/CMakeLists.txt deleted file mode 100644 index 99788b9..0000000 --- a/src/tools/base_lib/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ - -if(WIN32) -ADD_LIBRARY( - tools_base STATIC - CryptoHelper.cpp - win/CryptoHelperWindows.cpp -) -else(WIN32) -ADD_LIBRARY( - tools_base STATIC - CryptoHelper.cpp - linux/CryptoHelperLinux.cpp -) -ENDIF(WIN32) - -target_link_libraries( - tools_base - ${EXTERNAL_LIBS} -) - -install(TARGETS tools_base ARCHIVE DESTINATION lib) diff --git a/src/tools/base_lib/CryptoHelper.cpp b/src/tools/base_lib/CryptoHelper.cpp deleted file mode 100644 index 530596e..0000000 --- a/src/tools/base_lib/CryptoHelper.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <memory> -#include "CryptoHelper.h" -#ifdef __linux__ -#include"linux/CryptoHelperLinux.h" -#elif _WIN32 -#include"win/CryptoHelperWindows.h" -#endif - -using namespace std; -namespace license { - -unique_ptr<CryptoHelper> CryptoHelper::getInstance() { -#ifdef __linux__ - unique_ptr<CryptoHelper> ptr((CryptoHelper*) new CryptoHelperLinux()); -#elif _WIN32 - unique_ptr<CryptoHelper> ptr((CryptoHelper*) new CryptoHelperWindows()); -#endif - return ptr; -} -} - diff --git a/src/tools/base_lib/CryptoHelper.h b/src/tools/base_lib/CryptoHelper.h deleted file mode 100644 index c1751f8..0000000 --- a/src/tools/base_lib/CryptoHelper.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef CRYPTPHELPER_H_ -#define CRYPTPHELPER_H_ - -#include <memory> -#include <cstddef> -#include <string> - -namespace license { -using namespace std; -/** - * Helper class definition to generate and export Public/Private keys - * for Asymmetric encryption. - * - * <p>Since this part relies heavily on operating system libraries this class - * provides a common facade to the cryptographic functions. The two implementing - * subclasses are chosen in the factory method #getInstance(). This is to avoid - * to clutter the code with many "ifdef". (extreme performance is not an issue here)</p> - *<p> *it is shared by bootstrap and license-generator projects.</p> - */ - -class CryptoHelper { - -protected: - inline CryptoHelper(){}; - -public: - virtual void generateKeyPair() = 0; - virtual const string exportPrivateKey() const = 0; - virtual const string exportPublicKey() const = 0; - - virtual const string signString(const void* privateKey, - size_t pklen, const string& license) const = 0; - static unique_ptr<CryptoHelper> getInstance(); - inline virtual ~CryptoHelper(){}; -}; -} -#endif diff --git a/src/tools/base_lib/README.TXT b/src/tools/base_lib/README.TXT deleted file mode 100644 index 838c5e9..0000000 --- a/src/tools/base_lib/README.TXT +++ /dev/null @@ -1,3 +0,0 @@ -This is the base library for the tools projects. -It contains cryptographic functions (that are very different from Linux and -Windows operating systems) \ No newline at end of file diff --git a/src/tools/base_lib/linux/CryptoHelperLinux.cpp b/src/tools/base_lib/linux/CryptoHelperLinux.cpp deleted file mode 100644 index d65ac77..0000000 --- a/src/tools/base_lib/linux/CryptoHelperLinux.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * CryptpHelperLinux.cpp - * - * Created on: Sep 14, 2014 - * - */ - -#include "CryptoHelperLinux.h" -#include <openssl/evp.h> -#include <openssl/bio.h> -#include <openssl/pem.h> -#include <openssl/err.h> -#include <openssl/rsa.h> -#include <stdexcept> -#include <string> -#include <cstddef> -#include <stdexcept> - -namespace license { -using namespace std; - -static std::string replaceAll(std::string subject, const std::string& search, - const std::string& replace) { - size_t pos = 0; - while ((pos = subject.find(search, pos)) != std::string::npos) { - subject.replace(pos, search.length(), replace); - pos += replace.length(); - } - return subject; -} - -CryptoHelperLinux::CryptoHelperLinux() { - static int initialized = 0; - rsa = NULL; - if (initialized == 0) { - initialized = 1; - ERR_load_ERR_strings(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - } - -} -void CryptoHelperLinux::generateKeyPair() { - rsa = RSA_generate_key(kBits, kExp, 0, 0); -} - -const string CryptoHelperLinux::exportPrivateKey() const { - if (rsa == NULL) { - throw logic_error( - string("Export not initialized.Call generateKeyPair first.")); - } - BIO* bio_private = BIO_new(BIO_s_mem()); - PEM_write_bio_RSAPrivateKey(bio_private, rsa, NULL, NULL, 0, NULL, NULL); - int keylen = BIO_pending(bio_private); - char* pem_key = (char*) (calloc(keylen + 1, 1)); /* Null-terminate */ - BIO_read(bio_private, pem_key, keylen); - string dest = string("\"") - + replaceAll(string(pem_key), string("\n"), string("\\n\" \\\n\"")) - + string("\""); - BIO_free_all(bio_private); - free(pem_key); - return dest; -} - -const string CryptoHelperLinux::exportPublicKey() const { - if (rsa == NULL) { - throw logic_error( - string("Export not initialized.Call generateKeyPair first.")); - } - BIO* bio_public = BIO_new(BIO_s_mem()); - PEM_write_bio_RSAPublicKey(bio_public, rsa); - int keylen = BIO_pending(bio_public); - char* pem_key = (char*) (calloc(keylen + 1, 1)); /* Null-terminate */ - BIO_read(bio_public, pem_key, keylen); - std::string dest = string("\"") - + replaceAll(string(pem_key), string("\n"), string("\\n\" \\\n\"")) - + string("\""); - BIO_free_all(bio_public); - free(pem_key); - return dest; -} - -string CryptoHelperLinux::signString(const void* privateKey, - size_t pklen, const string& license) const { - size_t slen; - unsigned char* signature; - signature = NULL; - /* Create the Message Digest Context */ - EVP_MD_CTX* mdctx = EVP_MD_CTX_create(); - if (!mdctx) { - throw logic_error("Message digest creation context"); - } - - BIO* bio = BIO_new_mem_buf((void*) (privateKey), pklen); - EVP_PKEY *pktmp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); - BIO_free(bio); - /*Initialise the DigestSign operation - SHA-256 has been selected - * as the message digest function in this example */ - if (1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pktmp)) { - EVP_MD_CTX_destroy(mdctx); - } - /* Call update with the message */ - if (EVP_DigestSignUpdate(mdctx, (const void* ) license.c_str(), - (size_t ) license.length()) - != 1) { - EVP_MD_CTX_destroy(mdctx); - throw logic_error("Message signing exception"); - } - /* Finalise the DigestSign operation */ - /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the - * signature. Length is returned in slen */ - if (EVP_DigestSignFinal(mdctx, NULL, &slen) != 1) { - EVP_MD_CTX_destroy(mdctx); - throw logic_error("Message signature finalization exception"); - } - /* Allocate memory for the signature based on size in slen */ - if (!(signature = (unsigned char *) OPENSSL_malloc( - sizeof(unsigned char) * slen))) { - EVP_MD_CTX_destroy(mdctx); - throw logic_error("Message signature memory allocation exception"); - } - /* Obtain the signature */ - if (1 != EVP_DigestSignFinal(mdctx, signature, &slen)) { - OPENSSL_free(signature); - EVP_MD_CTX_destroy(mdctx); - throw logic_error("Message signature exception"); - } - /* - FILE* stream = fmemopen(*buffer, encodedSize+1, "w"); - */ - //bio = BIO_new_fp(stdout, BIO_NOCLOSE); - /*int encodedSize = 4 * ceil(slen / 3); - char* buffer = (char*) (malloc(encodedSize + 1)); - memset(buffer,0,encodedSize+1);*/ - string signatureStr = Opensslb64Encode(slen, signature); - /* - * BIO *bio, *b64; - char message[] = "Hello World \n"; - b64 = BIO_new(BIO_f_base64()); - bio = BIO_new_fp(stdout, BIO_NOCLOSE); - bio = BIO_push(b64, bio); - BIO_write(bio, message, strlen(message)); - BIO_flush(bio); - BIO_free_all(bio); - Read Base64 encoded data from standard input and write the decoded data to standard output: - - BIO *bio, *b64, *bio_out; - char inbuf[512]; - int inlen; - b64 = BIO_new(BIO_f_base64()); - bio = BIO_new_fp(stdin, BIO_NOCLOSE); - bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); - bio = BIO_push(b64, bio); - while((inlen = BIO_read(bio, inbuf, 512)) > 0) - BIO_write(bio_out, inbuf, inlen); - BIO_free_all(bio); - */ - /* Clean up */ - //free(buffer); - if (pktmp) - EVP_PKEY_free(pktmp); - if (signature) - OPENSSL_free(signature); - - if (mdctx) - EVP_MD_CTX_destroy(mdctx); - return signatureStr; -} - -const string CryptoHelperLinux::Opensslb64Encode(size_t slen, - unsigned char* signature) const { - /* - FILE* stream = fmemopen(*buffer, encodedSize+1, "w"); - */ - //bio = BIO_new_fp(stdout, BIO_NOCLOSE); - /*int encodedSize = 4 * ceil(slen / 3); - char* buffer = (char*) (malloc(encodedSize + 1)); - memset(buffer,0,encodedSize+1);*/ - BIO* mem_bio = BIO_new(BIO_s_mem()); - BIO* b64 = BIO_new(BIO_f_base64()); - BIO* bio1 = BIO_push(b64, mem_bio); - BIO_set_flags(bio1, BIO_FLAGS_BASE64_NO_NL); - BIO_write(bio1, signature, slen); - BIO_flush(bio1); - char* charBuf; - int sz = BIO_get_mem_data(mem_bio, &charBuf); - string signatureStr; - signatureStr.assign(charBuf, sz); - BIO_free_all(bio1); - return signatureStr; -} - -CryptoHelperLinux::~CryptoHelperLinux() { - RSA_free(rsa); -} - -} /* namespace license */ diff --git a/src/tools/base_lib/linux/CryptoHelperLinux.h b/src/tools/base_lib/linux/CryptoHelperLinux.h deleted file mode 100644 index 534b1e3..0000000 --- a/src/tools/base_lib/linux/CryptoHelperLinux.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CryptpHelperLinux.h - * - * Created on: Sep 14, 2014 - * - */ - -#ifndef CRYPTPHELPERLINUX_H_ -#define CRYPTPHELPERLINUX_H_ -#include <openssl/rsa.h> -#include <cstddef> -#include <string> - -namespace license { -using namespace std; - -class CryptoHelperLinux { -private: - static const int kBits = 1024; - static const int kExp = 65537; - RSA * rsa; - const string Opensslb64Encode(size_t slen, unsigned char* signature) const; -public: - CryptoHelperLinux(); - - virtual void generateKeyPair(); - virtual const string exportPrivateKey() const; - virtual const string exportPublicKey() const; - - virtual string signString(const void* privateKey, size_t pklen, - const string& license) const; - virtual ~CryptoHelperLinux(); -}; - -} /* namespace license */ - -#endif /* CRYPTPHELPERLINUX_H_ */ diff --git a/src/tools/base_lib/win/CryptoHelperWindows.cpp b/src/tools/base_lib/win/CryptoHelperWindows.cpp deleted file mode 100644 index ff40457..0000000 --- a/src/tools/base_lib/win/CryptoHelperWindows.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * CryptoHelperWindows.cpp - * - * Created on: Sep 14, 2014 - * - */ - -#include <sstream> -#include <vector> -#include <string> -#include "CryptoHelperWindows.h" -// The RSA public-key key exchange algorithm -#define ENCRYPT_ALGORITHM CALG_RSA_SIGN -// The high order WORD 0x0200 (decimal 512) -// determines the key length in bits. -#define KEYLENGTH 0x02000000 -#pragma comment(lib, "crypt32.lib") - -namespace license { - -CryptoHelperWindows::CryptoHelperWindows() { - m_hCryptProv = NULL; - m_hCryptKey = NULL; - if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, 0)) { - // If the key container cannot be opened, try creating a new - // container by specifying a container name and setting the - // CRYPT_NEWKEYSET flag. - DWORD lastError = GetLastError(); - printf("Error in CryptAcquireContext (1) 0x%08x \n", lastError); - if (NTE_BAD_KEYSET == lastError) { - if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL , PROV_RSA_FULL, CRYPT_NEWKEYSET)) { - printf("Warn in CryptAcquireContext: acquiring new user keyset failed 0x%08x, trying less secure mackine keyset \n", GetLastError()); - //maybe access to protected storage disabled. Try with machine keys (less secure) - if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) { - printf("Error in CryptAcquireContext (2) 0x%08x \n", GetLastError()); - if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)) { - printf("Error in CryptAcquireContext (3): acquiring new keyset(machine) failed 0x%08x \n", GetLastError()); - throw logic_error(""); - } - } - } - } else { - printf(" Error in CryptAcquireContext (4) 0x%08x \n", lastError); - throw logic_error(""); - } - } - -} - -/** - This method calls the CryptGenKey function to get a handle to an - - exportable key-pair. The key-pair is generated with the RSA public-key - key exchange algorithm using Microsoft Enhanced Cryptographic Provider. - */ -void CryptoHelperWindows::generateKeyPair() { - HRESULT hr = S_OK; - DWORD dwErrCode; - // If the handle to key container is NULL, fail. - if (m_hCryptProv == NULL) - throw logic_error("Cryptocontext not correctly initialized"); - // Release a previously acquired handle to key-pair. - if (m_hCryptKey) - m_hCryptKey = NULL; - // Call the CryptGenKey method to get a handle - // to a new exportable key-pair. - if (!CryptGenKey(m_hCryptProv, ENCRYPT_ALGORITHM, - KEYLENGTH | CRYPT_EXPORTABLE, &m_hCryptKey)) { - dwErrCode = GetLastError(); - throw logic_error( - string("Error generating keys ") - + to_string(static_cast<long long>(dwErrCode))); - } - //double check the key is really generated - if(m_hCryptKey == NULL) { - dwErrCode = GetLastError(); - throw logic_error( - string("Error generating keys (2)") - + to_string(static_cast<long long>(dwErrCode))); - } -} - -/* This method calls the CryptExportKey function to get the Public key - in a string suitable for C source inclusion. - */ -const string CryptoHelperWindows::exportPublicKey() const { - HRESULT hr = S_OK; - DWORD dwErrCode; - DWORD dwBlobLen; - BYTE *pbKeyBlob = nullptr; - stringstream ss; - // If the handle to key container is NULL, fail. - if (m_hCryptKey == NULL) - throw logic_error("call GenerateKey first."); - // This call here determines the length of the key - // blob. - if (!CryptExportKey(m_hCryptKey, - NULL, PUBLICKEYBLOB, 0, nullptr, &dwBlobLen)) { - dwErrCode = GetLastError(); - throw logic_error( - string("Error calculating size of public key ") - + to_string(static_cast<long long>(dwErrCode))); - } - // Allocate memory for the pbKeyBlob. - if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) { - throw logic_error(string("Out of memory exporting public key ")); - } - // Do the actual exporting into the key BLOB. - if (!CryptExportKey(m_hCryptKey, - NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { - delete pbKeyBlob; - dwErrCode = GetLastError(); - throw logic_error( - string("Error exporting public key ") - + to_string(static_cast<long long>(dwErrCode))); - } else { - ss << "\t"; - for (unsigned int i = 0; i < dwBlobLen; i++) { - if (i != 0) { - ss << ", "; - if (i % 10 == 0) { - ss << "\\" << endl << "\t"; - } - } - ss << to_string(static_cast<long long>(pbKeyBlob[i])); - } - delete pbKeyBlob; - } - return ss.str(); -} - -CryptoHelperWindows::~CryptoHelperWindows() { - if (m_hCryptProv) { - CryptReleaseContext(m_hCryptProv, 0); - m_hCryptProv = NULL; - } - if (m_hCryptKey) - m_hCryptKey = NULL; -} - -//-------------------------------------------------------------------- -// This method calls the CryptExportKey function to get the Private key -// in a byte array. The byte array is allocated on the heap and the size -// of this is returned to the caller. The caller is responsible for releasing // this memory using a delete call. -//-------------------------------------------------------------------- -const string CryptoHelperWindows::exportPrivateKey() const { - HRESULT hr = S_OK; - DWORD dwErrCode; - DWORD dwBlobLen; - BYTE *pbKeyBlob; - stringstream ss; - // If the handle to key container is NULL, fail. - if (m_hCryptKey == NULL) - throw logic_error(string("call GenerateKey first.")); - // This call here determines the length of the key - // blob. - if (!CryptExportKey(m_hCryptKey, - NULL, PRIVATEKEYBLOB, 0, nullptr, &dwBlobLen)) { - dwErrCode = GetLastError(); - throw logic_error( - string("Error calculating size of private key ") - + to_string(static_cast<long long>(dwErrCode))); - } - // Allocate memory for the pbKeyBlob. - if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) { - throw logic_error(string("Out of memory exporting private key ")); - } - - // Do the actual exporting into the key BLOB. - if (!CryptExportKey(m_hCryptKey, - NULL, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { - delete pbKeyBlob; - dwErrCode = GetLastError(); - throw logic_error( - string("Error exporting private key ") - + to_string(static_cast<long long>(dwErrCode))); - } else { - ss << "\t"; - for (unsigned int i = 0; i < dwBlobLen; i++) { - if (i != 0) { - ss << ", "; - if (i % 15 == 0) { - ss << "\\" << endl << "\t"; - } - } - ss << to_string(static_cast<long long>(pbKeyBlob[i])); - } - delete pbKeyBlob; - } - return ss.str(); -} - -void CryptoHelperWindows::printHash(HCRYPTHASH *hHash) const { - BYTE *pbHash; - DWORD dwHashLen; - DWORD dwHashLenSize = sizeof(DWORD); - char *hashStr; - unsigned int i; - - if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE*) &dwHashLen, - &dwHashLenSize, 0)) { - pbHash = (BYTE*) malloc(dwHashLen); - hashStr = (char*) malloc(dwHashLen * 2 + 1); - if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { - for (i = 0; i < dwHashLen; i++) { - sprintf(&hashStr[i * 2], "%02x", pbHash[i]); - } - printf("hash To be signed: %s \n", hashStr); - } - free(pbHash); - free(hashStr); - } -} - -const string CryptoHelperWindows::signString(const void *privateKey, - size_t pklen, const string &license) const { - BYTE *pbBuffer = (BYTE*) license.c_str(); - const DWORD dwBufferLen = (DWORD) strlen((char*) pbBuffer); - HCRYPTHASH hHash; - - HCRYPTKEY hKey; - BYTE *pbSignature; - DWORD dwSigLen; - DWORD strLen; - - //------------------------------------------------------------------- - // Acquire a cryptographic provider context handle. - - if (!CryptImportKey(m_hCryptProv, (const BYTE*) privateKey, (DWORD) pklen, - 0, 0, &hKey)) { - throw logic_error( - string("Error in importing the PrivateKey ") - + to_string(static_cast<long long>(GetLastError()))); - } - - //------------------------------------------------------------------- - // Create the hash object. - - if (CryptCreateHash(m_hCryptProv, CALG_SHA1, 0, 0, &hHash)) { - printf("Hash object created. \n"); - } else { - CryptDestroyKey(hKey); - throw logic_error(string("Error during CryptCreateHash.")); - } - //------------------------------------------------------------------- - // Compute the cryptographic hash of the buffer. - - if (CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) { -#ifdef _DEBUG - printf("Length of data to be hashed: %d \n", dwBufferLen); - printHash(&hHash); -#endif - } else { - throw logic_error(string("Error during CryptHashData.")); - } - //------------------------------------------------------------------- - // Determine the size of the signature and allocate memory. - - dwSigLen = 0; - if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, nullptr, &dwSigLen)) { - printf("Signature length %d found.\n", dwSigLen); - } else { - throw logic_error(string("Error during CryptSignHash.")); - } - //------------------------------------------------------------------- - // Allocate memory for the signature buffer. - - if (pbSignature = (BYTE*) malloc(dwSigLen)) { - printf("Memory allocated for the signature.\n"); - } else { - throw logic_error(string("Out of memory.")); - } - //------------------------------------------------------------------- - // Sign the hash object. - - if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, pbSignature, - &dwSigLen)) { - printf("pbSignature is the signature length. %d\n", dwSigLen); - } else { - throw logic_error(string("Error during CryptSignHash.")); - } - //------------------------------------------------------------------- - // Destroy the hash object. - - CryptDestroyHash(hHash); - CryptDestroyKey(hKey); - - CryptBinaryToString(pbSignature, dwSigLen, - CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &strLen); - vector<char> buffer(strLen); - CryptBinaryToString(pbSignature, dwSigLen, - CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &buffer[0], &strLen); - - //------------------------------------------------------------------- - // In the second phase, the hash signature is verified. - // This would most often be done by a different user in a - // separate program. The hash, signature, and the PUBLICKEYBLOB - // would be read from a file, an email message, - // or some other source. - - // Here, the original pbBuffer, pbSignature, szDescription. - // pbKeyBlob, and their lengths are used. - - // The contents of the pbBuffer must be the same data - // that was originally signed. - - //------------------------------------------------------------------- - // Get the public key of the user who created the digital signature - // and import it into the CSP by using CryptImportKey. This returns - // a handle to the public key in hPubKey. - - /*if (CryptImportKey( - hProv, - pbKeyBlob, - dwBlobLen, - 0, - 0, - &hPubKey)) - { - printf("The key has been imported.\n"); - } - else - { - MyHandleError("Public key import failed."); - } - //------------------------------------------------------------------- - // Create a new hash object. - - if (CryptCreateHash( - hProv, - CALG_MD5, - 0, - 0, - &hHash)) - { - printf("The hash object has been recreated. \n"); - } - else - { - MyHandleError("Error during CryptCreateHash."); - } - //------------------------------------------------------------------- - // Compute the cryptographic hash of the buffer. - - if (CryptHashData( - hHash, - pbBuffer, - dwBufferLen, - 0)) - { - printf("The new hash has been created.\n"); - } - else - { - MyHandleError("Error during CryptHashData."); - } - //------------------------------------------------------------------- - // Validate the digital signature. - - if (CryptVerifySignature( - hHash, - pbSignature, - dwSigLen, - hPubKey, - NULL, - 0)) - { - printf("The signature has been verified.\n"); - } - else - { - printf("Signature not validated!\n"); - } - //------------------------------------------------------------------- - // Free memory to be used to store signature. - - - - //------------------------------------------------------------------- - // Destroy the hash object. - - - - //------------------------------------------------------------------- - // Release the provider handle. - - /*if (hProv) - CryptReleaseContext(hProv, 0);*/ - if (pbSignature) { - free(pbSignature); - } - return string(&buffer[0]); -} -} /* namespace license */ diff --git a/src/tools/base_lib/win/CryptoHelperWindows.h b/src/tools/base_lib/win/CryptoHelperWindows.h deleted file mode 100644 index b4e7594..0000000 --- a/src/tools/base_lib/win/CryptoHelperWindows.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CryptoHelperWindows.h - * - * Created on: Sep 14, 2014 - * - */ - -#ifndef CRYPTOHELPERWINDOWS_H_ -#define CRYPTOHELPERWINDOWS_H_ - -//#define _WIN32_WINNT 0x0400 -#include <windows.h> -#include <wincrypt.h> -#include <tchar.h> -#include <string> -#include "../CryptoHelper.h" - - - -namespace license { -using namespace std; - -class CryptoHelperWindows: public CryptoHelper { -private : - void acquireContext(); - // Handle to the cryptography provider. - HCRYPTPROV m_hCryptProv; - // Handle to the cryptography key. - HCRYPTKEY m_hCryptKey; - void printHash(HCRYPTHASH* hHash) const; -public: - CryptoHelperWindows(); - - virtual void generateKeyPair(); - virtual const string exportPrivateKey() const; - virtual const string exportPublicKey() const; - - virtual const string signString(const void* privateKey, size_t pklen, - const string& license) const; - - virtual ~CryptoHelperWindows(); -}; - -} /* namespace license */ - -#endif /* CRYPTOHELPERWINDOWS_H_ */ diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt deleted file mode 100644 index 6bdf996..0000000 --- a/src/tools/bootstrap/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -add_executable( - bootstrap - bootstrap.cpp -) - -#SET_TARGET_PROPERTIES(bootstrap PROPERTIES LINK_SEARCH_START_STATIC ON) -SET_TARGET_PROPERTIES(bootstrap PROPERTIES LINK_SEARCH_END_STATIC OFF) -target_link_libraries( - bootstrap - tools_base - ${EXTERNAL_LIBS} -) - -if(MINGW) - #Cross compiling from linux host to windows - IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING) - #this is to avoid to install binfmt_misc (for builds in docker, or LXC) - add_custom_command ( - OUTPUT "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/bootstrap.exe "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS bootstrap) - ELSE() - add_custom_command ( - OUTPUT "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - COMMAND ./bootstrap.exe "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS bootstrap) - ENDIF() -else(MINGW) - add_custom_command ( - OUTPUT "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - COMMAND bootstrap "${CMAKE_BINARY_DIR}/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - DEPENDS bootstrap) -endif(MINGW) - -add_custom_target(private_key DEPENDS "${CMAKE_BINARY_DIR}/private-key.h") -add_custom_target(public_key DEPENDS "${CMAKE_BINARY_DIR}/public-key.h") - - -# add the command to generate the source code -#add_custom_command ( -# OUTPUT "${CMAKE_BINARY_DIR}/public-key.h" -# COMMAND bootstrap derive_public "${CMAKE_CURRENT_SOURCE_DIR}/../license-generator/private-key.h" "${CMAKE_BINARY_DIR}/public-key.h" -# DEPENDS bootstrap private_key -#) -#add_custom_target(public_key DEPENDS "${CMAKE_BINARY_DIR}/public-key.h") diff --git a/src/tools/bootstrap/bootstrap.cpp b/src/tools/bootstrap/bootstrap.cpp deleted file mode 100644 index e3647de..0000000 --- a/src/tools/bootstrap/bootstrap.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include <stdio.h> -#include "../base_lib/CryptoHelper.h" -#include <string> -#include <stdlib.h> -#include <iostream> -#include <sys/stat.h> - -using namespace std; -namespace license { - -void write_pubkey_file(const string& public_fname, const string& pbPublicKey) { - FILE* fp = fopen(public_fname.c_str(), "w"); - if (fp == nullptr) { - throw ios_base::failure(string("can't create :") + public_fname); - } - fprintf(fp, "//file generated by bootstrap.cpp, do not edit.\n\n"); - fprintf(fp, "#ifndef PUBLIC_KEY_H_\n#define PUBLIC_KEY_H_\n"); - fprintf(fp, "#define PUBLIC_KEY { \\\n"); - fprintf(fp, "%s", pbPublicKey.c_str()); - fprintf(fp, "}\n\n"); - const int random = rand() % 1000; - fprintf(fp, "#define SHARED_RANDOM %d;\n", random); - fprintf(fp, "#endif\n"); - fclose(fp); -} - -void write_privkey_file(const string& private_fname, const string& privateKey) { - FILE* fp = fopen(private_fname.c_str(), "w"); - if (fp == nullptr) { - throw ios_base::failure(string("can't create :") + private_fname); - } - fprintf(fp, "//file generated by bootstrap.cpp, do not edit.\n\n"); - fprintf(fp, "#ifndef PRIVATE_KEY_H_\n#define PRIVATE_KEY_H_\n"); - fprintf(fp, "#define PRIVATE_KEY { \\\n"); - fprintf(fp, "%s", privateKey.c_str()); - fprintf(fp, "}\n\n"); - fprintf(fp, "#endif\n"); - fclose(fp); -} - -void generatePk(string private_include, string public_include) { - unique_ptr<CryptoHelper> cryptoHlpr = CryptoHelper::getInstance(); - - try { - cryptoHlpr->generateKeyPair(); - } catch (exception &e) { - cerr << endl << "Error generating key pair: " << e.what() << endl - << "aborting" << endl; - exit(2); - } - - try { - const string pubKey = cryptoHlpr->exportPublicKey(); - write_pubkey_file(public_include, pubKey); - // Print out the public key to console as a - // hexadecimal string. - cout << endl << "PublicKey" << pubKey.c_str() << endl; - } catch (exception &e) { - cerr << endl << "Error exporting public key: " << e.what() << endl - << "aborting." << endl; - exit(4); - } - - try { - const string privKey = cryptoHlpr->exportPrivateKey(); - write_privkey_file(private_include, privKey); - } catch (exception &e) { - cerr << endl << "Error exporting private key: " << e.what() << endl - << "aborting" << endl; - exit(5); - } - - return; -} -} - -bool file_exists (const std::string & name) -{ - struct stat buffer; - return (stat (name.c_str(), &buffer) == 0); -} - -int main(int argc, char** argv) { - - if (argc != 3) { - //print_usage(); - exit(2); - } else { - printf("********************************************\n"); - printf("* Bootstrap!!! *\n"); - printf("********************************************\n"); - - } - const string private_fname = string(argv[1]); - const string public_fname(argv[2]); - - if (file_exists(private_fname) || file_exists(public_fname)) { - printf("Key files exist, skipping key generation. Do 'make clean' to generate new keys.\n"); - exit(0); - } - - license::generatePk(private_fname, public_fname); - return 0; -} diff --git a/src/tools/license-generator/.gitignore b/src/tools/license-generator/.gitignore deleted file mode 100644 index 3190db4..0000000 --- a/src/tools/license-generator/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/private-key.h diff --git a/src/tools/license-generator/CMakeLists.txt b/src/tools/license-generator/CMakeLists.txt deleted file mode 100644 index 334b178..0000000 --- a/src/tools/license-generator/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -include_directories(${Boost_INCLUDE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) -link_directories ( ${Boost_LIBRARY_DIR} ) - -ADD_LIBRARY( - license_generator_lib STATIC - license-generator.cpp -) - -target_link_libraries( - license_generator_lib - tools_base - base - licensecc_static - $<$<CONFIG:Debug>:${Boost_PROGRAM_OPTIONS_LIBRARY_DEBUG}> - $<$<NOT:$<CONFIG:Debug>>:${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE}> - $<$<CONFIG:Debug>:${Boost_SYSTEM_LIBRARY_DEBUG}> - $<$<NOT:$<CONFIG:Debug>>:${Boost_SYSTEM_LIBRARY_RELEASE}> - ${EXTERNAL_LIBS} -) - -add_executable( - license_generator - license-generator-main.cpp -) - -target_link_libraries( - license_generator - license_generator_lib -) -add_dependencies( license_generator private_key ) - -install(TARGETS license_generator RUNTIME DESTINATION bin) - diff --git a/src/tools/license-generator/license-generator-main.cpp b/src/tools/license-generator/license-generator-main.cpp deleted file mode 100644 index 39dc455..0000000 --- a/src/tools/license-generator/license-generator-main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include <stdlib.h> -#include "license-generator.h" - -int main(int argc, const char *argv[]) { - return license::LicenseGenerator::generateLicense(argc, argv); - -} - diff --git a/src/tools/license-generator/license-generator.cpp b/src/tools/license-generator/license-generator.cpp deleted file mode 100644 index d7335cf..0000000 --- a/src/tools/license-generator/license-generator.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "license-generator.h" - -#include <stddef.h> -#include <stdlib.h> -#include <cerrno> -#include <cstdio> -#include <cstring> -#include <ctime> -#include <fstream> -#include <iomanip> -#include <iostream> -#include <iterator> -#include <map> -#include <memory> -#include <regex> -#include <sstream> -#include <stdexcept> -#include <string> -#include <vector> -#include <boost/program_options.hpp> -#include <boost/algorithm/string.hpp> - -#include <private-key.h> -#include <build_properties.h> -#include "../../library/base/base64.h" -#include "../base_lib/CryptoHelper.h" - -//namespace fs = boost::filesystem; -//namespace bt = boost::posix_time; -namespace po = boost::program_options; - -using namespace std; - -namespace license { - -void LicenseGenerator::printHelp(const char *prog_name, - const po::options_description &options) { - cout << endl; - cout << prog_name << " Version " << PROJECT_VERSION << endl << ". Usage:" - << endl; - cout << prog_name << " [options] product_name1 product_name2 ... " << endl - << endl; - cout - << " product_name1 ... = Product name. This string must match the one passed by the software." - << endl; - cout << options << endl; -} - -po::options_description LicenseGenerator::configureProgramOptions() { - po::options_description common("General options"); - common.add_options()("help,h", "print help message and exit.") // - ("verbose,v", "print more information.")// - - ("output,o", po::value<string>(), "Output file name. If not specified the " - "license will be printed to standard output"); - po::options_description licenseGeneration("License Generation"); - licenseGeneration.add_options()("private_key,p", po::value<string>(), - "Specify an alternate file for the primary key to be used. " - "If not specified the internal primary key will be used.")( - "begin_date,b", po::value<string>(), - "Specify the start of the validity for this license. " - " Format YYYYMMDD. If not specified defaults to today")( - "expire_date,e", po::value<string>(), - "Specify the expire date for this license. " - " Format YYYYMMDD. If not specified the license won't expire")( - "client_signature,s", po::value<string>(), - "The signature of the pc that requires the license. " - "It should be in the format XXXX-XXXX-XXXX-XXXX." - " If not specified the license " - "won't be linked to a specific pc.")("start_version,t", - po::value<unsigned int>()->default_value(0 - /*FullLicenseInfo.UNUSED_SOFTWARE_VERSION*/, "All Versions"), - "Specify the first version of the software this license apply to.")( - "end_version,n", po::value<unsigned int>()->default_value(0 - /*FullLicenseInfo.UNUSED_SOFTWARE_VERSION*/, "All Versions"), - "Specify the last version of the software this license apply to.")( - "extra_data,x", po::value<string>(), - "Specify extra data to be included into the license"); - po::options_description visibleOptions; - visibleOptions.add(common).add(licenseGeneration); - return visibleOptions; -} - -vector<FullLicenseInfo> LicenseGenerator::parseLicenseInfo( - const po::variables_map &vm) { - string begin_date = FullLicenseInfo::UNUSED_TIME; - string end_date = FullLicenseInfo::UNUSED_TIME; - if (vm.count("expire_date")) { - const std::string dt_end = vm["expire_date"].as<string>(); - try { - end_date = normalize_date(dt_end); - char curdate[20]; - time_t curtime = time(nullptr); - strftime(curdate, 20, "%Y-%m-%d", localtime(&curtime)); - begin_date.assign(curdate); - } catch (const invalid_argument &e) { - cerr << endl << "End date not recognized: " << dt_end - << " Please enter a valid date in format YYYYMMDD" << endl; - exit(2); - } - } - if (vm.count("begin_date")) { - const std::string begin_date_str = vm["begin_date"].as<string>(); - try { - begin_date = normalize_date(begin_date_str); - } catch (invalid_argument &e) { - cerr << endl << "Begin date not recognized: " << begin_date_str - << " Please enter a valid date in format YYYYMMDD" << endl; - //print_usage(vm); - exit(2); - } - } - string client_signature = ""; - if (vm.count("client_signature")) { - client_signature = vm["client_signature"].as<string>(); - cout << "cli sig:" << client_signature; - regex e( - "[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}-[A-Za-z0-9\\+/]{4}"); - cout << "\nregex:"; - if (!regex_match(client_signature, e)) { - cerr << endl << "Client signature not recognized: " - << client_signature - << " Please enter a valid signature in format XXXX-XXXX-XXXX-XXXX" - << endl; - exit(2); - } - } - string extra_data = ""; - if (vm.count("extra_data")) { - extra_data = vm["extra_data"].as<string>(); - } - unsigned int from_sw_version = vm["start_version"].as<unsigned int>(); - unsigned int to_sw_version = vm["end_version"].as<unsigned int>(); - if (vm.count("product") == 0) { - cerr << endl << "Parameter [product] not found. " << endl; - exit(2); - } - vector<string> products = vm["product"].as<vector<string>>(); - vector<FullLicenseInfo> licInfo; - licInfo.reserve(products.size()); - for (auto it = products.begin(); it != products.end(); it++) { - if (boost::algorithm::trim_copy(*it).length() > 0) { - licInfo.push_back( - FullLicenseInfo("", *it, "", PROJECT_INT_VERSION, - begin_date, end_date, client_signature, - from_sw_version, to_sw_version, extra_data)); - } - } - return licInfo; -} - -void LicenseGenerator::generateAndOutputLicenses(const po::variables_map &vm, - ostream &outputFile) { - vector<FullLicenseInfo> licenseInfo = parseLicenseInfo(vm); - const unique_ptr<CryptoHelper> helper = CryptoHelper::getInstance(); - const unsigned char pkey[] = PRIVATE_KEY; - const size_t len = sizeof(pkey); - for (auto it = licenseInfo.begin(); it != licenseInfo.end(); ++it) { - const string license = it->printForSign(); - const string signature = helper->signString((const void*) pkey, len, - license); - it->license_signature = signature; - it->printAsIni(outputFile); - } -} - -void LicenseGenerator::generateB64Licenses(const po::variables_map &vm, - ostream &outputFile) { - std::ostringstream tempStream; - generateAndOutputLicenses(vm, tempStream); - - std::string str = tempStream.str(); - const char *chr = str.c_str(); - int finalLenght; - char *encoded = base64(chr, str.length(), &finalLenght); - outputFile.write(encoded, finalLenght); - free(encoded); -} - -int LicenseGenerator::generateLicense(int argc, const char **argv) { - - po::options_description visibleOptions = configureProgramOptions(); - //positional options must be added to standard options - po::options_description allOptions; - allOptions.add(visibleOptions).add_options()("product", - po::value<vector<string>>(), "product names"); - - po::positional_options_description p; - p.add("product", -1); - - po::variables_map vm; - po::store( - po::command_line_parser(argc, argv).options(allOptions).positional( - p).run(), vm); - po::notify(vm); - if (vm.count("help") || argc == 1) { - printHelp(argv[0], visibleOptions); - return 0; - } - - if (vm.count("output")) { - const std::string fname = vm["output"].as<string>(); - - fstream ofstream(fname, std::ios::out | std::ios::app); - if (!ofstream.is_open()) { - cerr << "can't open file [" << fname << "] for output." << endl - << " error: " << strerror(errno) << endl; - exit(3); - } - if (vm.count("base64")) { - generateB64Licenses(vm, ofstream); - } else { - generateAndOutputLicenses(vm, ofstream); - } - ofstream.close(); - } else { - if (vm.count("base64")) { - generateB64Licenses(vm, cout); - } else { - generateAndOutputLicenses(vm, cout); - } - } - return 0; -} - -const std::string formats[] = { "%4u-%2u-%2u", "%4u/%2u/%2u", "%4u%2u%2u" }; -const size_t formats_n = 3; - -string LicenseGenerator::normalize_date(const std::string &sDate) { - if (sDate.size() < 8) - throw invalid_argument("Date string too small for known formats"); - unsigned int year, month, day; - bool found = false; - for (size_t i = 0; i < formats_n && !found; ++i) { - const int chread = sscanf(sDate.c_str(), formats[i].c_str(), &year, - &month, &day); - if (chread == 3) { - found = true; - break; - } - } - if (!found) - throw invalid_argument("Date string did not match a known format"); - ostringstream oss; - oss << year << "-" << setfill('0') << std::setw(2) << month << "-" - << setfill('0') << std::setw(2) << day; - return oss.str(); -} -} diff --git a/src/tools/license-generator/license-generator.h b/src/tools/license-generator/license-generator.h deleted file mode 100644 index 04eaee6..0000000 --- a/src/tools/license-generator/license-generator.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * LicenseSigner.h - * - * Created on: Apr 6, 2014 - * - */ - -#ifndef LICENSE_GENERATOR_H_ -#define LICENSE_GENERATOR_H_ - -#include <boost/program_options.hpp> -#include "../../library/LicenseReader.hpp" - -namespace license { - -namespace po = boost::program_options; -/** - * This class contains all the logic used to generate a new license. - * Since it has no method "main", can be easily used in unit tests. - */ -class LicenseGenerator { -private: - LicenseGenerator(); - - static void printHelp(const char* prog_name, const po::options_description& options); - static po::options_description configureProgramOptions(); - static std::vector<FullLicenseInfo> parseLicenseInfo(const po::variables_map& vm); - static void generateAndOutputLicenses(const po::variables_map& vm, - std::ostream& outputFile); - static void generateB64Licenses(const po::variables_map& vm, - std::ostream& outputFile); - static std::string normalize_date(const std::string& s); -public: - /** - * Available options: - * <ul> - * <li>-s : use Client Signature.</li> - * </ul> - * @param argc - * count of arguments. - * @param argv - * char** of parameters. - * @return - */ - static int generateLicense(int argc, const char** argv); -}; - -} /* namespace license */ - -#endif /* LICENSE_GENERATOR_H_ */ diff --git a/src/tools/pc-identifier/CMakeLists.txt b/src/tools/pc-identifier/CMakeLists.txt deleted file mode 100644 index 7cb985b..0000000 --- a/src/tools/pc-identifier/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -#set_target_properties(ui PROPERTIES LINK_FLAGS "-static") \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0fb6853..ec61aef 100644 --- a/test/CMakeLists.txt +++ b/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) \ No newline at end of file diff --git a/test/functional/CMakeLists.txt b/test/functional/CMakeLists.txt index 44b4a8d..cdcc680 100644 --- a/test/functional/CMakeLists.txt +++ b/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}) diff --git a/test/functional/date_test.cpp b/test/functional/date_test.cpp index 44a9911..15fbdd0 100644 --- a/test/functional/date_test.cpp +++ b/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 diff --git a/test/functional/generate-license.cpp b/test/functional/generate-license.cpp index 7f81722..8ef9477 100644 --- a/test/functional/generate-license.cpp +++ b/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 diff --git a/test/functional/generate-license.h b/test/functional/generate-license.h index 4c1dcc0..28fba23 100644 --- a/test/functional/generate-license.h +++ b/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 diff --git a/test/functional/hijiaking_test.cpp b/test/functional/hijiaking_test.cpp index b4871b1..d18b84d 100644 --- a/test/functional/hijiaking_test.cpp +++ b/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" diff --git a/test/functional/signature_verifier_test.cpp b/test/functional/signature_verifier_test.cpp new file mode 100644 index 0000000..709f7fc --- /dev/null +++ b/test/functional/signature_verifier_test.cpp @@ -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 */ diff --git a/test/functional/standard-license_test.cpp b/test/functional/standard-license_test.cpp index b30d690..669ca46 100644 --- a/test/functional/standard-license_test.cpp +++ b/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 diff --git a/test/functional/volid_test.cpp b/test/functional/volid_test.cpp index dedb040..53dfae3 100644 --- a/test/functional/volid_test.cpp +++ b/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 diff --git a/test/library/CMakeLists.txt b/test/library/CMakeLists.txt index b7f4d90..e849663 100644 --- a/test/library/CMakeLists.txt +++ b/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() \ No newline at end of file +ADD_TEST(NAME test_event_registry COMMAND test_event_registry) diff --git a/test/library/EventRegistry_test.cpp b/test/library/EventRegistry_test.cpp index 70abe9b..7a72a2c 100644 --- a/test/library/EventRegistry_test.cpp +++ b/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 diff --git a/test/library/LicenseLocator_test.cpp b/test/library/LicenseLocator_test.cpp index b1f7eaf..6c83fc0 100644 --- a/test/library/LicenseLocator_test.cpp +++ b/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 diff --git a/test/library/LicenseReader_test.cpp b/test/library/LicenseReader_test.cpp index 1c9776e..0b16149 100644 --- a/test/library/LicenseReader_test.cpp +++ b/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 diff --git a/test/library/Os_Linux_test.cpp b/test/library/Os_Linux_test.cpp index bd57c92..6d68d0d 100644 --- a/test/library/Os_Linux_test.cpp +++ b/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 @@ } } } - diff --git a/test/library/license_verifier_test.cpp b/test/library/license_verifier_test.cpp new file mode 100644 index 0000000..50bd9d3 --- /dev/null +++ b/test/library/license_verifier_test.cpp @@ -0,0 +1,10 @@ +/* + * LicenseVerifier_test.cpp + * + * Created on: Nov 20, 2019 + * Author: devel + */ + +#include "LicenseVerifier.hpp" + +namespace license {} /* namespace license */ diff --git a/test/library/test_reader.ini b/test/library/test_reader.ini index 6700638..a3ed87e 100644 --- a/test/library/test_reader.ini +++ b/test/library/test_reader.ini @@ -1,3 +1,3 @@ [PRODUCT] -license_version = 100 -license_signature = qAz \ No newline at end of file +lic_ver = 200 +sig = qAz diff --git a/test/license-generator/CMakeLists.txt b/test/license-generator/CMakeLists.txt deleted file mode 100644 index f50b2ea..0000000 --- a/test/license-generator/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ - -add_executable( - license_generator_test - license-generator_test.cpp -) - -target_link_libraries( - license_generator_test - license_generator_lib - ${Boost_LIBRARIES} -) - -IF( ( CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") AND CMAKE_CROSSCOMPILING) - ADD_TEST(NAME license_generator_test COMMAND wine ${CMAKE_CURRENT_BINARY_DIR}/license_generator_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -ELSE() - ADD_TEST(NAME license_generator_test COMMAND license_generator_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -ENDIF() diff --git a/test/license-generator/license-generator_test.cpp b/test/license-generator/license-generator_test.cpp deleted file mode 100644 index 4e8c6ec..0000000 --- a/test/license-generator/license-generator_test.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#define BOOST_TEST_MODULE license_generator_test -//#define BOOST_TEST_MAIN -//#define BOOST_TEST_DYN_LINK -#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/ini/SimpleIni.h" - -namespace fs = boost::filesystem; -using namespace license; -using namespace std; - -void generate_license(const string& prod_name, const string& fname) { - const int argc = 4; - const char** argv = new const char*[argc + 1]; - argv[0] = "lic-generator"; - argv[1] = "-o"; - argv[2] = fname.c_str(); - argv[3] = "test"; - const int retCode = LicenseGenerator::generateLicense(argc, argv); - delete[] (argv); - BOOST_CHECK_EQUAL(retCode, 0); - BOOST_ASSERT(fs::exists(fname)); - CSimpleIniA ini; - const SI_Error rc = ini.LoadFile(fname.c_str()); - BOOST_CHECK_GE(rc,0); - const int sectionSize = ini.GetSectionSize(prod_name.c_str()); - BOOST_CHECK_GT(sectionSize,0); -} - -BOOST_AUTO_TEST_CASE( generate_lic_file ) { - const string licLocation(PROJECT_TEST_TEMP_DIR "/test1.lic"); - generate_license(string("TEST"), licLocation); -} - -- Gitblit v1.9.1