diff --git a/cmd/tailscale/cli/web.go b/cmd/tailscale/cli/web.go index 0cf7e6f69..855471d15 100644 --- a/cmd/tailscale/cli/web.go +++ b/cmd/tailscale/cli/web.go @@ -208,12 +208,20 @@ func qnapAuthn(r *http.Request) (string, *qnapAuthResponse, error) { return "", nil, err } token, err := r.Cookie("qtoken") - if err != nil { - return "", nil, err + if err == nil { + return qnapAuthnQtoken(r, user.Value, token.Value) + } + sid, err := r.Cookie("NAS_SID") + if err == nil { + return qnapAuthnSid(r, user.Value, sid.Value) } + return "", nil, fmt.Errorf("not authenticated by any mechanism") +} + +func qnapAuthnQtoken(r *http.Request, user, token string) (string, *qnapAuthResponse, error) { query := url.Values{ - "qtoken": []string{token.Value}, - "user": []string{user.Value}, + "qtoken": []string{token}, + "user": []string{user}, } u := url.URL{ Scheme: r.URL.Scheme, @@ -221,7 +229,26 @@ func qnapAuthn(r *http.Request) (string, *qnapAuthResponse, error) { Path: "/cgi-bin/authLogin.cgi", RawQuery: query.Encode(), } - resp, err := http.Get(u.String()) + + return qnapAuthnFinish(user, u.String()) +} + +func qnapAuthnSid(r *http.Request, user, sid string) (string, *qnapAuthResponse, error) { + query := url.Values{ + "sid": []string{sid}, + } + u := url.URL{ + Scheme: r.URL.Scheme, + Host: r.URL.Host, + Path: "/cgi-bin/authLogin.cgi", + RawQuery: query.Encode(), + } + + return qnapAuthnFinish(user, u.String()) +} + +func qnapAuthnFinish(user, url string) (string, *qnapAuthResponse, error) { + resp, err := http.Get(url) if err != nil { return "", nil, err } @@ -237,7 +264,7 @@ func qnapAuthn(r *http.Request) (string, *qnapAuthResponse, error) { if authResp.AuthPassed == 0 { return "", nil, fmt.Errorf("not authenticated") } - return user.Value, authResp, nil + return user, authResp, nil } func synoAuthn() (string, error) {