diff --git a/go.mod b/go.mod index a4ef76f..a49542e 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/emersion/go-imap v1.2.1 github.com/emersion/go-mbox v1.0.3 github.com/emersion/go-message v0.16.0 - github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac // indirect - github.com/emersion/go-smtp v0.15.0 + github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead // indirect + github.com/emersion/go-smtp v0.18.0 github.com/emersion/go-vcard v0.0.0-20220507122617-d4056df0ec4a github.com/emersion/go-webdav v0.3.2-0.20220524091811-5d845721d8f7 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 diff --git a/go.sum b/go.sum index 3eb505e..2f0b044 100644 --- a/go.sum +++ b/go.sum @@ -18,10 +18,10 @@ github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwd github.com/emersion/go-message v0.16.0 h1:uZLz8ClLv3V5fSFF/fFdW9jXjrZkXIpE1Fn8fKx7pO4= github.com/emersion/go-message v0.16.0/go.mod h1:pDJDgf/xeUIF+eicT6B/hPX/ZbEorKkUMPOxrPVG2eQ= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac h1:tn/OQ2PmwQ0XFVgAHfjlLyqMewry25Rz7jWnVoh4Ggs= -github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-smtp v0.15.0 h1:3+hMGMGrqP/lqd7qoxZc1hTU8LY8gHV9RFGWlqSDmP8= -github.com/emersion/go-smtp v0.15.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead h1:fI1Jck0vUrXT8bnphprS1EoVRe2Q5CKCX8iDlpqjQ/Y= +github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-smtp v0.18.0 h1:lrVQqB0JdxYjC8CsBt55pSwB756bRRN6vK0DSr0pXfM= +github.com/emersion/go-smtp v0.18.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emersion/go-vcard v0.0.0-20191221110513-5f81fa0d3cc7/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= diff --git a/smtp/smtp.go b/smtp/smtp.go index 69caddd..6df1006 100644 --- a/smtp/smtp.go +++ b/smtp/smtp.go @@ -367,29 +367,64 @@ func SendMail(c *protonmail.Client, u *protonmail.User, privateKeys openpgp.Enti } type session struct { - c *protonmail.Client - u *protonmail.User - privateKeys openpgp.EntityList - addrs []*protonmail.Address + be *backend + + c *protonmail.Client + u *protonmail.User + privateKeys openpgp.EntityList + addrs []*protonmail.Address + allReceivers []string } -func (s *session) Mail(from string, options smtp.MailOptions) error { +func (s *session) AuthPlain(username, password string) error { + c, privateKeys, err := s.be.sessions.Auth(username, password) + if err != nil { + return err + } + + u, err := c.GetCurrentUser() + if err != nil { + return err + } + + addrs, err := c.ListAddresses() + if err != nil { + return err + } + + // TODO: decrypt private keys in u.Addresses + + log.Printf("%s logged in", username) + s.c = c + s.u = u + s.privateKeys = privateKeys + s.addrs = addrs return nil } -func (s *session) Rcpt(to string) error { +func (s *session) Mail(from string, options *smtp.MailOptions) error { + if s.c == nil { + return smtp.ErrAuthRequired + } + return nil +} + +func (s *session) Rcpt(to string, options *smtp.RcptOptions) error { + if s.c == nil { + return smtp.ErrAuthRequired + } if to == "" { return nil } - - // Seems like github.com/emersion/go-smtp/conn.go:487 removes marks on message - // "to" is added into allReceivers blindly s.allReceivers = append(s.allReceivers, to) return nil } func (s *session) Data(r io.Reader) error { + if s.c == nil { + return smtp.ErrAuthRequired + } return SendMail(s.c, s.u, s.privateKeys, s.addrs, s.allReceivers, r) } @@ -398,10 +433,7 @@ func (s *session) Reset() { } func (s *session) Logout() error { - s.c = nil - s.u = nil - s.privateKeys = nil - s.allReceivers = nil + *s = session{be: s.be} return nil } @@ -409,36 +441,8 @@ type backend struct { sessions *auth.Manager } -func (be *backend) Login(_ *smtp.ConnectionState, username, password string) (smtp.Session, error) { - c, privateKeys, err := be.sessions.Auth(username, password) - if err != nil { - return nil, err - } - - u, err := c.GetCurrentUser() - if err != nil { - return nil, err - } - - addrs, err := c.ListAddresses() - if err != nil { - return nil, err - } - - // TODO: decrypt private keys in u.Addresses - - log.Printf("%s logged in", username) - - return &session{ - c: c, - u: u, - privateKeys: privateKeys, - addrs: addrs, - }, nil -} - -func (be *backend) AnonymousLogin(_ *smtp.ConnectionState) (smtp.Session, error) { - return nil, smtp.ErrAuthRequired +func (be *backend) NewSession(_ *smtp.Conn) (smtp.Session, error) { + return &session{be: be}, nil } func New(sessions *auth.Manager) smtp.Backend {