]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-ssl-iostream, global: io_stream_*create_ssl_client() - Add flags parameter
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 16 Jun 2023 14:44:33 +0000 (17:44 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:09 +0000 (12:34 +0200)
Add SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT initially, which allows enabling
ssl_iostream_settings.allow_invalid_cert after context is already created.

12 files changed:
src/lib-doveadm/doveadm-client.c
src/lib-http/http-client-connection.c
src/lib-imap-client/imapc-connection.c
src/lib-smtp/smtp-client-connection.c
src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-openssl.h
src/lib-ssl-iostream/iostream-ssl-private.h
src/lib-ssl-iostream/iostream-ssl.c
src/lib-ssl-iostream/iostream-ssl.h
src/lib-ssl-iostream/test-iostream-ssl.c
src/lib-storage/index/pop3c/pop3c-client.c
src/login-common/login-proxy.c

index ac6b8382e9a6ba429482254ad1918796c67d4485..a8e4d4311f2c12f74b8c4bdc6152cc0d67d24839 100644 (file)
@@ -578,7 +578,7 @@ static int doveadm_client_init_ssl(struct doveadm_client *conn,
                conn->set.hostname != NULL ? conn->set.hostname : "";
        connection_input_halt(&conn->conn);
        if (io_stream_create_ssl_client(conn->set.ssl_ctx, hostname,
-                                       conn->conn.event,
+                                       conn->conn.event, 0,
                                        &conn->conn.input, &conn->conn.output,
                                        &conn->ssl_iostream, &error) < 0) {
                *error_r = t_strdup_printf(
index 270e11d59cbf53e6b17c441c43f84d8493ac1b40..8ec511dc2fcc83c3a429f37858621d3116a1fd38 100644 (file)
@@ -1509,7 +1509,7 @@ http_client_connection_ssl_init(struct http_client_connection *conn,
 
        connection_input_halt(&conn->conn);
        if (io_stream_create_ssl_client(ssl_ctx, pshared->addr.a.tcp.https_name,
-                                       conn->event,
+                                       conn->event, 0,
                                        &conn->conn.input, &conn->conn.output,
                                        &conn->ssl_iostream, &error) < 0) {
                *error_r = t_strdup_printf(
index 7abd36ac4efad35b8fec5d1c071094826a126d04..1d34f5714ae095a845b3618ed53c4403f3a354f4 100644 (file)
@@ -1692,7 +1692,7 @@ static int imapc_connection_ssl_init(struct imapc_connection *conn)
        io_remove(&conn->io);
        if (io_stream_create_ssl_client(conn->client->ssl_ctx,
                                        conn->client->set.host,
-                                       conn->event,
+                                       conn->event, 0,
                                        &conn->input, &conn->output,
                                        &conn->ssl_iostream, &error) < 0) {
                e_error(conn->event, "Couldn't initialize SSL client: %s",
index 2a95ed34b30c6b09bdc7160c594e317a33787937..f3c3b31a3ec4db2ba9875d3883ffb9f950426bb8 100644 (file)
@@ -1620,7 +1620,7 @@ smtp_client_connection_ssl_init(struct smtp_client_connection *conn,
 
        connection_input_halt(&conn->conn);
        if (io_stream_create_ssl_client(
-               conn->ssl_ctx, conn->host, conn->event,
+               conn->ssl_ctx, conn->host, conn->event, 0,
                &conn->conn.input, &conn->conn.output,
                &conn->ssl_iostream, &error) < 0) {
                *error_r = t_strdup_printf(
index 73ef2163645dd04df8348a6c6c136a4305248ae3..7da03c0ac298462bf102e4562e4750567f09fb14 100644 (file)
@@ -100,7 +100,7 @@ openssl_iostream_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx)
        }
        if (preverify_ok == 0) {
                ssl_io->cert_broken = TRUE;
-               if (!ssl_io->ctx->allow_invalid_cert) {
+               if (!ssl_io->allow_invalid_cert) {
                        ssl_io->handshake_failed = TRUE;
                        return 0;
                }
@@ -129,6 +129,7 @@ static int
 openssl_iostream_create(struct ssl_iostream_context *ctx,
                        struct event *event_parent, const char *host,
                        bool client,
+                       enum ssl_iostream_flags flags,
                        struct istream **input, struct ostream **output,
                        struct ssl_iostream **iostream_r,
                        const char **error_r)
@@ -170,6 +171,8 @@ openssl_iostream_create(struct ssl_iostream_context *ctx,
        ssl_io->plain_output = *output;
        ssl_io->connected_host = i_strdup(host);
        ssl_io->event = event_create(event_parent);
+       ssl_io->allow_invalid_cert = ctx->allow_invalid_cert ||
+               (flags & SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT) != 0;
        if (client)
                event_add_category(ssl_io->event, &event_category_ssl_client);
        else
@@ -601,7 +604,7 @@ static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
                        ssl_io->handshake_failed = TRUE;
                }
        } else if (ssl_io->connected_host != NULL && !ssl_io->handshake_failed &&
-                 !ssl_io->ctx->allow_invalid_cert) {
+                 !ssl_io->allow_invalid_cert) {
                if (ssl_iostream_check_cert_validity(ssl_io, ssl_io->connected_host, &reason) < 0) {
                        openssl_iostream_set_error(ssl_io, reason);
                        ssl_io->handshake_failed = TRUE;
@@ -682,7 +685,7 @@ openssl_iostream_has_broken_client_cert(struct ssl_iostream *ssl_io)
 static bool
 openssl_iostream_get_allow_invalid_cert(struct ssl_iostream *ssl_io)
 {
-       return ssl_io->ctx->allow_invalid_cert;
+       return ssl_io->allow_invalid_cert;
 }
 
 static const char *
index fca067444ccbdad335a92447d4acf223bb323beb..5eb9eb7bdc8954baacefffb3a0f9d99e4aaf6206 100644 (file)
@@ -58,6 +58,7 @@ struct ssl_iostream {
        void *sni_context;
 
        bool do_shutdown:1;
+       bool allow_invalid_cert:1;
        bool handshaked:1;
        bool handshake_failed:1;
        bool cert_received:1;
index 2c028c2355c52b32a9bee4d2b5cfef140fb4bc65..f0680c887da44cb59b68617d06e300e9b2c0fe55 100644 (file)
@@ -19,6 +19,7 @@ struct iostream_ssl_vfuncs {
                      struct event *event_parent,
                      const char *host,
                      bool client,
+                     enum ssl_iostream_flags flags,
                      struct istream **input, struct ostream **output,
                      struct ssl_iostream **iostream_r, const char **error_r);
        void (*unref)(struct ssl_iostream *ssl_io);
index b19b83a7e1fce48ca4dd98add7494e6fb16e08e3..dd29183b5bee14e0b0c55c875bf5b0bc22bead88 100644 (file)
@@ -109,11 +109,12 @@ void ssl_iostream_context_unref(struct ssl_iostream_context **_ctx)
 
 int io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host,
                                struct event *event_parent,
+                               enum ssl_iostream_flags flags,
                                struct istream **input, struct ostream **output,
                                struct ssl_iostream **iostream_r,
                                const char **error_r)
 {
-       return ssl_vfuncs->create(ctx, event_parent, host, TRUE,
+       return ssl_vfuncs->create(ctx, event_parent, host, TRUE, flags,
                                  input, output, iostream_r, error_r);
 }
 
@@ -123,12 +124,13 @@ int io_stream_create_ssl_server(struct ssl_iostream_context *ctx,
                                struct ssl_iostream **iostream_r,
                                const char **error_r)
 {
-       return ssl_vfuncs->create(ctx, event_parent, NULL, TRUE,
+       return ssl_vfuncs->create(ctx, event_parent, NULL, TRUE, 0,
                                  input, output, iostream_r, error_r);
 }
 
 int io_stream_autocreate_ssl_client(
        struct event *event_parent, const char *host,
+       enum ssl_iostream_flags flags,
        struct istream **input, struct ostream **output,
        struct ssl_iostream **iostream_r,
        const char **error_r)
@@ -149,7 +151,7 @@ int io_stream_autocreate_ssl_client(
        if (ret < 0)
                return -1;
 
-       ret = io_stream_create_ssl_client(ctx, host, event_parent, input,
+       ret = io_stream_create_ssl_client(ctx, host, event_parent, flags, input,
                                          output, iostream_r, error_r);
        ssl_iostream_context_unref(&ctx);
        return ret;
index caff8f633b0ecb68bcc5681c6dbdd0fe630a78bf..78dbc42b48a0527edc317606d3ca0e49b4e3b095 100644 (file)
@@ -6,6 +6,14 @@
 struct ssl_iostream;
 struct ssl_iostream_context;
 
+enum ssl_iostream_flags {
+       /* Enable ssl_iostream_settings.allow_invalid_cert after context is
+          already created. If the context already has
+          ssl_iostream_settings.allow_invalid_cert enabled, it can't
+          be anymore disabled. */
+       SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT = BIT(0),
+};
+
 struct ssl_iostream_cert {
        const char *cert;
        const char *key;
@@ -69,6 +77,7 @@ int io_stream_ssl_global_init(const struct ssl_iostream_settings *set,
 
 int io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host,
                                struct event *event_parent,
+                               enum ssl_iostream_flags flags,
                                struct istream **input, struct ostream **output,
                                struct ssl_iostream **iostream_r,
                                const char **error_r);
@@ -82,6 +91,7 @@ int io_stream_create_ssl_server(struct ssl_iostream_context *ctx,
    get the context and call io_stream_create_ssl_client(). */
 int io_stream_autocreate_ssl_client(
        struct event *event_parent, const char *host,
+       enum ssl_iostream_flags flags,
        struct istream **input, struct ostream **output,
        struct ssl_iostream **iostream_r,
        const char **error_r);
@@ -147,7 +157,8 @@ int ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
    will always return FALSE before even checking the hostname. */
 bool ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io, const char *name,
                                  const char **reason_r);
-/* Returns ssl_iostream_settings.allow_invalid_cert. */
+/* Returns if ssl_iostream_settings.allow_invalid_cert is set or
+   SSL_IOSTREAM_FLAG_ALLOW_INVALID_CERT is used. */
 bool ssl_iostream_get_allow_invalid_cert(struct ssl_iostream *ssl_io);
 /* Returns username from the received certificate of the peer (client) if
    available, NULL if not. The username is based on cert_username_field
index ed6893accb4371312ed456ceb78ab4386f829c60..a11a3ad3846b6c4c70b35a1c0a1b83a751f53853 100644 (file)
@@ -222,7 +222,7 @@ static int test_iostream_ssl_handshake_real(struct ssl_iostream_settings *server
                ret = -1;
        }
 
-       if (io_stream_create_ssl_client(client->ctx, client->hostname, NULL,
+       if (io_stream_create_ssl_client(client->ctx, client->hostname, NULL, 0,
                                        &client->input, &client->output,
                                        &client->iostream, &error) != 0) {
                ret = -1;
@@ -416,7 +416,7 @@ static void test_iostream_ssl_get_buffer_avail_size(void)
        test_assert(io_stream_create_ssl_server(server->ctx, NULL,
                                                &server->input, &server->output,
                                                &server->iostream, &error) == 0);
-       test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL,
+       test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL, 0,
                                                &client->input, &client->output,
                                                &client->iostream, &error) == 0);
 
@@ -508,7 +508,7 @@ static void test_iostream_ssl_small_packets(void)
        test_assert(io_stream_create_ssl_server(server->ctx, NULL,
                                                &server->input, &server->output,
                                                &server->iostream, &error) == 0);
-       test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL,
+       test_assert(io_stream_create_ssl_client(client->ctx, "localhost", NULL, 0,
                                                &client->input, &client->output,
                                                &client->iostream, &error) == 0);
 
index c157c6c2cab6c09247ddab3a99a35eeec01bb1f2..eb7277177d148a4499aae5ceab142ad0da47f642 100644 (file)
@@ -574,7 +574,7 @@ static int pop3c_client_ssl_init(struct pop3c_client *client)
        }
 
        if (io_stream_create_ssl_client(client->ssl_ctx, client->set.host,
-                                       client->event,
+                                       client->event, 0,
                                        &client->input, &client->output,
                                        &client->ssl_iostream, &error) < 0) {
                e_error(client->event,
index c6fe54ac429282933f53d5397aae80dd0ca4790a..353bd066c96a83848585994a05472feb5c163298 100644 (file)
@@ -1238,7 +1238,7 @@ int login_proxy_starttls(struct login_proxy *proxy)
        }
 
        if (io_stream_create_ssl_client(ssl_ctx, proxy->host,
-                                       proxy->event,
+                                       proxy->event, 0,
                                        &proxy->server_input,
                                        &proxy->server_output,
                                        &proxy->server_ssl_iostream,