License简介和Licensecc的使用
- License简介
- 什么是LIcense
- 简易License制作
- 加密扫盲
- 对称加密
- 非对称加密
- Licensecc使用
- 构建和编译
- 在linux上进行编译
- Ubuntu
- CentOS 7
- CentOS 8
- 下载并编译
- 配置
- 编译和测试
- cmake 后可以跟的参数
- 在Linux上为Windows进行交叉编译
- 在windos上进行编译
- MSVC (2017~2019)
- cmake 后可以跟的参数
- MINGW
- 整合以及使用
- 硬件标志
- 使用场景
- 在物理硬件上执行
- 在虚拟机中执行
- 在容器中执行
- 硬件标识符生成
- 默认标识符生成(实现细节)
- **许可证检索**
- 在你的应用程序中集成 Licensecc
- 构建系统 - 定位并链接 licensecc
- 从你的代码调用 Licensecc
- 颁发许可证:
- 公共 API
- 获取硬件标识符
- **许可证验证**
- 简易demo
- demo环境搭建
- demo目录
- ubuntu
- centos
License简介
什么是LIcense
为了在向客户销售商业软件时实施必要的控制措施,需要对发布的软件进行管理。这些措施包括验证用户身份、检查软件是否已过期以及保护版权信息和开发人员详细信息。
考虑到某些应用程序可能在离线环境中运行,无法进行实时网络验证,因此还需要考虑在单机验证时防止破解的问题。
总而言之,许可证利用 HTTPS 网站的证书和签名技术:一方面,证明当前用户是许可证申请人;另一方面,防止恶意破解和伪造篡改许可证以免费使用软件。
简易License制作
1、获取目标电脑的信息例如:MAC地址、IP地址、主板序列号等等
2、根据目标电脑的MAC地址、IP地址、主板序列号、生成时间、失效时间等生成一个JSON文件
3、软件启动读取JSON和软件启动的电脑配置及当前时间进行对比,如果一样那么符合,软件启动,如果不一样License报错
4、当前JSON就是记事本文件,用户可以随机更该,这肯定不行所以就需要加密
加密扫盲
对称加密
对称加密:也称为对称密码,是指在加密和解密时使用同一密钥得加密方式
非对称加密
有非对称加密必然就会有对称加密,对称加密就是我们一般意义上的加密算法,这种算法在加密和解密时都使用同一个密钥,所以对称加密算法的密钥又叫做共享密钥。对称加密算法一般使用AES(Advanced
Encryption Standard)加密算法。
非对称加密有两个密钥,一个公钥一个私钥。公钥是公开的,供多个人使用;私钥是非公开的,仅一个人或者少数群体使用。
当非对称加密算法用作加解密时,公钥用来对明文加密,私钥用来给密文解密
,这个顺序不能颠倒。你可以这样理解,密文是私密的东西,只有少数人才能解密,所以少数人手里的私钥用来解密,多数人手里的公钥不能解密只能加密。
为什么要区分公钥和私钥呢?直接使用一个共享密钥不行吗?可以,但是前提是你能够安全的将共享密钥传递给对方。共享密钥如何在线上安全的同步给对方是一个问题,毕竟在网络上传输信息很容易暴露。如果使用非对称密钥就可以将公钥同步给消息发送者,而消息接收者则保留私钥用来解密消息,这样即使公钥被中间人盗取,他也只能用来做加密操作而不能解密密文。
签名 &验签
虽然非对称加密可以解决“密钥分配问题”,但是它不能防止伪造消息的问题。既然公钥可以公之于众,大家都知道你的消息要怎么加密,假如A想给B发送消息,那么中间人X可不可以将A发送的消息拦截,并将自己的消息加密以后发送给B呢?当然可以!
这就好比你买了一张周杰伦的演唱会的门票,我看到了之后自己伪造了一个一模一样的,如此一来我也可以去看周杰伦的演唱会。这时官方组织者发现了这个漏洞以后,规定周杰伦的演唱会门票需要带上官方印章才能进场,此时我就算把门票画的再惟妙惟肖,少了官方印章,我的这张假门票依然是张废纸。
如何解决这个问题呢?答案就是给你的消息“盖章”,即签名,签名就是认证你的身份。这里还是使用非对称密钥算法,只不过使用的顺序和加密消息时恰好相反。
签名时是私钥用来加密,公钥用来解密。
你可以这样理解,给消息签名就好比给文件盖章,你会随随便便把你自己的印章交给别人来使用吗?当然不行!所以公钥不适合用来签名,私钥用作签名更加合理。需要注意的是签名所使用的密钥对由消息发送者生成并提供给消息接收者,这和给消息加密时正好相反,这样说来消息加密和消息签名这两个使用场景就需要生成两套密钥对。
出于性能方面的考虑,大多数情况下给消息加密还是使用的对称加密算法,为了解决“密钥分配问题”,只会在第一次发送共享密钥的时候才会使用非对称加密,一旦消息接收者得到了共享密钥,通信双方就能够通过共享密钥进行通信了。
此外,使用非对称密钥对消息签名也可以防止消息被人篡改,由于性能原因一般不会对消息原文进行签名,而是先通过哈希算法形成消息摘要,再对消息摘要签名。消息接收者验签时会将消息的明文进行哈希,再将消息签名解密,两者比对如果一致则证明消息没有被篡改过。
Licensecc使用
构建和编译
在linux上进行编译
Ubuntu
支持的Ubuntu发行版包括20.04(Focal Fossa)、18.04(Bionic Beaver)和16.04(Xenial)。 应该可以在任何较新的Debian派生发行版上进行构建。
Install prerequisites: 安装先决条件:
sudo apt-get install cmake valgrind libssl-dev zlib1g-dev libboost-test-dev libboost-filesystem-dev \
libboost-iostreams-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev \
libboost-date-time-dev build-essential
CentOS 7
CentOS 7 预装了 gcc 4.8,但它无法编译带有正则表达式错误的代码。因此,有必要将 gcc 升级到 4.9 或更高版本。 安装先决条件:
yum -y update && yum -y install install centos-release-scl
yum -y install wget boost boost-devel boost-static openssl openssl-devel openssl-static
yum -y install glibc-static devtoolset-7-toolchain devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-valgrind-devel
export CC=/opt/rh/devtoolset-7/root/usr/bin/gcc
export CXX=/opt/rh/devtoolset-7/root/usr/bin/g++
CentOS 7自带的CMake版本为2.8.11,该版本已不再受支持。您需要编译并安装一个较新的(>3.6)版本的CMake。
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
./bootstrap
make
sudo make install
cmake --version #(check it's 3.11.0)
CentOS 8
Install prerequisites: 安装先决条件:
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
CentOS 8 没有预装静态版本的 OpenSSL。需要从源代码编译安装。
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
sudo make install
Licensecc应该可以在任何近期(2020年)的Linux发行版上编译。我们保持与CentOS 7(较旧的发行版)的兼容性。
最低要求
- gcc => 4.9, cmake => 3.6GCC => 4.9, CMake => 3.6
- zlib, openssl => 1.0.2 zlib, openssl => 1.0.2
- Boost => 1.57 提升至 1.57 (如果您想自行编译 Boost 版本,请记得使用该旗标)
可选的先决条件:
- Doxygen和Sphynx都是用于编写文档的工具。
下载并编译
这个项目有一个子模块(许可证生成器)。请记得在克隆项目时添加该选项
git clone --recursive https://github.com/open-license-manager/licensecc.git
配置
cd licensecc/build
cmake .. -DCMAKE_INSTALL_PREFIX=../install
编译和测试
make
make install
make test
ctest -T memcheck
cmake 后可以跟的参数
定义的名字 | 描述 |
---|---|
LCC_PROJECT_NAME= | 这与正在为其生成许可证的项目名称相对应。 该标志是可选的,如果您不指定它,构建系统将为您创建一个名为 DEFAULT 的项目(该目录如果存在只能生成一次)。 |
LCC_LOCATION= | 如果您单独下载了许可证生成器,那么该文件就安装在该文件夹中,或者可以在该文件夹中找到名为“lcc-config.cmake”的文件 |
CMAKE_BUILD_TYPE=Release | 生成库的发布版本(应作为默认版本使用) |
CMAKE_INSTALL_PREFIX “CMAKE_INSTALL_PREFIX” 是 CMake 的预设变量,用于指定安装程序的根目录。 | 用于安装编译好的库和头文件的文件夹。(默认值:/usr/local) |
BOOST_ROOT | 安装Boost的文件夹(可选:如果您使用系统包管理器安装Boost,则可能不需要指定此文件夹) |
OPENSSL_ROOT | 安装OpenSSL的文件夹(可选:如果您将OpenSSL作为系统包安装,则可能不需要指定此文件夹) |
在Linux上为Windows进行交叉编译
在主机上进行测试:Ubuntu 18.04
先行条件
sudo apt-get install cmake valgrind binutils-mingw-w64 mingw-w64 mingw-w64-tools \
mingw-w64-x86-64-dev libz-mingw-w64-dev wine-stable wine-binfmt p7zip-full
下载并编译Boost:
export CUR_PATH=$(pwd)
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
rm boost_1_71_0.tar.bz2
cd boost_1_71_0
sudo ln -s /usr/bin/x86_64-w64-mingw32-g++ /usr/local/bin/g++-mingw
./bootstrap.sh
./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
安装OpenSSL:
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
rm openssl.7z
配置并编译:
cmake -DCMAKE_TOOLCHAIN_FILE=../modules/toolchain-ubuntu-mingw64.cmake -DOPENSSL_ROOT_DIR=$CUR_PATH/openssl-OpenSSL_1_1_1d/dist -DCMAKE_FIND_DEBUG_MODE=ON -DOPENSSL_USE_STATIC_LIBS=ON -DBOOST_ROOT=$CUR_PATH/boost_1_71_0/dist ..
编写文档
创建Python虚拟环境:
python3 -m venv .venv
. .venv/bin/activate
pip install wheel
pip install -r requirements.txt
构建文档
. .venv/bin/activate
cd build
cmake ..
make documentation
在windos上进行编译
本页介绍如何在Windows平台上构建该库。支持MSVC编译器和MinGW。
MSVC (2017~2019)
支持的Visual Studio版本如下:
- 最新的Visual Studio 2019(用于开发)
- 在Travis.ci上使用Visual Studio 2017进行自动化测试。
MSVC安装前置条件
Git是必备条件。如果您没有安装Git,可以从Git-scm.com下载。
可以在SourceForge上找到Boost的预编译版本https://sourceforge.net/projects/boost/files/boost-binaries/。选择与所需架构匹配的版本(例如,如果您需要使用Visual Studio 2019 64位,可以下载https://dl.bintray.com/boostorg/release/1.71.0/binaries/boost_1_71_0-bin-msvc-all-32-64.7z和https://dl.bintray.com/boostorg/release/1.71.0/binaries/boost_1_71_0-msvc-14.2-64.exe
使用Boost 1.71时,建议下载最新版本的CMake(版本号大于3.16)。Visual Studio 2019版本并非最新版本。
检查代码
使用Git检查代码:
[!NOTE]
这个项目有一个子模块(许可证生成器)。记得在克隆时使用选项
-recursive
。
git clone --recursive https://github.com/open-license-manager/open-license-manager.git
编译和构建(命令行)
在你检出库所在的文件夹中打开命令提示窗口。
配置该库(Windows x64):
cd build
cmake .. -G "Visual Studio 16 2019" -A x64 -DBOOST_ROOT="C:\local\boost" //(or where boost was installed)
配置该库(Windows x86):
由于某些配置原因,我们无法使用Visual Studio生成器在x86架构上构建。我们建议使用Ninja构建系统。
cd build
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86
cmake .. -G "Ninja" -DBOOST_ROOT="C:\local\boost" //(or where boost was installed)
支持的CMake定义/选项
cmake 后可以跟的参数
定义的名字 | 描述 |
---|---|
-DSTATIC_RUNTIME=1 | 静态链接到标准库和运行时支持库(编译器标志/MT) |
-DCMAKE_BUILD_TYPE=Release | 链接到Boost库的发布版本。 |
-DCMAKE_INSTALL_PREFIX=C:… | 安装库和头文件的文件夹 |
-DBOOST_ROOT=C:… -DBOOST_ROOT=C:… | 将 boost 安装到某个文件夹中。如果 cmake 报告找不到 boost,请考虑更新 cmake。 |
编译和测试
cmake --build . --target install --config Release
ctest -C Release
编译和构建(Visual Studio 2019)
Visual Studio 2019与CMake集成(此过程需要重启几次,但并非完全“流畅”)。
在以“作为CMake项目”方式打开项目后,应在根目录中出现一个名为“CMakeSettings.json”的文件。按照以下方式编辑该文件(该文件适用于x86架构)。特别要注意的是: 在CMake项目中,我们需要指定要使用的CMake版本。为此,我们需要在CMakeSettings.json文件中添加以下内容:
{
"configurations": [
{
"name": "x86-Debug",
"generator": "Visual Studio 16 2019",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeExecutable": "C:/Program Files/CMake/bin/cmake.exe",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"intelliSenseMode": "windows-msvc-x86",
"variables": [
{
"name": "BOOST_ROOT",
"value": "F:/boost_1_71_0",
"type": "PATH"
}
]
}
]
}
MINGW
[!NOTE]
说明如何安装和配置 mingw
前提条件
- Powershell
- 7zip
- git
- cmake
安装和编译boost:
wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.7z
7z x boost_1_68_0.7z -oC:/local
cd "C:\local\boost_1_68_0"
bootstrap.bat gcc
b2.exe -d0 --with-date_time --with-test --with-filesystem --with-program_options --with-regex --with-serialization --with-system runtime-link=static toolset=gcc --prefix=C:\local\boost_1_68_0\boost-mingw install
cd C:/local/boost_1_68_0/boost-mingw/lib
dir
确认是否已正确编译了许可证服务器。请前往您想要下载许可证服务器的文件夹。
git clone --recursive https://github.com/open-license-manager/open-license-manager.git
cd build && cmake -G "MinGW Makefiles" -DBOOST_ROOT="C:/local/boost_1_68_0/boost-mingw" -DBoost_ARCHITECTURE="-x64" -DCMAKE_CXX_COMPILER_ARCHITECTURE_ID="x64" -DCMAKE_SH="CMAKE_SH-NOTFOUND" ..
cmake --build . --target install --config Release
接下来进行测试
ctest -C Release
整合以及使用
硬件标志
硬件标识符用于将软件的执行与物理硬件(如PC)关联起来。当客户端的软件发现许可证丢失时,它会调用API“identify_pc”并生成一个硬件标识符。客户端必须将硬件ID返回给软件发行商,后者将为其颁发许可证(有关详细信息,请参见“颁发许可证”)。
[!NOTE]
Licensecc 会猜测用户试图启动软件的环境(例如虚拟机),并将相关信息嵌入硬件ID中,在颁发许可证之前将信息报告给软件发行商。
使用场景
随着虚拟化环境的出现,软件直接在机器上安装的情况越来越少。
在物理硬件上执行
如果客户端在物理硬件上运行该软件,可以通过多种参数(CPU类型/内存/磁盘标签/MAC地址)来识别硬件。有关支持的识别策略的详细信息,请参见“功能”部分。
在虚拟机中执行
如果你允许软件用户在虚拟机中生成PC标识符,你应该问自己这样做的真正用途是什么,因为虚拟机可以被完整地复制到其他地方,而且很难检测到这一点(除非使用尚未支持此库的外部许可证服务器)
- 通常情况下,当机器被复制时,MAC地址会发生变化。但是有时MAC地址会自动发生变化。软件发行商可能会将其作为最后一种手段来防止虚拟机被复制。具体情况需要逐一验证。
- 软件编辑者可能希望防止人们从虚拟机中提取软件。他们可以使用一个隐藏的注册表键或位于安装目录之外的特定文件来验证软件是在原始虚拟机中分发的。或者,他们可以将执行与特定类型的虚拟化进行链接(OpenLicenseManager支持此功能)。
[!NOTE]
在这种情况下,建议仅限日期的试用许可证。
在容器中执行
取决于容器是如何使用的,是否需要包含硬件标识符可能有意义或毫无意义。例如,如果容器用于避免污染外部分发环境,那么包含硬件标识符是完全有意义的。但如果用户在云中的Kubernetes集群中运行Docker,则包含硬件标识符毫无意义。
硬件标识符生成
授权应用程序将调用API方法“identify_pc”来生成硬件标识符,并将其打印给用户查看。用户随后将联系软件许可方获取相应的许可证。
授权应用程序可以使用参数来指定标识策略(参见: ),也可以让 licensecc 自动选择如何生成标识符(通过传递 hw_id_method=STRATEGY_DEFAULT)。在这种情况下,licensecc 能够识别用户正在运行的虚拟环境并选择适当的生成策略。
下面是“identify_pc”方法使用的完整标识符生成工作流。
默认标识符生成(实现细节)
本节介绍默认硬件标识策略的内部工作原理。
当授权软件调用identify_pc时,标识生成将遵循以下步骤:
- 它会首先查看环境变量IDENTIFICATION_STRATEGY。如果已经设置,它将使用该变量中的识别策略。
- 它会尝试确定已授权软件正在运行的虚拟环境。
- 如果未找到虚拟环境,它将使用
LCC_BARE_TO_METAL_STRATEGIES
中的策略,它将逐个尝试这些策略,直到第一个策略成功。 - 如果它检测到正在虚拟机中运行,它将尝试
LCC_VM_STRATEGIES
中的策略,它将逐个尝试这些策略,直到第一个策略成功。
- 如果未找到虚拟环境,它将使用
如果你想实现自己的硬件识别策略,可以查看一下这个库。
http://open-license-manager.github.io/licensecc/api/extend.html#tweak-hardware-signature-generator
[!NOTE]
无论当前使用的默认方法是什么,licensecc都会尝试使用与生成标识符时相同的策略对其进行验证。例如:磁盘标识符始终将通过“.”进行验证。
许可证检索
licensecc 如何查找许可证文件
当 licensecc 集成到软件中时,它可以根据以下内容自动查找其许可证文件(或多个许可证文件):
环境变量:
- 在环境变量
LICENSE_LOCATION
中放置许可证文件的完整路径,库将查找它。多个许可证文件可以用“;”分隔。 - 在环境变量
LICENSE_DATA
中放置完整的许可证内容,将允许库加载它。
将许可证放在许可可执行文件的同一文件夹中,将使软件找到自己的许可证。文件名必须与可执行文件相同,扩展名为 .lic
。例如,如果你正在许可 my_awesome_software.exe
,许可证文件必须位于同一文件夹中,并且必须称为 my_awesome_software.lic
。
**调用应用程序可以使用 LicenseLocation
结构指定位置(或完整的许可证数据)。**实现并注册接口 LicenseLocator
,软件作者可以轻松地定义自己的策略。
在你的应用程序中集成 Licensecc
本简短指南解释了如何在你的应用程序中集成 licensecc。
示例项目中提供了工作示例https://github.com/open-license-manager/examples。
构建系统 - 定位并链接 licensecc
我们强烈建议使用 CMake 作为构建系统。如果是这种情况,最简单的编译方法是将 LicenseCC 配置为项目的 git 子模块。
然后,你可以将 cmake 模块 Findlicensecc.cmake
复制到 cmake 模块目录中,以便能够找到已编译的库。
将以下行添加到你的 CMakeLists.txt
:
find_package(licensecc 2.0.0 REQUIRED)
将使外部目标 licensecc::licensecc_static
可用于链接。
Findlicensecc.cmake
将以下 CMake 变量作为输入。
CMake 变量 | 说明 |
---|---|
LICENSECC_LOCATION | 如果 licensecc 未检出为 git 子模块,你可以在此变量中提供提示以找到库。它可以指向安装文件夹或源文件夹。 |
LCC_PROJECT_NAME | 项目的名称(你要集成 licensecc 的软件)。 |
或者,可以在 find_package
的 component
部分中指定组件名称。
从你的代码调用 Licensecc
包含公共 API 的文件是 include/licensecc/licensecc.h
。其中的函数被认为是稳定的。
请参阅公共 API 了解如何生成硬件标识符或验证许可证。
颁发许可证:
1. 创建项目结构:
-
在所需位置创建一个 projects 文件夹。
-
在 projects 文件夹内,创建一个子文件夹并将其命名为 DEFAULT(或你项目的名称)。
-
在 DEFAULT 文件夹内,创建以下子文件夹:
- include/licensecc/DEFAULT
- licenses
-
向 DEFAULT 文件夹中添加一个 private_key.rsa 文件。
-
projects └── DEFAULT #(your project name) ├── include │ └── licensecc │ └── DEFAULT │ ├── licensecc_properties.h │ └── public_key.h ├── licenses │ └── test.lic └── private_key.rsa
2. 将 lcc 可执行文件放入你的路径:
- lcc 可执行文件通常位于你的构建树或安装目录中。将它添加到你的系统路径中。
3. 颁发永久无限许可证:
cd projects/DEFAULT
lcc license issue -o licenses/{license-file-name}.lic
4. 颁发与硬件标识符关联的许可证:
- 从目标机器获取硬件标识符(例如,使用 lcc inspector)。
- 颁发以下命令:
lcc license issue --client-signature XXXX-XXXX-XXXX -o licenses/{license-file-name}.lic
其他选项:
- **base64,b:**对许可证进行编码以用于环境变量。
- **valid-from:**设置许可证有效期的开始日期(YYYY-MM-DD)。如果未指定,则默认为当天。
- **valid-to:**设置许可证的到期日期(YYYY-MM-DD)。如果未指定,则许可证不会过期。
- **client-signature:**被许可软件运行所在的机器的硬件标识符。
- **output-file-name:**为许可证指定输出文件路径。
- **extra-data:**在许可证中包含特定于应用程序的数据。在调用 acquire_license 方法时将会返回这些数据。
- **feature-names:**在多功能上下文中指定要许可的功能的逗号分隔列表。
注意:
- 项目充当 licensecc 自定义项的容器,包括密钥和构建参数。
- 项目名称显示在已颁发的许可证文件中。
公共 API
该库的公共 API 可以在 include/licensecc/licensecc.h 找到,这是在使用库时唯一应该包含的文件。
获取硬件标识符
**bool identify_pc(LCC_API_HW_IDENTIFICATION_STRATEGY hw_id_method, char identifier_out, size_t buf_size, ExecutionEnvironmentInfo *execution_environment_info)
计算与特定电脑关联的硬件标识符。
当调用者没有找到有效的许可证(见下文的 acquire_license)时,应向用户显示计算出的标识符。用户应向软件编辑者报告 pc_identifier,软件编辑者随后会用它来颁发许可证。
pc_id_method = STRATEGY_DEFAULT 通常是最佳选择。
首先使用 identifier_out = nullptr 和 buf_size = 0 调用此方法,它会在 buf_size 参数中返回请求的缓冲区大小。
然后分配必要的内存,然后再次调用此方法。
返回值
如果成功,则返回 true;如果失败(因为不可能识别或缓冲区太小),则返回 false。
参数
- hw_id_method[in]:指定首选识别方法。通常 STRATEGY_DEFAULT 适用于大多数情况。有关更多信息,请参阅 wiki。
- identifier_out[out]:将放置识别字符串的缓冲区。
- buf_size[in-out]:将放置识别字符串的缓冲区的大小。
- execution_environment_info[out]:如果不是 null,将包含有关执行环境的信息。
enum LCC_API_HW_IDENTIFICATION_STRATEGY
此枚举列出了所有可能的电脑识别策略。用作 identify_pc 的参数。
STRATEGY_DEFAULT 在大多数情况下都应该使用。
值:
enumeratorSTRATEGY_DEFAULT
默认策略。
此策略首先检查环境变量 IDENTIFICATION_STRATEGY 的内容。如果变量已定义,它将使用其中指定的策略;如果未定义,它将尝试检测软件在哪个虚拟环境中运行。
- 如果未检测到虚拟环境,它将尝试 LCC_BARE_TO_METAL_STRATEGIES 中定义的策略
- 如果检测到软件在虚拟机中运行,它将使用 LCC_VM_STRATEGIES
- 如果检测到软件在 docker 或 LXC 中运行,它将使用::LCC_DOCKER_STRATEGIES 或::LCC_DOCKER_STRATEGIES
- 如果检测到软件在云中的虚拟机中运行,它将使用 LCC_CLOUD_STRATEGIES
enumeratorSTRATEGY_ETHERNET
enumeratorSTRATEGY_IP_ADDRESS
enumeratorSTRATEGY_DISK
enumeratorSTRATEGY_CPU_SIZE
尚未实现
enumeratorSTRATEGY_HOST_NAME
尚未实现
enumeratorSTRATEGY_NONE
LCC_BARE_TO_METAL_STRATEGIES
当未检测到虚拟环境时,列出所用的策略
LCC_VM_STRATEGIES
软件在虚拟机中执行时使用的策略列表
LCC_LXC_STRATEGIES
LCC_DOCKER_STRATEGIES
LCC_CLOUD_STRATEGIES
检测到在云中执行时使用的策略列表
许可证验证
LCC_EVENT_TYPE acquire_license(constCallerInformations *callerInformation, constLicenseLocation *licenseLocation, LicenseInfo *license_out)
此方法用于请求使用一个产品许可证。若是本地许可证,则用于检查产品是否已获得许可。
返回
- LCC_EVENT_TYPE::LICENSE_OK(0):成功
- 其他值:如有错误
参数
- callerInformation[in]:可选,可为 NULL。包含关于请求许可证验证的软件的信息。让软件指定其版本或请求单独启用所需功能的验证。
- licenseLocation[in]:可选,可为 NULL。许可证位置,文件名称或环境变量的名称应不等于“\0”。
- license_out[out]:可选,可为 NULL。如果设置,它将返回有关许可证的额外信息。
structCallerInformations
请求许可证验证的软件信息(例如,软件版本、要验证的功能)。
公共成员
- char version[LCC_API_VERSION_LENGTH + 1]
软件版本格式 xxxx[.xxxx.xxxx] 未实现,传递“\0” - char feature_name[LCC_API_FEATURE_NAME_SIZE + 1]
要验证的功能的名称。如果为空(\0),将验证“default”功能。(每个项目都有一个默认功能,等于项目名称)。每个功能在许可证文件中都有一个单独的节: - unsigned int magic
应用程序传递的此数字必须与编译库时使用的魔术数字相对应。请参阅 cmake 参数 -DLCC_PROJECT_MAGIC_NUM 和 licensecc_properties.h 宏 VERIFY_MAGIC
structLicenseLocation
此结构包含有关原始许可证数据的信息。软件作者可以指定许可证文件的位置或其全部内容。
可为 NULL,在这种情况下,OpenLicenseManager 将尝试自行找出许可证文件的位置。
structLicenseInfo
公共成员
- AuditEvent status[LCC_API_AUDIT_EVENT_NUM]
成功/失败的详细原因。失败的原因可能有多个(例如,许可证已过期且签名未验证)。仅报告最后 AUDIT_EVENT_NUM 个。 - char expiry_date[LCC_API_EXPIRY_DATE_SIZE + 1]
软件的最终到期日期,如果软件不会过期,则可以为“\0”
简易demo
demo环境搭建
1、优先安装licensecc环境
2、git clone --recursive https://github.com/open-license-manager/licensecc.git
3、在licensecc目录中mkdir
4、mkdir build
5、cd build
6、cmake LCC_PROJECT_NAME=“项目名称” …
7、make
8、make install DESTDIR= ./
9、会看生成对应的文件,并且会在licensecc/project/你指定的项目名称/中看到你生成的公钥和私钥,后面生成license的时候会用到
10、生成文件中有licensecc_properties.h和liblicensecc_static.a 请复制到demo中去使用。
demo目录
demo
└── build
└── inc
├── licensecc
└── datatypes.h
└── licensecc.h
├── licensecc_properties.h
└── lib
├── liblicensecc_static.a
└── src
├── demo.cpp
└── CMakeLists.txt
在上面目录中 licensecc_properties.h 和 liblicensecc_static.a都是由licensecc生成的,其中 liblicensecc_static.a 包含着license中的公钥。licensecc_properties.h包含着你cmake LCC_PROJECT_NAME=“项目名称” … 的时候 的项目名称
demo.cpp
#include <iostream>
#include <unordered_map>
#include <licensecc/licensecc.h>
using namespace std;
int main(int argc, char *argv[]) {
unordered_map<LCC_EVENT_TYPE, string> stringByEventType = {
{LICENSE_OK, "OK "},
{LICENSE_FILE_NOT_FOUND, "许可证文件不存在 "},
{LICENSE_SERVER_NOT_FOUND, "无法联系许可证服务器 "},
{ENVIRONMENT_VARIABLE_NOT_DEFINED, "未定义环境变量 "},
{FILE_FORMAT_NOT_RECOGNIZED, "许可证文件格式无效(不是 .ini 文件) "},
{LICENSE_MALFORMED, "缺少某些必需字段,或无法完整读取数据 "},
{PRODUCT_NOT_LICENSED, "此产品未获得许可 "},
{PRODUCT_EXPIRED, "许可证已过期 "},
{LICENSE_CORRUPTED, "许可证签名与当前许可证不匹配 "},
{IDENTIFIERS_MISMATCH, "已计算标识符与许可证中提供的标识符不匹配"}};
LicenseInfo licenseInfo;
LicenseLocation licenseLocation = {LICENSE_PATH,"file.lic"};
// string filePath = "";
// copy(filePath.begin(), filePath.end(), licenseLocation.licenseData);
LCC_EVENT_TYPE result = acquire_license(nullptr, &licenseLocation, &licenseInfo);
if (result == LICENSE_OK) {
cout << "许可证正常" << endl;
if (!licenseInfo.linked_to_pc) {
cout << "许可证文件中没有硬件签名。这是一个“演示”许可证,适用于所有电脑。" << endl
<< "要生成“单一电脑”许可证,请使用选项 -s 调用“发行许可证”,并使用之前获得的硬件标识符。" << endl;
}
}
if (result != LICENSE_OK) {
size_t pc_id_sz = LCC_API_PC_IDENTIFIER_SIZE;
char pc_identifier[LCC_API_PC_IDENTIFIER_SIZE + 1];
cout << "许可证错误:" << endl;
cout << " " << stringByEventType[result].c_str() << endl;
if (identify_pc(STRATEGY_DEFAULT, pc_identifier, &pc_id_sz, nullptr)) {
cout << "电脑签名为:" << endl;
cout << " " << pc_identifier << endl;
} else {
cerr << "identify_pc 出现错误" << endl;
}
}
return result;
}
ubuntu
CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project (demo VERSION 1.0.0 LANGUAGES CXX)
SET(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/inc)
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib)
add_executable(demo src/demo.cpp)
target_link_libraries(demo liblicensecc_static.a ${OPENSSL_CRYPTO_LIBRARY} -pthread -ldl)
centos
cmake_minimum_required(VERSION 3.6)
project (demo VERSION 1.0.0 LANGUAGES CXX)
SET(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/inc)
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib)
add_executable(demo src/demo.cpp)
target_link_libraries(demo liblicensecc_static.a ${OPENSSL_CRYPTO_LIBRARY} -lz -pthread -ldl)
在第一个语法中,-pthread
和 -ldl
被链接在 liblicensecc_static.a
和 OPENSSL_CRYPTO_LIBRARY
之后。
在第二个语法中,-lz
、-pthread
和 -ldl
被链接在 liblicensecc_static.a
和 OPENSSL_CRYPTO_LIBRARY
之前。