-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.go
155 lines (137 loc) · 3.74 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"time"
"github.com/hashicorp/go-uuid"
"github.com/jcmturner/golick/licence"
)
const appTitle = "Go licence generator"
var buildhash = "Not set"
var buildtime = "Not set"
var version = "Not set"
func ver() (string, string, time.Time) {
bt, _ := time.Parse(time.RFC3339, buildtime)
return version, buildhash, bt
}
// versionStr returns the version number, hash from git and the time of the build in a pretty formatted string.
func versionStr() string {
v, bh, bt := ver()
return fmt.Sprintf("%s Version Information:\nVersion:\t%s\nBuild hash:\t%s\nBuild time:\t%v\n", appTitle, v, bh, bt)
}
func main() {
keyPath := flag.String("key", "", "Path to private key file")
v := flag.Bool("version", false, "Print version information")
d := flag.Int64("duration", 0, "Duration in days of licence from now")
m := flag.Int64("maxcount", 0, "Max count for licence coverage")
r := flag.Int64("runduration", 0, "Duration in minutes the licence will enable the service to run for. Typically for trial usage.")
i := flag.String("init", "", "Initialise licencing key pair at the path provided")
flag.Parse()
// Print version information and exit.
if *v {
fmt.Fprintln(os.Stderr, versionStr())
os.Exit(0)
}
if *i != "" {
pvt, pub, err := initLicKeyPair(*i)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating key pair: %v\n", err)
os.Exit(1)
}
fmt.Printf("Private key: %s\nPublic key: %s\n", pvt, pub)
os.Exit(0)
}
if *keyPath == "" {
fmt.Fprintln(os.Stderr, "Private key path not specified.")
os.Exit(1)
}
keyFile, err := os.Open(*keyPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not access private key: %v\n", err)
os.Exit(1)
}
key, err := loadPvtKey(keyFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not load private key: %v", err)
os.Exit(1)
}
var l *licence.Licence
if *r > 0 {
mins := time.Duration(*r) * time.Minute
l, err = licence.NewRunPeriod(key, mins, *m)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not generate licence: %v\n", err)
os.Exit(1)
}
} else {
if *d <= 0 {
fmt.Fprintln(os.Stderr, "Duration must be a positive integer.")
os.Exit(1)
}
days := time.Duration(*d)
l, err = licence.New(key, time.Now().UTC(), time.Now().UTC().Add(time.Hour*24*days), *m)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not generate licence: %v\n", err)
os.Exit(1)
}
}
lk, err := l.String()
if err != nil {
fmt.Fprintf(os.Stderr, "Could not generate key string: %v\n", err)
os.Exit(1)
}
fmt.Printf("%s\nKey:\n%s\n", l.Print(), lk)
}
func loadPvtKey(r io.Reader) (*rsa.PrivateKey, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
der, err := hex.DecodeString(string(b))
return x509.ParsePKCS1PrivateKey(der)
}
func initLicKeyPair(path string) (string, string, error) {
pair, _ := rsa.GenerateKey(rand.Reader, 2048)
pubbytes := x509.MarshalPKCS1PublicKey(pair.Public().(*rsa.PublicKey))
pvtbytes := x509.MarshalPKCS1PrivateKey(pair)
u, err := uuid.GenerateUUID()
if err != nil {
return "", "", err
}
path = strings.TrimRight(path, "/") + "/"
pvtPath := path + u + ".key"
pubPath := path + u + ".pub"
pvtFile, err := os.Create(pvtPath)
if err != nil {
return "", "", err
}
err = pvtFile.Chmod(0600)
if err != nil {
return "", "", err
}
_, err = pvtFile.WriteString(hex.EncodeToString(pvtbytes))
if err != nil {
return "", "", err
}
pubFile, err := os.Create(pubPath)
if err != nil {
return "", "", err
}
err = pubFile.Chmod(0644)
if err != nil {
return "", "", err
}
_, err = pubFile.WriteString(hex.EncodeToString(pubbytes))
if err != nil {
return "", "", err
}
return pvtFile.Name(), pubFile.Name(), nil
}