|
|
|
@ -376,31 +376,46 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
|
|
|
|
}
|
|
|
|
|
// Enforce an email claim
|
|
|
|
|
if claims.Email == "" {
|
|
|
|
|
return nil, errs.Unauthorized("oidc.AuthorizeSSHSign: failed to validate oidc token payload: email not found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the identity using either the default identityFunc or one injected
|
|
|
|
|
// externally. Note that the PreferredUsername might be empty.
|
|
|
|
|
// TBD: Would preferred_username present a safety issue here?
|
|
|
|
|
iden, err := o.ctl.GetIdentity(ctx, claims.Email)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
|
|
|
|
if claims.Subject == "" {
|
|
|
|
|
return nil, errs.Unauthorized("oidc.AuthorizeSSHSign: failed to validate oidc token payload: subject not found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certificate templates.
|
|
|
|
|
data := sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames)
|
|
|
|
|
if v, err := unsafeParseSigned(token); err == nil {
|
|
|
|
|
data.SetToken(v)
|
|
|
|
|
}
|
|
|
|
|
// Add custom extensions added in the identity function.
|
|
|
|
|
for k, v := range iden.Permissions.Extensions {
|
|
|
|
|
data.AddExtension(k, v)
|
|
|
|
|
}
|
|
|
|
|
// Add custom critical options added in the identity function.
|
|
|
|
|
for k, v := range iden.Permissions.CriticalOptions {
|
|
|
|
|
data.AddCriticalOption(k, v)
|
|
|
|
|
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
|
|
|
|
|
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.
|
|
|
|
|
// TBD: Would preferred_username present a safety issue here?
|
|
|
|
|
iden, err := o.ctl.GetIdentity(ctx, claims.Email)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Certificate templates.
|
|
|
|
|
data = sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames)
|
|
|
|
|
if v, err := unsafeParseSigned(token); err == nil {
|
|
|
|
|
data.SetToken(v)
|
|
|
|
|
}
|
|
|
|
|
// Add custom extensions added in the identity function.
|
|
|
|
|
for k, v := range iden.Permissions.Extensions {
|
|
|
|
|
data.AddExtension(k, v)
|
|
|
|
|
}
|
|
|
|
|
// Add custom critical options added in the identity function.
|
|
|
|
|
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
|
|
|
|
@ -429,7 +444,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
|
|
|
|
|
} else {
|
|
|
|
|
signOptions = append(signOptions, sshCertOptionsValidator(SignSSHOptions{
|
|
|
|
|
CertType: SSHUserCert,
|
|
|
|
|
Principals: iden.Usernames,
|
|
|
|
|
Principals: principals,
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|