Make SanitizeSSHPrincipal a public function.

This commit is contained in:
Mariano Cano 2019-07-29 16:21:22 -07:00
parent f01286bb48
commit 48c98dea2a
3 changed files with 30 additions and 21 deletions

View file

@ -309,7 +309,7 @@ func (o *OIDC) authorizeSSHSign(claims *openIDPayload) ([]SignOption, error) {
if o.IsAdmin(claims.Email) { if o.IsAdmin(claims.Email) {
signOptions = append(signOptions, &sshCertificateOptionsValidator{}) signOptions = append(signOptions, &sshCertificateOptionsValidator{})
} else { } else {
name := principalFromEmail(claims.Email) name := SanitizeSSHPrincipal(claims.Email)
if !sshUserRegex.MatchString(name) { if !sshUserRegex.MatchString(name) {
return nil, errors.Errorf("invalid principal '%s' from email address '%s'", name, claims.Email) return nil, errors.Errorf("invalid principal '%s' from email address '%s'", name, claims.Email)
} }
@ -338,21 +338,3 @@ func getAndDecode(uri string, v interface{}) error {
} }
return nil return nil
} }
func principalFromEmail(email string) string {
if i := strings.LastIndex(email, "@"); i >= 0 {
email = email[:i]
}
return strings.Map(func(r rune) rune {
switch {
case r >= 'a' && r <= 'z':
return r
case r >= '0' && r <= '9':
return r
case r == '.': // drop dots
return -1
default:
return '_'
}
}, strings.ToLower(email))
}

View file

@ -11,8 +11,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
var sshUserRegex = regexp.MustCompile("^[a-z][-a-z0-9_]*$")
// Interface is the interface that all provisioner types must implement. // Interface is the interface that all provisioner types must implement.
type Interface interface { type Interface interface {
GetID() string GetID() string
@ -164,3 +162,29 @@ func (l *List) UnmarshalJSON(data []byte) error {
return nil return nil
} }
var sshUserRegex = regexp.MustCompile("^[a-z][-a-z0-9_]*$")
// SanitizeSSHPrincipal grabs an email or a string with the format local@domain
// and returns a sanitized version of the local, valid to be used as a user
// name. If the email starts with a letter between a and z, the resulting string
// will match the regular expression `^[a-z][-a-z0-9_]*$`.
func SanitizeSSHPrincipal(email string) string {
if i := strings.LastIndex(email, "@"); i >= 0 {
email = email[:i]
}
return strings.Map(func(r rune) rune {
switch {
case r >= 'a' && r <= 'z':
return r
case r >= '0' && r <= '9':
return r
case r == '-':
return '-'
case r == '.': // drop dots
return -1
default:
return '_'
}
}, strings.ToLower(email))
}

View file

@ -211,6 +211,9 @@ type sshCertificateOptionsValidator struct {
// Valid implements SSHCertificateOptionsValidator and returns nil if both // Valid implements SSHCertificateOptionsValidator and returns nil if both
// SSHOptions match. // SSHOptions match.
func (v *sshCertificateOptionsValidator) Valid(got SSHOptions) error { func (v *sshCertificateOptionsValidator) Valid(got SSHOptions) error {
if v.Want == nil {
return nil
}
return v.Want.match(got) return v.Want.match(got)
} }