]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: Use application protocol negotiation
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 14 May 2024 16:32:09 +0000 (19:32 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:40:01 +0000 (10:40 +0200)
src/login-common/client-common.c
src/login-common/login-common.h
src/login-common/login-proxy.c

index 2cd3b21981fe361ee980000ffd95bbb91496653a..cbec0eca0dc98754c94d3b1d301ac131b6c8a64f 100644 (file)
@@ -220,6 +220,15 @@ static int client_settings_get(struct client *client, const char **error_r)
        return 0;
 }
 
+static bool application_protocol_equals(const char *proto)
+{
+       /* If login binary has no application protocols configured
+          we accept whatever we get. */
+       if (login_binary->application_protocols == NULL)
+               return TRUE;
+       return str_array_find(login_binary->application_protocols, proto);
+}
+
 int client_alloc(int fd, const struct master_service_connection *conn,
                 struct client **client_r)
 {
@@ -304,6 +313,18 @@ int client_alloc(int fd, const struct master_service_connection *conn,
                client->end_client_tls_secured = conn->haproxy.ssl;
                client->local_name = conn->haproxy.hostname;
                client->client_cert_common_name = conn->haproxy.cert_common_name;
+               /* Check that alpn matches. */
+               if (conn->haproxy.alpn_size > 0) {
+                       const char *proto =
+                               t_strndup(conn->haproxy.alpn, conn->haproxy.alpn_size);
+                       if (!application_protocol_equals(proto)) {
+                               e_error(client->event, "HAproxy application protocol mismatch (requested '%s')",
+                                       proto);
+                               event_unref(&client->event);
+                               pool_unref(&client->pool);
+                               return -1;
+                       }
+               }
        } else if (net_ip_compare(&conn->real_remote_ip, &conn->real_local_ip)) {
                /* localhost connections are always secured */
                client->connection_secured = TRUE;
@@ -702,6 +723,10 @@ int client_sni_callback(const char *name, const char **error_r,
                return -1;
        }
        settings_free(ssl_set);
+       if (login_binary->application_protocols != NULL) {
+               ssl_iostream_context_set_application_protocols(ssl_ctx,
+                       login_binary->application_protocols);
+       }
        ssl_iostream_change_context(client->ssl_iostream, ssl_ctx);
        ssl_iostream_context_unref(&ssl_ctx);
 
@@ -729,6 +754,7 @@ int client_init_ssl(struct client *client)
                client->v.iostream_change_pre(client);
        const struct ssl_iostream_server_autocreate_parameters parameters = {
                .event_parent = client->event,
+               .application_protocols = login_binary->application_protocols,
        };
        int ret = io_stream_autocreate_ssl_server(&parameters,
                                                  &client->input, &client->output,
index 37726757607f721aab9c1e6192258194a4af1b39..7156745d8eb644e41e961cb1fde328658f3341d5 100644 (file)
@@ -21,6 +21,8 @@ struct login_binary {
        const char *protocol;
        /* e.g. imap-login, pop3-login */
        const char *process_name;
+       /* e.g. ManageSieve, h2.. */
+       const char *const *application_protocols;
 
        /* e.g. 143, 110 */
        in_port_t default_port;
index be17623ee36797e0675e8ff6693be98ba0c40e1c..5c31086eedaccf1e7c0db5759beb34d0b11f0204 100644 (file)
@@ -1226,6 +1226,7 @@ int login_proxy_starttls(struct login_proxy *proxy)
                .event_parent = proxy->event,
                .host = proxy->host,
                .flags = ssl_flags,
+               .application_protocols = login_binary->application_protocols,
        };
        if (io_stream_autocreate_ssl_client(&parameters,
                                            &proxy->server_input,