Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/lib-ldap/ldap-connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ int ldap_connection_setup(struct ldap_connection *conn, const char **error_r)
conn->set->uris, conn->ssl_set, error_r) < 0)
return -1;

#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
/* refuse to connect to SSLv2 as it's completely insecure */
opt = LDAP_OPT_X_TLS_PROTOCOL_SSL3;
ldap_set_option(conn->conn, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt);
#endif
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done in ldap_set_tls_options().

opt = conn->set->timeout_secs;
/* default timeout */
ldap_set_option(conn->conn, LDAP_OPT_TIMEOUT, &opt);
Expand All @@ -79,11 +74,6 @@ int ldap_connection_setup(struct ldap_connection *conn, const char **error_r)

ldap_set_option(conn->conn, LDAP_OPT_REFERRALS, 0);

#ifdef LDAP_OPT_X_TLS_NEWCTX
opt = 0;
ldap_set_option(conn->conn, LDAP_OPT_X_TLS_NEWCTX, &opt);
#endif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done in ldap_set_tls_options().

return 0;
}

Expand Down
56 changes: 45 additions & 11 deletions src/lib-ldap/ldap-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@ int ldap_set_tls_options(LDAP *ld ATTR_UNUSED, bool starttls ATTR_UNUSED,
return 0;
}
#else
static const struct {
const char *name;
int opt;
} protocol_versions[] = {
{ "ANY", LDAP_OPT_X_TLS_PROTOCOL_SSL3 },
{ "TLSv1", LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 },
{ "TLSv1.1", LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 },
{ "TLSv1.2", LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 },
{ "TLSv1.3", LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 },
{ "LATEST", LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 }
};

static int ldap_min_protocol_to_option(const char *min_protocol, int *opt_r)
{
unsigned int i = 0;
for (; i < N_ELEMENTS(protocol_versions); i++) {
if (strcasecmp(protocol_versions[i].name, min_protocol) == 0) {
*opt_r = protocol_versions[i].opt;
return 0;
}
}
return -1;
}

int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris,
const struct ssl_settings *ssl_set,
const char **error_r)
Expand Down Expand Up @@ -70,29 +94,39 @@ int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris,
ssl_set->ssl_cipher_list,
"ssl_cipher_list", error_r) < 0)
return -1;
if (ldap_set_opt_str(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN,
ssl_set->ssl_min_protocol,
"ssl_min_protocol", error_r) < 0)
return -1;
if (ldap_set_opt_str(ld, LDAP_OPT_X_TLS_ECNAME,
ssl_set->ssl_curve_list,
"ssl_curve_list", error_r) < 0)
return -1;

bool requires = ssl_set->ssl_client_require_valid_cert;
int opt = requires ? LDAP_OPT_X_TLS_HARD : LDAP_OPT_X_TLS_ALLOW;

/* required for Bookworm */
if (ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's required for Bookworm and others to either set the global TLS options (by passing a NULL LDAP handle for ldap_set_option) and not to create a connection specific TLS context (by setting the LDAP_OPT_X_TLS_NEWCTX option) or to set the connection specific TLS options (by passing a non-NULL LDAP handle for ldap_set_option like on RHEL9) and to create a connection specific TLS context (by setting the LDAP_OPT_X_TLS_NEWCTX option).

It's better to set set the connection specific TLS options and to create a connection specific TLS context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in the commit message.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (ldap_set_opt(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt,
"ssl_client_require_valid_cert",
requires ? "yes" : "no", error_r) < 0)
return -1;

/* required for RHEL9 */
if (ldap_set_opt(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt,
"ssl_client_require_valid_cert",
requires ? "yes" : "no", error_r) < 0)
if (ldap_min_protocol_to_option(
*ssl_set->ssl_min_protocol != '\0'
? ssl_set->ssl_min_protocol
: "ANY",
&opt) < 0) {
*error_r = t_strdup_printf("Can't set option %s to %s: %s",
"ssl_min_protocol", ssl_set->ssl_min_protocol,
"Unknown value");
return -1;
}
if (ldap_set_opt(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt,
"ssl_min_protocol", ssl_set->ssl_min_protocol,
error_r) < 0)
return -1;

#ifdef LDAP_OPT_X_TLS_NEWCTX
bool is_server = false;
opt = is_server;
ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &opt);
#endif

return 0;
}

Expand Down