Skip to content
New issue

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

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

Already on GitHub? # to your account

Add format version flag & rework payload creation #1098

Merged
merged 1 commit into from
Nov 25, 2024
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ accessible to this tool. Use FQDNs in order to retrieve certificates using
- Optional support for ignoring expiring intermediate certificates
- Optional support for ignoring expired intermediate certificates
- Optional support for ignoring expiring root certificates
- Optional support for ignoring expired of root certificates
- Optional support for ignoring expired root certificates
- Optional support for omitting Subject Alternate Names (SANs) entries from
plugin output
- Optional support for embedding an encoded certificate metadata payload
Expand All @@ -326,6 +326,8 @@ accessible to this tool. Use FQDNs in order to retrieve certificates using
the original certificate chain included* in PEM encoded format
- this is not enabled by default due to the significant increase in plugin
output size
- Optional support for overriding the default certificate metadata format
version used when generating payloads

### `lscert`

Expand Down Expand Up @@ -696,6 +698,7 @@ validation checks and any behavior changes at that time noted.
| `v`, `verbose` | No | `false` | No | `v`, `verbose` | Toggles emission of detailed certificate metadata. This level of output is disabled by default. |
| `payload` | No | `false` | No | `true`, `false` | Toggles emission of encoded certificate chain payload. This output is disabled by default. |
| `payload-with-full-chain` | No | `false` | No | `true`, `false` | Toggles emission of encoded certificate chain payload with the full certificate chain included. This option is disabled by default due to the significant increase in payload size. |
| `payload-format` | No | `false` | No | *positive whole number for valid payload format version* | Specifies the format version to use when generating the (optional) certificate metadata payload. |
| `omit-sans-list`, `omit-sans-entries` | No | `false` | No | `true`, `false` | Toggles listing of SANs entries list items in certificate metadata output. This list is included by default. |
| `version` | No | `false` | No | `version` | Whether to display application version and then immediately exit application. |
| `c`, `age-critical` | No | 15 | No | *positive whole number of days* | The threshold for the certificate check's `CRITICAL` state. If the certificate expires before this number of days then the service check will be considered in a `CRITICAL` state. |
Expand Down
78 changes: 50 additions & 28 deletions cmd/check_cert/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,10 @@ func main() {
// configuration overrides (to either a user-specified value or Info as an
// app default).
if zerolog.GlobalLevel() == zerolog.DebugLevel || zerolog.GlobalLevel() == zerolog.TraceLevel {
plugin.DebugLoggingEnablePluginOutputSize()
// plugin.DebugLoggingEnablePluginOutputSize()
plugin.DebugLoggingEnableAll()
}

// Annotate all errors (if any) with remediation advice just before ending
// plugin execution.
defer annotateErrors(plugin)

if cfg.EmitBranding {
// If enabled, show application details at end of notification
plugin.BrandingCallback = config.Branding("Notification generated by ")
Expand All @@ -83,9 +80,53 @@ func main() {
Str("expected_sans_entries", cfg.SANsEntries.String()).
Logger()

var certChain []*x509.Certificate

var certChainSource string
// We declare these earlier so that they can be referenced by closures
// (e.g., adding certificate metadata payload to plugin).
var (
certChain []*x509.Certificate
certChainSource string
ipAddr string
)

// We run this function next to last so that we have access to the latest
// state of the plugin, including any errors registered with the plugin
// (e.g., after any annotations have been applied).
defer func(cc *[]*x509.Certificate, p *nagios.Plugin, c *config.Config, ip *string) {
if cfg.EmitPayload || cfg.EmitPayloadWithFullChain {
// We intentionally use different var names to prevent capturing
// outside variable values at time of deferring this closure.
payloadErr := addCertChainPayload(*cc, p, c, *ip)
if payloadErr != nil {
log.Error().
Err(payloadErr).
Msg("failed to add encoded payload")

// addCertChainPayload will record any errors in the generated
// payload that were previously registered with the plugin (e.g.,
// failure to connect to a service, timeout, etc.). This error is
// registered for display in plugin output and not for the payload
// (since at this point we failed to create the payload).
plugin.Errors = append(plugin.Errors, payloadErr)

plugin.ExitStatusCode = nagios.StateUNKNOWNExitCode
plugin.ServiceOutput = fmt.Sprintf(
"%s: Failed to add encoded payload",
nagios.StateUNKNOWNLabel,
)

return
}
}
// We use pointers so that the deferred function will access the
// latest value for the variable at the time of execution (otherwise
// it would capture only the value at the time the function is
// deferred).
}(&certChain, plugin, cfg, &ipAddr)

// Annotate all errors (if any) with remediation advice just before
// generating the certificate metadata payload and ending plugin
// execution.
defer annotateErrors(plugin)

// Honor request to parse filename first
switch {
Expand Down Expand Up @@ -230,7 +271,7 @@ func main() {
// Grab first IP Address from the resolved collection. We'll
// explicitly use it for cert retrieval and note it in the report
// output.
ipAddr := expandedHost.Expanded[0]
ipAddr = expandedHost.Expanded[0]

// Server Name Indication (SNI) support is used to request a specific
// certificate chain from a remote server.
Expand Down Expand Up @@ -423,25 +464,6 @@ func main() {
return
}

if cfg.EmitPayload || cfg.EmitPayloadWithFullChain {
payloadErr := addCertChainPayload(plugin, cfg, validationResults)
if payloadErr != nil {
log.Error().
Err(payloadErr).
Msg("failed to add encoded payload")

plugin.Errors = append(plugin.Errors, payloadErr)

plugin.ExitStatusCode = nagios.StateUNKNOWNExitCode
plugin.ServiceOutput = fmt.Sprintf(
"%s: Failed to add encoded payload",
nagios.StateUNKNOWNLabel,
)

return
}
}

switch {
case validationResults.HasFailed():

Expand Down
Loading
Loading