From df59748719bccb6707d0ef6b53c34fd8e520f70a Mon Sep 17 00:00:00 2001 From: Iglocska Date: Tue, 15 Sep 2015 15:11:08 +0200 Subject: [PATCH 1/6] progress on several issues - switching workstations, this is all WiP --- app/Controller/AttributesController.php | 23 +++-- app/Controller/EventBlacklistsController.php | 2 +- app/Controller/EventsController.php | 53 +++++----- app/Model/AppModel.php | 102 ++++++++++++++++++ app/Model/Event.php | 20 ++-- app/Model/EventBlacklist.php | 2 + app/Model/Server.php | 103 +------------------ app/View/EventBlacklists/add.ctp | 5 + app/View/EventBlacklists/index.ctp | 6 ++ app/View/Pages/administration.ctp | 1 + 10 files changed, 178 insertions(+), 139 deletions(-) diff --git a/app/Controller/AttributesController.php b/app/Controller/AttributesController.php index 0ca614c85..6f4308347 100755 --- a/app/Controller/AttributesController.php +++ b/app/Controller/AttributesController.php @@ -236,7 +236,11 @@ class AttributesController extends AppController { } else { if ($this->_isRest()) { // TODO return error if REST // REST users want to see the failed attribute - throw new NotFoundException('Could not save the attribute. ' . $this->Attribute->validationErrors); + $message = ''; + foreach ($this->Attribute->validationErrors as $k => $v) { + $message .= '[' . $k . ']: ' . $v[0] . PHP_EOL; + } + throw new NotFoundException('Could not save the attribute. ' . $message); } elseif ($this->request->is('ajax')) { $this->autoRender = false; return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $this->Attribute->validationErrors)),'status'=>200)); @@ -1492,7 +1496,7 @@ class AttributesController extends AppController { } $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid'); foreach ($simpleFalse as $sF) { - if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF})) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Attribute->Event->dateFieldCheck($from); @@ -1738,7 +1742,7 @@ class AttributesController extends AppController { public function text($key='download', $type='all', $tags=false, $eventId=false, $allowNonIDS=false, $from=false, $to=false, $last=false) { $simpleFalse = array('eventId', 'allowNonIDS', 'tags', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($type === 'null' || $type === '0' || $type === 'false') $type = 'all'; if ($from) $from = $this->Attribute->Event->dateFieldCheck($from); @@ -1788,7 +1792,7 @@ class AttributesController extends AppController { $simpleFalse = array('eventId', 'tags', 'from', 'to', 'policy', 'walled_garden', 'ns', 'email', 'serial', 'refresh', 'retry', 'expiry', 'minimum_ttl', 'ttl'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || ${$sF} === null || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if (!in_array($policy, array('NXDOMAIN', 'NODATA', 'DROP', 'walled-garden'))) $policy = false; App::uses('RPZExport', 'Export'); @@ -2109,7 +2113,7 @@ class AttributesController extends AppController { $simpleFalse = array('hash', 'allSamples', 'eventID'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } // valid combinations of settings are: @@ -2217,7 +2221,14 @@ class AttributesController extends AppController { $this->set('message', $error); $this->set('_serialize', array('message')); } - } + public function pruneOrphanedAttributes() { + if (!$this->_isSiteAdmin()) throw new MethodNotAllowedException('You are not authorised to do that.'); + $events = array_keys($this->Attribute->Event->find('list')); + $orphans = $this->Attribute->find('list', array('conditions' => array('Attribute.event_id !=' => $events))); + if (count($orphans) > 0) $this->Attribute->deleteAll(array('Attribute.event_id !=' => $events), false, true); + $this->Session->setFlash('Removed ' . count($orphans) . ' attribute(s).'); + $this->redirect('/pages/display/administration'); + } } diff --git a/app/Controller/EventBlacklistsController.php b/app/Controller/EventBlacklistsController.php index a0c63828f..654f181e2 100644 --- a/app/Controller/EventBlacklistsController.php +++ b/app/Controller/EventBlacklistsController.php @@ -57,7 +57,7 @@ class EventBlacklistsController extends AppController { $uuid = trim($uuid); if (strlen($uuid) == 36) { $this->EventBlacklist->create(); - if ($this->EventBlacklist->save(array('event_uuid' => $uuid))) { + if ($this->EventBlacklist->save(array('event_uuid' => $uuid, 'comment' => $data['EventBlacklist']['comment']))) { $successes[] = $uuid; } else { $fails[] = $uuid; diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 9761c52f5..e83389a8a 100755 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -1739,7 +1739,7 @@ class EventsController extends AppController { $simpleFalse = array('tags', 'eventid', 'withAttachment', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); if ($to) $to = $this->Event->dateFieldCheck($to); @@ -1819,7 +1819,7 @@ class EventsController extends AppController { public function nids($format = 'suricata', $key = 'download', $id = false, $continue = false, $tags = false, $from = false, $to = false, $last = false) { $simpleFalse = array('id', 'continue', 'tags', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); @@ -1860,7 +1860,7 @@ class EventsController extends AppController { public function hids($type, $key='download', $tags = false, $from = false, $to = false, $last = false) { $simpleFalse = array('tags', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); if ($to) $to = $this->Event->dateFieldCheck($to); @@ -1895,7 +1895,7 @@ class EventsController extends AppController { public function csv($key, $eventid=false, $ignore=false, $tags = false, $category=false, $type=false, $includeContext=false, $from=false, $to=false, $last = false) { $simpleFalse = array('eventid', 'ignore', 'tags', 'category', 'type', 'includeContext', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); @@ -2428,7 +2428,7 @@ class EventsController extends AppController { $simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'searchall', 'from', 'to', 'last', 'eventid'); foreach ($simpleFalse as $sF) { - if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF})) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); @@ -2436,7 +2436,6 @@ class EventsController extends AppController { if ($tags) $tags = str_replace(';', ':', $tags); if ($last) $last = $this->Event->resolveTimeDelta($last); if ($searchall === 'true') $searchall = "1"; - $conditions['AND'] = array(); $subcondition = array(); $this->loadModel('Attribute'); @@ -2458,12 +2457,14 @@ class EventsController extends AppController { $subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result); } } else { - if ($parameters[$k] === 'org') { - $subcondition['AND'][] = array('Event.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); - } elseif ($parameters[$k] === 'eventid') { - $subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1)); - } else { - $subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + if (!empty(substr($v, 1))) { + if ($parameters[$k] === 'org') { + $subcondition['AND'][] = array('Event.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1)); + } else { + $subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + } } } } else { @@ -2473,12 +2474,14 @@ class EventsController extends AppController { $subcondition['OR'][] = array('Attribute.value LIKE' => $result); } } else { - if ($parameters[$k] === 'org') { - $subcondition['OR'][] = array('Event.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); - } elseif ($parameters[$k] === 'eventid') { - $subcondition['OR'][] = array('Attribute.event_id' => $v); - } else { - $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); + if (!empty($v)) { + if ($parameters[$k] === 'org') { + $subcondition['OR'][] = array('Event.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); + } elseif ($parameters[$k] === 'eventid') { + $subcondition['OR'][] = array('Attribute.event_id' => $v); + } else { + $subcondition['OR'][] = array('Attribute.' . $parameters[$k] . ' LIKE' => '%'.$v.'%'); + } } } } @@ -2522,7 +2525,8 @@ class EventsController extends AppController { if ($from) $conditions['AND'][] = array('Event.date >=' => $from); if ($to) $conditions['AND'][] = array('Event.date <=' => $to); if ($last) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last); - + debug($conditions); + throw new Exception(); $params = array( 'conditions' => $conditions, 'fields' => array('DISTINCT(Attribute.event_id)'), @@ -3029,7 +3033,7 @@ class EventsController extends AppController { $simpleFalse = array('id', 'withAttachments', 'tags', 'from', 'to', 'last'); foreach ($simpleFalse as $sF) { - if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false; + if (!is_array(${$sF}) && (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false')) ${$sF} = false; } if ($from) $from = $this->Event->dateFieldCheck($from); if ($to) $to = $this->Event->dateFieldCheck($to); @@ -3300,7 +3304,7 @@ class EventsController extends AppController { // check if the user has permission to create attributes for an event, if the event ID has been passed // If not, create an event if (isset($data['event_id']) && !empty($data['event_id']) && is_numeric($data['event_id'])) { - $conditons = array(); + $conditions = array(); if (!$this->_isSiteAdmin()) { $conditions = array('Event.orgc' => $this->Auth->user('org')); if (!$this->userRole['perm_modify_org']) $conditions[] = array('Event.user_id' => $this->Auth->user('id')); @@ -3387,15 +3391,18 @@ class EventsController extends AppController { if ($successCount > 0) { $this->set('name', 'Partial success'); $this->set('message', 'Successfuly saved ' . $successCount . ' sample(s), but some samples could not be saved.'); + $this->set('url', '/events/view/' . $data['event_id']); + $this->set('_serialize', array('name', 'message', 'url', 'errors')); } else { $this->set('name', 'Failed'); $this->set('message', 'Failed to save any of the supplied samples.'); + $this->set('_serialize', array('name', 'message', 'errors')); } - $this->set('_serialize', array('name', 'message', 'errors')); } else { $this->set('name', 'Success'); $this->set('message', 'Success, saved all attributes.'); - $this->set('_serialize', array('name', 'message')); + $this->set('url', '/events/view/' . $data['event_id']); + $this->set('_serialize', array('name', 'message', 'url')); } $this->view($data['event_id']); $this->render('view'); diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index afffcc407..4d05bad8f 100755 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -45,4 +45,106 @@ class AppModel extends Model { $this->name = get_class($this); } + + + public function updateDatabase($command) { + $sql = ''; + $model = 'Event'; + $this->Log = ClassRegistry::init('Log'); + switch ($command) { + case 'extendServerOrganizationLength': + $sql = 'ALTER TABLE `servers` MODIFY COLUMN `organization` varchar(255) NOT NULL;'; + $model = 'Server'; + break; + case 'convertLogFieldsToText': + $sql = 'ALTER TABLE `logs` MODIFY COLUMN `title` text, MODIFY COLUMN `change` text;'; + $model= 'Log'; + break; + case 'addEventBlacklists': + $sql = 'CREATE TABLE IF NOT EXISTS `event_blacklists` ( `id` int(11) NOT NULL AUTO_INCREMENT, `event_uuid` varchar(40) COLLATE utf8_bin NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`), `event_info` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `event_orgc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;'; + break; + case 'addEventBlacklistsContext': + $sql = 'ALTER TABLE `event_blacklists` ADD `event_orgc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , ADD `event_info` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, ADD `comment` TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ;'; + break; + case 'makeAttributeUUIDsUnique': + $this->__dropIndex('attributes', 'uuid'); + $sql = 'ALTER TABLE `attributes` ADD UNIQUE (uuid);'; + break; + case 'makeEventUUIDsUnique': + $this->__dropIndex('events', 'uuid'); + $sql = 'ALTER TABLE `events` ADD UNIQUE (uuid);'; + break; + default: + return false; + break; + } + $m = ClassRegistry::init($model); + try { + $m->query($sql); + $this->Log->create(); + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'Server', + 'model_id' => 0, + 'email' => 'SYSTEM', + 'action' => 'update_database', + 'user_id' => 0, + 'title' => 'Successfuly executed the SQL query for ' . $command, + 'change' => 'The executed SQL query was: ' . $sql + )); + } catch (Exception $e) { + $this->Log->create(); + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'Server', + 'model_id' => 0, + 'email' => 'SYSTEM', + 'action' => 'update_database', + 'user_id' => 0, + 'title' => 'Issues executing the SQL query for ' . $command, + 'change' => 'The executed SQL query was: ' . $sql . PHP_EOL . ' The returned error is: ' . $e->getMessage() + )); + } + $this->__cleanCacheFiles(); + return true; + } + + private function __dropIndex($table, $field) { + $this->Log = ClassRegistry::init('Log'); + $indexCheck = "SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name='" . $table . "' AND index_name LIKE '" . $field . "%'"; + $indexCheckResult = $this->query($indexCheck); + foreach ($indexCheckResult as $icr) { + $dropIndex = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $icr['STATISTICS']['INDEX_NAME']; + $result = true; + try { + $this->query($dropIndex); + } catch (Exception $e) { + $result = false; + } + $this->Log->create(); + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'Server', + 'model_id' => 0, + 'email' => 'SYSTEM', + 'action' => 'update_database', + 'user_id' => 0, + 'title' => ($result ? 'Removed index ' : 'Failed to remove index ') . $icr['STATISTICS']['INDEX_NAME'] . ' from ' . $table, + 'change' => ($result ? 'Removed index ' : 'Failed to remove index ') . $icr['STATISTICS']['INDEX_NAME'] . ' from ' . $table, + )); + } + } + + private function __cleanCacheFiles() { + $directories = array(APP . '/tmp/cache/models', APP . '/tmp/cache/persistent'); + foreach ($directories as $directory) { + $dir = new Folder($directory); + $files = $dir->find('myapp.*'); + foreach ($files as $file) { + $file = new File($dir->path . DS . $file); + $file->delete(); + $file->close(); + } + } + } } diff --git a/app/Model/Event.php b/app/Model/Event.php index c039ea590..9556ad799 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -797,19 +797,21 @@ class Event extends AppModel { } $eventIds = array(); if ($all) { - foreach ($eventArray['response']['Event'] as $event) { + if (isset($eventArray['response']['Event']) && !empty($eventArray['response']['Event'])) foreach ($eventArray['response']['Event'] as $event) { $eventIds[] = $event['uuid']; } } else { // multiple events, iterate over the array - foreach ($eventArray['response']['Event'] as &$event) { - if (1 != $event['published']) { - continue; // do not keep non-published events - } - // get rid of events that are the same timestamp as ours or older, we don't want to transfer the attributes for those - // The event's timestamp also matches the newest attribute timestamp by default - if ($this->checkIfNewer($event)) { - $eventIds[] = $event['id']; + if (isset($eventArray['response']['Event']) && !empty($eventArray['response']['Event'])) { + foreach ($eventArray['response']['Event'] as &$event) { + if (1 != $event['published']) { + continue; // do not keep non-published events + } + // get rid of events that are the same timestamp as ours or older, we don't want to transfer the attributes for those + // The event's timestamp also matches the newest attribute timestamp by default + if ($this->checkIfNewer($event)) { + $eventIds[] = $event['id']; + } } } } diff --git a/app/Model/EventBlacklist.php b/app/Model/EventBlacklist.php index e800337c9..a1061e785 100644 --- a/app/Model/EventBlacklist.php +++ b/app/Model/EventBlacklist.php @@ -22,6 +22,8 @@ class EventBlacklist extends AppModel{ public function beforeValidate($options = array()) { parent::beforeValidate(); + $schema = $this->schema(); + if (!isset($schema['event_info'])) $this->updateDatabase('addEventBlacklistsContext'); $date = date('Y-m-d H:i:s'); if (empty($this->data['EventBlacklist']['id'])) { $this->data['EventBlacklist']['date_created'] = $date; diff --git a/app/Model/Server.php b/app/Model/Server.php index 57a5721a6..ba74a951c 100755 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -1333,7 +1333,8 @@ class Server extends AppModel { if ($value) { try { $this->EventBlacklist = ClassRegistry::init('EventBlacklist'); - $this->EventBlacklist->schema(); + $schema = $this->EventBlacklist->schema(); + if (!isset($schema['event_info'])) $this->updateDatabase('addEventBlacklistsContext'); } catch (Exception $e) { $this->updateDatabase('addEventBlacklists'); } @@ -1642,7 +1643,7 @@ class Server extends AppModel { $workers = $this->ResqueStatus->getWorkers(); $this->Log = ClassRegistry::init('Log'); $currentUser = get_current_user(); - foreach ($workers as $pid => $worker) { + foreach ($workers as $pid => $worker) { if (!is_numeric($pid)) throw new MethodNotAllowedException('Non numeric PID found!'); $pidTest = substr_count(trim(shell_exec('ps -p ' . $pid)), PHP_EOL) > 0 ? true : false; if ($worker['user'] == $currentUser && !$pidTest) { @@ -1661,102 +1662,4 @@ class Server extends AppModel { } } } - - private function __dropIndex($table, $field) { - $this->Log = ClassRegistry::init('Log'); - $indexCheck = "SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name='" . $table . "' AND index_name LIKE '" . $field . "%'"; - $indexCheckResult = $this->query($indexCheck); - foreach ($indexCheckResult as $icr) { - $dropIndex = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $icr['STATISTICS']['INDEX_NAME']; - $result = true; - try { - $this->query($dropIndex); - } catch (Exception $e) { - $result = false; - } - $this->Log->create(); - $this->Log->save(array( - 'org' => 'SYSTEM', - 'model' => 'Server', - 'model_id' => 0, - 'email' => 'SYSTEM', - 'action' => 'update_database', - 'user_id' => 0, - 'title' => ($result ? 'Removed index ' : 'Failed to remove index ') . $icr['STATISTICS']['INDEX_NAME'] . ' from ' . $table, - 'change' => ($result ? 'Removed index ' : 'Failed to remove index ') . $icr['STATISTICS']['INDEX_NAME'] . ' from ' . $table, - )); - } - } - - public function updateDatabase($command) { - $sql = ''; - $model = 'Event'; - $this->Log = ClassRegistry::init('Log'); - switch ($command) { - case 'extendServerOrganizationLength': - $sql = 'ALTER TABLE `servers` MODIFY COLUMN `organization` varchar(255) NOT NULL;'; - $model = 'Server'; - break; - case 'convertLogFieldsToText': - $sql = 'ALTER TABLE `logs` MODIFY COLUMN `title` text, MODIFY COLUMN `change` text;'; - $model= 'Log'; - break; - case 'addEventBlacklists': - $sql = 'CREATE TABLE IF NOT EXISTS `event_blacklists` ( `id` int(11) NOT NULL AUTO_INCREMENT, `event_uuid` varchar(40) COLLATE utf8_bin NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ;'; - break; - case 'makeAttributeUUIDsUnique': - $this->__dropIndex('attributes', 'uuid'); - $sql = 'ALTER TABLE `attributes` ADD UNIQUE (uuid);'; - break; - case 'makeEventUUIDsUnique': - $this->__dropIndex('events', 'uuid'); - $sql = 'ALTER TABLE `events` ADD UNIQUE (uuid);'; - break; - default: - $this->Session->setFlash('Invalid command.'); - $this->redirect(array('controller' => 'pages', 'action' => 'display', 'administration')); - break; - } - $m = ClassRegistry::init($model); - try { - $m->query($sql); - $this->Log->create(); - $this->Log->save(array( - 'org' => 'SYSTEM', - 'model' => 'Server', - 'model_id' => 0, - 'email' => 'SYSTEM', - 'action' => 'update_database', - 'user_id' => 0, - 'title' => 'Successfuly executed the SQL query for ' . $command, - 'change' => 'The executed SQL query was: ' . $sql - )); - } catch (Exception $e) { - $this->Log->create(); - $this->Log->save(array( - 'org' => 'SYSTEM', - 'model' => 'Server', - 'model_id' => 0, - 'email' => 'SYSTEM', - 'action' => 'update_database', - 'user_id' => 0, - 'title' => 'Issues executing the SQL query for ' . $command, - 'change' => 'The executed SQL query was: ' . $sql . PHP_EOL . ' The returned error is: ' . $e->getMessage() - )); - } - $this->__cleanCacheFiles(); - } - - private function __cleanCacheFiles() { - $directories = array(APP . '/tmp/cache/models', APP . '/tmp/cache/persistent'); - foreach ($directories as $directory) { - $dir = new Folder($directory); - $files = $dir->find('myapp.*'); - foreach ($files as $file) { - $file = new File($dir->path . DS . $file); - $file->delete(); - $file->close(); - } - } - } } diff --git a/app/View/EventBlacklists/add.ctp b/app/View/EventBlacklists/add.ctp index e8fa5967d..6960d5a6e 100644 --- a/app/View/EventBlacklists/add.ctp +++ b/app/View/EventBlacklists/add.ctp @@ -9,6 +9,11 @@ 'div' => 'input clear', 'class' => 'input-xxlarge' )); + echo $this->Form->input('comment', array( + 'type' => 'textarea', + 'div' => 'input clear', + 'class' => 'input-xxlarge' + )); ?> Paginator->sort('id');?> + Paginator->sort('org');?> Paginator->sort('event_uuid');?> Paginator->sort('created');?> + Paginator->sort('event_info');?> + Paginator->sort('comment');?>   +     + + Form->postLink('', array('action' => 'delete', $item['EventBlacklist']['id']), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete the blacklist entry for the event UUID %s?', $item['EventBlacklist']['event_uuid'])); ?> diff --git a/app/View/Pages/administration.ctp b/app/View/Pages/administration.ctp index d8bcdb6f8..3e23c0773 100644 --- a/app/View/Pages/administration.ctp +++ b/app/View/Pages/administration.ctp @@ -20,6 +20,7 @@ if (!$isSiteAdmin) exit();
  • Convert log fields to text (Hotfix 2.3.78: Some of the log fields that were varchar(255) ended up truncating the data. This function will change them to "text")
  • Fix duplicate UUIDs (Hotfix 2.3.107: it was previously possible to get duplicate attribute UUIDs in the database, this script will remove all duplicates and ensure that duplicates will not be entered into the database in the future.)
  • Remove dupicate events (with the same UUID) (Hotfix 2.3.115: In some rare situations it could occur that a duplicate of an event was created on an instance, with the exact same uuid. This action will remove any such duplicates and make sure that this cannot happen again.)
  • +
  • Prune orphaned attributes (In some rare occasions it can happen that you end up with some attributes in your database that do not belong to an event - for example during a race condition between an event insert and a delete. This tool will collect and delete any such orphaned attributes. If you ever run into an issue where you cannot add an attribute with a specific valid value, this is probably the reason.)
  • Date: Wed, 16 Sep 2015 12:15:43 +0200 Subject: [PATCH 2/6] Further progress on several issues --- app/Controller/AppController.php | 2 + app/Controller/EventsController.php | 5 +- app/Controller/UsersController.php | 6 --- app/Model/AppModel.php | 12 ++++- app/Model/Attribute.php | 21 +++++--- app/Model/Event.php | 7 +-- app/Model/Server.php | 11 ++-- app/View/Elements/global_menu.ctp | 1 - app/View/Elements/side_menu.ctp | 1 - app/View/EventBlacklists/index.ctp | 2 +- app/View/Pages/Errors/csrf.ctp | 5 ++ app/View/Users/news.ctp | 79 ----------------------------- 12 files changed, 40 insertions(+), 112 deletions(-) create mode 100644 app/View/Pages/Errors/csrf.ctp delete mode 100755 app/View/Users/news.ctp diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index 56ece5646..e752617cd 100755 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -79,6 +79,8 @@ class AppController extends Controller { public $mispVersion = '2.3.0'; public function beforeFilter() { + $versionArray = $this->{$this->modelClass}->checkMISPVersion(); + $this->mispVersion = implode('.', array_values($versionArray)); $this->Security->blackHoleCallback = 'blackHole'; // send users away that are using ancient versions of IE // Make sure to update this if IE 20 comes out :) diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index e83389a8a..4cdadc19a 100755 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -2457,7 +2457,8 @@ class EventsController extends AppController { $subcondition['AND'][] = array('Attribute.value NOT LIKE' => $result); } } else { - if (!empty(substr($v, 1))) { + $temp = substr($v, 1); + if (!empty($temp)) { if ($parameters[$k] === 'org') { $subcondition['AND'][] = array('Event.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); } elseif ($parameters[$k] === 'eventid') { @@ -2525,8 +2526,6 @@ class EventsController extends AppController { if ($from) $conditions['AND'][] = array('Event.date >=' => $from); if ($to) $conditions['AND'][] = array('Event.date <=' => $to); if ($last) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last); - debug($conditions); - throw new Exception(); $params = array( 'conditions' => $conditions, 'fields' => array('DISTINCT(Attribute.event_id)'), diff --git a/app/Controller/UsersController.php b/app/Controller/UsersController.php index 25791c0f8..4bc6a3a29 100755 --- a/app/Controller/UsersController.php +++ b/app/Controller/UsersController.php @@ -737,12 +737,6 @@ class UsersController extends AppController { return $this->response; } - public function news() { - $this->User->id = $this->Auth->user('id'); - $this->User->saveField('newsread', date("Y-m-d")); - $this->_refreshAuth(); // refresh auth info - } - public function extraLog($action = null, $description = null, $fieldsResult = null) { // TODO move audit to AuditsController? // new data $userId = $this->Auth->user('id'); diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index 4d05bad8f..420fbdd6c 100755 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -105,7 +105,7 @@ class AppModel extends Model { 'change' => 'The executed SQL query was: ' . $sql . PHP_EOL . ' The returned error is: ' . $e->getMessage() )); } - $this->__cleanCacheFiles(); + $this->cleanCacheFiles(); return true; } @@ -135,7 +135,7 @@ class AppModel extends Model { } } - private function __cleanCacheFiles() { + public function cleanCacheFiles() { $directories = array(APP . '/tmp/cache/models', APP . '/tmp/cache/persistent'); foreach ($directories as $directory) { $dir = new Folder($directory); @@ -147,4 +147,12 @@ class AppModel extends Model { } } } + + public function checkMISPVersion() { + App::uses('Folder', 'Utility'); + $file = new File (ROOT . DS . 'VERSION.json', true); + $version_array = json_decode($file->read(), true); + $file->close(); + return $version_array; + } } diff --git a/app/Model/Attribute.php b/app/Model/Attribute.php index 0f816efe5..e0f8382a2 100755 --- a/app/Model/Attribute.php +++ b/app/Model/Attribute.php @@ -553,21 +553,24 @@ class Attribute extends AppModel { switch($type) { case 'md5': if (preg_match("#^[0-9a-f]{32}$#", $value)) { - $returnValue = true; + if ($value === 'd41d8cd98f00b204e9800998ecf8427e') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } break; case 'sha1': if (preg_match("#^[0-9a-f]{40}$#", $value)) { - $returnValue = true; + if ($value === 'da39a3ee5e6b4b0d3255bfef95601890afd80709') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } break; case 'sha256': if (preg_match("#^[0-9a-f]{64}$#", $value)) { - $returnValue = true; + if ($value === 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } @@ -588,7 +591,9 @@ class Attribute extends AppModel { case 'filename|md5': // no newline if (preg_match("#^.+\|[0-9a-f]{32}$#", $value)) { - $returnValue = true; + $parts = explode('|', $value); + if ($parts[1] === 'd41d8cd98f00b204e9800998ecf8427e') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } @@ -596,7 +601,9 @@ class Attribute extends AppModel { case 'filename|sha1': // no newline if (preg_match("#^.+\|[0-9a-f]{40}$#", $value)) { - $returnValue = true; + $parts = explode('|', $value); + if ($parts[1] === 'da39a3ee5e6b4b0d3255bfef95601890afd80709') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } @@ -604,7 +611,9 @@ class Attribute extends AppModel { case 'filename|sha256': // no newline if (preg_match("#^.+\|[0-9a-f]{64}$#", $value)) { - $returnValue = true; + $parts = explode('|', $value); + if ($parts[1] === 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855') $returnValue = 'The supplied hash indicates an empty file.'; + else $returnValue = true; } else { $returnValue = 'Checksum has invalid length or format. Please double check the value or select "other" for a type.'; } diff --git a/app/Model/Event.php b/app/Model/Event.php index 9556ad799..5e7dfac36 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -330,14 +330,9 @@ class Event extends AppModel { public function beforeDelete($cascade = true) { // blacklist the event UUID if the feature is enabled if (Configure::read('MISP.enableEventBlacklisting')) { - $event = $this->find('first', array( - 'recursive' => -1, - 'fields' => array('uuid'), - 'conditions' => array('id' => $this->id), - )); $this->EventBlacklist = ClassRegistry::init('EventBlacklist'); $this->EventBlacklist->create(); - $this->EventBlacklist->save(array('event_uuid' => $this->data['Event']['uuid'])); + $this->EventBlacklist->save(array('event_uuid' => $this->data['Event']['uuid'], 'event_info' => $this->data['Event']['info'], 'event_orgc' => $this->data['Event']['orgc'])); } // delete all of the event->tag combinations that involve the deleted event diff --git a/app/Model/Server.php b/app/Model/Server.php index ba74a951c..0dc4d0190 100755 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -1329,7 +1329,7 @@ class Server extends AppModel { } public function eventBlacklistingBeforeHook($setting, $value) { - $this->__cleanCacheFiles(); + $this->cleanCacheFiles(); if ($value) { try { $this->EventBlacklist = ClassRegistry::init('EventBlacklist'); @@ -1358,13 +1358,10 @@ class Server extends AppModel { } public function checkVersion($newest) { - App::uses('Folder', 'Utility'); - $file = new File (ROOT . DS . 'VERSION.json', true); - $version_array = json_decode($file->read()); - $file->close(); - $current = 'v' . $version_array->major . '.' . $version_array->minor . '.' . $version_array->hotfix; + $version_array = $this->checkMISPVersion(); + $current = 'v' . $version_array['major'] . '.' . $version_array['minor'] . '.' . $version_array['hotfix']; $newest_array = $this->__dissectVersion($newest); - $upToDate = $this->__compareVersions(array($version_array->major, $version_array->minor, $version_array->hotfix), $newest_array, 0); + $upToDate = $this->__compareVersions(array($version_array['major'], $version_array['minor'], $version_array['hotfix']), $newest_array, 0); return array ('current' => $current, 'newest' => $newest, 'upToDate' => $upToDate); } diff --git a/app/View/Elements/global_menu.ctp b/app/View/Elements/global_menu.ctp index 240de6635..3af038f06 100755 --- a/app/View/Elements/global_menu.ctp +++ b/app/View/Elements/global_menu.ctp @@ -70,7 +70,6 @@