Skip to content

Commit efd1446

Browse files
committed
Deprecate GLPIKEY usage
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.
1 parent af1ffc6 commit efd1446

15 files changed

+406
-31
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/config/config_db*
2+
/config/glpi.key
23
/config/config_path.php
34
/config/local_define.php
45
/tests/config_db*

Diff for: ajax/mailcollector.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
if (empty($input["passwd"])) {
5959
unset($input["passwd"]);
6060
} else {
61-
$input["passwd"] = Toolbox::encrypt(stripslashes($input["passwd"]), GLPIKEY);
61+
$input["passwd"] = Toolbox::encrypt(stripslashes($input["passwd"]));
6262
}
6363
}
6464

Diff for: inc/auth.class.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,7 @@ function login($login_name, $login_password, $noauto = false, $remember_me = fal
664664
$ds = AuthLdap::connectToServer($ldap_method["host"],
665665
$ldap_method["port"],
666666
$ldap_method["rootdn"],
667-
Toolbox::decrypt($ldap_method["rootdn_passwd"],
668-
GLPIKEY),
667+
Toolbox::decrypt($ldap_method["rootdn_passwd"]),
669668
$ldap_method["use_tls"],
670669
$ldap_method["deref_option"]);
671670

Diff for: inc/authldap.class.php

+7-8
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ function prepareInputForUpdate($input) {
192192
if (empty($input["rootdn_passwd"])) {
193193
unset($input["rootdn_passwd"]);
194194
} else {
195-
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]),
196-
GLPIKEY);
195+
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]));
197196
}
198197
}
199198

@@ -1456,7 +1455,7 @@ static function testLDAPConnection($auths_id, $replicate_id = -1) {
14561455
$port = $config_ldap->fields['port'];
14571456
}
14581457
$ds = self::connectToServer($host, $port, $config_ldap->fields['rootdn'],
1459-
Toolbox::decrypt($config_ldap->fields['rootdn_passwd'], GLPIKEY),
1458+
Toolbox::decrypt($config_ldap->fields['rootdn_passwd']),
14601459
$config_ldap->fields['use_tls'],
14611460
$config_ldap->fields['deref_option']);
14621461
if ($ds) {
@@ -2608,7 +2607,7 @@ function connect() {
26082607

26092608
return $this->connectToServer($this->fields['host'], $this->fields['port'],
26102609
$this->fields['rootdn'],
2611-
Toolbox::decrypt($this->fields['rootdn_passwd'], GLPIKEY),
2610+
Toolbox::decrypt($this->fields['rootdn_passwd']),
26122611
$this->fields['use_tls'],
26132612
$this->fields['deref_option']);
26142613
}
@@ -2669,7 +2668,7 @@ static function tryToConnectToServer($ldap_method, $login, $password) {
26692668
}
26702669
$ds = self::connectToServer($ldap_method['host'], $ldap_method['port'],
26712670
$ldap_method['rootdn'],
2672-
Toolbox::decrypt($ldap_method['rootdn_passwd'], GLPIKEY),
2671+
Toolbox::decrypt($ldap_method['rootdn_passwd']),
26732672
$ldap_method['use_tls'], $ldap_method['deref_option']);
26742673

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

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

34433442
if (self::connectToServer($authldap->getField('host'), $authldap->getField('port'),
34443443
$authldap->getField('rootdn'),
3445-
Toolbox::decrypt($authldap->getField('rootdn_passwd'), GLPIKEY),
3444+
Toolbox::decrypt($authldap->getField('rootdn_passwd')),
34463445
$authldap->getField('use_tls'),
34473446
$authldap->getField('deref_option'))) {
34483447
self::showLdapUsers();
@@ -3500,7 +3499,7 @@ function prepareInputForAdd($input) {
35003499
}
35013500

35023501
if (isset($input["rootdn_passwd"]) && !empty($input["rootdn_passwd"])) {
3503-
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]), GLPIKEY);
3502+
$input["rootdn_passwd"] = Toolbox::encrypt(stripslashes($input["rootdn_passwd"]));
35043503
}
35053504

35063505
return $input;

Diff for: inc/config.class.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function prepareInputForUpdate($input) {
151151
if (empty($input["smtp_passwd"])) {
152152
unset($input["smtp_passwd"]);
153153
} else {
154-
$input["smtp_passwd"] = Toolbox::encrypt(stripslashes($input["smtp_passwd"]), GLPIKEY);
154+
$input["smtp_passwd"] = Toolbox::encrypt(stripslashes($input["smtp_passwd"]));
155155
}
156156
}
157157

