Skip to content

Commit

Permalink
Deprecate GLPIKEY usage
Browse files Browse the repository at this point in the history
CVE-2020-5248

Deprecate GLPIKEY usage, and replace it with key file per instance.
Add a command to generate new key, and update database.
Add plugins hooks to register fields or configuration entries to be
handled when updating db.
  • Loading branch information
trasher committed Apr 23, 2020
1 parent af1ffc6 commit efd1446
Show file tree
Hide file tree
Showing 15 changed files with 406 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,4 +1,5 @@
/config/config_db*
/config/glpi.key
/config/config_path.php
/config/local_define.php
/tests/config_db*
Expand Down
2 changes: 1 addition & 1 deletion ajax/mailcollector.php
Expand Up @@ -58,7 +58,7 @@
if (empty($input["passwd"])) {
unset($input["passwd"]);
} else {
$input["passwd"] = Toolbox::encrypt(stripslashes($input["passwd"]), GLPIKEY);
$input["passwd"] = Toolbox::encrypt(stripslashes($input["passwd"]));
}
}

Expand Down
3 changes: 1 addition & 2 deletions inc/auth.class.php
Expand Up @@ -664,8 +664,7 @@ function login($login_name, $login_password, $noauto = false, $remember_me = fal
$ds = AuthLdap::connectToServer($ldap_method["host"],
$ldap_method["port"],
$ldap_method["rootdn"],
Toolbox::decrypt($ldap_method["rootdn_passwd"],
GLPIKEY),
Toolbox::decrypt($ldap_method["rootdn_passwd"]),
$ldap_method["use_tls"],
$ldap_method["deref_option"]);

Expand Down
15 changes: 7 additions & 8 deletions inc/authldap.class.php
Expand Up @@ -192,8 +192,7 @@ function prepareInputForUpdate($input) {
if (empty($input["rootdn_passwd"])) {
unset($input["rootdn_passwd"]);
} else {
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]),
GLPIKEY);
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]));
}
}

Expand Down Expand Up @@ -1456,7 +1455,7 @@ static function testLDAPConnection($auths_id, $replicate_id = -1) {
$port = $config_ldap->fields['port'];
}
$ds = self::connectToServer($host, $port, $config_ldap->fields['rootdn'],
Toolbox::decrypt($config_ldap->fields['rootdn_passwd'], GLPIKEY),
Toolbox::decrypt($config_ldap->fields['rootdn_passwd']),
$config_ldap->fields['use_tls'],
$config_ldap->fields['deref_option']);
if ($ds) {
Expand Down Expand Up @@ -2608,7 +2607,7 @@ function connect() {

return $this->connectToServer($this->fields['host'], $this->fields['port'],
$this->fields['rootdn'],
Toolbox::decrypt($this->fields['rootdn_passwd'], GLPIKEY),
Toolbox::decrypt($this->fields['rootdn_passwd']),
$this->fields['use_tls'],
$this->fields['deref_option']);
}
Expand Down Expand Up @@ -2669,7 +2668,7 @@ static function tryToConnectToServer($ldap_method, $login, $password) {
}
$ds = self::connectToServer($ldap_method['host'], $ldap_method['port'],
$ldap_method['rootdn'],
Toolbox::decrypt($ldap_method['rootdn_passwd'], GLPIKEY),
Toolbox::decrypt($ldap_method['rootdn_passwd']),
$ldap_method['use_tls'], $ldap_method['deref_option']);

// Test with login and password of the user if exists
Expand All @@ -2686,7 +2685,7 @@ static function tryToConnectToServer($ldap_method, $login, $password) {
foreach (self::getAllReplicateForAMaster($ldap_method['id']) as $replicate) {
$ds = self::connectToServer($replicate["host"], $replicate["port"],
$ldap_method['rootdn'],
Toolbox::decrypt($ldap_method['rootdn_passwd'], GLPIKEY),
Toolbox::decrypt($ldap_method['rootdn_passwd']),
$ldap_method['use_tls'], $ldap_method['deref_option']);

// Test with login and password of the user
Expand Down Expand Up @@ -3442,7 +3441,7 @@ static function searchUser(AuthLDAP $authldap) {

if (self::connectToServer($authldap->getField('host'), $authldap->getField('port'),
$authldap->getField('rootdn'),
Toolbox::decrypt($authldap->getField('rootdn_passwd'), GLPIKEY),
Toolbox::decrypt($authldap->getField('rootdn_passwd')),
$authldap->getField('use_tls'),
$authldap->getField('deref_option'))) {
self::showLdapUsers();
Expand Down Expand Up @@ -3500,7 +3499,7 @@ function prepareInputForAdd($input) {
}

if (isset($input["rootdn_passwd"]) && !empty($input["rootdn_passwd"])) {
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]), GLPIKEY);
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]));
}

