dovecot-2.0: Added ssl-params binary that login process uses to ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Oct 8 00:55:18 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/ea36bad4d9da
changeset: 9985:ea36bad4d9da
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Oct 07 17:47:01 2009 -0400
description:
Added ssl-params binary that login process uses to read SSL parameters.

diffstat:

10 files changed, 530 insertions(+)
configure.in                          |    1 
doc/example-config/conf.d/master.conf |    9 +
src/Makefile.am                       |    1 
src/ssl-params/Makefile.am            |   21 +++
src/ssl-params/main.c                 |  136 +++++++++++++++++++++
src/ssl-params/ssl-params-openssl.c   |   71 +++++++++++
src/ssl-params/ssl-params-settings.c  |   53 ++++++++
src/ssl-params/ssl-params-settings.h  |   13 ++
src/ssl-params/ssl-params.c           |  208 +++++++++++++++++++++++++++++++++
src/ssl-params/ssl-params.h           |   17 ++

diffs (truncated from 585 to 300 lines):

diff -r 097588a7903c -r ea36bad4d9da configure.in
--- a/configure.in	Wed Oct 07 17:46:14 2009 -0400
+++ b/configure.in	Wed Oct 07 17:47:01 2009 -0400
@@ -2507,6 +2507,7 @@ src/master/Makefile
 src/master/Makefile
 src/pop3/Makefile
 src/pop3-login/Makefile
+src/ssl-params/Makefile
 src/util/Makefile
 src/plugins/Makefile
 src/plugins/acl/Makefile
diff -r 097588a7903c -r ea36bad4d9da doc/example-config/conf.d/master.conf
--- a/doc/example-config/conf.d/master.conf	Wed Oct 07 17:46:14 2009 -0400
+++ b/doc/example-config/conf.d/master.conf	Wed Oct 07 17:47:01 2009 -0400
@@ -153,3 +153,12 @@ service dict {
     mode = 0666
   }
 }
+
+service ssl-params {
+  executable = ssl-params
+
+  unix_listener {
+    path = login/ssl-params
+    mode = 0666
+  }
+}
diff -r 097588a7903c -r ea36bad4d9da src/Makefile.am
--- a/src/Makefile.am	Wed Oct 07 17:46:14 2009 -0400
+++ b/src/Makefile.am	Wed Oct 07 17:47:01 2009 -0400
@@ -33,4 +33,5 @@ SUBDIRS = \
 	config \
 	util \
 	dsync \
+	ssl-params \
 	plugins
