checker-dangling/checker/types.go

90 lines
2.6 KiB
Go

// Package checker detects dangling pointer records (CNAME/MX/SRV/NS) whose external targets
// may have expired or been re-registered, enabling subdomain takeover.
package checker
import (
"encoding/json"
)
const ObservationKeyDangling = "dangling_records"
// DanglingData is the raw observation payload; one Pointer per (owner, rrtype, target) triple.
type DanglingData struct {
Zone string `json:"zone,omitempty"`
ServicesScanned int `json:"services_scanned"`
Pointers []Pointer `json:"pointers,omitempty"`
// CollectErrors surfaces non-fatal scan problems so silent skips don't masquerade as a clean pass.
CollectErrors []string `json:"collect_errors,omitempty"`
}
// Pointer is one (owner, rrtype, target) triple from the zone, with its DNS resolution verdict.
type Pointer struct {
Owner string `json:"owner"`
Subdomain string `json:"subdomain"`
Rrtype string `json:"rrtype"`
Target string `json:"target"`
// External flags takeover risk: Target's registrable domain differs from the zone's.
External bool `json:"external"`
Registrable string `json:"registrable,omitempty"`
// ServiceType identifies the happyDomain service for linking back to the edit screen.
ServiceType string `json:"service_type,omitempty"`
Resolution string `json:"resolution"`
ResolutionDetail string `json:"resolution_detail,omitempty"`
}
// rawZone is a partial Zone type redeclared here to avoid importing the happyDomain module.
type rawZone struct {
DomainName string `json:"domain_name,omitempty"`
Services map[string][]rawService `json:"services"`
}
type rawService struct {
Type string `json:"_svctype"`
Domain string `json:"_domain"`
Service json.RawMessage `json:"Service"`
}
type cnameBody struct {
Record struct {
Hdr struct {
Name string `json:"Name"`
} `json:"Hdr"`
Target string `json:"Target"`
} `json:"cname"`
}
type mxRecord struct {
Hdr struct {
Name string `json:"Name"`
} `json:"Hdr"`
Mx string `json:"Mx"`
}
type mxsBody struct {
MXs []mxRecord `json:"mx"`
}
type srvRecord struct {
Hdr struct {
Name string `json:"Name"`
} `json:"Hdr"`
Target string `json:"Target"`
}
type srvsBody struct {
Records []srvRecord `json:"srv"`
}
// orphanRecord wraps an svcs.Orphan body; Hdr.Rrtype is sniffed to pick the right field.
type orphanRecord struct {
Record struct {
Hdr struct {
Name string `json:"Name"`
Rrtype uint16 `json:"Rrtype"`
} `json:"Hdr"`
// Optional fields, populated for the relevant rrtype.
Target string `json:"Target,omitempty"`
Mx string `json:"Mx,omitempty"`
Ns string `json:"Ns,omitempty"`
} `json:"record"`
}