mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 16:33:47 +03:00
use new sherpadoc rename mechanism to remove some typename stuttering
the stuttering was introduced to make the same type name declared in multiple packages, and used in the admin sherpa api, unique. with sherpadoc's new rename, we can make them unique when generating the api definition/docs, and the Go code can use nicer names.
This commit is contained in:
parent
962575f21b
commit
ec967ef321
18 changed files with 73 additions and 83 deletions
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ build0:
|
||||||
CGO_ENABLED=0 go build
|
CGO_ENABLED=0 go build
|
||||||
CGO_ENABLED=0 go vet ./...
|
CGO_ENABLED=0 go vet ./...
|
||||||
./gendoc.sh
|
./gendoc.sh
|
||||||
(cd webadmin && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none -rename 'config Domain ConfigDomain' Admin) >webadmin/api.json
|
(cd webadmin && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none -rename 'config Domain ConfigDomain,dmarc Policy DMARCPolicy,mtasts MX STSMX,tlsrptdb Record TLSReportRecord,tlsrptdb SuppressAddress TLSRPTSuppressAddress' Admin) >webadmin/api.json
|
||||||
(cd webaccount && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Account) >webaccount/api.json
|
(cd webaccount && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Account) >webaccount/api.json
|
||||||
(cd webmail && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Webmail) >webmail/api.json
|
(cd webmail && CGO_ENABLED=0 go run ../vendor/github.com/mjl-/sherpadoc/cmd/sherpadoc/*.go -adjust-function-names none Webmail) >webmail/api.json
|
||||||
./gents.sh webadmin/api.json webadmin/api.ts
|
./gents.sh webadmin/api.json webadmin/api.ts
|
||||||
|
|
|
@ -92,9 +92,9 @@ func parseRecord(s string, checkRequired bool) (record *Record, isdmarc bool, re
|
||||||
// ../rfc/7489:1105
|
// ../rfc/7489:1105
|
||||||
p.xerrorf("p= (policy) must be first tag")
|
p.xerrorf("p= (policy) must be first tag")
|
||||||
}
|
}
|
||||||
r.Policy = DMARCPolicy(p.xtakelist("none", "quarantine", "reject"))
|
r.Policy = Policy(p.xtakelist("none", "quarantine", "reject"))
|
||||||
case "sp":
|
case "sp":
|
||||||
r.SubdomainPolicy = DMARCPolicy(p.xkeyword())
|
r.SubdomainPolicy = Policy(p.xkeyword())
|
||||||
// note: we check if the value is valid before returning.
|
// note: we check if the value is valid before returning.
|
||||||
case "rua":
|
case "rua":
|
||||||
r.AggregateReportAddresses = append(r.AggregateReportAddresses, p.xuri())
|
r.AggregateReportAddresses = append(r.AggregateReportAddresses, p.xuri())
|
||||||
|
|
16
dmarc/txt.go
16
dmarc/txt.go
|
@ -5,18 +5,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// todo: DMARCPolicy should be named just Policy, but this is causing conflicting types in sherpadoc output. should somehow get the dmarc-prefix only in the sherpadoc.
|
|
||||||
|
|
||||||
// Policy as used in DMARC DNS record for "p=" or "sp=".
|
// Policy as used in DMARC DNS record for "p=" or "sp=".
|
||||||
type DMARCPolicy string
|
type Policy string
|
||||||
|
|
||||||
// ../rfc/7489:1157
|
// ../rfc/7489:1157
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PolicyEmpty DMARCPolicy = "" // Only for the optional Record.SubdomainPolicy.
|
PolicyEmpty Policy = "" // Only for the optional Record.SubdomainPolicy.
|
||||||
PolicyNone DMARCPolicy = "none"
|
PolicyNone Policy = "none"
|
||||||
PolicyQuarantine DMARCPolicy = "quarantine"
|
PolicyQuarantine Policy = "quarantine"
|
||||||
PolicyReject DMARCPolicy = "reject"
|
PolicyReject Policy = "reject"
|
||||||
)
|
)
|
||||||
|
|
||||||
// URI is a destination address for reporting.
|
// URI is a destination address for reporting.
|
||||||
|
@ -56,8 +54,8 @@ const (
|
||||||
// v=DMARC1; p=reject; rua=mailto:postmaster@mox.example
|
// v=DMARC1; p=reject; rua=mailto:postmaster@mox.example
|
||||||
type Record struct {
|
type Record struct {
|
||||||
Version string // "v=DMARC1", fixed.
|
Version string // "v=DMARC1", fixed.
|
||||||
Policy DMARCPolicy // Required, for "p=".
|
Policy Policy // Required, for "p=".
|
||||||
SubdomainPolicy DMARCPolicy // Like policy but for subdomains. Optional, for "sp=".
|
SubdomainPolicy Policy // Like policy but for subdomains. Optional, for "sp=".
|
||||||
AggregateReportAddresses []URI // Optional, for "rua=". Destination addresses for aggregate reports.
|
AggregateReportAddresses []URI // Optional, for "rua=". Destination addresses for aggregate reports.
|
||||||
FailureReportAddresses []URI // Optional, for "ruf=". Destination addresses for failure reports.
|
FailureReportAddresses []URI // Optional, for "ruf=". Destination addresses for failure reports.
|
||||||
ADKIM Align // Alignment: "r" (default) for relaxed or "s" for simple. For "adkim=".
|
ADKIM Align // Alignment: "r" (default) for relaxed or "s" for simple. For "adkim=".
|
||||||
|
|
|
@ -201,7 +201,7 @@ Accounts:
|
||||||
mtastsPolicy := mtasts.Policy{
|
mtastsPolicy := mtasts.Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: mtasts.ModeTesting,
|
Mode: mtasts.ModeTesting,
|
||||||
MX: []mtasts.STSMX{
|
MX: []mtasts.MX{
|
||||||
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "backup-example.com"}, Wildcard: true},
|
{Domain: dns.Domain{ASCII: "backup-example.com"}, Wildcard: true},
|
||||||
|
|
|
@ -43,9 +43,9 @@ func mtastsPolicyHandle(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var mxs []mtasts.STSMX
|
var mxs []mtasts.MX
|
||||||
for _, s := range sts.MX {
|
for _, s := range sts.MX {
|
||||||
var mx mtasts.STSMX
|
var mx mtasts.MX
|
||||||
if strings.HasPrefix(s, "*.") {
|
if strings.HasPrefix(s, "*.") {
|
||||||
mx.Wildcard = true
|
mx.Wildcard = true
|
||||||
s = s[2:]
|
s = s[2:]
|
||||||
|
@ -60,7 +60,7 @@ func mtastsPolicyHandle(w http.ResponseWriter, r *http.Request) {
|
||||||
mxs = append(mxs, mx)
|
mxs = append(mxs, mx)
|
||||||
}
|
}
|
||||||
if len(mxs) == 0 {
|
if len(mxs) == 0 {
|
||||||
mxs = []mtasts.STSMX{{Domain: mox.Conf.Static.HostnameDomain}}
|
mxs = []mtasts.MX{{Domain: mox.Conf.Static.HostnameDomain}}
|
||||||
}
|
}
|
||||||
|
|
||||||
policy := mtasts.Policy{
|
policy := mtasts.Policy{
|
||||||
|
|
|
@ -75,9 +75,8 @@ const (
|
||||||
ModeNone Mode = "none" // In case MTA-STS is not or no longer implemented.
|
ModeNone Mode = "none" // In case MTA-STS is not or no longer implemented.
|
||||||
)
|
)
|
||||||
|
|
||||||
// STSMX is an allowlisted MX host name/pattern.
|
// MX is an allowlisted MX host name/pattern.
|
||||||
// todo: find a way to name this just STSMX without getting duplicate names for "MX" in the sherpa api.
|
type MX struct {
|
||||||
type STSMX struct {
|
|
||||||
// "*." wildcard, e.g. if a subdomain matches. A wildcard must match exactly one
|
// "*." wildcard, e.g. if a subdomain matches. A wildcard must match exactly one
|
||||||
// label. *.example.com matches mail.example.com, but not example.com, and not
|
// label. *.example.com matches mail.example.com, but not example.com, and not
|
||||||
// foor.bar.example.com.
|
// foor.bar.example.com.
|
||||||
|
@ -88,7 +87,7 @@ type STSMX struct {
|
||||||
|
|
||||||
// LogString returns a loggable string representing the host, with both unicode
|
// LogString returns a loggable string representing the host, with both unicode
|
||||||
// and ascii version for IDNA domains.
|
// and ascii version for IDNA domains.
|
||||||
func (s STSMX) LogString() string {
|
func (s MX) LogString() string {
|
||||||
pre := ""
|
pre := ""
|
||||||
if s.Wildcard {
|
if s.Wildcard {
|
||||||
pre = "*."
|
pre = "*."
|
||||||
|
@ -103,7 +102,7 @@ func (s STSMX) LogString() string {
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
Version string // "STSv1"
|
Version string // "STSv1"
|
||||||
Mode Mode
|
Mode Mode
|
||||||
MX []STSMX
|
MX []MX
|
||||||
MaxAgeSeconds int // How long this policy can be cached. Suggested values are in weeks or more.
|
MaxAgeSeconds int // How long this policy can be cached. Suggested values are in weeks or more.
|
||||||
Extensions []Pair
|
Extensions []Pair
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ func (p *parser) take(s string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ../rfc/8461:469
|
// ../rfc/8461:469
|
||||||
func (p *parser) xmx() (mx STSMX) {
|
func (p *parser) xmx() (mx MX) {
|
||||||
if p.prefix("*.") {
|
if p.prefix("*.") {
|
||||||
mx.Wildcard = true
|
mx.Wildcard = true
|
||||||
p.o += 2
|
p.o += 2
|
||||||
|
|
|
@ -77,7 +77,7 @@ max_age: 1296000
|
||||||
Policy{
|
Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: ModeTesting,
|
Mode: ModeTesting,
|
||||||
MX: []STSMX{
|
MX: []MX{
|
||||||
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
||||||
|
@ -89,7 +89,7 @@ max_age: 1296000
|
||||||
Policy{
|
Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: ModeEnforce,
|
Mode: ModeEnforce,
|
||||||
MX: []STSMX{
|
MX: []MX{
|
||||||
{Wildcard: true, Domain: dns.Domain{ASCII: "example.com"}},
|
{Wildcard: true, Domain: dns.Domain{ASCII: "example.com"}},
|
||||||
},
|
},
|
||||||
MaxAgeSeconds: 0,
|
MaxAgeSeconds: 0,
|
||||||
|
@ -99,7 +99,7 @@ max_age: 1296000
|
||||||
Policy{
|
Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: ModeEnforce,
|
Mode: ModeEnforce,
|
||||||
MX: []STSMX{
|
MX: []MX{
|
||||||
{Wildcard: true, Domain: dns.Domain{ASCII: "example.com"}},
|
{Wildcard: true, Domain: dns.Domain{ASCII: "example.com"}},
|
||||||
},
|
},
|
||||||
MaxAgeSeconds: 1,
|
MaxAgeSeconds: 1,
|
||||||
|
@ -140,7 +140,7 @@ max_age: 1296000
|
||||||
policy := Policy{
|
policy := Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: ModeTesting,
|
Mode: ModeTesting,
|
||||||
MX: []STSMX{
|
MX: []MX{
|
||||||
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
||||||
|
|
|
@ -52,7 +52,7 @@ func TestDB(t *testing.T) {
|
||||||
policy1 := mtasts.Policy{
|
policy1 := mtasts.Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: mtasts.ModeTesting,
|
Mode: mtasts.ModeTesting,
|
||||||
MX: []mtasts.STSMX{
|
MX: []mtasts.MX{
|
||||||
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx2.example.com"}},
|
||||||
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
{Domain: dns.Domain{ASCII: "mx.backup-example.com"}},
|
||||||
|
@ -71,7 +71,7 @@ func TestDB(t *testing.T) {
|
||||||
policy2 := mtasts.Policy{
|
policy2 := mtasts.Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: mtasts.ModeEnforce,
|
Mode: mtasts.ModeEnforce,
|
||||||
MX: []mtasts.STSMX{
|
MX: []mtasts.MX{
|
||||||
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
{Domain: dns.Domain{ASCII: "mx1.example.com"}},
|
||||||
},
|
},
|
||||||
MaxAgeSeconds: 360000,
|
MaxAgeSeconds: 360000,
|
||||||
|
|
|
@ -64,7 +64,7 @@ func TestRefresh(t *testing.T) {
|
||||||
policy := mtasts.Policy{
|
policy := mtasts.Policy{
|
||||||
Version: "STSv1",
|
Version: "STSv1",
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
MX: []mtasts.STSMX{{Wildcard: false, Domain: mxd}},
|
MX: []mtasts.MX{{Wildcard: false, Domain: mxd}},
|
||||||
MaxAgeSeconds: maxAge,
|
MaxAgeSeconds: maxAge,
|
||||||
Extensions: nil,
|
Extensions: nil,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ReportDBTypes = []any{TLSReportRecord{}}
|
ReportDBTypes = []any{Record{}}
|
||||||
ReportDB *bstore.DB
|
ReportDB *bstore.DB
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
|
|
||||||
// Accessed directly by tlsrptsend.
|
// Accessed directly by tlsrptsend.
|
||||||
ResultDBTypes = []any{TLSResult{}, TLSRPTSuppressAddress{}}
|
ResultDBTypes = []any{TLSResult{}, SuppressAddress{}}
|
||||||
ResultDB *bstore.DB
|
ResultDB *bstore.DB
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,10 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TLSReportRecord is a TLS report as a database record, including information
|
// Record is a TLS report as a database record, including information
|
||||||
// about the sender.
|
// about the sender.
|
||||||
//
|
type Record struct {
|
||||||
// todo: should be named just Record, but it would cause a sherpa type name conflict.
|
ID int64
|
||||||
type TLSReportRecord struct {
|
|
||||||
ID int64 `bstore:"typename Record"`
|
|
||||||
Domain string `bstore:"index"` // Policy domain to which the TLS report applies. Unicode.
|
Domain string `bstore:"index"` // Policy domain to which the TLS report applies. Unicode.
|
||||||
FromDomain string
|
FromDomain string
|
||||||
MailFrom string
|
MailFrom string
|
||||||
|
@ -119,7 +117,7 @@ func AddReport(ctx context.Context, log mlog.Log, verifiedFromDomain dns.Domain,
|
||||||
metricSession.WithLabelValues(result).Add(float64(f.FailedSessionCount))
|
metricSession.WithLabelValues(result).Add(float64(f.FailedSessionCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
record := TLSReportRecord{0, d.Name(), verifiedFromDomain.Name(), mailFrom, d == mox.Conf.Static.HostnameDomain, *r}
|
record := Record{0, d.Name(), verifiedFromDomain.Name(), mailFrom, d == mox.Conf.Static.HostnameDomain, *r}
|
||||||
if err := tx.Insert(&record); err != nil {
|
if err := tx.Insert(&record); err != nil {
|
||||||
return fmt.Errorf("inserting report for domain: %w", err)
|
return fmt.Errorf("inserting report for domain: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -133,22 +131,22 @@ func AddReport(ctx context.Context, log mlog.Log, verifiedFromDomain dns.Domain,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Records returns all TLS reports in the database.
|
// Records returns all TLS reports in the database.
|
||||||
func Records(ctx context.Context) ([]TLSReportRecord, error) {
|
func Records(ctx context.Context) ([]Record, error) {
|
||||||
db, err := reportDB(ctx)
|
db, err := reportDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return bstore.QueryDB[TLSReportRecord](ctx, db).List()
|
return bstore.QueryDB[Record](ctx, db).List()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordID returns the report for the ID.
|
// RecordID returns the report for the ID.
|
||||||
func RecordID(ctx context.Context, id int64) (TLSReportRecord, error) {
|
func RecordID(ctx context.Context, id int64) (Record, error) {
|
||||||
db, err := reportDB(ctx)
|
db, err := reportDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return TLSReportRecord{}, err
|
return Record{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
e := TLSReportRecord{ID: id}
|
e := Record{ID: id}
|
||||||
err = db.Get(ctx, &e)
|
err = db.Get(ctx, &e)
|
||||||
return e, err
|
return e, err
|
||||||
}
|
}
|
||||||
|
@ -156,18 +154,18 @@ func RecordID(ctx context.Context, id int64) (TLSReportRecord, error) {
|
||||||
// RecordsPeriodPolicyDomain returns the reports overlapping start and end, for the
|
// RecordsPeriodPolicyDomain returns the reports overlapping start and end, for the
|
||||||
// given policy domain. If policy domain is empty, records for all domains are
|
// given policy domain. If policy domain is empty, records for all domains are
|
||||||
// returned.
|
// returned.
|
||||||
func RecordsPeriodDomain(ctx context.Context, start, end time.Time, policyDomain dns.Domain) ([]TLSReportRecord, error) {
|
func RecordsPeriodDomain(ctx context.Context, start, end time.Time, policyDomain dns.Domain) ([]Record, error) {
|
||||||
db, err := reportDB(ctx)
|
db, err := reportDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
q := bstore.QueryDB[TLSReportRecord](ctx, db)
|
q := bstore.QueryDB[Record](ctx, db)
|
||||||
var zerodom dns.Domain
|
var zerodom dns.Domain
|
||||||
if policyDomain != zerodom {
|
if policyDomain != zerodom {
|
||||||
q.FilterNonzero(TLSReportRecord{Domain: policyDomain.Name()})
|
q.FilterNonzero(Record{Domain: policyDomain.Name()})
|
||||||
}
|
}
|
||||||
q.FilterFn(func(r TLSReportRecord) bool {
|
q.FilterFn(func(r Record) bool {
|
||||||
dr := r.Report.DateRange
|
dr := r.Report.DateRange
|
||||||
return !dr.Start.Before(start) && dr.Start.Before(end) || dr.End.After(start) && !dr.End.After(end)
|
return !dr.Start.Before(start) && dr.Start.Before(end) || dr.End.After(start) && !dr.End.After(end)
|
||||||
})
|
})
|
||||||
|
|
|
@ -60,12 +60,10 @@ type TLSResult struct {
|
||||||
Results []tlsrpt.Result
|
Results []tlsrpt.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: TLSRPTSuppressAddress should be named just SuppressAddress, but would clash with dmarcdb.SuppressAddress in sherpa api.
|
// SuppressAddress is a reporting address for which outgoing TLS reports
|
||||||
|
|
||||||
// TLSRPTSuppressAddress is a reporting address for which outgoing TLS reports
|
|
||||||
// will be suppressed for a period.
|
// will be suppressed for a period.
|
||||||
type TLSRPTSuppressAddress struct {
|
type SuppressAddress struct {
|
||||||
ID int64
|
ID int64 `bstore:"typename TLSRPTSuppressAddress"`
|
||||||
Inserted time.Time `bstore:"default now"`
|
Inserted time.Time `bstore:"default now"`
|
||||||
ReportingAddress string `bstore:"unique"`
|
ReportingAddress string `bstore:"unique"`
|
||||||
Until time.Time `bstore:"nonzero"`
|
Until time.Time `bstore:"nonzero"`
|
||||||
|
@ -205,7 +203,7 @@ func RemoveResultsRecipientDomain(ctx context.Context, recipientDomain dns.Domai
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuppressAdd adds an address to the suppress list.
|
// SuppressAdd adds an address to the suppress list.
|
||||||
func SuppressAdd(ctx context.Context, ba *TLSRPTSuppressAddress) error {
|
func SuppressAdd(ctx context.Context, ba *SuppressAddress) error {
|
||||||
db, err := resultDB(ctx)
|
db, err := resultDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -215,13 +213,13 @@ func SuppressAdd(ctx context.Context, ba *TLSRPTSuppressAddress) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuppressList returns all reporting addresses on the suppress list.
|
// SuppressList returns all reporting addresses on the suppress list.
|
||||||
func SuppressList(ctx context.Context) ([]TLSRPTSuppressAddress, error) {
|
func SuppressList(ctx context.Context) ([]SuppressAddress, error) {
|
||||||
db, err := resultDB(ctx)
|
db, err := resultDB(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return bstore.QueryDB[TLSRPTSuppressAddress](ctx, db).SortDesc("ID").List()
|
return bstore.QueryDB[SuppressAddress](ctx, db).SortDesc("ID").List()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuppressRemove removes a reporting address record from the suppress list.
|
// SuppressRemove removes a reporting address record from the suppress list.
|
||||||
|
@ -231,7 +229,7 @@ func SuppressRemove(ctx context.Context, id int64) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.Delete(ctx, &TLSRPTSuppressAddress{ID: id})
|
return db.Delete(ctx, &SuppressAddress{ID: id})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuppressUpdate updates the until field of a reporting address record.
|
// SuppressUpdate updates the until field of a reporting address record.
|
||||||
|
@ -241,7 +239,7 @@ func SuppressUpdate(ctx context.Context, id int64, until time.Time) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ba := TLSRPTSuppressAddress{ID: id}
|
ba := SuppressAddress{ID: id}
|
||||||
err = db.Get(ctx, &ba)
|
err = db.Get(ctx, &ba)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -577,8 +577,8 @@ Period: %s - %s UTC
|
||||||
var queued bool
|
var queued bool
|
||||||
for _, rcpt := range recipients {
|
for _, rcpt := range recipients {
|
||||||
// If recipient is on suppression list, we won't queue the reporting message.
|
// If recipient is on suppression list, we won't queue the reporting message.
|
||||||
q := bstore.QueryDB[tlsrptdb.TLSRPTSuppressAddress](ctx, db)
|
q := bstore.QueryDB[tlsrptdb.SuppressAddress](ctx, db)
|
||||||
q.FilterNonzero(tlsrptdb.TLSRPTSuppressAddress{ReportingAddress: rcpt.Address.Path().String()})
|
q.FilterNonzero(tlsrptdb.SuppressAddress{ReportingAddress: rcpt.Address.Path().String()})
|
||||||
q.FilterGreater("Until", time.Now())
|
q.FilterGreater("Until", time.Now())
|
||||||
exists, err := q.Exists()
|
exists, err := q.Exists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -488,9 +488,9 @@ func TestSendReports(t *testing.T) {
|
||||||
// Suppressed addresses don't get a report.
|
// Suppressed addresses don't get a report.
|
||||||
resolver.TXT["_smtp._tls.mailhost.xn--74h.example."] = []string{"v=TLSRPTv1; rua=mailto:tls-reports1@mailhost.xn--74h.example,mailto:tls-reports2@mailhost.xn--74h.example; rua=mailto:tls-reports3@mailhost.xn--74h.example"}
|
resolver.TXT["_smtp._tls.mailhost.xn--74h.example."] = []string{"v=TLSRPTv1; rua=mailto:tls-reports1@mailhost.xn--74h.example,mailto:tls-reports2@mailhost.xn--74h.example; rua=mailto:tls-reports3@mailhost.xn--74h.example"}
|
||||||
db.Insert(ctxbg,
|
db.Insert(ctxbg,
|
||||||
&tlsrptdb.TLSRPTSuppressAddress{ReportingAddress: "tls-reports@xn--74h.example", Until: time.Now().Add(-time.Minute)}, // Expired, so ignored.
|
&tlsrptdb.SuppressAddress{ReportingAddress: "tls-reports@xn--74h.example", Until: time.Now().Add(-time.Minute)}, // Expired, so ignored.
|
||||||
&tlsrptdb.TLSRPTSuppressAddress{ReportingAddress: "tls-reports1@mailhost.xn--74h.example", Until: time.Now().Add(time.Minute)}, // Still valid.
|
&tlsrptdb.SuppressAddress{ReportingAddress: "tls-reports1@mailhost.xn--74h.example", Until: time.Now().Add(time.Minute)}, // Still valid.
|
||||||
&tlsrptdb.TLSRPTSuppressAddress{ReportingAddress: "tls-reports3@mailhost.xn--74h.example", Until: time.Now().Add(31 * 24 * time.Hour)}, // Still valid.
|
&tlsrptdb.SuppressAddress{ReportingAddress: "tls-reports3@mailhost.xn--74h.example", Until: time.Now().Add(31 * 24 * time.Hour)}, // Still valid.
|
||||||
)
|
)
|
||||||
test(tlsResults, map[string][]tlsrpt.Report{
|
test(tlsResults, map[string][]tlsrpt.Report{
|
||||||
"tls-reports@xn--74h.example": {report1},
|
"tls-reports@xn--74h.example": {report1},
|
||||||
|
|
|
@ -1603,7 +1603,7 @@ func (Admin) MTASTSPolicies(ctx context.Context) (records []mtastsdb.PolicyRecor
|
||||||
// TLSReports returns TLS reports overlapping with period start/end, for the given
|
// TLSReports returns TLS reports overlapping with period start/end, for the given
|
||||||
// policy domain (or all domains if empty). The reports are sorted first by period
|
// policy domain (or all domains if empty). The reports are sorted first by period
|
||||||
// end (most recent first), then by policy domain.
|
// end (most recent first), then by policy domain.
|
||||||
func (Admin) TLSReports(ctx context.Context, start, end time.Time, policyDomain string) (reports []tlsrptdb.TLSReportRecord) {
|
func (Admin) TLSReports(ctx context.Context, start, end time.Time, policyDomain string) (reports []tlsrptdb.Record) {
|
||||||
var polDom dns.Domain
|
var polDom dns.Domain
|
||||||
if policyDomain != "" {
|
if policyDomain != "" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -1625,7 +1625,7 @@ func (Admin) TLSReports(ctx context.Context, start, end time.Time, policyDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSReportID returns a single TLS report.
|
// TLSReportID returns a single TLS report.
|
||||||
func (Admin) TLSReportID(ctx context.Context, domain string, reportID int64) tlsrptdb.TLSReportRecord {
|
func (Admin) TLSReportID(ctx context.Context, domain string, reportID int64) tlsrptdb.Record {
|
||||||
record, err := tlsrptdb.RecordID(ctx, reportID)
|
record, err := tlsrptdb.RecordID(ctx, reportID)
|
||||||
if err == nil && record.Domain != domain {
|
if err == nil && record.Domain != domain {
|
||||||
err = bstore.ErrAbsent
|
err = bstore.ErrAbsent
|
||||||
|
@ -2384,13 +2384,13 @@ func (Admin) TLSRPTSuppressAdd(ctx context.Context, reportingAddress string, unt
|
||||||
addr, err := smtp.ParseAddress(reportingAddress)
|
addr, err := smtp.ParseAddress(reportingAddress)
|
||||||
xcheckuserf(ctx, err, "parsing reporting address")
|
xcheckuserf(ctx, err, "parsing reporting address")
|
||||||
|
|
||||||
ba := tlsrptdb.TLSRPTSuppressAddress{ReportingAddress: addr.String(), Until: until, Comment: comment}
|
ba := tlsrptdb.SuppressAddress{ReportingAddress: addr.String(), Until: until, Comment: comment}
|
||||||
err = tlsrptdb.SuppressAdd(ctx, &ba)
|
err = tlsrptdb.SuppressAdd(ctx, &ba)
|
||||||
xcheckf(ctx, err, "adding address to suppresslist")
|
xcheckf(ctx, err, "adding address to suppresslist")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSRPTSuppressList returns all reporting addresses on the suppress list.
|
// TLSRPTSuppressList returns all reporting addresses on the suppress list.
|
||||||
func (Admin) TLSRPTSuppressList(ctx context.Context) []tlsrptdb.TLSRPTSuppressAddress {
|
func (Admin) TLSRPTSuppressList(ctx context.Context) []tlsrptdb.SuppressAddress {
|
||||||
l, err := tlsrptdb.SuppressList(ctx)
|
l, err := tlsrptdb.SuppressList(ctx)
|
||||||
xcheckf(ctx, err, "listing reporting addresses in suppresslist")
|
xcheckf(ctx, err, "listing reporting addresses in suppresslist")
|
||||||
return l
|
return l
|
||||||
|
|
|
@ -2947,7 +2947,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "STSMX",
|
"Name": "STSMX",
|
||||||
"Docs": "STSMX is an allowlisted MX host name/pattern.\ntodo: find a way to name this just STSMX without getting duplicate names for \"MX\" in the sherpa api.",
|
"Docs": "MX is an allowlisted MX host name/pattern.",
|
||||||
"Fields": [
|
"Fields": [
|
||||||
{
|
{
|
||||||
"Name": "Wildcard",
|
"Name": "Wildcard",
|
||||||
|
@ -4041,7 +4041,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "TLSReportRecord",
|
"Name": "TLSReportRecord",
|
||||||
"Docs": "TLSReportRecord is a TLS report as a database record, including information\nabout the sender.\n\ntodo: should be named just Record, but it would cause a sherpa type name conflict.",
|
"Docs": "Record is a TLS report as a database record, including information\nabout the sender.",
|
||||||
"Fields": [
|
"Fields": [
|
||||||
{
|
{
|
||||||
"Name": "ID",
|
"Name": "ID",
|
||||||
|
@ -6802,7 +6802,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "TLSRPTSuppressAddress",
|
"Name": "TLSRPTSuppressAddress",
|
||||||
"Docs": "TLSRPTSuppressAddress is a reporting address for which outgoing TLS reports\nwill be suppressed for a period.",
|
"Docs": "SuppressAddress is a reporting address for which outgoing TLS reports\nwill be suppressed for a period.",
|
||||||
"Fields": [
|
"Fields": [
|
||||||
{
|
{
|
||||||
"Name": "ID",
|
"Name": "ID",
|
||||||
|
|
|
@ -221,8 +221,7 @@ export interface Policy {
|
||||||
Extensions?: Pair[] | null
|
Extensions?: Pair[] | null
|
||||||
}
|
}
|
||||||
|
|
||||||
// STSMX is an allowlisted MX host name/pattern.
|
// MX is an allowlisted MX host name/pattern.
|
||||||
// todo: find a way to name this just STSMX without getting duplicate names for "MX" in the sherpa api.
|
|
||||||
export interface STSMX {
|
export interface STSMX {
|
||||||
Wildcard: boolean // "*." wildcard, e.g. if a subdomain matches. A wildcard must match exactly one label. *.example.com matches mail.example.com, but not example.com, and not foor.bar.example.com.
|
Wildcard: boolean // "*." wildcard, e.g. if a subdomain matches. A wildcard must match exactly one label. *.example.com matches mail.example.com, but not example.com, and not foor.bar.example.com.
|
||||||
Domain: Domain
|
Domain: Domain
|
||||||
|
@ -425,10 +424,8 @@ export interface PolicyRecord {
|
||||||
PolicyText: string // Text that make up the policy, as retrieved. We didn't store this in the past. If empty, policy can be reconstructed from Policy field. Needed by TLSRPT.
|
PolicyText: string // Text that make up the policy, as retrieved. We didn't store this in the past. If empty, policy can be reconstructed from Policy field. Needed by TLSRPT.
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSReportRecord is a TLS report as a database record, including information
|
// Record is a TLS report as a database record, including information
|
||||||
// about the sender.
|
// about the sender.
|
||||||
//
|
|
||||||
// todo: should be named just Record, but it would cause a sherpa type name conflict.
|
|
||||||
export interface TLSReportRecord {
|
export interface TLSReportRecord {
|
||||||
ID: number
|
ID: number
|
||||||
Domain: string // Policy domain to which the TLS report applies. Unicode.
|
Domain: string // Policy domain to which the TLS report applies. Unicode.
|
||||||
|
@ -995,7 +992,7 @@ export interface TLSResult {
|
||||||
Results?: Result[] | null // Results is updated for each TLS attempt.
|
Results?: Result[] | null // Results is updated for each TLS attempt.
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSRPTSuppressAddress is a reporting address for which outgoing TLS reports
|
// SuppressAddress is a reporting address for which outgoing TLS reports
|
||||||
// will be suppressed for a period.
|
// will be suppressed for a period.
|
||||||
export interface TLSRPTSuppressAddress {
|
export interface TLSRPTSuppressAddress {
|
||||||
ID: number
|
ID: number
|
||||||
|
|
Loading…
Reference in a new issue