Initial commit
This commit is contained in:
commit
19296f4188
18 changed files with 2562 additions and 0 deletions
114
checker/rule.go
Normal file
114
checker/rule.go
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
// Rule returns the single aggregation rule for this checker. It folds
|
||||
// every finding produced by Collect into a CheckState whose status is
|
||||
// the worst severity seen.
|
||||
func Rule() sdk.CheckRule {
|
||||
return &emailKeyRule{}
|
||||
}
|
||||
|
||||
type emailKeyRule struct{}
|
||||
|
||||
func (r *emailKeyRule) Name() string { return "openpgpkey_smimea_check" }
|
||||
|
||||
func (r *emailKeyRule) Description() string {
|
||||
return "Validates a DNS-published OpenPGP key (RFC 7929) or S/MIME certificate (RFC 8162), running DNSSEC, record-hash, parse, expiration, algorithm-strength, and S/MIME EKU checks."
|
||||
}
|
||||
|
||||
func (r *emailKeyRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts sdk.CheckerOptions) []sdk.CheckState {
|
||||
var data EmailKeyData
|
||||
if err := obs.Get(ctx, ObservationKey, &data); err != nil {
|
||||
return []sdk.CheckState{{
|
||||
Status: sdk.StatusError,
|
||||
Message: fmt.Sprintf("Failed to read observation %q: %v", ObservationKey, err),
|
||||
Code: "openpgpkey_observation_error",
|
||||
}}
|
||||
}
|
||||
return []sdk.CheckState{evaluate(&data)}
|
||||
}
|
||||
|
||||
// evaluate folds findings into a CheckState. The status is the highest
|
||||
// severity observed: any Crit makes the whole result Crit, any Warn
|
||||
// makes it Warn, otherwise Info/OK.
|
||||
func evaluate(data *EmailKeyData) sdk.CheckState {
|
||||
var crit, warn, info int
|
||||
var firstCrit, firstWarn, firstInfo string
|
||||
for _, f := range data.Findings {
|
||||
switch f.Severity {
|
||||
case SeverityCrit:
|
||||
crit++
|
||||
if firstCrit == "" {
|
||||
firstCrit = f.Message
|
||||
}
|
||||
case SeverityWarn:
|
||||
warn++
|
||||
if firstWarn == "" {
|
||||
firstWarn = f.Message
|
||||
}
|
||||
case SeverityInfo:
|
||||
info++
|
||||
if firstInfo == "" {
|
||||
firstInfo = f.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status := sdk.StatusOK
|
||||
msg := summariseHealthy(data)
|
||||
code := "openpgpkey_ok"
|
||||
switch {
|
||||
case crit > 0:
|
||||
status = sdk.StatusCrit
|
||||
msg = firstCrit
|
||||
code = "openpgpkey_crit"
|
||||
case warn > 0:
|
||||
status = sdk.StatusWarn
|
||||
msg = firstWarn
|
||||
code = "openpgpkey_warn"
|
||||
case info > 0:
|
||||
status = sdk.StatusInfo
|
||||
msg = firstInfo
|
||||
code = "openpgpkey_info"
|
||||
}
|
||||
|
||||
meta := map[string]any{
|
||||
"kind": data.Kind,
|
||||
"queried": data.QueriedOwner,
|
||||
"record_count": data.RecordCount,
|
||||
"findings": data.Findings,
|
||||
}
|
||||
if data.DNSSECSecure != nil {
|
||||
meta["dnssec_secure"] = *data.DNSSECSecure
|
||||
}
|
||||
|
||||
return sdk.CheckState{
|
||||
Status: status,
|
||||
Message: msg,
|
||||
Code: code,
|
||||
Subject: data.QueriedOwner,
|
||||
Meta: meta,
|
||||
}
|
||||
}
|
||||
|
||||
func summariseHealthy(data *EmailKeyData) string {
|
||||
switch data.Kind {
|
||||
case KindOpenPGPKey:
|
||||
if data.OpenPGP != nil && data.OpenPGP.Fingerprint != "" {
|
||||
return fmt.Sprintf("OPENPGPKEY %s published and valid (fingerprint %s)", data.QueriedOwner, data.OpenPGP.Fingerprint)
|
||||
}
|
||||
return fmt.Sprintf("OPENPGPKEY %s published and valid", data.QueriedOwner)
|
||||
case KindSMIMEA:
|
||||
if data.SMIMEA != nil && data.SMIMEA.Certificate != nil {
|
||||
return fmt.Sprintf("SMIMEA %s valid (subject %s)", data.QueriedOwner, data.SMIMEA.Certificate.Subject)
|
||||
}
|
||||
return fmt.Sprintf("SMIMEA %s published and valid", data.QueriedOwner)
|
||||
}
|
||||
return "Record validated"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue