challenge

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2025 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RequestOptBackendHost       = "backend-host"
	RequestOptProxyMetaTags     = "proxy-meta-tags"
	RequestOptProxySafeLinkTags = "proxy-safe-link-tags"
)
View Source
const (
	QueryArgPrefix    = "__goaway"
	QueryArgReferer   = QueryArgPrefix + "_referer"
	QueryArgRedirect  = QueryArgPrefix + "_redirect"
	QueryArgRequestId = QueryArgPrefix + "_id"
	QueryArgChallenge = QueryArgPrefix + "_challenge"
	QueryArgToken     = QueryArgPrefix + "_token"
)
View Source
const (
	// ClassTransparent Transparent challenges work inline in the execution process.
	// These can pass or continue, so more challenges or requests can ve served afterward.
	ClassTransparent = Class(iota)

	// ClassBlocking Blocking challenges must serve a different response to challenge the requester.
	// These can pass or stop, for example, due to serving a challenge
	ClassBlocking
)
View Source
const (
	VerifyStateNone = VerifyState(iota)
	// VerifyStatePass Challenge was just passed on this request
	VerifyStatePass
	// VerifyStateBrief Challenge token was verified but didn't check the challenge
	VerifyStateBrief
	// VerifyStateFull Challenge token was verified and challenge verification was done
	VerifyStateFull
)
View Source
const (
	// VerifyResultNone A negative pass result, without a token
	VerifyResultNone = VerifyResult(iota)
	// VerifyResultFail A negative pass result, with an invalid token
	VerifyResultFail
	// VerifyResultSkip Challenge was skipped due to precondition
	VerifyResultSkip
	// VerifyResultNotOK A negative pass result, with a valid token
	VerifyResultNotOK

	// VerifyResultOK A positive pass result, with a valid token
	VerifyResultOK
)
View Source
const DefaultDuration = time.Hour * 24 * 7

DefaultDuration TODO: adjust

View Source
const (
	KeyFlagIsIPv4 = KeyFlags(1 << iota)
)
View Source
const KeySize = sha256.Size
View Source
const MakeChallengeUrlSuffix = "/make-challenge"
View Source
const VerifyChallengeUrlSuffix = "/verify-challenge"

Variables

View Source
var ErrInvalidToken = errors.New("invalid token")
View Source
var ErrMismatchedToken = errors.New("mismatched token")
View Source
var ErrMismatchedTokenHappyEyeballs = errors.New("mismatched token: IPv4 to IPv6 upgrade detected, retrying")
View Source
var ErrTokenExpired = errors.New("token: expired")
View Source
var ErrVerifyKeyMismatch = errors.New("verify: key mismatch")
View Source
var ErrVerifyVerifyMismatch = errors.New("verify: verification mismatch")
View Source
var Runtimes = make(map[string]FillRegistration)

Functions

func RedirectUrl added in v0.5.0

func RedirectUrl(r *http.Request, reg *Registration) (*url.URL, error)

func ServeChallengeScript added in v0.5.0

func ServeChallengeScript(w http.ResponseWriter, r *http.Request, reg *Registration, params any, script string)

func VerifyHandlerChallengeResponseFunc added in v0.5.0

func VerifyHandlerChallengeResponseFunc(state StateInterface, data *RequestData, w http.ResponseWriter, r *http.Request, verifyResult VerifyResult, err error, redirect string)

func VerifyHandlerFunc added in v0.5.0

func VerifyHandlerFunc(state StateInterface, reg *Registration, verify VerifyFunc, responseFunc func(state StateInterface, data *RequestData, w http.ResponseWriter, r *http.Request, verifyResult VerifyResult, err error, redirect string)) http.HandlerFunc

func VerifyUrl added in v0.5.0

func VerifyUrl(r *http.Request, reg *Registration, token string) (*url.URL, error)

Types

type Awaiter added in v0.5.0

type Awaiter[K ~string | ~int64 | ~uint64] haxmap.Map[K, awaiterCallback]

func NewAwaiter added in v0.5.0

func NewAwaiter[T ~string | ~int64 | ~uint64]() *Awaiter[T]

func (*Awaiter[T]) Await added in v0.5.0

func (a *Awaiter[T]) Await(key T, ctx context.Context) VerifyResult

func (*Awaiter[T]) Close added in v0.5.0

func (a *Awaiter[T]) Close() error

func (*Awaiter[T]) Solve added in v0.5.0

