-
Notifications
You must be signed in to change notification settings - Fork 2
/
config.go
130 lines (99 loc) · 4.47 KB
/
config.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
package config
import (
"net/http"
"time"
"github.com/pkg/errors"
"github.com/dpb587/ssoca/auth"
"github.com/dpb587/ssoca/certauth"
"github.com/dpb587/ssoca/server/service/dynamicvalue"
)
type configCriticalOption string
type configExtension string
const (
// CriticalOptionForceCommand defines a command that is executed (replacing any the user specified on the ssh command-line) whenever this key is used for authentication.
CriticalOptionForceCommand configCriticalOption = "force-command"
// CriticalOptionSourceAddress defines a comma-separated list of source addresses from which this certificate is accepted for authentication. Addresses are specified in CIDR format (nn.nn.nn.nn/nn or hhhh::hhhh/nn). If this option is not present then certificates may be presented from any source address.
CriticalOptionSourceAddress configCriticalOption = "source-address"
// ExtensionPermitX11Forwarding is a flag indicating that X11 forwarding should be permitted. X11 forwarding will be refused if this option is absent.
ExtensionPermitX11Forwarding configExtension = "permit-X11-forwarding"
// ExtensionPermitAgentForwarding is a flag indicating that agent forwarding should be allowed. Agent forwarding must not be permitted unless this option is present.
ExtensionPermitAgentForwarding configExtension = "permit-agent-forwarding"
// ExtensionPermitPortForwarding is a flag indicating that port-forwarding should be allowed. If this option is not present then no port forwarding will be allowed.
ExtensionPermitPortForwarding configExtension = "permit-port-forwarding"
// ExtensionPermitPTY is a flag indicating that PTY allocation should be permitted. In the absence of this option PTY allocation will be disabled.
ExtensionPermitPTY configExtension = "permit-pty"
// ExtensionPermitUserRC is a flag indicating that execution of ~/.ssh/rc should be permitted. Execution of this script will not be permitted if this option is not present.
ExtensionPermitUserRC configExtension = "permit-user-rc"
// ExtensionNoDefaults disables the default set of extensions ssoca would normally add.
ExtensionNoDefaults configExtension = "ssoca-no-defaults"
)
// ExtensionDefaults is the set of extensions which will be enabled if ExtensionNoDefaults is not configured.
var ExtensionDefaults = Extensions{
ExtensionPermitX11Forwarding,
ExtensionPermitAgentForwarding,
ExtensionPermitPortForwarding,
ExtensionPermitPTY,
ExtensionPermitUserRC,
}
// Config settings for SSH key signing.
type Config struct {
CertAuth certauth.ConfigValue `yaml:"certauth,omitempty"`
Validity time.Duration `yaml:"validity,omitempty"`
Principals dynamicvalue.MultiConfigValue `yaml:"principals,omitempty"`
Target Target `yaml:"target,omitempty"`
CriticalOptions CriticalOptions `yaml:"critical_options,omitempty"`
Extensions Extensions `yaml:"extensions,omitempty"`
}
type CriticalOptions struct {
factory dynamicvalue.Factory
values map[configCriticalOption]dynamicvalue.Value
}
type Extensions []configExtension
type Target struct {
Host string `yaml:"host,omitempty"`
User dynamicvalue.ConfigValue `yaml:"user,omitempty"`
Port int `yaml:"port,omitempty"`
PublicKey string `yaml:"public_key,omitempty"`
}
func (c *Config) ApplyDefaults() {
if !c.CertAuth.IsConfigured() {
err := c.CertAuth.Configure(certauth.DefaultName)
if err != nil {
panic(err)
}
}
}
func NewCriticalOptions(factory dynamicvalue.Factory) CriticalOptions {
return CriticalOptions{
factory: factory,
values: map[configCriticalOption]dynamicvalue.Value{},
}
}
func (co *CriticalOptions) Set(option configCriticalOption, value dynamicvalue.Value) {
co.values[option] = value
}
func (co *CriticalOptions) UnmarshalYAML(unmarshal func(interface{}) error) error {
var dataSlice map[configCriticalOption]string
if err := unmarshal(&dataSlice); err != nil {
return err
}
for dataIdx, data := range dataSlice {
value, err := co.factory.Create(data)
if err != nil {
return errors.Wrap(err, "parsing dynamic value")
}
co.values[dataIdx] = value
}
return nil
}
func (co CriticalOptions) Evaluate(arg0 *http.Request, arg1 *auth.Token) (map[configCriticalOption]string, error) {
values := map[configCriticalOption]string{}
for valueIdx, value := range co.values {
res, err := value.Evaluate(arg0, arg1)
if err != nil {
return nil, errors.Wrap(err, "evaluating template")
}
values[valueIdx] = res
}
return values, nil
}