-
Notifications
You must be signed in to change notification settings - Fork 0
/
secure.go
76 lines (67 loc) · 1.47 KB
/
secure.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
package rs
import (
"bytes"
"crypto/sha256"
"flag"
"fmt"
)
// Secure command manages credentials in /etc/credentials
func Secure(cmd *Cmd) error {
flags := flag.NewFlagSet("secure", flag.ContinueOnError)
name := flags.String("a", "", "account name")
secret := flags.String("s", "", "secret")
check := flags.Bool("c", false, "check if secret is valid")
flags.SetOutput(cmd.Out)
if err := flags.Parse(cmd.Args); err != nil {
return err
}
if *secret == "" {
return fmt.Errorf("empty secret")
}
var acc Account
if err := cmd.Sys.LoadAccount(&acc, *name); err != nil {
return err
}
cred := NewCredentials()
cmd.Sys.Load(&cred, "/etc/credentials")
if *check {
if err := cred.Check(acc.UID, *secret); err != nil {
return err
}
}
hash := sha256.New()
cred.AddSecret(&Secret{
UID: acc.UID,
Encrypted: hash.Sum([]byte(*secret)),
})
return cmd.Sys.Save("/etc/credentials", &cred)
}
func NewCredentials() *Credentials {
return &Credentials{
Secrets: make([]*Secret, 0),
}
}
type Credentials struct {
Secrets []*Secret
}
// AddSecret
func (me *Credentials) AddSecret(s *Secret) {
me.Secrets = append(me.Secrets, s)
}
// Check
func (me *Credentials) Check(uid int, secret string) error {
for _, s := range me.Secrets {
if s.UID != uid {
continue
}
encrypted := sha256.New().Sum([]byte(secret))
if bytes.Equal(encrypted, s.Encrypted) {
return nil
}
}
return fmt.Errorf("invalid")
}
type Secret struct {
UID int
Encrypted []byte
}