forked from StanfordSNR/guardian-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
policy.go
89 lines (79 loc) · 2.93 KB
/
policy.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
package guardianagent
import (
"errors"
"fmt"
)
type Policy struct {
Store *Store
UI UI
}
func (policy *Policy) RequestApproval(scope Scope, cmd string) error {
if policy.Store.IsAllowed(scope, cmd) {
policy.UI.Inform(fmt.Sprintf("Request by %s to run '%s' on %s@%s AUTO-APPROVED by policy",
scope.Client, cmd, scope.ServiceUsername,
scope.ServiceHostname))
return nil
}
question := fmt.Sprintf("Allow %s to run '%s' on %s@%s?",
scope.Client, cmd, scope.ServiceUsername, scope.ServiceHostname)
prompt := Prompt{
Question: question,
Choices: []string{
"Disallow", "Allow once", "Allow forever",
fmt.Sprintf("Allow %s to run any command on %s@%s forever",
scope.Client, scope.ServiceUsername, scope.ServiceHostname),
},
}
resp, err := policy.UI.Ask(prompt)
if err != nil {
return fmt.Errorf("Failed to get user approval: %s", err)
}
switch resp {
case 2:
policy.UI.Inform(fmt.Sprintf("Request by %s to run '%s' on %s@%s APPROVED by user",
scope.Client, cmd, scope.ServiceUsername, scope.ServiceHostname))
err = nil
case 3:
policy.UI.Inform(fmt.Sprintf("Request by %s to run '%s' on %s@%s PERMANENTLY APPROVED by user",
scope.Client, cmd, scope.ServiceUsername, scope.ServiceHostname))
err = policy.Store.AllowCommand(scope, cmd)
case 4:
policy.UI.Inform(fmt.Sprintf("Request by %s to run ANY COMMAND on %s@%s PERMANENTLY APPROVED by user",
scope.Client, scope.ServiceUsername, scope.ServiceHostname))
err = policy.Store.AllowAll(scope)
default:
policy.UI.Inform(fmt.Sprintf("Request by %s to run '%s' on %s@%s DENIED by user",
scope.Client, cmd, scope.ServiceUsername, scope.ServiceHostname))
err = errors.New("User rejected client request")
}
return err
}
func (policy *Policy) RequestApprovalForAllCommands(scope Scope) error {
if policy.Store.AreAllAllowed(scope) {
policy.UI.Inform(fmt.Sprintf("Request by %s to run ANY COMMAND on %s@%s AUTO-APPROVED by policy",
scope.Client, scope.ServiceUsername, scope.ServiceHostname))
return nil
}
question := fmt.Sprintf("Can't enforce permission for a single command. Allow %s to run ANY COMMAND on %s@%s?",
scope.Client, scope.ServiceUsername, scope.ServiceHostname)
prompt := Prompt{
Question: question,
Choices: []string{"Disallow", "Allow once", "Allow forever"},
}
resp, err := policy.UI.Ask(prompt)
switch resp {
case 2:
policy.UI.Inform(fmt.Sprintf("Request by %s to run ANY COMMAND on %s@%s APPROVED by user",
scope.Client, scope.ServiceUsername, scope.ServiceHostname))
err = nil
case 3:
policy.UI.Inform(fmt.Sprintf("Request by %s to run ANY COMMAND on %s@%s PERMANENTLY APPROVED by user",
scope.Client, scope.ServiceUsername, scope.ServiceHostname))
err = policy.Store.AllowAll(scope)
default:
policy.UI.Inform(fmt.Sprintf("Request by %s to run ANY COMMAND on %s@%s DENIED by user",
scope.Client, scope.ServiceUsername, scope.ServiceHostname))
err = errors.New("User rejected approval escalation")
}
return err
}