emersion / go-milter

Go library to write mail filters
BSD 2-Clause "Simplified" License
42 stars 19 forks source link

Add a milter client #3

Closed emersion closed 4 years ago

emersion commented 5 years ago

Could be used to implement a MTA

foxcpp commented 4 years ago

As a MTA implementer, I expect a flow somehow like this:

// Create new client (may maintain connection pool internally or something)
c, _ := milter.NewClient("unix", "/var/lib/whatever.sock")

// Start new session (may internally create a new connection or reuse old one)
// Argument is the "command codes" we are allowed to use.
s, _ := c.Session(milter.Conn|milter.Whatever|...)

// Provide "macro" for connection command.
s.Macro(milter.Conn, "tls_cipher", "...")
// Provide connection information.
resp, _ := s.Conn(...)
// Inspect resp and determine if we stop here or continue.

defer s.Abort() // abort in case something goes wrong
// No-op if End() below is called.

// All that stuff in envelope and header ...

// Provide HELO info, commands are silently ignored if milter does not include them in OPTNEG.
resp, _ = s.Helo(...)
// Inspect resp and determine if we stop here or continue.

// Send body chunk. 
resp, _ = s.Body([]byte{"heya"})

modify, resp, err := s.End()
// resp is the same thing as all previous ones, modify is the slice of "modification actions" MTA should apply
for _, action := range modify {
 // Inspect action and apply it.
}

Not sure about types for modify and resp, perhaps some server constructs can be reused? WDYT, in general?

foxcpp commented 4 years ago

Thought dump: It would be nice to have interoperability tests using Sendmail's libmilter.