From 5271df59621127f934ab79a6e66225ea13decab9 Mon Sep 17 00:00:00 2001 From: riccardom Date: Mon, 1 Jun 2026 17:25:00 +0200 Subject: [PATCH] Align split tunnel code --- client/mdm/policy.go | 20 ++++++++++++++++---- client/mdm/policy_test.go | 20 ++++++++++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/client/mdm/policy.go b/client/mdm/policy.go index f469c03fa..da3dd0d06 100644 --- a/client/mdm/policy.go +++ b/client/mdm/policy.go @@ -33,8 +33,20 @@ const ( KeyRosenpassEnabled = "rosenpassEnabled" KeyRosenpassPermissive = "rosenpassPermissive" KeyWireguardPort = "wireguardPort" - KeySplitTunnelAllowApps = "splitTunnelAllowApps" - KeySplitTunnelDisallowApps = "splitTunnelDisallowApps" + + // Split tunnel is modeled as a single conceptual policy with two + // registry/plist values. KeySplitTunnelMode is the discriminator + // ("allow" or "disallow"); KeySplitTunnelApps is a comma-separated + // list of package names. The values are mutually exclusive by + // construction — only one mode can be set at a time. + KeySplitTunnelMode = "splitTunnelMode" + KeySplitTunnelApps = "splitTunnelApps" +) + +// Split-tunnel mode literals (KeySplitTunnelMode values). +const ( + SplitTunnelModeAllow = "allow" + SplitTunnelModeDisallow = "disallow" ) // AllKeys is the set of recognised MDM keys. Unknown keys in a managed @@ -54,8 +66,8 @@ var AllKeys = []string{ KeyRosenpassEnabled, KeyRosenpassPermissive, KeyWireguardPort, - KeySplitTunnelAllowApps, - KeySplitTunnelDisallowApps, + KeySplitTunnelMode, + KeySplitTunnelApps, } // SecretKeys lists keys whose values must be redacted in logs. diff --git a/client/mdm/policy_test.go b/client/mdm/policy_test.go index d7632e786..47a6ed2c9 100644 --- a/client/mdm/policy_test.go +++ b/client/mdm/policy_test.go @@ -17,7 +17,7 @@ func TestPolicy_NilSafe(t *testing.T) { assert.False(t, ok) _, ok = p.GetBool(KeyDisableProfiles) assert.False(t, ok) - _, ok = p.GetStringSlice(KeySplitTunnelAllowApps) + _, ok = p.GetStringSlice(KeySplitTunnelApps) assert.False(t, ok) } @@ -110,42 +110,42 @@ func TestPolicy_GetBool(t *testing.T) { func TestPolicy_GetStringSlice(t *testing.T) { t.Run("native string slice", func(t *testing.T) { p := NewPolicy(map[string]any{ - KeySplitTunnelAllowApps: []string{"com.a", "com.b"}, + KeySplitTunnelApps: []string{"com.a", "com.b"}, }) - got, ok := p.GetStringSlice(KeySplitTunnelAllowApps) + got, ok := p.GetStringSlice(KeySplitTunnelApps) assert.True(t, ok) assert.Equal(t, []string{"com.a", "com.b"}, got) }) t.Run("any slice of strings", func(t *testing.T) { p := NewPolicy(map[string]any{ - KeySplitTunnelAllowApps: []any{"com.a", "com.b"}, + KeySplitTunnelApps: []any{"com.a", "com.b"}, }) - got, ok := p.GetStringSlice(KeySplitTunnelAllowApps) + got, ok := p.GetStringSlice(KeySplitTunnelApps) assert.True(t, ok) assert.Equal(t, []string{"com.a", "com.b"}, got) }) t.Run("single string lifts to one-element slice", func(t *testing.T) { p := NewPolicy(map[string]any{ - KeySplitTunnelAllowApps: "com.a", + KeySplitTunnelApps: "com.a", }) - got, ok := p.GetStringSlice(KeySplitTunnelAllowApps) + got, ok := p.GetStringSlice(KeySplitTunnelApps) assert.True(t, ok) assert.Equal(t, []string{"com.a"}, got) }) t.Run("mixed any slice rejected", func(t *testing.T) { p := NewPolicy(map[string]any{ - KeySplitTunnelAllowApps: []any{"com.a", 1}, + KeySplitTunnelApps: []any{"com.a", 1}, }) - _, ok := p.GetStringSlice(KeySplitTunnelAllowApps) + _, ok := p.GetStringSlice(KeySplitTunnelApps) assert.False(t, ok) }) t.Run("missing key", func(t *testing.T) { p := NewPolicy(nil) - _, ok := p.GetStringSlice(KeySplitTunnelAllowApps) + _, ok := p.GetStringSlice(KeySplitTunnelApps) assert.False(t, ok) }) }