// Package checker probes a domain for the three competing email // autoconfiguration mechanisms (Bucksch autoconfig, Microsoft Autodiscover // POX, RFC 6186 SRV) and cross-checks them. package checker import ( "time" ) // ObservationKeyAutoconfig is the observation key for autoconfig data. const ObservationKeyAutoconfig = "email_autoconfig" // Data is the full collected payload. type Data struct { Domain string `json:"domain"` Email string `json:"email"` CollectedAt time.Time `json:"collected_at"` MX []MXRecord `json:"mx,omitempty"` MXError string `json:"mx_error,omitempty"` SRV []SRVRecord `json:"srv,omitempty"` Autoconfig []AutoconfigProbe `json:"autoconfig,omitempty"` Autodiscover []AutodiscoverProbe `json:"autodiscover,omitempty"` // First successful autoconfig parse, promoted here for rules to consume. ClientConfig *ClientConfig `json:"client_config,omitempty"` ClientConfigSource string `json:"client_config_source,omitempty"` AutodiscoverResult *AutodiscoverResponse `json:"autodiscover_result,omitempty"` } // MXRecord is a single MX record. type MXRecord struct { Host string `json:"host"` Preference uint16 `json:"preference"` } // SRVRecord is a single RFC 6186 SRV record observation. type SRVRecord struct { Service string `json:"service"` // RFC 6186 tag, e.g. "_imaps._tcp" Target string `json:"target"` Port uint16 `json:"port"` Priority uint16 `json:"priority"` Weight uint16 `json:"weight"` // Skip means the service is explicitly disabled (RFC 6186 target "."). Skip bool `json:"skip,omitempty"` } // ProbeResult captures the outcome of a single HTTP probe. type ProbeResult struct { URL string `json:"url"` Method string `json:"method,omitempty"` StatusCode int `json:"status_code,omitempty"` DurationMs int64 `json:"duration_ms,omitempty"` ContentType string `json:"content_type,omitempty"` BodyBytes int `json:"body_bytes,omitempty"` Redirected bool `json:"redirected,omitempty"` FinalURL string `json:"final_url,omitempty"` TLSServerName string `json:"tls_server_name,omitempty"` TLSIssuer string `json:"tls_issuer,omitempty"` TLSSubject string `json:"tls_subject,omitempty"` TLSNotAfter string `json:"tls_not_after,omitempty"` TLSError string `json:"tls_error,omitempty"` Error string `json:"error,omitempty"` ParseError string `json:"parse_error,omitempty"` } // AutoconfigProbe is one probe attempt for Thunderbird-style autoconfig. type AutoconfigProbe struct { Source string `json:"source"` // "autoconfig", "wellknown", "http-autoconfig", "ispdb", "mx-autoconfig", "mx-ispdb" Result ProbeResult `json:"result"` Parsed *ClientConfig `json:"parsed,omitempty"` } // AutodiscoverProbe is one probe attempt for MS Autodiscover (POX). type AutodiscoverProbe struct { Source string `json:"source"` // "root", "subdomain", "srv", "redirect" Result ProbeResult `json:"result"` Parsed *AutodiscoverResponse `json:"parsed,omitempty"` } // ClientConfig is the parsed Thunderbird-style clientConfig document. type ClientConfig struct { Version string `json:"version,omitempty"` EmailProviderID string `json:"email_provider_id,omitempty"` DisplayName string `json:"display_name,omitempty"` ShortName string `json:"short_name,omitempty"` Domains []string `json:"domains,omitempty"` Incoming []ServerConfig `json:"incoming,omitempty"` Outgoing []ServerConfig `json:"outgoing,omitempty"` AddressBook []DavServer `json:"address_book,omitempty"` Calendar []DavServer `json:"calendar,omitempty"` WebMail *WebMail `json:"webmail,omitempty"` Documentation []Documentation `json:"documentation,omitempty"` } // ServerConfig is one incoming/outgoing server definition. type ServerConfig struct { Type string `json:"type"` // imap, pop3, smtp Hostname string `json:"hostname"` Port int `json:"port"` SocketType string `json:"socket_type"` // plain, SSL, STARTTLS Username string `json:"username"` // may contain %EMAIL% placeholders Authentication string `json:"authentication"` // password-cleartext, password-encrypted, OAuth2, ... } // DavServer is a CardDAV or CalDAV server reference. type DavServer struct { Type string `json:"type"` Username string `json:"username,omitempty"` Authentication string `json:"authentication,omitempty"` ServerURL string `json:"server_url,omitempty"` } // WebMail holds webmail configuration (if any). type WebMail struct { LoginPage string `json:"login_page,omitempty"` } // Documentation is a clientConfig entry. type Documentation struct { URL string `json:"url,omitempty"` Descr string `json:"descr,omitempty"` } // AutodiscoverResponse is the parsed POX response. type AutodiscoverResponse struct { DisplayName string `json:"display_name,omitempty"` // Set when Action is redirectAddr / redirectUrl; mutually exclusive with Protocols. RedirectAddr string `json:"redirect_addr,omitempty"` RedirectURL string `json:"redirect_url,omitempty"` Protocols []AutodiscoverProtocol `json:"protocols,omitempty"` } // AutodiscoverProtocol covers IMAP/POP/SMTP fields; Exchange-only protocols // (EXCH/EXPR/MobileSync) are stored but not analysed. type AutodiscoverProtocol struct { Type string `json:"type"` // IMAP, POP3, SMTP, EXCH, EXPR, WEB, MobileSync Server string `json:"server,omitempty"` Port int `json:"port,omitempty"` Encryption string `json:"encryption,omitempty"` // SSL, TLS, None SSL string `json:"ssl,omitempty"` // on/off LoginName string `json:"login_name,omitempty"` DomainRequired string `json:"domain_required,omitempty"` AuthRequired string `json:"auth_required,omitempty"` }