Mercurial > dovecot > core-2.2
changeset 9275:c38f3fb4c6b6 HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 13 May 2009 19:52:25 -0400 |
parents | 39c2db5f1fcc |
children | 435298234943 |
files | dovecot-example.conf src/login-common/login-settings.c src/login-common/login-settings.h src/login-common/ssl-proxy-openssl.c |
diffstat | 4 files changed, 87 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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 @@ 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 @@ 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 @@ 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 @@ } #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);
--- 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 @@ 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;
--- 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 @@ return ssl_proxy_count; } -static bool is_pem_key_file(const char *path) +static bool is_pem_key(const char *cert) { - 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; + return strstr(cert, "PRIVATE KEY---") != NULL; } static void @@ -818,8 +805,60 @@ 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 @@ 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)