Package: ssmtp Version: 2.64-5 Severity: wishlist Tags: patch The current versions of sSMTP doesn't attempt to validate the server certificate when using TLS. Without this, users authenticating over encrypted connections might unknowingly be sending their authentication information to a man in the middle.
The attached patch allows the user to configure a set of trusted authorities which can be used to validate the server (`TLS_CA_File` and `TLS_CA_Dir`). If neither configuration option is given, the current behavious (no validation) is preserved. The attached patch should be applied after my patch for bug #662959 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=662959). Trevor -- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
From d4f02531856d842cea082cd22babe9cf7e78003e Mon Sep 17 00:00:00 2001 From: W. Trevor King <wk...@drexel.edu> Date: Wed, 7 Mar 2012 10:12:43 -0500 Subject: [PATCH 3/3] Validate the server certificate when using TLS. --- TLS | 7 +++++-- ssmtp.c | 45 +++++++++++++++++++++++++++++++++++++++++---- ssmtp.conf.5 | 6 ++++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/TLS b/TLS index 74404a3..844bbd8 100644 --- a/TLS +++ b/TLS @@ -30,5 +30,8 @@ TLSKey=<file> Specify which key file should be used (can be the same as the certificate file). -TODO: -* Check server certificate for changes and notify about it. +TLS_CA_File=<file> +Optional file of trusted certificates for validating the server. + +TLS_CA_Dir=<file> +Optional directory of trusted certificates for validating the server. diff --git a/ssmtp.c b/ssmtp.c index c491cd4..85f5950 100644 --- a/ssmtp.c +++ b/ssmtp.c @@ -69,6 +69,8 @@ char *prog = (char)NULL; char *root = NULL; char *tls_cert = "/etc/ssl/certs/ssmtp.pem"; /* Default Certificate */ char *tls_key = "/etc/ssl/certs/ssmtp.pem"; /* Default private key */ +char *tls_ca_file = NULL; /* Trusted Certificate file */ +char *tls_ca_dir = NULL; /* Trusted Certificate directory */ char *uad = (char)NULL; char *config_file = (char)NULL; /* alternate configuration file */ @@ -1043,6 +1045,24 @@ bool_t read_config() log_event(LOG_INFO, "Set TLSKey=\"%s\"", tls_key); } } + else if(strcasecmp(p, "TLS_CA_File") == 0) { + if((tls_ca_file = strdup(q)) == (char *)NULL) { + die("parse_config() -- strdup() failed"); + } + + if(log_level > 0) { + log_event(LOG_INFO, "Set TLS_CA_File=\"%s\"\n", tls_ca_file); + } + } + else if(strcasecmp(p, "TLS_CA_Dir") == 0) { + if((tls_ca_dir = strdup(q)) == (char *)NULL) { + die("parse_config() -- strdup() failed"); + } + + if(log_level > 0) { + log_event(LOG_INFO, "Set TLS_CA_Dir=\"%s\"\n", tls_ca_dir); + } + } #endif /* Command-line overrides these */ else if(strcasecmp(p, "AuthUser") == 0 && !auth_user) { @@ -1126,6 +1146,8 @@ int smtp_open(char *host, int port) #ifdef HAVE_SSL int err; + long lerr; + unsigned long ulerr; char buf[(BUF_SZ + 1)]; /* Init SSL stuff */ @@ -1157,6 +1179,17 @@ int smtp_open(char *host, int port) log_event(LOG_ERR, "Private key does not match the certificate public key"); return(-1); } + + if (tls_ca_file || tls_ca_dir) { + if(!SSL_CTX_load_verify_locations(ctx, tls_ca_file, tls_ca_dir)) { + ulerr = ERR_get_error(); + log_event(LOG_ERR, "Error setting verify location: %s", + ERR_reason_error_string(ulerr)); + return(-1); + } + } + + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); } #endif @@ -1261,14 +1294,20 @@ int smtp_open(char *host, int port) ssl = SSL_new(ctx); if(!ssl) { - log_event(LOG_ERR, "SSL not working"); + ulerr = ERR_get_error(); + log_event(LOG_ERR, "SSL not working: %s", + ERR_reason_error_string(ulerr)); return(-1); } SSL_set_fd(ssl, s); err = SSL_connect(ssl); if(err < 0) { - perror("SSL_connect"); + ulerr = ERR_get_error(); + lerr = SSL_get_verify_result(ssl); + log_event(LOG_ERR, "SSL not working: %s (%ld)", + ERR_reason_error_string(ulerr), lerr); + return(-1); } @@ -1282,8 +1321,6 @@ int smtp_open(char *host, int port) return(-1); } X509_free(server_cert); - - /* TODO: Check server cert if changed! */ } #endif diff --git a/ssmtp.conf.5 b/ssmtp.conf.5 index d80a24a..d8479bc 100644 --- a/ssmtp.conf.5 +++ b/ssmtp.conf.5 @@ -57,6 +57,12 @@ The file name of an RSA certificate to use for TLS, if required. .It Cm TLSKey The file name of an RSA key to use for TLS, if required. .Pp +.It Cm TLS_CA_File +A file of trusted certificates for validating the server, if required. +.Pp +.It Cm TLS_CA_Dir +A directory of trusted certificates for validating the server, if required. +.Pp .It Cm AuthUser The user name to use for SMTP AUTH. The default is blank, in which case SMTP AUTH is not used. -- 1.7.3.4
signature.asc
Description: OpenPGP digital signature