package reportscollector import ( "compress/gzip" "encoding/json" "io" "net/http" "time" ) type tlsrptFailure struct { ResultType string `json:"result-type"` SendingMTA string `json:"sending-mta-ip"` ReceivingMX string `json:"receiving-mx-hostname"` ReceivingIP string `json:"receiving-ip"` NumFailed int `json:"failed-session-count"` ErrorCode string `json:"failure-reason-code"` AdditionalInfo string `json:"additional-information"` } type tlsrptPolicy struct { Policy struct { Type string `json:"policy-type"` Policy []string `json:"policy-string"` Domain string `json:"policy-domain"` Mx string `json:"mx-host"` } `json:"policy"` Summary struct { NumSuccessful int `json:"total-successful-session-count"` NumFailed int `json:"total-failure-session-count"` } `json:"summary"` Failures []*tlsrptFailure `json:"failure-details"` } // A TLS RPT report. type tlsrpt struct { ReportID string `json:"report-id"` Organization string `json:"organization-name"` ContactInfo string `json:"contact-info"` DateRange struct { Start time.Time `json:"start-datetime"` End time.Time `json:"end-datetime"` } `json:"date-range"` Policies []*tlsrptPolicy `json:"policies"` } type TLSRPTHandler struct{} func (h *TLSRPTHandler) Parse(contentType string, req *http.Request) ([]Event, error) { var r io.Reader switch contentType { case "application/tlsrpt+json": r = req.Body case "application/tlsrpt+gzip": var err error r, err = gzip.NewReader(req.Body) if err != nil { return nil, err } default: return nil, ErrNoMatch } var report tlsrpt if err := json.NewDecoder(r).Decode(&report); err != nil { return nil, err } var events []Event for _, p := range report.Policies { for _, f := range p.Failures { events = append(events, h.eventFromFailure(&report, p, f)) } } return events, nil } func (h *TLSRPTHandler) eventFromFailure(report *tlsrpt, policy *tlsrptPolicy, failure *tlsrptFailure) Event { e := make(Event) e.Set("type", "tlsrpt") e.Set("event_timestamp", report.DateRange.End) e.Set("domain", policy.Policy.Domain) e.Set("report_id", report.ReportID) e.Set("report_organization", report.Organization) e.Set("tlsrpt_type", failure.ResultType) e.Set("sending_mta", failure.SendingMTA) e.Set("receiving_mx", failure.ReceivingMX) e.Set("receiving_ip", failure.ReceivingIP) e.Set("failed_session_count", failure.NumFailed) e.Set("failure_reason", failure.ErrorCode) return e }