Skip to content

Commit d627d76

Browse files
authored
v1.0.X-experimental
(Prototype) Remote Command Execution (#177)
1 parent c2bb04b commit d627d76

17 files changed

+1104
-18
lines changed

cmd/api.go

+43-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/go-resty/resty/v2"
1111
)
1212

13-
func ProcessAPIType(policy Policy, rgPath string) error {
13+
func ProcessAPIType(policy Policy, rgPath string, isObserve bool) error {
1414
client := resty.New()
1515
client.SetDebug(debugOutput)
1616

@@ -46,9 +46,9 @@ func ProcessAPIType(policy Policy, rgPath string) error {
4646

4747
// Process the response based on policy type
4848
if policy.Schema.Structure != "" {
49-
return processWithCUE(policy, resp.Body())
49+
return processWithCUE(policy, resp.Body(), isObserve)
5050
} else if len(policy.Regex) > 0 {
51-
return processWithRegex(policy, resp.Body(), rgPath)
51+
return processWithRegex(policy, resp.Body(), rgPath, isObserve)
5252
}
5353

5454
return handlePolicyError(policy, fmt.Errorf("no processing method specified for policy %s", policy.ID))
@@ -81,7 +81,7 @@ func applyAuth(req *resty.Request, auth map[string]string) error {
8181
return nil
8282
}
8383

84-
func processWithCUE(policy Policy, data []byte) error {
84+
func processWithCUE(policy Policy, data []byte, isObserve bool) error {
8585
valid, issues := validateContentAndCUE(data, policy.Schema.Structure, "json", policy.Schema.Strict, policy.ID)
8686

8787
// Generate SARIF report
@@ -109,6 +109,25 @@ func processWithCUE(policy Policy, data []byte) error {
109109

110110
}
111111

112+
if isObserve {
113+
114+
// if remote cache the results
115+
if policy.RunID != "" {
116+
var resultMsg string
117+
118+
if sarifReport.Runs[0].Invocations[0].Properties.ReportCompliant {
119+
120+
resultMsg = fmt.Sprintf("🟢 %s : %s", "Compliant")
121+
122+
} else {
123+
resultMsg = fmt.Sprintf("🔴 %s : %s", "Non Compliant")
124+
}
125+
storeResultInCache(policy.ID, resultMsg)
126+
127+
}
128+
129+
}
130+
112131
log.Debug().Msgf("Policy %s processed. SARIF report written to: %s ", policy.ID, sarifOutputFile)
113132

114133
if !valid {
@@ -121,7 +140,7 @@ func processWithCUE(policy Policy, data []byte) error {
121140
log.Debug().Msgf("Policy %s validation passed for API response ", policy.ID)
122141
return nil
123142
}
124-
func processWithRegex(policy Policy, data []byte, rgPath string) error {
143+
func processWithRegex(policy Policy, data []byte, rgPath string, isObserve bool) error {
125144
// Create a temporary file with the API response
126145
tempFile, err := os.CreateTemp("", "api_response_*.json")
127146
if err != nil {
@@ -173,6 +192,25 @@ func processWithRegex(policy Policy, data []byte, rgPath string) error {
173192

174193
}
175194

195+
if isObserve {
196+
197+
// if remote cache the results
198+
if policy.RunID != "" {
199+
var resultMsg string
200+
201+
if sarifReport.Runs[0].Invocations[0].Properties.ReportCompliant {
202+
203+
resultMsg = fmt.Sprintf("🟢 %s", "Compliant")
204+
205+
} else {
206+
resultMsg = fmt.Sprintf("🔴 %s", "Non Compliant")
207+
}
208+
storeResultInCache(policy.ID, resultMsg)
209+
210+
}
211+
212+
}
213+
176214
log.Debug().Msgf("Policy %s processed. SARIF report written to: %s ", policy.ID, sarifOutputFile)
177215

178216
if matchesFound {

cmd/audit.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func processPolicyByType(policy Policy, rgPath, gossPath, targetDir string, file
259259
case "runtime":
260260
err = ProcessRuntimeType(policy, gossPath, targetDir, filePaths, false)
261261
case "api":
262-
err = ProcessAPIType(policy, rgPath)
262+
err = ProcessAPIType(policy, rgPath, false)
263263
case "yml":
264264
if policy.Schema.Patch {
265265
err = processGenericType(policy, filePaths, "yaml")

cmd/embed_remote_darwin_amd64.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build darwin && amd64
2+
// +build darwin,amd64
3+
4+
package cmd
5+
6+
import (
7+
"embed"
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
)
12+
13+
//go:embed gossh/gossh-darwin-amd64
14+
var embeddedGossh embed.FS
15+
16+
var gosshPath string
17+
18+
func prepareGosshExecutable() (string, error) {
19+
tempDir, err := os.MkdirTemp("", "temp_exec")
20+
if err != nil {
21+
return "", fmt.Errorf("failed to create temp dir: %w", err)
22+
}
23+
24+
gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-darwin-amd64")
25+
if err != nil {
26+
return "", err
27+
}
28+
29+
return gosshPath, nil
30+
}
31+
32+
func extractGosshExecutable(tempDir, executableName string) (string, error) {
33+
executableFolder := filepath.Dir(executableName)
34+
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
35+
if err != nil {
36+
return "", fmt.Errorf("failed to create folder structure: %w", err)
37+
}
38+
39+
executablePath := filepath.Join(tempDir, executableName)
40+
41+
data, err := embeddedGossh.ReadFile(executableName)
42+
if err != nil {
43+
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
44+
}
45+
46+
err = os.WriteFile(executablePath, data, 0755)
47+
if err != nil {
48+
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
49+
}
50+
51+
return executablePath, nil
52+
}

cmd/embed_remote_darwin_arm64.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build darwin && arm64
2+
// +build darwin,arm64
3+
4+
package cmd
5+
6+
import (
7+
"embed"
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
)
12+
13+
//go:embed gossh/gossh-darwin-arm64
14+
var embeddedGossh embed.FS
15+
16+
var gosshPath string
17+
18+
func prepareGosshExecutable() (string, error) {
19+
tempDir, err := os.MkdirTemp("", "temp_exec")
20+
if err != nil {
21+
return "", fmt.Errorf("failed to create temp dir: %w", err)
22+
}
23+
24+
gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-darwin-arm64")
25+
if err != nil {
26+
return "", err
27+
}
28+
29+
return gosshPath, nil
30+
}
31+
32+
func extractGosshExecutable(tempDir, executableName string) (string, error) {
33+
executableFolder := filepath.Dir(executableName)
34+
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
35+
if err != nil {
36+
return "", fmt.Errorf("failed to create folder structure: %w", err)
37+
}
38+
39+
executablePath := filepath.Join(tempDir, executableName)
40+
41+
data, err := embeddedGossh.ReadFile(executableName)
42+
if err != nil {
43+
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
44+
}
45+
46+
err = os.WriteFile(executablePath, data, 0755)
47+
if err != nil {
48+
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
49+
}
50+
51+
return executablePath, nil
52+
}

cmd/embed_remote_linux_amd64.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build linux && amd64
2+
// +build linux,amd64
3+
4+
package cmd
5+
6+
import (
7+
"embed"
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
)
12+
13+
//go:embed gossh/gossh-linux-amd64
14+
var embeddedGossh embed.FS
15+
16+
var gosshPath string
17+
18+
func prepareGosshExecutable() (string, error) {
19+
tempDir, err := os.MkdirTemp("", "temp_exec")
20+
if err != nil {
21+
return "", fmt.Errorf("failed to create temp dir: %w", err)
22+
}
23+
24+
gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-linux-amd64")
25+
if err != nil {
26+
return "", err
27+
}
28+
29+
return gosshPath, nil
30+
}
31+
32+
func extractGosshExecutable(tempDir, executableName string) (string, error) {
33+
executableFolder := filepath.Dir(executableName)
34+
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
35+
if err != nil {
36+
return "", fmt.Errorf("failed to create folder structure: %w", err)
37+
}
38+
39+
executablePath := filepath.Join(tempDir, executableName)
40+
41+
data, err := embeddedGossh.ReadFile(executableName)
42+
if err != nil {
43+
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
44+
}
45+
46+
err = os.WriteFile(executablePath, data, 0755)
47+
if err != nil {
48+
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
49+
}
50+
51+
return executablePath, nil
52+
}

cmd/embed_remote_linux_arm64.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build linux && arm64
2+
// +build linux,arm64
3+
4+
package cmd
5+
6+
import (
7+
"embed"
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
)
12+
13+
//go:embed gossh/gossh-linux-arm64
14+
var embeddedGossh embed.FS
15+
16+
var gosshPath string
17+
18+
func prepareGosshExecutable() (string, error) {
19+
tempDir, err := os.MkdirTemp("", "temp_exec")
20+
if err != nil {
21+
return "", fmt.Errorf("failed to create temp dir: %w", err)
22+
}
23+
24+
gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-linux-arm64")
25+
if err != nil {
26+
return "", err
27+
}
28+
29+
return gosshPath, nil
30+
}
31+
32+
func extractGosshExecutable(tempDir, executableName string) (string, error) {
33+
executableFolder := filepath.Dir(executableName)
34+
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
35+
if err != nil {
36+
return "", fmt.Errorf("failed to create folder structure: %w", err)
37+
}
38+
39+
executablePath := filepath.Join(tempDir, executableName)
40+
41+
data, err := embeddedGossh.ReadFile(executableName)
42+
if err != nil {
43+
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
44+
}
45+
46+
err = os.WriteFile(executablePath, data, 0755)
47+
if err != nil {
48+
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
49+
}
50+
51+
return executablePath, nil
52+
}

cmd/embed_remote_unavailable.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//go:build windows || (linux && arm && !arm64)
2+
// +build windows linux,arm,!arm64
3+
4+
package cmd
5+
6+
import (
7+
"embed"
8+
)
9+
10+
var embeddedGossh embed.FS
11+
12+
var gosshPath string
13+
14+
func prepareGosshExecutable() (string, error) {
15+
return "", nil
16+
}
17+
18+
func extractGosshExecutable(_, _ string) (string, error) {
19+
return "", nil
20+
}

cmd/gossh/1.15.1

Whitespace-only changes.

cmd/gossh/gossh-darwin-amd64

10.3 MB
Binary file not shown.

cmd/gossh/gossh-darwin-arm64

10.2 MB
Binary file not shown.

cmd/gossh/gossh-linux-amd64

10.5 MB
Binary file not shown.

cmd/gossh/gossh-linux-arm64

10.2 MB
Binary file not shown.

0 commit comments

Comments
 (0)