// Package dmarcdb stores incoming DMARC aggrate reports and evaluations for outgoing aggregate reports. // // With DMARC, a domain can request reports with DMARC evaluation results to be // sent to a specified address. Mox parses such reports, stores them in its // database and makes them available through its admin web interface. Mox also // keeps track of the evaluations it does for incoming messages and sends reports // to mail servers that request reports. // // Only aggregate reports are stored and sent. Failure reports about individual // messages are not implemented. package dmarcdb import ( "context" "fmt" "os" "path/filepath" "time" "github.com/mjl-/bstore" "github.com/mjl-/mox/mlog" "github.com/mjl-/mox/mox-" ) // Init opens the databases. // // The incoming reports and evaluations for outgoing reports are in separate // databases for simpler file-based handling of the databases. func Init() error { if ReportsDB != nil || EvalDB != nil { return fmt.Errorf("already initialized") } log := mlog.New("dmarcdb", nil) var err error ReportsDB, err = openReportsDB(mox.Shutdown, log) if err != nil { return fmt.Errorf("open reports db: %v", err) } EvalDB, err = openEvalDB(mox.Shutdown, log) if err != nil { return fmt.Errorf("open eval db: %v", err) } return nil } func Close() error { if err := ReportsDB.Close(); err != nil { return fmt.Errorf("closing reports db: %w", err) } ReportsDB = nil if err := EvalDB.Close(); err != nil { return fmt.Errorf("closing eval db: %w", err) } EvalDB = nil return nil } func openReportsDB(ctx context.Context, log mlog.Log) (*bstore.DB, error) { p := mox.DataDirPath("dmarcrpt.db") os.MkdirAll(filepath.Dir(p), 0770) opts := bstore.Options{Timeout: 5 * time.Second, Perm: 0660, RegisterLogger: log.Logger} return bstore.Open(ctx, p, &opts, ReportsDBTypes...) } func openEvalDB(ctx context.Context, log mlog.Log) (*bstore.DB, error) { p := mox.DataDirPath("dmarceval.db") os.MkdirAll(filepath.Dir(p), 0770) opts := bstore.Options{Timeout: 5 * time.Second, Perm: 0660, RegisterLogger: log.Logger} return bstore.Open(ctx, p, &opts, EvalDBTypes...) }