add strict mode when parsing messages, typically enabled for incoming special-use messages like tls/dmarc reports, subjectpass emails

and pass a logger to the message parser, so problems with message parsing get
the cid logged.
This commit is contained in:
Mechiel Lukkien
2023-08-15 08:25:56 +02:00
parent f5f953b3ab
commit 34c2dcd49d
24 changed files with 312 additions and 153 deletions

View File

@ -76,7 +76,7 @@ func Generate(mailFrom smtp.Address, key []byte, tm time.Time) string {
// Verify parses "message" and checks if it includes a subjectpass token in its
// Subject header that is still valid (within "period") and signed with "key".
func Verify(r io.ReaderAt, key []byte, period time.Duration) (rerr error) {
func Verify(log *mlog.Log, r io.ReaderAt, key []byte, period time.Duration) (rerr error) {
var token string
defer func() {
@ -89,7 +89,7 @@ func Verify(r io.ReaderAt, key []byte, period time.Duration) (rerr error) {
log.Debugx("subjectpass verify result", rerr, mlog.Field("token", token), mlog.Field("period", period))
}()
p, err := message.Parse(r)
p, err := message.Parse(log, true, r)
if err != nil {
return fmt.Errorf("%w: parse message: %s", ErrMessage, err)
}

View File

@ -7,26 +7,29 @@ import (
"testing"
"time"
"github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/smtp"
)
var xlog = mlog.New("subjectpass")
func TestSubjectPass(t *testing.T) {
key := []byte("secret token")
addr, _ := smtp.ParseAddress("mox@mox.example")
sig := Generate(addr, key, time.Now())
message := fmt.Sprintf("From: <mox@mox.example>\r\nSubject: let me in %s\r\n\r\nthe message", sig)
if err := Verify(strings.NewReader(message), key, time.Hour); err != nil {
if err := Verify(xlog, strings.NewReader(message), key, time.Hour); err != nil {
t.Fatalf("verifyPassToken: %s", err)
}
if err := Verify(strings.NewReader(message), []byte("bad key"), time.Hour); err == nil {
if err := Verify(xlog, strings.NewReader(message), []byte("bad key"), time.Hour); err == nil {
t.Fatalf("verifyPassToken did not fail")
}
sig = Generate(addr, key, time.Now().Add(-time.Hour-257))
message = fmt.Sprintf("From: <mox@mox.example>\r\nSubject: let me in %s\r\n\r\nthe message", sig)
if err := Verify(strings.NewReader(message), key, time.Hour); !errors.Is(err, ErrExpired) {
if err := Verify(xlog, strings.NewReader(message), key, time.Hour); !errors.Is(err, ErrExpired) {
t.Fatalf("verifyPassToken should have expired")
}
}