author | Alberto Bertogli
<albertito@blitiri.com.ar> 2020-09-17 01:45:48 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2020-09-17 01:47:42 UTC |
parent | 1cc7b9a864ee3b60d2c477d59b04af8a065e8f0d |
chasquid.go | +1 | -1 |
internal/courier/{procmail.go => mda.go} | +10 | -11 |
internal/courier/{procmail_test.go => mda_test.go} | +9 | -9 |
internal/smtpsrv/fuzz.go | +1 | -1 |
diff --git a/chasquid.go b/chasquid.go index a1d195d..32491ba 100644 --- a/chasquid.go +++ b/chasquid.go @@ -159,7 +159,7 @@ func main() { } go stsCache.PeriodicallyRefresh(context.Background()) - localC := &courier.Procmail{ + localC := &courier.MDA{ Binary: conf.MailDeliveryAgentBin, Args: conf.MailDeliveryAgentArgs, Timeout: 30 * time.Second, diff --git a/internal/courier/procmail.go b/internal/courier/mda.go similarity index 80% rename from internal/courier/procmail.go rename to internal/courier/mda.go index b357e07..dbf36a9 100644 --- a/internal/courier/procmail.go +++ b/internal/courier/mda.go @@ -18,12 +18,11 @@ var ( errTimeout = fmt.Errorf("operation timed out") ) -// Procmail delivers local mail by executing a local binary, like procmail or -// maildrop. It is named after procmail just for reference, it works with any -// binary that: +// MDA delivers local mail by executing a local binary, like procmail or +// maildrop. It works with any binary that: // - Receives the email to deliver via stdin. // - Exits with code EX_TEMPFAIL (75) for transient issues. -type Procmail struct { +type MDA struct { Binary string // Path to the binary. Args []string // Arguments to pass. Timeout time.Duration // Timeout for each invocation. @@ -31,13 +30,13 @@ type Procmail struct { // Deliver an email. On failures, returns an error, and whether or not it is // permanent. -func (p *Procmail) Deliver(from string, to string, data []byte) (error, bool) { - tr := trace.New("Courier.Procmail", to) +func (p *MDA) Deliver(from string, to string, data []byte) (error, bool) { + tr := trace.New("Courier.MDA", to) defer tr.Finish() // Sanitize, just in case. - from = sanitizeForProcmail(from) - to = sanitizeForProcmail(to) + from = sanitizeForMDA(from) + to = sanitizeForMDA(to) tr.Debugf("%s -> %s", from, to) @@ -78,7 +77,7 @@ func (p *Procmail) Deliver(from string, to string, data []byte) (error, bool) { permanent = status.ExitStatus() != 75 } } - err = tr.Errorf("procmail failed: %v - %q", err, string(output)) + err = tr.Errorf("MDA delivery failed: %v - %q", err, string(output)) return err, permanent } @@ -86,12 +85,12 @@ func (p *Procmail) Deliver(from string, to string, data []byte) (error, bool) { return nil, false } -// sanitizeForProcmail cleans the string, removing characters that could be +// sanitizeForMDA cleans the string, removing characters that could be // problematic considering we will run an external command. // // The server does not rely on this to do substitution or proper filtering, // that's done at a different layer; this is just for defense in depth. -func sanitizeForProcmail(s string) string { +func sanitizeForMDA(s string) string { valid := func(r rune) rune { switch { case unicode.IsSpace(r), unicode.IsControl(r), diff --git a/internal/courier/procmail_test.go b/internal/courier/mda_test.go similarity index 87% rename from internal/courier/procmail_test.go rename to internal/courier/mda_test.go index 1729215..30738db 100644 --- a/internal/courier/procmail_test.go +++ b/internal/courier/mda_test.go @@ -10,11 +10,11 @@ import ( "blitiri.com.ar/go/chasquid/internal/testlib" ) -func TestProcmail(t *testing.T) { +func TestMDA(t *testing.T) { dir := testlib.MustTempDir(t) defer testlib.RemoveIfOk(t, dir) - p := Procmail{ + p := MDA{ Binary: "tee", Args: []string{dir + "/%to_user%"}, Timeout: 1 * time.Minute, @@ -31,8 +31,8 @@ func TestProcmail(t *testing.T) { } } -func TestProcmailTimeout(t *testing.T) { - p := Procmail{"/bin/sleep", []string{"1"}, 100 * time.Millisecond} +func TestMDATimeout(t *testing.T) { + p := MDA{"/bin/sleep", []string{"1"}, 100 * time.Millisecond} err, permanent := p.Deliver("from", "to@local", []byte("data")) if err != errTimeout { @@ -43,9 +43,9 @@ func TestProcmailTimeout(t *testing.T) { } } -func TestProcmailBadCommandLine(t *testing.T) { +func TestMDABadCommandLine(t *testing.T) { // Non-existent binary. - p := Procmail{"thisdoesnotexist", nil, 1 * time.Minute} + p := MDA{"thisdoesnotexist", nil, 1 * time.Minute} err, permanent := p.Deliver("from", "to", []byte("data")) if err == nil { t.Errorf("unexpected success for non-existent binary") @@ -55,7 +55,7 @@ func TestProcmailBadCommandLine(t *testing.T) { } // Incorrect arguments. - p = Procmail{"cat", []string{"--fail_unknown_option"}, 1 * time.Minute} + p = MDA{"cat", []string{"--fail_unknown_option"}, 1 * time.Minute} err, _ = p.Deliver("from", "to", []byte("data")) if err == nil { t.Errorf("unexpected success for incorrect arguments") @@ -82,7 +82,7 @@ func TestExitCode(t *testing.T) { {"../../test/util/exitcode", []string{"75"}, false}, } for _, c := range cases { - p := &Procmail{c.cmd, c.args, 5 * time.Second} + p := &MDA{c.cmd, c.args, 5 * time.Second} err, permanent := p.Deliver("from", "to", []byte("data")) if err == nil { t.Errorf("%q: pipe delivery worked, expected failure", c.cmd) @@ -116,7 +116,7 @@ func TestSanitize(t *testing.T) { {"موزهها", "موزه\u200cها"}, } for _, c := range cases { - out := sanitizeForProcmail(c.v) + out := sanitizeForMDA(c.v) if out != c.expected { t.Errorf("%q: expected %q, got %q", c.v, c.expected, out) } diff --git a/internal/smtpsrv/fuzz.go b/internal/smtpsrv/fuzz.go index 2313386..058a2bb 100644 --- a/internal/smtpsrv/fuzz.go +++ b/internal/smtpsrv/fuzz.go @@ -257,7 +257,7 @@ func init() { s.AddAddr(submissionAddr, ModeSubmission) s.AddAddr(submissionTLSAddr, ModeSubmissionTLS) - localC := &courier.Procmail{} + localC := &courier.MDA{} remoteC := &courier.SMTP{} s.InitQueue(tmpDir+"/queue", localC, remoteC) s.InitDomainInfo(tmpDir + "/domaininfo")