func (a *Awaiter[T]) Solve(key T, result VerifyResult)

type Class added in v0.5.0

type Class uint8

type FillRegistration added in v0.5.0

type FillRegistration func(state StateInterface, reg *Registration, parameters ast.Node) error

type Id

type Id int64

type Key added in v0.5.0

type Key [KeySize]byte

func GetChallengeKeyForRequest added in v0.5.0

func GetChallengeKeyForRequest(state StateInterface, reg *Registration, until time.Time, r *http.Request) Key

func KeyFromString added in v0.5.0

func KeyFromString(s string) (Key, error)

func (*Key) Get added in v0.5.0

func (k *Key) Get(flags KeyFlags) KeyFlags

func (*Key) Set added in v0.5.0

func (k *Key) Set(flags KeyFlags)

func (*Key) Unset added in v0.5.0

func (k *Key) Unset(flags KeyFlags)

type KeyFlags added in v0.5.0

type KeyFlags uint8

type Register added in v0.5.0

type Register map[Id]*Registration

func (Register) Add added in v0.5.0

func (r Register) Add(c *Registration) Id

func (Register) Create added in v0.5.0

func (r Register) Create(state StateInterface, name string, pol policy.Challenge, replacer *strings.Replacer) (*Registration, Id, error)

func (Register) Get added in v0.5.0

func (r Register) Get(id Id) (*Registration, bool)

func (Register) GetByName added in v0.5.0

func (r Register) GetByName(name string) (*Registration, Id, bool)

type Registration added in v0.5.0

type Registration struct {

	// Name The unique name for this challenge
	Name string

	// Class whether this challenge is transparent or otherwise
	Class Class

	// Condition A CEL condition which is passed the same environment as general rules.
	// If nil, always true
	// If non-nil, must return true for this challenge to be allowed to be executed
	Condition cel.Program

	// Path The url path that this challenge is hosted under for the Handler to be called.
	Path string

	// Duration How long this challenge will be valid when passed
	Duration time.Duration

	// Handler An HTTP handler for all requests coming on the Path
	// This handler will need to handle MakeChallengeUrlSuffix and VerifyChallengeUrlSuffix as well if needed
	// Recommended to use http.ServeMux
	Handler http.Handler

	// Verify Verify an issued token
	Verify            VerifyFunc
	VerifyProbability float64

	// IssueChallenge Issues a challenge to a request.
	// If Class is ClassTransparent and VerifyResult is !VerifyResult.Ok(), continue with other challenges
	// TODO: have this return error as well
	IssueChallenge func(w http.ResponseWriter, r *http.Request, key Key, expiry time.Time) VerifyResult

	// Object used to handle state or similar
	// Can be nil if no state is needed
	// If non-nil must implement io.Closer even if there's nothing to do
	Object io.Closer
	// contains filtered or unexported fields
}

func (Registration) Id added in v0.5.0

func (reg Registration) Id() Id

type RequestData added in v0.5.0

type RequestData struct {
	Id              RequestId
	Time            time.Time
	ChallengeVerify map[Id]VerifyResult
	ChallengeState  map[Id]VerifyState
	ChallengeMap    TokenChallengeMap

	RemoteAddress netip.AddrPort
	State         StateInterface

	ExtraHeaders http.Header
	// contains filtered or unexported fields
}

func CreateRequestData added in v0.5.0

func CreateRequestData(r *http.Request, state StateInterface) (*http.Request, *RequestData)

func RequestDataFromContext added in v0.5.0

func RequestDataFromContext(ctx context.Context) *RequestData

func (*RequestData) BackendHost added in v0.7.0

func (d *RequestData) BackendHost() (http.Handler, string)

func (*RequestData) ClearChallengeToken added in v0.7.0

func (d *RequestData) ClearChallengeToken(reg *Registration)

func (*RequestData) EvaluateChallenges added in v0.5.0

func (d *RequestData) EvaluateChallenges(w http.ResponseWriter, r *http.Request)

func (*RequestData) Expiration added in v0.5.0

func (d *RequestData) Expiration(duration time.Duration) time.Time

func (*RequestData) GetOpt added in v0.7.0

func (d *RequestData) GetOpt(n, def string) string

func (*RequestData) GetOptBool added in v0.7.0

func (d *RequestData) GetOptBool(n string, def bool) bool

func (*RequestData) HasValidChallenge added in v0.5.0

