Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update to newer emersion/go-smtp and go-sasl #4

Merged
merged 4 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 41 additions & 24 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (

dkim "github.com/emersion/go-msgauth/dkim"
smtp "github.com/emersion/go-smtp"
smtpproxy "github.com/emersion/go-smtp-proxy"
"github.com/mback2k/smtp-dkim-signer/internal/smtpproxy"
log "github.com/sirupsen/logrus"
)

Expand All @@ -56,24 +56,13 @@ type backend struct {
type sessionState struct {
Session smtp.Session

bkdvh *backendVHost
backend *backend
bkdvh *backendVHost

from string
to []string
}

func (bkdvh *backendVHost) Login(state *smtp.ConnectionState, username, password string) (smtp.Session, error) {
session, err := bkdvh.ProxyBe.Login(state, username, password)
if err != nil {
return nil, err
}
return &sessionState{Session: session, bkdvh: bkdvh}, nil
}

func (bkdvh *backendVHost) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error) {
return nil, smtp.ErrAuthRequired
}

func (s *sessionState) generateMessageID() string {
idbytes := make([]byte, 5)
idread, err := rand.Read(idbytes)
Expand Down Expand Up @@ -135,7 +124,10 @@ func (s *sessionState) Reset() {
s.Session.Reset()
}

func (s *sessionState) Mail(from string, opts smtp.MailOptions) error {
func (s *sessionState) Mail(from string, opts *smtp.MailOptions) error {
if s.Session == nil {
return smtp.ErrAuthRequired
}
err := s.Session.Mail(from, opts)
if err != nil {
return err
Expand All @@ -145,6 +137,9 @@ func (s *sessionState) Mail(from string, opts smtp.MailOptions) error {
}

func (s *sessionState) Rcpt(to string) error {
if s.Session == nil {
return smtp.ErrAuthRequired
}
err := s.Session.Rcpt(to)
if err != nil {
return err
Expand All @@ -158,6 +153,10 @@ func (s *sessionState) Rcpt(to string) error {
}

func (s *sessionState) Data(r io.Reader) error {
if s.Session == nil {
return smtp.ErrAuthRequired
}

id := s.generateMessageID()
log.WithField("message", id).Infof("Handling message %s from %s to %s", id, s.from, s.to)

Expand All @@ -174,28 +173,46 @@ func (s *sessionState) Data(r io.Reader) error {
}

func (s *sessionState) Logout() error {
if s.Session == nil {
return smtp.ErrAuthRequired
}
s.Reset()
return s.Session.Logout()
}

func (bkd *backend) Login(state *smtp.ConnectionState, username, password string) (smtp.Session, error) {
func (bkd *backend) NewSession(state *smtp.Conn) (smtp.Session, error) {
return &sessionState{
backend: bkd,
// Session and bkdvh are filled in on successful AuthPlain().
}, nil
}

func (s *sessionState) AuthPlain(username, password string) error {
splits := strings.Split(username, "@")
if len(splits) < 1 {
return nil, ErrAuthFailed
return ErrAuthFailed
}
domain := splits[len(splits)-1]
if len(domain) < 1 {
return nil, ErrAuthFailed
return ErrAuthFailed
}
bkdvh, found := bkd.VHosts[domain]
bkdvh, found := s.backend.VHosts[domain]
if !found {
return nil, ErrAuthFailed
log.Infof("Auth failed: domain %q not found", domain)
return ErrAuthFailed
}
s.bkdvh = bkdvh

session, err := bkdvh.ProxyBe.NewSession(nil)
if err != nil {
return err
}
if err := session.AuthPlain(username, password); err != nil {
return err
}
return bkdvh.Login(state, username, password)
}

func (bkd *backend) AnonymousLogin(state *smtp.ConnectionState) (smtp.Session, error) {
return nil, smtp.ErrAuthRequired
s.Session = session
return nil
}

func makeBackend(cfg *config) (*backend, error) {
Expand Down
6 changes: 6 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ type configAcmeLe struct {
ChallengePort int
}

type configTLS struct {
CertPath string
KeyPath string
}

type configVHost struct {
Domain string
Upstream string
Expand All @@ -64,6 +69,7 @@ type config struct {
Domain string
UseSMTPS bool
LetsEncrypt *configAcmeLe
TLS *configTLS
ReadTimeout time.Duration
WriteTimeout time.Duration
MaxMessageBytes int
Expand Down
3 changes: 3 additions & 0 deletions dkim.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ func loadPrivKey(privkeypath string) (*rsa.PrivateKey, error) {
if err != nil {
return nil, err
}
if err := key.Validate(); err != nil {
return nil, err
}
return key, err
}

Expand Down
55 changes: 33 additions & 22 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
module github.com/mback2k/smtp-dkim-signer

go 1.12
go 1.20

require (
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/emersion/go-msgauth v0.4.0
github.com/emersion/go-sasl v0.0.0-20191210011802-430746ea8b9b
github.com/emersion/go-smtp v0.12.1
github.com/emersion/go-smtp-proxy v0.0.0-20200210193521-e8e7dd723514
github.com/heroku/rollrus v0.1.1
github.com/klauspost/cpuid v1.2.3 // indirect
github.com/emersion/go-msgauth v0.6.6
github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead
github.com/emersion/go-smtp v0.16.1-0.20230409084921-7bfb069c5a7d
github.com/heroku/rollrus v0.2.0
github.com/mholt/certmagic v0.9.3
github.com/miekg/dns v1.1.27 // indirect
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/rollbar/rollbar-go v1.4.5
github.com/rollbar/rollbar-go/errors v0.0.0-20220927065624-ed38c7c74ef6
github.com/sirupsen/logrus v1.9.2
github.com/spf13/viper v1.15.0
)

require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-acme/lego/v3 v3.9.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/klauspost/cpuid v1.3.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/miekg/dns v1.1.54 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rollbar/rollbar-go v1.2.0
github.com/rollbar/rollbar-go/errors v0.0.0-20191126182519-4b2c800372e7
github.com/sirupsen/logrus v1.4.2
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678 // indirect
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
gopkg.in/ini.v1 v1.52.0 // indirect
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/tools v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading