|
|
|
@ -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
|
|
|
|
|