From 8a6c86644e6d73421e325c937916cefe7495bc38 Mon Sep 17 00:00:00 2001 From: Dmitry Azhichakov Date: Thu, 12 Feb 2015 18:54:51 +0300 Subject: [PATCH 1/3] New feature: SMTP connection may use client certificate. New config keys in [mailer] section: - CERT_FILE: path to a certificate file. - KEY_FILE: path to a key file. --- modules/mailer/mailer.go | 6 ++++++ modules/setting/setting.go | 13 ++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go index 6a23e5d09ea1..792e44354380 100644 --- a/modules/mailer/mailer.go +++ b/modules/mailer/mailer.go @@ -72,9 +72,15 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte) return err } + cert, err := tls.LoadX509KeyPair(settings.CertFile, settings.KeyFile) + if err != nil { + return err + } + tlsconfig := &tls.Config{ InsecureSkipVerify: settings.SkipVerify, ServerName: host, + Certificates: []tls.Certificate{cert}, } conn, err := net.Dial("tcp", net.JoinHostPort(host, port)) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index d71a8cda555e..cf19b1aa8be4 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -446,11 +446,12 @@ func newSessionService() { // Mailer represents mail service. type Mailer struct { - Name string - Host string - From string - User, Passwd string - SkipVerify bool + Name string + Host string + From string + User, Passwd string + SkipVerify bool + CertFile, KeyFile string } type OauthInfo struct { @@ -483,6 +484,8 @@ func newMailService() { User: sec.Key("USER").String(), Passwd: sec.Key("PASSWD").String(), SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), + CertFile: sec.Key("CERT_FILE").String(), + KeyFile: sec.Key("KEY_FILE").String(), } MailService.From = sec.Key("FROM").MustString(MailService.User) log.Info("Mail Service Enabled") From 3aaf292ba8c222003048e695bf9b9ec43191ff01 Mon Sep 17 00:00:00 2001 From: Dmitry Azhichakov Date: Fri, 13 Feb 2015 10:33:55 +0300 Subject: [PATCH 2/3] Fix "forcing" client certificate for SMTP --- conf/app.ini | 4 ++++ modules/mailer/mailer.go | 14 ++++++++------ modules/setting/setting.go | 16 +++++++++------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/conf/app.ini b/conf/app.ini index e80d77a9ca5b..6a7c67ca073f 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -105,6 +105,10 @@ SUBJECT = %(APP_NAME)s HOST = ; Do not verify the certificate of the server. Only use this for self-signed certificates SKIP_VERIFY = +; Use client certificate +; USE_CERTIFICATE = true +; CERT_FILE = custom/mailer/cert.pem +; KEY_FILE = custom/mailer/key.pem ; Mail from address, RFC 5322. This can be just an email address, or the "Name" format FROM = ; Mailer user name and password diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go index 792e44354380..f658427c1a91 100644 --- a/modules/mailer/mailer.go +++ b/modules/mailer/mailer.go @@ -72,15 +72,17 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte) return err } - cert, err := tls.LoadX509KeyPair(settings.CertFile, settings.KeyFile) - if err != nil { - return err - } - tlsconfig := &tls.Config{ InsecureSkipVerify: settings.SkipVerify, ServerName: host, - Certificates: []tls.Certificate{cert}, + } + + if settings.UseCertificate { + cert, err := tls.LoadX509KeyPair(settings.CertFile, settings.KeyFile) + if err != nil { + return err + } + tlsconfig.Certificates = []tls.Certificate{cert} } conn, err := net.Dial("tcp", net.JoinHostPort(host, port)) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index cf19b1aa8be4..32284b42361f 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -451,6 +451,7 @@ type Mailer struct { From string User, Passwd string SkipVerify bool + UseCertificate bool CertFile, KeyFile string } @@ -479,13 +480,14 @@ func newMailService() { } MailService = &Mailer{ - Name: sec.Key("NAME").MustString(AppName), - Host: sec.Key("HOST").String(), - User: sec.Key("USER").String(), - Passwd: sec.Key("PASSWD").String(), - SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), - CertFile: sec.Key("CERT_FILE").String(), - KeyFile: sec.Key("KEY_FILE").String(), + Name: sec.Key("NAME").MustString(AppName), + Host: sec.Key("HOST").String(), + User: sec.Key("USER").String(), + Passwd: sec.Key("PASSWD").String(), + SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), + UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), + CertFile: sec.Key("CERT_FILE").String(), + KeyFile: sec.Key("KEY_FILE").String(), } MailService.From = sec.Key("FROM").MustString(MailService.User) log.Info("Mail Service Enabled") From 2692d4aa49deec286058cd2196da379a97534787 Mon Sep 17 00:00:00 2001 From: Dmitry Azhichakov Date: Fri, 13 Feb 2015 11:06:12 +0300 Subject: [PATCH 3/3] Make conf/app.ini changes match the style --- conf/app.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/app.ini b/conf/app.ini index 6a7c67ca073f..6f4ae897f744 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -106,9 +106,9 @@ HOST = ; Do not verify the certificate of the server. Only use this for self-signed certificates SKIP_VERIFY = ; Use client certificate -; USE_CERTIFICATE = true -; CERT_FILE = custom/mailer/cert.pem -; KEY_FILE = custom/mailer/key.pem +USE_CERTIFICATE = false +CERT_FILE = custom/mailer/cert.pem +KEY_FILE = custom/mailer/key.pem ; Mail from address, RFC 5322. This can be just an email address, or the "Name" format FROM = ; Mailer user name and password