Add/rename parameters that control TLS

This commit is contained in:
Denis Glazachev 2020-06-12 21:59:47 +04:00
parent 04f222f85b
commit 276fcd8903
4 changed files with 134 additions and 40 deletions

View File

@ -209,10 +209,15 @@
Specify 'no' for plain text (ldap://) protocol (not recommended).
Specify 'yes' for LDAP over SSL/TLS (ldaps://) protocol (recommended, the default).
Specify 'starttls' for legacy StartTLS protocol (plain text (ldap://) protocol, upgraded to TLS).
tls_cert_verify - TLS peer certificate verification behavior.
Accepted values are: never, allow, try, demand.
ca_cert_dir - path to CA certificates directory.
ca_cert_file - path to CA certificate file.
tls_minimum_protocol_version - the minimum protocol version of SSL/TLS.
Accepted values are: 'ssl2', 'ssl3', 'tls1.0', 'tls1.1', 'tls1.2' (the default).
tls_require_cert - SSL/TLS peer certificate verification behavior.
Accepted values are: 'never', 'allow', 'try', 'demand' (the default).
tls_cert_file - path to certificate file.
tls_key_file - path to certificate key file.
tls_ca_cert_file - path to CA certificate file.
tls_ca_cert_dir - path to the directory containing CA certificates.
tls_cipher_suite - allowed cipher suite.
Example:
<my_ldap_server>
<host>localhost</host>
@ -220,9 +225,13 @@
<auth_dn_prefix>cn=</auth_dn_prefix>
<auth_dn_suffix>, ou=users, dc=example, dc=com</auth_dn_suffix>
<enable_tls>yes</enable_tls>
<tls_cert_verify>demand</tls_cert_verify>
<ca_cert_dir>/path/to/ca_cert_dir</ca_cert_dir>
<ca_cert_file>/path/to/ca_cert_file</ca_cert_file>
<tls_minimum_protocol_version>tls1.2</tls_minimum_protocol_version>
<tls_require_cert>demand</tls_require_cert>
<tls_cert_file>/path/to/tls_cert_file</tls_cert_file>
<tls_key_file>/path/to/tls_key_file</tls_key_file>
<tls_ca_cert_file>/path/to/tls_ca_cert_file</tls_ca_cert_file>
<tls_ca_cert_dir>/path/to/tls_ca_cert_dir</tls_ca_cert_dir>
<tls_cipher_suite>SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:-RSA:-DHE-DSS:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC</tls_cipher_suite>
</my_ldap_server>
-->
</ldap_servers>

View File

@ -30,9 +30,13 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
const bool has_auth_dn_prefix = config.has(ldap_server_config + ".auth_dn_prefix");
const bool has_auth_dn_suffix = config.has(ldap_server_config + ".auth_dn_suffix");
const bool has_enable_tls = config.has(ldap_server_config + ".enable_tls");
const bool has_tls_cert_verify = config.has(ldap_server_config + ".tls_cert_verify");
const bool has_ca_cert_dir = config.has(ldap_server_config + ".ca_cert_dir");
const bool has_ca_cert_file = config.has(ldap_server_config + ".ca_cert_file");
const bool has_tls_minimum_protocol_version = config.has(ldap_server_config + ".tls_minimum_protocol_version");
const bool has_tls_require_cert = config.has(ldap_server_config + ".tls_require_cert");
const bool has_tls_cert_file = config.has(ldap_server_config + ".tls_cert_file");
const bool has_tls_key_file = config.has(ldap_server_config + ".tls_key_file");
const bool has_tls_ca_cert_file = config.has(ldap_server_config + ".tls_ca_cert_file");
const bool has_tls_ca_cert_dir = config.has(ldap_server_config + ".tls_ca_cert_dir");
const bool has_tls_cipher_suite = config.has(ldap_server_config + ".tls_cipher_suite");
if (!has_host)
throw Exception("Missing 'host' entry", ErrorCodes::BAD_ARGUMENTS);
@ -61,28 +65,56 @@ auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const Str
params.enable_tls = LDAPServerParams::TLSEnable::NO;
}
if (has_tls_cert_verify)
if (has_tls_minimum_protocol_version)
{
String tls_cert_verify_lc_str = config.getString(ldap_server_config + ".tls_cert_verify");
boost::to_lower(tls_cert_verify_lc_str);
String tls_minimum_protocol_version_lc_str = config.getString(ldap_server_config + ".tls_minimum_protocol_version");
boost::to_lower(tls_minimum_protocol_version_lc_str);
if (tls_cert_verify_lc_str == "never")
params.tls_cert_verify = LDAPServerParams::TLSCertVerify::NEVER;
else if (tls_cert_verify_lc_str == "allow")
params.tls_cert_verify = LDAPServerParams::TLSCertVerify::ALLOW;
else if (tls_cert_verify_lc_str == "try")
params.tls_cert_verify = LDAPServerParams::TLSCertVerify::TRY;
else if (tls_cert_verify_lc_str == "demand")
params.tls_cert_verify = LDAPServerParams::TLSCertVerify::DEMAND;
if (tls_minimum_protocol_version_lc_str == "ssl2")
params.tls_minimum_protocol_version = LDAPServerParams::TLSProtocolVersion::SSL2;
else if (tls_minimum_protocol_version_lc_str == "ssl3")
params.tls_minimum_protocol_version = LDAPServerParams::TLSProtocolVersion::SSL3;
else if (tls_minimum_protocol_version_lc_str == "tls1.0")
params.tls_minimum_protocol_version = LDAPServerParams::TLSProtocolVersion::TLS1_0;
else if (tls_minimum_protocol_version_lc_str == "tls1.1")
params.tls_minimum_protocol_version = LDAPServerParams::TLSProtocolVersion::TLS1_1;
else if (tls_minimum_protocol_version_lc_str == "tls1.2")
params.tls_minimum_protocol_version = LDAPServerParams::TLSProtocolVersion::TLS1_2;
else
throw Exception("Bad value for 'tls_cert_verify' entry, allowed values are: 'never', 'allow', 'try', 'demand'", ErrorCodes::BAD_ARGUMENTS);
throw Exception("Bad value for 'tls_minimum_protocol_version' entry, allowed values are: 'ssl2', 'ssl3', 'tls1.0', 'tls1.1', 'tls1.2'", ErrorCodes::BAD_ARGUMENTS);
}
if (has_ca_cert_dir)
params.ca_cert_dir = config.getString(ldap_server_config + ".ca_cert_dir");
if (has_tls_require_cert)
{
String tls_require_cert_lc_str = config.getString(ldap_server_config + ".tls_require_cert");
boost::to_lower(tls_require_cert_lc_str);
if (has_ca_cert_file)
params.ca_cert_file = config.getString(ldap_server_config + ".ca_cert_file");
if (tls_require_cert_lc_str == "never")
params.tls_require_cert = LDAPServerParams::TLSRequireCert::NEVER;
else if (tls_require_cert_lc_str == "allow")
params.tls_require_cert = LDAPServerParams::TLSRequireCert::ALLOW;
else if (tls_require_cert_lc_str == "try")
params.tls_require_cert = LDAPServerParams::TLSRequireCert::TRY;
else if (tls_require_cert_lc_str == "demand")
params.tls_require_cert = LDAPServerParams::TLSRequireCert::DEMAND;
else
throw Exception("Bad value for 'tls_require_cert' entry, allowed values are: 'never', 'allow', 'try', 'demand'", ErrorCodes::BAD_ARGUMENTS);
}
if (has_tls_cert_file)
params.tls_cert_file = config.getString(ldap_server_config + ".tls_cert_file");
if (has_tls_key_file)
params.tls_key_file = config.getString(ldap_server_config + ".tls_key_file");
if (has_tls_ca_cert_file)
params.tls_ca_cert_file = config.getString(ldap_server_config + ".tls_ca_cert_file");
if (has_tls_ca_cert_dir)
params.tls_ca_cert_dir = config.getString(ldap_server_config + ".tls_ca_cert_dir");
if (has_tls_cipher_suite)
params.tls_cipher_suite = config.getString(ldap_server_config + ".tls_cipher_suite");
if (has_port)
{

View File

@ -140,19 +140,23 @@ int LDAPClient::openConnection(const bool graceful_bind_failure)
diag(ldap_set_option(handle, LDAP_OPT_KEEPCONN, LDAP_OPT_ON));
#endif
#ifdef LDAP_OPT_TIMEOUT
{
::timeval operation_timeout;
operation_timeout.tv_sec = params.operation_timeout.count();
operation_timeout.tv_usec = 0;
diag(ldap_set_option(handle, LDAP_OPT_TIMEOUT, &operation_timeout));
}
#endif
#ifdef LDAP_OPT_NETWORK_TIMEOUT
{
::timeval network_timeout;
network_timeout.tv_sec = params.network_timeout.count();
network_timeout.tv_usec = 0;
diag(ldap_set_option(handle, LDAP_OPT_NETWORK_TIMEOUT, &network_timeout));
}
#endif
{
const int search_timeout = params.search_timeout.count();
@ -164,23 +168,59 @@ int LDAPClient::openConnection(const bool graceful_bind_failure)
diag(ldap_set_option(handle, LDAP_OPT_SIZELIMIT, &size_limit));
}
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
{
int value = 0;
switch (params.tls_cert_verify)
switch (params.tls_minimum_protocol_version)
{
case LDAPServerParams::TLSCertVerify::NEVER: value = LDAP_OPT_X_TLS_NEVER; break;
case LDAPServerParams::TLSCertVerify::ALLOW: value = LDAP_OPT_X_TLS_ALLOW; break;
case LDAPServerParams::TLSCertVerify::TRY: value = LDAP_OPT_X_TLS_TRY; break;
case LDAPServerParams::TLSCertVerify::DEMAND: value = LDAP_OPT_X_TLS_DEMAND; break;
case LDAPServerParams::TLSProtocolVersion::SSL2: value = LDAP_OPT_X_TLS_PROTOCOL_SSL2; break;
case LDAPServerParams::TLSProtocolVersion::SSL3: value = LDAP_OPT_X_TLS_PROTOCOL_SSL3; break;
case LDAPServerParams::TLSProtocolVersion::TLS1_0: value = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; break;
case LDAPServerParams::TLSProtocolVersion::TLS1_1: value = LDAP_OPT_X_TLS_PROTOCOL_TLS1_1; break;
case LDAPServerParams::TLSProtocolVersion::TLS1_2: value = LDAP_OPT_X_TLS_PROTOCOL_TLS1_2; break;
}
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_PROTOCOL_MIN, &value));
}
#endif
#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
{
int value = 0;
switch (params.tls_require_cert)
{
case LDAPServerParams::TLSRequireCert::NEVER: value = LDAP_OPT_X_TLS_NEVER; break;
case LDAPServerParams::TLSRequireCert::ALLOW: value = LDAP_OPT_X_TLS_ALLOW; break;
case LDAPServerParams::TLSRequireCert::TRY: value = LDAP_OPT_X_TLS_TRY; break;
case LDAPServerParams::TLSRequireCert::DEMAND: value = LDAP_OPT_X_TLS_DEMAND; break;
}
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_REQUIRE_CERT, &value));
}
#endif
if (!params.ca_cert_dir.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CACERTDIR, params.ca_cert_dir.c_str()));
#ifdef LDAP_OPT_X_TLS_CERTFILE
if (!params.tls_cert_file.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CERTFILE, params.tls_cert_file.c_str()));
#endif
if (!params.ca_cert_file.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CACERTFILE, params.ca_cert_file.c_str()));
#ifdef LDAP_OPT_X_TLS_KEYFILE
if (!params.tls_key_file.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_KEYFILE, params.tls_key_file.c_str()));
#endif
#ifdef LDAP_OPT_X_TLS_CACERTFILE
if (!params.tls_ca_cert_file.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CACERTFILE, params.tls_ca_cert_file.c_str()));
#endif
#ifdef LDAP_OPT_X_TLS_CACERTDIR
if (!params.tls_ca_cert_dir.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CACERTDIR, params.tls_ca_cert_dir.c_str()));
#endif
#ifdef LDAP_OPT_X_TLS_CIPHER_SUITE
if (!params.tls_cipher_suite.empty())
diag(ldap_set_option(handle, LDAP_OPT_X_TLS_CIPHER_SUITE, params.tls_cipher_suite.c_str()));
#endif
#ifdef LDAP_OPT_X_TLS_NEWCTX
{

View File

@ -23,7 +23,16 @@ struct LDAPServerParams
YES
};
enum class TLSCertVerify
enum class TLSProtocolVersion
{
SSL2,
SSL3,
TLS1_0,
TLS1_1,
TLS1_2
};
enum class TLSRequireCert
{
NEVER,
ALLOW,
@ -42,9 +51,13 @@ struct LDAPServerParams
std::uint16_t port = 636;
TLSEnable enable_tls = TLSEnable::YES;
TLSCertVerify tls_cert_verify = TLSCertVerify::DEMAND;
String ca_cert_dir;
String ca_cert_file;
TLSProtocolVersion tls_minimum_protocol_version = TLSProtocolVersion::TLS1_2;
TLSRequireCert tls_require_cert = TLSRequireCert::DEMAND;
String tls_cert_file;
String tls_key_file;
String tls_ca_cert_file;
String tls_ca_cert_dir;
String tls_cipher_suite;
SASLMechanism sasl_mechanism = SASLMechanism::SIMPLE;