From 9d78c95a2a8c1be3731dc6bfb7800b6d945d83d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Legastelois?= Date: Wed, 3 Mar 2021 10:37:25 +0100 Subject: [PATCH] feat: support cert and key for LDAPS --- .gitignore | 3 +- inc/auth.class.php | 5 ++- inc/authldap.class.php | 78 +++++++++++++++++++++++++++++++++++------- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index ff281ff5236b..fd3f6dcaa5d7 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ phpunit.xml .package.hash /public/build/ /public/lib/ -/tests/web/error.log \ No newline at end of file +/tests/web/error.log +/config/ldap/* diff --git a/inc/auth.class.php b/inc/auth.class.php index b15bfb6608bc..48c8d13d0ad5 100644 --- a/inc/auth.class.php +++ b/inc/auth.class.php @@ -760,7 +760,10 @@ function login($login_name, $login_password, $noauto = false, $remember_me = fal $ldap_method["rootdn"], Toolbox::sodiumDecrypt($ldap_method["rootdn_passwd"]), $ldap_method["use_tls"], - $ldap_method["deref_option"]); + $ldap_method["deref_option"], + $ldap_method["tls_certfile"], + $ldap_method["tls_certkey"], + $ldap_method["use_bind"]); if ($ds) { $ldapservers_status = true; diff --git a/inc/authldap.class.php b/inc/authldap.class.php index ffd20091b513..9840a25d75e0 100644 --- a/inc/authldap.class.php +++ b/inc/authldap.class.php @@ -396,6 +396,11 @@ function showForm($ID, $options = []) { $this->fields["rootdn"]."\">"; echo ""; + echo ""; + echo ""; + Dropdown::showYesNo('use_bind', $this->fields["use_bind"]); + echo ""; + echo ""; echo ""; @@ -532,6 +537,15 @@ function showFormAdvancedConfig() { Html::autocompletionTextField($this, "inventory_domain", ['size' => 100]); echo ""; + echo ""; + echo "" . __('TLS Certfile') . ""; + echo ""; + echo ""; + echo "" . __('TLS Keyfile') . ""; + echo ""; + echo ""; + echo ""; + echo ""; echo ""; echo $hidden; @@ -1459,7 +1473,10 @@ static function testLDAPConnection($auths_id, $replicate_id = -1) { $ds = self::connectToServer($host, $port, $config_ldap->fields['rootdn'], Toolbox::sodiumDecrypt($config_ldap->fields['rootdn_passwd']), $config_ldap->fields['use_tls'], - $config_ldap->fields['deref_option']); + $config_ldap->fields['deref_option'], + $config_ldap->fields['tls_certfile'], + $config_ldap->fields['tls_keyfile'], + $config_ldap->fields['use_bind']); if ($ds) { return true; } @@ -2615,7 +2632,10 @@ function connect() { $this->fields['rootdn'], Toolbox::sodiumDecrypt($this->fields['rootdn_passwd']), $this->fields['use_tls'], - $this->fields['deref_option']); + $this->fields['deref_option'], + $this->fields['tls_certfile'], + $this->fields['tls_keyfile'], + $this->fields['use_bind']); } @@ -2628,28 +2648,47 @@ function connect() { * @param string $password password to use (default '') * @param boolean $use_tls use a TLS connection? (false by default) * @param integer $deref_options deref options used + * @param string $tls_certfile TLS CERT file name within config directory (default '') + * @param string $tls_keyfile TLS KEY file name within config directory (default '') + * @param boolean $use_bind do we need to do an ldap_bind? (true by default) * * @return resource link to the LDAP server : false if connection failed */ static function connectToServer($host, $port, $login = "", $password = "", - $use_tls = false, $deref_options = 0) { + $use_tls = false, $deref_options = 0, + $tls_certfile = "", $tls_keyfile = "", + $use_bind = true) { $ds = @ldap_connect($host, intval($port)); if ($ds) { @ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); @ldap_set_option($ds, LDAP_OPT_DEREF, $deref_options); + + if (file_exists(GLPI_CONFIG_DIR . '/ldap/' . $tls_certfile)) { + @ldap_set_option(null, LDAP_OPT_X_TLS_CERTFILE, GLPI_CONFIG_DIR . '/ldap/' . $tls_certfile); + } + + if (GLPI_CONFIG_DIR . '/ldap/' . $tls_keyfile) { + @ldap_set_option(null, LDAP_OPT_X_TLS_KEYFILE, GLPI_CONFIG_DIR . '/ldap/' . $tls_keyfile); + } + if ($use_tls) { if (!@ldap_start_tls($ds)) { return false; } } // Auth bind - if ($login != '') { - $b = @ldap_bind($ds, $login, $password); - } else { // Anonymous bind - $b = @ldap_bind($ds); + if ($use_bind) { + if ($login != '') { + $b = @ldap_bind($ds, $login, $password); + } else { // Anonymous bind + $b = @ldap_bind($ds); + } + } else { + $b = true; } + if ($b) { return $ds; } @@ -2675,14 +2714,20 @@ static function tryToConnectToServer($ldap_method, $login, $password) { $ds = self::connectToServer($ldap_method['host'], $ldap_method['port'], $ldap_method['rootdn'], Toolbox::sodiumDecrypt($ldap_method['rootdn_passwd']), - $ldap_method['use_tls'], $ldap_method['deref_option']); + $ldap_method['use_tls'], $ldap_method['deref_option'], + $ldap_method['tls_certfile'], + $ldap_method['tls_keyfile'], + $ldap_method['use_bind']); // Test with login and password of the user if exists if (!$ds && !empty($login)) { $ds = self::connectToServer($ldap_method['host'], $ldap_method['port'], $login, $password, $ldap_method['use_tls'], - $ldap_method['deref_option']); + $ldap_method['deref_option'], + $ldap_method['tls_certfile'], + $ldap_method['tls_keyfile'], + $ldap_method['use_bind']); } //If connection is not successful on this directory, try replicates (if replicates exists) @@ -2692,14 +2737,20 @@ static function tryToConnectToServer($ldap_method, $login, $password) { $ds = self::connectToServer($replicate["host"], $replicate["port"], $ldap_method['rootdn'], Toolbox::sodiumDecrypt($ldap_method['rootdn_passwd']), - $ldap_method['use_tls'], $ldap_method['deref_option']); + $ldap_method['use_tls'], $ldap_method['deref_option'], + $ldap_method['tls_certfile'], + $ldap_method['tls_keyfile'], + $ldap_method['use_bind']); // Test with login and password of the user if (!$ds && !empty($login)) { $ds = self::connectToServer($replicate["host"], $replicate["port"], $login, $password, $ldap_method['use_tls'], - $ldap_method['deref_option']); + $ldap_method['deref_option'], + $ldap_method['tls_certfile'], + $ldap_method['tls_keyfile'], + $ldap_method['use_bind']); } if ($ds) { return $ds; @@ -3447,7 +3498,10 @@ static function searchUser(AuthLDAP $authldap) { $authldap->getField('rootdn'), Toolbox::sodiumDecrypt($authldap->getField('rootdn_passwd')), $authldap->getField('use_tls'), - $authldap->getField('deref_option'))) { + $authldap->getField('deref_option'), + $authldap->getField('tls_certfile'), + $authldap->getField('tls_keyfile'), + $authldap->getField('use_bind'))) { self::showLdapUsers(); } else {