Commit efcc51f2 authored by 李科's avatar 李科

init project

parent d586c3bf
*.out
*.txt
id_ed25519
id_ed25519.pub
cmd/license-keyinit/id_ed25519
cmd/license-keyinit/id_ed25519.pub
license.txt
!license/licenseutil/testdata/*
### VisualStudioCode template
.vscode/*
*.code-workspace
# Local History for Visual Studio Code
.history/
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
# Generated files
# Sensitive or high-churn files
# Gradle
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
# File-based project format
*.iws
# IntelliJ
out/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
# Android studio 3.1+ serialized cache file
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
vendor/
### Vim template
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
### Archives template
# It's better to unpack these files and commit the raw source because
# git has its own built in compression methods.
*.7z
*.jar
*.rar
*.zip
*.gz
*.gzip
*.tgz
*.bzip
*.bzip2
*.bz2
*.xz
*.lzma
*.cab
*.xar
# Packing-only formats
*.iso
*.tar
# Package management formats
*.dmg
*.xpi
*.gem
*.egg
*.deb
*.rpm
*.msi
*.msm
*.msp
*.txz
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/go-license.iml" filepath="$PROJECT_DIR$/.idea/go-license.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
......@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package cmd
import (
"flag"
"fmt"
"io/ioutil"
"os"
"time"
......@@ -15,36 +13,40 @@ import (
"github.com/drone/go-license/license/licenseutil"
)
var month = time.Hour * 24 * 31
var (
in = flag.String("in", "id_ed25519", "")
out = flag.String("out", "license.txt", "")
iss = flag.String("iss", "", "")
cus = flag.String("cus", "", "")
sub = flag.String("sub", "", "")
typ = flag.String("typ", "", "")
lim = flag.Int("lim", 0, "")
exp = flag.Duration("exp", month, "")
)
func main() {
flag.Parse()
var year = time.Hour * 24 * 365
type Args struct {
In string `json:"in"` // 输入数据
Out string `json:"out"` // 输出数据
Iss string `json:"iss"` // 发布者
Cus string `json:"cus"` // 客户
Sub string `json:"sub"` // 主题
Typ string `json:"typ"` // 类型
Lim int `json:"lim"` // 限制
Dat string `json:"dat"` // 数据
Exp time.Duration `json:"exp"` // 过期时间
}
privateKey, err := licenseutil.ReadPrivateKey(*in)
func LicenseCreate(args Args) {
if args.Exp == 0 {
args.Exp = year
}
privateKey, err := licenseutil.ReadPrivateKey(args.In)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
now := time.Now().UTC()
license := &license.License{
Iss: *iss,
Cus: *cus,
Sub: *sub,
Typ: *typ,
Lim: *lim,
Exp: time.Now().UTC().Add(*exp),
Iat: time.Now().UTC(),
Iss: args.Iss,
Cus: args.Cus,
Sub: args.Sub,
Typ: args.Typ,
Lim: args.Lim,
Exp: now.Add(args.Exp),
Iat: now,
Dat: []byte(args.Dat),
}
encoded, err := license.Encode(privateKey)
......@@ -53,7 +55,7 @@ func main() {
os.Exit(1)
}
err = ioutil.WriteFile(*out, encoded, 0644)
err = os.WriteFile(args.Out, encoded, 0644)
if err != nil {
fmt.Println(err)
os.Exit(1)
......
......@@ -2,24 +2,24 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package cmd
import (
"crypto/rand"
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"os"
"golang.org/x/crypto/ed25519"
)
var out = flag.String("out", "id_ed25519", "")
// var out = flag.String("out", "id_ed25519", "")
func main() {
flag.Parse()
type Args struct {
Out string
}
func LicenseKeyGen(args Args) {
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
fmt.Println(err)
......@@ -29,13 +29,13 @@ func main() {
publicKeyHex, privateKeyHex := base64.StdEncoding.EncodeToString(publicKey),
base64.StdEncoding.EncodeToString(privateKey)
err = ioutil.WriteFile(*out, []byte(privateKeyHex), 0644)
err = os.WriteFile(args.Out, []byte(privateKeyHex), 0644)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
err = ioutil.WriteFile(*out+".pub", []byte(publicKeyHex), 0644)
err = os.WriteFile(args.Out+".pub", []byte(publicKeyHex), 0644)
if err != nil {
fmt.Println(err)
os.Exit(1)
......
package license_keyinit
import "embed"
//go:embed id_ed25519 id_ed25519.pub
var Files embed.FS
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package cmd
import (
"bytes"
......@@ -23,16 +23,20 @@ var (
addr = flag.String("addr", "http://localhost:9000", "")
)
func main() {
flag.Parse()
type Args struct {
Pub string
File string
Addr string
}
publicKey, err := licenseutil.ReadPublicKey(*pub)
func LicenseRenew(args Args) {
publicKey, err := licenseutil.ReadPublicKey(args.Pub)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
l, err := license.DecodeFile(*file, publicKey)
l, err := license.DecodeFile(args.File, publicKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
......@@ -41,7 +45,7 @@ func main() {
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(l)
res, err := http.Post(*addr, "application/json", buf)
res, err := http.Post(args.Addr, "application/json", buf)
if err != nil {
fmt.Println(err)
os.Exit(1)
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package cmd
import (
"encoding/json"
......@@ -16,17 +16,25 @@ import (
var monthly = time.Hour * 24 * 30
var (
/*var (
addr = flag.String("addr", ":9000", "")
renewal = flag.Duration("dur", monthly, "")
signer = flag.String("signer", "id_ed25519", "")
)
)*/
var Payload Args
type Args struct {
Addr string
Renewal time.Duration
Signer string
}
func main() {
func LicenseServer() {
flag.Parse()
http.HandleFunc("/", handler)
http.ListenAndServe(*addr, nil)
http.ListenAndServe(Payload.Addr, nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
......@@ -40,9 +48,9 @@ func handler(w http.ResponseWriter, r *http.Request) {
// TODO verify the License.Cus (customer id) is valid
// and in good standing prior to issuing a new license.
l.Exp = time.Now().UTC().Add(*renewal)
l.Exp = time.Now().UTC().Add(Payload.Renewal)
privateKey, err := licenseutil.ReadPrivateKey(*signer)
privateKey, err := licenseutil.ReadPrivateKey(Payload.Signer)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
......
......@@ -2,33 +2,39 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
package cmd
import (
"encoding/json"
"flag"
"fmt"
"os"
"time"
"github.com/drone/go-license/license"
"github.com/drone/go-license/license/licenseutil"
)
var (
/*var (
pub = flag.String("pub", "id_ed25519.pub", "")
file = flag.String("file", "license.txt", "")
)
)*/
type Args struct {
Pub string
File string
}
func main() {
func LicenseVerify(args Args) {
flag.Parse()
publicKey, err := licenseutil.ReadPublicKey(*pub)
publicKey, err := licenseutil.ReadPublicKey(args.Pub)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
l, err := license.DecodeFile(*file, publicKey)
l, err := license.DecodeFile(args.File, publicKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
......@@ -38,3 +44,26 @@ func main() {
enc.SetIndent("", " ")
enc.Encode(l)
}
func LicenseHealth(args Args) {
flag.Parse()
publicKey, err := licenseutil.ReadPublicKey(args.Pub)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
l, err := license.DecodeFile(args.File, publicKey)
if err == nil {
if l.Exp.After(time.Now()) {
os.Exit(0) // 正常退出
}
os.Exit(1)
}
if err != nil {
fmt.Println(err)
os.Exit(2)
}
}
module github.com/drone/go-license
go 1.19
require golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac h1:7d7lG9fHOLdL6jZPtnV4LpI41SbohIJ1Atq7U991dMg=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
......@@ -9,14 +9,24 @@ package licenseutil
import (
"encoding/base64"
"io/ioutil"
license_keyinit "github.com/drone/go-license/cmd/license-keyinit"
"io/fs"
"os"
"golang.org/x/crypto/ed25519"
)
// ReadPublicKey reads a base64-encoded public key file.
func ReadPublicKey(path string) (ed25519.PublicKey, error) {
data, err := ioutil.ReadFile(path)
var (
data []byte
err error
)
if path == "empty" {
data, _ = fs.ReadFile(license_keyinit.Files, "id_ed25519.pub")
} else {
data, err = os.ReadFile(path)
}
if err != nil {
return nil, err
}
......@@ -25,7 +35,15 @@ func ReadPublicKey(path string) (ed25519.PublicKey, error) {
// ReadPrivateKey reads a base64-encoded private key file.
func ReadPrivateKey(path string) (ed25519.PrivateKey, error) {
data, err := ioutil.ReadFile(path)
var (
data []byte
err error
)
if path == "empty" {
data, _ = fs.ReadFile(license_keyinit.Files, "id_ed25519")
} else {
data, err = os.ReadFile(path)
}
if err != nil {
return nil, err
}
......
package main
import (
"fmt"
create "github.com/drone/go-license/cmd/license-create"
keygen "github.com/drone/go-license/cmd/license-keygen"
renew "github.com/drone/go-license/cmd/license-renew"
server "github.com/drone/go-license/cmd/license-server"
verify "github.com/drone/go-license/cmd/license-verify"
"github.com/spf13/cobra"
"os"
"time"
)
var (
licenseKeyGenArgs keygen.Args
licenseCreateArgs create.Args
licenseRenewArgs renew.Args
licenseVerifyArgs verify.Args
)
var rootCmd = &cobra.Command{
Use: "go-license",
Short: "go license tool",
Long: `This tool is used to generate ed25519 signed license`,
}
var keygenCmd = &cobra.Command{
Use: "keygen --out=id_ed25519",
Short: "Output license public and private keys",
Args: cobra.MaximumNArgs(1),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
keygen.LicenseKeyGen(licenseKeyGenArgs)
},
}
var createCmd = &cobra.Command{
Use: "create --iss=company_name --cus=user_name --sub=user_id --typ=internal --exp=12h",
Short: "Create a certificate signed with ed25519",
Long: `Create a certificate signed with ed25519`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("args:%+v\n", licenseCreateArgs)
create.LicenseCreate(licenseCreateArgs)
},
}
var renewCmd = &cobra.Command{
Use: "renew --pub=public_key --file=file.txt --addr=http://localhost:9000",
Short: "Renew a license",
Long: `Renew a license`,
//Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("args:%+v\n", licenseRenewArgs)
renew.LicenseRenew(licenseRenewArgs)
},
}
var serverCmd = &cobra.Command{
Use: "server --addr=:9000 --renewal=30d --signer=id_ed25519",
Short: "Start the server",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("The service listens on:%s signer:%s renewal:%s\n", server.Payload.Addr, server.Payload.Signer, server.Payload.Renewal)
server.LicenseServer()
},
}
var verifyCmd = &cobra.Command{
Use: "verify --pub=id_ed25519.pub --file=license.txt",
Short: "Validate license and return the plaintext license content",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("args:%+v\n", licenseVerifyArgs)
verify.LicenseVerify(licenseVerifyArgs)
},
}
var healthCmd = &cobra.Command{
Use: "health --pub=id_ed25519.pub --file=license.txt",
Short: "Validate license and return the plaintext license content",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("args:%+v\n", licenseVerifyArgs)
verify.LicenseHealth(licenseVerifyArgs)
},
}
/*
privateKey, _ := fs.ReadFile(Files, "id_ed25519")
publicKey, _ := fs.ReadFile(Files, "id_ed25519.pub")
fmt.Println(string(privateKey))
fmt.Println(string(publicKey))
*/
func init() {
keygenCmd.Flags().StringVarP(&licenseKeyGenArgs.Out, "out", "", "id_ed25519", "license file name")
rootCmd.AddCommand(keygenCmd)
createCmd.Flags().StringVarP(&licenseCreateArgs.In, "in", "", "empty", "Input data") // 兼容内容:去除默认值,在函数中判断,id_ed25519
createCmd.Flags().StringVarP(&licenseCreateArgs.Out, "out", "", "license.txt", "license file")
createCmd.Flags().StringVarP(&licenseCreateArgs.Iss, "iss", "", "", "Issuer")
createCmd.Flags().StringVarP(&licenseCreateArgs.Cus, "cus", "", "", "Customer")
createCmd.Flags().StringVarP(&licenseCreateArgs.Sub, "sub", "", "", "Subject")
createCmd.Flags().StringVarP(&licenseCreateArgs.Typ, "typ", "", "", "Type")
createCmd.Flags().StringVarP(&licenseCreateArgs.Dat, "dat", "", "", "JSON data")
createCmd.Flags().IntVarP(&licenseCreateArgs.Lim, "lim", "", 0, "Limit")
createCmd.Flags().DurationVarP(&licenseCreateArgs.Exp, "exp", "", 0, "Expiration time")
rootCmd.AddCommand(createCmd)
renewCmd.Flags().StringVarP(&licenseRenewArgs.Pub, "pub", "", "empty", "Public key") // id_ed25519.pub
renewCmd.Flags().StringVarP(&licenseRenewArgs.File, "file", "", "license.txt", "File name")
renewCmd.Flags().StringVarP(&licenseRenewArgs.Addr, "addr", "", "http://localhost:9000", "Ip Address")
rootCmd.AddCommand(renewCmd)
serverCmd.Flags().StringVarP(&server.Payload.Addr, "addr", "", ":9000", "Address to bind to")
serverCmd.Flags().DurationVarP(&server.Payload.Renewal, "renewal", "", time.Hour*24*30, "Certificate renewal interval in seconds")
serverCmd.Flags().StringVarP(&server.Payload.Signer, "signer", "", "empty", "Certificate signer") // id_ed25519
rootCmd.AddCommand(serverCmd)
verifyCmd.Flags().StringVarP(&licenseVerifyArgs.Pub, "pub", "", "empty", "Public key file path") //id_ed25519.pub
verifyCmd.Flags().StringVarP(&licenseVerifyArgs.File, "file", "", "license.txt", "File to verify")
rootCmd.AddCommand(verifyCmd)
healthCmd.Flags().StringVarP(&licenseVerifyArgs.Pub, "pub", "", "empty", "Public key file path") //id_ed25519.pub
healthCmd.Flags().StringVarP(&licenseVerifyArgs.File, "file", "", "license.txt", "File to verify")
rootCmd.AddCommand(healthCmd)
/*privateKey, _ := fs.ReadFile(license_keyinit.Files, "id_ed25519")
publicKey, _ := fs.ReadFile(license_keyinit.Files, "id_ed25519.pub")
fmt.Println("privateKey", string(privateKey))
fmt.Println("publicKey", string(publicKey))*/
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment