From ee2df8dc613a0abd754291769ff0be401cc6d024 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 06:50:57 +0000 Subject: [PATCH] Bump github.com/xhit/go-simple-mail/v2 from 2.13.0 to 2.15.0 Bumps [github.com/xhit/go-simple-mail/v2](https://github.com/xhit/go-simple-mail) from 2.13.0 to 2.15.0. - [Release notes](https://github.com/xhit/go-simple-mail/releases) - [Commits](https://github.com/xhit/go-simple-mail/compare/v2.13.0...v2.15.0) --- updated-dependencies: - dependency-name: github.com/xhit/go-simple-mail/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../xhit/go-simple-mail/v2/.gitignore | 5 +- .../xhit/go-simple-mail/v2/README.md | 86 +++++++- .../xhit/go-simple-mail/v2/email.go | 185 ++++++++++++------ vendor/modules.txt | 2 +- 6 files changed, 210 insertions(+), 74 deletions(-) diff --git a/go.mod b/go.mod index 62266b6b7..7234baaa7 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/thejerf/suture/v4 v4.0.2 github.com/tus/tusd v1.10.1 github.com/urfave/cli/v2 v2.25.7 - github.com/xhit/go-simple-mail/v2 v2.13.0 + github.com/xhit/go-simple-mail/v2 v2.15.0 go-micro.dev/v4 v4.9.0 go.etcd.io/bbolt v1.3.7 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.1-0.20230608065455-5cc3715df180 diff --git a/go.sum b/go.sum index 6f8f2bfe5..069afb135 100644 --- a/go.sum +++ b/go.sum @@ -1628,8 +1628,8 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xhit/go-simple-mail/v2 v2.13.0 h1:OANWU9jHZrVfBkNkvLf8Ww0fexwpQVF/v/5f96fFTLI= -github.com/xhit/go-simple-mail/v2 v2.13.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98= +github.com/xhit/go-simple-mail/v2 v2.15.0 h1:qMXeqcZErUW/Dw6EXxmPuxHzVI8MdxWnEnu2xcisohU= +github.com/xhit/go-simple-mail/v2 v2.15.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= diff --git a/vendor/github.com/xhit/go-simple-mail/v2/.gitignore b/vendor/github.com/xhit/go-simple-mail/v2/.gitignore index 0928ac8d3..ed4498477 100644 --- a/vendor/github.com/xhit/go-simple-mail/v2/.gitignore +++ b/vendor/github.com/xhit/go-simple-mail/v2/.gitignore @@ -25,4 +25,7 @@ _testmain.go # Eclipse Project files .project -.settings \ No newline at end of file +.settings + +# Go coverage file +coverage.txt \ No newline at end of file diff --git a/vendor/github.com/xhit/go-simple-mail/v2/README.md b/vendor/github.com/xhit/go-simple-mail/v2/README.md index ad237a030..54b58c977 100644 --- a/vendor/github.com/xhit/go-simple-mail/v2/README.md +++ b/vendor/github.com/xhit/go-simple-mail/v2/README.md @@ -69,6 +69,7 @@ Go Simple Mail supports: - Add Custom Headers in Message - Send NOOP, RESET, QUIT and CLOSE to SMTP client - PLAIN, LOGIN and CRAM-MD5 Authentication (since v2.3.0) +- AUTO Authentication (since v2.14.0) - Allow connect to SMTP without authentication (since v2.10.0) - Custom TLS Configuration (since v2.5.0) - Send a RFC822 formatted message (since v2.8.0) @@ -76,12 +77,15 @@ Go Simple Mail supports: - Support text/calendar content type body (since v2.11.0) - Support add a List-Unsubscribe header (since v2.11.0) - Support to add a DKIM signarure (since v2.11.0) +- Support to send using custom connection, ideal for proxy (since v2.15.0) ## Documentation https://pkg.go.dev/github.com/xhit/go-simple-mail/v2?tab=doc -Note: by default duplicated recipients throws an error, from `v2.13.0` you can use `email.AllowDuplicateAddress = true` to avoid the check. +Note 1: by default duplicated recipients throws an error, from `v2.13.0` you can use `email.AllowDuplicateAddress = true` to avoid the check. + +Note 2: by default Bcc header is not set in email. From `v2.14.0` you can use `email.AddBccToHeader = true` to add this. ## Download @@ -99,7 +103,7 @@ package main import ( "log" - "github.com/xhit/go-simple-mail/v2" + mail "github.com/xhit/go-simple-mail/v2" "github.com/toorop/go-dkim" ) @@ -153,12 +157,13 @@ func main() { server.Password = "examplepass" server.Encryption = mail.EncryptionSTARTTLS - // Since v2.3.0 you can specified authentication type: - // - PLAIN (default) + // You can specified authentication type: + // - AUTO (default) + // - PLAIN // - LOGIN // - CRAM-MD5 // - None - // server.Authentication = mail.AuthPlain + // server.Authentication = mail.AuthAuto // Variable to keep alive connection server.KeepAlive = false @@ -265,6 +270,77 @@ func main() { } ``` +# Send with custom connection + +It's possible to use a custom connection with custom dieler, like a dialer that uses a proxy server, etc... + +With this, these servers params are ignored: `Host`, `Port`. You have total control of the connection. + +Example using a conn for proxy: + +```go +package main + +import ( + "crypto/tls" + "fmt" + "log" + "net" + + mail "github.com/xhit/go-simple-mail/v2" + "golang.org/x/net/proxy" +) + +func main() { + server := mail.NewSMTPClient() + + host := "smtp.example.com" + port := 587 + proxyAddr := "proxy.server" + + conn, err := getCustomConnWithProxy(proxyAddr, host, port) + if err != nil { + log.Fatal(err) + } + + server.Username = "test@example.com" + server.Password = "examplepass" + server.Encryption = mail.EncryptionSTARTTLS + server.CustomConn = conn + + smtpClient, err := server.Connect() + if err != nil { + log.Fatal(err) + } + + email := mail.NewMSG() + + err = email.SetFrom("From Example ").AddTo("xhit@example.com").Send(smtpClient) + if err != nil { + log.Fatal(err) + } + +} + +func getCustomConnWithProxy(proxyAddr, host string, port int) (net.Conn, error) { + dial, err := proxy.SOCKS5("tcp", proxyAddr, nil, proxy.Direct) + if err != nil { + return nil, err + } + + dialer, err := dial.Dial("tcp", fmt.Sprintf("%s:%d", host, port)) + if err != nil { + return nil, err + } + + conf := &tls.Config{ServerName: host} + conn := tls.Client(dialer, conf) + + return conn, nil +} + +``` + ## More examples See [example/example_test.go](example/example_test.go). diff --git a/vendor/github.com/xhit/go-simple-mail/v2/email.go b/vendor/github.com/xhit/go-simple-mail/v2/email.go index 4f9f6d122..c590edc07 100644 --- a/vendor/github.com/xhit/go-simple-mail/v2/email.go +++ b/vendor/github.com/xhit/go-simple-mail/v2/email.go @@ -9,6 +9,8 @@ import ( "net/mail" "net/textproto" "strconv" + "strings" + "sync" "time" "github.com/toorop/go-dkim" @@ -31,6 +33,7 @@ type Email struct { SMTPServer *smtpClient DkimMsg string AllowDuplicateAddress bool + AddBccToHeader bool } /* @@ -49,10 +52,14 @@ type SMTPServer struct { Port int KeepAlive bool TLSConfig *tls.Config + + // use custom dialer + CustomConn net.Conn } // SMTPClient represents a SMTP Client for send email type SMTPClient struct { + mu sync.Mutex Client *smtpClient KeepAlive bool SendTimeout time.Duration @@ -134,8 +141,23 @@ const ( AuthCRAMMD5 // AuthNone for SMTP servers without authentication AuthNone + // AuthAuto (default) use the first AuthType of the list of returned types supported by SMTP + AuthAuto ) +func (at AuthType) String() string { + switch at { + case AuthPlain: + return "PLAIN" + case AuthLogin: + return "LOGIN" + case AuthCRAMMD5: + return "CRAM-MD5" + default: + return "" + } +} + // NewMSG creates a new email. It uses UTF-8 by default. All charsets: http://webcheatsheet.com/HTML/character_sets_list.php func NewMSG() *Email { email := &Email{ @@ -152,7 +174,7 @@ func NewMSG() *Email { // NewSMTPClient returns the client for send email func NewSMTPClient() *SMTPServer { server := &SMTPServer{ - Authentication: AuthPlain, + Authentication: AuthAuto, Encryption: EncryptionNone, ConnectTimeout: 10 * time.Second, SendTimeout: 10 * time.Second, @@ -333,6 +355,11 @@ func (email *Email) AddAddresses(header string, addresses ...string) *Email { return email } + // add Bcc only if AddBccToHeader is true + if header == "Bcc" && email.AddBccToHeader { + email.headers.Add(header, address.String()) + } + // add all addresses to the headers except for Bcc and Return-Path if header != "Bcc" && header != "Return-Path" { // add the address to the headers @@ -687,27 +714,30 @@ func (email *Email) SendEnvelopeFrom(from string, client *SMTPClient) error { } // dial connects to the smtp server with the request encryption type -func dial(host string, port string, encryption Encryption, config *tls.Config) (*smtpClient, error) { +func dial(customConn net.Conn, host string, port string, encryption Encryption, config *tls.Config) (*smtpClient, error) { var conn net.Conn var err error + var c *smtpClient - address := host + ":" + port + if customConn != nil { + conn = customConn + } else { + address := host + ":" + port + // do the actual dial + switch encryption { + // TODO: Remove EncryptionSSL check before launch v3 + case EncryptionSSL, EncryptionSSLTLS: + conn, err = tls.Dial("tcp", address, config) + default: + conn, err = net.Dial("tcp", address) + } - // do the actual dial - switch encryption { - // TODO: Remove EncryptionSSL check before launch v3 - case EncryptionSSL, EncryptionSSLTLS: - conn, err = tls.Dial("tcp", address, config) - default: - conn, err = net.Dial("tcp", address) + if err != nil { + return nil, errors.New("Mail Error on dialing with encryption type " + encryption.String() + ": " + err.Error()) + } } - if err != nil { - return nil, errors.New("Mail Error on dialing with encryption type " + encryption.String() + ": " + err.Error()) - } - - c, err := newClient(conn, host) - + c, err = newClient(conn, host) if err != nil { return nil, fmt.Errorf("Mail Error on smtp dial: %w", err) } @@ -717,9 +747,9 @@ func dial(host string, port string, encryption Encryption, config *tls.Config) ( // smtpConnect connects to the smtp server and starts TLS and passes auth // if necessary -func smtpConnect(host, port, helo string, a auth, at AuthType, encryption Encryption, config *tls.Config) (*smtpClient, error) { +func smtpConnect(customConn net.Conn, host, port, helo string, encryption Encryption, config *tls.Config) (*smtpClient, error) { // connect to the mail server - c, err := dial(host, port, encryption, config) + c, err := dial(customConn, host, port, encryption, config) if err != nil { return nil, err @@ -746,42 +776,60 @@ func smtpConnect(host, port, helo string, a auth, at AuthType, encryption Encryp } } - // only pass authentication if defined - if at != AuthNone { - // pass the authentication if necessary - if a != nil { - if ok, _ := c.extension("AUTH"); ok { - if err = c.authenticate(a); err != nil { - c.close() - return nil, fmt.Errorf("Mail Error on Auth: %w", err) - } - } + return c, nil +} + +func (server *SMTPServer) getAuth(a string) (auth, error) { + var afn auth + switch { + case strings.Contains(a, AuthPlain.String()): + if server.Username != "" || server.Password != "" { + afn = plainAuthfn("", server.Username, server.Password, server.Host) + } + case strings.Contains(a, AuthLogin.String()): + if server.Username != "" || server.Password != "" { + afn = loginAuthfn("", server.Username, server.Password, server.Host) + } + case strings.Contains(a, AuthCRAMMD5.String()): + if server.Username != "" || server.Password != "" { + afn = cramMD5Authfn(server.Username, server.Password) + } + default: + return nil, fmt.Errorf("Mail Error on determining auth type, %s is not supported", a) + } + return afn, nil +} + +func (server *SMTPServer) validateAuth(c *smtpClient) error { + var err error + var afn auth + switch { + case server.Authentication == AuthNone || server.Username == "": + return nil + case server.Authentication != AuthAuto: + afn, err = server.getAuth(server.Authentication.String()) + if err != nil { + return err } } - - return c, nil + if ok, a := c.extension("AUTH"); ok { + // Determine Auth type automatically from extension + if afn == nil { + afn, err = server.getAuth(a) + if err != nil { + return err + } + } + if err = c.authenticate(afn); err != nil { + c.close() + return fmt.Errorf("Mail Error on Auth: %w", err) + } + } + return nil } // Connect returns the smtp client func (server *SMTPServer) Connect() (*SMTPClient, error) { - - var a auth - - switch server.Authentication { - case AuthPlain: - if server.Username != "" || server.Password != "" { - a = plainAuthfn("", server.Username, server.Password, server.Host) - } - case AuthLogin: - if server.Username != "" || server.Password != "" { - a = loginAuthfn("", server.Username, server.Password, server.Host) - } - case AuthCRAMMD5: - if server.Username != "" || server.Password != "" { - a = cramMD5Authfn(server.Username, server.Password) - } - } - var smtpConnectChannel chan error var c *smtpClient var err error @@ -795,7 +843,7 @@ func (server *SMTPServer) Connect() (*SMTPClient, error) { if server.ConnectTimeout != 0 { smtpConnectChannel = make(chan error, 2) go func() { - c, err = smtpConnect(server.Host, fmt.Sprintf("%d", server.Port), server.Helo, a, server.Authentication, server.Encryption, tlsConfig) + c, err = smtpConnect(server.CustomConn, server.Host, fmt.Sprintf("%d", server.Port), server.Helo, server.Encryption, tlsConfig) // send the result smtpConnectChannel <- err }() @@ -810,7 +858,7 @@ func (server *SMTPServer) Connect() (*SMTPClient, error) { } } else { // no ConnectTimeout, just fire the connect - c, err = smtpConnect(server.Host, fmt.Sprintf("%d", server.Port), server.Helo, a, server.Authentication, server.Encryption, tlsConfig) + c, err = smtpConnect(server.CustomConn, server.Host, fmt.Sprintf("%d", server.Port), server.Helo, server.Encryption, tlsConfig) if err != nil { return nil, err } @@ -820,26 +868,34 @@ func (server *SMTPServer) Connect() (*SMTPClient, error) { Client: c, KeepAlive: server.KeepAlive, SendTimeout: server.SendTimeout, - }, nil + }, server.validateAuth(c) } // Reset send RSET command to smtp client func (smtpClient *SMTPClient) Reset() error { + smtpClient.mu.Lock() + defer smtpClient.mu.Unlock() return smtpClient.Client.reset() } // Noop send NOOP command to smtp client func (smtpClient *SMTPClient) Noop() error { + smtpClient.mu.Lock() + defer smtpClient.mu.Unlock() return smtpClient.Client.noop() } // Quit send QUIT command to smtp client func (smtpClient *SMTPClient) Quit() error { + smtpClient.mu.Lock() + defer smtpClient.mu.Unlock() return smtpClient.Client.quit() } // Close closes the connection func (smtpClient *SMTPClient) Close() error { + smtpClient.mu.Lock() + defer smtpClient.mu.Unlock() return smtpClient.Client.close() } @@ -869,14 +925,14 @@ func send(from string, to []string, msg string, client *SMTPClient) error { if client.SendTimeout != 0 { smtpSendChannel = make(chan error, 1) - go func(from string, to []string, msg string, c *smtpClient) { - smtpSendChannel <- sendMailProcess(from, to, msg, c) - }(from, to, msg, client.Client) + go func(from string, to []string, msg string, client *SMTPClient) { + smtpSendChannel <- sendMailProcess(from, to, msg, client) + }(from, to, msg, client) } if client.SendTimeout == 0 { // no SendTimeout, just fire the sendMailProcess - return sendMailProcess(from, to, msg, client.Client) + return sendMailProcess(from, to, msg, client) } // get the send result or timeout result, which ever happens first @@ -888,35 +944,36 @@ func send(from string, to []string, msg string, client *SMTPClient) error { checkKeepAlive(client) return errors.New("Mail Error: SMTP Send timed out") } - } } return errors.New("Mail Error: No SMTP Client Provided") } -func sendMailProcess(from string, to []string, msg string, c *smtpClient) error { +func sendMailProcess(from string, to []string, msg string, c *SMTPClient) error { + c.mu.Lock() + defer c.mu.Unlock() cmdArgs := make(map[string]string) - if _, ok := c.ext["SIZE"]; ok { + if _, ok := c.Client.ext["SIZE"]; ok { cmdArgs["SIZE"] = strconv.Itoa(len(msg)) } // Set the sender - if err := c.mail(from, cmdArgs); err != nil { + if err := c.Client.mail(from, cmdArgs); err != nil { return err } // Set the recipients for _, address := range to { - if err := c.rcpt(address); err != nil { + if err := c.Client.rcpt(address); err != nil { return err } } // Send the data command - w, err := c.data() + w, err := c.Client.data() if err != nil { return err } @@ -938,9 +995,9 @@ func sendMailProcess(from string, to []string, msg string, c *smtpClient) error // check if keepAlive for close or reset func checkKeepAlive(client *SMTPClient) { if client.KeepAlive { - client.Client.reset() + client.Reset() } else { - client.Client.quit() - client.Client.close() + client.Quit() + client.Close() } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 4628f39cf..b0f8f0ab8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1686,7 +1686,7 @@ github.com/xeipuuv/gojsonpointer # github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 ## explicit github.com/xeipuuv/gojsonreference -# github.com/xhit/go-simple-mail/v2 v2.13.0 +# github.com/xhit/go-simple-mail/v2 v2.15.0 ## explicit; go 1.13 github.com/xhit/go-simple-mail/v2 # github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e