Upgrade to latest go-smtp

This commit is contained in:
Michal Horejsek
2020-11-20 15:44:16 +01:00
parent ca962ce5ad
commit 635e51f32f
13 changed files with 192 additions and 31 deletions

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Code generated by ./credits.sh at Fri Nov 27 09:08:56 CET 2020. DO NOT EDIT.
// Code generated by ./credits.sh at Fri Nov 27 09:23:06 CET 2020. DO NOT EDIT.
package bridge
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"

View File

@ -126,7 +126,9 @@ func (s *imapServer) ListenAndServe() {
// Stops the server.
func (s *imapServer) Close() {
_ = s.server.Close()
if err := s.server.Close(); err != nil {
log.WithError(err).Error("Failed to close the connection")
}
}
func (s *imapServer) monitorDisconnectedUsers() {
@ -139,7 +141,9 @@ func (s *imapServer) monitorDisconnectedUsers() {
disconnectUser := func(conn imapserver.Conn) {
connUser := conn.Context().User
if connUser != nil && strings.EqualFold(connUser.Username(), address) {
_ = conn.Close()
if err := conn.Close(); err != nil {
log.WithError(err).Error("Failed to close the connection")
}
}
}
s.server.ForEachConn(disconnectUser)

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Code generated by ./credits.sh at Fri Nov 27 09:08:56 CET 2020. DO NOT EDIT.
// Code generated by ./credits.sh at Fri Nov 27 09:23:06 CET 2020. DO NOT EDIT.
package importexport
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-smtp;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"
const Credits = "github.com/0xAX/notificator;github.com/Masterminds/semver/v3;github.com/ProtonMail/bcrypt;github.com/ProtonMail/crypto;github.com/ProtonMail/docker-credential-helpers;github.com/ProtonMail/go-appdir;github.com/ProtonMail/go-apple-mobileconfig;github.com/ProtonMail/go-autostart;github.com/ProtonMail/go-imap;github.com/ProtonMail/go-imap-id;github.com/ProtonMail/go-rfc5322;github.com/ProtonMail/go-vcard;github.com/ProtonMail/gopenpgp/v2;github.com/PuerkitoBio/goquery;github.com/abiosoft/ishell;github.com/abiosoft/readline;github.com/allan-simon/go-singleinstance;github.com/chzyer/logex;github.com/chzyer/test;github.com/cucumber/godog;github.com/docker/docker-credential-helpers;github.com/emersion/go-imap;github.com/emersion/go-imap-appendlimit;github.com/emersion/go-imap-idle;github.com/emersion/go-imap-move;github.com/emersion/go-imap-quota;github.com/emersion/go-imap-specialuse;github.com/emersion/go-imap-unselect;github.com/emersion/go-mbox;github.com/emersion/go-message;github.com/emersion/go-sasl;github.com/emersion/go-smtp;github.com/emersion/go-textwrapper;github.com/emersion/go-vcard;github.com/fatih/color;github.com/flynn-archive/go-shlex;github.com/getsentry/sentry-go;github.com/go-resty/resty/v2;github.com/golang/mock;github.com/google/go-cmp;github.com/google/uuid;github.com/gopherjs/gopherjs;github.com/hashicorp/go-multierror;github.com/jameskeane/bcrypt;github.com/jaytaylor/html2text;github.com/kardianos/osext;github.com/keybase/go-keychain;github.com/logrusorgru/aurora;github.com/mattn/go-runewidth;github.com/miekg/dns;github.com/myesui/uuid;github.com/nsf/jsondiff;github.com/olekukonko/tablewriter;github.com/pkg/errors;github.com/sirupsen/logrus;github.com/skratchdot/open-golang;github.com/ssor/bom;github.com/stretchr/testify;github.com/therecipe/qt;github.com/twinj/uuid;github.com/urfave/cli;go.etcd.io/bbolt;golang.org/x/crypto;golang.org/x/net;golang.org/x/text;gopkg.in/stretchr/testify.v1;;Font Awesome 4.7.0;;Qt 5.13 by Qt group;"

View File

@ -27,6 +27,7 @@ import (
"github.com/ProtonMail/proton-bridge/pkg/confirmer"
"github.com/ProtonMail/proton-bridge/pkg/listener"
goSMTPBackend "github.com/emersion/go-smtp"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@ -70,7 +71,7 @@ func newSMTPBackend(
}
// Login authenticates a user.
func (sb *smtpBackend) Login(username, password string) (goSMTPBackend.User, error) {
func (sb *smtpBackend) Login(_ *goSMTPBackend.ConnectionState, username, password string) (goSMTPBackend.Session, error) {
// Called from go-smtp in goroutines - we need to handle panics for each function.
defer sb.panicHandler.HandlePanic()
username = strings.ToLower(username)
@ -97,7 +98,14 @@ func (sb *smtpBackend) Login(username, password string) (goSMTPBackend.User, err
if user.IsCombinedAddressMode() {
addressID = ""
}
return newSMTPUser(sb.panicHandler, sb.eventListener, sb, user, addressID)
return newSMTPUser(sb.panicHandler, sb.eventListener, sb, user, username, addressID)
}
func (sb *smtpBackend) AnonymousLogin(_ *goSMTPBackend.ConnectionState) (goSMTPBackend.Session, error) {
// Called from go-smtp in goroutines - we need to handle panics for each function.
defer sb.panicHandler.HandlePanic()
return nil, errors.New("anonymous login not supported")
}
func (sb *smtpBackend) shouldReportOutgoingNoEnc() bool {

View File

@ -51,12 +51,12 @@ func NewSMTPServer(debug bool, port int, useSSL bool, tls *tls.Config, smtpBacke
s.EnableAuth(sasl.Login, func(conn *goSMTP.Conn) sasl.Server {
return sasl.NewLoginServer(func(address, password string) error {
user, err := conn.Server().Backend.Login(address, password)
user, err := conn.Server().Backend.Login(nil, address, password)
if err != nil {
return err
}
conn.SetUser(user)
conn.SetSession(user)
return nil
})
})
@ -85,14 +85,16 @@ func (s *smtpServer) ListenAndServe() {
l.Error("SMTP failed: ", err)
return
}
defer s.server.Close()
defer s.server.Close() //nolint[errcheck]
l.Info("SMTP server stopped")
}
// Stops the server.
func (s *smtpServer) Close() {
s.server.Close()
if err := s.server.Close(); err != nil {
log.WithError(err).Error("Failed to close the connection")
}
}
func (s *smtpServer) monitorDisconnectedUsers() {
@ -102,9 +104,11 @@ func (s *smtpServer) monitorDisconnectedUsers() {
for address := range ch {
log.Info("Disconnecting all open SMTP connections for ", address)
disconnectUser := func(conn *goSMTP.Conn) {
connUser := conn.User()
connUser := conn.Session()
if connUser != nil {
_ = conn.Close()
if err := conn.Close(); err != nil {
log.WithError(err).Error("Failed to close the connection")
}
}
}
s.server.ForEachConn(disconnectUser)

View File

@ -44,7 +44,11 @@ type smtpUser struct {
backend *smtpBackend
user bridgeUser
storeUser storeUserProvider
username string
addressID string
from string
to []string
}
// newSMTPUser returns struct implementing go-smtp/session interface.
@ -53,8 +57,9 @@ func newSMTPUser(
eventListener listener.Listener,
smtpBackend *smtpBackend,
user bridgeUser,
username string,
addressID string,
) (goSMTPBackend.User, error) {
) (goSMTPBackend.Session, error) {
storeUser := user.GetStore()
if storeUser == nil {
return nil, errors.New("user database is not initialized")
@ -66,6 +71,7 @@ func newSMTPUser(
backend: smtpBackend,
user: user,
storeUser: storeUser,
username: username,
addressID: addressID,
}, nil
}
@ -145,6 +151,55 @@ func (su *smtpUser) getAPIKeyData(recipient string) (apiKeys []pmapi.PublicKey,
return su.client().GetPublicKeysForEmail(recipient)
}
// Discard currently processed message.
func (su *smtpUser) Reset() {
log.Trace("Resetting the session")
su.from = ""
su.to = []string{}
}
// Set return path for currently processed message.
func (su *smtpUser) Mail(from string, opts goSMTPBackend.MailOptions) error {
log.WithField("from", from).WithField("opts", opts).Trace("Setting mail from")
// REQUIRETLS and SMTPUTF8 have to be announced to be used by client.
// Bridge does not use those extensions so this should not happen.
if opts.RequireTLS {
return errors.New("REQUIRETLS extension is not supported")
}
if opts.UTF8 {
return errors.New("SMTPUTF8 extension is not supported")
}
if opts.Auth != nil && *opts.Auth != "" && *opts.Auth != su.username {
return errors.New("changing identity is not supported")
}
su.from = from
return nil
}
// Add recipient for currently processed message.
func (su *smtpUser) Rcpt(to string) error {
log.WithField("to", to).Trace("Adding recipient")
if to != "" {
su.to = append(su.to, to)
}
return nil
}
// Set currently processed message contents and send it.
func (su *smtpUser) Data(r io.Reader) error {
log.Trace("Sending the message")
if su.from == "" {
return errors.New("missing sender")
}
if len(su.to) == 0 {
return errors.New("missing recipient")
}
return su.Send(su.from, su.to, r)
}
// Send sends an email from the given address to the given addresses with the given body.
func (su *smtpUser) Send(from string, to []string, messageReader io.Reader) (err error) { //nolint[funlen]
// Called from go-smtp in goroutines - we need to handle panics for each function.