Add warning on missing entity information (#17428)

When requesting a SSH certificate with default_extension templating
enabled, if the request lacks entity information and a particular
extension requires templating, just these extensions will be elided.
Other extensions (if present) will still be on the final certificate.

Add a warning in the event of missing entity information and at least
one extension that was skipped as a result.

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>

Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
Alexander Scheel 2022-10-06 14:00:56 -04:00 committed by GitHub
parent 06d843d3b0
commit 11e4f2600e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 7 deletions

View File

@ -93,7 +93,7 @@ func (b *backend) pathSignIssueCertificateHelper(ctx context.Context, req *logic
return logical.ErrorResponse(err.Error()), nil return logical.ErrorResponse(err.Error()), nil
} }
extensions, err := b.calculateExtensions(data, req, role) extensions, addExtTemplatingWarning, err := b.calculateExtensions(data, req, role)
if err != nil { if err != nil {
return logical.ErrorResponse(err.Error()), nil return logical.ErrorResponse(err.Error()), nil
} }
@ -140,6 +140,10 @@ func (b *backend) pathSignIssueCertificateHelper(ctx context.Context, req *logic
}, },
} }
if addExtTemplatingWarning {
response.AddWarning("default_extension templating enabled with at least one extension requiring identity templating. However, this request lacked identity entity information, causing one or more extensions to be skipped from the generated certificate.")
}
return response, nil return response, nil
} }
@ -300,7 +304,7 @@ func (b *backend) calculateCriticalOptions(data *framework.FieldData, role *sshR
return criticalOptions, nil return criticalOptions, nil
} }
func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Request, role *sshRole) (map[string]string, error) { func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Request, role *sshRole) (map[string]string, bool, error) {
unparsedExtensions := data.Get("extensions").(map[string]interface{}) unparsedExtensions := data.Get("extensions").(map[string]interface{})
extensions := make(map[string]string) extensions := make(map[string]string)
@ -308,7 +312,7 @@ func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Re
extensions := convertMapToStringValue(unparsedExtensions) extensions := convertMapToStringValue(unparsedExtensions)
if role.AllowedExtensions == "*" { if role.AllowedExtensions == "*" {
// Allowed extensions was configured to allow all // Allowed extensions was configured to allow all
return extensions, nil return extensions, false, nil
} }
notAllowed := []string{} notAllowed := []string{}
@ -320,11 +324,13 @@ func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Re
} }
if len(notAllowed) != 0 { if len(notAllowed) != 0 {
return nil, fmt.Errorf("extensions %v are not on allowed list", notAllowed) return nil, false, fmt.Errorf("extensions %v are not on allowed list", notAllowed)
} }
return extensions, nil return extensions, false, nil
} }
haveMissingEntityInfoWithTemplatedExt := false
if role.DefaultExtensionsTemplate { if role.DefaultExtensionsTemplate {
for extensionKey, extensionValue := range role.DefaultExtensions { for extensionKey, extensionValue := range role.DefaultExtensions {
// Look for templating markers {{ .* }} // Look for templating markers {{ .* }}
@ -337,8 +343,10 @@ func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Re
// Template returned an extension value that we can use // Template returned an extension value that we can use
extensions[extensionKey] = templateExtensionValue extensions[extensionKey] = templateExtensionValue
} else { } else {
return nil, fmt.Errorf("template '%s' could not be rendered -> %s", extensionValue, err) return nil, false, fmt.Errorf("template '%s' could not be rendered -> %s", extensionValue, err)
} }
} else {
haveMissingEntityInfoWithTemplatedExt = true
} }
} else { } else {
// Static extension value or err template // Static extension value or err template
@ -349,7 +357,7 @@ func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Re
extensions = role.DefaultExtensions extensions = role.DefaultExtensions
} }
return extensions, nil return extensions, haveMissingEntityInfoWithTemplatedExt, nil
} }
func (b *backend) calculateTTL(data *framework.FieldData, role *sshRole) (time.Duration, error) { func (b *backend) calculateTTL(data *framework.FieldData, role *sshRole) (time.Duration, error) {