func (d *RequestData) HasValidChallenge(id Id) bool

func (*RequestData) IssueChallengeToken added in v0.7.0

func (d *RequestData) IssueChallengeToken(reg *Registration, key Key, result []byte, until time.Time, ok bool)

func (*RequestData) NetworkPrefix added in v0.7.0

func (d *RequestData) NetworkPrefix() netip.Addr

func (*RequestData) Parent added in v0.5.0

func (d *RequestData) Parent() cel.Activation

func (*RequestData) RequestHeaders added in v0.7.0

func (d *RequestData) RequestHeaders(headers http.Header)

func (*RequestData) ResolveName added in v0.5.0

func (d *RequestData) ResolveName(name string) (any, bool)

func (*RequestData) ResponseHeaders added in v0.7.0

func (d *RequestData) ResponseHeaders(w http.ResponseWriter)

func (*RequestData) SetOpt added in v0.7.0

func (d *RequestData) SetOpt(n, v string)

func (*RequestData) VerifyChallengeToken added in v0.7.0

func (d *RequestData) VerifyChallengeToken(reg *Registration, token TokenChallenge, expectedKey Key) (VerifyResult, VerifyState, error)

type RequestId added in v0.5.0

type RequestId [16]byte

func GetVerifyInformation added in v0.5.0

func GetVerifyInformation(r *http.Request, reg *Registration) (requestId RequestId, redirect, token string, err error)

func (RequestId) String added in v0.5.0

func (id RequestId) String() string

type StateInterface added in v0.5.0

type StateInterface interface {
	RegisterCondition(operator string, conditions ...string) (cel.Program, error)

	Client() *http.Client
	PrivateKeyFingerprint() []byte
	PrivateKey() ed25519.PrivateKey
	PublicKey() ed25519.PublicKey

	UrlPath() string

	ChallengeFailed(r *http.Request, reg *Registration, err error, redirect string, logger *slog.Logger)
	ChallengePassed(r *http.Request, reg *Registration, redirect string, logger *slog.Logger)
	ChallengeIssued(r *http.Request, reg *Registration, redirect string, logger *slog.Logger)
	ChallengeChecked(r *http.Request, reg *Registration, redirect string, logger *slog.Logger)

	RuleHit(r *http.Request, name string, logger *slog.Logger)
	RuleMiss(r *http.Request, name string, logger *slog.Logger)
	ActionHit(r *http.Request, name policy.RuleAction, logger *slog.Logger)

	Logger(r *http.Request) *slog.Logger

	ChallengePage(w http.ResponseWriter, r *http.Request, status int, reg *Registration, params map[string]any)
	ErrorPage(w http.ResponseWriter, r *http.Request, status int, err error, redirect string)

	GetChallenge(id Id) (*Registration, bool)
	GetChallengeByName(name string) (*Registration, bool)
	GetChallenges() Register

	Settings() policy.StateSettings

	Strings() utils.Strings

	GetBackend(host string) http.Handler
}

type Token

type Token struct {
	State TokenChallengeMap `json:"state"`

	Expiry    jwt.NumericDate `json:"exp,omitempty"`
	NotBefore jwt.NumericDate `json:"nbf,omitempty"`
	IssuedAt  jwt.NumericDate `json:"iat,omitempty"`
}

type TokenChallenge added in v0.7.0

type TokenChallenge struct {
	Key    []byte `json:"key"`
	Result []byte `json:"result,omitempty"`
	Ok     bool   `json:"ok"`

	Expiry    jwt.NumericDate `json:"exp,omitempty"`
	NotBefore jwt.NumericDate `json:"nbf,omitempty"`
	IssuedAt  jwt.NumericDate `json:"iat,omitempty"`
}

type TokenChallengeMap added in v0.7.0

type TokenChallengeMap map[string]TokenChallenge

type VerifyFunc added in v0.5.0

type VerifyFunc func(key Key, token []byte, r *http.Request) (VerifyResult, error)

func NewKeyVerifier added in v0.5.0

func NewKeyVerifier() (verify VerifyFunc, issue func(key Key) string)

type VerifyResult

type VerifyResult uint8

func (VerifyResult) Ok

func (r VerifyResult) Ok() bool

func (VerifyResult) String

func (r VerifyResult) String() string

type VerifyState added in v0.5.0

type VerifyState uint8

func (VerifyState) String added in v0.5.0

func (r VerifyState) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL