Merge branch '2.4' of github.com:MISP/MISP into eventFiltering

pull/4076/head
mokaddem 2019-02-04 10:00:12 +01:00
commit 1db4567692
14 changed files with 197 additions and 160 deletions

2
PyMISP

@ -1 +1 @@
Subproject commit dc5d40a327233895792b8148a7c87d5a1c2ebfb1
Subproject commit 2c877f2aec11b7f5d2f23dfc5ce7398b2ce33b48

View File

@ -1 +1 @@
{"major":2, "minor":4, "hotfix":101}
{"major":2, "minor":4, "hotfix":102}

View File

@ -146,15 +146,26 @@ class AdminShell extends AppShell
}
public function setSetting() {
$setting = !isset($this->args[0]) ? null : $this->args[0];
$setting_name = !isset($this->args[0]) ? null : $this->args[0];
$value = !isset($this->args[1]) ? null : $this->args[1];
if ($value === 'false') $value = 0;
if ($value === 'true') $value = 1;
if (empty($setting) || $value === null) {
$cli_user = array('id' => 0, 'email' => 'SYSTEM', 'Organisation' => array('name' => 'SYSTEM'));
if (empty($setting_name) || $value === null) {
echo 'Invalid parameters. Usage: ' . APP . 'Console/cake Admin setSetting [setting_name] [setting_value]';
} else {
$this->Server->serverSettingsSaveValue($setting, $value);
$setting = $this->Server->getSettingData($setting_name);
if (empty($setting)) {
echo 'Invalid setting. Please make sure that the setting that you are attempting to change exists.';
}
$result = $this->Server->serverSettingsEditValue($cli_user, $setting, $value);
if ($result === true) {
echo 'Setting changed.';
} else {
echo $result;
}
}
echo PHP_EOL;
}
public function setDatabaseVersion() {

View File

@ -47,8 +47,8 @@ class AppController extends Controller
public $helpers = array('Utility', 'OrgImg');
private $__queryVersion = '54';
public $pyMispVersion = '2.4.101';
public $phpmin = '5.6.5';
public $pyMispVersion = '2.4.102';
public $phpmin = '7.0.16';
public $phprec = '7.0.16';
public $baseurl = '';

View File

@ -1933,9 +1933,18 @@ class AttributesController extends AppController
$this->set('fails', $this->Attribute->checkComposites());
}
public function restSearch($returnFormat = false, $value = false, $type = false, $category = false, $org = false, $tags = false, $from = false, $to = false, $last = false, $eventid = false, $withAttachments = false, $uuid = false, $publish_timestamp = false, $published = false, $timestamp = false, $enforceWarninglist = false, $to_ids = false, $deleted = false, $includeEventUuid = false, $event_timestamp = false, $threat_level_id = false)
public function restSearch(
$returnFormat = false, $value = false, $type = false, $category = false, $org = false, $tags = false, $from = false,
$to = false, $last = false, $eventid = false, $withAttachments = false, $uuid = false, $publish_timestamp = false, $published = false,
$timestamp = false, $enforceWarninglist = false, $to_ids = false, $deleted = false, $includeEventUuid = false, $event_timestamp = false,
$threat_level_id = false
)
{
$paramArray = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'event_timestamp', 'threat_level_id', 'includeEventTags', 'includeProposals', 'returnFormat', 'published');
$paramArray = array(
'value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachbocsi ments', 'uuid', 'publish_timestamp',
'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'event_timestamp', 'threat_level_id', 'includeEventTags',
'includeProposals', 'returnFormat', 'published', 'limit', 'page', 'requested_attributes', 'includeContext', 'headerless'
);
$filterData = array(
'request' => $this->request,
'named_params' => $this->params['named'],

View File

@ -3136,7 +3136,7 @@ class EventsController extends AppController
// && - you can use && between two search values to put a logical OR between them. for value, 1.1.1.1&&2.2.2.2 would find attributes with the value being either of the two.
// ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't.
public function restSearch(
$returnFormat = 'json',
$returnFormat = false,
$value = false,
$type = false,
$category = false,
@ -3158,7 +3158,8 @@ class EventsController extends AppController
) {
$paramArray = array(
'value', 'type', 'category', 'org', 'tag', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments',
'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly'
'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly', 'returnFormat',
'limit', 'page', 'requested_attributes', 'includeContext', 'headerless'
);
$filterData = array(
'request' => $this->request,
@ -3177,10 +3178,9 @@ class EventsController extends AppController
if ($user === false) {
return $exception;
}
if (isset($filters['returnFormat'])) {
if (!empty($filters['returnFormat'])) {
$returnFormat = $filters['returnFormat'];
}
if ($returnFormat === 'download') {
} else if (empty($filters['returnFormat']) || $filters['returnFormat'] === 'download'){
$returnFormat = 'json';
}
$elementCounter = 0;
@ -4114,12 +4114,12 @@ class EventsController extends AppController
'checkbox_set' => '/events/csv/download/' . $id . '/1/0/0/0/1'
),
'stix_xml' => array(
'url' => '/events/stix/download/' . $id . '.xml',
'url' => '/events/restSearch/stix/eventid:' . $id,
'text' => 'STIX XML (metadata + all attributes)',
'requiresPublished' => true,
'checkbox' => true,
'checkbox_text' => 'Encode Attachments',
'checkbox_set' => '/events/stix/download/' . $id . '/true.xml'
'checkbox_set' => '/events/restSearch/stix/eventid:' . $id . '/withAttachments:1'
),
'stix_json' => array(
'url' => '/events/stix/download/' . $id . '.json',
@ -4130,12 +4130,12 @@ class EventsController extends AppController
'checkbox_set' => '/events/stix/download/' . $id . '/true.json'
),
'stix2_json' => array(
'url' => '/events/stix2/download/' . $id . '.json',
'url' => '/events/restSearch/stix2/eventid:' . $id,
'text' => 'STIX2 (requires the STIX 2 library)',
'requiresPublished' => false,
'checkbox' => true,
'checkbox_text' => 'Encode Attachments',
'checkbox_set' => '/events/stix2/download/' . $id . '/1.json'
'checkbox_set' => '/events/restSearch/stix2/eventid:' . $id . '/withAttachments:1'
),
'rpz' => array(
'url' => '/attributes/rpz/download/false/' . $id,

View File

@ -1135,67 +1135,39 @@ class ServersController extends AppController
}
}
public function serverSettingsEdit($setting, $id = false, $forceSave = false)
public function serverSettingsEdit($setting_name, $id = false, $forceSave = false)
{
// invalidate config.php from php opcode cache
if (function_exists('opcache_reset')) {
opcache_reset();
}
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException();
}
if (!isset($setting) || !isset($id)) {
if (!isset($setting_name) || !isset($id)) {
throw new MethodNotAllowedException();
}
$this->set('id', $id);
if (strpos($setting, 'Plugin.Enrichment') !== false || strpos($setting, 'Plugin.Import') !== false || strpos($setting, 'Plugin.Export') !== false || strpos($setting, 'Plugin.Cortex') !== false) {
$serverSettings = $this->Server->getCurrentServerSettings();
} else {
$serverSettings = $this->Server->serverSettings;
}
$relevantSettings = (array_intersect_key(Configure::read(), $serverSettings));
$found = null;
foreach ($serverSettings as $k => $s) {
if (isset($s['branch'])) {
foreach ($s as $ek => $es) {
if ($ek != 'branch') {
if ($setting == $k . '.' . $ek) {
$found = $es;
continue 2;
}
}
}
} else {
if ($setting == $k) {
$found = $s;
continue;
}
}
}
$setting = $this->Server->getSettingData($setting_name);
if ($this->request->is('get')) {
if ($found != null) {
$value = Configure::read($setting);
if ($setting != null) {
$value = Configure::read($setting['name']);
if ($value) {
$found['value'] = $value;
$setting['value'] = $value;
}
$found['setting'] = $setting;
$setting['setting'] = $setting['name'];
}
if (isset($found['optionsSource']) && !empty($found['optionsSource'])) {
$found['options'] = $this->{'__load' . $found['optionsSource']}();
if (isset($setting['optionsSource']) && !empty($setting['optionsSource'])) {
$setting['options'] = $this->{'__load' . $setting['optionsSource']}();
}
$subGroup = 'general';
$subGroup = explode('.', $setting);
$subGroup = explode('.', $setting['name']);
if ($subGroup[0] === 'Plugin') {
$subGroup = explode('_', $subGroup[1])[0];
} else {
$subGroup = 'general';
}
if ($this->_isRest()) {
return $this->RestResponse->viewData(array($setting => $found['value']));
return $this->RestResponse->viewData(array($setting['name'] => $setting['value']));
} else {
$this->set('subGroup', $subGroup);
$this->set('setting', $found);
$this->set('setting', $setting);
$this->render('ajax/server_settings_edit');
}
}
@ -1227,7 +1199,7 @@ class ServersController extends AppController
'action' => 'serverSettingsEdit',
'user_id' => $this->Auth->user('id'),
'title' => 'Server setting issue',
'change' => 'There was an issue witch changing ' . $setting . ' to ' . $this->request->data['Server']['value'] . '. The error message returned is: app/Config.config.php is not writeable to the apache user. No changes were made.',
'change' => 'There was an issue witch changing ' . $setting['name'] . ' to ' . $this->request->data['Server']['value'] . '. The error message returned is: app/Config.config.php is not writeable to the apache user. No changes were made.',
));
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, 'app/Config.config.php is not writeable to the apache user.', $this->response->type());
@ -1235,101 +1207,19 @@ class ServersController extends AppController
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'app/Config.config.php is not writeable to the apache user.')), 'status'=>200, 'type' => 'json'));
}
}
if (isset($found['beforeHook'])) {
$beforeResult = call_user_func_array(array($this->Server, $found['beforeHook']), array($setting, $this->request->data['Server']['value']));
if ($beforeResult !== true) {
$this->Log->create();
$result = $this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $this->Auth->user('email'),
'action' => 'serverSettingsEdit',
'user_id' => $this->Auth->user('id'),
'title' => 'Server setting issue',
'change' => 'There was an issue witch changing ' . $setting . ' to ' . $this->request->data['Server']['value'] . '. The error message returned is: ' . $beforeResult . 'No changes were made.',
));
if ($this->_isRest) {
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, $beforeResult, $this->response->type());
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $beforeResult)), 'status'=>200, 'type' => 'json'));
}
}
}
$this->request->data['Server']['value'] = trim($this->request->data['Server']['value']);
if ($found['type'] == 'boolean') {
$this->request->data['Server']['value'] = ($this->request->data['Server']['value'] ? true : false);
}
if ($found['type'] == 'numeric') {
$this->request->data['Server']['value'] = intval($this->request->data['Server']['value']);
}
if (!empty($leafValue['test'])) {
$testResult = $this->Server->{$found['test']}($this->request->data['Server']['value']);
} else {
$testResult = true; # No test defined for this setting: cannot fail
}
if (!$forceSave && $testResult !== true) {
if ($testResult === false) {
$errorMessage = $found['errorMessage'];
$result = $this->Server->serverSettingsEditValue($this->Auth->user(), $setting, $this->request->data['Server']['value'], $forceSave);
if ($result === true) {
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Servers', 'serverSettingsEdit', false, $this->response->type(), 'Field updated');
} else {
$errorMessage = $testResult;
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Field updated.')), 'status'=>200, 'type' => 'json'));
}
} else {
if ($this->_isRest) {
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, $errorMessage, $this->response->type());
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, $result, $this->response->type());
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $errorMessage)), 'status'=>200, 'type' => 'json'));
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $result)), 'status'=>200, 'type' => 'json'));
}
} else {
$oldValue = Configure::read($setting);
$settingSaveResult = $this->Server->serverSettingsSaveValue($setting, $this->request->data['Server']['value']);
$this->Log->create();
if ($settingSaveResult) {
$result = $this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $this->Auth->user('email'),
'action' => 'serverSettingsEdit',
'user_id' => $this->Auth->user('id'),
'title' => 'Server setting changed',
'change' => $setting . ' (' . $oldValue . ') => (' . $this->request->data['Server']['value'] . ')',
));
// execute after hook
if (isset($found['afterHook'])) {
$afterResult = call_user_func_array(array($this->Server, $found['afterHook']), array($setting, $this->request->data['Server']['value']));
if ($afterResult !== true) {
$this->Log->create();
$result = $this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $this->Auth->user('email'),
'action' => 'serverSettingsEdit',
'user_id' => $this->Auth->user('id'),
'title' => 'Server setting issue',
'change' => 'There was an issue after setting a new setting. The error message returned is: ' . $afterResult,
));
if ($this->_isRest) {
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, $afterResult, $this->response->type());
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $afterResult)), 'status'=>200, 'type' => 'json'));
}
}
}
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Servers', 'serverSettingsEdit', false, $this->response->type(), 'Field updated');
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Field updated.')), 'status'=>200, 'type' => 'json'));
}
} else {
if ($this->_isRest()) {
$message = __('Something went wrong. MISP tried to save a malformed config file. Setting change reverted.');
return $this->RestResponse->saveFailResponse('Servers', 'serverSettingsEdit', false, $message, $this->response->type());
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $message)), 'status'=>200, 'type' => 'json'));
}
}
}
}
}

