JoomlaPolska / jezyk-J4

Język polski dla Joomla 4
GNU General Public License v2.0
3 stars 5 forks source link

[4.x] Fix LDAP over SSL #310

Closed joomlapl-bot closed 1 year ago

joomlapl-bot commented 1 year ago

PR w związku ze zmianą oryginału https://github.com/joomla/joomla-cms/pull/37962 Poniżej zmiany w oryginale:

Click to expand the diff! ```diff diff --git a/administrator/components/com_admin/sql/updates/mysql/4.3.0-2023-01-30.sql b/administrator/components/com_admin/sql/updates/mysql/4.3.0-2023-01-30.sql new file mode 100644 index 000000000000..ac7ab1b99a8c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.3.0-2023-01-30.sql @@ -0,0 +1,36 @@ +UPDATE `#__extensions` + SET `params` = REPLACE(`params`, '"negotiate_tls":1', '"encryption":"tls"') + WHERE `name` = 'plg_authentication_ldap' + AND `type` = 'plugin' + AND `element` = 'ldap' + AND `folder` = 'authentication' + AND `client_id` = 0 + AND `params` LIKE '{%"negotiate_tls":1%}'; + +UPDATE `#__extensions` + SET `params` = REPLACE(`params`, '"negotiate_tls":0', '"encryption":"none"') + WHERE `name` = 'plg_authentication_ldap' + AND `type` = 'plugin' + AND `element` = 'ldap' + AND `folder` = 'authentication' + AND `client_id` = 0 + AND `params` LIKE '{%"negotiate_tls":0%}'; + +UPDATE `#__extensions` + SET `params` = REPLACE(`params`, '"encryption":"none"', '"encryption":"ssl"') + WHERE `name` = 'plg_authentication_ldap' + AND `type` = 'plugin' + AND `element` = 'ldap' + AND `folder` = 'authentication' + AND `client_id` = 0 + AND `params` LIKE '{%"host":"ldaps:\\\\/\\\\/%}'; + +UPDATE `#__extensions` + SET `params` = REPLACE(`params`, '"host":"ldaps:\\/\\/', '"host":"') + WHERE `name` = 'plg_authentication_ldap' + AND `type` = 'plugin' + AND `element` = 'ldap' + AND `folder` = 'authentication' + AND `client_id` = 0 + AND `params` LIKE '{%"host":"ldaps:\\\\/\\\\/%}'; + diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.3.0-2023-01-30.sql b/administrator/components/com_admin/sql/updates/postgresql/4.3.0-2023-01-30.sql new file mode 100644 index 000000000000..c4071bdccce0 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.3.0-2023-01-30.sql @@ -0,0 +1,36 @@ +UPDATE "#__extensions" + SET "params" = REPLACE("params", '"negotiate_tls":1', '"encryption":"tls"') + WHERE "name" = 'plg_authentication_ldap' + AND "type" = 'plugin' + AND "element" = 'ldap' + AND "folder" = 'authentication' + AND "client_id" = 0 + AND "params" LIKE '{%"negotiate_tls":1%}'; + +UPDATE "#__extensions" + SET "params" = REPLACE("params", '"negotiate_tls":0', '"encryption":"none"') + WHERE "name" = 'plg_authentication_ldap' + AND "type" = 'plugin' + AND "element" = 'ldap' + AND "folder" = 'authentication' + AND "client_id" = 0 + AND "params" LIKE '{%"negotiate_tls":0%}'; + +UPDATE "#__extensions" + SET "params" = REPLACE("params", '"encryption":"none"', '"encryption":"ssl"') + WHERE "name" = 'plg_authentication_ldap' + AND "type" = 'plugin' + AND "element" = 'ldap' + AND "folder" = 'authentication' + AND "client_id" = 0 + AND "params" LIKE '{%"host":"ldaps:\\/\\/%}'; + +UPDATE "#__extensions" + SET "params" = REPLACE("params", '"host":"ldaps:\/\/', '"host":"') + WHERE "name" = 'plg_authentication_ldap' + AND "type" = 'plugin' + AND "element" = 'ldap' + AND "folder" = 'authentication' + AND "client_id" = 0 + AND "params" LIKE '{%"host":"ldaps:\\/\\/%}'; + diff --git a/administrator/language/en-GB/plg_authentication_ldap.ini b/administrator/language/en-GB/plg_authentication_ldap.ini index 98cdb50dd9cb..6b71a5a2f87c 100644 --- a/administrator/language/en-GB/plg_authentication_ldap.ini +++ b/administrator/language/en-GB/plg_authentication_ldap.ini @@ -6,14 +6,17 @@ PLG_AUTHENTICATION_LDAP="Authentication - LDAP" PLG_LDAP_FIELD_AUTHMETHOD_LABEL="Authorisation Method" PLG_LDAP_FIELD_BASEDN_LABEL="Base DN" +PLG_LDAP_FIELD_CACERT_LABEL="Path to the server certificate" +PLG_LDAP_FIELD_CACERT_DESC="Full path to the file or directory where Joomla can find the LDAP server's (Certificate Authority) certificate. If this is empty, the system defaults for the TLS_CACERT and TLS_CACERTDIR LDAP client options are used." +PLG_LDAP_FIELD_ENCRYPTION_LABEL="Connection Security" PLG_LDAP_FIELD_EMAIL_DESC="LDAP attribute which has the User's email address." PLG_LDAP_FIELD_EMAIL_LABEL="Map: Email" PLG_LDAP_FIELD_FULLNAME_DESC="LDAP attribute which has the User's full name." PLG_LDAP_FIELD_FULLNAME_LABEL="Map: Full Name" PLG_LDAP_FIELD_HOST_LABEL="Host" +PLG_LDAP_FIELD_IGNORE_REQCERT_TLS_LABEL="Ignore Certificate" PLG_LDAP_FIELD_LDAPDEBUG_DESC="Enables debug hardcoded to level 7" PLG_LDAP_FIELD_LDAPDEBUG_LABEL="Debug" -PLG_LDAP_FIELD_NEGOCIATE_LABEL="Negotiate TLS" PLG_LDAP_FIELD_PASSWORD_DESC="The Connect Password is the password of an administrative account." PLG_LDAP_FIELD_PASSWORD_LABEL="Connect Password" PLG_LDAP_FIELD_PORT_LABEL="Port" @@ -31,4 +34,7 @@ PLG_LDAP_FIELD_V3_DESC="Default is LDAP2, but the latest versions of OpenLdap re PLG_LDAP_FIELD_V3_LABEL="LDAP V3" PLG_LDAP_FIELD_VALUE_BINDSEARCH="Bind and Search" PLG_LDAP_FIELD_VALUE_BINDUSER="Bind Directly as User" +PLG_LDAP_FIELD_VALUE_ENCRYPTIONNONE="None" +PLG_LDAP_FIELD_VALUE_ENCRYPTIONSSL="SSL/TLS" +PLG_LDAP_FIELD_VALUE_ENCRYPTIONTLS="STARTTLS" PLG_LDAP_XML_DESCRIPTION="

