Skip to content

Commit

Permalink
v1.0.X-experimental
Browse files Browse the repository at this point in the history
(Prototype) Remote Command Execution (#177)
  • Loading branch information
xfhg authored Oct 25, 2024
1 parent c2bb04b commit d627d76
Show file tree
Hide file tree
Showing 17 changed files with 1,104 additions and 18 deletions.
48 changes: 43 additions & 5 deletions cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/go-resty/resty/v2"
)

func ProcessAPIType(policy Policy, rgPath string) error {
func ProcessAPIType(policy Policy, rgPath string, isObserve bool) error {
client := resty.New()
client.SetDebug(debugOutput)

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

// Process the response based on policy type
if policy.Schema.Structure != "" {
return processWithCUE(policy, resp.Body())
return processWithCUE(policy, resp.Body(), isObserve)
} else if len(policy.Regex) > 0 {
return processWithRegex(policy, resp.Body(), rgPath)
return processWithRegex(policy, resp.Body(), rgPath, isObserve)
}

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

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

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

}

if isObserve {

// if remote cache the results
if policy.RunID != "" {
var resultMsg string

if sarifReport.Runs[0].Invocations[0].Properties.ReportCompliant {

resultMsg = fmt.Sprintf("🟢 %s : %s", "Compliant")

} else {
resultMsg = fmt.Sprintf("🔴 %s : %s", "Non Compliant")
}
storeResultInCache(policy.ID, resultMsg)

}

}

log.Debug().Msgf("Policy %s processed. SARIF report written to: %s ", policy.ID, sarifOutputFile)

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

}

if isObserve {

// if remote cache the results
if policy.RunID != "" {
var resultMsg string

if sarifReport.Runs[0].Invocations[0].Properties.ReportCompliant {

resultMsg = fmt.Sprintf("🟢 %s", "Compliant")

} else {
resultMsg = fmt.Sprintf("🔴 %s", "Non Compliant")
}
storeResultInCache(policy.ID, resultMsg)

}

}

log.Debug().Msgf("Policy %s processed. SARIF report written to: %s ", policy.ID, sarifOutputFile)

if matchesFound {
Expand Down
2 changes: 1 addition & 1 deletion cmd/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func processPolicyByType(policy Policy, rgPath, gossPath, targetDir string, file
case "runtime":
err = ProcessRuntimeType(policy, gossPath, targetDir, filePaths, false)
case "api":
err = ProcessAPIType(policy, rgPath)
err = ProcessAPIType(policy, rgPath, false)
case "yml":
if policy.Schema.Patch {
err = processGenericType(policy, filePaths, "yaml")
Expand Down
52 changes: 52 additions & 0 deletions cmd/embed_remote_darwin_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build darwin && amd64
// +build darwin,amd64

package cmd

import (
"embed"
"fmt"
"os"
"path/filepath"
)

//go:embed gossh/gossh-darwin-amd64
var embeddedGossh embed.FS

var gosshPath string

func prepareGosshExecutable() (string, error) {
tempDir, err := os.MkdirTemp("", "temp_exec")
if err != nil {
return "", fmt.Errorf("failed to create temp dir: %w", err)
}

gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-darwin-amd64")
if err != nil {
return "", err
}

return gosshPath, nil
}

func extractGosshExecutable(tempDir, executableName string) (string, error) {
executableFolder := filepath.Dir(executableName)
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
if err != nil {
return "", fmt.Errorf("failed to create folder structure: %w", err)
}

executablePath := filepath.Join(tempDir, executableName)

data, err := embeddedGossh.ReadFile(executableName)
if err != nil {
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
}

err = os.WriteFile(executablePath, data, 0755)
if err != nil {
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
}

return executablePath, nil
}
52 changes: 52 additions & 0 deletions cmd/embed_remote_darwin_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build darwin && arm64
// +build darwin,arm64

package cmd

import (
"embed"
"fmt"
"os"
"path/filepath"
)

//go:embed gossh/gossh-darwin-arm64
var embeddedGossh embed.FS

var gosshPath string

func prepareGosshExecutable() (string, error) {
tempDir, err := os.MkdirTemp("", "temp_exec")
if err != nil {
return "", fmt.Errorf("failed to create temp dir: %w", err)
}

gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-darwin-arm64")
if err != nil {
return "", err
}

return gosshPath, nil
}

func extractGosshExecutable(tempDir, executableName string) (string, error) {
executableFolder := filepath.Dir(executableName)
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
if err != nil {
return "", fmt.Errorf("failed to create folder structure: %w", err)
}

executablePath := filepath.Join(tempDir, executableName)

data, err := embeddedGossh.ReadFile(executableName)
if err != nil {
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
}

err = os.WriteFile(executablePath, data, 0755)
if err != nil {
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
}

return executablePath, nil
}
52 changes: 52 additions & 0 deletions cmd/embed_remote_linux_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build linux && amd64
// +build linux,amd64

package cmd

import (
"embed"
"fmt"
"os"
"path/filepath"
)

//go:embed gossh/gossh-linux-amd64
var embeddedGossh embed.FS

var gosshPath string

func prepareGosshExecutable() (string, error) {
tempDir, err := os.MkdirTemp("", "temp_exec")
if err != nil {
return "", fmt.Errorf("failed to create temp dir: %w", err)
}

gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-linux-amd64")
if err != nil {
return "", err
}

return gosshPath, nil
}

func extractGosshExecutable(tempDir, executableName string) (string, error) {
executableFolder := filepath.Dir(executableName)
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
if err != nil {
return "", fmt.Errorf("failed to create folder structure: %w", err)
}

executablePath := filepath.Join(tempDir, executableName)

data, err := embeddedGossh.ReadFile(executableName)
if err != nil {
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
}

err = os.WriteFile(executablePath, data, 0755)
if err != nil {
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
}

return executablePath, nil
}
52 changes: 52 additions & 0 deletions cmd/embed_remote_linux_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build linux && arm64
// +build linux,arm64

package cmd

import (
"embed"
"fmt"
"os"
"path/filepath"
)

//go:embed gossh/gossh-linux-arm64
var embeddedGossh embed.FS

var gosshPath string

func prepareGosshExecutable() (string, error) {
tempDir, err := os.MkdirTemp("", "temp_exec")
if err != nil {
return "", fmt.Errorf("failed to create temp dir: %w", err)
}

gosshPath, err = extractGosshExecutable(tempDir, "gossh/gossh-linux-arm64")
if err != nil {
return "", err
}

return gosshPath, nil
}

func extractGosshExecutable(tempDir, executableName string) (string, error) {
executableFolder := filepath.Dir(executableName)
err := os.MkdirAll(filepath.Join(tempDir, executableFolder), 0755)
if err != nil {
return "", fmt.Errorf("failed to create folder structure: %w", err)
}

executablePath := filepath.Join(tempDir, executableName)

data, err := embeddedGossh.ReadFile(executableName)
if err != nil {
return "", fmt.Errorf("failed to read embedded gossh: %w", err)
}

err = os.WriteFile(executablePath, data, 0755)
if err != nil {
return "", fmt.Errorf("failed to write gossh to temp path: %w", err)
}

return executablePath, nil
}
20 changes: 20 additions & 0 deletions cmd/embed_remote_unavailable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build windows || (linux && arm && !arm64)
// +build windows linux,arm,!arm64

package cmd

import (
"embed"
)

var embeddedGossh embed.FS

var gosshPath string

func prepareGosshExecutable() (string, error) {
return "", nil
}

func extractGosshExecutable(_, _ string) (string, error) {
return "", nil
}
Empty file added cmd/gossh/1.15.1
Empty file.
Binary file added cmd/gossh/gossh-darwin-amd64
Binary file not shown.
Binary file added cmd/gossh/gossh-darwin-arm64
Binary file not shown.
Binary file added cmd/gossh/gossh-linux-amd64
Binary file not shown.
Binary file added cmd/gossh/gossh-linux-arm64
Binary file not shown.
Loading

0 comments on commit d627d76

Please sign in to comment.