//go:build windows // +build windows package comm import ( "encoding/base64" "encoding/json" "fmt" "io/ioutil" "os" "path" "time" "github.com/nats-io/nats.go" ) var msgbus *NatsBus // 开启liscense检测 func InitLiscenseBus(bus *NatsBus) error { msgbus = bus // liscense = NewLiscenseTask() // return liscense.Run(nil) return nil } type LiscenseTask struct { Task time.Time dirty bool SK string activeObj *LiscenseActiveCode appPrivateKey []byte appKey string keyLabel []byte DataDir string } type TimeFlag struct { I string R int32 LT time.Time } func NewLiscenseTask(sk string, privateKey string, label string, appKey string, dataDir string) *LiscenseTask { t := &LiscenseTask{SK: sk, appPrivateKey: []byte(privateKey), keyLabel: []byte(label), appKey: appKey, DataDir: dataDir} t.Task = NewBackgroundTask(t, nil) t.LoadLiscense() t.SubscribeActiveMsg() return t } type ActiveReq struct { ActiveCode string } type ActiveResp struct { Error error Succ bool AuthName string StartTime time.Time ExpireTime time.Time Duration int ErrorDesc string } // 加本地liscense func (t *LiscenseTask) LoadLiscense() error { datafile := path.Join(t.DataDir, "liscense") d, e := ioutil.ReadFile(datafile) if e != nil { return e } c, e := base64.StdEncoding.DecodeString(string(d)) if e != nil { return e } p, e := decryptOAEP(t.appPrivateKey, c, t.keyLabel) if e != nil { return e } o := &LiscenseActiveCode{} e = json.Unmarshal(p, o) if e != nil { return e } t.activeObj = o return nil } func (t *LiscenseTask) Active(req *ActiveReq) *ActiveResp { //清除已有的激活信息 infoPath := path.Join(t.DataDir, "authinfo") os.Remove(infoPath) //存储激活码 datafile := path.Join(t.DataDir, "liscense") e := ioutil.WriteFile(datafile, []byte(req.ActiveCode), os.ModePerm) if e != nil { return &ActiveResp{Succ: false, Error: e} } e = t.LoadLiscense() if e != nil { os.Remove(datafile) return &ActiveResp{Succ: false, Error: fmt.Errorf("激活码无效")} } //验证当前系统时间 if time.Now().Before(t.activeObj.CreateTime) { return &ActiveResp{Succ: false, Error: fmt.Errorf("系统时间无效,无法激活")} } //存储最新时间 f := t.setTimeFlag() if f == nil { return &ActiveResp{Succ: false, Error: fmt.Errorf("系统时间无效")} } if t.IsLiscenseOk() { //保存激活码 obj := t.activeObj ret := &ActiveResp{Succ: true, AuthName: obj.AuthName, Duration: int(obj.Duration), StartTime: obj.StartTime, ExpireTime: obj.ExpireTime} return ret } return &ActiveResp{Succ: false, Error: fmt.Errorf("激活码无效")} } func (t *LiscenseTask) UpdateAuthInfo(status string) { info := &AuthInfo{} info.AuthId = t.activeObj.AuthId info.AuthName = t.activeObj.AuthName info.Expired = t.activeObj.ExpireTime info.CreateTime = t.activeObj.CreateTime info.Duration = t.activeObj.Duration info.Status = status infoPath := path.Join(t.DataDir, "authinfo") d, e := json.Marshal(info) if e == nil { ioutil.WriteFile(infoPath, d, os.ModePerm) } } func (t *LiscenseTask) SubscribeActiveMsg() { if msgbus == nil { return } msgbus.QueueSubscribe(&SubOption{ Sub: "liscense.active." + t.appKey, Obj: func() interface{} { return &ActiveReq{} }, Call: func(obj interface{}, msg *nats.Msg) interface{} { req := obj.(*ActiveReq) resp := t.Active(req) if resp.Error != nil { resp.ErrorDesc = resp.Error.Error() } else { msgbus.PublishObj("liscense.active.succ", map[string]string{"appkey": t.appKey}) } return resp }, }) } func (t *LiscenseTask) getTimeFlag() *TimeFlag { //存储最新时间 tickfile := path.Join(t.DataDir, "tick") d, e := ioutil.ReadFile(tickfile) if e != nil { return nil } p, e := Decode(t.SK, string(d)) if e != nil { return nil } f := &TimeFlag{} e = json.Unmarshal(p, f) if e != nil { return nil } if f.I != t.appKey { return nil } return f } func (t *LiscenseTask) setTimeFlag() *TimeFlag { //存储最新时间 tickfile := path.Join(t.DataDir, "tick") f := &TimeFlag{I: t.appKey, R: radomInt(), LT: time.Now()} flag, e := json.Marshal(f) if e != nil { return nil } c, e := Encode(t.SK, flag) if e != nil { return nil } e = ioutil.WriteFile(tickfile, []byte(c), os.ModePerm) if e != nil { return nil } return f } func (t *LiscenseTask) UpdateTimeFlag() bool { f1 := t.getTimeFlag() if f1 == nil { t.dirty = true return false } if time.Now().Before(f1.LT) { t.dirty = true return false } t.dirty = false t.setTimeFlag() return true } func (t *LiscenseTask) IsLiscenseOk() bool { ready := true if t.activeObj == nil || t.activeObj.AppKey != t.appKey { ready = false } //校验系统时间 if t.dirty { ready = false } if t.activeObj != nil { hash := GetDeviceHash() if t.activeObj.DeviceHashCode != hash { ready = false } } infoPath := path.Join(t.DataDir, "authinfo") if !ready { os.Remove(infoPath) return false } isOk := false s := AuthStatusNoActive if t.activeObj.Duration == -1 { isOk = true s = AuthStatusOK } else { n := time.Now() if n.Before(t.activeObj.ExpireTime) && n.After(t.activeObj.StartTime) { isOk = true s = AuthStatusOK } else { s = AuthStatusExpired } if !isOk { os.Remove(infoPath) } } t.UpdateAuthInfo(s) return isOk } func (t *LiscenseTask) Loop() bool { t.UpdateTimeFlag() time.Sleep(5 * time.Minute) //5分钟更新一下 return false } func (t *LiscenseTask) OnAfterRun() error { return nil } func (t *LiscenseTask) OnBeforeRun() error { // if t.activeObj == nil { // return fmt.Errorf("应用未激活") // } return nil }