Browse Source

tshttp, derphttp: send Proxy-Authorization, not Authorization, to proxies

Whoops. But weirdly, sending Authorization sometimes worked?
Brad Fitzpatrick 5 years ago
parent
commit
1e0be5a458

+ 6 - 2
cmd/tailscale/cli/debug.go

@@ -106,10 +106,14 @@ func getURL(ctx context.Context, urlStr string) error {
 	}
 	if proxyURL != nil {
 		auth, err := tshttpproxy.GetAuthHeader(proxyURL)
-		log.Printf("tshttpproxy.GetAuthHeader(%v) = %q, %v", proxyURL, auth, err)
 		if err == nil && auth != "" {
-			tr.ProxyConnectHeader.Set("Authorization", auth)
+			tr.ProxyConnectHeader.Set("Proxy-Authorization", auth)
 		}
+		const truncLen = 20
+		if len(auth) > truncLen {
+			auth = fmt.Sprintf("%s...(%d total bytes)", auth[:truncLen], len(auth))
+		}
+		log.Printf("tshttpproxy.GetAuthHeader(%v) for Proxy-Auth: = %q, %v", proxyURL, auth, err)
 	}
 	res, err := tr.RoundTrip(req)
 	if err != nil {

+ 1 - 1
derp/derphttp/derphttp_client.go

@@ -594,7 +594,7 @@ func (c *Client) dialNodeUsingProxy(ctx context.Context, n *tailcfg.DERPNode, pr
 	if v, err := tshttpproxy.GetAuthHeader(pu); err != nil {
 		c.logf("derphttp: error getting proxy auth header for %v: %v", proxyURL, err)
 	} else if v != "" {
-		authHeader = fmt.Sprintf("Authorization: %s\r\n", v)
+		authHeader = fmt.Sprintf("Proxy-Authorization: %s\r\n", v)
 	}
 
 	if _, err := fmt.Fprintf(proxyConn, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n%s\r\n", target, pu.Hostname(), authHeader); err != nil {

+ 13 - 1
net/tshttpproxy/tshttpproxy_future.go

@@ -11,11 +11,14 @@ package tshttpproxy
 
 import (
 	"context"
+	"fmt"
 	"log"
 	"net/http"
 	"net/url"
 )
 
+const proxyAuthHeader = "Proxy-Authorization"
+
 func init() {
 	condSetTransportGetProxyConnectHeader = func(tr *http.Transport) {
 		tr.GetProxyConnectHeader = func(ctx context.Context, proxyURL *url.URL, target string) (http.Header, error) {
@@ -27,7 +30,16 @@ func init() {
 			if v == "" {
 				return nil, nil
 			}
-			return http.Header{"Authorization": []string{v}}, nil
+			return http.Header{proxyAuthHeader: []string{v}}, nil
+		}
+		tr.OnProxyConnectResponse = func(ctx context.Context, proxyURL *url.URL, connectReq *http.Request, res *http.Response) error {
+			auth := connectReq.Header.Get(proxyAuthHeader)
+			const truncLen = 20
+			if len(auth) > truncLen {
+				auth = fmt.Sprintf("%s...(%d total bytes)", auth[:truncLen], len(auth))
+			}
+			log.Printf("tshttpproxy: CONNECT response from %v for target %q (auth %q): %v", proxyURL, connectReq.Host, auth, res.Status)
+			return nil
 		}
 	}
 }