From 7fa97bedec94f2e186100775b355aa576355dcc2 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Wed, 19 Jul 2023 10:39:42 -0700 Subject: [PATCH] Remove OIDC user regexp check This commit removes the regular expression check on OIDC usernames. Although it is not recommended to use any character in a username, it is possible to create and use them. The tool useradd has the flag --badname and adduser has --allow-badname and --allow-all-names to create new users with any character. Moreover, it is possible to create any username with the rest of provisioners. Fixes #1436 --- authority/provisioner/controller.go | 15 +++++---------- authority/provisioner/controller_test.go | 6 ++++++ authority/provisioner/provisioner_test.go | 14 +++++++------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/authority/provisioner/controller.go b/authority/provisioner/controller.go index 25030fbc..d364d5aa 100644 --- a/authority/provisioner/controller.go +++ b/authority/provisioner/controller.go @@ -4,7 +4,6 @@ import ( "context" "crypto/x509" "net/http" - "regexp" "strings" "time" @@ -115,20 +114,18 @@ func DefaultIdentityFunc(_ context.Context, p Interface, email string) (*Identit switch k := p.(type) { case *OIDC: // OIDC principals would be: - // ~~1. Preferred usernames.~~ Note: Under discussion, currently disabled - // 2. Sanitized local. - // 3. Raw local (if different). - // 4. Email address. + // ~~1. Preferred usernames.~~ Note: Under discussion, currently disabled + // 2. Sanitized local. + // 3. Raw local (if different). + // 4. Email address. name := SanitizeSSHUserPrincipal(email) - if !sshUserRegex.MatchString(name) { - return nil, errors.Errorf("invalid principal '%s' from email '%s'", name, email) - } usernames := []string{name} if i := strings.LastIndex(email, "@"); i >= 0 { usernames = append(usernames, email[:i]) } usernames = append(usernames, email) return &Identity{ + // Remove duplicated and empty usernames. Usernames: SanitizeStringSlices(usernames), }, nil default: @@ -178,8 +175,6 @@ func DefaultAuthorizeSSHRenew(_ context.Context, p *Controller, cert *ssh.Certif return nil } -var sshUserRegex = regexp.MustCompile("^[a-z][-a-z0-9_]*$") - // SanitizeStringSlices removes duplicated an empty strings. func SanitizeStringSlices(original []string) []string { output := []string{} diff --git a/authority/provisioner/controller_test.go b/authority/provisioner/controller_test.go index c628f074..155163d6 100644 --- a/authority/provisioner/controller_test.go +++ b/authority/provisioner/controller_test.go @@ -167,6 +167,12 @@ func TestController_GetIdentity(t *testing.T) { }}, args{ctx, "jane@doe.org"}, &Identity{ Usernames: []string{"jane"}, }, false}, + {"ok badname", fields{&OIDC{}, nil}, args{ctx, "1000@doe.org"}, &Identity{ + Usernames: []string{"1000", "1000@doe.org"}, + }, false}, + {"ok sanitized badname", fields{&OIDC{}, nil}, args{ctx, "1000+10@doe.org"}, &Identity{ + Usernames: []string{"1000_10", "1000+10", "1000+10@doe.org"}, + }, false}, {"fail provisioner", fields{&JWK{}, nil}, args{ctx, "jane@doe.org"}, nil, true}, {"fail custom", fields{&OIDC{}, func(ctx context.Context, p Interface, email string) (*Identity, error) { return nil, fmt.Errorf("an error") diff --git a/authority/provisioner/provisioner_test.go b/authority/provisioner/provisioner_test.go index 65fb8e1d..865e5291 100644 --- a/authority/provisioner/provisioner_test.go +++ b/authority/provisioner/provisioner_test.go @@ -76,13 +76,6 @@ func TestDefaultIdentityFunc(t *testing.T) { err: errors.New("provisioner type '*provisioner.X5C' not supported by identity function"), } }, - "fail/bad-ssh-regex": func(t *testing.T) test { - return test{ - p: &OIDC{}, - email: "$%^#_>@smallstep.com", - err: errors.New("invalid principal '______' from email '$%^#_>@smallstep.com'"), - } - }, "ok": func(t *testing.T) test { return test{ p: &OIDC{}, @@ -142,6 +135,13 @@ func TestDefaultIdentityFunc(t *testing.T) { identity: &Identity{Usernames: []string{"john", "john@smallstep.com"}}, } }, + "ok/badname": func(t *testing.T) test { + return test{ + p: &OIDC{}, + email: "$%^#_>@smallstep.com", + identity: &Identity{Usernames: []string{"______", "$%^#_>", "$%^#_>@smallstep.com"}}, + } + }, } for name, get := range tests { t.Run(name, func(t *testing.T) {