package checker import ( "context" "fmt" sdk "git.happydns.org/checker-sdk-go/checker" ) // starttlsAdvertisedRule flags STARTTLS endpoints whose server did not // advertise the upgrade. Severity depends on RequireSTARTTLS: opportunistic // STARTTLS degrades to a warning; mandatory STARTTLS is critical. type starttlsAdvertisedRule struct{} func (r *starttlsAdvertisedRule) Name() string { return "tls.starttls_advertised" } func (r *starttlsAdvertisedRule) Description() string { return "Verifies that STARTTLS endpoints advertise the upgrade capability." } func (r *starttlsAdvertisedRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { data, errSt := loadData(ctx, obs) if errSt != nil { return []sdk.CheckState{*errSt} } if len(data.Probes) == 0 { return []sdk.CheckState{emptyCaseState("tls.starttls_advertised.no_endpoints")} } var out []sdk.CheckState anySTARTTLS := false for _, ref := range sortedRefs(data) { p := data.Probes[ref] if p.STARTTLSDialect == "" { continue } anySTARTTLS = true if !p.STARTTLSNotOffered { continue } status := sdk.StatusWarn if p.RequireSTARTTLS { status = sdk.StatusCrit } out = append(out, sdk.CheckState{ Status: status, Code: "tls.starttls_advertised.missing", Subject: subjectOf(p), Message: fmt.Sprintf("Server on %s does not advertise STARTTLS.", p.Endpoint), Meta: metaOf(p), }) } if !anySTARTTLS { return []sdk.CheckState{unknownState( "tls.starttls_advertised.not_applicable", "No STARTTLS endpoint in the discovered set.", )} } if len(out) == 0 { return []sdk.CheckState{passState( "tls.starttls_advertised.ok", "STARTTLS is advertised on every STARTTLS endpoint.", )} } return out } // starttlsSupportedRule flags endpoints whose STARTTLS dialect is not // implemented by this checker. A misconfigured discovery entry (typo, new // protocol) should be visible as its own concern rather than blending into // generic handshake failures. type starttlsSupportedRule struct{} func (r *starttlsSupportedRule) Name() string { return "tls.starttls_dialect_supported" } func (r *starttlsSupportedRule) Description() string { return "Verifies that discovered STARTTLS dialects are implemented by the checker." } func (r *starttlsSupportedRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { data, errSt := loadData(ctx, obs) if errSt != nil { return []sdk.CheckState{*errSt} } if len(data.Probes) == 0 { return []sdk.CheckState{emptyCaseState("tls.starttls_dialect_supported.no_endpoints")} } var out []sdk.CheckState for _, ref := range sortedRefs(data) { p := data.Probes[ref] if !p.STARTTLSUnsupportedProto { continue } out = append(out, sdk.CheckState{ Status: sdk.StatusError, Code: "tls.starttls_dialect_supported.unknown", Subject: subjectOf(p), Message: fmt.Sprintf("Unsupported STARTTLS dialect %q for %s.", p.STARTTLSDialect, p.Endpoint), Meta: metaOf(p), }) } if len(out) == 0 { return []sdk.CheckState{passState( "tls.starttls_dialect_supported.ok", "Every STARTTLS dialect encountered is implemented.", )} } return out }