From 0be073f9d70d0d88127d550a24f5c735a8c04253 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Fri, 1 Apr 2016 09:52:17 -0700 Subject: [PATCH] Ticket #48784 - Make the SSL version set to the client library configurable. Description: The value to set to LDAP_OPT_X_TLS_PROTOCOL_MIN is hardcoded: optval = LDAP_OPT_X_TLS_PROTOCOL_SSL3; ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &optval); Changing the code to retrieve the supported SSL min version and set it. https://fedorahosted.org/389/ticket/48784 Reviewed by wibrown@redhat.com (Thank you, William!) --- ldap/servers/slapd/ldaputil.c | 42 ++++++++++------- ldap/servers/slapd/ssl.c | 87 +++++++++++++++++++++++++++++++++-- 2 files changed, 108 insertions(+), 21 deletions(-) diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c index 3851be5c8f..8a54cb9c2f 100644 --- a/ldap/servers/slapd/ldaputil.c +++ b/ldap/servers/slapd/ldaputil.c @@ -70,6 +70,11 @@ static PRCallOnceType ol_init_callOnce = {0,0}; static PRLock *ol_init_lock = NULL; +#if defined(USE_OPENLDAP) +extern void getSSLVersionRangeOL(int *min, int *max); +extern int getSSLVersionRange(char **min, char **max); +#endif + static PRStatus internal_ol_init_init(void) { @@ -572,35 +577,38 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) int rc = 0; if (config_get_ssl_check_hostname()) { - ssl_strength = LDAP_OPT_X_TLS_HARD; + ssl_strength = LDAP_OPT_X_TLS_HARD; } else { - /* verify certificate only */ - ssl_strength = LDAP_OPT_X_TLS_NEVER; + /* verify certificate only */ + ssl_strength = LDAP_OPT_X_TLS_NEVER; } if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &ssl_strength))) { - slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", - "failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength); + slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", + "failed: unable to set REQUIRE_CERT option to %d\n", ssl_strength); } /* tell it where our cert db is */ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, certdir))) { - slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", - "failed: unable to set CACERTDIR option to %s\n", certdir); + slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", + "failed: unable to set CACERTDIR option to %s\n", certdir); } slapi_ch_free_string(&certdir); #if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN) - optval = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + getSSLVersionRangeOL(&optval, NULL); if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &optval))) { - slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", - "failed: unable to set minimum TLS protocol level to SSL3\n"); + char *minstr = NULL; + (void)getSSLVersionRange(&minstr, NULL); + slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", + "failed: unable to set minimum TLS protocol level to %s\n", minstr); + slapi_ch_free_string(&minstr); } #endif /* LDAP_OPT_X_TLS_PROTOCOL_MIN */ if (clientauth) { - rc = slapd_SSL_client_auth(ld); - if (rc) { - slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", - "failed: unable to setup connection for TLS/SSL EXTERNAL client cert authentication - %d\n", rc); - } + rc = slapd_SSL_client_auth(ld); + if (rc) { + slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", + "failed: unable to setup connection for TLS/SSL EXTERNAL client cert authentication - %d\n", rc); + } } /* have to do this last - this creates the new TLS handle and sets/copies @@ -608,8 +616,8 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) that optval is zero, meaning create a context for a client */ optval = 0; if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &optval))) { - slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", - "failed: unable to create new TLS context - %d\n", rc); + slapi_log_error(SLAPI_LOG_FATAL, "setup_ol_tls_conn", + "failed: unable to create new TLS context - %d\n", rc); } return rc; diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c index 38efc73d03..544c9bcf39 100644 --- a/ldap/servers/slapd/ssl.c +++ b/ldap/servers/slapd/ssl.c @@ -380,21 +380,100 @@ getSSLVersionInfo(int *ssl2, int *ssl3, int *tls1) int getSSLVersionRange(char **min, char **max) { - if (!slapd_ssl_listener_is_initialized()) { + if (!min && !max) { return -1; } - if ((NULL == min) || (NULL == max)) { + if (!slapd_ssl_listener_is_initialized()) { + if (min) { + *min = slapi_getSSLVersion_str(LDAP_OPT_X_TLS_PROTOCOL_TLS1_0, NULL, 0); + } + if (max) { + *max = slapi_getSSLVersion_str(LDAP_OPT_X_TLS_PROTOCOL_TLS1_2, NULL, 0); + } return -1; } #if defined(NSS_TLS10) return -1; /* not supported */ #else /* NSS_TLS11 or newer */ - *min = slapi_getSSLVersion_str(slapdNSSVersions.min, NULL, 0); - *max = slapi_getSSLVersion_str(slapdNSSVersions.max, NULL, 0); + if (min) { + *min = slapi_getSSLVersion_str(slapdNSSVersions.min, NULL, 0); + } + if (max) { + *max = slapi_getSSLVersion_str(slapdNSSVersions.max, NULL, 0); + } return 0; #endif } +#if defined(USE_OPENLDAP) +void +getSSLVersionRangeOL(int *min, int *max) +{ + /* default range values */ + if (min) { + *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; + } + if (max) { + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; + } + if (!slapd_ssl_listener_is_initialized()) { + return; + } +#if defined(NSS_TLS10) + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; + return; +#else /* NSS_TLS11 or newer */ + if (min) { + switch (slapdNSSVersions.min) { + case SSL_LIBRARY_VERSION_3_0: + *min = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + break; + case SSL_LIBRARY_VERSION_TLS_1_0: + *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; + break; + case SSL_LIBRARY_VERSION_TLS_1_1: + *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_1; + break; + case SSL_LIBRARY_VERSION_TLS_1_2: + *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; + break; + default: + if (slapdNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) { + *min = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 + 1; + } else { + *min = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + } + break; + } + } + if (max) { + switch (slapdNSSVersions.max) { + case SSL_LIBRARY_VERSION_3_0: + *max = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + break; + case SSL_LIBRARY_VERSION_TLS_1_0: + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; + break; + case SSL_LIBRARY_VERSION_TLS_1_1: + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_1; + break; + case SSL_LIBRARY_VERSION_TLS_1_2: + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; + break; + default: + if (slapdNSSVersions.max > SSL_LIBRARY_VERSION_TLS_1_2) { + *max = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 + 1; + } else { + *max = LDAP_OPT_X_TLS_PROTOCOL_SSL3; + } + break; + } + } + return; +#endif +} +#endif /* USE_OPENLDAP */ + static void _conf_init_ciphers() {