token.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package management
  2. import (
  3. "fmt"
  4. "github.com/go-jose/go-jose/v4"
  5. "github.com/go-jose/go-jose/v4/jwt"
  6. )
  7. type managementTokenClaims struct {
  8. Tunnel tunnel `json:"tun"`
  9. Actor actor `json:"actor"`
  10. }
  11. // VerifyTunnel compares the tun claim isn't empty
  12. func (c *managementTokenClaims) verify() bool {
  13. return c.Tunnel.verify() && c.Actor.verify()
  14. }
  15. type tunnel struct {
  16. ID string `json:"id"`
  17. AccountTag string `json:"account_tag"`
  18. }
  19. // verify compares the tun claim isn't empty
  20. func (t *tunnel) verify() bool {
  21. return t.AccountTag != "" && t.ID != ""
  22. }
  23. type actor struct {
  24. ID string `json:"id"`
  25. Support bool `json:"support"`
  26. }
  27. // verify checks the ID claim isn't empty
  28. func (t *actor) verify() bool {
  29. return t.ID != ""
  30. }
  31. func parseToken(token string) (*managementTokenClaims, error) {
  32. jwt, err := jwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.ES256})
  33. if err != nil {
  34. return nil, fmt.Errorf("malformed jwt: %v", err)
  35. }
  36. var claims managementTokenClaims
  37. // This is actually safe because we verify the token in the edge before it reaches cloudflared
  38. err = jwt.UnsafeClaimsWithoutVerification(&claims)
  39. if err != nil {
  40. return nil, fmt.Errorf("malformed jwt: %v", err)
  41. }
  42. if !claims.verify() {
  43. return nil, fmt.Errorf("invalid management token format provided")
  44. }
  45. return &claims, nil
  46. }