diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..3b551bb --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,73 @@ +linters-settings: + gocritic: + enabled-tags: + - diagnostic + - experimental + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + govet: + check-shadowing: true + misspell: + locale: US + +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck +# - funlen + - gochecknoinits + - goconst +# - gocritic + - gocyclo + - gofmt + - goimports + - golint + - gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - lll + - misspell + - nakedret +# - nolintlint + - rowserrcheck + - scopelint + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + + # don't enable: + # - asciicheck + # - gochecknoglobals + # - gocognit + # - godot + # - godox + # - goerr113 + # - maligned + # - nestif + # - prealloc + # - testpackage + # - wsl + diff --git a/.vscode/settings.json b/.vscode/settings.json index 12b2711..2e5c0da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,8 @@ { "cSpell.words": [ - "myname" + "myname", + "HELO", + "EHLO", + "gosec" ] } \ No newline at end of file diff --git a/README.md b/README.md index c941e36..0f03bd2 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ Some older appliances such as scanners, multi-function printers, RAID cards or N Run `mailrelay` on a local PC or server and set your device (e.g. scanner) to send mail to it. -`mailrelay` is written in Go, and can be compiled for any Go supported platform including Linux, MacOS, Windows. +`mailrelay` can be compiled for any Go supported platform including Linux, MacOS, Windows. ## Encryption `mailrelay` uses TLS to connect to your SMTP provider. By default implicit TLS connections are assumed, meaning the connection is established using TLS at the socket level. This is in accordance with [RFC 8314 section 3](https://tools.ietf.org/html/rfc8314#section-3). These connections usually use port 465. -However, some providers do not adhere to this recommendation (I'm looking at you Office365!) and only support the legacy STARTTLS command, which expects a non-encrypted socket connection at first, which is then upgraded to TLS. To enable this, set `smtp_starttls` to `true` in your config. +However, some providers do not adhere to this recommendation (I'm looking at you Office365!) and only support the legacy STARTTLS command, which expects a non-encrypted socket connection at first, which is then upgraded to TLS. To enable this, set `smtp_starttls` to `true` in your config. You may also need to set `smtp_login_auth_type` to `true` which enables the legacy [LOGIN authentication](https://www.ietf.org/archive/id/draft-murchison-sasl-login-00.txt) method. These connections usually use port 587. ## Testing your configuration @@ -43,6 +43,7 @@ On local PC (192.168.1.54) create file `/etc/mailrelay.json` with contents: "smtp_starttls": false, "smtp_username": "username@fastmail.com", "smtp_password": "secretAppPassword", + "smtp_login_auth_type": false, "local_listen_ip": "0.0.0.0", "local_listen_port": 2525, "allowed_hosts": ["*"] diff --git a/auth.go b/auth.go new file mode 100644 index 0000000..a711070 --- /dev/null +++ b/auth.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "net/smtp" +) + +type loginAuth struct { + username, password string +} + +// LoginAuth provides a simple implementation of LOGIN authorization of SMTP as +// described here: https://www.ietf.org/archive/id/draft-murchison-sasl-login-00.txt +func LoginAuth(username, password string) smtp.Auth { + return &loginAuth{username, password} +} + +func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { + return "LOGIN", []byte{}, nil +} + +func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { + if more { + switch string(fromServer) { + case "User Name", "Username:": + return []byte(a.username), nil + case "Password", "Password:": + return []byte(a.password), nil + default: + return nil, fmt.Errorf("unknown server response \"%s\"", string(fromServer)) + } + } + return nil, nil +} diff --git a/client.go b/client.go index eb196f9..5579a1c 100644 --- a/client.go +++ b/client.go @@ -19,7 +19,7 @@ type closeable interface { // sendMail sends the contents of the envelope to a SMTP server. func sendMail(e *mail.Envelope, config *relayConfig) error { - server := fmt.Sprintf("%s:%d", config.SMTPServer, config.SMTPPort) + server := fmt.Sprintf("%s:%d", config.Server, config.Port) to := getTo(e) var msg bytes.Buffer @@ -33,8 +33,8 @@ func sendMail(e *mail.Envelope, config *relayConfig) error { var writer io.WriteCloser tlsconfig := &tls.Config{ - InsecureSkipVerify: true, - ServerName: config.SMTPServer, + InsecureSkipVerify: config.SkipVerify, //nolint:gosec + ServerName: config.Server, } if config.STARTTLS { @@ -47,7 +47,7 @@ func sendMail(e *mail.Envelope, config *relayConfig) error { } } - if client, err = smtp.NewClient(conn, config.SMTPServer); err != nil { + if client, err = smtp.NewClient(conn, config.Server); err != nil { close(conn, "conn") return errors.Wrap(err, "newclient error") } @@ -58,15 +58,8 @@ func sendMail(e *mail.Envelope, config *relayConfig) error { } }(&shouldCloseClient) - if config.STARTTLS { - if err = client.StartTLS(tlsconfig); err != nil { - return errors.Wrap(err, "starttls error") - } - } - - auth := smtp.PlainAuth("", config.SMTPUsername, config.SMTPPassword, config.SMTPServer) - if err = client.Auth(auth); err != nil { - return errors.Wrap(err, "auth error") + if err = handshake(client, config, tlsconfig); err != nil { + return err } if err = client.Mail(e.MailFrom.String()); err != nil { @@ -98,10 +91,30 @@ func sendMail(e *mail.Envelope, config *relayConfig) error { return nil } +func handshake(client *smtp.Client, config *relayConfig, tlsConfig *tls.Config) error { + if config.STARTTLS { + if err := client.StartTLS(tlsConfig); err != nil { + return errors.Wrap(err, "starttls error") + } + } + + var auth smtp.Auth + if config.LoginAuthType { + auth = LoginAuth(config.Username, config.Password) + } else { + auth = smtp.PlainAuth("", config.Username, config.Password, config.Server) + } + + if err := client.Auth(auth); err != nil { + return errors.Wrap(err, "auth error") + } + return nil +} + func close(c closeable, what string) { err := c.Close() if err != nil { - fmt.Printf("!!!!! Error closing %s: %v\n", what, err) + fmt.Printf("Error closing %s: %v\n", what, err) } } @@ -122,8 +135,8 @@ func isQuitError(err error) bool { // getTo returns the array of email addresses in the envelope. func getTo(e *mail.Envelope) []string { var ret []string - for _, addy := range e.RcptTo { - ret = append(ret, addy.String()) + for i := range e.RcptTo { + ret = append(ret, e.RcptTo[i].String()) } return ret } diff --git a/go.mod b/go.mod index 4174e32..c03ae7e 100644 --- a/go.mod +++ b/go.mod @@ -6,12 +6,12 @@ require ( github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb // indirect github.com/flashmob/go-guerrilla v1.6.1 github.com/go-sql-driver/mysql v1.5.0 // indirect - github.com/onsi/ginkgo v1.12.0 // indirect - github.com/onsi/gomega v1.10.0 // indirect - github.com/pkg/errors v0.8.0 - github.com/sirupsen/logrus v1.0.5 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/pkg/errors v0.9.1 + github.com/sirupsen/logrus v1.6.0 // indirect github.com/stretchr/testify v1.5.1 // indirect - golang.org/x/crypto v0.0.0-20181126163421-e657309f52e7 // indirect - gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect - gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect + golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 // indirect + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect ) diff --git a/go.sum b/go.sum index 5da025e..153533d 100644 --- a/go.sum +++ b/go.sum @@ -1,58 +1,40 @@ github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb h1:UgErHX+sTKfxJ1+2IksfX2Jeb2DcSgWN0oqRTUzSg74= github.com/asaskevich/EventBus v0.0.0-20180103000110-68a521d7cbbb/go.mod h1:JS7hed4L1fj0hXcyEejnW57/7LCetXggd+vwrRnYeII= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/flashmob/go-guerrilla v0.0.0-20180822023650-1c628e503aed h1:vEVXJyIHYlQuQ/mU8+gL9xpn50OYgBsMpB/zr69aGFc= -github.com/flashmob/go-guerrilla v0.0.0-20180822023650-1c628e503aed/go.mod h1:ZT9TRggRsSY4ZVndoyx8TRUxi3tM/nOYtKWKDX94H0I= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/flashmob/go-guerrilla v1.6.1 h1:MLkqzRFUJveVAWuQ3s2MNPTAWbvXLt8EFsBoraS6qHA= github.com/flashmob/go-guerrilla v1.6.1/go.mod h1:ZT9TRggRsSY4ZVndoyx8TRUxi3tM/nOYtKWKDX94H0I= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.0 h1:Gwkk+PTu/nfOwNMtUB/mRUv0X7ewW5dO4AERT1ThVKo= -github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= -github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -golang.org/x/crypto v0.0.0-20181126163421-e657309f52e7 h1:70UTJTdHsz+jRjphEW+is2SdxjhZL1AdKsewqjYzcQU= -golang.org/x/crypto v0.0.0-20181126163421-e657309f52e7/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/mailrelay.json b/mailrelay.json index 279f8ec..778d70b 100644 --- a/mailrelay.json +++ b/mailrelay.json @@ -2,8 +2,10 @@ "smtp_server": "smtp.fastmail.com", "smtp_port": 465, "smtp_starttls": false, + "smtp_login_auth_type": false, "smtp_username": "username@fastmail.com", "smtp_password": "secret_app_password", + "smtp_skip_cert_verify": false, "local_listen_port": 2525, "local_listen_ip": "0.0.0.0", "allowed_hosts": ["*"] diff --git a/main.go b/main.go index d720ab2..99c06dd 100644 --- a/main.go +++ b/main.go @@ -15,14 +15,16 @@ import ( var Logger log.Logger type mailRelayConfig struct { - SMTPServer string `json:"smtp_server"` - SMTPPort int `json:"smtp_port"` - SMTPStartTLS bool `json:"smtp_starttls"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` - LocalListenIP string `json:"local_listen_ip"` - LocalListenPort int `json:"local_listen_port"` - AllowedHosts []string `json:"allowed_hosts"` + SMTPServer string `json:"smtp_server"` + SMTPPort int `json:"smtp_port"` + SMTPStartTLS bool `json:"smtp_starttls"` + SMTPLoginAuthType bool `json:"smtp_login_auth_type"` + SMTPUsername string `json:"smtp_username"` + SMTPPassword string `json:"smtp_password"` + SkipCertVerify bool `json:"smtp_skip_cert_verify"` + LocalListenIP string `json:"local_listen_ip"` + LocalListenPort int `json:"local_listen_port"` + AllowedHosts []string `json:"allowed_hosts"` } func main() { @@ -114,18 +116,18 @@ func sendTest(sender string, rcpt string, port int) error { return err } - writeBody := func(c *smtp.Client) error { - wc, err := conn.Data() - if err != nil { - return err - } - defer wc.Close() - _, err = fmt.Fprintf(wc, "From: %s\nSubject: Test message\n\nThis is a test email from mailrelay.\n", sender) + if err := writeBody(conn, sender); err != nil { return err } - if err := writeBody(conn); err != nil { + return conn.Quit() +} + +func writeBody(conn *smtp.Client, sender string) error { + wc, err := conn.Data() + if err != nil { return err } - - return conn.Quit() + defer wc.Close() + _, err = fmt.Fprintf(wc, "From: %s\nSubject: Test message\n\nThis is a test email from mailrelay.\n", sender) + return err } diff --git a/server.go b/server.go index e27ca9e..fd861d7 100644 --- a/server.go +++ b/server.go @@ -9,9 +9,10 @@ import ( "github.com/flashmob/go-guerrilla/mail" ) +const saveWorkersSize = 3 + // Start starts the server. func Start(appConfig *mailRelayConfig, verbose bool) (err error) { - listen := fmt.Sprintf("%s:%d", appConfig.LocalListenIP, appConfig.LocalListenPort) logLevel := "info" @@ -31,15 +32,17 @@ func Start(appConfig *mailRelayConfig, verbose bool) (err error) { cfg.Servers = append(cfg.Servers, sc) bcfg := backends.BackendConfig{ - "save_workers_size": 3, - "save_process": "HeadersParser|Header|Hasher|Debugger|MailRelay", - "log_received_mails": true, - "primary_mail_host": "homeoffice.com", - "smtp_username": appConfig.SMTPUsername, - "smtp_password": appConfig.SMTPPassword, - "smtp_server": appConfig.SMTPServer, - "smtp_port": appConfig.SMTPPort, - "smtp_starttls": appConfig.SMTPStartTLS, + "save_workers_size": saveWorkersSize, + "save_process": "HeadersParser|Header|Hasher|Debugger|MailRelay", + "log_received_mails": true, + "primary_mail_host": "homeoffice.com", + "smtp_username": appConfig.SMTPUsername, + "smtp_password": appConfig.SMTPPassword, + "smtp_server": appConfig.SMTPServer, + "smtp_port": appConfig.SMTPPort, + "smtp_starttls": appConfig.SMTPStartTLS, + "smtp_login_auth_type": appConfig.SMTPLoginAuthType, + "smtp_skip_cert_verify": appConfig.SkipCertVerify, } cfg.BackendConfig = bcfg @@ -50,11 +53,13 @@ func Start(appConfig *mailRelayConfig, verbose bool) (err error) { } type relayConfig struct { - SMTPServer string `json:"smtp_server"` - SMTPPort int `json:"smtp_port"` - STARTTLS bool `json:"smtp_starttls"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` + Server string `json:"smtp_server"` + Port int `json:"smtp_port"` + STARTTLS bool `json:"smtp_starttls"` + LoginAuthType bool `json:"smtp_login_auth_type"` + Username string `json:"smtp_username"` + Password string `json:"smtp_password"` + SkipVerify bool `json:"smtp_skip_cert_verify"` } // mailRelayProcessor decorator relays emails to another SMTP server.