Mercurial > dovecot > core-2.2
changeset 14729:0de6b238d6eb
Added libdovecot-ssl for creating SSL servers more easily using lib-ssl-iostream.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 28 Jul 2012 17:55:46 +0300 |
parents | 983c6ff12cc9 |
children | 73ce16df6b16 |
files | Makefile.am configure.in dovecot-config.in.in dovecot.m4 src/Makefile.am src/lib-dovecot/Makefile.am src/lib-master/Makefile.am src/lib-master/master-service-ssl.c src/lib-master/master-service-ssl.h |
diffstat | 9 files changed, 182 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -65,6 +65,7 @@ -e "s|^\(LIBDOVECOT\)=.*$$|\1='-L$(pkglibdir) -ldovecot'|" \ -e "s|^\(LIBDOVECOT_LOGIN\)=.*$$|\1=-ldovecot-login|" \ -e "s|^\(LIBDOVECOT_SQL\)=.*$$|\1=-ldovecot-sql|" \ + -e "s|^\(LIBDOVECOT_SSL\)=.*$$|\1=-ldovecot-ssl|" \ -e "s|^\(LIBDOVECOT_LDA\)=.*$$|\1=-ldovecot-lda|" \ -e "s|^\(LIBDOVECOT_STORAGE\)=.*$$|\1=-ldovecot-storage|" \ -e "s|^\(LIBDOVECOT_INCLUDE\)=.*$$|\1=-I$(pkgincludedir)|" \
--- a/configure.in Sat Jul 28 17:54:19 2012 +0300 +++ b/configure.in Sat Jul 28 17:55:46 2012 +0300 @@ -2514,6 +2514,7 @@ LIBDOVECOT="$LIBDOVECOT_DEPS" LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la' + LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la' @@ -2522,6 +2523,7 @@ LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la' LIBDOVECOT_STORAGE_DEPS="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST" LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' + LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la' fi LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_DEPS $LINKED_STORAGE_LDADD" @@ -2532,6 +2534,7 @@ AC_SUBST(LIBDOVECOT_STORAGE_DEPS) AC_SUBST(LIBDOVECOT_LOGIN) AC_SUBST(LIBDOVECOT_SQL) +AC_SUBST(LIBDOVECOT_SSL) AC_SUBST(LIBDOVECOT_LDA) dnl **
--- a/dovecot-config.in.in Sat Jul 28 17:54:19 2012 +0300 +++ b/dovecot-config.in.in Sat Jul 28 17:55:46 2012 +0300 @@ -6,16 +6,18 @@ LIBDOVECOT="@LIBDOVECOT@ @MODULE_LIBS@" LIBDOVECOT_LOGIN="@LIBDOVECOT_LOGIN@ @SSL_LIBS@" LIBDOVECOT_SQL="@LIBDOVECOT_SQL@" +LIBDOVECOT_SSL="@LIBDOVECOT_SSL@" LIBDOVECOT_LDA="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE="@LIBDOVECOT_STORAGE@" LIBDOVECOT_DEPS="@LIBDOVECOT_DEPS@" LIBDOVECOT_LOGIN_DEPS="@LIBDOVECOT_LOGIN@" LIBDOVECOT_SQL_DEPS="@LIBDOVECOT_SQL@" +LIBDOVECOT_SSL_DEPS="@LIBDOVECOT_SSL@" LIBDOVECOT_LDA_DEPS="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE_DEPS="@LIBDOVECOT_STORAGE_DEPS@" -LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-settings" +LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-settings" LIBDOVECOT_LDA_INCLUDE="-I$(incdir)/src/lib-lda -I$(incdir)/src/lda" LIBDOVECOT_STORAGE_INCLUDE="-I$(incdir)/src/lib-index -I$(incdir)/src/lib-storage -I$(incdir)/src/lib-storage/index -I$(incdir)/src/lib-storage/index/raw" LIBDOVECOT_LOGIN_INCLUDE="-I$(incdir)/src/login-common"
--- a/dovecot.m4 Sat Jul 28 17:54:19 2012 +0300 +++ b/dovecot.m4 Sat Jul 28 17:55:46 2012 +0300 @@ -60,8 +60,8 @@ eval `grep '^LIBDOVECOT[[A-Z_]]*=' "$dovecotdir"/dovecot-config` AX_SUBST_L([dovecotdir], [dovecot_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir]) AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS]) - AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) - AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) + AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) + AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE]) DC_PLUGIN_DEPS
--- a/src/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -9,12 +9,12 @@ lib-imap-storage \ lib-master \ lib-dict \ - lib-settings + lib-settings \ + lib-ssl-iostream SUBDIRS = \ lib-test \ $(LIBDOVECOT_SUBDIRS) \ - lib-ssl-iostream \ lib-imap-client \ lib-dovecot \ lib-index \
--- a/src/lib-dovecot/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/lib-dovecot/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -10,15 +10,26 @@ ../lib-master/libmaster.la \ ../lib/liblib.la -pkglib_LTLIBRARIES = libdovecot.la +ssl_libs = \ + ../lib-master/libmaster_ssl.la + ../lib-ssl-iostream/libssl_iostream.la + +pkglib_LTLIBRARIES = libdovecot.la libdovecot-ssl.la libdovecot_la_SOURCES = +libdovecot_ssl_la_SOURCES = libdovecot_la_LIBADD = \ $(libs) \ $(MODULE_LIBS) \ $(LTLIBICONV) +libdovecot_ssl_la_LIBADD = \ + $(ssl_libs) \ + $(SSL_LIBS) + libdovecot_la_DEPENDENCIES = $(libs) +libdovecot_ssl_la_DEPENDENCIES = $(ssl_libs) libdovecot_la_LDFLAGS = -export-dynamic +libdovecot_ssl_la_LDFLAGS = -export-dynamic
--- a/src/lib-master/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/lib-master/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -1,10 +1,11 @@ pkgsysconfdir = $(sysconfdir)/dovecot -noinst_LTLIBRARIES = libmaster.la +noinst_LTLIBRARIES = libmaster.la libmaster_ssl.la AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-ssl-iostream \ -DPKG_RUNDIR=\""$(rundir)"\" \ -DPKG_STATEDIR=\""$(statedir)"\" \ -DSYSCONFDIR=\""$(pkgsysconfdir)"\" \ @@ -25,6 +26,9 @@ mountpoint-list.c \ syslog-util.c +libmaster_ssl_la_SOURCES = \ + master-service-ssl.c + headers = \ anvil-client.h \ ipc-client.h \ @@ -38,6 +42,7 @@ master-service-private.h \ master-service-settings.h \ master-service-settings-cache.h \ + master-service-ssl.h \ master-service-ssl-settings.h \ service-settings.h \ mountpoint-list.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/master-service-ssl.c Sat Jul 28 17:55:46 2012 +0300 @@ -0,0 +1,138 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "buffer.h" +#include "iostream-ssl.h" +#include "master-service-private.h" +#include "master-service-settings.h" +#include "master-service-ssl-settings.h" +#include "master-service-ssl.h" + +#include <unistd.h> + +/* Check every 30 minutes if parameters file has been updated */ +#define SSL_PARAMS_CHECK_INTERVAL (60*30) + +#define SSL_PARAMETERS_PATH "ssl-params" + +static int ssl_refresh_parameters(struct master_service *service) +{ +#define BUF_APPEND_SIZE 1024 + const char *path; + buffer_t *buf; + void *data; + ssize_t ret; + int fd; + + if (ioloop_time == 0 || + service->ssl_params_last_refresh > ioloop_time - SSL_PARAMS_CHECK_INTERVAL) + return 0; + service->ssl_params_last_refresh = ioloop_time; + + path = t_strdup_printf("%s/"SSL_PARAMETERS_PATH, service->set->base_dir); + fd = net_connect_unix(path); + if (fd == -1) { + i_error("connect(%s) failed: %m", path); + return -1; + } + net_set_nonblock(fd, FALSE); + + buf = buffer_create_dynamic(default_pool, BUF_APPEND_SIZE*2); + for (;;) { + data = buffer_append_space_unsafe(buf, BUF_APPEND_SIZE); + ret = read(fd, data, BUF_APPEND_SIZE); + buffer_set_used_size(buf, buf->used - BUF_APPEND_SIZE + + (ret < 0 ? 0 : ret)); + if (ret <= 0) + break; + } + if (ret < 0) + i_error("read(%s) failed: %m", path); + else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) { + i_error("Corrupted SSL parameters file: " + PKG_STATEDIR"/ssl-parameters.dat - disabling SSL %u", (int)buf->used); + ret = -1; + } + i_close_fd(&fd); + buffer_free(&buf); + return ret < 0 ? -1 : 0; +} + +int master_service_ssl_init(struct master_service *service, + struct istream **input, struct ostream **output, + struct ssl_iostream **ssl_iostream_r) +{ + const struct master_service_ssl_settings *set; + struct ssl_iostream_settings ssl_set; + + i_assert(service->ssl_ctx_initialized); + + if (service->ssl_ctx == NULL) + return -1; + + (void)ssl_refresh_parameters(service); + + set = master_service_ssl_settings_get(service); + + memset(&ssl_set, 0, sizeof(ssl_set)); + ssl_set.verbose = set->verbose_ssl; + ssl_set.verify_remote_cert = set->ssl_verify_client_cert; + + return io_stream_create_ssl(service->ssl_ctx, service->name, &ssl_set, + input, output, ssl_iostream_r); +} + +bool master_service_ssl_is_enabled(struct master_service *service) +{ + return service->ssl_ctx != NULL; +} + +void master_service_ssl_ctx_init(struct master_service *service) +{ + const struct master_service_ssl_settings *set; + struct ssl_iostream_settings ssl_set; + + if (service->ssl_ctx_initialized) + return; + service->ssl_ctx_initialized = TRUE; + + /* must be called after master_service_init_finish() so that if + initialization fails we can close the SSL listeners */ + i_assert(service->listeners != NULL); + + set = master_service_ssl_settings_get(service); + + memset(&ssl_set, 0, sizeof(ssl_set)); + ssl_set.protocols = set->ssl_protocols; + ssl_set.cipher_list = set->ssl_cipher_list; + ssl_set.ca = set->ssl_ca; + ssl_set.cert = set->ssl_cert; + ssl_set.key = set->ssl_key; + ssl_set.key_password = set->ssl_key_password; + ssl_set.cert_username_field = set->ssl_cert_username_field; + ssl_set.crypto_device = set->ssl_crypto_device; + + ssl_set.verbose = set->verbose_ssl; + ssl_set.verify_remote_cert = set->ssl_verify_client_cert; + + if (ssl_iostream_context_init_server(service->name, &ssl_set, + &service->ssl_ctx) < 0) { + i_error("SSL context initialization failed, disabling SSL"); + master_service_ssl_io_listeners_remove(service); + return; + } + if (ssl_refresh_parameters(service) < 0) { + i_error("Couldn't initialize SSL parameters, disabling SSL"); + ssl_iostream_context_deinit(&service->ssl_ctx); + master_service_ssl_io_listeners_remove(service); + return; + } +} + +void master_service_ssl_ctx_deinit(struct master_service *service) +{ + if (service->ssl_ctx != NULL) + ssl_iostream_context_deinit(&service->ssl_ctx); + service->ssl_ctx_initialized = FALSE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/master-service-ssl.h Sat Jul 28 17:55:46 2012 +0300 @@ -0,0 +1,15 @@ +#ifndef MASTER_SERVICE_SSL_H +#define MASTER_SERVICE_SSL_H + +struct ssl_iostream; + +int master_service_ssl_init(struct master_service *service, + struct istream **input, struct ostream **output, + struct ssl_iostream **ssl_iostream_r); + +bool master_service_ssl_is_enabled(struct master_service *service); + +void master_service_ssl_ctx_init(struct master_service *service); +void master_service_ssl_ctx_deinit(struct master_service *service); + +#endif