From 3e5c3e932c8c4dff0cc0c8658a5c80818422400d Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Wed, 17 Feb 2021 16:01:47 -0500 Subject: [PATCH] net/tshttpproxy: support basic auth when available (#1354) This allows proxy URLs such as: http://azurediamond:hunter2@192.168.122.154:38274 to be used in order to dial out to control, logs or derp servers. Signed-off-by: Christine Dodrill --- net/tshttpproxy/tshttpproxy.go | 12 +++++++ net/tshttpproxy/tshttpproxy_test.go | 49 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 net/tshttpproxy/tshttpproxy_test.go diff --git a/net/tshttpproxy/tshttpproxy.go b/net/tshttpproxy/tshttpproxy.go index 56d4d57de..98f67a31a 100644 --- a/net/tshttpproxy/tshttpproxy.go +++ b/net/tshttpproxy/tshttpproxy.go @@ -74,6 +74,18 @@ func GetAuthHeader(u *url.URL) (string, error) { if sysAuthHeader != nil { return sysAuthHeader(u) } + + if user := u.User.Username(); user != "" { + pass, ok := u.User.Password() + if !ok { + return "", nil + } + + req := &http.Request{Header: make(http.Header)} + req.SetBasicAuth(user, pass) + return req.Header.Get("Authorization"), nil + } + return "", nil } diff --git a/net/tshttpproxy/tshttpproxy_test.go b/net/tshttpproxy/tshttpproxy_test.go new file mode 100644 index 000000000..2b3d40beb --- /dev/null +++ b/net/tshttpproxy/tshttpproxy_test.go @@ -0,0 +1,49 @@ +// 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 tshttpproxy + +import ( + "net/url" + "testing" +) + +func TestGetAuthHeaderNoResult(t *testing.T) { + const proxyURL = `http://127.0.0.1:38274` + + u, err := url.Parse(proxyURL) + if err != nil { + t.Fatalf("can't parse %q: %v", proxyURL, err) + } + + ahval, err := GetAuthHeader(u) + if err != nil { + t.Fatalf("can't get auth header value: %v", err) + } + + if ahval != "" { + t.Fatalf("wanted auth header value to be empty, got: %q", ahval) + } +} + +func TestGetAuthHeaderBasicAuth(t *testing.T) { + const proxyURL = `http://user:password@127.0.0.1:38274` + const expect = `Basic dXNlcjpwYXNzd29yZA==` + + u, err := url.Parse(proxyURL) + if err != nil { + t.Fatalf("can't parse %q: %v", proxyURL, err) + } + + ahval, err := GetAuthHeader(u) + if err != nil { + t.Fatalf("can't get auth header value: %v", err) + } + + if ahval != expect { + t.Fatalf("wrong auth header value: want: %q, got: %q", expect, ahval) + } +}