MCPcopy
hub / github.com/caddyserver/caddy / enforceAccessControls

Method enforceAccessControls

admin.go:668–723  ·  view source on GitHub ↗

enforceAccessControls enforces application-layer access controls for r based on remote. It expects that the TLS server has already established at least one verified chain of trust, and then looks for a matching, authorized public key that is allowed to access the defined path(s) using the defined me

(r *http.Request)

Source from the content-addressed store, hash-verified

666// trust, and then looks for a matching, authorized public key that is allowed to access
667// the defined path(s) using the defined method(s).
668func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {
669 for _, chain := range r.TLS.VerifiedChains {
670 for _, peerCert := range chain {
671 for _, adminAccess := range remote.AccessControl {
672 for _, allowedKey := range adminAccess.publicKeys {
673 // see if we found a matching public key; the TLS server already verified the chain
674 // so we know the client possesses the associated private key; this handy interface
675 // doesn't appear to be defined anywhere in the std lib, but was implemented here:
676 // https://github.com/golang/go/commit/b5f2c0f50297fa5cd14af668ddd7fd923626cf8c
677 comparer, ok := peerCert.PublicKey.(interface{ Equal(crypto.PublicKey) bool })
678 if !ok || !comparer.Equal(allowedKey) {
679 continue
680 }
681
682 // key recognized; make sure its HTTP request is permitted
683 for _, accessPerm := range adminAccess.Permissions {
684 // verify method
685 methodFound := accessPerm.Methods == nil || slices.Contains(accessPerm.Methods, r.Method)
686 if !methodFound {
687 return APIError{
688 HTTPStatus: http.StatusForbidden,
689 Message: "not authorized to use this method",
690 }
691 }
692
693 // verify path
694 pathFound := accessPerm.Paths == nil
695 for _, allowedPath := range accessPerm.Paths {
696 if adminPathAllowed(r.URL.Path, allowedPath) {
697 pathFound = true
698 break
699 }
700 }
701 if !pathFound {
702 return APIError{
703 HTTPStatus: http.StatusForbidden,
704 Message: "not authorized to access this path",
705 }
706 }
707 }
708
709 // public key authorized, method and path allowed
710 return nil
711 }
712 }
713 }
714 }
715
716 // in theory, this should never happen; with an unverified chain, the TLS server
717 // should not accept the connection in the first place, and the acceptable cert
718 // pool is configured using the same list of public keys we verify against
719 return APIError{
720 HTTPStatus: http.StatusUnauthorized,
721 Message: "client identity not authorized",
722 }
723}
724
725func adminPathAllowed(reqPath, allowedPath string) bool {

Callers 2

serveHTTPMethod · 0.80

Calls 2

adminPathAllowedFunction · 0.85
EqualMethod · 0.45