Skip to content

Commit

Permalink
smtp: fix bcc being ignored
Browse files Browse the repository at this point in the history
* Save all Rcpt command parameters on allReceivers
* On Data command, if bccList is empty, compare To and CC with
  allReceivers
* Receivers not referenced by To and CC are BCC
  • Loading branch information
mrvik authored and emersion committed Nov 24, 2020
1 parent 358ca10 commit 86db017
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions smtp/smtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,46 @@ func formatHeader(h mail.Header) string {
}

type session struct {
c *protonmail.Client
u *protonmail.User
privateKeys openpgp.EntityList
addrs []*protonmail.Address
c *protonmail.Client
u *protonmail.User
privateKeys openpgp.EntityList
addrs []*protonmail.Address
allReceivers []string
}

func (s *session) Mail(from string, options smtp.MailOptions) error {
return nil
}

func (s *session) Rcpt(to string) error {
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) bccFromRest(ignoreMails []*mail.Address) []*mail.Address {
ignore := make(map[string]struct{})
for _, mail := range ignoreMails {
ignore[mail.Address] = struct{}{}
}

final := make([]*mail.Address, 0, len(s.allReceivers))
for _, addr := range s.allReceivers {
if _, exists := ignore[addr]; exists {
continue
}
final = append(final, &mail.Address{
Address: addr,
})
}
return final
}

func (s *session) Data(r io.Reader) error {
// Parse the incoming MIME message header
mr, err := mail.CreateReader(r)
Expand All @@ -65,6 +91,10 @@ func (s *session) Data(r io.Reader) error {
ccList, _ := mr.Header.AddressList("Cc")
bccList, _ := mr.Header.AddressList("Bcc")

if len(bccList) == 0 {
bccList = s.bccFromRest(append(toList, ccList...))
}

if len(fromList) != 1 {
return errors.New("the From field must contain exactly one address")
}
Expand Down Expand Up @@ -353,12 +383,15 @@ func (s *session) Data(r io.Reader) error {
return nil
}

func (s *session) Reset() {}
func (s *session) Reset() {
s.allReceivers = nil
}

func (s *session) Logout() error {
s.c = nil
s.u = nil
s.privateKeys = nil
s.allReceivers = nil
return nil
}

Expand Down Expand Up @@ -386,7 +419,12 @@ func (be *backend) Login(_ *smtp.ConnectionState, username, password string) (sm

log.Printf("%s logged in", username)

return &session{c, u, privateKeys, addrs}, nil
return &session{
c: c,
u: u,
privateKeys: privateKeys,
addrs: addrs,
}, nil
}

func (be *backend) AnonymousLogin(_ *smtp.ConnectionState) (smtp.Session, error) {
Expand Down

0 comments on commit 86db017

Please sign in to comment.