-
-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathmain.go
More file actions
145 lines (121 loc) · 3.92 KB
/
main.go
File metadata and controls
145 lines (121 loc) · 3.92 KB
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
//go:build linux || darwin || windows
// +build linux darwin windows
package main
import (
"errors"
"fmt"
"os"
"strings"
"github.com/jwalton/go-supportscolor"
"github.com/refaktor/rye/env"
"github.com/refaktor/rye/runner"
"github.com/refaktor/rye/security"
)
// Global variables to store the current security profiles
// These can be accessed from builtins to enforce additional restrictions
// These are now defined in the security package
type TagType int
type RjType int
type Series []any
type anyword struct {
kind RjType
idx int
}
type node struct {
kind RjType
value any
}
var CODE []any
//
// main function. Dispatches to appropriate mode function
//
func main() {
// CPU profiling (enabled with -tags profile)
stopProfile := startProfiling()
defer stopProfile()
// Initialize security profiles
// These are no-ops on non-Linux systems or when built without the appropriate tags
// The actual configuration will be set in runner.DoMain based on command-line flags
supportscolor.Stdout()
runner.DoMain(func(ps *env.ProgramState) error {
// Get script directory from runner
scriptDir := runner.GetScriptDirectory()
// Build CLI-based policy (lowest priority)
cliPolicy := buildCLIPolicy()
// Load security policy with proper precedence:
// 1. Embedded policy (compiled into binary) - highest priority
// 2. System policy (/etc/rye/mandatory.yaml)
// 3. Local policy (.ryesec in script directory)
// 4. CLI flags - lowest priority
policy, err := security.LoadSecurityPolicy(scriptDir, cliPolicy)
if err != nil {
// Policy file exists but is insecure or malformed - this is FATAL
fmt.Fprintf(os.Stderr, "FATAL: Security policy error: %v\n", err)
os.Exit(1)
}
// If we have an embedded or system policy, validate the script path
if policy.Source == security.PolicySourceEmbedded || policy.Source == security.PolicySourceSystem {
if ps.ScriptPath != "" {
if err := policy.ValidateScriptPath(ps.ScriptPath); err != nil {
fmt.Fprintf(os.Stderr, "FATAL: %v\n", err)
os.Exit(1)
}
}
}
// Apply the security policy
if err := security.ApplySecurityPolicy(policy); err != nil {
// For embedded/mandatory policies, failure is fatal
if policy.Mandatory || policy.Source == security.PolicySourceEmbedded {
fmt.Fprintf(os.Stderr, "FATAL: Failed to apply mandatory security policy: %v\n", err)
os.Exit(1)
}
// For other policies, warn but continue
fmt.Fprintf(os.Stderr, "Warning: Failed to apply security policy: %v\n", err)
}
return nil
})
}
// buildCLIPolicy creates a security policy from command-line flags
func buildCLIPolicy() *security.SecurityPolicy {
policy := &security.SecurityPolicy{
Mandatory: false, // CLI policies can always be overridden by file-based policies
}
// Seccomp from CLI flags
if *runner.SeccompProfile != "" {
policy.Seccomp.Enabled = true
policy.Seccomp.Profile = *runner.SeccompProfile
policy.Seccomp.Action = *runner.SeccompAction
if policy.Seccomp.Action == "" {
policy.Seccomp.Action = "errno"
}
}
// Landlock from CLI flags
if *runner.LandlockEnabled {
policy.Landlock.Enabled = true
policy.Landlock.Profile = *runner.LandlockProfile
if *runner.LandlockPaths != "" {
paths := strings.Split(*runner.LandlockPaths, ",")
// Clean up empty paths
for _, p := range paths {
if p != "" {
policy.Landlock.Paths = append(policy.Landlock.Paths, p)
}
}
}
}
// Code signing from CLI flags
if *runner.CodeSigEnforced {
policy.CodeSig.Enforced = true
}
// Unshare from CLI flags (records the intent; actual re-exec happens in DoMain)
if *runner.UnshareEnabled {
policy.Unshare.Enabled = true
policy.Unshare.Fs = *runner.UnshareFs
policy.Unshare.Net = *runner.UnshareNet
policy.Unshare.Pid = *runner.UnsharePid
policy.Unshare.Uts = *runner.UnshareUts
}
return policy
}
// ErrNoPath is returned when 'cd' was called without a second argument.
var ErrNoPath = errors.New("path required")