Added replacement for mcrypt removal in PHP 7.2, added stronger encryption options

SVN:trunk[5996]
This commit is contained in:
Stephen Abello
2018-08-03 08:43:36 +00:00
parent 0adadeb280
commit 8fe38b03f6
18 changed files with 279 additions and 23 deletions

View File

@@ -2737,7 +2737,7 @@ class AttributeEncryptedString extends AttributeString
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
static $sKey = null; // Encryption key used for all encrypted fields
static $sLibrary = null; // Encryption library used for all encrypted fields
public function __construct($sCode, $aParams)
{
parent::__construct($sCode, $aParams);
@@ -2745,6 +2745,10 @@ class AttributeEncryptedString extends AttributeString
{
self::$sKey = MetaModel::GetConfig()->GetEncryptionKey();
}
if(self::$sLibrary == null)
{
self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary();
}
}
/**
* When the attribute definitions are stored in APC cache:
@@ -2760,6 +2764,10 @@ class AttributeEncryptedString extends AttributeString
{
self::$sKey = MetaModel::GetConfig()->GetEncryptionKey();
}
if(self::$sLibrary == null)
{
self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary();
}
}
@@ -2788,7 +2796,7 @@ class AttributeEncryptedString extends AttributeString
*/
public function FromSQLToValue($aCols, $sPrefix = '')
{
$oSimpleCrypt = new SimpleCrypt();
$oSimpleCrypt = new SimpleCrypt(self::$sLibrary);
$sValue = $oSimpleCrypt->Decrypt(self::$sKey, $aCols[$sPrefix]);
return $sValue;
}
@@ -2798,7 +2806,7 @@ class AttributeEncryptedString extends AttributeString
*/
public function GetSQLValues($value)
{
$oSimpleCrypt = new SimpleCrypt();
$oSimpleCrypt = new SimpleCrypt(self::$sLibrary);
$encryptedValue = $oSimpleCrypt->Encrypt(self::$sKey, $value);
$aValues = array();

View File

@@ -37,6 +37,7 @@ define('ACCESS_READONLY', 0);
require_once('coreexception.class.inc.php');
require_once('attributedef.class.inc.php'); // For the defines
require_once('simplecrypt.class.inc.php');
class ConfigException extends CoreException
{
@@ -64,8 +65,8 @@ define('DEFAULT_FAST_RELOAD_INTERVAL', 1 * 60);
define('DEFAULT_SECURE_CONNECTION_REQUIRED', false);
define('DEFAULT_ALLOWED_LOGIN_TYPES', 'form|basic|external');
define('DEFAULT_EXT_AUTH_VARIABLE', '$_SERVER[\'REMOTE_USER\']');
define('DEFAULT_ENCRYPTION_KEY', '@iT0pEncr1pti0n!'); // We'll use a random value, later...
define('DEFAULT_ENCRYPTION_KEY', '@iT0pEncr1pti0n!'); // We'll use a random generated key later (if possible)
define('DEFAULT_ENCRYPTION_LIB', 'Mcrypt'); // We'll define the best encryption available later
/**
* Config
* configuration data (this class cannot not be localized, because it is responsible for loading the dictionaries)
@@ -1251,6 +1252,13 @@ class Config
*/
protected $m_sEncryptionKey;
/**
* @var string Encryption key used for all attributes of type "encrypted string". Can be set to a random value
* unless you want to import a database from another iTop instance, in which case you must use
* the same encryption key in order to properly decode the encrypted fields
*/
protected $m_sEncryptionLibrary;
/**
* @var array Additional character sets to be supported by the interactive CSV import
* 'iconv_code' => 'display name'
@@ -1296,10 +1304,14 @@ class Config
$this->m_sDefaultLanguage = 'EN US';
$this->m_sAllowedLoginTypes = DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = DEFAULT_EXT_AUTH_VARIABLE;
$this->m_sEncryptionKey = DEFAULT_ENCRYPTION_KEY;
$this->m_aCharsets = array();
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
//define default encryption params according to php install
$aEncryptParams = SimpleCrypt::GetNewDefaultParams();
$this->m_sEncryptionLibrary = isset($aEncryptParams['lib']) ? $aEncryptParams['lib'] : DEFAULT_ENCRYPTION_LIB;
$this->m_sEncryptionKey= isset($aEncryptParams['key']) ? $aEncryptParams['key'] : DEFAULT_ENCRYPTION_KEY;
$this->m_aModuleSettings = array();
if ($bLoadConfig)
@@ -1445,7 +1457,8 @@ class Config
$this->m_sDefaultLanguage = isset($MySettings['default_language']) ? trim($MySettings['default_language']) : 'EN US';
$this->m_sAllowedLoginTypes = isset($MySettings['allowed_login_types']) ? trim($MySettings['allowed_login_types']) : DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = isset($MySettings['ext_auth_variable']) ? trim($MySettings['ext_auth_variable']) : DEFAULT_EXT_AUTH_VARIABLE;
$this->m_sEncryptionKey = isset($MySettings['encryption_key']) ? trim($MySettings['encryption_key']) : DEFAULT_ENCRYPTION_KEY;
$this->m_sEncryptionKey = isset($MySettings['encryption_key']) ? trim($MySettings['encryption_key']) : $this->m_sEncryptionKey;
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
$this->m_aCharsets = isset($MySettings['csv_import_charsets']) ? $MySettings['csv_import_charsets'] : array();
}
@@ -1645,6 +1658,11 @@ class Config
return $this->m_sEncryptionKey;
}
public function GetEncryptionLibrary()
{
return $this->m_sEncryptionLibrary;
}
public function GetAllowedLoginTypes()
{
return explode('|', $this->m_sAllowedLoginTypes);
@@ -1773,6 +1791,7 @@ class Config
$aSettings['allowed_login_types'] = $this->m_sAllowedLoginTypes;
$aSettings['ext_auth_variable'] = $this->m_sExtAuthVariable;
$aSettings['encryption_key'] = $this->m_sEncryptionKey;
$aSettings['encryption_library'] = $this->m_sEncryptionLibrary;
$aSettings['csv_import_charsets'] = $this->m_aCharsets;
foreach ($this->m_aModuleSettings as $sModule => $aProperties)
@@ -1861,6 +1880,7 @@ class Config
'allowed_login_types' => $this->m_sAllowedLoginTypes,
'ext_auth_variable' => $this->m_sExtAuthVariable,
'encryption_key' => $this->m_sEncryptionKey,
'encryption_library' => $this->m_sEncryptionLibrary,
'csv_import_charsets' => $this->m_aCharsets,
);
foreach ($aOtherValues as $sKey => $value)

View File

@@ -43,17 +43,61 @@
class SimpleCrypt
{
public static function GetNewDefaultParams()
{
if(function_exists('sodium_crypto_secretbox_open') && function_exists('random_bytes')){
$sEngineName = 'Sodium';
}
else if (function_exists('openssl_decrypt'))
{
$sEngineName = 'OpenSSL';
}
else if(function_exists('mcrypt_module_open')){
$sEngineName = 'Mcrypt';
}
else
{
$sEngineName = 'Simple';
}
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
return $sEngineName::GetNewDefaultParams();
}
/**
* Constructor
* @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt
* @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt, Sodium or OpenSSL
* @throws Exception This library is unkown
*/
function __construct($sEngineName = 'Mcrypt')
{
if (($sEngineName == 'Mcrypt') && (!function_exists('mcrypt_module_open')))
{
// Defaults to Simple encryption if the mcrypt module is not present
$sEngineName = 'Simple';
}
switch($sEngineName){
case 'Sodium':
if(!function_exists('sodium_crypto_secretbox_open')){
$sEngineName = 'Simple';
}
break;
case 'Mcrypt':
if(!function_exists('mcrypt_module_open')){
if (function_exists('openssl_decrypt'))
{
$sEngineName = 'OpenSSLMcryptCompatibility';
}
else
{
$sEngineName = 'Simple';
}
}
break;
case 'OpenSSL':
if(!function_exists('openssl_decrypt')){
$sEngineName = 'Simple';
}
break;
case 'Simple':
break;
default:
throw new Exception(Dict::Format("Core:AttributeEncryptUnknownLibrary", $sEngineName));
}
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
$this->oEngine = new $sEngineName;
}
@@ -150,6 +194,7 @@ class SimpleCrypt
*/
interface CryptEngine
{
public static function GetNewDefaultParams();
function Encrypt($key, $sString);
function Decrypt($key, $encrypted_data);
}
@@ -161,7 +206,12 @@ interface CryptEngine
*/
class SimpleCryptSimpleEngine implements CryptEngine
{
public function Encrypt($key, $sString)
public static function GetNewDefaultParams()
{
return array( 'lib' => 'Simple', 'key' => null);
}
public function Encrypt($key, $sString)
{
$result = '';
for($i=1; $i<=strlen($sString); $i++)
@@ -197,7 +247,13 @@ class SimpleCryptMcryptEngine implements CryptEngine
{
var $alg = MCRYPT_BLOWFISH;
var $td = null;
public static function GetNewDefaultParams()
{
return array('lib' => 'Mcrypt', 'key' => null);
}
public function __construct()
{
$this->td = mcrypt_module_open($this->alg,'','cbc','');
@@ -205,7 +261,7 @@ class SimpleCryptMcryptEngine implements CryptEngine
public function Encrypt($key, $sString)
{
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND); // MCRYPT_RAND is the only choice on Windows prior to PHP 5.3
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND_URANDOM); // MCRYPT_RAND_URANDOM is now useable since itop requires php >= 5.6
mcrypt_generic_init($this->td, $key, $iv);
if (empty($sString))
{
@@ -223,7 +279,7 @@ class SimpleCryptMcryptEngine implements CryptEngine
$r = mcrypt_generic_init($this->td, $key, $iv);
if (($r < 0) || ($r === false))
{
$decrypted_data = '** decryption error **';
$decrypted_data = Dict::S("Core:AttributeEncryptFailedToDecrypt");
}
else
{
@@ -238,4 +294,121 @@ class SimpleCryptMcryptEngine implements CryptEngine
mcrypt_module_close($this->td);
}
}
?>
/**
* SodiumEngine requires Sodium extension
* Every encryption of the same string with the same key
* will return a different encrypted string.
* The key has to be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long.
*/
class SimpleCryptSodiumEngine implements CryptEngine
{
public static function GetNewDefaultParams()
{
return array('lib' => 'Sodium', 'key' => bin2hex(sodium_crypto_secretbox_keygen()));
}
public function Encrypt($key, $sString)
{
$key = hex2bin($key);
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted_string = sodium_crypto_secretbox($sString, $nonce, $key);
sodium_memzero($sString);
sodium_memzero($key);
return base64_encode($nonce.$encrypted_string);
}
public function Decrypt($key, $encrypted_data)
{
$key = hex2bin($key);
$encrypted_data = base64_decode($encrypted_data);
$nonce = mb_substr($encrypted_data, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$encrypted_data = mb_substr($encrypted_data, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$plaintext = sodium_crypto_secretbox_open($encrypted_data, $nonce, $key);
if ($plaintext === false)
{
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
}
sodium_memzero($encrypted_data);
sodium_memzero($key);
return $plaintext;
}
}
class SimpleCryptOpenSSLEngine implements CryptEngine
{
public static function GetNewDefaultParams()
{
return array('lib' => 'OpenSSL', 'key' => bin2hex(openssl_random_pseudo_bytes(32)));
}
public function Encrypt($key, $sString)
{
$key = hex2bin($key);
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"));
$encrypted_string = openssl_encrypt($sString, "AES-256-CBC", $key, 0 , $iv);
return $iv.$encrypted_string;
}
public function Decrypt($key, $encrypted_data)
{
$key = hex2bin($key);
$iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("AES-256-CBC"), '8bit');
$encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("AES-256-CBC"), null, '8bit');
$plaintext = openssl_decrypt($encrypted_data,"AES-256-CBC", $key, 0 , $iv);
if ($plaintext === false)
{
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
}
return trim($plaintext);
}
}
class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine
{
public static function GetNewDefaultParams()
{
return array('lib' => 'OpenSSLMcryptCompatibility', 'key' => null);
}
//fix for php < 7.1.8 (keys are Zero padded instead of cycle padded)
static private function MakeOpenSSLBlowfishKey($key)
{
if("$key" === '')
{
return $key;
}
$len = (16+2)*4;
while(strlen($key) < $len)
{
$key .= $key;
}
$key = substr($key, 0, $len);
return $key;
}
public function Encrypt($key, $sString)
{
$key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key);
$blockSize = 8;
$len = strlen($sString);
$paddingLen = intval (($len + $blockSize -1) / $blockSize) * $blockSize - $len;
$padding = str_repeat("\0", $paddingLen);
$sData = $sString . $padding;
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("BF-CBC"));
$encrypted_string = openssl_encrypt($sData, "BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
return $iv.$encrypted_string;
}
public function Decrypt($key, $encrypted_data)
{
$key = SimpleCryptOpenSSLMcryptCompatibilityEngine::MakeOpenSSLBlowfishKey($key);
$iv = mb_substr($encrypted_data, 0, openssl_cipher_iv_length("BF-CBC"), '8bit');
$encrypted_data = mb_substr($encrypted_data, openssl_cipher_iv_length("BF-CBC"), null, '8bit');
$plaintext = openssl_decrypt($encrypted_data,"BF-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
if ($plaintext === false)
{
$plaintext = Dict::S("Core:AttributeEncryptFailedToDecrypt");
}
return trim($plaintext);
}
}

View File

@@ -86,6 +86,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'Core:AttributeEncryptedString' => 'Šifrovaný řetězec',
'Core:AttributeEncryptedString+' => 'Řetězec šifrovaný lokálním klíčem',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text',
'Core:AttributeText+' => 'Víceřádkový řetězec znaků',

View File

@@ -1428,6 +1428,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'Core:AttributePassword+' => '',
'Core:AttributeEncryptedString' => 'Krypteret streng',
'Core:AttributeEncryptedString+' => '',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Tekst',
'Core:AttributeText+' => '',
'Core:AttributeHTML' => 'HTML',

View File

@@ -354,6 +354,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Core:AttributePassword+' => 'Passwort eines externen Geräts',
'Core:AttributeEncryptedString' => 'verschlüsselter String',
'Core:AttributeEncryptedString+' => 'mit einem lokalen Schüssel verschlüsselter String',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text',
'Core:AttributeText+' => 'Mehrzeiliger String',
'Core:AttributeHTML' => 'HTML',

View File

@@ -84,6 +84,8 @@ Dict::Add('EN US', 'English', 'English', array(
'Core:AttributeEncryptedString' => 'Encrypted string',
'Core:AttributeEncryptedString+' => 'String encrypted with a local key',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **',
'Core:AttributeText' => 'Text',
'Core:AttributeText+' => 'Multiline character string',

View File

@@ -84,7 +84,9 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'Core:AttributeEncryptedString' => 'Cadena encriptada',
'Core:AttributeEncryptedString+' => 'Cadena encriptada con llave local',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Texto',
'Core:AttributeText+' => 'Cadena de Múltiples Líneas de Caracteres',

View File

@@ -127,6 +127,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:CMDBChangeOpSetAttributeOneWayPassword/Attribute:prev_pwd+' => '',
'Class:CMDBChangeOpSetAttributeEncrypted' => 'Champ chiffré',
'Class:CMDBChangeOpSetAttributeEncrypted+' => '',
'Core:AttributeEncryptUnknownLibrary' => 'La bibliothèque de chiffrement specifée (%1$s) est inconnue',
'Core:AttributeEncryptFailedToDecrypt' => '** erreur de déchiffrage **',
'Class:CMDBChangeOpSetAttributeEncrypted/Attribute:prevstring' => 'Ancienne valeur',
'Class:CMDBChangeOpSetAttributeEncrypted/Attribute:prevstring+' => '',
'Class:CMDBChangeOpSetAttributeText' => 'Modification de texte',

View File

@@ -337,6 +337,8 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'Core:AttributePassword+' => '',
'Core:AttributeEncryptedString' => 'Encrypted string',
'Core:AttributeEncryptedString+' => '',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text',
'Core:AttributeText+' => '',
'Core:AttributeHTML' => 'HTML',

View File

@@ -78,6 +78,8 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'Core:AttributeEncryptedString' => 'Stringa criptata',
'Core:AttributeEncryptedString+' => 'Stringa cripta con una chiave locale',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Testo',
'Core:AttributeText+' => 'Stringa di caratteri multilinea',

View File

@@ -356,6 +356,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'Core:AttributePassword+' => '外部デバイス用パスワード',
'Core:AttributeEncryptedString' => '暗号化文字列',
'Core:AttributeEncryptedString+' => 'ローカルキーで暗号化された文字列',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'テキスト',
'Core:AttributeText+' => '複数行文字列',
'Core:AttributeHTML' => 'HTML',

View File

@@ -89,6 +89,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'Core:AttributeEncryptedString' => 'Gecodeerde string',
'Core:AttributeEncryptedString+' => 'String gecodeerd met een locale key',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text',
'Core:AttributeText+' => 'Multiline character string',

View File

@@ -84,6 +84,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'Core:AttributeEncryptedString' => 'String encriptada',
'Core:AttributeEncryptedString+' => 'String encriptada com uma chave local',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Texto',
'Core:AttributeText+' => 'Cadeia de caracteres Multi-linha',

View File

@@ -70,6 +70,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'Core:AttributeEncryptedString' => 'Шифр.значение',
'Core:AttributeEncryptedString+' => 'String encrypted with a local key',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Текст~~',
'Core:AttributeText+' => 'Multiline character string',

View File

@@ -444,6 +444,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'Core:AttributePassword+' => 'Password of an external device~~',
'Core:AttributeEncryptedString' => 'Encrypted string~~',
'Core:AttributeEncryptedString+' => 'String encrypted with a local key~~',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text~~',
'Core:AttributeText+' => 'Multiline character string~~',
'Core:AttributeHTML' => 'HTML~~',

View File

@@ -443,6 +443,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Core:AttributePassword+' => 'Password of an external device~~',
'Core:AttributeEncryptedString' => 'Encrypted string~~',
'Core:AttributeEncryptedString+' => 'String encrypted with a local key~~',
'Core:AttributeEncryptUnknownLibrary' => 'Encryption library specified (%1$s) unknown~~',
'Core:AttributeEncryptFailedToDecrypt' => '** decryption error **~~',
'Core:AttributeText' => 'Text~~',
'Core:AttributeText+' => 'Multiline character string~~',
'Core:AttributeHTML' => 'HTML~~',

View File

@@ -91,7 +91,9 @@ class SetupUtils
$aResult = array_merge($aResult, $aWritableDirsErrors);
$aMandatoryExtensions = array('mysqli', 'iconv', 'simplexml', 'soap', 'hash', 'json', 'session', 'pcre', 'dom', 'zlib', 'zip');
$aOptionalExtensions = array('mcrypt' => 'Strong encryption will not be used.',
$aOptionalExtensions = array( 'mcrypt, sodium or openssl' => array( 'mcrypt' => 'Strong encryption will not be used.',
'sodium' => 'Strong encryption will not be used.',
'openssl' => 'Strong encryption will not be used.',),
'ldap' => 'LDAP authentication will be disabled.',
'gd' => 'PDF export will be disabled. Also, image resizing will be disabled on profile pictures (May increase database size).');
asort($aMandatoryExtensions); // Sort the list to look clean !
@@ -125,13 +127,38 @@ class SetupUtils
$aMissingExtensions = array();
foreach($aOptionalExtensions as $sExtension => $sMessage)
{
if (extension_loaded($sExtension))
//if sMessage is an array, extensions in it are conditional between them
if (is_array($sMessage))
{
$aExtensionsOk[] = $sExtension;
$bIsAtLeastOneLoaded = false;
$sConditionalMissingMessage = '';
foreach($sMessage as $sConditionalExtension => $sConditionalMessage)
{
if (extension_loaded($sConditionalExtension))
{
$bIsAtLeastOneLoaded = true;
$aExtensionsOk[] = $sConditionalExtension;
}
else
{
$sConditionalMissingMessage = $sConditionalMessage;
}
}
if(!$bIsAtLeastOneLoaded)
{
$aMissingExtensions[$sExtension] = $sConditionalMissingMessage;
}
}
else
{
$aMissingExtensions[$sExtension] = $sMessage;
if (extension_loaded($sExtension))
{
$aExtensionsOk[] = $sExtension;
}
else
{
$aMissingExtensions[$sExtension] = $sMessage;
}
}
}
if (count($aExtensionsOk) > 0)