cmd/tailscale/cli: don't report outdated auth URL to web UI

This brings the web 'up' logic into line with 'tailscale up'.

Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
pull/1842/head
David Crawshaw 4 years ago committed by David Crawshaw
parent 1336ed8d9e
commit 1f48d3556f

@ -73,7 +73,11 @@ func runWeb(ctx context.Context, args []string) error {
} }
if webArgs.cgi { if webArgs.cgi {
return cgi.Serve(http.HandlerFunc(webHandler)) if err := cgi.Serve(http.HandlerFunc(webHandler)); err != nil {
log.Printf("tailscale.cgi: %v", err)
return err
}
return nil
} }
return http.ListenAndServe(webArgs.listen, http.HandlerFunc(webHandler)) return http.ListenAndServe(webArgs.listen, http.HandlerFunc(webHandler))
} }
@ -208,7 +212,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" { if r.Method == "POST" {
type mi map[string]interface{} type mi map[string]interface{}
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
url, err := tailscaleUp(r.Context()) url, err := tailscaleUpForceReauth(r.Context())
if err != nil { if err != nil {
json.NewEncoder(w).Encode(mi{"error": err}) json.NewEncoder(w).Encode(mi{"error": err})
return return
@ -244,7 +248,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) {
} }
// TODO(crawshaw): some of this is very similar to the code in 'tailscale up', can we share anything? // TODO(crawshaw): some of this is very similar to the code in 'tailscale up', can we share anything?
func tailscaleUp(ctx context.Context) (authURL string, retErr error) { func tailscaleUpForceReauth(ctx context.Context) (authURL string, retErr error) {
prefs := ipn.NewPrefs() prefs := ipn.NewPrefs()
prefs.ControlURL = ipn.DefaultControlURL prefs.ControlURL = ipn.DefaultControlURL
prefs.WantRunning = true prefs.WantRunning = true
@ -256,10 +260,31 @@ func tailscaleUp(ctx context.Context) (authURL string, retErr error) {
prefs.NetfilterMode = preftype.NetfilterOff prefs.NetfilterMode = preftype.NetfilterOff
} }
c, bc, ctx, cancel := connect(ctx) st, err := tailscale.Status(ctx)
if err != nil {
return "", fmt.Errorf("can't fetch status: %v", err)
}
origAuthURL := st.AuthURL
// printAuthURL reports whether we should print out the
// provided auth URL from an IPN notify.
printAuthURL := func(url string) bool {
return url != origAuthURL
}
c, bc, pumpCtx, cancel := connect(ctx)
defer cancel() defer cancel()
gotEngineUpdate := make(chan bool, 1) // gets value upon an engine update
go pump(pumpCtx, bc, c)
bc.SetNotifyCallback(func(n ipn.Notify) { bc.SetNotifyCallback(func(n ipn.Notify) {
if n.Engine != nil {
select {
case gotEngineUpdate <- true:
default:
}
}
if n.ErrMessage != nil { if n.ErrMessage != nil {
msg := *n.ErrMessage msg := *n.ErrMessage
if msg == ipn.ErrMsgPermissionDenied { if msg == ipn.ErrMsgPermissionDenied {
@ -272,11 +297,21 @@ func tailscaleUp(ctx context.Context) (authURL string, retErr error) {
} }
retErr = fmt.Errorf("backend error: %v", msg) retErr = fmt.Errorf("backend error: %v", msg)
cancel() cancel()
} else if url := n.BrowseToURL; url != nil { } else if url := n.BrowseToURL; url != nil && printAuthURL(*url) {
authURL = *url authURL = *url
cancel() cancel()
} }
}) })
// Wait for backend client to be connected so we know
// we're subscribed to updates. Otherwise we can miss
// an update upon its transition to running. Do so by causing some traffic
// back to the bus that we then wait on.
bc.RequestEngineStatus()
select {
case <-gotEngineUpdate:
case <-pumpCtx.Done():
return authURL, pumpCtx.Err()
}
bc.SetPrefs(prefs) bc.SetPrefs(prefs)
@ -284,7 +319,6 @@ func tailscaleUp(ctx context.Context) (authURL string, retErr error) {
StateKey: ipn.GlobalDaemonStateKey, StateKey: ipn.GlobalDaemonStateKey,
}) })
bc.StartLoginInteractive() bc.StartLoginInteractive()
pump(ctx, bc, c)
if authURL == "" && retErr == nil { if authURL == "" && retErr == nil {
return "", fmt.Errorf("login failed with no backend error message") return "", fmt.Errorf("login failed with no backend error message")

Loading…
Cancel
Save