@@ -163,8 +163,7 @@ function prepareInputForUpdate($input) {
163163
if (empty($input["proxy_passwd"])) {
164164
unset($input["proxy_passwd"]);
165165
} else {
166-
$input["proxy_passwd"] = Toolbox::encrypt(stripslashes($input["proxy_passwd"]),
167-
GLPIKEY);
166+
$input["proxy_passwd"] = Toolbox::encrypt(stripslashes($input["proxy_passwd"]));
168167
}
169168
}
170169

Diff for: inc/console/security/changekeycommand.class.php

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* ---------------------------------------------------------------------
4+
* GLPI - Gestionnaire Libre de Parc Informatique
5+
* Copyright (C) 2015-2018 Teclib' and contributors.
6+
*
7+
* http://glpi-project.org
8+
*
9+
* based on GLPI - Gestionnaire Libre de Parc Informatique
10+
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
11+
*
12+
* ---------------------------------------------------------------------
13+
*
14+
* LICENSE
15+
*
16+
* This file is part of GLPI.
17+
*
18+
* GLPI is free software; you can redistribute it and/or modify
19+
* it under the terms of the GNU General Public License as published by
20+
* the Free Software Foundation; either version 2 of the License, or
21+
* (at your option) any later version.
22+
*
23+
* GLPI is distributed in the hope that it will be useful,
24+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
25+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26+
* GNU General Public License for more details.
27+
*
28+
* You should have received a copy of the GNU General Public License
29+
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
30+
* ---------------------------------------------------------------------
31+
*/
32+
33+
namespace Glpi\Console\Security;
34+
35+
if (!defined('GLPI_ROOT')) {
36+
die("Sorry. You can't access this file directly");
37+
}
38+
39+
use Glpi\Console\AbstractCommand;
40+
use Symfony\Component\Console\Input\InputInterface;
41+
use Symfony\Component\Console\Output\OutputInterface;
42+
use Symfony\Component\Console\Question\ConfirmationQuestion;
43+
use GLPIKey;
44+
45+
class ChangekeyCommand extends AbstractCommand {
46+
/**
47+
* Error code returned when unable to renew key.
48+
*
49+
* @var integer
50+
*/
51+
const ERROR_UNABLE_TO_RENEW_KEY = 1;
52+
53+
protected function configure() {
54+
parent::configure();
55+
56+
$this->setName('glpi:security:change_key');
57+
$this->setDescription(__('Change password storage key and update values in database.'));
58+
}
59+
60+
protected function execute(InputInterface $input, OutputInterface $output) {
61+
$glpikey = new GLPIKey();
62+
63+
$fields = $glpikey->getFields();
64+
$configs = $glpikey->getConfigs();
65+
$conf_count = 0;
66+
foreach ($configs as $config) {
67+
$conf_count += count($config);
68+
}
69+
70+
$output->writeln(
71+
sprintf(
72+
'<info>' . __('Found %1$s field(s) and %2$s configuration entries requiring migration.') . '</info>',
73+
count($fields),
74+
$conf_count
75+
)
76+
);
77+
78+
if (!$input->getOption('no-interaction')) {
79+
// Ask for confirmation (unless --no-interaction)
80+
$question_helper = $this->getHelper('question');
81+
$run = $question_helper->ask(
82+
$input,
83+
$output,
84+
new ConfirmationQuestion(__('Do you want to continue ?') . ' [Yes/no]', true)
85+
);
86+
if (!$run) {
87+
$output->writeln(
88+
'<comment>' . __('Aborted.') . '</comment>',
89+
OutputInterface::VERBOSITY_VERBOSE
90+
);
91+
return 0;
92+
}
93+
}
94+
95+
$created = $glpikey->generate();
96+
if (!$created) {
97+
$output->writeln(
98+
'<error>' . __('Unable to change security key!') . '</error>',
99+
OutputInterface::VERBOSITY_QUIET
100+
);
101+
return self::ERROR_UNABLE_TO_RENEW_KEY;
102+
}
103+
104+
$this->output->write(PHP_EOL);
105+
106+
$output->writeln('<info>' . __('New security key generated; database updated.') . '</info>');
107+
108+
return 0; // Success
109+
}
110+
}

0 commit comments

Comments
 (0)