Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v9] Backport - Fix missing identity in certs logic #10822

Merged
merged 5 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/auth/permissions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ func TestAuthorizeWithLocksForLocalUser(t *testing.T) {
})
require.NoError(t, err)

user, _, err := CreateUserAndRole(srv.AuthServer, "test-user", []string{})
user, role, err := CreateUserAndRole(srv.AuthServer, "test-user", []string{})
require.NoError(t, err)
localUser := LocalUser{
Username: user.GetName(),
Identity: tlsca.Identity{
Username: user.GetName(),
Groups: []string{"test-role-1"},
Groups: []string{role.GetName()},
MFAVerified: "mfa-device-id",
ActiveRequests: []string{"test-request"},
},
Expand Down
17 changes: 5 additions & 12 deletions lib/services/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,9 +778,11 @@ func ExtractFromCertificate(cert *ssh.Certificate) ([]string, wrappers.Traits, e
// which Teleport passes along as a *tlsca.Identity. If roles and traits do not
// exist in the certificates, they are extracted from the backend.
func ExtractFromIdentity(access UserGetter, identity tlsca.Identity) ([]string, wrappers.Traits, error) {
// For legacy certificates, fetch roles and traits from the services.User
// object in the backend.
if missingIdentity(identity) {
// Legacy certs are not encoded with roles or traits,
// so we fallback to the traits and roles in the backend.
// empty traits are a valid use case in standard certs,
// so we only check for whether roles are empty.
if len(identity.Groups) == 0 {
u, err := access.GetUser(identity.Username, false)
if err != nil {
return nil, nil, trace.Wrap(err)
Expand Down Expand Up @@ -823,15 +825,6 @@ func FetchRoles(roleNames []string, access RoleGetter, traits map[string][]strin
return NewRoleSet(roles...), nil
}

// missingIdentity returns true if the identity is missing or the identity
// has no roles or traits.
func missingIdentity(identity tlsca.Identity) bool {
if len(identity.Groups) == 0 || len(identity.Traits) == 0 {
return true
}
return false
}

// ExtractRolesFromCert extracts roles from certificate metadata extensions.
func ExtractRolesFromCert(cert *ssh.Certificate) ([]string, error) {
data, ok := cert.Extensions[teleport.CertExtensionTeleportRoles]
Expand Down