From af62be378f067f9b648fdf20d249b549b7cd5874 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Sat, 29 Jan 2022 09:01:37 +0100 Subject: [PATCH] SMTP support (#146) --- README.md | 16 +++++++++- emailer/smtp.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ main.go | 25 ++++++++++++++- util/config.go | 6 ++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 emailer/smtp.go diff --git a/README.md b/README.md index dec0978..b3f213c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,9 @@ wireguard interface stats. See the `cap_add` and `network_mode` options on the d Set the `SESSION_SECRET` environment variable to a random value. -In order to sent the wireguard configuration to clients via email (using sendgrid api) set the following environment variables +In order to sent the wireguard configuration to clients via email, set the following environment variables: + +- using SendGrid API ``` SENDGRID_API_KEY: Your sendgrid api key @@ -41,6 +43,18 @@ EMAIL_FROM_ADDRESS: the email address you registered on sendgrid EMAIL_FROM_NAME: the sender's email address ``` +- using SMTP + +``` +SMTP_HOSTNAME +SMTP_PORT +SMTP_USERNAME +SMTP_PASSWORD +SMTP_AUTH_TYPE +EMAIL_FROM_ADDRESS: the sender's email address +EMAIL_FROM_NAME: the sender's name +``` + ### Using binary file Download the binary file from the release and run it with command: diff --git a/emailer/smtp.go b/emailer/smtp.go new file mode 100644 index 0000000..326fa11 --- /dev/null +++ b/emailer/smtp.go @@ -0,0 +1,81 @@ +package emailer + +import ( + "crypto/tls" + "fmt" + "time" + + mail "github.com/xhit/go-simple-mail/v2" +) + +type SmtpMail struct { + hostname string + port int + username string + password string + authType mail.AuthType + noTLSCheck bool + fromName string + from string +} + +func authType(authType string) mail.AuthType { + switch authType { + case "PLAIN": + return mail.AuthPlain + case "LOGIN": + return mail.AuthLogin + default: + return mail.AuthNone + } +} + +func NewSmtpMail(hostname string, port int, username string, password string, noTLSCheck bool, auth string, fromName, from string) *SmtpMail { + ans := SmtpMail{hostname: hostname, port: port, username: username, password: password, noTLSCheck: noTLSCheck, fromName: fromName, from: from, authType: authType(auth)} + return &ans +} + +func addressField(address string, name string) string { + if name == "" { + return address + } + return fmt.Sprintf("%s <%s>", name, address) +} + +func (o *SmtpMail) Send(toName string, to string, subject string, content string, attachments []Attachment) error { + server := mail.NewSMTPClient() + + server.Host = o.hostname + server.Port = o.port + server.Authentication = o.authType + server.Username = o.username + server.Password = o.password + server.Encryption = mail.EncryptionSTARTTLS + server.KeepAlive = false + server.ConnectTimeout = 10 * time.Second + server.SendTimeout = 10 * time.Second + + if o.noTLSCheck { + server.TLSConfig = &tls.Config{InsecureSkipVerify: true} + } + + smtpClient, err := server.Connect() + + if err != nil { + return err + } + + email := mail.NewMSG() + email.SetFrom("From "+addressField(o.from, o.fromName)). + AddTo(addressField(to, toName)). + SetSubject(subject). + SetBody(mail.TextHTML, content) + + for _, v := range attachments { + email.Attach(&mail.File{Name: v.Name, Data: v.Data}) + } + + err = email.Send(smtpClient) + + return err +} diff --git a/go.mod b/go.mod index fb535fe..918d704 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/sendgrid/rest v2.6.4+incompatible // indirect github.com/sendgrid/sendgrid-go v3.10.0+incompatible github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 + github.com/xhit/go-simple-mail/v2 v2.10.0 golang.zx2c4.com/wireguard v0.0.20200121 // indirect golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c gopkg.in/go-playground/assert.v1 v1.2.1 // indirect diff --git a/go.sum b/go.sum index b31de99..206090f 100644 --- a/go.sum +++ b/go.sum @@ -147,6 +147,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4= github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8= +github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/main.go b/main.go index 8cf5dc9..99e0460 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,12 @@ var ( // configuration variables flagDisableLogin bool = false flagBindAddress string = "0.0.0.0:5000" + flagSmtpHostname string = "127.0.0.1" + flagSmtpPort int = 25 + flagSmtpUsername string + flagSmtpPassword string + flagSmtpAuthType string = "None" + flagSmtpNoTLSCheck bool = false flagSendgridApiKey string flagEmailFrom string flagEmailFromName string = "WireGuard UI" @@ -45,6 +51,12 @@ func init() { // command-line flags and env variables flag.BoolVar(&flagDisableLogin, "disable-login", util.LookupEnvOrBool("DISABLE_LOGIN", flagDisableLogin), "Disable authentication on the app. This is potentially dangerous.") flag.StringVar(&flagBindAddress, "bind-address", util.LookupEnvOrString("BIND_ADDRESS", flagBindAddress), "Address:Port to which the app will be bound.") + flag.StringVar(&flagSmtpHostname, "smtp-hostname", util.LookupEnvOrString("SMTP_HOSTNAME", flagSmtpHostname), "SMTP Hostname") + flag.IntVar(&flagSmtpPort, "smtp-port", util.LookupEnvOrInt("SMTP_PORT", flagSmtpPort), "SMTP Port") + flag.StringVar(&flagSmtpUsername, "smtp-username", util.LookupEnvOrString("SMTP_USERNAME", flagSmtpUsername), "SMTP Password") + flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword), "SMTP Password") + flag.BoolVar(&flagSmtpNoTLSCheck, "smtp-no-tls-check", util.LookupEnvOrBool("SMTP_NO_TLS_CHECK", flagSmtpNoTLSCheck), "Disable TLS verification for SMTP. This is potentially dangerous.") + flag.StringVar(&flagSmtpAuthType, "smtp-auth-type", util.LookupEnvOrString("SMTP_AUTH_TYPE", flagSmtpAuthType), "SMTP Auth Type : Plain or None.") flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey), "Your sendgrid api key.") flag.StringVar(&flagEmailFrom, "email-from", util.LookupEnvOrString("EMAIL_FROM_ADDRESS", flagEmailFrom), "'From' email address.") flag.StringVar(&flagEmailFromName, "email-from-name", util.LookupEnvOrString("EMAIL_FROM_NAME", flagEmailFromName), "'From' email name.") @@ -54,6 +66,12 @@ func init() { // update runtime config util.DisableLogin = flagDisableLogin util.BindAddress = flagBindAddress + util.SmtpHostname = flagSmtpHostname + util.SmtpPort = flagSmtpPort + util.SmtpUsername = flagSmtpUsername + util.SmtpPassword = flagSmtpPassword + util.SmtpAuthType = flagSmtpAuthType + util.SmtpNoTLSCheck = flagSmtpNoTLSCheck util.SendgridApiKey = flagSendgridApiKey util.EmailFrom = flagEmailFrom util.EmailFromName = flagEmailFromName @@ -103,7 +121,12 @@ func main() { app.POST("/login", handler.Login(db)) } - sendmail := emailer.NewSendgridApiMail(util.SendgridApiKey, util.EmailFromName, util.EmailFrom) + var sendmail emailer.Emailer + if util.SendgridApiKey != "" { + sendmail = emailer.NewSendgridApiMail(util.SendgridApiKey, util.EmailFromName, util.EmailFrom) + } else { + sendmail = emailer.NewSmtpMail(util.SmtpHostname, util.SmtpPort, util.SmtpUsername, util.SmtpPassword, util.SmtpNoTLSCheck, util.SmtpAuthType, util.EmailFromName, util.EmailFrom) + } app.GET("/_health", handler.Health()) app.GET("/logout", handler.Logout(), handler.ValidSession) diff --git a/util/config.go b/util/config.go index acdb720..80cbc9c 100644 --- a/util/config.go +++ b/util/config.go @@ -4,6 +4,12 @@ package util var ( DisableLogin bool BindAddress string + SmtpHostname string + SmtpPort int + SmtpUsername string + SmtpPassword string + SmtpNoTLSCheck bool + SmtpAuthType string SendgridApiKey string EmailFrom string EmailFromName string