]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: client: Properly allow per-connection SSL configuration.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Fri, 19 Jan 2018 15:05:18 +0000 (16:05 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 22 Jan 2018 15:46:55 +0000 (17:46 +0200)
Although this was already partially possible, the connection was still always
using the global client SSL context.

src/lib-smtp/smtp-client-connection.c
src/lib-smtp/smtp-client-private.h

index b41587058c59e37786257c4359e22d7a361ed621..65293b5fd53ce2dcc89f434fa43828236bffc139 100644 (file)
@@ -1166,25 +1166,52 @@ smtp_client_connection_streams_changed(struct smtp_client_connection *conn)
        }
 }
 
+static int
+smtp_client_connection_init_ssl_ctx(struct smtp_client_connection *conn,
+                                   const char **error_r)
+{
+       struct smtp_client *client = conn->client;
+       const char *error;
+
+       if (conn->ssl_ctx != NULL)
+               return 0;
+
+       if (conn->set.ssl == client->set.ssl) {
+               if (smtp_client_init_ssl_ctx(client, error_r) < 0)
+                       return -1;
+               conn->ssl_ctx = client->ssl_ctx;
+               ssl_iostream_context_ref(conn->ssl_ctx);
+               return 0;
+       }
+
+       if (conn->set.ssl == NULL) {
+               *error_r = "Requested SSL connection, but no SSL settings given";
+               return -1;
+       }
+       if (ssl_iostream_client_context_cache_get(conn->set.ssl,
+               &conn->ssl_ctx, &error) < 0) {
+               *error_r = t_strdup_printf("Couldn't initialize SSL context: %s",
+                                          error);
+               return -1;
+       }
+       return 0;
+}
+
 static int
 smtp_client_connection_ssl_init(struct smtp_client_connection *conn,
                                const char **error_r)
 {
-       struct smtp_client *client = conn->client;
        struct ssl_iostream_settings ssl_set;
        const char *error;
 
-       if(client->ssl_ctx == NULL) {
-               // FIXME: support per-connection settings
-               if (smtp_client_init_ssl_ctx(client, &error) < 0) {
-                       *error_r = t_strdup_printf(
-                               "Failed to initialize SSL: %s", error);
-                       return -1;
-               }
+       if (smtp_client_connection_init_ssl_ctx(conn, &error) < 0) {
+               *error_r = t_strdup_printf(
+                       "Failed to initialize SSL: %s", error);
+               return -1;
        }
 
        i_zero(&ssl_set);
-       if (!conn->client->set.ssl->allow_invalid_cert) {
+       if (!conn->set.ssl->allow_invalid_cert) {
                ssl_set.verbose_invalid_cert = TRUE;
        }
 
@@ -1201,7 +1228,7 @@ smtp_client_connection_ssl_init(struct smtp_client_connection *conn,
                conn->conn.output = conn->raw_output;
        }
 
-       if (io_stream_create_ssl_client(client->ssl_ctx,
+       if (io_stream_create_ssl_client(conn->ssl_ctx,
                conn->host, &ssl_set,
                &conn->conn.input, &conn->conn.output,
                &conn->ssl_iostream, &error) < 0) {
@@ -1535,6 +1562,8 @@ void smtp_client_connection_disconnect(struct smtp_client_connection *conn)
 
        if (conn->ssl_iostream != NULL)
                ssl_iostream_unref(&conn->ssl_iostream);
+       if (conn->ssl_ctx != NULL)
+               ssl_iostream_context_unref(&conn->ssl_ctx);
        if (conn->sasl_client != NULL)
                dsasl_client_free(&conn->sasl_client);
 
index b0052f3adcd9c3dceee839ff75479e4fa764fa9c..8916396d77961ff3809424ce1257e6f9def36f0b 100644 (file)
@@ -136,6 +136,7 @@ struct smtp_client_connection {
        struct istream *raw_input;
        struct ostream *raw_output, *dot_output;
 
+       struct ssl_iostream_context *ssl_ctx;
        struct ssl_iostream *ssl_iostream;
 
        enum smtp_client_connection_state state;