fix: make daemon reset conflict safe
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -15,6 +16,70 @@ import (
|
||||
"proxyctl/internal/target/targettest"
|
||||
)
|
||||
|
||||
func TestShellDiagnosticsRejectSymlinkedPathsWithoutTouchingVictim(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
path func(t *testing.T, root, victim string) string
|
||||
}{
|
||||
{
|
||||
name: "final path",
|
||||
path: func(t *testing.T, root, victim string) string {
|
||||
t.Helper()
|
||||
path := filepath.Join(root, "config", "shell.env")
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Symlink(victim, path); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return path
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ancestor path",
|
||||
path: func(t *testing.T, root, victim string) string {
|
||||
t.Helper()
|
||||
link := filepath.Join(root, "config")
|
||||
if err := os.Symlink(filepath.Dir(victim), link); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return filepath.Join(link, filepath.Base(victim))
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
victim := filepath.Join(t.TempDir(), "victim")
|
||||
const content = "shell-diagnostic-victim"
|
||||
if err := os.WriteFile(victim, []byte(content), 0o640); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
before, err := os.Stat(victim)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
environmentPath := test.path(t, root, victim)
|
||||
a := shell.New(shell.Configuration{Shell: "/bin/bash", EnvironmentFile: environmentPath, RecoveryFile: filepath.Join(root, "state", "shell.json")}, nil, shell.MapEnvironment{})
|
||||
|
||||
checks := a.DiagnosticChecks(context.Background(), nil)
|
||||
if len(checks) != 2 || checks[1].OK || !strings.Contains(checks[1].Evidence, "symbolic link") {
|
||||
t.Fatalf("Shell diagnostics accepted symlink: %#v", checks)
|
||||
}
|
||||
after, err := os.Stat(victim)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := os.ReadFile(victim)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != content || !reflect.DeepEqual(before.Sys(), after.Sys()) {
|
||||
t.Fatalf("diagnostics changed victim: before=%#v after=%#v content=%q", before, after, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShellAvailabilitySupportsOnlyBashAndZsh(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
shell string
|
||||
|
||||
Reference in New Issue
Block a user