diff --git a/VERSION.json b/VERSION.json index 660524be2..59803d254 100644 --- a/VERSION.json +++ b/VERSION.json @@ -1 +1 @@ -{"major":2, "minor":3, "hotfix":125} \ No newline at end of file +{"major":2, "minor":3, "hotfix":126} \ No newline at end of file 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/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..6d27d404a 100644 --- a/app/Controller/EventBlacklistsController.php +++ b/app/Controller/EventBlacklistsController.php @@ -22,7 +22,6 @@ class EventBlacklistsController extends AppController { ); public function index() { - if ($this->response->type() === 'application/json' || $this->response->type() == 'application/xml' || $this->_isRest()) { $blackList = $this->paginate(); $eventBlacklist= array(); @@ -57,7 +56,15 @@ 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'], + 'event_info' => $data['EventBlacklist']['info'], + 'event_orgc' => $data['EventBlacklist']['orgc'], + ) + ) + ) { $successes[] = $uuid; } else { $fails[] = $uuid; @@ -69,13 +76,57 @@ class EventBlacklistsController extends AppController { $message = 'Done. Added ' . count($successes) . ' new entries to the blacklist. ' . count($fails) . ' entries could not be saved.'; if ($this->_isRest()) { $this->set('result', array('successes' => $successes, 'fails' => $fails)); - $this->set('_serialize', array('result')); + $this->set('message', $message); + $this->set('_serialize', array('message', 'result')); } else { $this->Session->setFlash(__($message)); $this->redirect(array('action' => 'index')); } } } + + public function edit($id) { + if (strlen($id) == 36) { + $eb = $this->EventBlacklist->find('first', array('conditions' => array('uuid' => $id))); + } else { + $eb = $this->EventBlacklist->find('first', array('conditions' => array('id' => $id))); + } + if (empty($eb)) throw new NotFoundException('Blacklist item not found.'); + $this->set('eb', $eb); + if ($this->request->is('post')) { + if ($this->_isRest()) { + if ($this->response->type() === 'application/json') { + $isJson = true; + $data = $this->request->input('json_decode', true); + } else { + $data = $this->request->data; + } + if (isset($data['request'])) $data = $data['request']; + } else { + $data = $this->request->data; + } + $fields = array('comment', 'event_info', 'event_orgc'); + foreach ($fields as $f) { + if (isset($data['EventBlacklist'][$f])) $eb['EventBlacklist'][$f] = $data['EventBlacklist'][$f]; + } + if ($this->EventBlacklist->save($eb)) { + if ($this->_isRest()) { + $this->set('message', array('Blacklist item added.')); + $this->set('_serialize', array('message')); + } else { + $this->Session->setFlash(__('Blacklist item added.')); + $this->redirect(array('action' => 'index')); + } + } else { + if ($this->_isRest()) { + throw new MethodNotAllowedException('Could not save the blacklist item.'); + } else { + $this->Session->setFlash('Could not save the blacklist item'); + $this->redirect(array('action' => 'index')); + } + } + } + } public function delete($id) { if (strlen($id) == 36) { diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 9761c52f5..4cdadc19a 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,15 @@ 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).'%'); + $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') { + $subcondition['AND'][] = array('Attribute.event_id !=' => substr($v, 1)); + } else { + $subcondition['AND'][] = array('Attribute.' . $parameters[$k] . ' NOT LIKE' => '%'.substr($v, 1).'%'); + } } } } else { @@ -2473,12 +2475,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 +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); - $params = array( 'conditions' => $conditions, 'fields' => array('DISTINCT(Attribute.event_id)'), @@ -3029,7 +3032,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 +3303,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 +3390,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/Controller/UsersController.php b/app/Controller/UsersController.php index 25791c0f8..e626a8894 100755 --- a/app/Controller/UsersController.php +++ b/app/Controller/UsersController.php @@ -563,14 +563,6 @@ class UsersController extends AppController { if (!$this->Auth->user('termsaccepted')) { $this->redirect(array('action' => 'terms')); } - - // News page - $newNewsdate = new DateTime("2012-03-27"); // TODO general, fixed odd date?? - $newsdate = new DateTime($this->Auth->user('newsread')); - if ($newNewsdate > $newsdate) { - $this->redirect(array('action' => 'news')); - } - // Events list $this->redirect(array('controller' => 'events', 'action' => 'index')); } @@ -737,12 +729,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 afffcc407..bc784b818 100755 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -45,4 +45,114 @@ 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, `comment` 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, + )); + } + } + + public 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(); + } + } + } + + 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 c039ea590..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 @@ -797,19 +792,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..0dc4d0190 100755 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -1329,11 +1329,12 @@ class Server extends AppModel { } public function eventBlacklistingBeforeHook($setting, $value) { - $this->__cleanCacheFiles(); + $this->cleanCacheFiles(); 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'); } @@ -1357,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); } @@ -1642,7 +1640,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 +1659,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/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 @@