Browse Source

logpolicy: set log target on windows based on a registry key (#1542)

Signed-off-by: Christine Dodrill <[email protected]>
Christine Dodrill 5 years ago
parent
commit
a480b1baa5
4 changed files with 67 additions and 1 deletions
  1. 1 0
      cmd/tailscaled/depaware.txt
  2. 22 1
      logpolicy/logpolicy.go
  3. 28 0
      util/winutil/winutil.go
  4. 16 0
      util/winutil/winutil_notwindows.go

+ 1 - 0
cmd/tailscaled/depaware.txt

@@ -130,6 +130,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         tailscale.com/util/pidowner                                  from tailscale.com/ipn/ipnserver
         tailscale.com/util/racebuild                                 from tailscale.com/logpolicy
         tailscale.com/util/systemd                                   from tailscale.com/control/controlclient+
+        tailscale.com/util/winutil                                   from tailscale.com/logpolicy
         tailscale.com/version                                        from tailscale.com/cmd/tailscaled+
         tailscale.com/version/distro                                 from tailscale.com/control/controlclient+
         tailscale.com/wgengine                                       from tailscale.com/cmd/tailscaled+

+ 22 - 1
logpolicy/logpolicy.go

@@ -24,6 +24,7 @@ import (
 	"runtime"
 	"strconv"
 	"strings"
+	"sync"
 	"time"
 
 	"golang.org/x/term"
@@ -37,9 +38,29 @@ import (
 	"tailscale.com/smallzstd"
 	"tailscale.com/types/logger"
 	"tailscale.com/util/racebuild"
+	"tailscale.com/util/winutil"
 	"tailscale.com/version"
 )
 
+var getLogTargetOnce struct {
+	sync.Once
+	v string // URL of logs server, or empty for default
+}
+
+func getLogTarget() string {
+	getLogTargetOnce.Do(func() {
+		if val, ok := os.LookupEnv("TS_LOG_TARGET"); ok {
+			getLogTargetOnce.v = val
+		} else {
+			if runtime.GOOS == "windows" {
+				getLogTargetOnce.v = winutil.GetRegString("LogTarget", "")
+			}
+		}
+	})
+
+	return getLogTargetOnce.v
+}
+
 // Config represents an instance of logs in a collection.
 type Config struct {
 	Collection string
@@ -400,7 +421,7 @@ func New(collection string) *Policy {
 		HTTPC: &http.Client{Transport: newLogtailTransport(logtail.DefaultHost)},
 	}
 
-	if val, ok := os.LookupEnv("TS_LOG_TARGET"); ok {
+	if val := getLogTarget(); val != "" {
 		log.Println("You have enabled a non-default log target. Doing without being told to by Tailscale staff or your network administrator will make getting support difficult.")
 		c.BaseURL = val
 		u, _ := url.Parse(val)

+ 28 - 0
util/winutil/winutil.go

@@ -8,9 +8,14 @@
 package winutil
 
 import (
+	"log"
+
 	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/registry"
 )
 
+const RegBase = `SOFTWARE\Tailscale IPN`
+
 // GetDesktopPID searches the PID of the process that's running the
 // currently active desktop and whether it was found.
 // Usually the PID will be for explorer.exe.
@@ -22,3 +27,26 @@ func GetDesktopPID() (pid uint32, ok bool) {
 	windows.GetWindowThreadProcessId(hwnd, &pid)
 	return pid, pid != 0
 }
+
+// GetRegString looks up a registry path in our local machine path, or returns
+// the given default if it can't.
+//
+// This function will only work on GOOS=windows. Trying to run it on any other
+// OS will always return the default value.
+func GetRegString(name, defval string) string {
+	key, err := registry.OpenKey(registry.LOCAL_MACHINE, RegBase, registry.READ)
+	if err != nil {
+		log.Printf("registry.OpenKey(%v): %v", RegBase, err)
+		return defval
+	}
+	defer key.Close()
+
+	val, _, err := key.GetStringValue(name)
+	if err != nil {
+		if err != registry.ErrNotExist {
+			log.Printf("registry.GetStringValue(%v): %v", name, err)
+		}
+		return defval
+	}
+	return val
+}

+ 16 - 0
util/winutil/winutil_notwindows.go

@@ -0,0 +1,16 @@
+// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+
+package winutil
+
+const RegBase = ``
+
+// GetRegString looks up a registry path in our local machine path, or returns
+// the given default if it can't.
+//
+// This function will only work on GOOS=windows. Trying to run it on any other
+// OS will always return the default value.
+func GetRegString(name, defval string) string { return defval }