aboutsummaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
authorpg9182 <96569817+pg9182@users.noreply.github.com>2022-10-13 18:42:29 -0400
committerpg9182 <96569817+pg9182@users.noreply.github.com>2022-10-13 18:42:29 -0400
commitd6247edb2ab541540b4f0420fff5b8ae43a5f8c1 (patch)
treef40db4385fd7fc61cdf6c31fc63a5fc039f3ceed /pkg/api
parentdc0d9298fa09a45d53955d4171f1a62127523d2d (diff)
downloadAtlas-d6247edb2ab541540b4f0420fff5b8ae43a5f8c1.tar.gz
Atlas-d6247edb2ab541540b4f0420fff5b8ae43a5f8c1.zip
pkg/api/api0: Implement version gate
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/api0/api.go41
-rw-r--r--pkg/api/api0/client.go8
2 files changed, 48 insertions, 1 deletions
diff --git a/pkg/api/api0/api.go b/pkg/api/api0/api.go
index e6ed251..f7b787c 100644
--- a/pkg/api/api0/api.go
+++ b/pkg/api/api0/api.go
@@ -20,6 +20,9 @@ import (
"net/http"
"strconv"
"strings"
+
+ "github.com/rs/zerolog/hlog"
+ "golang.org/x/mod/semver"
)
// Handler serves requests for the original master server API.
@@ -40,6 +43,11 @@ type Handler struct {
// makes the server trust that clients are who they say they are. Blame
// @BobTheBob9 for this option even existing in the first place.
InsecureDevNoCheckPlayerAuth bool
+
+ // MinimumLauncherVersion restricts authentication and server registration
+ // to clients with at least this version, which must be valid semver. +dev
+ // versions are always allowed.
+ MinimumLauncherVersion string
}
// ServeHTTP routes requests to Handler.
@@ -71,6 +79,39 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
+// checkLauncherVersion checks if the r was made by NorthstarLauncher and if it
+// is at least MinimumLauncherVersion.
+func (h *Handler) checkLauncherVersion(r *http.Request) bool {
+ rver, _, _ := strings.Cut(r.Header.Get("User-Agent"), " ")
+ if x := strings.TrimPrefix(rver, "R2Northstar/"); rver != x {
+ if x[0] != 'v' {
+ rver = "v" + x
+ } else {
+ rver = x
+ }
+ } else {
+ return false // deny: not R2Northstar
+ }
+
+ mver := h.MinimumLauncherVersion
+ if mver != "" {
+ if mver[0] != 'v' {
+ mver = "v" + mver
+ }
+ } else {
+ return true // allow: no minimum version
+ }
+ if !semver.IsValid(mver) {
+ hlog.FromRequest(r).Warn().Msgf("not checking invalid minimum version %q", mver)
+ return true // allow: invalid minimum version
+ }
+
+ if strings.HasSuffix(rver, "+dev") {
+ return true // allow: dev versions
+ }
+ return semver.Compare(rver, mver) >= 0
+}
+
// respJSON writes the JSON encoding of obj with the provided response status.
func respJSON(w http.ResponseWriter, r *http.Request, status int, obj any) {
if r.Method == http.MethodHead {
diff --git a/pkg/api/api0/client.go b/pkg/api/api0/client.go
index 3f10dcb..b805261 100644
--- a/pkg/api/api0/client.go
+++ b/pkg/api/api0/client.go
@@ -75,7 +75,13 @@ func (h *Handler) handleClientAuthWithSelf(w http.ResponseWriter, r *http.Reques
return
}
- // TODO: version gate
+ if !h.checkLauncherVersion(r) {
+ respJSON(w, r, http.StatusBadRequest, map[string]any{
+ "success": false,
+ "error": ErrorCode_UNSUPPORTED_VERSION,
+ })
+ return
+ }
uidQ := r.URL.Query().Get("id")
if uidQ == "" {