|
|
|
|
@ -60,6 +60,15 @@ type tmplData struct { |
|
|
|
|
LicensesURL string |
|
|
|
|
TUNMode bool |
|
|
|
|
IsSynology bool |
|
|
|
|
DSMVersion int // 6 or 7, if IsSynology=true
|
|
|
|
|
IPNVersion string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type postedData struct { |
|
|
|
|
AdvertiseRoutes string |
|
|
|
|
AdvertiseExitNode bool |
|
|
|
|
Reauthenticate bool |
|
|
|
|
ForceLogout bool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var webCmd = &ffcli.Command{ |
|
|
|
|
@ -133,7 +142,7 @@ func runWeb(ctx context.Context, args []string) error { |
|
|
|
|
Handler: http.HandlerFunc(webHandler), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.Printf("web server runNIng on: https://%s", server.Addr) |
|
|
|
|
log.Printf("web server running on: https://%s", server.Addr) |
|
|
|
|
return server.ListenAndServeTLS("", "") |
|
|
|
|
} else { |
|
|
|
|
log.Printf("web server running on: %s", urlOfListenAddr(webArgs.listen)) |
|
|
|
|
@ -353,11 +362,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
|
|
|
|
|
if r.Method == "POST" { |
|
|
|
|
defer r.Body.Close() |
|
|
|
|
var postData struct { |
|
|
|
|
AdvertiseRoutes string |
|
|
|
|
AdvertiseExitNode bool |
|
|
|
|
Reauthenticate bool |
|
|
|
|
} |
|
|
|
|
var postData postedData |
|
|
|
|
type mi map[string]any |
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&postData); err != nil { |
|
|
|
|
w.WriteHeader(400) |
|
|
|
|
@ -386,8 +391,15 @@ func webHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "application/json") |
|
|
|
|
log.Printf("tailscaleUp(reauth=%v) ...", postData.Reauthenticate) |
|
|
|
|
url, err := tailscaleUp(r.Context(), st, postData.Reauthenticate) |
|
|
|
|
var reauth, logout bool |
|
|
|
|
if postData.Reauthenticate { |
|
|
|
|
reauth = true |
|
|
|
|
} |
|
|
|
|
if postData.ForceLogout { |
|
|
|
|
logout = true |
|
|
|
|
} |
|
|
|
|
log.Printf("tailscaleUp(reauth=%v, logout=%v) ...", reauth, logout) |
|
|
|
|
url, err := tailscaleUp(r.Context(), st, postData) |
|
|
|
|
log.Printf("tailscaleUp = (URL %v, %v)", url != "", err) |
|
|
|
|
if err != nil { |
|
|
|
|
w.WriteHeader(http.StatusInternalServerError) |
|
|
|
|
@ -404,6 +416,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
|
|
|
|
|
profile := st.User[st.Self.UserID] |
|
|
|
|
deviceName := strings.Split(st.Self.DNSName, ".")[0] |
|
|
|
|
versionShort := strings.Split(st.Version, "-")[0] |
|
|
|
|
data := tmplData{ |
|
|
|
|
SynologyUser: user, |
|
|
|
|
Profile: profile, |
|
|
|
|
@ -412,6 +425,8 @@ func webHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
LicensesURL: licensesURL(), |
|
|
|
|
TUNMode: st.TUN, |
|
|
|
|
IsSynology: distro.Get() == distro.Synology || envknob.Bool("TS_FAKE_SYNOLOGY"), |
|
|
|
|
DSMVersion: distro.DSMVersion(), |
|
|
|
|
IPNVersion: versionShort, |
|
|
|
|
} |
|
|
|
|
exitNodeRouteV4 := netip.MustParsePrefix("0.0.0.0/0") |
|
|
|
|
exitNodeRouteV6 := netip.MustParsePrefix("::/0") |
|
|
|
|
@ -437,10 +452,18 @@ func webHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
w.Write(buf.Bytes()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func tailscaleUp(ctx context.Context, st *ipnstate.Status, forceReauth bool) (authURL string, retErr error) { |
|
|
|
|
func tailscaleUp(ctx context.Context, st *ipnstate.Status, postData postedData) (authURL string, retErr error) { |
|
|
|
|
if postData.ForceLogout { |
|
|
|
|
if err := localClient.Logout(ctx); err != nil { |
|
|
|
|
return "", fmt.Errorf("Logout error: %w", err) |
|
|
|
|
} |
|
|
|
|
return "", nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
origAuthURL := st.AuthURL |
|
|
|
|
isRunning := st.BackendState == ipn.Running.String() |
|
|
|
|
|
|
|
|
|
forceReauth := postData.Reauthenticate |
|
|
|
|
if !forceReauth { |
|
|
|
|
if origAuthURL != "" { |
|
|
|
|
return origAuthURL, nil |
|
|
|
|
|