Initial commit
This commit is contained in:
commit
d96ebc4d0e
19 changed files with 2537 additions and 0 deletions
135
checker/types.go
Normal file
135
checker/types.go
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// Package checker implements the XMPP server checker for happyDomain.
|
||||
//
|
||||
// It probes a domain's XMPP deployment (SRV discovery, STARTTLS,
|
||||
// stream features, SASL mechanisms, dialback / SASL EXTERNAL,
|
||||
// XEP-0368 direct TLS) and reports actionable findings.
|
||||
//
|
||||
// TLS certificate chain / SAN / expiry / cipher posture is intentionally
|
||||
// out of scope; a dedicated TLS checker covers that.
|
||||
package checker
|
||||
|
||||
import (
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
const ObservationKeyXMPP sdk.ObservationKey = "xmpp"
|
||||
|
||||
type XMPPMode string
|
||||
|
||||
const (
|
||||
ModeClient XMPPMode = "c2s"
|
||||
ModeServer XMPPMode = "s2s"
|
||||
ModeBoth XMPPMode = "both"
|
||||
)
|
||||
|
||||
var validModes = []string{string(ModeClient), string(ModeServer), string(ModeBoth)}
|
||||
|
||||
// XMPPData is the full observation stored per run.
|
||||
type XMPPData struct {
|
||||
Domain string `json:"domain"`
|
||||
RunAt string `json:"run_at"`
|
||||
SRV SRVLookup `json:"srv"`
|
||||
Endpoints []EndpointProbe `json:"endpoints"`
|
||||
Coverage ReachabilitySpan `json:"coverage"`
|
||||
Issues []Issue `json:"issues"`
|
||||
}
|
||||
|
||||
type SRVLookup struct {
|
||||
Client []SRVRecord `json:"client,omitempty"`
|
||||
Server []SRVRecord `json:"server,omitempty"`
|
||||
ClientSecure []SRVRecord `json:"client_secure,omitempty"`
|
||||
ServerSecure []SRVRecord `json:"server_secure,omitempty"`
|
||||
Jabber []SRVRecord `json:"jabber,omitempty"`
|
||||
// Errors per-set (keyed by record type like "_xmpp-client._tcp").
|
||||
Errors map[string]string `json:"errors,omitempty"`
|
||||
// FallbackProbed is true when no SRV was published and we probed the bare domain.
|
||||
FallbackProbed bool `json:"fallback_probed,omitempty"`
|
||||
}
|
||||
|
||||
type SRVRecord struct {
|
||||
Target string `json:"target"`
|
||||
Port uint16 `json:"port"`
|
||||
Priority uint16 `json:"priority"`
|
||||
Weight uint16 `json:"weight"`
|
||||
// IPv4 and IPv6 addresses resolved for the target (at probe time).
|
||||
IPv4 []string `json:"ipv4,omitempty"`
|
||||
IPv6 []string `json:"ipv6,omitempty"`
|
||||
}
|
||||
|
||||
// EndpointProbe is the result of probing one (mode, host, port, address) tuple.
|
||||
type EndpointProbe struct {
|
||||
Mode XMPPMode `json:"mode"`
|
||||
SRVPrefix string `json:"srv_prefix"`
|
||||
Target string `json:"target"`
|
||||
Port uint16 `json:"port"`
|
||||
Address string `json:"address"`
|
||||
IsIPv6 bool `json:"is_ipv6,omitempty"`
|
||||
DirectTLS bool `json:"direct_tls,omitempty"`
|
||||
|
||||
// What happened.
|
||||
TCPConnected bool `json:"tcp_connected"`
|
||||
StreamOpened bool `json:"stream_opened"`
|
||||
|
||||
STARTTLSOffered bool `json:"starttls_offered"`
|
||||
STARTTLSRequired bool `json:"starttls_required"`
|
||||
STARTTLSUpgraded bool `json:"starttls_upgraded"`
|
||||
|
||||
TLSVersion string `json:"tls_version,omitempty"`
|
||||
TLSCipher string `json:"tls_cipher,omitempty"`
|
||||
|
||||
// Post-TLS features.
|
||||
FeaturesRead bool `json:"features_read,omitempty"`
|
||||
SASLMechanisms []string `json:"sasl_mechanisms,omitempty"`
|
||||
DialbackOffered bool `json:"dialback_offered,omitempty"`
|
||||
SASLExternal bool `json:"sasl_external,omitempty"`
|
||||
|
||||
StreamFrom string `json:"stream_from,omitempty"`
|
||||
|
||||
ElapsedMS int64 `json:"elapsed_ms"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type ReachabilitySpan struct {
|
||||
HasIPv4 bool `json:"has_ipv4"`
|
||||
HasIPv6 bool `json:"has_ipv6"`
|
||||
// WorkingC2S is true when at least one c2s endpoint completed TLS + advertised SASL.
|
||||
WorkingC2S bool `json:"working_c2s"`
|
||||
// WorkingS2S is true when at least one s2s endpoint completed TLS + advertised dialback or SASL EXTERNAL.
|
||||
WorkingS2S bool `json:"working_s2s"`
|
||||
}
|
||||
|
||||
// Issue is a structured finding attached to the observation so the rule and
|
||||
// the HTML report can both consume them without re-deriving logic.
|
||||
type Issue struct {
|
||||
Code string `json:"code"`
|
||||
Severity string `json:"severity"` // "info" | "warn" | "crit"
|
||||
Message string `json:"message"`
|
||||
Fix string `json:"fix,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
}
|
||||
|
||||
// Severities (string for stable JSON, independent of sdk.Status numeric values).
|
||||
const (
|
||||
SeverityInfo = "info"
|
||||
SeverityWarn = "warn"
|
||||
SeverityCrit = "crit"
|
||||
)
|
||||
|
||||
// Issue codes.
|
||||
const (
|
||||
CodeNoSRV = "xmpp.no_srv"
|
||||
CodeSRVServfail = "xmpp.srv.servfail"
|
||||
CodeStartTLSMissing = "xmpp.starttls.missing"
|
||||
CodeStartTLSNotRequired = "xmpp.starttls.not_required"
|
||||
CodeStartTLSFailed = "xmpp.starttls.handshake_failed"
|
||||
CodeTCPUnreachable = "xmpp.tcp.unreachable"
|
||||
CodeSASLPlainOnly = "xmpp.sasl.plain_only"
|
||||
CodeSASLNoSCRAM = "xmpp.sasl.no_scram"
|
||||
CodeSASLNoSCRAMPlus = "xmpp.sasl.no_scram_plus"
|
||||
CodeS2SNoAuth = "xmpp.s2s.no_auth"
|
||||
CodeS2SProbeIncomplete = "xmpp.s2s.probe_incomplete"
|
||||
CodeLegacyJabber = "xmpp.legacy_jabber"
|
||||
CodeNoIPv6 = "xmpp.no_ipv6"
|
||||
CodeNoDirectTLS = "xmpp.no_direct_tls"
|
||||
CodeAllEndpointsDown = "xmpp.all_endpoints_down"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue