Merge pull request #335 from jzelinskie/fix-jwt

middleware/jwt: encode infohashes as hex
This commit is contained in:
Jimmy Zelinskie 2017-06-09 00:11:02 -04:00 committed by GitHub
commit fa6dcddcb6

View file

@ -9,10 +9,11 @@ package jwt
import ( import (
"context" "context"
"crypto" "crypto"
"encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"net/http" "net/http"
"net/url" "strings"
"time" "time"
jc "github.com/SermoDigital/jose/crypto" jc "github.com/SermoDigital/jose/crypto"
@ -163,20 +164,21 @@ func validateJWT(ih bittorrent.InfoHash, jwtBytes []byte, cfgIss, cfgAud string,
return jwt.ErrInvalidISSClaim return jwt.ErrInvalidISSClaim
} }
if aud, ok := claims.Audience(); !ok || !validAudience(aud, cfgAud) { if auds, ok := claims.Audience(); !ok || !in(cfgAud, auds) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"exists": ok, "exists": ok,
"claim": aud, "claim": strings.Join(auds, ","),
"config": cfgAud, "config": cfgAud,
}).Debugln("unequal or missing audience when validating JWT") }).Debugln("unequal or missing audience when validating JWT")
return jwt.ErrInvalidAUDClaim return jwt.ErrInvalidAUDClaim
} }
if ihClaim, ok := claims.Get("infohash").(string); !ok || !validInfoHash(ihClaim, ih) { ihHex := hex.EncodeToString(ih[:])
if ihClaim, ok := claims.Get("infohash").(string); !ok || ihClaim != ihHex {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"exists": ok, "exists": ok,
"request": url.QueryEscape(ih.String()),
"claim": ihClaim, "claim": ihClaim,
"request": ihHex,
}).Debugln("unequal or missing infohash when validating JWT") }).Debugln("unequal or missing infohash when validating JWT")
return errors.New("claim \"infohash\" is invalid") return errors.New("claim \"infohash\" is invalid")
} }
@ -209,30 +211,11 @@ func validateJWT(ih bittorrent.InfoHash, jwtBytes []byte, cfgIss, cfgAud string,
return nil return nil
} }
func validAudience(aud []string, cfgAud string) bool { func in(x string, xs []string) bool {
for _, a := range aud { for _, y := range xs {
if a == cfgAud { if x == y {
return true return true
} }
} }
return false return false
} }
// validInfoHash attempts to match the claim for the Infohash field of a JWT by
// checking both the raw and unescaped forms of the contents of the field.
func validInfoHash(claim string, ih bittorrent.InfoHash) bool {
if len(claim) == 20 && bittorrent.InfoHashFromString(claim) == ih {
return true
}
unescapedClaim, err := url.QueryUnescape(claim)
if err != nil {
return false
}
if len(unescapedClaim) == 20 && bittorrent.InfoHashFromString(unescapedClaim) == ih {
return true
}
return false
}