From 656b141630c5f37a953a75ff05d3a1a30b14eef1 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 1 Feb 2018 14:28:24 -0500 Subject: [PATCH] Ticket 49557 - Add config option for checking CRL on outbound SSL Connections Bug Description: There are cases where a CRL is not available during an outbound replication connection. This is seen as an error by openldap, and the connection fails. Fix Description: Add on/off option for checking the CRL. The default is not to check the CRL. https://pagure.io/389-ds-base/issue/49557 Reviewed by: wibrown, Ludwig Krispenz, Thierry Bordaz --- dirsrvtests/tests/suites/{ssl => tls}/__init__.py | 0 dirsrvtests/tests/suites/tls/tls_check_crl_test.py | 52 +++++++++++++++++ ldap/schema/01core389.ldif | 1 + ldap/servers/slapd/ldaputil.c | 9 ++- ldap/servers/slapd/libglobs.c | 66 +++++++++++++++++++++- ldap/servers/slapd/proto-slap.h | 2 + ldap/servers/slapd/slap.h | 10 +++- 7 files changed, 135 insertions(+), 5 deletions(-) rename dirsrvtests/tests/suites/{ssl => tls}/__init__.py (100%) create mode 100644 dirsrvtests/tests/suites/tls/tls_check_crl_test.py diff --git a/dirsrvtests/tests/suites/ssl/__init__.py b/dirsrvtests/tests/suites/tls/__init__.py similarity index 100% rename from dirsrvtests/tests/suites/ssl/__init__.py rename to dirsrvtests/tests/suites/tls/__init__.py diff --git a/dirsrvtests/tests/suites/tls/tls_check_crl_test.py b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py new file mode 100644 index 000000000..8b4d07f94 --- /dev/null +++ b/dirsrvtests/tests/suites/tls/tls_check_crl_test.py @@ -0,0 +1,52 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2018 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# + + +import pytest +import ldap +from lib389.topologies import topology_st + +def test_tls_check_crl(topology_st): + """Test that TLS check_crl configurations work as expected. + + :id: + :steps: + 1. Enable TLS + 2. Set invalid value + 3. Set valid values + 4. Check config reset + :expectedresults: + 1. TlS is setup + 2. The invalid value is rejected + 3. The valid values are used + 4. The value can be reset + """ + standalone = topology_st.standalone + # Enable TLS + standalone.enable_tls() + # Check all the valid values. + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') + with pytest.raises(ldap.OPERATIONS_ERROR): + standalone.config.set('nsslapd-tls-check-crl', 'tnhoeutnoeutn') + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') + + standalone.config.set('nsslapd-tls-check-crl', 'peer') + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'peer') + + standalone.config.set('nsslapd-tls-check-crl', 'none') + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') + + standalone.config.set('nsslapd-tls-check-crl', 'all') + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'all') + + standalone.config.remove_all('nsslapd-tls-check-crl') + assert(standalone.config.get_attr_val_utf8('nsslapd-tls-check-crl') == 'none') + + + diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif index ab124c86c..c7f9fef2b 100644 --- a/ldap/schema/01core389.ldif +++ b/ldap/schema/01core389.ldif @@ -304,6 +304,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2332 NAME 'allowWeakDHParam' DESC 'Netsc attributeTypes: ( 2.16.840.1.113730.3.1.2333 NAME 'nsds5ReplicaReleaseTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2335 NAME 'nsds5ReplicaIgnoreMissingChange' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2336 NAME 'nsDS5ReplicaBindDnGroupCheckInterval' DESC 'Replication configuration setting for controlling the bind dn group check interval' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) +attributeTypes: ( 2.16.840.1.113730.3.1.2344 NAME 'nsslapd-tls-check-crl' DESC 'Check CRL when opening outbound TLS connections. Valid options are none, peer, all.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' ) # # objectclasses # diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c index fa9d276a3..2fc2f0615 100644 --- a/ldap/servers/slapd/ldaputil.c +++ b/ldap/servers/slapd/ldaputil.c @@ -570,6 +570,7 @@ slapi_ldif_parse_line( } #if defined(USE_OPENLDAP) + static int setup_ol_tls_conn(LDAP *ld, int clientauth) { @@ -602,7 +603,13 @@ setup_ol_tls_conn(LDAP *ld, int clientauth) } } if (slapi_client_uses_openssl(ld)) { - const int crlcheck = LDAP_OPT_X_TLS_CRL_ALL; + int32_t crlcheck = LDAP_OPT_X_TLS_CRL_NONE; + tls_check_crl_t tls_check_state = config_get_tls_check_crl(); + if (tls_check_state == TLS_CHECK_PEER) { + crlcheck = LDAP_OPT_X_TLS_CRL_PEER; + } else if (tls_check_state == TLS_CHECK_ALL) { + crlcheck = LDAP_OPT_X_TLS_CRL_ALL; + } /* Sets the CRL evaluation strategy. */ rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CRLCHECK, &crlcheck); if (rc) { diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index c1a765aca..eb6552af1 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -157,7 +157,8 @@ typedef enum { CONFIG_STRING_OR_EMPTY, /* use an empty string */ CONFIG_SPECIAL_ANON_ACCESS_SWITCH, /* maps strings to an enumeration */ CONFIG_SPECIAL_VALIDATE_CERT_SWITCH, /* maps strings to an enumeration */ - CONFIG_SPECIAL_UNHASHED_PW_SWITCH /* unhashed pw: on/off/nolog */ + CONFIG_SPECIAL_UNHASHED_PW_SWITCH, /* unhashed pw: on/off/nolog */ + CONFIG_SPECIAL_TLS_CHECK_CRL, /* maps enum tls_check_crl_t to char * */ } ConfigVarType; static int32_t config_set_onoff(const char *attrname, char *value, int32_t *configvalue, char *errorbuf, int apply); @@ -1173,7 +1174,15 @@ static struct config_get_and_set {CONFIG_LOGGING_BACKEND, NULL, log_set_backend, 0, (void **)&global_slapdFrontendConfig.logging_backend, - CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL}}; + CONFIG_STRING_OR_EMPTY, NULL, SLAPD_INIT_LOGGING_BACKEND_INTERNAL}, + {CONFIG_TLS_CHECK_CRL_ATTRIBUTE, config_set_tls_check_crl, + NULL, 0, + (void **)&global_slapdFrontendConfig.tls_check_crl, + CONFIG_SPECIAL_TLS_CHECK_CRL, (ConfigGetFunc)config_get_tls_check_crl, + "none" /* Allow reset to this value */} + + /* End config */ + }; /* * hashNocaseString - used for case insensitive hash lookups @@ -1506,7 +1515,6 @@ FrontendConfig_init(void) cfg->maxdescriptors = SLAPD_DEFAULT_MAXDESCRIPTORS; cfg->groupevalnestlevel = SLAPD_DEFAULT_GROUPEVALNESTLEVEL; cfg->snmp_index = SLAPD_DEFAULT_SNMP_INDEX; - cfg->SSLclientAuth = SLAPD_DEFAULT_SSLCLIENTAUTH; #ifdef USE_SYSCONF @@ -1524,6 +1532,7 @@ FrontendConfig_init(void) #endif init_security = cfg->security = LDAP_OFF; init_ssl_check_hostname = cfg->ssl_check_hostname = LDAP_ON; + cfg->tls_check_crl = TLS_CHECK_NONE; init_return_exact_case = cfg->return_exact_case = LDAP_ON; init_result_tweak = cfg->result_tweak = LDAP_OFF; init_attrname_exceptions = cfg->attrname_exceptions = LDAP_OFF; @@ -2042,6 +2051,7 @@ config_set_port(const char *attrname, char *port, char *errorbuf, int apply) return retVal; } + int config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply) { @@ -2073,6 +2083,33 @@ config_set_secureport(const char *attrname, char *port, char *errorbuf, int appl } +int32_t +config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply) +{ + int32_t retVal = LDAP_SUCCESS; + /* Default */ + tls_check_crl_t state = TLS_CHECK_NONE; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + if (strcasecmp(value, "none") == 0) { + state = TLS_CHECK_NONE; + } else if (strcasecmp(value, "peer") == 0) { + state = TLS_CHECK_PEER; + } else if (strcasecmp(value, "all") == 0) { + state = TLS_CHECK_ALL; + } else { + retVal = LDAP_OPERATIONS_ERROR; + slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: unsupported value: %s", attrname, value); + } + + if (retVal == LDAP_SUCCESS && apply) { + slapi_atomic_store_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), state, __ATOMIC_RELEASE); + } + + return retVal; +} + + int config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply) { @@ -4591,6 +4628,12 @@ config_set_versionstring(const char *attrname __attribute__((unused)), char *ver #define config_copy_strval(s) s ? slapi_ch_strdup(s) : NULL; +tls_check_crl_t +config_get_tls_check_crl() { + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + return (tls_check_crl_t)slapi_atomic_load_32((int32_t *)&(slapdFrontendConfig->tls_check_crl), __ATOMIC_ACQUIRE); +} + int config_get_port() { @@ -7439,6 +7482,23 @@ config_set_value( slapi_entry_attr_set_int(e, cgas->attr_name, ival); break; + case CONFIG_SPECIAL_TLS_CHECK_CRL: + if (!value) { + slapi_entry_attr_set_charptr(e, cgas->attr_name, (char *)cgas->initvalue); + break; + } + tls_check_crl_t state = *(tls_check_crl_t *)value; + + if (state == TLS_CHECK_ALL) { + sval = "all"; + } else if (state == TLS_CHECK_PEER) { + sval = "peer"; + } else { + sval = "none"; + } + slapi_entry_attr_set_charptr(e, cgas->attr_name, sval); + break; + case CONFIG_SPECIAL_SSLCLIENTAUTH: if (!value) { slapi_entry_attr_set_charptr(e, cgas->attr_name, "off"); diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 3b7ab53b2..b13334ad1 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -236,6 +236,7 @@ int config_set_port(const char *attrname, char *port, char *errorbuf, int apply) int config_set_secureport(const char *attrname, char *port, char *errorbuf, int apply); int config_set_SSLclientAuth(const char *attrname, char *value, char *errorbuf, int apply); int config_set_ssl_check_hostname(const char *attrname, char *value, char *errorbuf, int apply); +int32_t config_set_tls_check_crl(const char *attrname, char *value, char *errorbuf, int apply); int config_set_SSL3ciphers(const char *attrname, char *value, char *errorbuf, int apply); int config_set_localhost(const char *attrname, char *value, char *errorbuf, int apply); int config_set_listenhost(const char *attrname, char *value, char *errorbuf, int apply); @@ -397,6 +398,7 @@ void log_disable_hr_timestamps(void); int config_get_SSLclientAuth(void); int config_get_ssl_check_hostname(void); +tls_check_crl_t config_get_tls_check_crl(void); char *config_get_SSL3ciphers(void); char *config_get_localhost(void); char *config_get_listenhost(void); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 216d94afd..443d90094 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -443,6 +443,13 @@ typedef void (*VFPV)(); /* takes undefined arguments */ typedef int32_t slapi_onoff_t; typedef int32_t slapi_int_t; +typedef enum _tls_check_crl_t { + TLS_CHECK_NONE = 0, + TLS_CHECK_PEER = 1, + TLS_CHECK_ALL = 2, +} tls_check_crl_t; + + struct subfilt { char *sf_type; @@ -2151,6 +2158,7 @@ typedef struct _slapdEntryPoints #define CONFIG_RUNDIR_ATTRIBUTE "nsslapd-rundir" #define CONFIG_SSLCLIENTAUTH_ATTRIBUTE "nsslapd-SSLclientAuth" #define CONFIG_SSL_CHECK_HOSTNAME_ATTRIBUTE "nsslapd-ssl-check-hostname" +#define CONFIG_TLS_CHECK_CRL_ATTRIBUTE "nsslapd-tls-check-crl" #define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters" #define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout" #define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external" @@ -2263,6 +2271,7 @@ typedef struct _slapdFrontendConfig slapi_onoff_t security; int SSLclientAuth; slapi_onoff_t ssl_check_hostname; + tls_check_crl_t tls_check_crl; int validate_cert; int sizelimit; int SNMPenabled; @@ -2294,7 +2303,6 @@ typedef struct _slapdFrontendConfig slapi_onoff_t plugin_track; slapi_onoff_t moddn_aci; struct pw_scheme *pw_storagescheme; - slapi_onoff_t pwpolicy_local; slapi_onoff_t pw_is_global_policy; slapi_onoff_t pwpolicy_inherit_global; -- 2.13.6