fix: harden target recovery metadata safety
This commit is contained in:
@@ -108,6 +108,91 @@ func active() *profile.Profile {
|
||||
return &profile.Profile{Name: "office", Mode: profile.AdvancedMode, HTTPURL: "http://proxy.example:8080", HTTPSURL: "http://secure.example:8443", AllURL: "socks5://socks.example:1080", Bypass: []string{"localhost", ".example.com", "10.0.0.0/8", "2001:db8::1"}}
|
||||
}
|
||||
|
||||
func TestAuthenticationPasswordSetFailureSuppressesRunnerErrorAndProfileArgument(t *testing.T) {
|
||||
const profilePassword = "GNOME-PROFILE-PASSWORD-07"
|
||||
r, state := newRunner(), &memoryState{}
|
||||
r.fail = func(c gnome.Command) error {
|
||||
if len(c.Args) == 4 && c.Args[0] == "set" && c.Args[2] == "authentication-password" {
|
||||
return fmt.Errorf("runner echoed argument %s: %w", c.Args[3], os.ErrPermission)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
p := *active()
|
||||
p.HTTPURL = "http://alice:" + profilePassword + "@proxy.example:8080"
|
||||
result := adapter(r, state).SetDesired(context.Background(), true, &p)
|
||||
if result.Err == nil || !errors.Is(result.Err, os.ErrPermission) {
|
||||
t.Fatalf("set error classification = %#v", result)
|
||||
}
|
||||
if strings.Contains(result.Err.Error(), profilePassword) || strings.Contains(result.Err.Error(), "runner echoed") {
|
||||
t.Fatalf("set exposed runner error or password argument: %v", result.Err)
|
||||
}
|
||||
if !strings.Contains(result.Err.Error(), "sensitive argument and runner error suppressed") {
|
||||
t.Fatalf("set lacks fixed safe message: %v", result.Err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthenticationPasswordRestoreFailureSuppressesRunnerErrorAndSavedArgument(t *testing.T) {
|
||||
const savedPassword = "GNOME-SAVED-ORIGINAL-PASSWORD-07"
|
||||
r, state := newRunner(), &memoryState{}
|
||||
r.values["org.gnome.system.proxy mode"] = "'auto'"
|
||||
r.values["org.gnome.system.proxy.http authentication-password"] = "'" + savedPassword + "'"
|
||||
a := adapter(r, state)
|
||||
if result := a.SetDesired(context.Background(), true, active()); result.Err != nil {
|
||||
t.Fatalf("enable = %#v", result)
|
||||
}
|
||||
r.fail = func(c gnome.Command) error {
|
||||
if reflect.DeepEqual(c.Args[:min(len(c.Args), 3)], []string{"set", "org.gnome.system.proxy.http", "authentication-password"}) {
|
||||
return fmt.Errorf("runner echoed argument %s: %w", c.Args[3], os.ErrPermission)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
result := a.SetDesired(context.Background(), false, nil)
|
||||
if result.Err == nil || !errors.Is(result.Err, os.ErrPermission) {
|
||||
t.Fatalf("restore error classification = %#v", result)
|
||||
}
|
||||
if strings.Contains(result.Err.Error(), savedPassword) || strings.Contains(result.Err.Error(), "runner echoed") {
|
||||
t.Fatalf("restore exposed runner error or password argument: %v", result.Err)
|
||||
}
|
||||
if !strings.Contains(result.Err.Error(), "sensitive argument and runner error suppressed") {
|
||||
t.Fatalf("restore lacks fixed safe message: %v", result.Err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIncompleteRecoveryMetadataRejectsMutationAndPreservesGNOMESettings(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"empty object": `{}`,
|
||||
"missing original": `{"version":1,"lastFingerprint":"` + strings.Repeat("a", 64) + `"}`,
|
||||
"incomplete original": `{"version":1,"lastFingerprint":"` + strings.Repeat("a", 64) + `","original":{"mode":"none"}}`,
|
||||
"invalid fingerprint": `{"version":1,"lastFingerprint":"short","original":{}}`,
|
||||
}
|
||||
for name, metadata := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r, state := newRunner(), &memoryState{data: []byte(metadata)}
|
||||
before := make(map[string]string, len(r.values))
|
||||
for key, value := range r.values {
|
||||
before[key] = value
|
||||
}
|
||||
a := adapter(r, state)
|
||||
if inspection := a.Inspect(context.Background(), nil); inspection.State != target.Drifted {
|
||||
t.Fatalf("inspection = %#v", inspection)
|
||||
}
|
||||
callStart := len(r.calls)
|
||||
result := a.SetDesired(context.Background(), false, nil)
|
||||
if result.Err == nil || result.Inspection.State != target.Drifted {
|
||||
t.Fatalf("unsafe disable = %#v", result)
|
||||
}
|
||||
if !reflect.DeepEqual(r.values, before) || string(state.data) != metadata {
|
||||
t.Fatalf("configuration mutated: values=%#v metadata=%q", r.values, state.data)
|
||||
}
|
||||
for _, call := range r.calls[callStart:] {
|
||||
if len(call.Args) > 0 && call.Args[0] == "set" {
|
||||
t.Fatalf("unsafe metadata caused set: %#v", call)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiagnosticsSuppressSensitiveGSettingsOutputAndRunnerErrors(t *testing.T) {
|
||||
const secret = "GNOME-DIAGNOSTIC-SECRET-7f3a"
|
||||
for _, test := range []struct {
|
||||
|
||||
Reference in New Issue
Block a user