mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-11 16:57:14 +08:00
feat(license): 增加核心模块,优化代码结构
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-license</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<artifactId>continew-starter-license-core</artifactId>
|
||||
<description>ContiNew Starter License核心模块</description>
|
||||
<dependencies>
|
||||
|
||||
<!-- continew starter 核心模块 -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- license 依赖-->
|
||||
<dependency>
|
||||
<groupId>de.schlichtherle.truelicense</groupId>
|
||||
<artifactId>truelicense-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--zip4j压缩文件-->
|
||||
<dependency>
|
||||
<groupId>net.lingala.zip4j</groupId>
|
||||
<artifactId>zip4j</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.exception;
|
||||
|
||||
import top.continew.starter.core.exception.BaseException;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 自定义证书认证异常
|
||||
*
|
||||
* @author loach
|
||||
* @author echo
|
||||
* @since 2.11.0
|
||||
*/
|
||||
public class LicenseException extends BaseException {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public LicenseException() {
|
||||
}
|
||||
|
||||
public LicenseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LicenseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public LicenseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 生成创建者返回参数
|
||||
*
|
||||
* @author echo
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class BuildCreatorResp implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 许可证创建者参数
|
||||
*/
|
||||
private LicenseCreatorParam param;
|
||||
|
||||
/**
|
||||
* 客户端zip文件
|
||||
*/
|
||||
private ZipFile clientZipFile;
|
||||
|
||||
public BuildCreatorResp(LicenseCreatorParam param, ZipFile clientZipFile) {
|
||||
this.param = param;
|
||||
this.clientZipFile = clientZipFile;
|
||||
}
|
||||
|
||||
public BuildCreatorResp() {
|
||||
}
|
||||
|
||||
public LicenseCreatorParam getParam() {
|
||||
return param;
|
||||
}
|
||||
|
||||
public void setParam(LicenseCreatorParam param) {
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public ZipFile getClientZipFile() {
|
||||
return clientZipFile;
|
||||
}
|
||||
|
||||
public void setClientZipFile(ZipFile clientZipFile) {
|
||||
this.clientZipFile = clientZipFile;
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
/**
|
||||
* config参数
|
||||
*
|
||||
* @author loach
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class ConfigParam {
|
||||
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
private String subject;
|
||||
|
||||
/**
|
||||
* 公钥别称
|
||||
*/
|
||||
private String publicAlias;
|
||||
|
||||
/**
|
||||
* 访问公钥库的密码
|
||||
*/
|
||||
private String storePass;
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getPublicAlias() {
|
||||
return publicAlias;
|
||||
}
|
||||
|
||||
public void setPublicAlias(String publicAlias) {
|
||||
this.publicAlias = publicAlias;
|
||||
}
|
||||
|
||||
public String getStorePass() {
|
||||
return storePass;
|
||||
}
|
||||
|
||||
public void setStorePass(String storePass) {
|
||||
this.storePass = storePass;
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
import de.schlichtherle.license.AbstractKeyStoreParam;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 自定义密钥存储参数
|
||||
*
|
||||
* @author loach
|
||||
* @author echo
|
||||
* @since 2.11.0
|
||||
*/
|
||||
public class CustomKeyStoreParam extends AbstractKeyStoreParam {
|
||||
/**
|
||||
* 密钥路径,可为磁盘路径,也可为项目资源文件里的路径,如果为磁盘路径需重写getStream()方法
|
||||
*/
|
||||
private String storePath;
|
||||
|
||||
/**
|
||||
* 公钥或私钥的别名
|
||||
*/
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 访问公钥/私钥库的密码
|
||||
*/
|
||||
private String storePass;
|
||||
|
||||
/**
|
||||
* 公钥/私钥的密码
|
||||
*/
|
||||
private String keyPass;
|
||||
|
||||
public CustomKeyStoreParam(Class aClass, String s) {
|
||||
super(aClass, s);
|
||||
}
|
||||
|
||||
public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePass, String keyPass) {
|
||||
super(clazz, resource);
|
||||
this.storePath = resource;
|
||||
this.alias = alias;
|
||||
this.storePass = storePass;
|
||||
this.keyPass = keyPass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStorePwd() {
|
||||
return storePass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyPwd() {
|
||||
return keyPass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getStream() throws IOException {
|
||||
return new FileInputStream(storePath);
|
||||
}
|
||||
}
|
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 许可证创建者参数
|
||||
*
|
||||
* @author loach
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class LicenseCreatorParam implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 证书主题
|
||||
*/
|
||||
private String subject;
|
||||
|
||||
/**
|
||||
* 私钥别称
|
||||
*/
|
||||
private String privateAlias;
|
||||
|
||||
/**
|
||||
* 私钥密码
|
||||
*/
|
||||
private String keyPass;
|
||||
|
||||
/**
|
||||
* 访问公钥库的密码
|
||||
*/
|
||||
private String storePass;
|
||||
|
||||
/**
|
||||
* 证书生成路径
|
||||
*/
|
||||
private String licensePath;
|
||||
|
||||
/**
|
||||
* 私钥库存储路径
|
||||
*/
|
||||
private String privateKeysStorePath;
|
||||
|
||||
/**
|
||||
* 证书生效时间
|
||||
*/
|
||||
private Date issuedTime = new Date();
|
||||
|
||||
/**
|
||||
* 证书失效时间
|
||||
*/
|
||||
private Date expiryTime;
|
||||
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
private String consumerType = "user";
|
||||
|
||||
/**
|
||||
* 用户数量
|
||||
*/
|
||||
private Integer consumerAmount = 1;
|
||||
|
||||
/**
|
||||
* 描述信息
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 额外的服务器硬件校验信息
|
||||
*/
|
||||
private LicenseExtraModel licenseExtraModel;
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getPrivateAlias() {
|
||||
return privateAlias;
|
||||
}
|
||||
|
||||
public void setPrivateAlias(String privateAlias) {
|
||||
this.privateAlias = privateAlias;
|
||||
}
|
||||
|
||||
public String getKeyPass() {
|
||||
return keyPass;
|
||||
}
|
||||
|
||||
public void setKeyPass(String keyPass) {
|
||||
this.keyPass = keyPass;
|
||||
}
|
||||
|
||||
public String getStorePass() {
|
||||
return storePass;
|
||||
}
|
||||
|
||||
public void setStorePass(String storePass) {
|
||||
this.storePass = storePass;
|
||||
}
|
||||
|
||||
public String getLicensePath() {
|
||||
return licensePath;
|
||||
}
|
||||
|
||||
public void setLicensePath(String licensePath) {
|
||||
this.licensePath = licensePath;
|
||||
}
|
||||
|
||||
public String getPrivateKeysStorePath() {
|
||||
return privateKeysStorePath;
|
||||
}
|
||||
|
||||
public void setPrivateKeysStorePath(String privateKeysStorePath) {
|
||||
this.privateKeysStorePath = privateKeysStorePath;
|
||||
}
|
||||
|
||||
public Date getIssuedTime() {
|
||||
return issuedTime;
|
||||
}
|
||||
|
||||
public void setIssuedTime(Date issuedTime) {
|
||||
this.issuedTime = issuedTime;
|
||||
}
|
||||
|
||||
public Date getExpiryTime() {
|
||||
return expiryTime;
|
||||
}
|
||||
|
||||
public void setExpiryTime(Date expiryTime) {
|
||||
this.expiryTime = expiryTime;
|
||||
}
|
||||
|
||||
public String getConsumerType() {
|
||||
return consumerType;
|
||||
}
|
||||
|
||||
public void setConsumerType(String consumerType) {
|
||||
this.consumerType = consumerType;
|
||||
}
|
||||
|
||||
public Integer getConsumerAmount() {
|
||||
return consumerAmount;
|
||||
}
|
||||
|
||||
public void setConsumerAmount(Integer consumerAmount) {
|
||||
this.consumerAmount = consumerAmount;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public LicenseExtraModel getLicenseExtraModel() {
|
||||
return licenseExtraModel;
|
||||
}
|
||||
|
||||
public void setLicenseExtraModel(LicenseExtraModel licenseExtraModel) {
|
||||
this.licenseExtraModel = licenseExtraModel;
|
||||
}
|
||||
}
|
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 为用户生成证书需要的具体参数
|
||||
*
|
||||
* @author loach
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class LicenseCreatorParamVO {
|
||||
|
||||
/**
|
||||
* 有效期截至时间
|
||||
*/
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 公钥钥库密码库,必须包含数字和字母
|
||||
*/
|
||||
private String storePass;
|
||||
|
||||
/**
|
||||
* 私钥密码,必须包含数字和字母
|
||||
*/
|
||||
private String keyPass;
|
||||
|
||||
/**
|
||||
* 描述信息
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* license 保存位置
|
||||
*/
|
||||
private String licenseSavePath;
|
||||
|
||||
/**
|
||||
* 额外的服务器硬件校验信息
|
||||
*/
|
||||
private LicenseExtraModel licenseExtraModel;
|
||||
|
||||
public Date getExpireTime() {
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
public void setExpireTime(Date expireTime) {
|
||||
this.expireTime = expireTime;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public String getStorePass() {
|
||||
return storePass;
|
||||
}
|
||||
|
||||
public void setStorePass(String storePass) {
|
||||
this.storePass = storePass;
|
||||
}
|
||||
|
||||
public String getKeyPass() {
|
||||
return keyPass;
|
||||
}
|
||||
|
||||
public void setKeyPass(String keyPass) {
|
||||
this.keyPass = keyPass;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getLicenseSavePath() {
|
||||
return licenseSavePath;
|
||||
}
|
||||
|
||||
public void setLicenseSavePath(String licenseSavePath) {
|
||||
this.licenseSavePath = licenseSavePath;
|
||||
}
|
||||
|
||||
public LicenseExtraModel getLicenseExtraModel() {
|
||||
return licenseExtraModel;
|
||||
}
|
||||
|
||||
public void setLicenseExtraModel(LicenseExtraModel licenseExtraModel) {
|
||||
this.licenseExtraModel = licenseExtraModel;
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.model;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 额外的服务器硬件校验信息对象,这里的属性可根据需求自定义
|
||||
*
|
||||
* @author loach
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class LicenseExtraModel {
|
||||
|
||||
/**
|
||||
* 可被允许的IP地址
|
||||
*/
|
||||
private Set<String> ipAddress;
|
||||
|
||||
/**
|
||||
* 可被允许的mac地址
|
||||
*/
|
||||
private Set<String> macAddress;
|
||||
|
||||
/**
|
||||
* 可被允许的CPU序列号
|
||||
*/
|
||||
private String cpuSerial;
|
||||
|
||||
/**
|
||||
* 可被允许的主板序列号
|
||||
*/
|
||||
private String mainBoardSerial;
|
||||
|
||||
public Set<String> getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(Set<String> ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public Set<String> getMacAddress() {
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public void setMacAddress(Set<String> macAddress) {
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public String getCpuSerial() {
|
||||
return cpuSerial;
|
||||
}
|
||||
|
||||
public void setCpuSerial(String cpuSerial) {
|
||||
this.cpuSerial = cpuSerial;
|
||||
}
|
||||
|
||||
public String getMainBoardSerial() {
|
||||
return mainBoardSerial;
|
||||
}
|
||||
|
||||
public void setMainBoardSerial(String mainBoardSerial) {
|
||||
this.mainBoardSerial = mainBoardSerial;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.util;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
|
||||
/**
|
||||
* 运行命令行工具类
|
||||
*
|
||||
* @author loach
|
||||
* @since 2.11.0
|
||||
**/
|
||||
public class ExecCmdUtil {
|
||||
|
||||
private static final String CREATE_3RDSESSION_SHELL_SCRIPT = "head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 168";
|
||||
|
||||
/**
|
||||
* 执行cmd命令(shell脚本)
|
||||
*
|
||||
* @param cmd linux sh/windows bat命令
|
||||
* @return String 返回打印信息
|
||||
*/
|
||||
public static String exec(String... cmd) throws IOException {
|
||||
Process process;
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (cmd != null && cmd.length == 1) {
|
||||
process = Runtime.getRuntime().exec(cmd[0]);
|
||||
} else {
|
||||
process = Runtime.getRuntime().exec(cmd);
|
||||
}
|
||||
} else {
|
||||
cmd = ArrayUtil.addAll(new String[] {"/bin/sh", "-c"}, cmd);
|
||||
process = Runtime.getRuntime().exec(cmd);
|
||||
}
|
||||
|
||||
String print = readProcess(process.getInputStream());
|
||||
String err = readProcess(process.getErrorStream());
|
||||
return print + " " + err;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 InputStream 内容为字符串(使用 GBK 编码)。
|
||||
*
|
||||
* @param in 输入流
|
||||
* @return 拼接后的字符串,读取失败返回空字符串
|
||||
*/
|
||||
private static String readProcess(InputStream in) {
|
||||
try (LineNumberReader print = new LineNumberReader(new InputStreamReader(in, "GBK"))) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String line;
|
||||
while ((line = print.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行linux命令(shell脚本)生成3rd_session随机数
|
||||
*/
|
||||
public static String create3rdSessionToken() throws IOException {
|
||||
|
||||
return exec(CREATE_3RDSESSION_SHELL_SCRIPT);
|
||||
}
|
||||
}
|
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.license.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import top.continew.license.exception.LicenseException;
|
||||
import top.continew.license.model.LicenseExtraModel;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 服务器信息工具类
|
||||
*
|
||||
* @author Rong.Jia
|
||||
* @since 2.11.0
|
||||
*/
|
||||
public class ServerInfoUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ServerInfoUtils.class);
|
||||
|
||||
private static class ServerInfosContainer {
|
||||
private static Set<String> ipAddress = null;
|
||||
private static Set<String> macAddress = null;
|
||||
private static String cpuSerial = null;
|
||||
private static String mainBoardSerial = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装需要额外校验的License参数
|
||||
*
|
||||
* @return {@link LicenseExtraModel }
|
||||
*/
|
||||
public static LicenseExtraModel getServerInfos() {
|
||||
LicenseExtraModel result = new LicenseExtraModel();
|
||||
try {
|
||||
initServerInfos();
|
||||
result.setIpAddress(ServerInfosContainer.ipAddress);
|
||||
result.setMacAddress(ServerInfosContainer.macAddress);
|
||||
result.setCpuSerial(ServerInfosContainer.cpuSerial);
|
||||
result.setMainBoardSerial(ServerInfosContainer.mainBoardSerial);
|
||||
} catch (Exception e) {
|
||||
log.error("获取服务器硬件信息异常", e);
|
||||
throw new LicenseException(String.format("获取服务器硬件信息异常, %s", e.getMessage()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化服务器硬件信息,并将信息缓存到内存
|
||||
*
|
||||
* @throws Exception 例外
|
||||
*/
|
||||
private static void initServerInfos() throws Exception {
|
||||
if (ServerInfosContainer.ipAddress == null) {
|
||||
ServerInfosContainer.ipAddress = getIpAddress();
|
||||
}
|
||||
if (ServerInfosContainer.macAddress == null) {
|
||||
ServerInfosContainer.macAddress = getMacAddress();
|
||||
}
|
||||
if (ServerInfosContainer.cpuSerial == null) {
|
||||
ServerInfosContainer.cpuSerial = getCpuSerial();
|
||||
}
|
||||
if (ServerInfosContainer.mainBoardSerial == null) {
|
||||
ServerInfosContainer.mainBoardSerial = getMainBoardSerial();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器临时磁盘位置
|
||||
*
|
||||
* @return {@link String}
|
||||
*/
|
||||
public static String getServerTempPath() {
|
||||
return System.getProperty("user.dir");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取CPU序列号
|
||||
*
|
||||
* @return String CPU 序列号
|
||||
*/
|
||||
public static String getCpuSerial() {
|
||||
return FileUtil.isWindows() ? getWindowCpuSerial() : getLinuxCpuSerial();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主板序列号
|
||||
*
|
||||
* @return String 主板序列号
|
||||
*/
|
||||
public static String getMainBoardSerial() {
|
||||
return FileUtil.isWindows() ? getWindowMainBoardSerial() : getLinuxMainBoardSerial();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取linux cpu 序列号
|
||||
*
|
||||
* @return {@link String}
|
||||
*/
|
||||
private static String getLinuxCpuSerial() {
|
||||
String result = StrUtil.EMPTY;
|
||||
String cpuIdCmd = "dmidecode";
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
// 管道
|
||||
Process p = Runtime.getRuntime().exec(new String[] {"sh", "-c", cpuIdCmd});
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line = null;
|
||||
int index = -1;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
// 寻找标示字符串[hwaddr]
|
||||
index = line.toLowerCase().indexOf("uuid");
|
||||
if (index >= 0) {
|
||||
// 取出mac地址并去除2边空格
|
||||
result = line.substring(index + "uuid".length() + 1).trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("获取Linux cpu信息错误 {}", e.getMessage());
|
||||
} finally {
|
||||
IoUtil.close(bufferedReader);
|
||||
}
|
||||
return result.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Window cpu 序列号
|
||||
*
|
||||
* @return {@link String}
|
||||
*/
|
||||
private static String getWindowCpuSerial() {
|
||||
|
||||
StringBuilder result = new StringBuilder(StrUtil.EMPTY);
|
||||
File file = null;
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
file = File.createTempFile("tmp", ".vbs");
|
||||
file.deleteOnExit();
|
||||
FileWriter fw = new FileWriter(file);
|
||||
String vbs = """
|
||||
Set objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2")
|
||||
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
|
||||
|
||||
For Each objItem In colItems
|
||||
WScript.Echo objItem.ProcessorId
|
||||
Exit For ' do the first cpu only!
|
||||
Next
|
||||
""";
|
||||
fw.write(vbs);
|
||||
fw.close();
|
||||
|
||||
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
|
||||
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line;
|
||||
while ((line = input.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取window cpu信息错误, {}", e.getMessage());
|
||||
} finally {
|
||||
IoUtil.close(input);
|
||||
FileUtil.del(file);
|
||||
}
|
||||
return result.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Linux主板序列号
|
||||
*
|
||||
* @return {@link String}
|
||||
*/
|
||||
private static String getLinuxMainBoardSerial() {
|
||||
String command = "dmidecode | grep 'Serial Number' | awk '{print $3}' | tail -1";
|
||||
try {
|
||||
Process process = new ProcessBuilder("sh", "-c", command).start();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
return reader.lines().findFirst().orElse(StrUtil.EMPTY);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("获取 Linux 主板序列号失败: {}", e.getMessage());
|
||||
return StrUtil.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取window主板序列号
|
||||
*
|
||||
* @return {@link String}
|
||||
*/
|
||||
private static String getWindowMainBoardSerial() {
|
||||
StringBuilder result = new StringBuilder(StrUtil.EMPTY);
|
||||
File file = null;
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
file = File.createTempFile("realhowto", ".vbs");
|
||||
file.deleteOnExit();
|
||||
FileWriter fw = new FileWriter(file);
|
||||
|
||||
String vbs = """
|
||||
Set objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2")
|
||||
Set colItems = objWMIService.ExecQuery _
|
||||
("Select * from Win32_BaseBoard")
|
||||
For Each objItem in colItems
|
||||
Wscript.Echo objItem.SerialNumber
|
||||
exit for ' do the first cpu only!
|
||||
Next
|
||||
""";
|
||||
|
||||
fw.write(vbs);
|
||||
fw.close();
|
||||
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
|
||||
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line;
|
||||
while ((line = input.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取Window主板信息错误 {}", e.getMessage());
|
||||
} finally {
|
||||
IoUtil.close(input);
|
||||
FileUtil.del(file);
|
||||
}
|
||||
return result.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取Mac地址</p>
|
||||
*
|
||||
* @return List<String> Mac地址
|
||||
* @throws Exception 默认异常
|
||||
*/
|
||||
public static Set<String> getMacAddress() throws Exception {
|
||||
// 获取所有网络接口
|
||||
Set<InetAddress> inetAddresses = getLocalAllInetAddress();
|
||||
if (CollectionUtil.isNotEmpty(inetAddresses)) {
|
||||
return inetAddresses.stream()
|
||||
.map(ServerInfoUtils::getMacByInetAddress)
|
||||
.distinct()
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取IP地址</p>
|
||||
*
|
||||
* @return List<String> IP地址
|
||||
* @throws Exception 默认异常
|
||||
*/
|
||||
public static Set<String> getIpAddress() throws Exception {
|
||||
// 获取所有网络接口
|
||||
Set<InetAddress> inetAddresses = getLocalAllInetAddress();
|
||||
if (CollectionUtil.isNotEmpty(inetAddresses)) {
|
||||
return inetAddresses.stream()
|
||||
.map(InetAddress::getHostAddress)
|
||||
.distinct()
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取某个网络地址对应的Mac地址</p>
|
||||
*
|
||||
* @param inetAddr 网络地址
|
||||
* @return String Mac地址
|
||||
*/
|
||||
private static String getMacByInetAddress(InetAddress inetAddr) {
|
||||
try {
|
||||
byte[] mac = NetworkInterface.getByInetAddress(inetAddr).getHardwareAddress();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < mac.length; i++) {
|
||||
if (i != 0) {
|
||||
stringBuilder.append("-");
|
||||
}
|
||||
// 将十六进制byte转化为字符串
|
||||
String temp = Integer.toHexString(mac[i] & 0xff);
|
||||
if (temp.length() == 1) {
|
||||
stringBuilder.append("0").append(temp);
|
||||
} else {
|
||||
stringBuilder.append(temp);
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString().toUpperCase();
|
||||
} catch (SocketException e) {
|
||||
log.error("getMacByInetAddress {}", e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取当前服务器所有符合条件的网络地址</p>
|
||||
*
|
||||
* @return List<InetAddress> 网络地址列表
|
||||
* @throws Exception 默认异常
|
||||
*/
|
||||
private static Set<InetAddress> getLocalAllInetAddress() throws Exception {
|
||||
|
||||
Set<InetAddress> result = CollUtil.newHashSet();
|
||||
// 遍历所有的网络接口
|
||||
for (Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
networkInterfaces.hasMoreElements();) {
|
||||
NetworkInterface ni = networkInterfaces.nextElement();
|
||||
// 在所有的接口下再遍历IP
|
||||
for (Enumeration<InetAddress> addresses = ni.getInetAddresses(); addresses.hasMoreElements();) {
|
||||
InetAddress address = addresses.nextElement();
|
||||
//排除LoopbackAddress、SiteLocalAddress、LinkLocalAddress、MulticastAddress类型的IP地址
|
||||
/*&& !inetAddr.isSiteLocalAddress()*/
|
||||
if (!address.isLoopbackAddress() && !address.isLinkLocalAddress() && !address.isMulticastAddress()) {
|
||||
result.add(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user