package licence
|
|
import (
|
"encoding/json"
|
"strings"
|
"time"
|
|
"github.com/shirou/gopsutil/cpu"
|
"github.com/shirou/gopsutil/host"
|
psnet "github.com/shirou/gopsutil/net"
|
// "github.com/shirou/gopsutil/disk"
|
)
|
|
type Licence struct {
|
MachineCode string
|
Expires int64
|
}
|
|
const (
|
ValidationErrorMalformed uint32 = iota + 1 // Licence is malformed
|
ValidationErrorUnverifiableHost // Licence could not be verified because of signing problems
|
ValidationErrorExpired // Signature validation failed
|
)
|
|
func GetMachineCode() string {
|
var machineCode string
|
|
// CPU
|
if cpu, err := cpu.Info(); err == nil {
|
for _, c := range cpu {
|
machineCode = strings.Join([]string{machineCode, c.String()}, "-cpu-")
|
}
|
}
|
|
// // Disk
|
// if diskInfo, err := disk.Partitions(false); err == nil {
|
// for _, d := range diskInfo {
|
// diskSerialNumber := disk.GetDiskSerialNumber(d.Device)
|
// strings.Join([]string{machineCode, diskSerialNumber}, "-")
|
// }
|
// }
|
|
// Host
|
if host, err := host.Info(); err == nil {
|
machineCode = strings.Join([]string{machineCode, host.HostID}, "-host-")
|
}
|
|
// Net
|
if net, err := psnet.Interfaces(); err == nil {
|
for _, n := range net {
|
if n.MTU == 1500 && !VNetFilter(&n) {
|
machineCode = strings.Join([]string{machineCode, n.HardwareAddr}, "-mac-")
|
}
|
}
|
}
|
|
return GetMd5String(machineCode, true, false)
|
}
|
|
func VNetFilter(iface *psnet.InterfaceStat) bool {
|
vNetNamePrefix := [...]string{
|
"docker",
|
"br-",
|
"veth",
|
"Npcap",
|
"VirtualBox",
|
}
|
|
vNetAddrPrefix := [...]string{
|
"00:05:69", //vmware1
|
"00:0C:29", //vmware2
|
"00:50:56", //vmware3
|
"00:1c:14", //vmware4
|
"00:1C:42", //parallels1
|
"00:03:FF", //microsoft virtual pc
|
"00:0F:4B", //virtual iron 4
|
"00:16:3E", //red hat xen , oracle vm , xen source, novell xen
|
"08:00:27", //virtualbox
|
}
|
|
if iface.HardwareAddr == "" {
|
return true
|
}
|
|
for _, v := range vNetAddrPrefix {
|
if strings.HasPrefix(iface.HardwareAddr, v) {
|
return true
|
}
|
}
|
|
for _, v := range vNetNamePrefix {
|
if strings.HasPrefix(iface.Name, v) {
|
return true
|
}
|
}
|
|
return false
|
}
|
|
func GenerateLicence(machineCode, timeOut, key string) string {
|
timeLayout := "2006-01-02 15:04:05" //转化所需模板
|
loc, _ := time.LoadLocation("Local") //获取时区
|
tmp, _ := time.ParseInLocation(timeLayout, timeOut, loc)
|
timestamp := tmp.Unix()
|
|
licence := Licence{machineCode, timestamp}
|
|
json, _ := json.Marshal(licence)
|
return AESEncodeStr(json, key)
|
}
|
|
func VerifyLicence(licenceCode, key string) uint32 {
|
decodeData := AESDecodeStr(licenceCode, key)
|
if decodeData == nil {
|
return ValidationErrorMalformed
|
}
|
|
var licence Licence
|
|
if err := json.Unmarshal(decodeData, &licence); err != nil {
|
return ValidationErrorMalformed
|
}
|
|
code := GetMachineCode()
|
if licence.MachineCode != code {
|
return ValidationErrorUnverifiableHost
|
}
|
|
now := time.Now().Unix()
|
if now > licence.Expires {
|
return ValidationErrorExpired
|
}
|
|
return 0
|
}
|