diff --git a/handler.go b/handler.go index 7c2943c..41b52de 100644 --- a/handler.go +++ b/handler.go @@ -315,6 +315,37 @@ func (cr *Cluster) getRecordMiddleWare() utils.MiddleWareFunc { } } +func (cr *Cluster) checkQuerySign(req *http.Request, hash string, secret string) bool { + if config.Advanced.SkipSignatureCheck { + return true + } + query := req.Query() + sign, e := query.Get("s"), query.Get("e") + if len(sign) == 0 || len(e) == 0 { + return false + } + before, err := strconv.ParseInt(e, 36, 64) + if err != nil { + return false + } + if time.Now().UnixMilli() > before { + return false + } + hs := crypto.SHA1.New() + io.WriteString(hs, secret) + io.WriteString(hs, hash) + io.WriteString(hs, e) + var ( + buf [20]byte + sbuf [27]byte + ) + base64.RawURLEncoding.Encode(sbuf[:], hs.Sum(buf[:0])) + if (string)(sbuf[:]) != sign { + return false + } + return true +} + var emptyHashes = func() (hashes map[string]struct{}) { hashMethods := []crypto.Hash{ crypto.MD5, crypto.SHA1, @@ -329,9 +360,6 @@ var emptyHashes = func() (hashes map[string]struct{}) { var HeaderXPoweredBy = fmt.Sprintf("go-openbmclapi/%s; url=https://github.com/LiterMC/go-openbmclapi", build.BuildVersion) -var accessedTeapotMux sync.RWMutex -var accessedTeapot = make(map[string]struct{}) - //go:embed robots.txt var robotTxtContent string @@ -357,7 +385,7 @@ func (cr *Cluster) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } query := req.URL.Query() - if !checkQuerySign(hash, cr.clusterSecret, query) { + if !cr.checkQuerySign(req, hash, cr.clusterSecret) { http.Error(rw, "Cannot verify signature", http.StatusForbidden) return } @@ -379,7 +407,7 @@ func (cr *Cluster) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } query := req.URL.Query() - if !checkQuerySign(u.Path, cr.clusterSecret, query) { + if !cr.checkQuerySign(req, u.Path, cr.clusterSecret) { http.Error(rw, "Cannot verify signature", http.StatusForbidden) return } diff --git a/util.go b/util.go index 953bb95..191c1c9 100644 --- a/util.go +++ b/util.go @@ -163,33 +163,6 @@ func copyFile(src, dst string, mode os.FileMode) (err error) { return } -func checkQuerySign(hash string, secret string, query url.Values) bool { - if config.Advanced.SkipSignatureCheck { - return true - } - sign, e := query.Get("s"), query.Get("e") - if len(sign) == 0 || len(e) == 0 { - return false - } - before, err := strconv.ParseInt(e, 36, 64) - if err != nil { - return false - } - hs := crypto.SHA1.New() - io.WriteString(hs, secret) - io.WriteString(hs, hash) - io.WriteString(hs, e) - var ( - buf [20]byte - sbuf [27]byte - ) - base64.RawURLEncoding.Encode(sbuf[:], hs.Sum(buf[:0])) - if (string)(sbuf[:]) != sign { - return false - } - return time.Now().UnixMilli() < before -} - type RedirectError struct { Redirects []*url.URL Err error