dovecot-2.0: Renamed ssl_cert_file to ssl_cert and ssl_key_file ...
dovecot at dovecot.org
dovecot at dovecot.org
Thu May 14 02:52:43 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/c38f3fb4c6b6
changeset: 9275:c38f3fb4c6b6
user: Timo Sirainen <tss at iki.fi>
date: Wed May 13 19:52:25 2009 -0400
description:
Renamed ssl_cert_file to ssl_cert and ssl_key_file to ssl_key.
Instead of pointing to files they now contain the certs directly.
diffstat:
4 files changed, 88 insertions(+), 55 deletions(-)
dovecot-example.conf | 6 -
src/login-common/login-settings.c | 26 ++------
src/login-common/login-settings.h | 4 -
src/login-common/ssl-proxy-openssl.c | 107 +++++++++++++++++++++++-----------
diffs (240 lines):
diff -r 39c2db5f1fcc -r c38f3fb4c6b6 dovecot-example.conf
--- a/dovecot-example.conf Wed May 13 19:51:34 2009 -0400
+++ b/dovecot-example.conf Wed May 13 19:52:25 2009 -0400
@@ -15,7 +15,7 @@
# or plugin settings are added by default, they're listed only as examples.
# Paths are also just examples with the real defaults being based on configure
# options. The paths listed here are for configure --prefix=/usr
-# --sysconfdir=/etc --localstatedir=/var --with-ssldir=/etc/ssl
+# --sysconfdir=/etc --localstatedir=/var
# Base directory where to store runtime data.
#base_dir = /var/run/dovecot/
@@ -93,8 +93,8 @@
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
-#ssl_cert_file = /etc/ssl/certs/dovecot.pem
-#ssl_key_file = /etc/ssl/private/dovecot.pem
+ssl_cert_file = </etc/ssl/certs/dovecot.pem
+ssl_key_file = </etc/ssl/private/dovecot.pem
# If key file is password protected, give the password here. Alternatively
# give it when starting dovecot with -p parameter. Since this file is often
diff -r 39c2db5f1fcc -r c38f3fb4c6b6 src/login-common/login-settings.c
--- a/src/login-common/login-settings.c Wed May 13 19:51:34 2009 -0400
+++ b/src/login-common/login-settings.c Wed May 13 19:52:25 2009 -0400
@@ -26,8 +26,8 @@ static struct setting_define login_setti
DEF(SET_ENUM, ssl),
DEF(SET_STR, ssl_ca_file),
- DEF(SET_STR, ssl_cert_file),
- DEF(SET_STR, ssl_key_file),
+ DEF(SET_STR, ssl_cert),
+ DEF(SET_STR, ssl_key),
DEF(SET_STR, ssl_key_password),
DEF(SET_STR, ssl_parameters_file),
DEF(SET_STR, ssl_cipher_list),
@@ -60,8 +60,8 @@ static struct login_settings login_defau
MEMBER(ssl) "yes:no:required",
MEMBER(ssl_ca_file) "",
- MEMBER(ssl_cert_file) SSLDIR"/certs/dovecot.pem",
- MEMBER(ssl_key_file) SSLDIR"/private/dovecot.pem",
+ MEMBER(ssl_cert) "",
+ MEMBER(ssl_key) "",
MEMBER(ssl_key_password) "",
MEMBER(ssl_parameters_file) "ssl-parameters.dat",
MEMBER(ssl_cipher_list) "ALL:!LOW:!SSLv2",
@@ -103,12 +103,12 @@ static int ssl_settings_check(void *_set
set->ssl);
return FALSE;
#else
- if (*set->ssl_cert_file == '\0') {
- *error_r = "ssl_cert_file not set";
+ if (*set->ssl_cert == '\0') {
+ *error_r = "ssl enabled, but ssl_cert not set";
return FALSE;
}
- if (*set->ssl_key_file == '\0') {
- *error_r = "ssl_key_file not set";
+ if (*set->ssl_key == '\0') {
+ *error_r = "ssl enabled, but ssl_key not set";
return FALSE;
}
if (set->ssl_verify_client_cert && *set->ssl_ca_file == '\0') {
@@ -117,16 +117,6 @@ static int ssl_settings_check(void *_set
}
#ifndef CONFIG_BINARY
- if (access(set->ssl_cert_file, R_OK) < 0) {
- *error_r = t_strdup_printf("ssl_cert_file: access(%s) failed: %m",
- set->ssl_cert_file);
- return FALSE;
- }
- if (access(set->ssl_key_file, R_OK) < 0) {
- *error_r = t_strdup_printf("ssl_key_file: access(%s) failed: %m",
- set->ssl_key_file);
- return FALSE;
- }
if (*set->ssl_ca_file != '\0' && access(set->ssl_ca_file, R_OK) < 0) {
*error_r = t_strdup_printf("ssl_ca_file: access(%s) failed: %m",
set->ssl_ca_file);
diff -r 39c2db5f1fcc -r c38f3fb4c6b6 src/login-common/login-settings.h
--- a/src/login-common/login-settings.h Wed May 13 19:51:34 2009 -0400
+++ b/src/login-common/login-settings.h Wed May 13 19:52:25 2009 -0400
@@ -14,8 +14,8 @@ struct login_settings {
const char *ssl;
const char *ssl_ca_file;
- const char *ssl_cert_file;
- const char *ssl_key_file;
+ const char *ssl_cert;
+ const char *ssl_key;
const char *ssl_key_password;
const char *ssl_parameters_file;
const char *ssl_cipher_list;
diff -r 39c2db5f1fcc -r c38f3fb4c6b6 src/login-common/ssl-proxy-openssl.c
--- a/src/login-common/ssl-proxy-openssl.c Wed May 13 19:51:34 2009 -0400
+++ b/src/login-common/ssl-proxy-openssl.c Wed May 13 19:52:25 2009 -0400
@@ -765,22 +765,9 @@ unsigned int ssl_proxy_get_count(void)
return ssl_proxy_count;
}
-static bool is_pem_key_file(const char *path)
-{
- char buf[4096];
- int fd, ret;
-
- /* this code is used only for giving a better error message,
- so it needs to catch only the normal key files */
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return FALSE;
- ret = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if (ret <= 0)
- return FALSE;
- buf[ret] = '\0';
- return strstr(buf, "PRIVATE KEY---") != NULL;
+static bool is_pem_key(const char *cert)
+{
+ return strstr(cert, "PRIVATE KEY---") != NULL;
}
static void
@@ -818,8 +805,60 @@ ssl_proxy_ctx_verify_client(SSL_CTX *ssl
SSL_load_client_CA_file(set->ssl_ca_file));
}
+static int
+ssl_proxy_ctx_use_certificate_chain(SSL_CTX *ctx, const char *cert)
+{
+ /* mostly just copy&pasted from SSL_CTX_use_certificate_chain_file() */
+ BIO *in;
+ int ret = 0;
+ X509 *x;
+
+ in = BIO_new_mem_buf(t_strdup_noconst(cert), strlen(cert));
+ if (in == NULL)
+ i_fatal("BIO_new_mem_buf() failed");
+
+ x = PEM_read_bio_X509(in, NULL, NULL, NULL);
+ if (x == NULL)
+ goto end;
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+ if (ERR_peek_error() != 0)
+ ret = 0;
+
+ if (ret != 0) {
+ /* If we could set up our certificate, now proceed to
+ * the CA certificates.
+ */
+ X509 *ca;
+ int r;
+ unsigned long err;
+
+ while ((ca = PEM_read_bio_X509(in,NULL,NULL,NULL)) != NULL) {
+ r = SSL_CTX_add_extra_chain_cert(ctx, ca);
+ if (!r) {
+ X509_free(ca);
+ ret = 0;
+ goto end;
+ }
+ }
+ /* When the while loop ends, it's usually just EOF. */
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
+ ERR_clear_error();
+ else
+ ret = 0; /* some real error */
+ }
+
+end:
+ if (x != NULL) X509_free(x);
+ if (in != NULL) BIO_free(in);
+ return ret;
+}
+
static void ssl_proxy_init_server(const struct login_settings *set)
{
+ BIO *bio;
+ EVP_PKEY *pkey;
char *password;
unsigned long err;
@@ -832,33 +871,37 @@ static void ssl_proxy_init_server(const
set->ssl_cipher_list, ssl_last_error());
}
- if (SSL_CTX_use_certificate_chain_file(ssl_server_ctx,
- set->ssl_cert_file) != 1) {
+ if (ssl_proxy_ctx_use_certificate_chain(ssl_server_ctx,
+ set->ssl_cert) != 1) {
err = ERR_peek_error();
if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
ERR_GET_REASON(err) != PEM_R_NO_START_LINE) {
- i_fatal("Can't load certificate file %s: %s",
- set->ssl_cert_file, ssl_last_error());
- } else if (is_pem_key_file(set->ssl_cert_file)) {
- i_fatal("Can't load certificate file %s: "
+ i_fatal("Can't load ssl_cert: %s", ssl_last_error());
+ } else if (is_pem_key(set->ssl_cert)) {
+ i_fatal("Can't load ssl_cert: "
"The file contains a private key "
- "(you've mixed ssl_cert_file and ssl_key_file settings)",
- set->ssl_cert_file);
+ "(you've mixed ssl_cert and ssl_key settings)");
} else {
- i_fatal("Can't load certificate file %s: "
- "The file doesn't contain a certificate.",
- set->ssl_cert_file);
+ i_fatal("Can't load ssl_cert: There is no certificate.");
}
}
password = t_strdup_noconst(set->ssl_key_password);
SSL_CTX_set_default_passwd_cb(ssl_server_ctx, pem_password_callback);
SSL_CTX_set_default_passwd_cb_userdata(ssl_server_ctx, password);
- if (SSL_CTX_use_PrivateKey_file(ssl_server_ctx, set->ssl_key_file,
- SSL_FILETYPE_PEM) != 1) {
- i_fatal("Can't load private key file %s: %s",
- set->ssl_key_file, ssl_last_error());
- }
+
+ bio = BIO_new_mem_buf(t_strdup_noconst(set->ssl_key),
+ strlen(set->ssl_key));
+ if (bio == NULL)
+ i_fatal("BIO_new_mem_buf() failed");
+ pkey = PEM_read_bio_PrivateKey(bio, NULL, pem_password_callback,
+ password);
+ if (pkey == NULL)
+ i_fatal("Couldn't parse private ssl_key");
+ if (SSL_CTX_use_PrivateKey(ssl_server_ctx, pkey) != 1)
+ i_fatal("Can't load private ssl_key: %s", ssl_last_error());
+ EVP_PKEY_free(pkey);
+
safe_memset(password, 0, strlen(password));
if (set->verbose_ssl)
More information about the dovecot-cvs
mailing list