Fix (part of) PR comments

This commit is contained in:
Herman Slatman 2022-04-21 12:14:03 +02:00
parent 3eecc4f7bb
commit a2cfbe3d54
No known key found for this signature in database
GPG key ID: F4D8A44EA0A75A4F
11 changed files with 346 additions and 799 deletions

View file

@ -24,7 +24,7 @@ func JSON(r io.Reader, v interface{}) error {
}
// ProtoJSON reads JSON from the request body and stores it in the value
// pointed to by v.
// pointed to by m.
func ProtoJSON(r io.Reader, m proto.Message) error {
data, err := io.ReadAll(r)
if err != nil {

View file

@ -74,8 +74,7 @@ func (par *PolicyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
}
if policy != nil {
adminErr := admin.NewError(admin.ErrorBadRequestType, "authority already has a policy")
adminErr.Status = http.StatusConflict
adminErr := admin.NewError(admin.ErrorConflictType, "authority already has a policy")
render.Error(w, adminErr)
return
}
@ -197,8 +196,7 @@ func (par *PolicyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
policy := prov.GetPolicy()
if policy != nil {
adminErr := admin.NewError(admin.ErrorBadRequestType, "provisioner %s already has a policy", prov.Name)
adminErr.Status = http.StatusConflict
adminErr := admin.NewError(admin.ErrorConflictType, "provisioner %s already has a policy", prov.Name)
render.Error(w, adminErr)
return
}
@ -307,8 +305,7 @@ func (par *PolicyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
policy := eak.GetPolicy()
if policy != nil {
adminErr := admin.NewError(admin.ErrorBadRequestType, "ACME EAK %s already has a policy", eak.Id)
adminErr.Status = http.StatusConflict
adminErr := admin.NewError(admin.ErrorConflictType, "ACME EAK %s already has a policy", eak.Id)
render.Error(w, adminErr)
return
}

View file

@ -154,9 +154,8 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
},
"fail/existing-policy": func(t *testing.T) test {
ctx := context.Background()
err := admin.NewError(admin.ErrorBadRequestType, "authority already has a policy")
err := admin.NewError(admin.ErrorConflictType, "authority already has a policy")
err.Message = "authority already has a policy"
err.Status = http.StatusConflict
return test{
ctx: ctx,
auth: &mockAdminAuthority{
@ -864,9 +863,8 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
Policy: policy,
}
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
err := admin.NewError(admin.ErrorBadRequestType, "provisioner provName already has a policy")
err := admin.NewError(admin.ErrorConflictType, "provisioner provName already has a policy")
err.Message = "provisioner provName already has a policy"
err.Status = http.StatusConflict
return test{
ctx: ctx,
err: err,
@ -1466,9 +1464,8 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
}
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
ctx = linkedca.NewContextWithExternalAccountKey(ctx, eak)
err := admin.NewError(admin.ErrorBadRequestType, "ACME EAK eakID already has a policy")
err := admin.NewError(admin.ErrorConflictType, "ACME EAK eakID already has a policy")
err.Message = "ACME EAK eakID already has a policy"
err.Status = http.StatusConflict
return test{
ctx: ctx,
err: err,

View file

@ -24,10 +24,12 @@ const (
ErrorBadRequestType
// ErrorNotImplementedType not implemented.
ErrorNotImplementedType
// ErrorUnauthorizedType internal server error.
// ErrorUnauthorizedType unauthorized.
ErrorUnauthorizedType
// ErrorServerInternalType internal server error.
ErrorServerInternalType
// ErrorConflictType conflict.
ErrorConflictType
)
// String returns the string representation of the admin problem type,
@ -48,6 +50,8 @@ func (ap ProblemType) String() string {
return "unauthorized"
case ErrorServerInternalType:
return "internalServerError"
case ErrorConflictType:
return "conflict"
default:
return fmt.Sprintf("unsupported error type '%d'", int(ap))
}
@ -64,7 +68,7 @@ var (
errorServerInternalMetadata = errorMetadata{
typ: ErrorServerInternalType.String(),
details: "the server experienced an internal error",
status: 500,
status: http.StatusInternalServerError,
}
errorMap = map[ProblemType]errorMetadata{
ErrorNotFoundType: {
@ -98,6 +102,11 @@ var (
status: http.StatusUnauthorized,
},
ErrorServerInternalType: errorServerInternalMetadata,
ErrorConflictType: {
typ: ErrorConflictType.String(),
details: "conflict",
status: http.StatusConflict,
},
}
)

View file

@ -318,11 +318,10 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
opts := &authPolicy.Options{}
// fill x509 policy configuration
if p.GetX509() != nil {
if x509 := p.GetX509(); x509 != nil {
opts.X509 = &authPolicy.X509PolicyOptions{}
if p.GetX509().GetAllow() != nil {
if allow := x509.GetAllow(); allow != nil {
opts.X509.AllowedNames = &authPolicy.X509NameOptions{}
allow := p.GetX509().GetAllow()
if allow.Dns != nil {
opts.X509.AllowedNames.DNSDomains = allow.Dns
}
@ -336,9 +335,8 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
opts.X509.AllowedNames.URIDomains = allow.Uris
}
}
if p.GetX509().GetDeny() != nil {
if deny := x509.GetDeny(); deny != nil {
opts.X509.DeniedNames = &authPolicy.X509NameOptions{}
deny := p.GetX509().GetDeny()
if deny.Dns != nil {
opts.X509.DeniedNames.DNSDomains = deny.Dns
}
@ -352,22 +350,21 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
opts.X509.DeniedNames.URIDomains = deny.Uris
}
}
if p.GetX509().GetAllowWildcardLiteral() != nil {
opts.X509.AllowWildcardLiteral = &p.GetX509().GetAllowWildcardLiteral().Value
if v := x509.GetAllowWildcardLiteral(); v != nil {
opts.X509.AllowWildcardLiteral = &v.Value
}
if p.GetX509().GetVerifySubjectCommonName() != nil {
opts.X509.VerifySubjectCommonName = &p.GetX509().VerifySubjectCommonName.Value
if v := x509.GetVerifySubjectCommonName(); v != nil {
opts.X509.VerifySubjectCommonName = &v.Value
}
}
// fill ssh policy configuration
if p.GetSsh() != nil {
if ssh := p.GetSsh(); ssh != nil {
opts.SSH = &authPolicy.SSHPolicyOptions{}
if p.GetSsh().GetHost() != nil {
if host := ssh.GetHost(); host != nil {
opts.SSH.Host = &authPolicy.SSHHostCertificateOptions{}
if p.GetSsh().GetHost().GetAllow() != nil {
if allow := host.GetAllow(); allow != nil {
opts.SSH.Host.AllowedNames = &authPolicy.SSHNameOptions{}
allow := p.GetSsh().GetHost().GetAllow()
if allow.Dns != nil {
opts.SSH.Host.AllowedNames.DNSDomains = allow.Dns
}
@ -378,9 +375,8 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
opts.SSH.Host.AllowedNames.Principals = allow.Principals
}
}
if p.GetSsh().GetHost().GetDeny() != nil {
if deny := host.GetDeny(); deny != nil {
opts.SSH.Host.DeniedNames = &authPolicy.SSHNameOptions{}
deny := p.GetSsh().GetHost().GetDeny()
if deny.Dns != nil {
opts.SSH.Host.DeniedNames.DNSDomains = deny.Dns
}
@ -392,11 +388,10 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
}
}
}
if p.GetSsh().GetUser() != nil {
if user := ssh.GetUser(); user != nil {
opts.SSH.User = &authPolicy.SSHUserCertificateOptions{}
if p.GetSsh().GetUser().GetAllow() != nil {
if allow := user.GetAllow(); allow != nil {
opts.SSH.User.AllowedNames = &authPolicy.SSHNameOptions{}
allow := p.GetSsh().GetUser().GetAllow()
if allow.Emails != nil {
opts.SSH.User.AllowedNames.EmailAddresses = allow.Emails
}
@ -404,9 +399,8 @@ func policyToCertificates(p *linkedca.Policy) *authPolicy.Options {
opts.SSH.User.AllowedNames.Principals = allow.Principals
}
}
if p.GetSsh().GetUser().GetDeny() != nil {
if deny := user.GetDeny(); deny != nil {
opts.SSH.User.DeniedNames = &authPolicy.SSHNameOptions{}
deny := p.GetSsh().GetUser().GetDeny()
if deny.Emails != nil {
opts.SSH.User.DeniedNames.EmailAddresses = deny.Emails
}

View file

@ -67,6 +67,14 @@ func (o *X509NameOptions) HasNames() bool {
len(o.URIDomains) > 0
}
// GetAllowedNameOptions returns x509 allowed name policy configuration
func (o *X509PolicyOptions) GetAllowedNameOptions() *X509NameOptions {
if o == nil {
return nil
}
return o.AllowedNames
}
// GetDeniedNameOptions returns the x509 denied name policy configuration
func (o *X509PolicyOptions) GetDeniedNameOptions() *X509NameOptions {
if o == nil {
@ -75,18 +83,6 @@ func (o *X509PolicyOptions) GetDeniedNameOptions() *X509NameOptions {
return o.DeniedNames
}
// GetAllowedUserNameOptions returns the SSH allowed user name policy
// configuration.
func (o *SSHPolicyOptions) GetAllowedUserNameOptions() *SSHNameOptions {
if o == nil {
return nil
}
if o.User == nil {
return nil
}
return o.User.AllowedNames
}
func (o *X509PolicyOptions) IsWildcardLiteralAllowed() bool {
if o == nil {
return true
@ -122,21 +118,19 @@ type SSHPolicyOptions struct {
Host *SSHHostCertificateOptions `json:"host,omitempty"`
}
// GetAllowedNameOptions returns x509 allowed name policy configuration
func (o *X509PolicyOptions) GetAllowedNameOptions() *X509NameOptions {
if o == nil {
// GetAllowedUserNameOptions returns the SSH allowed user name policy
// configuration.
func (o *SSHPolicyOptions) GetAllowedUserNameOptions() *SSHNameOptions {
if o == nil || o.User == nil {
return nil
}
return o.AllowedNames
return o.User.AllowedNames
}
// GetDeniedUserNameOptions returns the SSH denied user name policy
// configuration.
func (o *SSHPolicyOptions) GetDeniedUserNameOptions() *SSHNameOptions {
if o == nil {
return nil
}
if o.User == nil {
if o == nil || o.User == nil {
return nil
}
return o.User.DeniedNames
@ -145,10 +139,7 @@ func (o *SSHPolicyOptions) GetDeniedUserNameOptions() *SSHNameOptions {
// GetAllowedHostNameOptions returns the SSH allowed host name policy
// configuration.
func (o *SSHPolicyOptions) GetAllowedHostNameOptions() *SSHNameOptions {
if o == nil {
return nil
}
if o.Host == nil {
if o == nil || o.Host == nil {
return nil
}
return o.Host.AllowedNames
@ -157,10 +148,7 @@ func (o *SSHPolicyOptions) GetAllowedHostNameOptions() *SSHNameOptions {
// GetDeniedHostNameOptions returns the SSH denied host name policy
// configuration.
func (o *SSHPolicyOptions) GetDeniedHostNameOptions() *SSHNameOptions {
if o == nil {
return nil
}
if o.Host == nil {
if o == nil || o.Host == nil {
return nil
}
return o.Host.DeniedNames

View file

@ -28,20 +28,20 @@ func NewX509PolicyEngine(policyOptions X509PolicyOptionsInterface) (X509Policy,
allowed := policyOptions.GetAllowedNameOptions()
if allowed != nil && allowed.HasNames() {
options = append(options,
policy.WithPermittedDNSDomains(allowed.DNSDomains),
policy.WithPermittedIPsOrCIDRs(allowed.IPRanges),
policy.WithPermittedEmailAddresses(allowed.EmailAddresses),
policy.WithPermittedURIDomains(allowed.URIDomains),
policy.WithPermittedDNSDomains(allowed.DNSDomains...),
policy.WithPermittedIPsOrCIDRs(allowed.IPRanges...),
policy.WithPermittedEmailAddresses(allowed.EmailAddresses...),
policy.WithPermittedURIDomains(allowed.URIDomains...),
)
}
denied := policyOptions.GetDeniedNameOptions()
if denied != nil && denied.HasNames() {
options = append(options,
policy.WithExcludedDNSDomains(denied.DNSDomains),
policy.WithExcludedIPsOrCIDRs(denied.IPRanges),
policy.WithExcludedEmailAddresses(denied.EmailAddresses),
policy.WithExcludedURIDomains(denied.URIDomains),
policy.WithExcludedDNSDomains(denied.DNSDomains...),
policy.WithExcludedIPsOrCIDRs(denied.IPRanges...),
policy.WithExcludedEmailAddresses(denied.EmailAddresses...),
policy.WithExcludedURIDomains(denied.URIDomains...),
)
}
@ -114,19 +114,19 @@ func newSSHPolicyEngine(policyOptions SSHPolicyOptionsInterface, typ sshPolicyEn
if allowed != nil && allowed.HasNames() {
options = append(options,
policy.WithPermittedDNSDomains(allowed.DNSDomains),
policy.WithPermittedIPsOrCIDRs(allowed.IPRanges),
policy.WithPermittedEmailAddresses(allowed.EmailAddresses),
policy.WithPermittedPrincipals(allowed.Principals),
policy.WithPermittedDNSDomains(allowed.DNSDomains...),
policy.WithPermittedIPsOrCIDRs(allowed.IPRanges...),
policy.WithPermittedEmailAddresses(allowed.EmailAddresses...),
policy.WithPermittedPrincipals(allowed.Principals...),
)
}
if denied != nil && denied.HasNames() {
options = append(options,
policy.WithExcludedDNSDomains(denied.DNSDomains),
policy.WithExcludedIPsOrCIDRs(denied.IPRanges),
policy.WithExcludedEmailAddresses(denied.EmailAddresses),
policy.WithExcludedPrincipals(denied.Principals),
policy.WithExcludedDNSDomains(denied.DNSDomains...),
policy.WithExcludedIPsOrCIDRs(denied.IPRanges...),
policy.WithExcludedEmailAddresses(denied.EmailAddresses...),
policy.WithExcludedPrincipals(denied.Principals...),
)
}

View file

@ -10,17 +10,19 @@ import (
"os"
"github.com/pkg/errors"
"gopkg.in/square/go-jose.v2/jwt"
"go.step.sm/cli-utils/step"
"go.step.sm/cli-utils/ui"
"go.step.sm/crypto/jose"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/authority/admin"
"github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/db"
"github.com/smallstep/certificates/errs"
"go.step.sm/cli-utils/step"
"go.step.sm/cli-utils/ui"
"go.step.sm/crypto/jose"
"go.step.sm/linkedca"
"gopkg.in/square/go-jose.v2/jwt"
)
// GetEncryptedKey returns the JWE key corresponding to the given kid argument.
@ -440,55 +442,55 @@ func optionsToCertificates(p *linkedca.Provisioner) *provisioner.Options {
ops.SSH.Template = string(p.SshTemplate.Template)
ops.SSH.TemplateData = p.SshTemplate.Data
}
if p.Policy != nil {
if p.Policy.X509 != nil {
if p.Policy.X509.Allow != nil {
if pol := p.GetPolicy(); pol != nil {
if x := pol.GetX509(); x != nil {
if allow := x.GetAllow(); allow != nil {
ops.X509.AllowedNames = &policy.X509NameOptions{
DNSDomains: p.Policy.X509.Allow.Dns,
IPRanges: p.Policy.X509.Allow.Ips,
EmailAddresses: p.Policy.X509.Allow.Emails,
URIDomains: p.Policy.X509.Allow.Uris,
DNSDomains: allow.Dns,
IPRanges: allow.Ips,
EmailAddresses: allow.Emails,
URIDomains: allow.Uris,
}
}
if p.Policy.X509.Deny != nil {
if deny := x.GetDeny(); deny != nil {
ops.X509.DeniedNames = &policy.X509NameOptions{
DNSDomains: p.Policy.X509.Deny.Dns,
IPRanges: p.Policy.X509.Deny.Ips,
EmailAddresses: p.Policy.X509.Deny.Emails,
URIDomains: p.Policy.X509.Deny.Uris,
DNSDomains: deny.Dns,
IPRanges: deny.Ips,
EmailAddresses: deny.Emails,
URIDomains: deny.Uris,
}
}
}
if p.Policy.Ssh != nil {
if p.Policy.Ssh.Host != nil {
if ssh := pol.GetSsh(); ssh != nil {
if host := ssh.GetHost(); host != nil {
ops.SSH.Host = &policy.SSHHostCertificateOptions{}
if p.Policy.Ssh.Host.Allow != nil {
if allow := host.GetAllow(); allow != nil {
ops.SSH.Host.AllowedNames = &policy.SSHNameOptions{
DNSDomains: p.Policy.Ssh.Host.Allow.Dns,
IPRanges: p.Policy.Ssh.Host.Allow.Ips,
Principals: p.Policy.Ssh.Host.Allow.Principals,
DNSDomains: allow.Dns,
IPRanges: allow.Ips,
Principals: allow.Principals,
}
}
if p.Policy.Ssh.Host.Deny != nil {
if deny := host.GetDeny(); deny != nil {
ops.SSH.Host.DeniedNames = &policy.SSHNameOptions{
DNSDomains: p.Policy.Ssh.Host.Deny.Dns,
IPRanges: p.Policy.Ssh.Host.Deny.Ips,
Principals: p.Policy.Ssh.Host.Deny.Principals,
DNSDomains: deny.Dns,
IPRanges: deny.Ips,
Principals: deny.Principals,
}
}
}
if p.Policy.Ssh.User != nil {
if user := ssh.GetUser(); user != nil {
ops.SSH.User = &policy.SSHUserCertificateOptions{}
if p.Policy.Ssh.User.Allow != nil {
if allow := user.GetAllow(); allow != nil {
ops.SSH.User.AllowedNames = &policy.SSHNameOptions{
EmailAddresses: p.Policy.Ssh.User.Allow.Emails,
Principals: p.Policy.Ssh.User.Allow.Principals,
EmailAddresses: allow.Emails,
Principals: allow.Principals,
}
}
if p.Policy.Ssh.User.Deny != nil {
if deny := user.GetDeny(); deny != nil {
ops.SSH.User.DeniedNames = &policy.SSHNameOptions{
EmailAddresses: p.Policy.Ssh.User.Deny.Emails,
Principals: p.Policy.Ssh.User.Deny.Principals,
EmailAddresses: deny.Emails,
Principals: deny.Principals,
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,7 @@ func WithAllowLiteralWildcardNames() NamePolicyOption {
}
}
func WithPermittedDNSDomains(domains []string) NamePolicyOption {
func WithPermittedDNSDomains(domains ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedDomains := make([]string, len(domains))
for i, domain := range domains {
@ -41,7 +41,7 @@ func WithPermittedDNSDomains(domains []string) NamePolicyOption {
}
}
func WithExcludedDNSDomains(domains []string) NamePolicyOption {
func WithExcludedDNSDomains(domains ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedDomains := make([]string, len(domains))
for i, domain := range domains {
@ -56,36 +56,14 @@ func WithExcludedDNSDomains(domains []string) NamePolicyOption {
}
}
func WithPermittedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedDomain, err := normalizeAndValidateDNSDomainConstraint(domain)
if err != nil {
return fmt.Errorf("cannot parse permitted domain constraint %q: %w", domain, err)
}
e.permittedDNSDomains = []string{normalizedDomain}
return nil
}
}
func WithExcludedDNSDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedDomain, err := normalizeAndValidateDNSDomainConstraint(domain)
if err != nil {
return fmt.Errorf("cannot parse excluded domain constraint %q: %w", domain, err)
}
e.excludedDNSDomains = []string{normalizedDomain}
return nil
}
}
func WithPermittedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
func WithPermittedIPRanges(ipRanges ...*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.permittedIPRanges = ipRanges
return nil
}
}
func WithPermittedCIDRs(cidrs []string) NamePolicyOption {
func WithPermittedCIDRs(cidrs ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := make([]*net.IPNet, len(cidrs))
for i, cidr := range cidrs {
@ -100,7 +78,7 @@ func WithPermittedCIDRs(cidrs []string) NamePolicyOption {
}
}
func WithExcludedCIDRs(cidrs []string) NamePolicyOption {
func WithExcludedCIDRs(cidrs ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := make([]*net.IPNet, len(cidrs))
for i, cidr := range cidrs {
@ -115,7 +93,7 @@ func WithExcludedCIDRs(cidrs []string) NamePolicyOption {
}
}
func WithPermittedIPsOrCIDRs(ipsOrCIDRs []string) NamePolicyOption {
func WithPermittedIPsOrCIDRs(ipsOrCIDRs ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := make([]*net.IPNet, len(ipsOrCIDRs))
for i, ipOrCIDR := range ipsOrCIDRs {
@ -133,7 +111,7 @@ func WithPermittedIPsOrCIDRs(ipsOrCIDRs []string) NamePolicyOption {
}
}
func WithExcludedIPsOrCIDRs(ipsOrCIDRs []string) NamePolicyOption {
func WithExcludedIPsOrCIDRs(ipsOrCIDRs ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
networks := make([]*net.IPNet, len(ipsOrCIDRs))
for i, ipOrCIDR := range ipsOrCIDRs {
@ -151,61 +129,14 @@ func WithExcludedIPsOrCIDRs(ipsOrCIDRs []string) NamePolicyOption {
}
}
func WithPermittedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return fmt.Errorf("cannot parse permitted CIDR constraint %q", cidr)
}
e.permittedIPRanges = []*net.IPNet{nw}
return nil
}
}
func WithPermittedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
nw := networkFor(ip)
e.permittedIPRanges = []*net.IPNet{nw}
return nil
}
}
func WithExcludedIPRanges(ipRanges []*net.IPNet) NamePolicyOption {
func WithExcludedIPRanges(ipRanges ...*net.IPNet) NamePolicyOption {
return func(e *NamePolicyEngine) error {
e.excludedIPRanges = ipRanges
return nil
}
}
func WithExcludedCIDR(cidr string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
_, nw, err := net.ParseCIDR(cidr)
if err != nil {
return fmt.Errorf("cannot parse excluded CIDR constraint %q", cidr)
}
e.excludedIPRanges = []*net.IPNet{nw}
return nil
}
}
func WithExcludedIP(ip net.IP) NamePolicyOption {
return func(e *NamePolicyEngine) error {
var mask net.IPMask
if !isIPv4(ip) {
mask = net.CIDRMask(128, 128)
} else {
mask = net.CIDRMask(32, 32)
}
nw := &net.IPNet{
IP: ip,
Mask: mask,
}
e.excludedIPRanges = []*net.IPNet{nw}
return nil
}
}
func WithPermittedEmailAddresses(emailAddresses []string) NamePolicyOption {
func WithPermittedEmailAddresses(emailAddresses ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedEmailAddresses := make([]string, len(emailAddresses))
for i, email := range emailAddresses {
@ -220,7 +151,7 @@ func WithPermittedEmailAddresses(emailAddresses []string) NamePolicyOption {
}
}
func WithExcludedEmailAddresses(emailAddresses []string) NamePolicyOption {
func WithExcludedEmailAddresses(emailAddresses ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedEmailAddresses := make([]string, len(emailAddresses))
for i, email := range emailAddresses {
@ -235,29 +166,7 @@ func WithExcludedEmailAddresses(emailAddresses []string) NamePolicyOption {
}
}
func WithPermittedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedEmailAddress, err := normalizeAndValidateEmailConstraint(emailAddress)
if err != nil {
return fmt.Errorf("cannot parse permitted email constraint %q: %w", emailAddress, err)
}
e.permittedEmailAddresses = []string{normalizedEmailAddress}
return nil
}
}
func WithExcludedEmailAddress(emailAddress string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedEmailAddress, err := normalizeAndValidateEmailConstraint(emailAddress)
if err != nil {
return fmt.Errorf("cannot parse excluded email constraint %q: %w", emailAddress, err)
}
e.excludedEmailAddresses = []string{normalizedEmailAddress}
return nil
}
}
func WithPermittedURIDomains(uriDomains []string) NamePolicyOption {
func WithPermittedURIDomains(uriDomains ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedURIDomains := make([]string, len(uriDomains))
for i, domain := range uriDomains {
@ -272,18 +181,7 @@ func WithPermittedURIDomains(uriDomains []string) NamePolicyOption {
}
}
func WithPermittedURIDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedURIDomain, err := normalizeAndValidateURIDomainConstraint(domain)
if err != nil {
return fmt.Errorf("cannot parse permitted URI domain constraint %q: %w", domain, err)
}
e.permittedURIDomains = []string{normalizedURIDomain}
return nil
}
}
func WithExcludedURIDomains(domains []string) NamePolicyOption {
func WithExcludedURIDomains(domains ...string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedURIDomains := make([]string, len(domains))
for i, domain := range domains {
@ -298,18 +196,7 @@ func WithExcludedURIDomains(domains []string) NamePolicyOption {
}
}
func WithExcludedURIDomain(domain string) NamePolicyOption {
return func(e *NamePolicyEngine) error {
normalizedURIDomain, err := normalizeAndValidateURIDomainConstraint(domain)
if err != nil {
return fmt.Errorf("cannot parse excluded URI domain constraint %q: %w", domain, err)
}
e.excludedURIDomains = []string{normalizedURIDomain}
return nil
}
}
func WithPermittedPrincipals(principals []string) NamePolicyOption {
func WithPermittedPrincipals(principals ...string) NamePolicyOption {
return func(g *NamePolicyEngine) error {
// TODO(hs): normalize and parse principal into the right type? Seems the safe thing to do.
g.permittedPrincipals = principals
@ -317,7 +204,7 @@ func WithPermittedPrincipals(principals []string) NamePolicyOption {
}
}
func WithExcludedPrincipals(principals []string) NamePolicyOption {
func WithExcludedPrincipals(principals ...string) NamePolicyOption {
return func(g *NamePolicyEngine) error {
// TODO(hs): normalize and parse principal into the right type? Seems the safe thing to do.
g.excludedPrincipals = principals
@ -357,7 +244,7 @@ func normalizeAndValidateDNSDomainConstraint(constraint string) (string, error)
if strings.LastIndex(normalizedConstraint, "*") > 0 {
return "", fmt.Errorf("domain constraint %q can only have wildcard as starting character", constraint)
}
if normalizedConstraint[0] == '*' && normalizedConstraint[1] != '.' {
if len(normalizedConstraint) >= 2 && normalizedConstraint[0] == '*' && normalizedConstraint[1] != '.' {
return "", fmt.Errorf("wildcard character in domain constraint %q can only be used to match (full) labels", constraint)
}
if strings.HasPrefix(normalizedConstraint, "*.") {

View file

@ -200,7 +200,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-dns-domains": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedDNSDomains([]string{"**.local"}),
WithPermittedDNSDomains("**.local"),
},
want: nil,
wantErr: true,
@ -209,25 +209,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-dns-domains": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedDNSDomains([]string{"**.local"}),
},
want: nil,
wantErr: true,
}
},
"fail/with-permitted-dns-domain": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedDNSDomain("**.local"),
},
want: nil,
wantErr: true,
}
},
"fail/with-excluded-dns-domain": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedDNSDomain("**.local"),
WithExcludedDNSDomains("**.local"),
},
want: nil,
wantErr: true,
@ -236,7 +218,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-cidrs": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedCIDRs([]string{"127.0.0.1//24"}),
WithPermittedCIDRs("127.0.0.1//24"),
},
want: nil,
wantErr: true,
@ -245,7 +227,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-cidrs": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedCIDRs([]string{"127.0.0.1//24"}),
WithExcludedCIDRs("127.0.0.1//24"),
},
want: nil,
wantErr: true,
@ -254,7 +236,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-ipsOrCIDRs-cidr": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedIPsOrCIDRs([]string{"127.0.0.1//24"}),
WithPermittedIPsOrCIDRs("127.0.0.1//24"),
},
want: nil,
wantErr: true,
@ -263,7 +245,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-ipsOrCIDRs-ip": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedIPsOrCIDRs([]string{"127.0.0:1"}),
WithPermittedIPsOrCIDRs("127.0.0:1"),
},
want: nil,
wantErr: true,
@ -272,7 +254,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-ipsOrCIDRs-cidr": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedIPsOrCIDRs([]string{"127.0.0.1//24"}),
WithExcludedIPsOrCIDRs("127.0.0.1//24"),
},
want: nil,
wantErr: true,
@ -281,25 +263,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-ipsOrCIDRs-ip": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedIPsOrCIDRs([]string{"127.0.0:1"}),
},
want: nil,
wantErr: true,
}
},
"fail/with-permitted-cidr": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedCIDR("127.0.0.1//24"),
},
want: nil,
wantErr: true,
}
},
"fail/with-excluded-cidr": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedCIDR("127.0.0.1//24"),
WithExcludedIPsOrCIDRs("127.0.0:1"),
},
want: nil,
wantErr: true,
@ -308,7 +272,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-emails": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedEmailAddresses([]string{"*.local"}),
WithPermittedEmailAddresses("*.local"),
},
want: nil,
wantErr: true,
@ -317,25 +281,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-emails": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedEmailAddresses([]string{"*.local"}),
},
want: nil,
wantErr: true,
}
},
"fail/with-permitted-email": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedEmailAddress("*.local"),
},
want: nil,
wantErr: true,
}
},
"fail/with-excluded-email": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedEmailAddress("*.local"),
WithExcludedEmailAddresses("*.local"),
},
want: nil,
wantErr: true,
@ -344,7 +290,7 @@ func TestNew(t *testing.T) {
"fail/with-permitted-uris": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedURIDomains([]string{"**.local"}),
WithPermittedURIDomains("**.local"),
},
want: nil,
wantErr: true,
@ -353,25 +299,7 @@ func TestNew(t *testing.T) {
"fail/with-excluded-uris": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedURIDomains([]string{"**.local"}),
},
want: nil,
wantErr: true,
}
},
"fail/with-permitted-uri": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithPermittedURIDomain("**.local"),
},
want: nil,
wantErr: true,
}
},
"fail/with-excluded-uri": func(t *testing.T) test {
return test{
options: []NamePolicyOption{
WithExcludedURIDomain("**.local"),
WithExcludedURIDomains("**.local"),
},
want: nil,
wantErr: true,
@ -410,7 +338,7 @@ func TestNew(t *testing.T) {
},
"ok/with-permitted-dns-wildcard-domains": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedDNSDomains([]string{"*.local", "*.example.com"}),
WithPermittedDNSDomains("*.local", "*.example.com"),
}
return test{
options: options,
@ -425,7 +353,7 @@ func TestNew(t *testing.T) {
},
"ok/with-excluded-dns-domains": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedDNSDomains([]string{"*.local", "*.example.com"}),
WithExcludedDNSDomains("*.local", "*.example.com"),
}
return test{
options: options,
@ -438,47 +366,13 @@ func TestNew(t *testing.T) {
wantErr: false,
}
},
"ok/with-permitted-dns-wildcard-domain": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedDNSDomain("*.example.com"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedDNSDomains: []string{".example.com"},
numberOfDNSDomainConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-dns-domain": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedDNSDomain("www.example.com"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedDNSDomains: []string{"www.example.com"},
numberOfDNSDomainConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-ip-ranges": func(t *testing.T) test {
_, nw1, err := net.ParseCIDR("127.0.0.1/24")
assert.FatalError(t, err)
_, nw2, err := net.ParseCIDR("192.168.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedIPRanges(
[]*net.IPNet{
nw1, nw2,
},
),
WithPermittedIPRanges(nw1, nw2),
}
return test{
options: options,
@ -499,11 +393,7 @@ func TestNew(t *testing.T) {
_, nw2, err := net.ParseCIDR("192.168.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedIPRanges(
[]*net.IPNet{
nw1, nw2,
},
),
WithExcludedIPRanges(nw1, nw2),
}
return test{
options: options,
@ -524,7 +414,7 @@ func TestNew(t *testing.T) {
_, nw2, err := net.ParseCIDR("192.168.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedCIDRs([]string{"127.0.0.1/24", "192.168.0.1/24"}),
WithPermittedCIDRs("127.0.0.1/24", "192.168.0.1/24"),
}
return test{
options: options,
@ -545,7 +435,7 @@ func TestNew(t *testing.T) {
_, nw2, err := net.ParseCIDR("192.168.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedCIDRs([]string{"127.0.0.1/24", "192.168.0.1/24"}),
WithExcludedCIDRs("127.0.0.1/24", "192.168.0.1/24"),
}
return test{
options: options,
@ -565,18 +455,20 @@ func TestNew(t *testing.T) {
assert.FatalError(t, err)
_, nw2, err := net.ParseCIDR("192.168.0.31/32")
assert.FatalError(t, err)
_, nw3, err := net.ParseCIDR("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedIPsOrCIDRs([]string{"127.0.0.1/24", "192.168.0.31"}),
WithPermittedIPsOrCIDRs("127.0.0.1/24", "192.168.0.31", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedIPRanges: []*net.IPNet{
nw1, nw2,
nw1, nw2, nw3,
},
numberOfIPRangeConstraints: 2,
totalNumberOfPermittedConstraints: 2,
totalNumberOfConstraints: 2,
numberOfIPRangeConstraints: 3,
totalNumberOfPermittedConstraints: 3,
totalNumberOfConstraints: 3,
},
wantErr: false,
}
@ -586,139 +478,27 @@ func TestNew(t *testing.T) {
assert.FatalError(t, err)
_, nw2, err := net.ParseCIDR("192.168.0.31/32")
assert.FatalError(t, err)
_, nw3, err := net.ParseCIDR("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedIPsOrCIDRs([]string{"127.0.0.1/24", "192.168.0.31"}),
WithExcludedIPsOrCIDRs("127.0.0.1/24", "192.168.0.31", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedIPRanges: []*net.IPNet{
nw1, nw2,
nw1, nw2, nw3,
},
numberOfIPRangeConstraints: 2,
totalNumberOfExcludedConstraints: 2,
totalNumberOfConstraints: 2,
},
wantErr: false,
}
},
"ok/with-permitted-cidr": func(t *testing.T) test {
_, nw1, err := net.ParseCIDR("127.0.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedCIDR("127.0.0.1/24"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-excluded-cidr": func(t *testing.T) test {
_, nw1, err := net.ParseCIDR("127.0.0.1/24")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedCIDR("127.0.0.1/24"),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfExcludedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-ipv4": func(t *testing.T) test {
ip1, nw1, err := net.ParseCIDR("127.0.0.15/32")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedIP(ip1),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-excluded-ipv4": func(t *testing.T) test {
ip1, nw1, err := net.ParseCIDR("127.0.0.15/32")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedIP(ip1),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfExcludedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-ipv6": func(t *testing.T) test {
ip1, nw1, err := net.ParseCIDR("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithPermittedIP(ip1),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-excluded-ipv6": func(t *testing.T) test {
ip1, nw1, err := net.ParseCIDR("2001:0db8:85a3:0000:0000:8a2e:0370:7334/128")
assert.FatalError(t, err)
options := []NamePolicyOption{
WithExcludedIP(ip1),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedIPRanges: []*net.IPNet{
nw1,
},
numberOfIPRangeConstraints: 1,
totalNumberOfExcludedConstraints: 1,
totalNumberOfConstraints: 1,
numberOfIPRangeConstraints: 3,
totalNumberOfExcludedConstraints: 3,
totalNumberOfConstraints: 3,
},
wantErr: false,
}
},
"ok/with-permitted-emails": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedEmailAddresses([]string{"mail@local", "@example.com"}),
WithPermittedEmailAddresses("mail@local", "@example.com"),
}
return test{
options: options,
@ -733,7 +513,7 @@ func TestNew(t *testing.T) {
},
"ok/with-excluded-emails": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedEmailAddresses([]string{"mail@local", "@example.com"}),
WithExcludedEmailAddresses("mail@local", "@example.com"),
}
return test{
options: options,
@ -746,39 +526,9 @@ func TestNew(t *testing.T) {
wantErr: false,
}
},
"ok/with-permitted-email": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedEmailAddress("mail@local"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedEmailAddresses: []string{"mail@local"},
numberOfEmailAddressConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-excluded-email": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedEmailAddress("mail@local"),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedEmailAddresses: []string{"mail@local"},
numberOfEmailAddressConstraints: 1,
totalNumberOfExcludedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-uris": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedURIDomains([]string{"host.local", "*.example.com"}),
WithPermittedURIDomains("host.local", "*.example.com"),
}
return test{
options: options,
@ -793,7 +543,7 @@ func TestNew(t *testing.T) {
},
"ok/with-excluded-uris": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedURIDomains([]string{"host.local", "*.example.com"}),
WithExcludedURIDomains("host.local", "*.example.com"),
}
return test{
options: options,
@ -806,54 +556,9 @@ func TestNew(t *testing.T) {
wantErr: false,
}
},
"ok/with-permitted-uri": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedURIDomain("host.local"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedURIDomains: []string{"host.local"},
numberOfURIDomainConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-uri-idna": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedURIDomain("*.bücher.example.com"),
}
return test{
options: options,
want: &NamePolicyEngine{
permittedURIDomains: []string{".xn--bcher-kva.example.com"},
numberOfURIDomainConstraints: 1,
totalNumberOfPermittedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-excluded-uri": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedURIDomain("host.local"),
}
return test{
options: options,
want: &NamePolicyEngine{
excludedURIDomains: []string{"host.local"},
numberOfURIDomainConstraints: 1,
totalNumberOfExcludedConstraints: 1,
totalNumberOfConstraints: 1,
},
wantErr: false,
}
},
"ok/with-permitted-principals": func(t *testing.T) test {
options := []NamePolicyOption{
WithPermittedPrincipals([]string{"root", "ops"}),
WithPermittedPrincipals("root", "ops"),
}
return test{
options: options,
@ -868,7 +573,7 @@ func TestNew(t *testing.T) {
},
"ok/with-excluded-principals": func(t *testing.T) test {
options := []NamePolicyOption{
WithExcludedPrincipals([]string{"root", "ops"}),
WithExcludedPrincipals("root", "ops"),
}
return test{
options: options,