diff --git a/ipn/ipnlocal/profiles.go b/ipn/ipnlocal/profiles.go index ee4bf5945..e807cf739 100644 --- a/ipn/ipnlocal/profiles.go +++ b/ipn/ipnlocal/profiles.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "math/rand" + "net/netip" "runtime" "time" @@ -19,6 +20,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/util/clientmetric" "tailscale.com/util/strs" + "tailscale.com/util/winutil" "tailscale.com/version" ) @@ -322,7 +324,7 @@ func (pm *profileManager) setAsUserSelectedProfileLocked() error { func (pm *profileManager) loadSavedPrefs(key ipn.StateKey) (ipn.PrefsView, error) { bs, err := pm.store.ReadState(key) if err == ipn.ErrStateNotExist || len(bs) == 0 { - return emptyPrefs, nil + return defaultPrefs, nil } if err != nil { return ipn.PrefsView{}, err @@ -394,15 +396,29 @@ func (pm *profileManager) writeKnownProfiles() error { func (pm *profileManager) NewProfile() { metricNewProfile.Add(1) - pm.prefs = emptyPrefs + pm.prefs = defaultPrefs pm.isNewProfile = true pm.currentProfile = &ipn.LoginProfile{} } -// emptyPrefs is the default prefs for a new profile. -var emptyPrefs = func() ipn.PrefsView { +// defaultPrefs is the default prefs for a new profile. +var defaultPrefs = func() ipn.PrefsView { prefs := ipn.NewPrefs() prefs.WantRunning = false + + prefs.ControlURL = winutil.GetPolicyString("LoginURL", "") + + if exitNode := winutil.GetPolicyString("ExitNodeIP", ""); exitNode != "" { + if ip, err := netip.ParseAddr(exitNode); err == nil { + prefs.ExitNodeIP = ip + } + } + + // Allow Incoming (used by the UI) is the negation of ShieldsUp (used by the + // backend), so this has to convert between the two conventions. + prefs.ShieldsUp = winutil.GetPolicyString("AllowIncomingConnections", "") == "never" + prefs.ForceDaemon = winutil.GetPolicyString("UnattendedMode", "") == "always" + return prefs.View() }() diff --git a/ipn/ipnlocal/profiles_test.go b/ipn/ipnlocal/profiles_test.go index 4bc646957..c977676ba 100644 --- a/ipn/ipnlocal/profiles_test.go +++ b/ipn/ipnlocal/profiles_test.go @@ -53,7 +53,7 @@ func TestProfileCurrentUserSwitch(t *testing.T) { } else if pm.currentProfile.ID != "" { t.Fatalf("currentProfile.ID = %q, want empty", pm.currentProfile.ID) } - if !pm.CurrentPrefs().Equals(emptyPrefs) { + if !pm.CurrentPrefs().Equals(defaultPrefs) { t.Fatalf("CurrentPrefs() = %v, want emptyPrefs", pm.CurrentPrefs().Pretty()) } @@ -67,7 +67,7 @@ func TestProfileCurrentUserSwitch(t *testing.T) { } else if pm.currentProfile.ID != "" { t.Fatalf("currentProfile.ID = %q, want empty", pm.currentProfile.ID) } - if !pm.CurrentPrefs().Equals(emptyPrefs) { + if !pm.CurrentPrefs().Equals(defaultPrefs) { t.Fatalf("CurrentPrefs() = %v, want emptyPrefs", pm.CurrentPrefs().Pretty()) } } @@ -159,7 +159,7 @@ func TestProfileManagement(t *testing.T) { } wantCurProfile := "" wantProfiles := map[string]ipn.PrefsView{ - "": emptyPrefs, + "": defaultPrefs, } checkProfiles := func(t *testing.T) { t.Helper() @@ -237,7 +237,7 @@ func TestProfileManagement(t *testing.T) { t.Logf("Create new profile") pm.NewProfile() wantCurProfile = "" - wantProfiles[""] = emptyPrefs + wantProfiles[""] = defaultPrefs checkProfiles(t) { @@ -276,7 +276,7 @@ func TestProfileManagement(t *testing.T) { t.Logf("Create new profile - 2") pm.NewProfile() wantCurProfile = "" - wantProfiles[""] = emptyPrefs + wantProfiles[""] = defaultPrefs checkProfiles(t) t.Logf("Login with the existing profile") @@ -310,7 +310,7 @@ func TestProfileManagementWindows(t *testing.T) { } wantCurProfile := "" wantProfiles := map[string]ipn.PrefsView{ - "": emptyPrefs, + "": defaultPrefs, } checkProfiles := func(t *testing.T) { t.Helper() @@ -363,7 +363,7 @@ func TestProfileManagementWindows(t *testing.T) { t.Logf("Create new profile") pm.NewProfile() wantCurProfile = "" - wantProfiles[""] = emptyPrefs + wantProfiles[""] = defaultPrefs checkProfiles(t) t.Logf("Save as test profile") @@ -380,7 +380,7 @@ func TestProfileManagementWindows(t *testing.T) { t.Fatal(err) } wantCurProfile = "" - wantProfiles[""] = emptyPrefs + wantProfiles[""] = defaultPrefs checkProfiles(t) {