/
vault.go
112 lines (91 loc) · 2.65 KB
/
vault.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
package vaulted
import (
"errors"
"time"
"github.com/miquella/ssh-proxy-agent/lib/proxyagent"
)
const (
DefaultSessionName = "VaultedSession"
)
var STSDurationDefault = time.Hour
var (
ErrInvalidCommand = errors.New("Invalid command")
ErrNoTokenEntered = errors.New("Could not get MFA code")
)
type SSHOptions struct {
DisableProxy bool `json:"disable_proxy"`
GenerateRSAKey bool `json:"generate_rsa_key"`
ValidPrincipals []string `json:"valid_principals,omitempty"`
VaultSigningUrl string `json:"vault_signing_url,omitempty"`
}
type Vault struct {
Duration time.Duration `json:"duration,omitempty"`
AWSKey *AWSKey `json:"aws_key,omitempty"`
Vars map[string]string `json:"vars,omitempty"`
SSHKeys map[string]string `json:"ssh_keys,omitempty"`
SSHOptions *SSHOptions `json:"ssh_options,omitempty"`
}
func (v *Vault) NewSession(name string) (*Session, error) {
return v.newSession(name, func(duration time.Duration) (*AWSCredentials, error) {
return v.AWSKey.GetAWSCredentials(duration)
})
}
func (v *Vault) NewSessionWithMFA(name, mfaToken string) (*Session, error) {
return v.newSession(name, func(duration time.Duration) (*AWSCredentials, error) {
return v.AWSKey.GetAWSCredentialsWithMFA(mfaToken, duration)
})
}
func (v *Vault) newSession(name string, credsFunc func(duration time.Duration) (*AWSCredentials, error)) (*Session, error) {
var duration time.Duration
if v.Duration == 0 {
duration = STSDurationDefault
} else {
duration = v.Duration
}
var expiration *time.Time
s := &Session{
Name: name,
SSHOptions: &SSHOptions{},
Vars: make(map[string]string),
}
// copy the vault vars to the session
for key, value := range v.Vars {
s.Vars[key] = value
}
// copy the vault ssh keys to the session
if len(v.SSHKeys) > 0 {
s.SSHKeys = make(map[string]string)
for key, value := range v.SSHKeys {
s.SSHKeys[key] = value
}
}
var err error
// copy the vault ssh options to the session
if v.SSHOptions != nil {
s.SSHOptions = v.SSHOptions
// generate an SSH key for the session if necessary
if v.SSHOptions.GenerateRSAKey {
var keyPair *proxyagent.KeyPair
keyPair, err = proxyagent.GenerateRSAKeyPair()
if err != nil {
return nil, err
}
s.GeneratedSSHKey = keyPair.PrivateKey
}
}
if v.AWSKey.Valid() {
s.AWSCreds, err = credsFunc(duration)
if err != nil {
return nil, err
}
s.Role = v.AWSKey.Role
expiration = s.AWSCreds.Expiration
}
// now that the session is generated, set the expiration
if expiration != nil {
s.Expiration = *expiration
} else {
s.Expiration = time.Now().Add(duration).Truncate(time.Second)
}
return s, nil
}