]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Renamed ssl_cert_file to ssl_cert and ssl_key_file to ssl_key.
authorTimo Sirainen <tss@iki.fi>
Wed, 13 May 2009 23:52:25 +0000 (19:52 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 13 May 2009 23:52:25 +0000 (19:52 -0400)
Instead of pointing to files they now contain the certs directly.

--HG--
branch : HEAD

dovecot-example.conf
src/login-common/login-settings.c
src/login-common/login-settings.h
src/login-common/ssl-proxy-openssl.c

index c0d313b095d021ae8d0f31f3dbdba2e9bfa557fa..2b148a16a93c715e98af82477278a9885f4c20a7 100644 (file)
@@ -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
index ecfb9109fcec7ced05e06900d118feb3fa7387c4..d5ce7c35a9b0c631b2bc9d6d450d54b14f3eece7 100644 (file)
@@ -26,8 +26,8 @@ static struct setting_define login_setting_defines[] = {
 
        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_default_settings = {
 
        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 ATTR_UNUSED, const char **error_r)
                                   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 ATTR_UNUSED, const char **error_r)
        }
 
 #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);
index a505692843baf5c2441066bb5136d075c00fd90f..aa721b2f6dea419659c6730101d1a21c302d62d9 100644 (file)
@@ -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;
index 5afdda892333398a89522353ea99362de10e33fc..d4f7ea3117a3e00214bd239fd864626d224dd6e9 100644 (file)
@@ -765,22 +765,9 @@ unsigned int ssl_proxy_get_count(void)
        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_proxy_ctx_verify_client(SSL_CTX *ssl_ctx, const struct login_settings *set)
                                   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 struct login_settings *set)
                        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)