mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 17:04:39 +03:00
better handling of outgoing tls reports to recipient domains vs hosts
based on discussion on uta mailing list. it seems the intention of the tlsrpt is to only send reports to recipient domains. but i was able to interpret the tlsrpt rfc as sending reports to mx hosts too ("policy domain", and because it makes sense given how DANE works per MX host, not recipient domain). this change makes the behaviour of outgoing reports to recipient domains work more in line with expectations most folks may have about tls reporting (i.e. also include per-mx host tlsa policies in the report). this also keeps reports to mx hosts working, and makes them more useful by including the recipient domains of affected deliveries.
This commit is contained in:
@ -19,26 +19,24 @@ import (
|
||||
type TLSResult struct {
|
||||
ID int64
|
||||
|
||||
// Domain with TLSRPT DNS record, with addresses that will receive reports. Either
|
||||
// a recipient domain (for MTA-STS policies) or an (MX) host (for DANE policies).
|
||||
// Unicode.
|
||||
// Domain potentially with TLSRPT DNS record, with addresses that will receive
|
||||
// reports. Either a recipient domain (for MTA-STS policies) or an (MX) host (for
|
||||
// DANE policies). Unicode.
|
||||
PolicyDomain string `bstore:"unique PolicyDomain+DayUTC+RecipientDomain,nonzero"`
|
||||
|
||||
// DayUTC is of the form yyyymmdd.
|
||||
DayUTC string `bstore:"nonzero"`
|
||||
// We send per 24h UTC-aligned days. ../rfc/8460:474
|
||||
|
||||
// Reports are sent per policy domain. When delivering a message to a recipient
|
||||
// domain, we can get multiple TLSResults, typically one for MTA-STS, and one or
|
||||
// more for DANE (one for each MX target, or actually TLSA base domain). We track
|
||||
// recipient domain so we can display successes/failures for delivery of messages
|
||||
// to a recipient domain in the admin pages. Unicode.
|
||||
// Reports are sent per recipient domain and per MX host. For reports to a
|
||||
// recipient domain, we type send a result for MTA-STS and one or more MX host
|
||||
// (DANE) results. Unicode.
|
||||
RecipientDomain string `bstore:"index,nonzero"`
|
||||
|
||||
Created time.Time `bstore:"default now"`
|
||||
Updated time.Time `bstore:"default now"`
|
||||
|
||||
IsHost bool // Result is for host (e.g. DANE), not recipient domain (e.g. MTA-STS).
|
||||
IsHost bool // Result is for MX host (DANE), not recipient domain (MTA-STS).
|
||||
|
||||
// Whether to send a report. TLS results for delivering messages with TLS reports
|
||||
// will be recorded, but will not cause a report to be sent.
|
||||
@ -47,6 +45,17 @@ type TLSResult struct {
|
||||
// but presumably that's to prevent mail servers sending a report every day once
|
||||
// they start.
|
||||
|
||||
// Set after sending to recipient domain, before sending results to policy domain
|
||||
// (after which the record is removed).
|
||||
SentToRecipientDomain bool
|
||||
// Reporting addresses from the recipient domain TLSRPT record, not necessarily
|
||||
// those we sent to (e.g. due to failure). Used to leave results to MX target
|
||||
// (DANE) policy domains out that were already sent in the report to the recipient
|
||||
// domain, so we don't report twice.
|
||||
RecipientDomainReportingAddresses []string
|
||||
// Set after sending report to policy domain.
|
||||
SentToPolicyDomain bool
|
||||
|
||||
// Results is updated for each TLS attempt.
|
||||
Results []tlsrpt.Result
|
||||
}
|
||||
@ -149,7 +158,7 @@ func Results(ctx context.Context) ([]TLSResult, error) {
|
||||
return bstore.QueryDB[TLSResult](ctx, db).SortAsc("PolicyDomain", "DayUTC", "RecipientDomain").List()
|
||||
}
|
||||
|
||||
// ResultsPolicyDomain returns all TLSResults for a policy domain, potentially for
|
||||
// ResultsDomain returns all TLSResults for a policy domain, potentially for
|
||||
// multiple days.
|
||||
func ResultsPolicyDomain(ctx context.Context, policyDomain dns.Domain) ([]TLSResult, error) {
|
||||
db, err := resultDB(ctx)
|
||||
@ -160,6 +169,17 @@ func ResultsPolicyDomain(ctx context.Context, policyDomain dns.Domain) ([]TLSRes
|
||||
return bstore.QueryDB[TLSResult](ctx, db).FilterNonzero(TLSResult{PolicyDomain: policyDomain.Name()}).SortAsc("DayUTC", "RecipientDomain").List()
|
||||
}
|
||||
|
||||
// ResultsRecipientDomain returns all TLSResults for a recipient domain,
|
||||
// potentially for multiple days.
|
||||
func ResultsRecipientDomain(ctx context.Context, recipientDomain dns.Domain) ([]TLSResult, error) {
|
||||
db, err := resultDB(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bstore.QueryDB[TLSResult](ctx, db).FilterNonzero(TLSResult{RecipientDomain: recipientDomain.Name()}).SortAsc("DayUTC", "PolicyDomain").List()
|
||||
}
|
||||
|
||||
// RemoveResultsPolicyDomain removes all TLSResults for the policy domain on the
|
||||
// day from the database.
|
||||
func RemoveResultsPolicyDomain(ctx context.Context, policyDomain dns.Domain, dayUTC string) error {
|
||||
@ -172,6 +192,18 @@ func RemoveResultsPolicyDomain(ctx context.Context, policyDomain dns.Domain, day
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveResultsRecipientDomain removes all TLSResults for the recipient domain on
|
||||
// the day from the database.
|
||||
func RemoveResultsRecipientDomain(ctx context.Context, recipientDomain dns.Domain, dayUTC string) error {
|
||||
db, err := resultDB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bstore.QueryDB[TLSResult](ctx, db).FilterNonzero(TLSResult{RecipientDomain: recipientDomain.Name(), DayUTC: dayUTC}).Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
// SuppressAdd adds an address to the suppress list.
|
||||
func SuppressAdd(ctx context.Context, ba *TLSRPTSuppressAddress) error {
|
||||
db, err := resultDB(ctx)
|
||||
|
Reference in New Issue
Block a user