Wrap email errs (#884)

* wrap errors returned by SMTP client

* remove client hello
This commit is contained in:
Victor Vrantchan 2017-01-10 23:56:32 -05:00 committed by GitHub
parent efca0947ec
commit f276ff3d90

View File

@ -7,6 +7,7 @@ import (
"net/smtp"
"github.com/kolide/kolide-ose/server/kolide"
"github.com/pkg/errors"
)
func NewService() kolide.MailService {
@ -27,11 +28,17 @@ type sender interface {
func Test(mailer kolide.MailService, e kolide.Email) error {
mailBody, err := getMessageBody(e)
if err != nil {
return err
return errors.Wrap(err, "failed to get message body")
}
if svc, ok := mailer.(sender); ok {
return svc.sendMail(e, mailBody)
svc, ok := mailer.(sender)
if !ok {
return nil
}
err = svc.sendMail(e, mailBody)
if err != nil {
return errors.Wrap(err, "sending mail")
}
return nil
@ -45,7 +52,7 @@ const (
func getMessageBody(e kolide.Email) ([]byte, error) {
body, err := e.Mailer.Message()
if err != nil {
return nil, err
return nil, errors.Wrap(err, "get mailer message")
}
mime := `MIME-version: 1.0;` + "\r\n"
content := `Content-Type: text/html; charset="UTF-8";` + "\r\n"
@ -74,31 +81,42 @@ func (m mailService) SendEmail(e kolide.Email) error {
return m.sendMail(e, msg)
}
func smtpAuth(e kolide.Email) (smtp.Auth, error) {
if e.Config.SMTPAuthenticationType != kolide.AuthTypeUserNamePassword {
return nil, nil
}
var auth smtp.Auth
switch e.Config.SMTPAuthenticationMethod {
case kolide.AuthMethodCramMD5:
auth = smtp.CRAMMD5Auth(e.Config.SMTPUserName, e.Config.SMTPPassword)
case kolide.AuthMethodPlain:
auth = smtp.PlainAuth("", e.Config.SMTPUserName, e.Config.SMTPPassword, e.Config.SMTPServer)
default:
return nil, fmt.Errorf("unknown SMTP auth type '%d'", e.Config.SMTPAuthenticationMethod)
}
return auth, nil
}
func (m mailService) sendMail(e kolide.Email, msg []byte) error {
smtpHost := fmt.Sprintf("%s:%d", e.Config.SMTPServer, e.Config.SMTPPort)
var auth smtp.Auth
if e.Config.SMTPAuthenticationType == kolide.AuthTypeUserNamePassword {
switch e.Config.SMTPAuthenticationMethod {
case kolide.AuthMethodCramMD5:
auth = smtp.CRAMMD5Auth(e.Config.SMTPUserName, e.Config.SMTPPassword)
return smtp.SendMail(smtpHost, auth, e.Config.SMTPSenderAddress, e.To, msg)
case kolide.AuthMethodPlain:
auth = smtp.PlainAuth("", e.Config.SMTPUserName, e.Config.SMTPPassword, e.Config.SMTPServer)
default:
return fmt.Errorf("Unknown SMTP auth type '%d'", e.Config.SMTPAuthenticationMethod)
}
} else {
auth = nil
auth, err := smtpAuth(e)
if err != nil {
return errors.Wrap(err, "failed to get smtp auth")
}
if e.Config.SMTPAuthenticationMethod == kolide.AuthMethodCramMD5 {
err = smtp.SendMail(smtpHost, auth, e.Config.SMTPSenderAddress, e.To, msg)
if err != nil {
return errors.Wrap(err, "failed to send mail. cramd5 auth method")
}
return nil
}
client, err := smtp.Dial(smtpHost)
if err != nil {
return err
return errors.Wrap(err, "could not dial smtp host")
}
defer client.Close()
if err = client.Hello(""); err != nil {
return err
}
if e.Config.SMTPEnableStartTLS {
if ok, _ := client.Extension("STARTTLS"); ok {
config := &tls.Config{
@ -106,30 +124,34 @@ func (m mailService) sendMail(e kolide.Email, msg []byte) error {
InsecureSkipVerify: !e.Config.SMTPVerifySSLCerts,
}
if err = client.StartTLS(config); err != nil {
return err
return errors.Wrap(err, "startTLS error")
}
}
}
if auth != nil {
if err = client.Auth(auth); err != nil {
return err
return errors.Wrap(err, "client auth error")
}
}
if err = client.Mail(e.Config.SMTPSenderAddress); err != nil {
return err
return errors.Wrap(err, "could not issue mail to provided address")
}
for _, recip := range e.To {
if err = client.Rcpt(recip); err != nil {
return err
return errors.Wrap(err, "failed to get recipient")
}
}
writer, err := client.Data()
if err != nil {
return nil
return errors.Wrap(err, "getting client data")
}
_, err = writer.Write(msg)
if err = writer.Close(); err != nil {
return err
return errors.Wrap(err, "failed to close writer")
}
return client.Quit()
if err := client.Quit(); err != nil {
return errors.Wrap(err, "error on client quit")
}
return nil
}