From 9fcda1f0a00da5f87607523e91084e6a8ce549b0 Mon Sep 17 00:00:00 2001 From: Denton Gentry Date: Sat, 16 Jul 2022 16:08:19 -0700 Subject: [PATCH] cmd/tailscale/cli/web: add QNAP NAS_SID authentication QTS 5.0 doesn't always pass a qtoken, in some circumstances it sends a NAS_SID cookie for us to verify instead. Signed-off-by: Denton Gentry --- cmd/tailscale/cli/web.go | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) 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) {