return $input;
Expand Down
5 changes: 2 additions & 3 deletions inc/config.class.php
Expand Up @@ -151,7 +151,7 @@ function prepareInputForUpdate($input) {
if (empty($input["smtp_passwd"])) {
unset($input["smtp_passwd"]);
} else {
$input["smtp_passwd"] = Toolbox::encrypt(stripslashes($input["smtp_passwd"]), GLPIKEY);
$input["smtp_passwd"] = Toolbox::encrypt(stripslashes($input["smtp_passwd"]));
}
}

Expand All @@ -163,8 +163,7 @@ function prepareInputForUpdate($input) {
if (empty($input["proxy_passwd"])) {
unset($input["proxy_passwd"]);
} else {
$input["proxy_passwd"] = Toolbox::encrypt(stripslashes($input["proxy_passwd"]),
GLPIKEY);
$input["proxy_passwd"] = Toolbox::encrypt(stripslashes($input["proxy_passwd"]));
}
}

Expand Down
110 changes: 110 additions & 0 deletions inc/console/security/changekeycommand.class.php
@@ -0,0 +1,110 @@
<?php
/**
* ---------------------------------------------------------------------
* GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2015-2018 Teclib' and contributors.
*
* http://glpi-project.org
*
* based on GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* GLPI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------
*/

namespace Glpi\Console\Security;

if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}

use Glpi\Console\AbstractCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use GLPIKey;

class ChangekeyCommand extends AbstractCommand {
/**
* Error code returned when unable to renew key.
*
* @var integer
*/
const ERROR_UNABLE_TO_RENEW_KEY = 1;

protected function configure() {
parent::configure();

$this->setName('glpi:security:change_key');
$this->setDescription(__('Change password storage key and update values in database.'));
}

protected function execute(InputInterface $input, OutputInterface $output) {
$glpikey = new GLPIKey();

$fields = $glpikey->getFields();
$configs = $glpikey->getConfigs();
$conf_count = 0;
foreach ($configs as $config) {
$conf_count += count($config);
}

$output->writeln(
sprintf(
'<info>' . __('Found %1$s field(s) and %2$s configuration entries requiring migration.') . '</info>',
count($fields),
$conf_count
)
);

if (!$input->getOption('no-interaction')) {
// Ask for confirmation (unless --no-interaction)
$question_helper = $this->getHelper('question');
$run = $question_helper->ask(
$input,
$output,
new ConfirmationQuestion(__('Do you want to continue ?') . ' [Yes/no]', true)
);
if (!$run) {
$output->writeln(
'<comment>' . __('Aborted.') . '</comment>',
OutputInterface::VERBOSITY_VERBOSE
);
return 0;
}
}

$created = $glpikey->generate();
if (!$created) {
$output->writeln(
'<error>' . __('Unable to change security key!') . '</error>',
OutputInterface::VERBOSITY_QUIET
);
return self::ERROR_UNABLE_TO_RENEW_KEY;
}

$this->output->write(PHP_EOL);

$output->writeln('<info>' . __('New security key generated; database updated.') . '</info>');

return 0; // Success
}
}

0 comments on commit efd1446

Please sign in to comment.