dovecot-2.2: dsync: Added tcps (TCP+SSL) target.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Feb 25 15:55:26 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/95ecdd9e13bf
changeset: 15934:95ecdd9e13bf
user: Timo Sirainen <tss at iki.fi>
date: Mon Feb 25 15:55:06 2013 +0200
description:
dsync: Added tcps (TCP+SSL) target.
diffstat:
src/doveadm/doveadm-server.h | 1 +
src/doveadm/doveadm-settings.c | 6 ++
src/doveadm/doveadm-settings.h | 3 +
src/doveadm/dsync/Makefile.am | 1 +
src/doveadm/dsync/doveadm-dsync.c | 40 +++++++++++++++++-
src/doveadm/server-connection.c | 84 ++++++++++++++++++++++++++++++++++++--
src/doveadm/server-connection.h | 4 +-
7 files changed, 129 insertions(+), 10 deletions(-)
diffs (truncated from 317 to 300 lines):
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/doveadm-server.h
--- a/src/doveadm/doveadm-server.h Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/doveadm-server.h Mon Feb 25 15:55:06 2013 +0200
@@ -8,6 +8,7 @@
struct doveadm_server {
const char *name;
+ struct ssl_iostream_context *ssl_ctx;
ARRAY(struct server_connection *) connections;
ARRAY_TYPE(string) queue;
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/doveadm-settings.c
--- a/src/doveadm/doveadm-settings.c Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/doveadm-settings.c Mon Feb 25 15:55:06 2013 +0200
@@ -65,6 +65,9 @@
DEF(SET_STR, dsync_alt_char),
DEF(SET_STR, dsync_remote_cmd),
+ DEF(SET_STR, ssl_client_ca_dir),
+ DEF(SET_STR, ssl_crypto_device),
+
{ SET_STRLIST, "plugin", offsetof(struct doveadm_settings, plugin_envs), NULL },
SETTING_DEFINE_LIST_END
@@ -83,6 +86,9 @@
.dsync_alt_char = "_",
.dsync_remote_cmd = "ssh -l%{login} %{host} doveadm dsync-server -u%u",
+ .ssl_client_ca_dir = "",
+ .ssl_crypto_device = "",
+
.plugin_envs = ARRAY_INIT
};
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/doveadm-settings.h
--- a/src/doveadm/doveadm-settings.h Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/doveadm-settings.h Mon Feb 25 15:55:06 2013 +0200
@@ -14,6 +14,9 @@
const char *dsync_alt_char;
const char *dsync_remote_cmd;
+ const char *ssl_client_ca_dir;
+ const char *ssl_crypto_device;
+
ARRAY(const char *) plugin_envs;
};
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/dsync/Makefile.am
--- a/src/doveadm/dsync/Makefile.am Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/dsync/Makefile.am Mon Feb 25 15:55:06 2013 +0200
@@ -4,6 +4,7 @@
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-test \
-I$(top_srcdir)/src/lib-settings \
+ -I$(top_srcdir)/src/lib-ssl-iostream \
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-imap \
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/dsync/doveadm-dsync.c Mon Feb 25 15:55:06 2013 +0200
@@ -7,6 +7,7 @@
#include "fd-set-nonblock.h"
#include "istream.h"
#include "ostream.h"
+#include "iostream-ssl.h"
#include "iostream-rawlog.h"
#include "write-full.h"
#include "str.h"
@@ -14,6 +15,7 @@
#include "var-expand.h"
#include "settings-parser.h"
#include "master-service.h"
+#include "master-service-ssl-settings.h"
#include "mail-storage-service.h"
#include "mail-user.h"
#include "mail-namespace.h"
@@ -58,6 +60,9 @@
struct istream *input, *err_stream;
struct ostream *output;
+ struct ssl_iostream_context *ssl_ctx;
+ struct ssl_iostream *ssl_iostream;
+
enum dsync_run_type run_type;
struct server_connection *tcp_conn;
const char *error;
@@ -489,6 +494,10 @@
dsync_ibc_deinit(&ibc);
if (ibc2 != NULL)
dsync_ibc_deinit(&ibc2);
+ if (ctx->ssl_iostream != NULL)
+ ssl_iostream_destroy(&ctx->ssl_iostream);
+ if (ctx->ssl_ctx != NULL)
+ ssl_iostream_context_deinit(&ctx->ssl_ctx);
if (ctx->fd_in != -1) {
if (ctx->fd_out != ctx->fd_in)
i_close_fd(&ctx->fd_out);
@@ -529,7 +538,7 @@
break;
case SERVER_CMD_REPLY_OK:
server_connection_extract(ctx->tcp_conn, &ctx->input,
- &ctx->output);
+ &ctx->output, &ctx->ssl_iostream);
ctx->fd_in = ctx->fd_out = -1;
break;
case SERVER_CMD_REPLY_INTERNAL_FAILURE:
@@ -541,8 +550,21 @@
io_loop_stop(current_ioloop);
}
+static int dsync_init_ssl_ctx(struct dsync_cmd_context *ctx)
+{
+ struct ssl_iostream_settings ssl_set;
+
+ memset(&ssl_set, 0, sizeof(ssl_set));
+ ssl_set.ca_dir = doveadm_settings->ssl_client_ca_dir;
+ ssl_set.verify_remote_cert = TRUE;
+ ssl_set.crypto_device = doveadm_settings->ssl_crypto_device;
+
+ return ssl_iostream_context_init_client("doveadm", &ssl_set,
+ &ctx->ssl_ctx);
+}
+
static int dsync_connect_tcp(struct dsync_cmd_context *ctx, const char *target,
- const char **error_r)
+ bool ssl, const char **error_r)
{
struct doveadm_server *server;
struct server_connection *conn;
@@ -551,6 +573,13 @@
server = p_new(ctx->ctx.pool, struct doveadm_server, 1);
server->name = p_strdup(ctx->ctx.pool, target);
+ if (ssl) {
+ if (dsync_init_ssl_ctx(ctx) < 0) {
+ *error_r = "Couldn't initialize SSL context";
+ return -1;
+ }
+ server->ssl_ctx = ctx->ssl_ctx;
+ }
p_array_init(&server->connections, ctx->ctx.pool, 1);
p_array_init(&server->queue, ctx->ctx.pool, 1);
@@ -596,7 +625,12 @@
if (strncmp(location, "tcp:", 4) == 0) {
/* TCP connection to remote dsync */
ctx->remote_name = location+4;
- return dsync_connect_tcp(ctx, ctx->remote_name, error_r);
+ return dsync_connect_tcp(ctx, ctx->remote_name, FALSE, error_r);
+ }
+ if (strncmp(location, "tcps:", 5) == 0) {
+ /* TCP+SSL connection to remote dsync */
+ ctx->remote_name = location+5;
+ return dsync_connect_tcp(ctx, ctx->remote_name, TRUE, error_r);
}
if (strncmp(location, "remote:", 7) == 0) {
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/server-connection.c
--- a/src/doveadm/server-connection.c Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/server-connection.c Mon Feb 25 15:55:06 2013 +0200
@@ -9,6 +9,7 @@
#include "ostream.h"
#include "str.h"
#include "strescape.h"
+#include "iostream-ssl.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "settings-parser.h"
@@ -38,6 +39,7 @@
struct io *io;
struct istream *input;
struct ostream *output;
+ struct ssl_iostream *ssl_iostream;
const char *delayed_cmd;
server_cmd_callback_t *callback;
@@ -313,6 +315,67 @@
return 0;
}
+static int server_connection_ssl_handshaked(void *context)
+{
+ struct server_connection *conn = context;
+ const char *host, *p;
+
+ host = conn->server->name;
+ p = strrchr(host, ':');
+ if (p != NULL)
+ host = t_strdup_until(host, p);
+
+ if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) {
+ if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
+ i_error("%s: SSL certificate not received",
+ conn->server->name);
+ } else {
+ i_error("%s: Received invalid SSL certificate",
+ conn->server->name);
+ }
+ } else if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) < 0) {
+ i_error("%s: SSL certificate doesn't match host name",
+ conn->server->name);
+ } else {
+ if (doveadm_debug) {
+ i_debug("%s: SSL handshake successful",
+ conn->server->name);
+ }
+ return 0;
+ }
+ i_stream_close(conn->input);
+ return -1;
+}
+
+static int server_connection_init_ssl(struct server_connection *conn)
+{
+ struct ssl_iostream_settings ssl_set;
+
+ if (conn->server->ssl_ctx == NULL)
+ return 0;
+
+ memset(&ssl_set, 0, sizeof(ssl_set));
+ ssl_set.verify_remote_cert = TRUE;
+ ssl_set.require_valid_cert = TRUE;
+ ssl_set.verbose_invalid_cert = TRUE;
+
+ if (io_stream_create_ssl(conn->server->ssl_ctx, "doveadm", &ssl_set,
+ &conn->input, &conn->output,
+ &conn->ssl_iostream) < 0) {
+ i_error("Couldn't initialize SSL client");
+ return -1;
+ }
+ ssl_iostream_set_handshake_callback(conn->ssl_iostream,
+ server_connection_ssl_handshaked,
+ conn);
+ if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
+ i_error("SSL handshake failed: %s",
+ ssl_iostream_get_last_error(conn->ssl_iostream));
+ return -1;
+ }
+ return 0;
+}
+
int server_connection_create(struct doveadm_server *server,
struct server_connection **conn_r)
{
@@ -330,15 +393,19 @@
conn->io = io_add(conn->fd, IO_READ, server_connection_input, conn);
conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE);
conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE);
+
+ array_append(&conn->server->connections, &conn, 1);
+
+ if (server_connection_read_settings(conn) < 0 ||
+ server_connection_init_ssl(conn) < 0) {
+ server_connection_destroy(&conn);
+ return -1;
+ }
+
o_stream_set_no_error_handling(conn->output, TRUE);
conn->state = SERVER_REPLY_STATE_DONE;
o_stream_nsend_str(conn->output, DOVEADM_SERVER_HANDSHAKE);
- array_append(&conn->server->connections, &conn, 1);
- if (server_connection_read_settings(conn) < 0) {
- server_connection_destroy(&conn);
- return -1;
- }
*conn_r = conn;
return 0;
}
@@ -370,6 +437,8 @@
i_stream_destroy(&conn->input);
if (conn->output != NULL)
o_stream_destroy(&conn->output);
+ if (conn->ssl_iostream != NULL)
+ ssl_iostream_unref(&conn->ssl_iostream);
if (conn->io != NULL)
io_remove(&conn->io);
if (conn->fd != -1) {
@@ -406,13 +475,16 @@
void server_connection_extract(struct server_connection *conn,
struct istream **istream_r,
- struct ostream **ostream_r)
+ struct ostream **ostream_r,
+ struct ssl_iostream **ssl_iostream_r)
{
*istream_r = conn->input;
*ostream_r = conn->output;
+ *ssl_iostream_r = conn->ssl_iostream;
conn->input = NULL;
conn->output = NULL;
+ conn->ssl_iostream = NULL;
if (conn->io != NULL)
io_remove(&conn->io);
conn->fd = -1;
diff -r 9a7680fe65ce -r 95ecdd9e13bf src/doveadm/server-connection.h
--- a/src/doveadm/server-connection.h Mon Feb 25 15:54:01 2013 +0200
+++ b/src/doveadm/server-connection.h Mon Feb 25 15:55:06 2013 +0200
More information about the dovecot-cvs
mailing list