Handles User Authentication against an LDAP server.

Warning! You must have at least one authentication plugin enabled or you will lose all access to your site.

" diff --git a/plugins/authentication/ldap/ldap.xml b/plugins/authentication/ldap/ldap.xml index 758a680f4684..fde40e71ca3c 100644 --- a/plugins/authentication/ldap/ldap.xml +++ b/plugins/authentication/ldap/ldap.xml @@ -45,7 +45,7 @@ type="radio" layout="joomla.form.field.radio.switcher" label="PLG_LDAP_FIELD_V3_LABEL" - default="0" + default="1" filter="integer" > @@ -53,17 +53,39 @@ + + + + + + + + params->get('ldap_fullname', ''); $ldap_uid = $this->params->get('ldap_uid', ''); $auth_method = $this->params->get('auth_method', ''); + // Load certificate info + $ignore_reqcert_tls = (bool) $this->params->get('ignore_reqcert_tls', '1'); + $cacert = $this->params->get('cacert', ''); + + // getting certificate file and certificate directory options (both need to be set) + if (!$ignore_reqcert_tls && !empty($cacert)) { + if (is_dir($cacert)) { + $cacertdir = $cacert; + $cacertfile = ""; + } elseif (is_file($cacert)) { + $cacertfile = $cacert; + $cacertdir = dirname($cacert); + } else { + $cacertfile = $cacert; + $cacertdir = $cacert; + Log::add(sprintf('Certificate path for LDAP client is neither an existing file nor directory: "%s"', $cacert), Log::ERROR, $logcategory); + } + } else { + Log::add(sprintf('Not setting any LDAP TLS CA certificate options because %s, system wide settings are used', $ignore_reqcert_tls ? "certificate is ignored" : "no certificate location is configured"), Log::DEBUG, $logcategory); + } $options = [ 'host' => $this->params->get('host', ''), 'port' => (int) $this->params->get('port', ''), - 'version' => $this->params->get('use_ldapV3', '0') == '1' ? 3 : 2, + 'version' => $this->params->get('use_ldapV3', '1') == '1' ? 3 : 2, 'referrals' => (bool) $this->params->get('no_referrals', '0'), - 'encryption' => $this->params->get('negotiate_tls', '0') == '1' ? 'tls' : 'none', + 'encryption' => $this->params->get('encryption', 'none'), + 'options' => [ + 'x_tls_require_cert' => $ignore_reqcert_tls ? LDAP_OPT_X_TLS_NEVER : LDAP_OPT_X_TLS_DEMAND, + ], ]; + // if these are not set, the system defaults are used + if (isset($cacertdir) && isset($cacertfile)) { + $options['options']['x_tls_cacertdir'] = $cacertdir; + $options['options']['x_tls_cacertfile'] = $cacertfile; + } + Log::add(sprintf('Creating LDAP session with options: %s', json_encode($options)), Log::DEBUG, $logcategory); $connection_string = sprintf('ldap%s://%s:%s', 'ssl' === $options['encryption'] ? 's' : '', $options['host'], $options['port']); Log::add(sprintf('Creating LDAP session to connect to "%s" while binding', $connection_string), Log::DEBUG, $logcategory); diff --git a/tests/Integration/Plugin/Authentication/Ldap/LdapPluginTest.php b/tests/Integration/Plugin/Authentication/Ldap/LdapPluginTest.php index 145de2e96243..4ed3767739fe 100644 --- a/tests/Integration/Plugin/Authentication/Ldap/LdapPluginTest.php +++ b/tests/Integration/Plugin/Authentication/Ldap/LdapPluginTest.php @@ -23,6 +23,12 @@ /** * Test class for Ldap plugin * + * Not testing for: + * * different certificate options + * these can't be properly automatically tested as the LDAP_OPT_X_ settings can only be set once in a running process + * * working ldap debug option. + * this can only be tested if phpunit stderr is redirected/duplicated/configured to a file + * * @package Joomla.IntegrationTest * @subpackage Ldap * @@ -72,38 +78,6 @@ private function getPlugin($options): LdapPlugin return $plugin; } - private function acceptCertificates(): void - { - //TODO make this (and LDAP_OPT_X_CERTFILE and LDAP_OPT_X_TLS_REQUIRE_CERT) Joomla ldap setting - $cert = JPATH_ROOT . '/' . JTEST_LDAP_CACERTFILE; - ldap_set_option(null, LDAP_OPT_X_TLS_CACERTDIR, dirname($cert)); - ldap_set_option(null, LDAP_OPT_X_TLS_CACERTFILE, $cert); - } - - private function getAdminConnection(array $options): Ldap - { - $admin_options = [ - 'host' => $options['host'], - 'port' => (int) $options['port'], - 'version' => $options['use_ldapV3'] == '1' ? 3 : 2, - 'referrals' => (bool) $options['no_referrals'], - 'encryption' => $options['encryption'], - 'debug' => (bool) $options['ldap_debug'], - ]; - $ldap = Ldap::create( - 'ext_ldap', - $admin_options - ); - $ldap->bind("cn=admin,cn=config", "configpassword"); - return $ldap; - } - - private function requireEncryption($encryption, $options): void - { - //$ldap = $this->getAdminConnection($options); - //TODO configure openldap (only if given permission in phpunit.xml, so people can use their own ldap server) to require the requested encryption to be sure encryption is used - } - private function skipIfAskedFor($options): void { if (empty($options["host"])) { @@ -136,6 +110,9 @@ public function setUp(): void 'ldap_email' => JTEST_LDAP_EMAIL, 'ldap_uid' => JTEST_LDAP_UID, 'ldap_debug' => 0, + /* the security options can only be set once, these are the best practice settings */ + 'ignore_reqcert_tls' => 0, + 'cacert' => JPATH_ROOT . '/' . JTEST_LDAP_CACERTFILE, /* changing options to test all code */ 'port' => self::LDAPPORT, 'encryption' => "none", @@ -235,9 +212,6 @@ public function testOnUserAuthenticateBindAndSearchTLS() $this->skipIfAskedFor($options); $plugin = $this->getPlugin($options); - $this->acceptCertificates(); - $this->requireEncryption("tls", $options); - $response = new AuthenticationResponse(); $plugin->onUserAuthenticate($this->default_credentials, [], $response); $this->assertEquals(Authentication::STATUS_SUCCESS, $response->status); @@ -252,8 +226,6 @@ public function testOnUserAuthenticateBindAndSearchTLS() */ public function testOnUserAuthenticateBindAndSearchSSL() { - $this->markTestSkipped("Fix provided in PR #37962"); - $options = $this->default_options; $options["auth_method"] = "search"; $options["encryption"] = "ssl"; @@ -261,33 +233,8 @@ public function testOnUserAuthenticateBindAndSearchSSL() $this->skipIfAskedFor($options); $plugin = $this->getPlugin($options); - $this->acceptCertificates(); - $this->requireEncryption("ssl", $options); - - $response = new AuthenticationResponse(); - $plugin->onUserAuthenticate($this->default_credentials, [], $response); - $this->assertEquals(Authentication::STATUS_SUCCESS, $response->status); - } - - /** - * @testdox does log ldap client calls and errors - * can only be tested if phpunit stderr is redirected/duplicated/configured to a file - * then, we can check if ldap_ calls are present in that file - * - * @return void - * - * @since 4.3.0 - */ - /* - public function testOnUserAuthenticateWithDebug() - { - $options = $this->default_options; - $options["ldap_debug"] = 1; - $plugin = $this->getPlugin($options); - $response = new AuthenticationResponse(); $plugin->onUserAuthenticate($this->default_credentials, [], $response); $this->assertEquals(Authentication::STATUS_SUCCESS, $response->status); } - */ } ```