dovecot-2.2: lib-ssl-iostream: Added support for TLS SNI, which ...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 4 17:39:29 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/f4bac0352464
changeset: 16159:f4bac0352464
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 04 17:39:17 2013 +0300
description:
lib-ssl-iostream: Added support for TLS SNI, which caused some API changes.
diffstat:
src/doveadm/server-connection.c | 7 ++-
src/lib-http/http-client-connection.c | 11 +++---
src/lib-imap-client/imapc-connection.c | 10 +++---
src/lib-master/master-service-ssl.c | 4 +-
src/lib-ssl-iostream/iostream-openssl-context.c | 28 +++++++++++++++++
src/lib-ssl-iostream/iostream-openssl.c | 40 ++++++++++++++++++------
src/lib-ssl-iostream/iostream-openssl.h | 5 +-
src/lib-ssl-iostream/iostream-ssl-private.h | 4 +-
src/lib-ssl-iostream/iostream-ssl.c | 33 ++++++++++++++++---
src/lib-ssl-iostream/iostream-ssl.h | 20 +++++++++---
src/lib-storage/index/pop3c/pop3c-client.c | 9 ++---
11 files changed, 125 insertions(+), 46 deletions(-)
diffs (truncated from 417 to 300 lines):
diff -r 52efc1740e15 -r f4bac0352464 src/doveadm/server-connection.c
--- a/src/doveadm/server-connection.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/doveadm/server-connection.c Thu Apr 04 17:39:17 2013 +0300
@@ -358,9 +358,10 @@
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, &error) < 0) {
+ if (io_stream_create_ssl_client(conn->server->ssl_ctx,
+ conn->server->name, &ssl_set,
+ &conn->input, &conn->output,
+ &conn->ssl_iostream, &error) < 0) {
i_error("Couldn't initialize SSL client: %s", error);
return -1;
}
diff -r 52efc1740e15 -r f4bac0352464 src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-http/http-client-connection.c Thu Apr 04 17:39:17 2013 +0300
@@ -667,7 +667,7 @@
const char **error_r)
{
struct ssl_iostream_settings ssl_set;
- const char *source, *error;
+ const char *error;
i_assert(conn->client->ssl_ctx != NULL);
@@ -681,11 +681,10 @@
if (conn->client->set.debug)
http_client_connection_debug(conn, "Starting SSL handshake");
- source = t_strdup_printf
- ("connection %s: ", http_client_connection_label(conn));
- if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set,
- &conn->conn.input, &conn->conn.output,
- &conn->ssl_iostream, &error) < 0) {
+ if (io_stream_create_ssl_client(conn->client->ssl_ctx,
+ conn->peer->addr.https_name, &ssl_set,
+ &conn->conn.input, &conn->conn.output,
+ &conn->ssl_iostream, &error) < 0) {
*error_r = t_strdup_printf(
"Couldn't initialize SSL client for %s: %s",
conn->conn.name, error);
diff -r 52efc1740e15 -r f4bac0352464 src/lib-imap-client/imapc-connection.c
--- a/src/lib-imap-client/imapc-connection.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-imap-client/imapc-connection.c Thu Apr 04 17:39:17 2013 +0300
@@ -1158,7 +1158,7 @@
{
struct ssl_iostream_settings ssl_set;
struct stat st;
- const char *source, *error;
+ const char *error;
if (conn->client->ssl_ctx == NULL) {
i_error("imapc(%s): No SSL context", conn->name);
@@ -1185,10 +1185,10 @@
conn->output = conn->raw_output;
}
- source = t_strdup_printf("imapc(%s): ", conn->name);
- if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set,
- &conn->input, &conn->output,
- &conn->ssl_iostream, &error) < 0) {
+ if (io_stream_create_ssl_client(conn->client->ssl_ctx,
+ conn->client->set.host,
+ &ssl_set, &conn->input, &conn->output,
+ &conn->ssl_iostream, &error) < 0) {
i_error("imapc(%s): Couldn't initialize SSL client: %s",
conn->name, error);
return -1;
diff -r 52efc1740e15 -r f4bac0352464 src/lib-master/master-service-ssl.c
--- a/src/lib-master/master-service-ssl.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-master/master-service-ssl.c Thu Apr 04 17:39:17 2013 +0300
@@ -82,8 +82,8 @@
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, error_r);
+ return io_stream_create_ssl_server(service->ssl_ctx, &ssl_set,
+ input, output, ssl_iostream_r, error_r);
}
bool master_service_ssl_is_enabled(struct master_service *service)
diff -r 52efc1740e15 -r f4bac0352464 src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c Thu Apr 04 17:39:17 2013 +0300
@@ -291,6 +291,25 @@
return new_set;
}
+#ifdef HAVE_SSL_GET_SERVERNAME
+static int ssl_servername_callback(SSL *ssl, int *al ATTR_UNUSED,
+ void *context ATTR_UNUSED)
+{
+ struct ssl_iostream *ssl_io;
+ const char *host;
+
+ ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
+ host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ if (SSL_get_servername_type(ssl) != -1) {
+ i_free(ssl_io->host);
+ ssl_io->host = i_strdup(host);
+ } else if (ssl_io->verbose) {
+ i_debug("SSL_get_servername() failed");
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+#endif
+
static int
ssl_iostream_context_set(struct ssl_iostream_context *ctx,
const struct ssl_iostream_settings *set,
@@ -355,6 +374,15 @@
return -1;
}
}
+#ifdef HAVE_SSL_GET_SERVERNAME
+ if (!ctx->client_ctx) {
+ if (SSL_CTX_set_tlsext_servername_callback(ctx->ssl_ctx,
+ ssl_servername_callback) != 1) {
+ if (set->verbose)
+ i_debug("OpenSSL library doesn't support SNI");
+ }
+ }
+#endif
return 0;
}
diff -r 52efc1740e15 -r f4bac0352464 src/lib-ssl-iostream/iostream-openssl.c
--- a/src/lib-ssl-iostream/iostream-openssl.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl.c Thu Apr 04 17:39:17 2013 +0300
@@ -15,16 +15,16 @@
ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
if ((where & SSL_CB_ALERT) != 0) {
- i_warning("%s: SSL alert: where=0x%x, ret=%d: %s %s",
- ssl_io->source, where, ret,
+ i_warning("%sSSL alert: where=0x%x, ret=%d: %s %s",
+ ssl_io->log_prefix, where, ret,
SSL_alert_type_string_long(ret),
SSL_alert_desc_string_long(ret));
} else if (ret == 0) {
- i_warning("%s: SSL failed: where=0x%x: %s",
- ssl_io->source, where, SSL_state_string_long(ssl));
+ i_warning("%sSSL failed: where=0x%x: %s",
+ ssl_io->log_prefix, where, SSL_state_string_long(ssl));
} else {
- i_debug("%s: SSL: where=0x%x, ret=%d: %s",
- ssl_io->source, where, ret,
+ i_debug("%sSSL: where=0x%x, ret=%d: %s",
+ ssl_io->log_prefix, where, ret,
SSL_state_string_long(ssl));
}
}
@@ -128,7 +128,7 @@
if (set->verbose)
SSL_set_info_callback(ssl_io->ssl, openssl_info_callback);
- if (set->cipher_list != NULL &&
+ if (set->cipher_list != NULL &&
strcmp(ctx_set->cipher_list, set->cipher_list) != 0) {
if (!SSL_set_cipher_list(ssl_io->ssl, set->cipher_list)) {
*error_r = t_strdup_printf(
@@ -179,7 +179,7 @@
}
static int
-openssl_iostream_create(struct ssl_iostream_context *ctx, const char *source,
+openssl_iostream_create(struct ssl_iostream_context *ctx, const char *host,
const struct ssl_iostream_settings *set,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r,
@@ -215,10 +215,15 @@
ssl_io->bio_ext = bio_ext;
ssl_io->plain_input = *input;
ssl_io->plain_output = *output;
- ssl_io->source = i_strdup(source);
+ ssl_io->host = i_strdup(host);
+ ssl_io->log_prefix = host == NULL ? i_strdup("") :
+ i_strdup_printf("%s: ", host);
/* bio_int will be freed by SSL_free() */
SSL_set_bio(ssl_io->ssl, bio_int, bio_int);
SSL_set_ex_data(ssl_io->ssl, dovecot_ssl_extdata_index, ssl_io);
+#ifdef HAVE_SSL_GET_SERVERNAME
+ SSL_set_tlsext_host_name(ssl_io->ssl, host);
+#endif
if (openssl_iostream_set(ssl_io, set, error_r) < 0) {
openssl_iostream_free(ssl_io);
@@ -249,7 +254,8 @@
BIO_free(ssl_io->bio_ext);
SSL_free(ssl_io->ssl);
i_free(ssl_io->last_error);
- i_free(ssl_io->source);
+ i_free(ssl_io->host);
+ i_free(ssl_io->log_prefix);
i_free(ssl_io);
}
@@ -566,6 +572,13 @@
ssl_io->handshake_context = context;
}
+static void openssl_iostream_set_log_prefix(struct ssl_iostream *ssl_io,
+ const char *prefix)
+{
+ i_free(ssl_io->log_prefix);
+ ssl_io->log_prefix = i_strdup(prefix);
+}
+
static bool openssl_iostream_is_handshaked(const struct ssl_iostream *ssl_io)
{
return ssl_io->handshaked;
@@ -617,6 +630,11 @@
return *name == '\0' ? NULL : name;
}
+static const char *openssl_iostream_get_server_name(struct ssl_iostream *ssl_io)
+{
+ return ssl_io->host;
+}
+
static const char *
openssl_iostream_get_security_string(struct ssl_iostream *ssl_io)
{
@@ -666,11 +684,13 @@
openssl_iostream_handshake,
openssl_iostream_set_handshake_callback,
+ openssl_iostream_set_log_prefix,
openssl_iostream_is_handshaked,
openssl_iostream_has_valid_client_cert,
openssl_iostream_has_broken_client_cert,
openssl_iostream_cert_match_name,
openssl_iostream_get_peer_name,
+ openssl_iostream_get_server_name,
openssl_iostream_get_security_string,
openssl_iostream_get_last_error
};
diff -r 52efc1740e15 -r f4bac0352464 src/lib-ssl-iostream/iostream-openssl.h
--- a/src/lib-ssl-iostream/iostream-openssl.h Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl.h Thu Apr 04 17:39:17 2013 +0300
@@ -21,8 +21,6 @@
int refcount;
struct ssl_iostream_context *ctx;
- const struct ssl_iostream_settings *set;
-
SSL *ssl;
BIO *bio_ext;
@@ -30,8 +28,9 @@
struct ostream *plain_output;
struct ostream *ssl_output;
- char *source;
+ char *host;
char *last_error;
+ char *log_prefix;
int plain_stream_errno;
/* copied settings */
diff -r 52efc1740e15 -r f4bac0352464 src/lib-ssl-iostream/iostream-ssl-private.h
--- a/src/lib-ssl-iostream/iostream-ssl-private.h Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-ssl-private.h Thu Apr 04 17:39:17 2013 +0300
@@ -16,7 +16,7 @@
int (*context_import_params)(struct ssl_iostream_context *ctx,
const buffer_t *input);
- int (*create)(struct ssl_iostream_context *ctx, const char *source,
+ int (*create)(struct ssl_iostream_context *ctx, const char *host,
const struct ssl_iostream_settings *set,
struct istream **input, struct ostream **output,
struct ssl_iostream **iostream_r, const char **error_r);
@@ -28,11 +28,13 @@
ssl_iostream_handshake_callback_t *callback,
void *context);
+ void (*set_log_prefix)(struct ssl_iostream *ssl_io, const char *prefix);
bool (*is_handshaked)(const struct ssl_iostream *ssl_io);
bool (*has_valid_client_cert)(const struct ssl_iostream *ssl_io);
bool (*has_broken_client_cert)(struct ssl_iostream *ssl_io);
int (*cert_match_name)(struct ssl_iostream *ssl_io, const char *name);
const char *(*get_peer_name)(struct ssl_iostream *ssl_io);
+ const char *(*get_server_name)(struct ssl_iostream *ssl_io);
const char *(*get_security_string)(struct ssl_iostream *ssl_io);
const char *(*get_last_error)(struct ssl_iostream *ssl_io);
};
diff -r 52efc1740e15 -r f4bac0352464 src/lib-ssl-iostream/iostream-ssl.c
--- a/src/lib-ssl-iostream/iostream-ssl.c Thu Apr 04 17:34:23 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-ssl.c Thu Apr 04 17:39:17 2013 +0300
@@ -92,13 +92,23 @@
return ssl_vfuncs->context_import_params(ctx, input);
}
-int io_stream_create_ssl(struct ssl_iostream_context *ctx, const char *source,
- const struct ssl_iostream_settings *set,
More information about the dovecot-cvs
mailing list