View File

@ -21,7 +21,9 @@ class StixExport
{
$attributes_count = count($data['Attribute']);
foreach ($data['Object'] as $_object) {
$attributes_count += count($_object['Attribute']);
if (isset($_object['Attribute'])) {
$attributes_count += count($_object['Attribute']);
}
}
App::uses('JSONConverterTool', 'Tools');
$converter = new JSONConverterTool();

View File

@ -3158,7 +3158,7 @@ class Server extends AppModel
public function customAuthBeforeHook($setting, $value)
{
if ($value) {
if (!empty($value)) {
$this->updateDatabase('addCustomAuth');
}
$this->cleanCacheFiles();
@ -3193,6 +3193,122 @@ class Server extends AppModel
return $value;
}
public function getSettingData($setting_name)
{
// invalidate config.php from php opcode cache
if (function_exists('opcache_reset')) {
opcache_reset();
}
if (strpos($setting_name, 'Plugin.Enrichment') !== false || strpos($setting_name, 'Plugin.Import') !== false || strpos($setting_name, 'Plugin.Export') !== false || strpos($setting_name, 'Plugin.Cortex') !== false) {
$serverSettings = $this->getCurrentServerSettings();
} else {
$serverSettings = $this->serverSettings;
}
$relevantSettings = (array_intersect_key(Configure::read(), $serverSettings));
$setting = false;
foreach ($serverSettings as $k => $s) {
if (isset($s['branch'])) {
foreach ($s as $ek => $es) {
if ($ek != 'branch') {
if ($setting_name == $k . '.' . $ek) {
$setting = $es;
continue 2;
}
}
}
} else {
if ($setting_name == $k) {
$setting = $s;
continue;
}
}
}
if (!empty($setting)) {
$setting['name'] = $setting_name;
}
return $setting;
}
public function serverSettingsEditValue($user, $setting, $value, $forceSave = false)
{
if (isset($setting['beforeHook'])) {
$beforeResult = call_user_func_array(array($this, $setting['beforeHook']), array($setting['name'], $value));
if ($beforeResult !== true) {
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
$result = $this->Log->save(array(
'org' => $user['Organisation']['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $user['email'],
'action' => 'serverSettingsEdit',
'user_id' => $user['id'],
'title' => 'Server setting issue',
'change' => 'There was an issue witch changing ' . $setting['name'] . ' to ' . $value . '. The error message returned is: ' . $beforeResult . 'No changes were made.',
));
return $beforeResult;
}
}
$value = trim($value);
if ($setting['type'] == 'boolean') {
$value = ($value ? true : false);
}
if ($setting['type'] == 'numeric') {
$value = intval($value);
}
if (!empty($setting['test'])) {
$testResult = $this->{$setting['test']}($value);
} else {
$testResult = true; # No test defined for this setting: cannot fail
}
if (!$forceSave && $testResult !== true) {
if ($testResult === false) {
$errorMessage = $setting['errorMessage'];
} else {
$errorMessage = $testResult;
}
return $errorMessage;
} else {
$oldValue = Configure::read($setting['name']);
$settingSaveResult = $this->serverSettingsSaveValue($setting['name'], $value);
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
if ($settingSaveResult) {
$result = $this->Log->save(array(
'org' => $user['Organisation']['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $user['email'],
'action' => 'serverSettingsEdit',
'user_id' => $user['id'],
'title' => 'Server setting changed',
'change' => $setting['name'] . ' (' . $oldValue . ') => (' . $value . ')',
));
// execute after hook
if (isset($setting['afterHook'])) {
$afterResult = call_user_func_array(array($this, $setting['afterHook']), array($setting['name'], $value));
if ($afterResult !== true) {
$this->Log->create();
$result = $this->Log->save(array(
'org' => $user['Organisation']['name'],
'model' => 'Server',
'model_id' => 0,
'email' => $user['email'],
'action' => 'serverSettingsEdit',
'user_id' => $user['id'],
'title' => 'Server setting issue',
'change' => 'There was an issue after setting a new setting. The error message returned is: ' . $afterResult,
));
return $afterResult;
}
}
return true;
} else {
return __('Something went wrong. MISP tried to save a malformed config file. Setting change reverted.');
}
}
}
public function serverSettingsSaveValue($setting, $value)
{
// validate if current config.php is intact:

View File

@ -21,7 +21,7 @@
<?php
if ($isSiteAdmin || ($mayModify && $isAclTagger)) {
echo $this->Form->create(false, array('url' => $baseurl . '/galaxy_clusters/detach/' . ucfirst(h($target_id)) . '/' . h($target_type) . '/' . $cluster['tag_id'], 'style' => 'display: inline-block; margin: 0px;'));
echo '<it href="#" class="icon-trash useCursorPointer" title="' . __('Are you sure you want to detach %s from this event?', h($cluster['value'])) . '" onclick="popoverConfirm(this)"></it>';
echo '<it href="#" class="icon-trash useCursorPointer" role="button" tabindex="0" aria-label="' . __('detach') . '" title="' . __('Are you sure you want to detach %s from this event?', h($cluster['value'])) . '" onclick="popoverConfirm(this)"></it>';
echo $this->Form->end();
}
?>

View File

@ -91,8 +91,8 @@ function setupChosen(id, redrawChosen) {
// hack to add template into the div
var $chosenContainer = $elem.parent().find('.chosen-container');
$elem.on('chosen:showing_dropdown chosen:searchdone chosen:picked keyup change', function() {
redrawChosenWithTemplate($elem, $chosenContainer)
$elem.on('chosen:searchdone chosen:picked keyup change', function(e) {
redrawChosenWithTemplate($elem, $chosenContainer, e.type)
});
if (redrawChosen) {
@ -100,13 +100,19 @@ function setupChosen(id, redrawChosen) {
}
}
function redrawChosenWithTemplate($select, $chosenContainer) {
function redrawChosenWithTemplate($select, $chosenContainer, eventType) {
var optionLength = $select.find('option').length;
if (optionLength > 1000) {
$chosenContainer.parent().find('.generic-picker-wrapper-warning-text').show(0)
} else {
console.log(eventType);
$chosenContainer.find('.generic-picker-wrapper-warning-text').hide(0)
var $matches = $chosenContainer.find('.chosen-results .active-result, .chosen-single > span, .search-choice > span');
var $matches;
if (eventType == 'chosen:picked' || eventType == 'change') {
$matches = $chosenContainer.find('.chosen-single > span, .search-choice > span');
} else {
$matches = $chosenContainer.find('.chosen-results .active-result');
}
$matches.each(function() {
var $item = $(this);
var index = $item.data('option-array-index');
@ -115,7 +121,10 @@ function redrawChosenWithTemplate($select, $chosenContainer) {
$option = $select.find('option:eq(' + index + ')');
} else { // if it is a `chosen-single span`, don't have index
var text = $item.text();
$option = $select.find('option:contains(' + text + ')');
$option = $select.find('option').filter(function(index) {
var temp = $.trim($(this).text());
return temp === text;
});
}
var template = options_templates[$select.attr('id')][$option.val()];
var res = "";

@ -1 +1 @@
Subproject commit 898bdaf7f89fd3d3edf3e2952af8231ad1f941a0
Subproject commit b9f13179412b0a6d944ef33493f36c2a49a63706

@ -1 +1 @@
Subproject commit f5c7530e0b375cdd1b72a98f532dca731f8a0b80
Subproject commit 75ae30f44df997280255eec60b981b9f376c5ac4

@ -1 +1 @@
Subproject commit 3320d14b68f78d8ca4c40a0a8f0af114f224a742
Subproject commit 4c995a260c73373daeddd7304e248e8fea900e75