forked from Silverfish/proton-bridge
Upgrade to latest go-smtp
This commit is contained in:
3
go.mod
3
go.mod
@ -6,7 +6,6 @@ go 1.13
|
|||||||
// They are in a separate require block to highlight this.
|
// They are in a separate require block to highlight this.
|
||||||
require (
|
require (
|
||||||
github.com/docker/docker-credential-helpers v0.6.3
|
github.com/docker/docker-credential-helpers v0.6.3
|
||||||
github.com/emersion/go-smtp v0.0.0-20180712174835-db5eec195e67
|
|
||||||
github.com/jameskeane/bcrypt v0.0.0-20170924085257-7509ea014998
|
github.com/jameskeane/bcrypt v0.0.0-20170924085257-7509ea014998
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||||
)
|
)
|
||||||
@ -38,6 +37,7 @@ require (
|
|||||||
github.com/emersion/go-mbox v1.0.2
|
github.com/emersion/go-mbox v1.0.2
|
||||||
github.com/emersion/go-message v0.12.1-0.20200903165315-e1abe21f389a
|
github.com/emersion/go-message v0.12.1-0.20200903165315-e1abe21f389a
|
||||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
|
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
|
||||||
|
github.com/emersion/go-smtp v0.14.0
|
||||||
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe
|
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe
|
||||||
github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 // indirect
|
github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 // indirect
|
||||||
github.com/fatih/color v1.9.0
|
github.com/fatih/color v1.9.0
|
||||||
@ -75,7 +75,6 @@ require (
|
|||||||
replace (
|
replace (
|
||||||
github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0
|
github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0
|
||||||
github.com/emersion/go-imap => github.com/ProtonMail/go-imap v0.0.0-20201102134601-418cd74e9474
|
github.com/emersion/go-imap => github.com/ProtonMail/go-imap v0.0.0-20201102134601-418cd74e9474
|
||||||
github.com/emersion/go-smtp => github.com/ProtonMail/go-smtp v0.0.0-20181206232543-8261df20d309
|
|
||||||
github.com/jameskeane/bcrypt => github.com/ProtonMail/bcrypt v0.0.0-20170924085257-7509ea014998
|
github.com/jameskeane/bcrypt => github.com/ProtonMail/bcrypt v0.0.0-20170924085257-7509ea014998
|
||||||
golang.org/x/crypto => github.com/ProtonMail/crypto v0.0.0-20200818122824-ed5d25e28db8
|
golang.org/x/crypto => github.com/ProtonMail/crypto v0.0.0-20200818122824-ed5d25e28db8
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -94,6 +94,8 @@ github.com/emersion/go-message v0.12.1-0.20200903165315-e1abe21f389a/go.mod h1:k
|
|||||||
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k=
|
||||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||||
|
github.com/emersion/go-smtp v0.14.0 h1:RYW203p+EcPjL8Z/ZpT9lZ6iOc8MG1MQzEx1UKEkXlA=
|
||||||
|
github.com/emersion/go-smtp v0.14.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||||
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe h1:40SWqY0zE3qCi6ZrtTf5OUdNm5lDnGnjRSq9GgmeTrg=
|
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe h1:40SWqY0zE3qCi6ZrtTf5OUdNm5lDnGnjRSq9GgmeTrg=
|
||||||
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
||||||
github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 h1:n9qx98xiS5V4x2WIpPC2rr9mUM5ri9r/YhCEKbhCHro=
|
github.com/emersion/go-vcard v0.0.0-20190105225839-8856043f13c5 h1:n9qx98xiS5V4x2WIpPC2rr9mUM5ri9r/YhCEKbhCHro=
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// 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
|
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;"
|
||||||
|
|||||||
@ -126,7 +126,9 @@ func (s *imapServer) ListenAndServe() {
|
|||||||
|
|
||||||
// Stops the server.
|
// Stops the server.
|
||||||
func (s *imapServer) Close() {
|
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() {
|
func (s *imapServer) monitorDisconnectedUsers() {
|
||||||
@ -139,7 +141,9 @@ func (s *imapServer) monitorDisconnectedUsers() {
|
|||||||
disconnectUser := func(conn imapserver.Conn) {
|
disconnectUser := func(conn imapserver.Conn) {
|
||||||
connUser := conn.Context().User
|
connUser := conn.Context().User
|
||||||
if connUser != nil && strings.EqualFold(connUser.Username(), address) {
|
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)
|
s.server.ForEachConn(disconnectUser)
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
// 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
|
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;"
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/pkg/confirmer"
|
"github.com/ProtonMail/proton-bridge/pkg/confirmer"
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||||
goSMTPBackend "github.com/emersion/go-smtp"
|
goSMTPBackend "github.com/emersion/go-smtp"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ func newSMTPBackend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Login authenticates a user.
|
// 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.
|
// Called from go-smtp in goroutines - we need to handle panics for each function.
|
||||||
defer sb.panicHandler.HandlePanic()
|
defer sb.panicHandler.HandlePanic()
|
||||||
username = strings.ToLower(username)
|
username = strings.ToLower(username)
|
||||||
@ -97,7 +98,14 @@ func (sb *smtpBackend) Login(username, password string) (goSMTPBackend.User, err
|
|||||||
if user.IsCombinedAddressMode() {
|
if user.IsCombinedAddressMode() {
|
||||||
addressID = ""
|
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 {
|
func (sb *smtpBackend) shouldReportOutgoingNoEnc() bool {
|
||||||
|
|||||||
@ -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 {
|
s.EnableAuth(sasl.Login, func(conn *goSMTP.Conn) sasl.Server {
|
||||||
return sasl.NewLoginServer(func(address, password string) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.SetUser(user)
|
conn.SetSession(user)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -85,14 +85,16 @@ func (s *smtpServer) ListenAndServe() {
|
|||||||
l.Error("SMTP failed: ", err)
|
l.Error("SMTP failed: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer s.server.Close()
|
defer s.server.Close() //nolint[errcheck]
|
||||||
|
|
||||||
l.Info("SMTP server stopped")
|
l.Info("SMTP server stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stops the server.
|
// Stops the server.
|
||||||
func (s *smtpServer) Close() {
|
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() {
|
func (s *smtpServer) monitorDisconnectedUsers() {
|
||||||
@ -102,9 +104,11 @@ func (s *smtpServer) monitorDisconnectedUsers() {
|
|||||||
for address := range ch {
|
for address := range ch {
|
||||||
log.Info("Disconnecting all open SMTP connections for ", address)
|
log.Info("Disconnecting all open SMTP connections for ", address)
|
||||||
disconnectUser := func(conn *goSMTP.Conn) {
|
disconnectUser := func(conn *goSMTP.Conn) {
|
||||||
connUser := conn.User()
|
connUser := conn.Session()
|
||||||
if connUser != nil {
|
if connUser != nil {
|
||||||
_ = conn.Close()
|
if err := conn.Close(); err != nil {
|
||||||
|
log.WithError(err).Error("Failed to close the connection")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.server.ForEachConn(disconnectUser)
|
s.server.ForEachConn(disconnectUser)
|
||||||
|
|||||||
@ -44,7 +44,11 @@ type smtpUser struct {
|
|||||||
backend *smtpBackend
|
backend *smtpBackend
|
||||||
user bridgeUser
|
user bridgeUser
|
||||||
storeUser storeUserProvider
|
storeUser storeUserProvider
|
||||||
|
username string
|
||||||
addressID string
|
addressID string
|
||||||
|
|
||||||
|
from string
|
||||||
|
to []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSMTPUser returns struct implementing go-smtp/session interface.
|
// newSMTPUser returns struct implementing go-smtp/session interface.
|
||||||
@ -53,8 +57,9 @@ func newSMTPUser(
|
|||||||
eventListener listener.Listener,
|
eventListener listener.Listener,
|
||||||
smtpBackend *smtpBackend,
|
smtpBackend *smtpBackend,
|
||||||
user bridgeUser,
|
user bridgeUser,
|
||||||
|
username string,
|
||||||
addressID string,
|
addressID string,
|
||||||
) (goSMTPBackend.User, error) {
|
) (goSMTPBackend.Session, error) {
|
||||||
storeUser := user.GetStore()
|
storeUser := user.GetStore()
|
||||||
if storeUser == nil {
|
if storeUser == nil {
|
||||||
return nil, errors.New("user database is not initialized")
|
return nil, errors.New("user database is not initialized")
|
||||||
@ -66,6 +71,7 @@ func newSMTPUser(
|
|||||||
backend: smtpBackend,
|
backend: smtpBackend,
|
||||||
user: user,
|
user: user,
|
||||||
storeUser: storeUser,
|
storeUser: storeUser,
|
||||||
|
username: username,
|
||||||
addressID: addressID,
|
addressID: addressID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -145,6 +151,55 @@ func (su *smtpUser) getAPIKeyData(recipient string) (apiKeys []pmapi.PublicKey,
|
|||||||
return su.client().GetPublicKeysForEmail(recipient)
|
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.
|
// 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]
|
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.
|
// Called from go-smtp in goroutines - we need to handle panics for each function.
|
||||||
|
|||||||
@ -1,29 +1,29 @@
|
|||||||
Feature: SMTP auth
|
Feature: SMTP auth
|
||||||
Scenario: Ask EHLO
|
Scenario: Ask EHLO
|
||||||
Given there is connected user "user"
|
Given there is connected user "user"
|
||||||
When SMTP client sends EHLO
|
When SMTP client sends "EHLO example.com"
|
||||||
Then SMTP response is "OK"
|
Then SMTP response is "OK"
|
||||||
|
|
||||||
Scenario: Authenticates successfully and EHLO successfully
|
Scenario: Authenticates successfully and EHLO successfully
|
||||||
Given there is connected user "user"
|
Given there is connected user "user"
|
||||||
When SMTP client authenticates "user"
|
When SMTP client authenticates "user"
|
||||||
Then SMTP response is "OK"
|
Then SMTP response is "OK"
|
||||||
When SMTP client sends EHLO
|
When SMTP client sends "EHLO example.com"
|
||||||
Then SMTP response is "OK"
|
Then SMTP response is "OK"
|
||||||
|
|
||||||
Scenario: Authenticates with bad password
|
Scenario: Authenticates with bad password
|
||||||
Given there is connected user "user"
|
Given there is connected user "user"
|
||||||
When SMTP client authenticates "user" with bad password
|
When SMTP client authenticates "user" with bad password
|
||||||
Then SMTP response is "SMTP error: 454 backend/credentials: incorrect password"
|
Then SMTP response is "SMTP error: 454 4.7.0 backend/credentials: incorrect password"
|
||||||
|
|
||||||
Scenario: Authenticates with disconnected user
|
Scenario: Authenticates with disconnected user
|
||||||
Given there is disconnected user "user"
|
Given there is disconnected user "user"
|
||||||
When SMTP client authenticates "user"
|
When SMTP client authenticates "user"
|
||||||
Then SMTP response is "SMTP error: 454 account is logged out, use the app to login again"
|
Then SMTP response is "SMTP error: 454 4.7.0 account is logged out, use the app to login again"
|
||||||
|
|
||||||
Scenario: Authenticates with no user
|
Scenario: Authenticates with no user
|
||||||
When SMTP client authenticates with username "user@pm.me" and password "bridgepassword"
|
When SMTP client authenticates with username "user@pm.me" and password "bridgepassword"
|
||||||
Then SMTP response is "SMTP error: 454 user user@pm.me not found"
|
Then SMTP response is "SMTP error: 454 4.7.0 user user@pm.me not found"
|
||||||
|
|
||||||
Scenario: Authenticates with capital letter
|
Scenario: Authenticates with capital letter
|
||||||
Given there is connected user "userAddressWithCapitalLetter"
|
Given there is connected user "userAddressWithCapitalLetter"
|
||||||
@ -43,7 +43,7 @@ Feature: SMTP auth
|
|||||||
Scenario: Authenticates with more addresses - disabled address
|
Scenario: Authenticates with more addresses - disabled address
|
||||||
Given there is connected user "userMoreAddresses"
|
Given there is connected user "userMoreAddresses"
|
||||||
When SMTP client authenticates "userMoreAddresses" with address "disabled"
|
When SMTP client authenticates "userMoreAddresses" with address "disabled"
|
||||||
Then SMTP response is "SMTP error: 454 user .* not found"
|
Then SMTP response is "SMTP error: 454 4.7.0 user .* not found"
|
||||||
|
|
||||||
@ignore-live
|
@ignore-live
|
||||||
Scenario: Authenticates with secondary address of account with disabled primary address
|
Scenario: Authenticates with secondary address of account with disabled primary address
|
||||||
|
|||||||
83
test/features/bridge/smtp/init.feature
Normal file
83
test/features/bridge/smtp/init.feature
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
Feature: SMTP initiation
|
||||||
|
Scenario: Empty FROM
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
|
||||||
|
Scenario: Send without FROM and TO
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "DATA"
|
||||||
|
Then SMTP response is "SMTP error: 502 5.5.1 Missing RCPT TO command."
|
||||||
|
|
||||||
|
Scenario: Reset is the same as without FROM and TO
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<user@pm.me>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "RCPT TO:<user@pm.me>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "RSET"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "DATA"
|
||||||
|
Then SMTP response is "SMTP error: 502 5.5.1 Missing RCPT TO command"
|
||||||
|
|
||||||
|
Scenario: Send without FROM
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "RCPT TO:<user@pm.me>"
|
||||||
|
Then SMTP response is "SMTP error: 502 5.5.1 Missing MAIL FROM command."
|
||||||
|
|
||||||
|
Scenario: Send without TO
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<user@pm.me>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "DATA"
|
||||||
|
Then SMTP response is "SMTP error: 502 5.5.1 Missing RCPT TO command."
|
||||||
|
|
||||||
|
Scenario: Send with empty FROM
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "RCPT TO:<user@pm.me>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "DATA"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "hello\r\n."
|
||||||
|
Then SMTP response is "SMTP error: 554 5.0.0 Error: transaction failed, blame it on the weather: missing sender"
|
||||||
|
|
||||||
|
Scenario: Send with empty TO
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<user@pm.me>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "RCPT TO:<>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "DATA"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "hello\r\n."
|
||||||
|
Then SMTP response is "SMTP error: 554 5.0.0 Error: transaction failed, blame it on the weather: missing recipient"
|
||||||
|
|
||||||
|
Scenario: Allow BODY parameter of MAIL FROM command
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<user@pm.me> BODY=7BIT"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
|
||||||
|
Scenario: Allow AUTH parameter of MAIL FROM command
|
||||||
|
Given there is connected user "user"
|
||||||
|
When SMTP client authenticates "user"
|
||||||
|
Then SMTP response is "OK"
|
||||||
|
When SMTP client sends "MAIL FROM:<user@pm.me> AUTH=<>"
|
||||||
|
Then SMTP response is "OK"
|
||||||
@ -38,4 +38,4 @@ Feature: SMTP wrong messages
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Then SMTP response is "SMTP error: 554 Error: transaction failed, blame it on the weather: failed to create new parser: unexpected EOF"
|
Then SMTP response is "SMTP error: 554 5.0.0 Error: transaction failed, blame it on the weather: failed to create new parser: unexpected EOF"
|
||||||
|
|||||||
@ -33,10 +33,10 @@ func SMTPActionsAuthFeatureContext(s *godog.Suite) {
|
|||||||
s.Step(`^SMTP client authenticates with username "([^"]*)" and password "([^"]*)"$`, smtpClientAuthenticatesWithUsernameAndPassword)
|
s.Step(`^SMTP client authenticates with username "([^"]*)" and password "([^"]*)"$`, smtpClientAuthenticatesWithUsernameAndPassword)
|
||||||
s.Step(`^SMTP client logs out$`, smtpClientLogsOut)
|
s.Step(`^SMTP client logs out$`, smtpClientLogsOut)
|
||||||
s.Step(`^SMTP client sends message$`, smtpClientSendsMessage)
|
s.Step(`^SMTP client sends message$`, smtpClientSendsMessage)
|
||||||
s.Step(`^SMTP client sends EHLO$`, smtpClientSendsEHLO)
|
|
||||||
s.Step(`^SMTP client "([^"]*)" sends message$`, smtpClientNamedSendsMessage)
|
s.Step(`^SMTP client "([^"]*)" sends message$`, smtpClientNamedSendsMessage)
|
||||||
s.Step(`^SMTP client sends message with bcc "([^"]*)"$`, smtpClientSendsMessageWithBCC)
|
s.Step(`^SMTP client sends message with bcc "([^"]*)"$`, smtpClientSendsMessageWithBCC)
|
||||||
s.Step(`^SMTP client "([^"]*)" sends message with bcc "([^"]*)"$`, smtpClientNamedSendsMessageWithBCC)
|
s.Step(`^SMTP client "([^"]*)" sends message with bcc "([^"]*)"$`, smtpClientNamedSendsMessageWithBCC)
|
||||||
|
s.Step(`^SMTP client sends "([^"]*)"$`, smtpClientSendsCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
func smtpClientAuthenticates(bddUserID string) error {
|
func smtpClientAuthenticates(bddUserID string) error {
|
||||||
@ -93,12 +93,6 @@ func smtpClientSendsMessage(message *gherkin.DocString) error {
|
|||||||
return smtpClientNamedSendsMessage("smtp", message)
|
return smtpClientNamedSendsMessage("smtp", message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func smtpClientSendsEHLO() error {
|
|
||||||
res := ctx.GetSMTPClient("smtp").SendCommands("EHLO ateist.test")
|
|
||||||
ctx.SetSMTPLastResponse("smtp", res)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func smtpClientNamedSendsMessage(clientID string, message *gherkin.DocString) error {
|
func smtpClientNamedSendsMessage(clientID string, message *gherkin.DocString) error {
|
||||||
return smtpClientNamedSendsMessageWithBCC(clientID, "", message)
|
return smtpClientNamedSendsMessageWithBCC(clientID, "", message)
|
||||||
}
|
}
|
||||||
@ -112,3 +106,11 @@ func smtpClientNamedSendsMessageWithBCC(clientID, bcc string, message *gherkin.D
|
|||||||
ctx.SetSMTPLastResponse(clientID, res)
|
ctx.SetSMTPLastResponse(clientID, res)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func smtpClientSendsCommand(command string) error {
|
||||||
|
command = strings.ReplaceAll(command, "\\r", "\r")
|
||||||
|
command = strings.ReplaceAll(command, "\\n", "\n")
|
||||||
|
res := ctx.GetSMTPClient("smtp").SendCommands(command)
|
||||||
|
ctx.SetSMTPLastResponse("smtp", res)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -11,3 +11,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
|||||||
### Removed
|
### Removed
|
||||||
* GODT-651 Build creates proper binary names.
|
* GODT-651 Build creates proper binary names.
|
||||||
* GODT-148 Allow import (using the Import-Export app) of already encrypted messages as is.
|
* GODT-148 Allow import (using the Import-Export app) of already encrypted messages as is.
|
||||||
|
* GODT-202 Update to latest go-smtp.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* GODT-135 Support parameters in SMTP `FROM MAIL` command, such as `BODY=7BIT`, or empty value `FROM MAIL:<>` used by some clients.
|
||||||
|
|||||||
Reference in New Issue
Block a user