Enforce an OIDC users to send all template variables.

This commit is contained in:
Mariano Cano 2020-08-03 15:28:48 -07:00
parent 9822305bb6
commit b66bdfabcd
2 changed files with 37 additions and 7 deletions

View file

@ -392,7 +392,15 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
data.AddCriticalOption(k, v)
}
templateOptions, err := TemplateSSHOptions(o.Options, data)
// Use the default template unless no-templates are configured and email is
// an admin, in that case we will use the parameters in the request.
isAdmin := o.IsAdmin(claims.Email)
defaultTemplate := sshutil.DefaultCertificate
if isAdmin && !o.Options.GetSSHOptions().HasTemplate() {
defaultTemplate = sshutil.DefaultAdminCertificate
}
templateOptions, err := CustomSSHTemplateOptions(o.Options, data, defaultTemplate)
if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "jwk.AuthorizeSign")
}
@ -401,7 +409,13 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
// Admin users can use any principal, and can sign user and host certificates.
// Non-admin users can only use principals returned by the identityFunc, and
// can only sign user certificates.
if !o.IsAdmin(claims.Email) {
if isAdmin {
signOptions = append(signOptions, &sshCertOptionsRequireValidator{
CertType: true,
KeyID: true,
Principals: true,
})
} else {
signOptions = append(signOptions, sshCertOptionsValidator(SignSSHOptions{
CertType: SSHUserCert,
Principals: iden.Usernames,

View file

@ -1,5 +1,6 @@
package sshutil
// Variables used to hold template data.
const (
TypeKey = "Type"
KeyIDKey = "KeyID"
@ -101,7 +102,7 @@ func (t TemplateData) SetType(typ CertType) {
t.Set(TypeKey, typ.String())
}
// SetType sets the certificate key id in the template data.
// SetKeyID sets the certificate key id in the template data.
func (t TemplateData) SetKeyID(id string) {
t.Set(KeyIDKey, id)
}
@ -148,13 +149,25 @@ const DefaultCertificate = `{
"criticalOptions": {{ toJson .CriticalOptions }}
}`
// DefaultAdminCertificate is the template used by an admin user in a OIDC
// provisioner.
const DefaultAdminCertificate = `{
"type": "{{ .Insecure.CR.Type }}",
"keyId": "{{ .Insecure.CR.KeyID }}",
"principals": {{ toJson .Insecure.CR.Principals }}
{{- if eq .Insecure.CR.Type "user" }}
, "extensions": {{ toJson .Extensions }},
"criticalOptions": {{ toJson .CriticalOptions }}
{{- end }}
}`
// DefaultIIDCertificate is the default template for IID provisioners. By
// default certificate type will be set always to host, key id to the instance
// id. Principals will be only enforced by the provisioner if disableCustomSANs
// is set to true.
const DefaultIIDCertificate = `{
"type": "{{ .Type }}",
{{- if .Insecure.CR.KeyID }}
"keyId": "{{ .Insecure.CR.KeyID }}",
{{- else }}
"keyId": "{{ .KeyID }}",
{{- end}}
{{- if .Insecure.CR.Principals }}
"principals": {{ toJson .Insecure.CR.Principals }},
{{- else }}
@ -163,6 +176,9 @@ const DefaultIIDCertificate = `{
"extensions": {{ toJson .Extensions }}
}`
// CertificateRequestTemplate is the template used for provisioners that accepts
// any certificate request. The provisioner must validate that type, keyId and
// principals are passed in the request.
const CertificateRequestTemplate = `{
"type": "{{ .Insecure.CR.Type }}",
"keyId": "{{ .Insecure.CR.KeyID }}",