From 5d87201abcdd67c651524161f766da1313d3053b Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Wed, 14 Dec 2022 17:51:50 -0800 Subject: [PATCH] Ignore principals validations with OIDC This commit will ignore principals validation when an OIDC provisioner is used. When the principals in the server does not match the principals given the validation was failing, even if the proper principals were set by templates or webhooks. With this change OIDC will not validate the principals and just set the default ones (name, name@example.org) plus the ones in the templates. This commit also includes a change in the templates to allow to pass a provisioner to the $(step path)/ssh/config template Related to #807 --- authority/provisioner/oidc.go | 12 +++--------- authority/provisioner/oidc_test.go | 4 +++- templates/values.go | 4 ++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/authority/provisioner/oidc.go b/authority/provisioner/oidc.go index 3840a4a8..ad1e5174 100644 --- a/authority/provisioner/oidc.go +++ b/authority/provisioner/oidc.go @@ -385,16 +385,13 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption } var data sshutil.TemplateData - var principals []string - if claims.Email == "" { - // If email is empty, use the Subject claim instead to create minimal data for the template to use + // If email is empty, use the Subject claim instead to create minimal + // data for the template to use. data = sshutil.CreateTemplateData(sshutil.UserCert, claims.Subject, nil) if v, err := unsafeParseSigned(token); err == nil { data.SetToken(v) } - - principals = nil } else { // Get the identity using either the default identityFunc or one injected // externally. Note that the PreferredUsername might be empty. @@ -417,8 +414,6 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption for k, v := range iden.Permissions.CriticalOptions { data.AddCriticalOption(k, v) } - - principals = iden.Usernames } // Use the default template unless no-templates are configured and email is @@ -446,8 +441,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption }) } else { signOptions = append(signOptions, sshCertOptionsValidator(SignSSHOptions{ - CertType: SSHUserCert, - Principals: principals, + CertType: SSHUserCert, })) } diff --git a/authority/provisioner/oidc_test.go b/authority/provisioner/oidc_test.go index 083799f6..ebd8e5a4 100644 --- a/authority/provisioner/oidc_test.go +++ b/authority/provisioner/oidc_test.go @@ -582,6 +582,9 @@ func TestOIDC_AuthorizeSSHSign(t *testing.T) { {"ok-principals", p1, args{t1, SignSSHOptions{Principals: []string{"name"}}, pub}, &SignSSHOptions{CertType: "user", Principals: []string{"name", "name@smallstep.com"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false}, + {"ok-principals-ignore-passed", p1, args{t1, SignSSHOptions{Principals: []string{"root"}}, pub}, + &SignSSHOptions{CertType: "user", Principals: []string{"name", "name@smallstep.com"}, + ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false}, {"ok-principals-getIdentity", p4, args{okGetIdentityToken, SignSSHOptions{Principals: []string{"mariano"}}, pub}, &SignSSHOptions{CertType: "user", Principals: []string{"max", "mariano"}, ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false}, @@ -600,7 +603,6 @@ func TestOIDC_AuthorizeSSHSign(t *testing.T) { ValidAfter: NewTimeDuration(tm), ValidBefore: NewTimeDuration(tm.Add(userDuration))}, http.StatusOK, false, false}, {"fail-rsa1024", p1, args{t1, SignSSHOptions{}, rsa1024.Public()}, expectedUserOptions, http.StatusOK, false, true}, {"fail-user-host", p1, args{t1, SignSSHOptions{CertType: "host"}, pub}, nil, http.StatusOK, false, true}, - {"fail-user-principals", p1, args{t1, SignSSHOptions{Principals: []string{"root"}}, pub}, nil, http.StatusOK, false, true}, {"fail-getIdentity", p5, args{failGetIdentityToken, SignSSHOptions{}, pub}, nil, http.StatusInternalServerError, true, false}, {"fail-sshCA-disabled", p6, args{"foo", SignSSHOptions{}, pub}, nil, http.StatusUnauthorized, true, false}, // Missing parametrs diff --git a/templates/values.go b/templates/values.go index a760001e..aa158a92 100644 --- a/templates/values.go +++ b/templates/values.go @@ -108,10 +108,10 @@ var DefaultSSHTemplateData = map[string]string{ {{- end }} {{- if or .User.GOOS "none" | eq "windows" }} UserKnownHostsFile "{{.User.StepPath}}\ssh\known_hosts" - ProxyCommand C:\Windows\System32\cmd.exe /c step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }} %r %h %p + ProxyCommand C:\Windows\System32\cmd.exe /c step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p {{- else }} UserKnownHostsFile "{{.User.StepPath}}/ssh/known_hosts" - ProxyCommand step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }} %r %h %p + ProxyCommand step ssh proxycommand{{- if .User.Context }} --context {{ .User.Context }}{{- end }}{{- if .User.Provisioner }} --provisioner {{ .User.Provisioner }}{{- end }} %r %h %p {{- end }} `,