diff -r 097588a7903c -r ea36bad4d9da src/ssl-params/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl-params/Makefile.am	Wed Oct 07 17:47:01 2009 -0400
@@ -0,0 +1,21 @@
+pkglibexecdir = $(libexecdir)/dovecot
+
+pkglibexec_PROGRAMS = ssl-params
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-master \
+	-I$(top_srcdir)/src/lib-settings \
+	-DPKG_STATEDIR=\""$(statedir)"\"
+
+ssl_params_LDADD = $(LIBDOVECOT) $(SSL_LIBS)
+ssl_params_DEPENDENCIES = $(LIBDOVECOT) $(SSL_LIBS)
+ssl_params_SOURCES = \
+	main.c \
+	ssl-params.c \
+	ssl-params-openssl.c \
+	ssl-params-settings.c
+
+noinst_HEADERS = \
+	ssl-params.h \
+	ssl-params-settings.h
diff -r 097588a7903c -r ea36bad4d9da src/ssl-params/main.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl-params/main.c	Wed Oct 07 17:47:01 2009 -0400
@@ -0,0 +1,136 @@
+/* Copyright (C) 2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "lib-signals.h"
+#include "array.h"
+#include "ostream.h"
+#include "master-service.h"
+#include "ssl-params-settings.h"
+#include "ssl-params.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#define SSL_BUILD_PARAM_FNAME "ssl-parameters.dat"
+
+struct client {
+	int fd;
+	struct ostream *output;
+};
+
+static ARRAY_DEFINE(delayed_fds, int);
+struct ssl_params *param;
+static buffer_t *ssl_params;
+
+static int client_output_flush(struct ostream *output)
+{
+	if (o_stream_flush(output) == 0) {
+		/* more to come */
+		return 0;
+	}
+	/* finished / disconnected */
+	o_stream_destroy(&output);
+	return -1;
+}
+
+static void client_handle(int fd)
+{
+	struct ostream *output;
+
+	output = o_stream_create_fd(fd, (size_t)-1, TRUE);
+	o_stream_send(output, ssl_params->data, ssl_params->used);
+
+	if (o_stream_get_buffer_used_size(output) == 0)
+		o_stream_destroy(&output);
+	else {
+		o_stream_set_flush_callback(output, client_output_flush,
+					    output);
+	}
+}
+
+static void client_connected(const struct master_service_connection *conn)
+{
+	if (ssl_params->used == 0) {
+		/* waiting for parameter building to finish */
+		if (!array_is_created(&delayed_fds))
+			i_array_init(&delayed_fds, 32);
+		array_append(&delayed_fds, &conn->fd, 1);
+	}
+	client_handle(conn->fd);
+}
+
+static void ssl_params_callback(const unsigned char *data, size_t size)
+{
+	const int *fds;
+	unsigned int i, count;
+
+	buffer_set_used_size(ssl_params, 0);
+	buffer_append(ssl_params, data, size);
+
+	if (!array_is_created(&delayed_fds))
+		return;
+
+	fds = array_get(&delayed_fds, &count);
+	for (i = 0; i < count; i++)
+		client_handle(fds[i]);
+	array_free(&delayed_fds);
+}
+
+static void sig_chld(const siginfo_t *si ATTR_UNUSED, void *context ATTR_UNUSED)
+{
+	int status;
+
+	if (waitpid(-1, &status, WNOHANG) < 0)
+		i_error("waitpid() failed: %m");
+	else if (status != 0)
+		i_error("child process failed with status %d", status);
+	else {
+		/* params should have been created now. try refreshing. */
+		ssl_params_refresh(param);
+	}
+}
+
+static void main_init(const struct ssl_params_settings *set)
+{
+	lib_signals_set_handler(SIGCHLD, TRUE, sig_chld, NULL);
+
+	ssl_params = buffer_create_dynamic(default_pool, 1024);
+	param = ssl_params_init(PKG_STATEDIR"/"SSL_BUILD_PARAM_FNAME,
+				ssl_params_callback, set);
+}
+
+static void main_deinit(void)
+{
+	ssl_params_deinit(&param);
+	if (array_is_created(&delayed_fds))
+		array_free(&delayed_fds);
+}
+
+int main(int argc, char *argv[])
+{
+	const struct ssl_params_settings *set;
+	int c;
+
+	master_service = master_service_init("ssl-build-param", 0, argc, argv);
+	master_service_init_log(master_service, "ssl-build-param: ");
+
+	while ((c = getopt(argc, argv, master_service_getopt_string())) > 0) {
+		if (!master_service_parse_option(master_service, c, optarg))
+			exit(FATAL_DEFAULT);
+	}
+
+	set = ssl_params_settings_read(master_service);
+	master_service_init_finish(master_service);
+
+#ifndef HAVE_SSL
+	i_fatal("Dovecot built without SSL support");
+#endif
+
+	main_init(set);
+	master_service_run(master_service, client_connected);
+	main_deinit();
+
+	master_service_deinit(&master_service);
+        return 0;
+}
diff -r 097588a7903c -r ea36bad4d9da src/ssl-params/ssl-params
Binary file src/ssl-params/ssl-params has changed
diff -r 097588a7903c -r ea36bad4d9da src/ssl-params/ssl-params-openssl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl-params/ssl-params-openssl.c	Wed Oct 07 17:47:01 2009 -0400
@@ -0,0 +1,71 @@
+/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "write-full.h"
+#include "ssl-params.h"
+
+#ifdef HAVE_OPENSSL
+
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+/* 2 or 5. Haven't seen their difference explained anywhere, but 2 is the
+   default.. */
+#define DH_GENERATOR 2
+
+static int dh_param_bitsizes[] = { 512, 1024 };
+
+static const char *ssl_last_error(void)
+{
+	unsigned long err;
+	char *buf;
+	size_t err_size = 256;
+
+	err = ERR_get_error();
+	if (err == 0)
+		return strerror(errno);
+
+	buf = t_malloc(err_size);
+	buf[err_size-1] = '\0';
+	ERR_error_string_n(err, buf, err_size-1);
+	return buf;
+}
+
+static void generate_dh_parameters(int bitsize, int fd, const char *fname)
+{
+        DH *dh = DH_generate_parameters(bitsize, DH_GENERATOR, NULL, NULL);
+	unsigned char *buf, *p;
+	int len;
+
+	if (dh == NULL) {
+		i_fatal("DH_generate_parameters(bits=%d, gen=%d) failed: %s",
+			bitsize, DH_GENERATOR, ssl_last_error());
+	}
+
+	len = i2d_DHparams(dh, NULL);
+	if (len < 0)
+		i_fatal("i2d_DHparams() failed: %s", ssl_last_error());
+
+	buf = p = i_malloc(len);
+	len = i2d_DHparams(dh, &p);
+
+	if (write_full(fd, &bitsize, sizeof(bitsize)) < 0 ||
+	    write_full(fd, &len, sizeof(len)) < 0 ||
+	    write_full(fd, buf, len) < 0)
+		i_fatal("write_full() failed for file %s: %m", fname);
+	i_free(buf);
+}
+
+void ssl_generate_parameters(int fd, const char *fname)
+{
+	unsigned int i;
+	int bits;
+
+	for (i = 0; i < N_ELEMENTS(dh_param_bitsizes); i++)
+		generate_dh_parameters(dh_param_bitsizes[i], fd, fname);
+	bits = 0;
+	if (write_full(fd, &bits, sizeof(bits)) < 0)
+		i_fatal("write_full() failed for file %s: %m", fname);
+}
+
+#endif
diff -r 097588a7903c -r ea36bad4d9da src/ssl-params/ssl-params-settings.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl-params/ssl-params-settings.c	Wed Oct 07 17:47:01 2009 -0400
@@ -0,0 +1,53 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "settings-parser.h"
+#include "master-service-settings.h"
+#include "ssl-params-settings.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#undef DEF
+#define DEF(type, name) \
+	{ type, #name, offsetof(struct ssl_params_settings, name), NULL }
+
+static struct setting_define ssl_params_setting_defines[] = {
+	DEF(SET_UINT, ssl_parameters_regenerate),
+


More information about the dovecot-cvs mailing list