diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go new file mode 100644 index 00000000..cfaffa06 --- /dev/null +++ b/apple_mobileconfig.go @@ -0,0 +1,179 @@ +package headscale + +import ( + "bytes" + "net/http" + "text/template" + + "github.com/gin-gonic/gin" + "github.com/gofrs/uuid" +) + +// AppleMobileConfig shows a simple message in the browser to point to the CLI +// Listens in /register +func (h *Headscale) AppleMobileConfig(c *gin.Context) { + t := template.Must(template.New("apple").Parse(` + +
++ This page provides configuration profiles for the official Tailscale clients for iOS and macOS. +
++ The profiles will configure Tailscale.app to use {{.Url}} as its control server. +
+ +You should always inspect the profile before installing it:
+curl {{.Url}}/apple/ios
curl {{.Url}}/apple/macos
+ iOS +
+ ++ macOS +
+ + +`)) + + config := map[string]interface{}{ + "Url": h.cfg.ServerURL, + } + + var payload bytes.Buffer + if err := t.Execute(&payload, config); err != nil { + c.Error(err) + return + } + + c.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes()) +} + +func (h *Headscale) ApplePlatformConfig(c *gin.Context) { + platform := c.Param("platform") + + id, err := uuid.NewV4() + if err != nil { + c.Error(err) + return + } + + contentId, err := uuid.NewV4() + if err != nil { + c.Error(err) + return + } + + platformConfig := AppleMobilePlatformConfig{ + UUID: contentId, + Url: h.cfg.ServerURL, + } + + var payload bytes.Buffer + + switch platform { + case "macos": + if err := macosTemplate.Execute(&payload, platformConfig); err != nil { + c.Error(err) + return + } + case "ios": + if err := iosTemplate.Execute(&payload, platformConfig); err != nil { + c.Error(err) + return + } + default: + c.Data(http.StatusOK, "text/html; charset=utf-8", []byte("Invalid platform, only ios and macos is supported")) + return + } + + config := AppleMobileConfig{ + UUID: id, + Url: h.cfg.ServerURL, + Payload: payload.String(), + } + + var content bytes.Buffer + if err := commonTemplate.Execute(&content, config); err != nil { + c.Error(err) + return + } + + c.Data(http.StatusOK, "application/x-apple-aspen-config; charset=utf-8", content.Bytes()) +} + +type AppleMobileConfig struct { + UUID uuid.UUID + Url string + Payload string +} + +type AppleMobilePlatformConfig struct { + UUID uuid.UUID + Url string +} + +var commonTemplate = template.Must(template.New("mobileconfig").Parse(` + +