mirror of https://github.com/MISP/MISP
Merge pull request #7938 from JakubOnderka/authkeys-encrypted-vol2
Authkeys encrypted vol2pull/7946/head
commit
5c5f2b54ca
|
@ -45,6 +45,15 @@ class AdminShell extends AppShell
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
$parser->addSubcommand('reencrypt', [
|
||||||
|
'help' => __('Reencrypt encrypted values in database (authkeys and sensitive system settings).'),
|
||||||
|
'parser' => [
|
||||||
|
'options' => [
|
||||||
|
'old' => ['help' => __('Old key. If not provided, current key will be used.')],
|
||||||
|
'new' => ['help' => __('New key. If not provided, new key will be generated.')],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
$parser->addSubcommand('removeOrphanedCorrelations', [
|
$parser->addSubcommand('removeOrphanedCorrelations', [
|
||||||
'help' => __('Remove orphaned correlations.'),
|
'help' => __('Remove orphaned correlations.'),
|
||||||
]);
|
]);
|
||||||
|
@ -891,4 +900,51 @@ class AdminShell extends AppShell
|
||||||
$this->out('Redis: ' . ($newStatus !== '0' ? 'True' : 'False'));
|
$this->out('Redis: ' . ($newStatus !== '0' ? 'True' : 'False'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reencrypt()
|
||||||
|
{
|
||||||
|
$old = $this->params['old'] ?? null;
|
||||||
|
$new = $this->params['new'] ?? null;
|
||||||
|
|
||||||
|
if ($new !== null && strlen($new) < 32) {
|
||||||
|
$this->error('New key must be at least 32 char long.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($old === null) {
|
||||||
|
$old = Configure::read('Security.encryption_key');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($new === null) {
|
||||||
|
// Generate random new key
|
||||||
|
$randomTool = new RandomTool();
|
||||||
|
$new = $randomTool->random_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Server->getDataSource()->begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
/** @var SystemSetting $systemSetting */
|
||||||
|
$systemSetting = ClassRegistry::init('SystemSetting');
|
||||||
|
$systemSetting->reencrypt($old, $new);
|
||||||
|
|
||||||
|
$this->Server->reencryptAuthKeys($old, $new);
|
||||||
|
|
||||||
|
/** @var Cerebrate $cerebrate */
|
||||||
|
$cerebrate = ClassRegistry::init('Cerebrate');
|
||||||
|
$cerebrate->reencryptAuthKeys($old, $new);
|
||||||
|
|
||||||
|
$result = $this->Server->serverSettingsSaveValue('Security.encryption_key', $new, true);
|
||||||
|
|
||||||
|
$this->Server->getDataSource()->commit();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
$this->error('Encrypt key was changed, but it is not possible to save key to config file', __('Please insert new key "%s" to config file manually.', $new));
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->Server->getDataSource()->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out(__('New encryption key "%s" saved into config file.', $new));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
App::uses('BetterSecurity', 'Tools');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for ondemand encryption of JSON serialized value
|
||||||
|
*/
|
||||||
|
class EncryptedValue implements JsonSerializable
|
||||||
|
{
|
||||||
|
const ENCRYPTED_MAGIC = "\x1F\x1D";
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $isJson;
|
||||||
|
|
||||||
|
public function __construct($value, $isJson = false)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
$this->isJson = $isJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
* @throws JsonException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function decrypt()
|
||||||
|
{
|
||||||
|
$decrypt = BetterSecurity::decrypt(substr($this->value, 2), Configure::read('Security.encryption_key'));
|
||||||
|
return $this->isJson ? JsonTool::decode($decrypt) : $decrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->decrypt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->decrypt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt provided string if encryption is enabled. If not enabled, input value will be returned.
|
||||||
|
* @param string $value
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function encryptIfEnabled($value)
|
||||||
|
{
|
||||||
|
$key = Configure::read('Security.encryption_key');
|
||||||
|
if ($key) {
|
||||||
|
return EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($value, $key);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if value is encrypted (starts with encrypted magic)
|
||||||
|
* @param string $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isEncrypted($value)
|
||||||
|
{
|
||||||
|
return substr($value, 0, 2) === EncryptedValue::ENCRYPTED_MAGIC;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1597,6 +1597,8 @@ class AppModel extends Model
|
||||||
`value` blob NOT NULL,
|
`value` blob NOT NULL,
|
||||||
PRIMARY KEY (`setting`)
|
PRIMARY KEY (`setting`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
|
||||||
|
$sqlArray[] = "ALTER TABLE `servers` MODIFY COLUMN `authkey` VARBINARY(255) NOT NULL;";
|
||||||
|
$sqlArray[] = "ALTER TABLE `cerebrates` MODIFY COLUMN `authkey` VARBINARY(255) NOT NULL;";
|
||||||
break;
|
break;
|
||||||
case 77:
|
case 77:
|
||||||
$sqlArray[] = "ALTER TABLE `tags` ADD `local_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `is_custom_galaxy`;";
|
$sqlArray[] = "ALTER TABLE `tags` ADD `local_only` tinyint(1) NOT NULL DEFAULT 0 AFTER `is_custom_galaxy`;";
|
||||||
|
@ -2687,15 +2689,21 @@ class AppModel extends Model
|
||||||
{
|
{
|
||||||
$version = implode('.', $this->checkMISPVersion());
|
$version = implode('.', $this->checkMISPVersion());
|
||||||
$commit = $this->checkMIPSCommit();
|
$commit = $this->checkMIPSCommit();
|
||||||
$request = array(
|
|
||||||
|
$authkey = $server[$model]['authkey'];
|
||||||
|
App::uses('EncryptedValue', 'Tools');
|
||||||
|
if (EncryptedValue::isEncrypted($authkey)) {
|
||||||
|
$authkey = (string)new EncryptedValue($authkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
'header' => array(
|
'header' => array(
|
||||||
'Authorization' => $server[$model]['authkey'],
|
'Authorization' => $authkey,
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
'Content-Type' => 'application/json',
|
'Content-Type' => 'application/json',
|
||||||
'User-Agent' => 'MISP ' . $version . (empty($commit) ? '' : ' - #' . $commit),
|
'User-Agent' => 'MISP ' . $version . (empty($commit) ? '' : ' - #' . $commit),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return $request;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
App::uses('AppModel', 'Model');
|
App::uses('AppModel', 'Model');
|
||||||
|
App::uses('EncryptedValue', 'Tools');
|
||||||
|
|
||||||
class Cerebrate extends AppModel
|
class Cerebrate extends AppModel
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,18 @@ class Cerebrate extends AppModel
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public function queryInstance($options) {
|
public function beforeSave($options = array())
|
||||||
|
{
|
||||||
|
$cerebrate = &$this->data['Server'];
|
||||||
|
// Encrypt authkey if plain key provided and encryption is enabled
|
||||||
|
if (!empty($cerebrate['authkey']) && strlen($cerebrate['authkey']) === 40) {
|
||||||
|
$cerebrate['authkey'] = EncryptedValue::encryptIfEnabled($cerebrate['authkey']);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function queryInstance($options)
|
||||||
|
{
|
||||||
$url = $options['cerebrate']['Cerebrate']['url'] . $options['path'];
|
$url = $options['cerebrate']['Cerebrate']['url'] . $options['path'];
|
||||||
$url_params = [];
|
$url_params = [];
|
||||||
|
|
||||||
|
@ -413,4 +424,37 @@ class Cerebrate extends AppModel
|
||||||
}
|
}
|
||||||
return __('The retrieved data isn\'t a valid sharing group.');
|
return __('The retrieved data isn\'t a valid sharing group.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $old Old (or current) encryption key.
|
||||||
|
* @param string|null $new New encryption key. If empty, encrypted values will be decrypted.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function reencryptAuthKeys($old, $new)
|
||||||
|
{
|
||||||
|
$cerebrates = $this->find('list', [
|
||||||
|
'fields' => ['Cerebrate.id', 'Cerebrate.authkey'],
|
||||||
|
]);
|
||||||
|
$toSave = [];
|
||||||
|
foreach ($cerebrates as $id => $authkey) {
|
||||||
|
if (EncryptedValue::isEncrypted($authkey)) {
|
||||||
|
try {
|
||||||
|
$authkey = BetterSecurity::decrypt(substr($authkey, 2), $old);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Exception("Could not decrypt auth key for Cerebrate #$id", 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($new)) {
|
||||||
|
$authkey = EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($authkey, $new);
|
||||||
|
}
|
||||||
|
$toSave[] = ['Cerebrate' => [
|
||||||
|
'id' => $id,
|
||||||
|
'authkey' => $authkey,
|
||||||
|
]];
|
||||||
|
}
|
||||||
|
if (empty($toSave)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $this->saveMany($toSave, ['validate' => false, 'fields' => ['authkey']]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ App::uses('AppModel', 'Model');
|
||||||
App::uses('GpgTool', 'Tools');
|
App::uses('GpgTool', 'Tools');
|
||||||
App::uses('ServerSyncTool', 'Tools');
|
App::uses('ServerSyncTool', 'Tools');
|
||||||
App::uses('SystemSetting', 'Model');
|
App::uses('SystemSetting', 'Model');
|
||||||
|
App::uses('EncryptedValue', 'Tools');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property-read array $serverSettings
|
* @property-read array $serverSettings
|
||||||
|
@ -165,8 +166,11 @@ class Server extends AppModel
|
||||||
|
|
||||||
public function beforeSave($options = array())
|
public function beforeSave($options = array())
|
||||||
{
|
{
|
||||||
$this->data['Server']['url'] = rtrim($this->data['Server']['url'], '/');
|
$server = &$this->data['Server'];
|
||||||
if (empty($this->data['Server']['id'])) {
|
if (!empty($server['url'])) {
|
||||||
|
$server['url'] = rtrim($server['url'], '/');
|
||||||
|
}
|
||||||
|
if (empty($server['id'])) {
|
||||||
$max_prio = $this->find('first', array(
|
$max_prio = $this->find('first', array(
|
||||||
'recursive' => -1,
|
'recursive' => -1,
|
||||||
'order' => array('Server.priority' => 'DESC'),
|
'order' => array('Server.priority' => 'DESC'),
|
||||||
|
@ -177,7 +181,11 @@ class Server extends AppModel
|
||||||
} else {
|
} else {
|
||||||
$max_prio = $max_prio['Server']['priority'];
|
$max_prio = $max_prio['Server']['priority'];
|
||||||
}
|
}
|
||||||
$this->data['Server']['priority'] = $max_prio + 1;
|
$server['priority'] = $max_prio + 1;
|
||||||
|
}
|
||||||
|
// Encrypt authkey if plain key provided and encryption is enabled
|
||||||
|
if (!empty($server['authkey']) && strlen($server['authkey']) === 40) {
|
||||||
|
$server['authkey'] = EncryptedValue::encryptIfEnabled($server['authkey']);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2268,6 +2276,9 @@ class Server extends AppModel
|
||||||
|
|
||||||
/** @var array $config */
|
/** @var array $config */
|
||||||
require $configFilePath;
|
require $configFilePath;
|
||||||
|
if (!isset($config)) {
|
||||||
|
throw new Exception("Could not load config file `$configFilePath`.");
|
||||||
|
}
|
||||||
$config = Hash::insert($config, $setting, $value);
|
$config = Hash::insert($config, $setting, $value);
|
||||||
|
|
||||||
$settingsToSave = array(
|
$settingsToSave = array(
|
||||||
|
@ -4522,6 +4533,39 @@ class Server extends AppModel
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $old Old (or current) encryption key.
|
||||||
|
* @param string|null $new New encryption key. If empty, encrypted values will be decrypted.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function reencryptAuthKeys($old, $new)
|
||||||
|
{
|
||||||
|
$servers = $this->find('list', [
|
||||||
|
'fields' => ['Server.id', 'Server.authkey'],
|
||||||
|
]);
|
||||||
|
$toSave = [];
|
||||||
|
foreach ($servers as $id => $authkey) {
|
||||||
|
if (EncryptedValue::isEncrypted($authkey)) {
|
||||||
|
try {
|
||||||
|
$authkey = BetterSecurity::decrypt(substr($authkey, 2), $old);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Exception("Could not decrypt auth key for server #$id", 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($new)) {
|
||||||
|
$authkey = EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($authkey, $new);
|
||||||
|
}
|
||||||
|
$toSave[] = ['Server' => [
|
||||||
|
'id' => $id,
|
||||||
|
'authkey' => $authkey,
|
||||||
|
]];
|
||||||
|
}
|
||||||
|
if (empty($toSave)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $this->saveMany($toSave, ['validate' => false, 'fields' => ['authkey']]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate just when required
|
* Generate just when required
|
||||||
* @return array[]
|
* @return array[]
|
||||||
|
@ -6001,6 +6045,12 @@ class Server extends AppModel
|
||||||
/** @var SystemSetting $systemSetting */
|
/** @var SystemSetting $systemSetting */
|
||||||
$systemSetting = ClassRegistry::init('SystemSetting');
|
$systemSetting = ClassRegistry::init('SystemSetting');
|
||||||
$systemSetting->reencrypt($old, $new);
|
$systemSetting->reencrypt($old, $new);
|
||||||
|
|
||||||
|
$this->reencryptAuthKeys($old, $new);
|
||||||
|
|
||||||
|
/** @var Cerebrate $cerebrate */
|
||||||
|
$cerebrate = ClassRegistry::init('Cerebrate');
|
||||||
|
$cerebrate->reencryptAuthKeys($old, $new);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
|
|
|
@ -1,45 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
App::uses('AppModel', 'Model');
|
App::uses('AppModel', 'Model');
|
||||||
App::uses('JsonTool', 'Tools');
|
App::uses('EncryptedValue', 'Tools');
|
||||||
App::uses('BetterSecurity', 'Tools');
|
App::uses('BetterSecurity', 'Tools');
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for ondemand encryption of JSON serialized value
|
|
||||||
*/
|
|
||||||
class EncryptedValue implements JsonSerializable
|
|
||||||
{
|
|
||||||
const ENCRYPTED_MAGIC = "\x1F\x1D";
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $value;
|
|
||||||
|
|
||||||
public function __construct($value)
|
|
||||||
{
|
|
||||||
$this->value = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
* @throws JsonException
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function decrypt()
|
|
||||||
{
|
|
||||||
$decrypt = BetterSecurity::decrypt($this->value, Configure::read('Security.encryption_key'));
|
|
||||||
return JsonTool::decode($decrypt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return $this->decrypt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function jsonSerialize()
|
|
||||||
{
|
|
||||||
return $this->decrypt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SystemSetting extends AppModel
|
class SystemSetting extends AppModel
|
||||||
{
|
{
|
||||||
public $actsAs = [
|
public $actsAs = [
|
||||||
|
@ -91,13 +54,20 @@ class SystemSetting extends AppModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function getSettings()
|
public function getSettings()
|
||||||
{
|
{
|
||||||
$settings = $this->find('list', [
|
$settings = $this->find('list', [
|
||||||
'fields' => ['SystemSetting.setting', 'SystemSetting.value'],
|
'fields' => ['SystemSetting.setting', 'SystemSetting.value'],
|
||||||
]);
|
]);
|
||||||
return array_map([$this, 'decode'], $settings);
|
return array_map(function ($value) {
|
||||||
|
if (EncryptedValue::isEncrypted($value)) {
|
||||||
|
return new EncryptedValue($value, true);
|
||||||
|
} else {
|
||||||
|
return JsonTool::decode($value);
|
||||||
|
}
|
||||||
|
}, $settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,9 +92,8 @@ class SystemSetting extends AppModel
|
||||||
$value = JsonTool::encode($value);
|
$value = JsonTool::encode($value);
|
||||||
|
|
||||||
// If encryption is enabled and setting name contains `password` or `apikey` string, encrypt value to protect it
|
// If encryption is enabled and setting name contains `password` or `apikey` string, encrypt value to protect it
|
||||||
$key = Configure::read('Security.encryption_key');
|
if (self::isSensitive($setting)) {
|
||||||
if ($key && self::isSensitive($setting)) {
|
$value = EncryptedValue::encryptIfEnabled($value);
|
||||||
$value = EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($value, $key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$valid = $this->save(['SystemSetting' => [
|
$valid = $this->save(['SystemSetting' => [
|
||||||
|
@ -140,7 +109,7 @@ class SystemSetting extends AppModel
|
||||||
/**
|
/**
|
||||||
* @param string|null $old Old (or current) encryption key.
|
* @param string|null $old Old (or current) encryption key.
|
||||||
* @param string|null $new New encryption key. If empty, encrypted values will be decrypted.
|
* @param string|null $new New encryption key. If empty, encrypted values will be decrypted.
|
||||||
* @throws JsonException
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function reencrypt($old, $new)
|
public function reencrypt($old, $new)
|
||||||
{
|
{
|
||||||
|
@ -152,8 +121,12 @@ class SystemSetting extends AppModel
|
||||||
if (!self::isSensitive($setting)) {
|
if (!self::isSensitive($setting)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (substr($value, 0, 2) === EncryptedValue::ENCRYPTED_MAGIC) {
|
if (EncryptedValue::isEncrypted($value)) {
|
||||||
|
try {
|
||||||
$value = BetterSecurity::decrypt(substr($value, 2), $old);
|
$value = BetterSecurity::decrypt(substr($value, 2), $old);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Exception("Could not decrypt `$setting` setting.", 0, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!empty($new)) {
|
if (!empty($new)) {
|
||||||
$value = EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($value, $new);
|
$value = EncryptedValue::ENCRYPTED_MAGIC . BetterSecurity::encrypt($value, $new);
|
||||||
|
@ -163,23 +136,12 @@ class SystemSetting extends AppModel
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
|
if (empty($toSave)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return $this->saveMany($toSave);
|
return $this->saveMany($toSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $value
|
|
||||||
* @return EncryptedValue|mixed
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
private function decode($value)
|
|
||||||
{
|
|
||||||
if (substr($value, 0, 2) === EncryptedValue::ENCRYPTED_MAGIC) {
|
|
||||||
return new EncryptedValue(substr($value, 2));
|
|
||||||
} else {
|
|
||||||
return JsonTool::decode($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sensitive setting are passwords or api keys.
|
* Sensitive setting are passwords or api keys.
|
||||||
* @param string $setting Setting name
|
* @param string $setting Setting name
|
||||||
|
|
|
@ -769,12 +769,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"column_name": "authkey",
|
"column_name": "authkey",
|
||||||
"is_nullable": "YES",
|
"is_nullable": "NO",
|
||||||
"data_type": "varchar",
|
"data_type": "varbinary",
|
||||||
"character_maximum_length": "40",
|
"character_maximum_length": "255",
|
||||||
"numeric_precision": null,
|
"numeric_precision": null,
|
||||||
"collation_name": "ascii_general_ci",
|
"collation_name": null,
|
||||||
"column_type": "varchar(40)",
|
"column_type": "varbinary(255)",
|
||||||
"column_default": null,
|
"column_default": null,
|
||||||
"extra": ""
|
"extra": ""
|
||||||
},
|
},
|
||||||
|
@ -5074,11 +5074,11 @@
|
||||||
{
|
{
|
||||||
"column_name": "authkey",
|
"column_name": "authkey",
|
||||||
"is_nullable": "NO",
|
"is_nullable": "NO",
|
||||||
"data_type": "varchar",
|
"data_type": "varbinary",
|
||||||
"character_maximum_length": "40",
|
"character_maximum_length": "255",
|
||||||
"numeric_precision": null,
|
"numeric_precision": null,
|
||||||
"collation_name": "utf8_bin",
|
"collation_name": null,
|
||||||
"column_type": "varchar(40)",
|
"column_type": "varbinary(255)",
|
||||||
"column_default": null,
|
"column_default": null,
|
||||||
"extra": ""
|
"extra": ""
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue