diff -up ssmtp-2.64/ssmtp.c.old ssmtp-2.64/ssmtp.c
--- ssmtp-2.64/ssmtp.c.old 2012-10-13 06:39:35.933898733 +0300
+++ ssmtp-2.64/ssmtp.c 2012-10-13 06:47:44.840337301 +0300
@@ -69,7 +69,10 @@ char *minus_F = (char)NULL;
char *gecos;
char *prog = (char)NULL;
char *root = NULL;
-char *tls_cert = "/etc/ssl/certs/ssmtp.pem"; /* Default Certificate */
+char *tls_cert = "/etc/pki/tls/private/ssmtp.pem"; /* Default Certificate */
+char *tls_key = "/etc/pki/tls/private/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 */
@@ -1084,6 +1087,33 @@ bool_t read_config()
log_event(LOG_INFO, "Set TLSCert=\"%s\"\n", tls_cert);
}
}
+ else if(strcasecmp(p, "TLSKey") == 0) {
+ if((tls_key = strdup(q)) == (char *)NULL) {
+ die("parse_config() -- strdup() failed");
+ }
+
+ if(log_level > 0) {
+ log_event(LOG_INFO, "Set TLSKey=\"%s\"\n", 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) {
@@ -1167,6 +1197,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 */
@@ -1189,7 +1221,7 @@ int smtp_open(char *host, int port)
return(-1);
}
- if(SSL_CTX_use_PrivateKey_file(ctx, tls_cert, SSL_FILETYPE_PEM) <= 0) {
+ if(SSL_CTX_use_PrivateKey_file(ctx, tls_key, SSL_FILETYPE_PEM) <= 0) {
perror("Use PrivateKey");
return(-1);
}
@@ -1198,6 +1230,17 @@ int smtp_open(char *host, int port)
log_event(LOG_ERR, "Private key does not match the certificate public key\n");
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
@@ -1302,14 +1345,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);
}
@@ -1323,8 +1372,6 @@ int smtp_open(char *host, int port)
return(-1);
}
X509_free(server_cert);
-
- /* TODO: Check server cert if changed! */
}
#endif
diff -up ssmtp-2.64/ssmtp.conf.5.old ssmtp-2.64/ssmtp.conf.5
--- ssmtp-2.64/ssmtp.conf.5.old 2008-02-29 04:50:15.000000000 +0200
+++ ssmtp-2.64/ssmtp.conf.5 2012-10-13 06:41:31.098787606 +0300
@@ -53,6 +53,13 @@ See RFC 2487.
.Pp
.It Cm TLSCert
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.
+.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.
diff -up ssmtp-2.64/TLS.old ssmtp-2.64/TLS
--- ssmtp-2.64/TLS.old 2004-04-23 15:32:07.000000000 +0300
+++ ssmtp-2.64/TLS 2012-10-13 06:41:31.098787606 +0300
@@ -26,9 +26,13 @@ Set this to yes to make ssmtp identify i
TLSCert=<file>
Specify which certificate file should be used.
+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.
-* Diffrent Certificate and Key file?
+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.