Merge branch 'master' into search-plugin-enhance

This commit is contained in:
Alexander Bigga 2021-03-03 17:18:08 +01:00 committed by GitHub
commit b69d040e81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 124 additions and 44 deletions

View File

@ -4,6 +4,7 @@ about: Create a report to help us improve.
title: ''
labels: bug
assignees: ''
---
## Description

View File

@ -0,0 +1,30 @@
---
name: Task for the development fund
about: A working package which may be sponsored by the Kitodo e.V. development fund.
title: "[FUND] "
labels: development fund
assignees: ""
---
## Description
A clear and concise description of what should be developed.
## Related Issues
Please check if there are already any [issues](https://github.com/kitodo/kitodo-presentation/issues) related to this task and link them here using `#issuenumber`.
## Expected Benefits of this Development
Please try to explain who will benefit of this development (administrators, editors, users, sales, ...).
## Estimated Costs and Complexity
Please try to estimate the costs and / or the complexity of the development.
e.g.
* **low** ~ less than 5 working days
* **medium** ~ less than 10 working days
* **high** ~ more than 10 working days

1
.gitignore vendored
View File

@ -8,4 +8,5 @@
composer.lock
Documentation-GENERATED-temp/
nbproject/
public/typo3/
vendor/

View File

@ -417,7 +417,7 @@ abstract class Document
// Sanitize input.
$pid = max(intval($pid), 0);
if (!$forceReload) {
$regObj = md5($uid);
$regObj = Helper::digest($uid);
if (
is_object(self::$registry[$regObj])
&& self::$registry[$regObj] instanceof self
@ -550,9 +550,9 @@ abstract class Document
if (
$instance instanceof self
&& $instance->ready) {
self::$registry[md5($instance->uid)] = $instance;
self::$registry[Helper::digest($instance->uid)] = $instance;
if ($instance->uid != $instance->location) {
self::$registry[md5($instance->location)] = $instance;
self::$registry[Helper::digest($instance->location)] = $instance;
}
// Load extension configuration
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);

View File

@ -34,6 +34,24 @@ class Helper
*/
public static $extKey = 'dlf';
/**
* This holds the cipher algorithm
* @see openssl_get_cipher_methods() for options
*
* @var string
* @access protected
*/
protected static $cipherAlgorithm = 'aes-256-ctr';
/**
* This holds the hash algorithm
* @see openssl_get_md_methods() for options
*
* @var string
* @access protected
*/
protected static $hashAlgorithm = 'sha256';
/**
* The locallang array for flash messages
*
@ -143,31 +161,36 @@ class Helper
* @access public
*
* @param string $encrypted: The encrypted value to decrypt
* @param string $hash: The control hash for decrypting
*
* @return mixed The decrypted value or null on error
* @return mixed The decrypted value or false on error
*/
public static function decrypt($encrypted, $hash)
public static function decrypt($encrypted)
{
if (
empty($encrypted)
|| empty($hash)
!in_array(self::$cipherAlgorithm, openssl_get_cipher_methods(true))
|| !in_array(self::$hashAlgorithm, openssl_get_md_methods(true))
) {
self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR);
return;
self::devLog('OpenSSL library doesn\'t support cipher and/or hash algorithm', DEVLOG_SEVERITY_ERROR);
return false;
}
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR);
return;
return false;
}
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, openssl_cipher_iv_length('BF-CFB'));
$decrypted = openssl_decrypt($encrypted, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv);
$salt = substr($hash, 0, 10);
$hashed = $salt . substr(sha1($salt . $decrypted), -10);
if ($hashed !== $hash) {
self::devLog('Invalid hash "' . $hash . '" given for decryption', DEVLOG_SEVERITY_WARNING);
return;
if (
empty($encrypted)
|| strlen($encrypted) < openssl_cipher_iv_length(self::$cipherAlgorithm)
) {
self::devLog('Invalid parameters given for decryption', DEVLOG_SEVERITY_ERROR);
return false;
}
// Split initialisation vector and encrypted data.
$binary = base64_decode($encrypted);
$iv = substr($binary, 0, openssl_cipher_iv_length(self::$cipherAlgorithm));
$data = substr($binary, openssl_cipher_iv_length(self::$cipherAlgorithm));
$key = openssl_digest($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], self::$hashAlgorithm, true);
// Decrypt data.
$decrypted = openssl_decrypt($data, self::$cipherAlgorithm, $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
@ -214,6 +237,26 @@ class Helper
}
}
/**
* Digest the given string
*
* @access public
*
* @param string $string: The string to encrypt
*
* @return mixed Hashed string or false on error
*/
public static function digest($string)
{
if (!in_array(self::$hashAlgorithm, openssl_get_md_methods(true))) {
self::devLog('OpenSSL library doesn\'t support hash algorithm', DEVLOG_SEVERITY_ERROR);
return false;
}
// Hash string.
$hashed = openssl_digest($string, self::$hashAlgorithm);
return $hashed;
}
/**
* Encrypt the given string
*
@ -221,19 +264,31 @@ class Helper
*
* @param string $string: The string to encrypt
*
* @return array Array with encrypted string and control hash
* @return mixed Encrypted string or false on error
*/
public static function encrypt($string)
{
if (
!in_array(self::$cipherAlgorithm, openssl_get_cipher_methods(true))
|| !in_array(self::$hashAlgorithm, openssl_get_md_methods(true))
) {
self::devLog('OpenSSL library doesn\'t support cipher and/or hash algorithm', DEVLOG_SEVERITY_ERROR);
return false;
}
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
self::devLog('No encryption key set in TYPO3 configuration', DEVLOG_SEVERITY_ERROR);
return;
return false;
}
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, openssl_cipher_iv_length('BF-CFB'));
$encrypted = openssl_encrypt($string, 'BF-CFB', substr($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 0, 56), 0, $iv);
$salt = substr(md5(uniqid(rand(), true)), 0, 10);
$hash = $salt . substr(sha1($salt . $string), -10);
return ['encrypted' => $encrypted, 'hash' => $hash];
// Generate random initialisation vector.
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(self::$cipherAlgorithm));
$key = openssl_digest($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], self::$hashAlgorithm, true);
// Encrypt data.
$encrypted = openssl_encrypt($string, self::$cipherAlgorithm, $key, OPENSSL_RAW_DATA, $iv);
// Merge initialisation vector and encrypted data.
if ($encrypted !== false) {
$encrypted = base64_encode($iv . $encrypted);
}
return $encrypted;
}
/**

View File

@ -425,11 +425,9 @@ class Solr
$parameters['rows'] = $this->limit;
// Set query.
$parameters['query'] = $query;
// calculate cache identifier
$cacheIdentifier = hash('md5', $this->core . print_r(array_merge($this->params, $parameters), 1));
// Calculate cache identifier.
$cacheIdentifier = Helper::digest($this->core . print_r(array_merge($this->params, $parameters), true));
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('tx_dlf_solr');
$resultSet = [];
if (($entry = $cache->get($cacheIdentifier)) === false) {
$selectQuery = $this->service->createSelect(array_merge($this->params, $parameters));
@ -437,10 +435,10 @@ class Solr
foreach ($result as $doc) {
$resultSet[] = $doc;
}
// Save value in cache
// Save value in cache.
$cache->set($cacheIdentifier, $resultSet);
} else {
// return cache hit
// Return cache hit.
$resultSet = $entry;
}
return $resultSet;

View File

@ -44,12 +44,11 @@ class SearchInDocument
// Get input parameters and decrypt core name.
$parameters = $request->getParsedBody();
$encrypted = (string) $parameters['encrypted'];
$hashed = (string) $parameters['hashed'];
$count = intval($parameters['start']);
if (empty($encrypted) || empty($hashed)) {
if (empty($encrypted)) {
throw new \InvalidArgumentException('No valid parameter passed!', 1580585079);
}
$core = Helper::decrypt($encrypted, $hashed);
$core = Helper::decrypt($encrypted);
// Perform Solr query.
$solr = Solr::getInstance($core);
if ($solr->ready) {

View File

@ -42,11 +42,10 @@ class SearchSuggest
// Get input parameters and decrypt core name.
$parameters = $request->getParsedBody();
$encrypted = (string) $parameters['encrypted'];
$hashed = (string) $parameters['hashed'];
if (empty($encrypted) || empty($hashed)) {
if (empty($encrypted)) {
throw new \InvalidArgumentException('No valid parameter passed!', 1580585079);
}
$core = Helper::decrypt($encrypted, $hashed);
$core = Helper::decrypt($encrypted);
// Perform Solr query.
$solr = Solr::getInstance($core);
if ($solr->ready) {

View File

@ -157,8 +157,8 @@ class Search extends \Kitodo\Dlf\Common\AbstractPlugin
$name = Helper::encrypt($name);
}
// Add encrypted fields to search form.
if (is_array($name)) {
return '<input type="hidden" name="' . $this->prefixId . '[encrypted]" value="' . $name['encrypted'] . '" /><input type="hidden" name="' . $this->prefixId . '[hashed]" value="' . $name['hash'] . '" />';
if ($name !== false) {
return '<input type="hidden" name="' . $this->prefixId . '[encrypted]" value="' . $name . '" />';
} else {
return '';
}

View File

@ -108,8 +108,7 @@ class SearchInDocumentTool extends \Kitodo\Dlf\Common\AbstractPlugin
'###LABEL_PAGE###' => htmlspecialchars($this->pi_getLL('label.logicalPage')),
'###LABEL_NORESULT###' => htmlspecialchars($this->pi_getLL('label.noresult')),
'###CURRENT_DOCUMENT###' => $this->doc->uid,
'###SOLR_ENCRYPTED###' => isset($encryptedSolr['encrypted']) ? $encryptedSolr['encrypted'] : '',
'###SOLR_HASH###' => isset($encryptedSolr['hash']) ? $encryptedSolr['hash'] : '',
'###SOLR_ENCRYPTED###' => $encryptedSolr ?: '',
];
$content .= $this->templateService->substituteMarkerArray($this->template, $markerArray);
@ -134,7 +133,7 @@ class SearchInDocumentTool extends \Kitodo\Dlf\Common\AbstractPlugin
*
* @access protected
*
* @return array with encrypted core name and hash
* @return string with encrypted core name
*/
protected function getEncryptedCoreName()
{

View File

@ -26,7 +26,6 @@ limitations under the License.
<fieldType name="standard" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory" />
<filter class="solr.StandardFilterFactory" />
<filter class="solr.LowerCaseFilterFactory" />
</analyzer>
</fieldType>

View File

@ -17,7 +17,6 @@
<input type="hidden" name="tx_dlf[start]" value="0" />
<input type="hidden" name="tx_dlf[id]" value="###CURRENT_DOCUMENT###" />
<input type="hidden" name="tx_dlf[encrypted]" value="###SOLR_ENCRYPTED###" />
<input type="hidden" name="tx_dlf[hashed]" value="###SOLR_HASH###" />
</div>
</form>
<div id="tx-dlf-search-in-document-loading" style="display: none;">###LABEL_LOADING###...</div>