From 3998745d608a1a96c0985d4f2191a944ca5b43a6 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Wed, 8 Nov 2023 04:15:03 +0100 Subject: [PATCH] auth: auth-mech-connection - Do not announce channel binding mechanisms for minor version < 3 Otherwise, old auth clients like Postfix that don't know about channel binding would announce these mechanisms, while using them would always fail. --- src/auth/auth-client-connection.c | 10 +++++++--- src/auth/mech.c | 27 +++++++++++++++++---------- src/auth/mech.h | 1 + 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/auth/auth-client-connection.c b/src/auth/auth-client-connection.c index 49fdac43dc..b328634830 100644 --- a/src/auth/auth-client-connection.c +++ b/src/auth/auth-client-connection.c @@ -185,7 +185,7 @@ auth_client_cancel(struct auth_client_connection *conn, const char *const *args) static void auth_client_finish_handshake(struct auth_client_connection *conn) { - const char *mechanisms; + const char *mechanisms, *mechanisms_cbind = ""; string_t *str; if (conn->token_auth) { @@ -193,11 +193,15 @@ static void auth_client_finish_handshake(struct auth_client_connection *conn) mech_dovecot_token.mech_name, "\tprivate\n", NULL); } else { mechanisms = str_c(conn->auth->reg->handshake); + if (conn->conn.minor_version >= 3) { + mechanisms_cbind = + str_c(conn->auth->reg->handshake_cbind); + } } str = t_str_new(128); - str_printfa(str, "%sSPID\t%s\nCUID\t%u\nCOOKIE\t", - mechanisms, my_pid, conn->connect_uid); + str_printfa(str, "%s%sSPID\t%s\nCUID\t%u\nCOOKIE\t", + mechanisms, mechanisms_cbind, my_pid, conn->connect_uid); binary_to_hex_append(str, conn->cookie, sizeof(conn->cookie)); str_append(str, "\nDONE\n"); diff --git a/src/auth/mech.c b/src/auth/mech.c index aff631945d..67e6df2dd6 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -90,28 +90,34 @@ static void mech_register_add(struct mechanisms_register *reg, const struct mech_module *mech) { struct mech_module_list *list; + string_t *handshake; list = p_new(reg->pool, struct mech_module_list, 1); list->module = *mech; - str_printfa(reg->handshake, "MECH\t%s", mech->mech_name); + if ((mech->flags & MECH_SEC_CHANNEL_BINDING) != 0) + handshake = reg->handshake_cbind; + else + handshake = reg->handshake; + + str_printfa(handshake, "MECH\t%s", mech->mech_name); if ((mech->flags & MECH_SEC_PRIVATE) != 0) - str_append(reg->handshake, "\tprivate"); + str_append(handshake, "\tprivate"); if ((mech->flags & MECH_SEC_ANONYMOUS) != 0) - str_append(reg->handshake, "\tanonymous"); + str_append(handshake, "\tanonymous"); if ((mech->flags & MECH_SEC_PLAINTEXT) != 0) - str_append(reg->handshake, "\tplaintext"); + str_append(handshake, "\tplaintext"); if ((mech->flags & MECH_SEC_DICTIONARY) != 0) - str_append(reg->handshake, "\tdictionary"); + str_append(handshake, "\tdictionary"); if ((mech->flags & MECH_SEC_ACTIVE) != 0) - str_append(reg->handshake, "\tactive"); + str_append(handshake, "\tactive"); if ((mech->flags & MECH_SEC_FORWARD_SECRECY) != 0) - str_append(reg->handshake, "\tforward-secrecy"); + str_append(handshake, "\tforward-secrecy"); if ((mech->flags & MECH_SEC_MUTUAL_AUTH) != 0) - str_append(reg->handshake, "\tmutual-auth"); + str_append(handshake, "\tmutual-auth"); if ((mech->flags & MECH_SEC_CHANNEL_BINDING) != 0) - str_append(reg->handshake, "\tchannel-binding"); - str_append_c(reg->handshake, '\n'); + str_append(handshake, "\tchannel-binding"); + str_append_c(handshake, '\n'); list->next = reg->modules; reg->modules = list; @@ -144,6 +150,7 @@ mech_register_init(const struct auth_settings *set) reg->pool = pool; reg->set = set; reg->handshake = str_new(pool, 512); + reg->handshake_cbind = str_new(pool, 256); if (!array_is_created(&set->mechanisms) || array_is_empty(&set->mechanisms)) diff --git a/src/auth/mech.h b/src/auth/mech.h index 885d8e027c..905d9e0857 100644 --- a/src/auth/mech.h +++ b/src/auth/mech.h @@ -53,6 +53,7 @@ struct mechanisms_register { struct mech_module_list *modules; buffer_t *handshake; + buffer_t *handshake_cbind; }; extern const struct mech_module mech_dovecot_token; -- 2.47.3