mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into fix-update-tags-on-attribute-edit
commit
e41ffb5c9e
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit f176fb0884770ff303de2c4db6606fbe4fcc4199
|
||||
Subproject commit 2fb61d4b32db8ac42c85cc3881f4441c2a7511e6
|
|
@ -1219,20 +1219,6 @@ class EventsController extends AppController
|
|||
$event = $this->Sightingdb->attachToEvent($event, $this->Auth->user());
|
||||
}
|
||||
$this->params->params['paging'] = array($this->modelClass => $params);
|
||||
// workaround to get the event dates in to the attribute relations
|
||||
$relatedDates = array();
|
||||
if (isset($event['RelatedEvent'])) {
|
||||
foreach ($event['RelatedEvent'] as $relation) {
|
||||
$relatedDates[$relation['Event']['id']] = $relation['Event']['date'];
|
||||
}
|
||||
if (isset($event['RelatedAttribute'])) {
|
||||
foreach ($event['RelatedAttribute'] as $key => $relatedAttribute) {
|
||||
foreach ($relatedAttribute as $key2 => $relation) {
|
||||
$event['RelatedAttribute'][$key][$key2]['date'] = $relatedDates[$relation['id']];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->set('event', $event);
|
||||
$dataForView = array(
|
||||
'Attribute' => array('attrDescriptions' => 'fieldDescriptions', 'distributionDescriptions' => 'distributionDescriptions', 'distributionLevels' => 'distributionLevels', 'shortDist' => 'shortDist'),
|
||||
|
@ -1374,21 +1360,12 @@ class EventsController extends AppController
|
|||
'Event' => array('eventDescriptions' => 'fieldDescriptions', 'analysisDescriptions' => 'analysisDescriptions', 'analysisLevels' => 'analysisLevels')
|
||||
);
|
||||
|
||||
// workaround to get the event dates in to the attribute relations and number of correlation per related event
|
||||
$relatedDates = array();
|
||||
// workaround to get number of correlation per related event
|
||||
$relatedEventCorrelationCount = array();
|
||||
if (!empty($event['RelatedEvent'])) {
|
||||
foreach ($event['RelatedEvent'] as $relation) {
|
||||
$relatedDates[$relation['Event']['id']] = $relation['Event']['date'];
|
||||
}
|
||||
if (!empty($event['RelatedAttribute'])) {
|
||||
foreach ($event['RelatedAttribute'] as $key => $relatedAttribute) {
|
||||
foreach ($relatedAttribute as $key2 => $relation) {
|
||||
if (!empty($relatedDates[$relation['id']])) {
|
||||
$event['RelatedAttribute'][$key][$key2]['date'] = $relatedDates[$relation['id']];
|
||||
}
|
||||
$relatedEventCorrelationCount[$relation['id']][$relation['value']] = 1;
|
||||
}
|
||||
if (!empty($event['RelatedAttribute'])) {
|
||||
foreach ($event['RelatedAttribute'] as $relatedAttribute) {
|
||||
foreach ($relatedAttribute as $relation) {
|
||||
$relatedEventCorrelationCount[$relation['id']][$relation['value']] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,11 +290,6 @@ class ShadowAttributesController extends AppController
|
|||
} else {
|
||||
$this->set('ajax', false);
|
||||
}
|
||||
if (empty($eventId)) {
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Invalid Event'));
|
||||
}
|
||||
}
|
||||
$event = $this->ShadowAttribute->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId));
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Invalid Event'));
|
||||
|
@ -457,14 +452,15 @@ class ShadowAttributesController extends AppController
|
|||
$categories = array_keys($this->ShadowAttribute->Event->Attribute->categoryDefinitions);
|
||||
$categories = $this->_arrayToValuesIndexArray($categories);
|
||||
$this->set('categories', $categories);
|
||||
foreach ($this->ShadowAttribute->Event->Attribute->categoryDefinitions as $key => $value) {
|
||||
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
|
||||
$fieldDesc = ['category' => [], 'type' => []];
|
||||
foreach ($this->ShadowAttribute->categoryDefinitions as $key => $value) {
|
||||
$fieldDesc['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
foreach ($this->ShadowAttribute->Event->Attribute->typeDefinitions as $key => $value) {
|
||||
$info['type'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
foreach ($this->ShadowAttribute->typeDefinitions as $key => $value) {
|
||||
$fieldDesc['type'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
$this->set('info', $info);
|
||||
$this->set('typeDefinitions', $this->ShadowAttribute->typeDefinitions);
|
||||
$this->set('fieldDesc', $fieldDesc);
|
||||
$this->set('categoryDefinitions', $this->ShadowAttribute->categoryDefinitions);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
require_once 'OrgsContributorsGeneric.php';
|
||||
|
||||
class OrgsContributorLastMonthWidget extends OrgsContributorsGeneric
|
||||
{
|
||||
public $title = 'Active Contributors in the last 30 days';
|
||||
public $description = 'Display the logos of all organisations having shared at least one event in the past month.';
|
||||
|
||||
protected function filter($user, $org, $start_timestamp) {
|
||||
$conditions = $this->Event->createEventConditions($user);
|
||||
$conditions['AND'][] = array('OR' => array('Event.orgc_id' => $org['Organisation']['id'], 'Event.org_id' => $org['Organisation']['id']));
|
||||
$conditions['AND'][] = array('Event.timestamp >=' => $start_timestamp);
|
||||
$results = array_values($this->Event->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'limit' => 1,
|
||||
'fields' => array('Event.id')
|
||||
)));
|
||||
return count($results) > 0;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
class OrgsContributorsGeneric
|
||||
{
|
||||
public $render = 'OrgsPictures';
|
||||
public $width = 4;
|
||||
public $height = 4;
|
||||
public $cacheLifetime = 3600;
|
||||
public $autoRefreshDelay = false;
|
||||
public $params = array (
|
||||
'blacklist_orgs' => 'A list of organisation names to filter out',
|
||||
'timeframe' => 'Number of days considered for the query (30 by default)'
|
||||
);
|
||||
public $placeholder =
|
||||
'{
|
||||
"blacklist_orgs": ["Orgs to filter"],
|
||||
"timeframe": "30"
|
||||
}';
|
||||
|
||||
//This is the default filter - to be overriden in children classes
|
||||
protected function filter($user, $org, $options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$this->Org = ClassRegistry::init('Organisation');
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
if (!empty($options['timeframe'])) {
|
||||
$days = (int) $options['timeframe'];
|
||||
} else {
|
||||
$days = 30;
|
||||
}
|
||||
$start_timestamp = $this->Event->resolveTimeDelta($days.'d');
|
||||
|
||||
$orgs = $this->Org->find('all', array( 'conditions' => array('Organisation.local' => 1)));
|
||||
$result = array();
|
||||
foreach($orgs as $org) {
|
||||
if(!empty($options['blacklist_orgs']) && in_array($org['Organisation']['name'], $options['blacklist_orgs'])) {
|
||||
continue;
|
||||
}
|
||||
if ($this->filter($user, $org, $start_timestamp)) {
|
||||
$result[] = $org;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
require_once 'OrgsContributorsGeneric.php';
|
||||
|
||||
class OrgsUsingMitreWidget extends OrgsContributorsGeneric
|
||||
{
|
||||
public $title = 'Orgs using MITRE ATT&CK';
|
||||
public $description = 'Display the logos of all organisations having shared at least one event using the MITRE ATT&CK tags in the last 100 days';
|
||||
|
||||
protected function filter($user, $org, $start_timestamp) {
|
||||
$options['joins'] = array(
|
||||
array('table' => 'event_tags',
|
||||
'alias' => 'EventTag',
|
||||
'type' => 'INNER',
|
||||
'conditions' => array(
|
||||
'EventTag.event_id = Event.id',
|
||||
)
|
||||
),
|
||||
array('table' => 'tags',
|
||||
'alias' => 'Tag',
|
||||
'type' => 'INNER',
|
||||
'conditions' => array(
|
||||
'Tag.id = EventTag.tag_id'
|
||||
)
|
||||
)
|
||||
);
|
||||
$options['fields'] = 'Event.id';
|
||||
$options['limit'] = 1;
|
||||
$conditions = $this->Event->createEventConditions($user);
|
||||
$conditions['AND'][] = array('Event.orgc_id' => $org['Organisation']['id'], 'Event.published' => 1, 'Event.timestamp >=' => $start_timestamp, 'Tag.name LIKE' => 'misp-galaxy:mitre%');
|
||||
$options['conditions'] = array('AND' => $conditions);
|
||||
$events = $this->Event->find('all', $options);
|
||||
return count($events) > 0;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
require_once 'OrgsContributorsGeneric.php';
|
||||
|
||||
class OrgsUsingObjectsWidget extends OrgsContributorsGeneric
|
||||
{
|
||||
public $title = 'Orgs using MISP objects';
|
||||
public $description = 'Display the logos of all organisations having shared at least one event containing an object in the last 100 days';
|
||||
|
||||
protected function filter($user, $org, $start_timestamp) {
|
||||
$options['joins'] = array(
|
||||
array('table' => 'objects',
|
||||
'alias' => 'Objects',
|
||||
'type' => 'INNER',
|
||||
'conditions' => array(
|
||||
'Objects.event_id = Event.id',
|
||||
)
|
||||
)
|
||||
);
|
||||
$options['fields'] = 'Event.id';
|
||||
$options['limit'] = 1;
|
||||
$conditions = $this->Event->createEventConditions($user);
|
||||
$conditions['AND'][] = array('Event.orgc_id' => $org['Organisation']['id'], 'Event.timestamp >' => $start_timestamp);
|
||||
$options['conditions'] = $conditions;
|
||||
$eventsIds = $this->Event->find('all', $options);
|
||||
return count($eventsIds) > 0;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
/**
|
||||
* Sharing Graph widget which computes a sharing score for each local organizations
|
||||
* The score is computed for each month.
|
||||
*
|
||||
* Warning: the scoring function is very experimental. Tweak it as you wish.
|
||||
*/
|
||||
class SharingGraphWidget
|
||||
{
|
||||
public $title = 'Sharing Trends';
|
||||
public $render = 'MultiLineChart';
|
||||
public $width = 8;
|
||||
public $height = 6;
|
||||
public $description = 'A graph to show sharing trends per organisation';
|
||||
public $cacheLifetime = 10;
|
||||
public $autoRefreshDelay = false;
|
||||
public $params = array (
|
||||
'blacklist_orgs' => 'A list of organisation names to filter out',
|
||||
'months' => 'Number of past months to consider for the graph'
|
||||
);
|
||||
|
||||
public $placeholder =
|
||||
'{
|
||||
"blacklist_orgs": ["Orgs to filter"],
|
||||
"months": "6"
|
||||
}';
|
||||
|
||||
|
||||
private function attribute_scoring($attribute) {
|
||||
// each attribute gets 1 point
|
||||
return 1;
|
||||
}
|
||||
|
||||
private function object_scoring($object) {
|
||||
$score = 0;
|
||||
$this->Object->bindModel(array('hasMany' => array('ObjectReference' => array('foreignKey' => 'object_id'))));
|
||||
$o = $this->Object->find('first', array('conditions' => array('id' => $object['id'])));
|
||||
// We score for each object reference from this object
|
||||
foreach ($o['ObjectReference'] as $reference ) {
|
||||
//TODO more points for different types of references ?
|
||||
$score += 2;
|
||||
}
|
||||
return $score+50; // bonus for having an object
|
||||
}
|
||||
|
||||
private function event_scoring($event) {
|
||||
$score = 0;
|
||||
$attr_count = 0;
|
||||
// Simple attribute scoring
|
||||
foreach($event['Attribute'] as $attribute) {
|
||||
$attr_count++;
|
||||
$score += $this->attribute_scoring($attribute);
|
||||
// cap at 100 attributes max per event to avoid privileging large dump
|
||||
if ($attr_count > 100)
|
||||
break;
|
||||
}
|
||||
//Object scoring
|
||||
foreach($event['Object'] as $object) {
|
||||
$score += $this->object_scoring($object);
|
||||
}
|
||||
// Todo check use of taxonomies, tagging for extra points
|
||||
return $score;
|
||||
}
|
||||
|
||||
/*
|
||||
* Target_month must be from 1 to 12
|
||||
* Target year must be 4 digits
|
||||
*/
|
||||
private function org_scoring($user, $org, $target_month, $target_year) {
|
||||
$total_score = 0;
|
||||
|
||||
$start_date = $target_year.'-'.$target_month.'-01';
|
||||
if($target_month == 12) {
|
||||
$end_date = ($target_year+1).'-01-01';
|
||||
} else {
|
||||
$end_date = $target_year.'-'.($target_month+1).'-01';
|
||||
}
|
||||
$conditions = array('Event.orgc_id' => $org['Organisation']['id'], 'Event.date >=' => $start_date, 'Event.date <' => $end_date);
|
||||
|
||||
//This is required to enforce the ACL (not pull directly from the DB)
|
||||
$eventIds = $this->Event->fetchSimpleEventIds($user, array('conditions' => $conditions));
|
||||
|
||||
if(!empty($eventIds)) {
|
||||
$params = array('Event.id' => $eventIds);
|
||||
$events = $this->Event->find('all', array('conditions' => array('AND' => $params)));
|
||||
foreach($events as $event) {
|
||||
$total_score+= $this->event_scoring($event);
|
||||
}
|
||||
}
|
||||
return $total_score;
|
||||
}
|
||||
|
||||
private function filter_ghost_orgs(&$data, $orgs){
|
||||
foreach ($data['data'] as &$item) {
|
||||
foreach(array_keys($orgs) as $org_name) {
|
||||
unset($item[$org_name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Org = ClassRegistry::init('Organisation');
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
$this->Attribute = ClassRegistry::init('Attribute');
|
||||
$this->Object = ClassRegistry::init('Object');
|
||||
$this->ObjectReference = ClassRegistry::init('ObjectReference');
|
||||
$orgs = $this->Org->find('all', array( 'conditions' => array('Organisation.local' => 1)));
|
||||
$current_month = date('n');
|
||||
$current_year = date('Y');
|
||||
$limit = 6; // months
|
||||
if(!empty($options['months'])) {
|
||||
$limit = (int) ($options['months']);
|
||||
}
|
||||
$offset = 0;
|
||||
$ghost_orgs = array(); // track orgs without any contribution
|
||||
// We start by putting all orgs_id in there:
|
||||
foreach($orgs as $org) {
|
||||
// We check for blacklisted orgs
|
||||
if(!empty($options['blacklist_orgs']) && in_array($org['Organisation']['name'], $options['blacklist_orgs'])) {
|
||||
unset($orgs[$offset]);
|
||||
} else {
|
||||
$ghost_orgs[$org['Organisation']['name']] = true;
|
||||
}
|
||||
$offset++;
|
||||
}
|
||||
$data = array();
|
||||
$data['data'] = array();
|
||||
for ($i=0; $i < $limit; $i++) {
|
||||
$target_month = $current_month - $i;
|
||||
$target_year = $current_year;
|
||||
if ($target_month < 1) {
|
||||
$target_month += 12;
|
||||
$target_year -= 1;
|
||||
}
|
||||
$item = array();
|
||||
$item ['date'] = $target_year.'-'.$target_month.'-01';
|
||||
foreach($orgs as $org) {
|
||||
$score = $this->org_scoring($user, $org, $target_month, $target_year);
|
||||
$item[$org['Organisation']['name']] = (int) round(log($score, 1.1)); // taking the logarithmic view
|
||||
// if a positive score is detected at least once it's enough to be
|
||||
// considered for the graph
|
||||
if($score > 0) {
|
||||
unset($ghost_orgs[$org['Organisation']['name']]);
|
||||
}
|
||||
}
|
||||
$data['data'][] = $item;
|
||||
}
|
||||
$this->filter_ghost_orgs($data, $ghost_orgs);
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/TmpFileTool.php';
|
||||
|
||||
class ComplexTypeTool
|
||||
{
|
||||
|
@ -140,31 +141,28 @@ class ComplexTypeTool
|
|||
return array_values($array);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse a CSV file with the given settings
|
||||
/**
|
||||
* Parse a CSV file with the given settings
|
||||
* All lines starting with # are stripped
|
||||
* The settings can contain the following:
|
||||
* delimiter: Expects a delimiter string (default is a simple comma).
|
||||
* For example, to split the following line: "value1##comma##value2" simply pass $settings['delimiter'] = "##comma##";
|
||||
* values: Expects an array (or a comma separated string) with numeric values denoting the columns containing indicators. If this is not set then every value will be checked. (column numbers start at 1)
|
||||
* @param string $input
|
||||
* @param array $settings
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkCSV($input, $settings = array())
|
||||
{
|
||||
$delimiter = !empty($settings['delimiter']) ? $settings['delimiter'] : ",";
|
||||
$rows = str_getcsv($input, "\n");
|
||||
unset($input);
|
||||
$data = array();
|
||||
foreach ($rows as $k => $row) {
|
||||
if (empty($row[0]) || $row[0] === '#') {
|
||||
continue;
|
||||
}
|
||||
if ($delimiter == '\t') {
|
||||
$data[$k] = explode("\t", $row);
|
||||
} else {
|
||||
$data[$k] = str_getcsv($row, $delimiter);
|
||||
}
|
||||
if (empty($input)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$delimiter = !empty($settings['delimiter']) ? $settings['delimiter'] : ",";
|
||||
if ($delimiter === '\t') {
|
||||
$delimiter = "\t";
|
||||
}
|
||||
unset($rows);
|
||||
$values = !empty($settings['value']) ? $settings['value'] : array();
|
||||
if (!is_array($values)) {
|
||||
$values = explode(',', $values);
|
||||
|
@ -172,23 +170,34 @@ class ComplexTypeTool
|
|||
foreach ($values as $key => $value) {
|
||||
$values[$key] = intval($value);
|
||||
}
|
||||
$iocArray = array();
|
||||
foreach ($data as $rowPos => $row) {
|
||||
|
||||
// Write to tmp file to save memory
|
||||
$tmpFile = new TmpFileTool();
|
||||
$tmpFile->write($input);
|
||||
unset($input);
|
||||
|
||||
$iocArray = [];
|
||||
foreach ($tmpFile->csv($delimiter) as $row) {
|
||||
if (!empty($row[0][0]) && $row[0][0] === '#') { // Comment
|
||||
continue;
|
||||
}
|
||||
foreach ($row as $elementPos => $element) {
|
||||
if ((!empty($values) && in_array(($elementPos + 1), $values)) || empty($values)) {
|
||||
if (empty($values) || in_array(($elementPos + 1), $values)) {
|
||||
$element = trim($element, " \t\n\r\0\x0B\"\'");
|
||||
if (isset($settings['excluderegex']) && !empty($settings['excluderegex'])) {
|
||||
if (preg_match($settings['excluderegex'], $element)) {
|
||||
continue;
|
||||
}
|
||||
if (empty($element)) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($settings['excluderegex']) && preg_match($settings['excluderegex'], $element)) {
|
||||
continue;
|
||||
}
|
||||
$resolvedResult = $this->__resolveType($element);
|
||||
if (!empty($resolvedResult)) {
|
||||
if ($resolvedResult) {
|
||||
$iocArray[] = $resolvedResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $iocArray;
|
||||
}
|
||||
|
||||
|
@ -244,9 +253,8 @@ class ComplexTypeTool
|
|||
|
||||
private function __resolveType($raw_input)
|
||||
{
|
||||
$input = array(
|
||||
'raw' => trim($raw_input)
|
||||
);
|
||||
$input = array('raw' => trim($raw_input));
|
||||
|
||||
$input = $this->__refangInput($input);
|
||||
$input = $this->__extractPort($input);
|
||||
|
||||
|
|
|
@ -37,6 +37,31 @@ class TmpFileTool
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get one line from file parsed as CSV.
|
||||
*
|
||||
* @param string $delimiter
|
||||
* @param string $enclosure
|
||||
* @param string $escape
|
||||
* @return Generator
|
||||
* @throws Exception
|
||||
*/
|
||||
public function csv($delimiter = ',', $enclosure = '"', $escape = "\\")
|
||||
{
|
||||
$this->rewind();
|
||||
$line = 0;
|
||||
while (!feof($this->tmpfile)) {
|
||||
$result = fgetcsv($this->tmpfile, 0, $delimiter, $enclosure, $escape);
|
||||
if ($result === false) {
|
||||
throw new Exception("Could not read line $line from temporary CSV file.");
|
||||
}
|
||||
$line++;
|
||||
yield $result;
|
||||
}
|
||||
fclose($this->tmpfile);
|
||||
$this->tmpfile = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Generator
|
||||
* @throws Exception
|
||||
|
|
|
@ -2890,4 +2890,31 @@ class AppModel extends Model
|
|||
{
|
||||
return Configure::read('MISP.tmpdir') ?: sys_get_temp_dir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes JSON string and throws exception if string is not valid JSON or if is not array.
|
||||
*
|
||||
* @param string $json
|
||||
* @return array
|
||||
* @throws JsonException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
protected function jsonDecode($json)
|
||||
{
|
||||
if (defined('JSON_THROW_ON_ERROR')) {
|
||||
// JSON_THROW_ON_ERROR is supported since PHP 7.3
|
||||
$decoded = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
$decoded = json_decode($json, true);
|
||||
if ($decoded === null) {
|
||||
throw new UnexpectedValueException('Could not parse JSON: ' . json_last_error_msg(), json_last_error());
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($decoded)) {
|
||||
throw new UnexpectedValueException('JSON must be array type, get ' . gettype($decoded));
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -977,34 +977,47 @@ class Event extends AppModel
|
|||
'order' => false,
|
||||
'limit' => $max_correlations
|
||||
));
|
||||
if (empty($correlations)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$eventIds = [];
|
||||
foreach ($correlations as $correlation) {
|
||||
$eventIds[] = $correlation[$settings[$context]['correlationModel']]['event_id'];
|
||||
}
|
||||
|
||||
$conditions = $this->createEventConditions($user);
|
||||
$conditions['AND']['Event.id'] = $eventIds;
|
||||
$events = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('Event.id', 'Event.orgc_id', 'Event.info', 'Event.date'),
|
||||
));
|
||||
|
||||
$eventInfos = array();
|
||||
foreach ($events as $event) {
|
||||
$eventInfos[$event['Event']['id']] = $event['Event'];
|
||||
}
|
||||
|
||||
$relatedAttributes = array();
|
||||
$orgc_ids = array();
|
||||
foreach ($correlations as $k => $correlation) {
|
||||
if (empty($orgc_ids[$correlation[$settings[$context]['correlationModel']]['event_id']])) {
|
||||
$temp = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Event.id' => $correlation[$settings[$context]['correlationModel']]['event_id']),
|
||||
'fields' => array('Event.orgc_id')
|
||||
));
|
||||
if (!empty($temp)) {
|
||||
$orgc_ids[$correlation[$settings[$context]['correlationModel']]['event_id']] = $temp['Event']['orgc_id'];
|
||||
}
|
||||
foreach ($correlations as $correlation) {
|
||||
$correlation = $correlation[$settings[$context]['correlationModel']];
|
||||
// User don't have access to correlated attribute event, skip.
|
||||
if (!isset($eventInfos[$correlation['event_id']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$eventInfo = $eventInfos[$correlation['event_id']];
|
||||
$current = array(
|
||||
'id' => $correlation[$settings[$context]['correlationModel']]['event_id'],
|
||||
'attribute_id' => $correlation[$settings[$context]['correlationModel']]['attribute_id'],
|
||||
'info' => $correlation[$settings[$context]['correlationModel']]['info'],
|
||||
'value' => $correlation[$settings[$context]['correlationModel']]['value'],
|
||||
'id' => $correlation['event_id'],
|
||||
'attribute_id' => $correlation['attribute_id'],
|
||||
'value' => $correlation['value'],
|
||||
'org_id' => $eventInfo['orgc_id'],
|
||||
'info' => $eventInfo['info'],
|
||||
'date' => $eventInfo['date'],
|
||||
);
|
||||
if (!empty($orgc_ids[$correlation[$settings[$context]['correlationModel']]['event_id']])) {
|
||||
$current['org_id'] = $orgc_ids[$correlation[$settings[$context]['correlationModel']]['event_id']];
|
||||
} else {
|
||||
$current['org_id'] = 'unknown';
|
||||
}
|
||||
if (empty($relatedAttributes[$correlation[$settings[$context]['correlationModel']][$settings[$context]['parentIdField']]]) || !in_array($current, $relatedAttributes[$correlation[$settings[$context]['correlationModel']][$settings[$context]['parentIdField']]])) {
|
||||
$relatedAttributes[$correlation[$settings[$context]['correlationModel']][$settings[$context]['parentIdField']]][] = $current;
|
||||
}
|
||||
unset($correlations[$k]);
|
||||
$parentId = $correlation[$settings[$context]['parentIdField']];
|
||||
$relatedAttributes[$parentId][] = $current;
|
||||
}
|
||||
return $relatedAttributes;
|
||||
}
|
||||
|
@ -1116,13 +1129,10 @@ class Event extends AppModel
|
|||
return $result;
|
||||
}
|
||||
}
|
||||
$uploadFailed = false;
|
||||
try {
|
||||
$json = json_decode($newTextBody, true);
|
||||
$this->jsonDecode($newTextBody);
|
||||
} catch (Exception $e) {
|
||||
$uploadFailed = true;
|
||||
}
|
||||
if (!is_array($json) || $uploadFailed) {
|
||||
$this->logException("Invalid JSON returned when pushing to remote server {$server['Server']['id']}", $e);
|
||||
return $this->__logUploadResult($server, $event, $newTextBody);
|
||||
}
|
||||
return 'Success';
|
||||
|
@ -1172,18 +1182,8 @@ class Event extends AppModel
|
|||
{
|
||||
switch ($response->code) {
|
||||
case '200': // 200 (OK) + entity-action-result
|
||||
if ($response->isOk()) {
|
||||
$newTextBody = $response->body();
|
||||
return true;
|
||||
} else {
|
||||
try {
|
||||
$jsonArray = json_decode($response->body, true);
|
||||
} catch (Exception $e) {
|
||||
return true;
|
||||
}
|
||||
return $jsonArray['name'];
|
||||
}
|
||||
// no break
|
||||
$newTextBody = $response->body();
|
||||
return true;
|
||||
case '302': // Found
|
||||
$newLocation = $response->headers['Location'];
|
||||
$newTextBody = $response->body();
|
||||
|
@ -6036,7 +6036,7 @@ class Event extends AppModel
|
|||
'action' => 'warning',
|
||||
'user_id' => 0,
|
||||
'title' => 'Uploading Event (' . $event['Event']['id'] . ') to Server (' . $server['Server']['id'] . ')',
|
||||
'change' => 'Returned message: ', $newTextBody,
|
||||
'change' => 'Returned message: ' . $newTextBody,
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2709,12 +2709,12 @@ class Server extends AppModel
|
|||
if (empty($filter_rules)) {
|
||||
return $final;
|
||||
}
|
||||
$filter_rules = json_decode($filter_rules, true);
|
||||
$filter_rules = $this->jsonDecode($filter_rules);
|
||||
$url_params = array();
|
||||
foreach ($filter_rules as $field => $rules) {
|
||||
$temp = array();
|
||||
if ($field === 'url_params') {
|
||||
$url_params = json_decode($rules, true);
|
||||
$url_params = $this->jsonDecode($rules);
|
||||
} else {
|
||||
foreach ($rules as $operator => $elements) {
|
||||
foreach ($elements as $k => $element) {
|
||||
|
@ -4249,7 +4249,7 @@ class Server extends AppModel
|
|||
}
|
||||
if ($response->code == '405') {
|
||||
try {
|
||||
$responseText = json_decode($response->body, true)['message'];
|
||||
$responseText = $this->jsonDecode($response->body)['message'];
|
||||
} catch (Exception $e) {
|
||||
return array('status' => 3);
|
||||
}
|
||||
|
@ -4452,7 +4452,12 @@ class Server extends AppModel
|
|||
|
||||
public function isJson($string)
|
||||
{
|
||||
return (json_last_error() == JSON_ERROR_NONE);
|
||||
try {
|
||||
$this->jsonDecode($string);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function captureServer($server, $user)
|
||||
|
@ -4995,9 +5000,19 @@ class Server extends AppModel
|
|||
$expected = array('stix' => '>1.2.0.9', 'cybox' => '>2.1.0.21', 'mixbox' => '1.0.3', 'maec' => '>4.1.0.14', 'stix2' => '>2.0', 'pymisp' => '>2.4.120');
|
||||
// check if the STIX and Cybox libraries are working using the test script stixtest.py
|
||||
$scriptResult = shell_exec($this->getPythonVersion() . ' ' . APP . 'files' . DS . 'scripts' . DS . 'stixtest.py');
|
||||
$scriptResult = json_decode($scriptResult, true);
|
||||
if ($scriptResult == null) {
|
||||
return array('operational' => 0, 'stix' => array('expected' => $expected['stix']), 'cybox' => array('expected' => $expected['cybox']), 'mixbox' => array('expected' => $expected['mixbox']), 'maec' => array('expected' => $expected['maec']), 'stix2' => array('expected' => $expected['stix2']), 'pymisp' => array('expected' => $expected['pymisp']));
|
||||
try {
|
||||
$scriptResult = $this->jsonDecode($scriptResult);
|
||||
} catch (Exception $e) {
|
||||
$this->logException('Invalid JSON returned from stixtest', $e);
|
||||
return array(
|
||||
'operational' => 0,
|
||||
'stix' => array('expected' => $expected['stix']),
|
||||
'cybox' => array('expected' => $expected['cybox']),
|
||||
'mixbox' => array('expected' => $expected['mixbox']),
|
||||
'maec' => array('expected' => $expected['maec']),
|
||||
'stix2' => array('expected' => $expected['stix2']),
|
||||
'pymisp' => array('expected' => $expected['pymisp'])
|
||||
);
|
||||
}
|
||||
$scriptResult['operational'] = $scriptResult['success'];
|
||||
if ($scriptResult['operational'] == 0) {
|
||||
|
@ -5944,11 +5959,14 @@ class Server extends AppModel
|
|||
}
|
||||
if ($response->isOk()) {
|
||||
try {
|
||||
$response = json_decode($response->body, true);
|
||||
$response = $this->jsonDecode($response->body);
|
||||
} catch (Exception $e) {
|
||||
$message = 'Invalid response received from the remote instance.';
|
||||
|
||||
$this->logException($message, $e);
|
||||
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$message = 'Invalid response received from the remote instance.';
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
|
|
|
@ -5,25 +5,84 @@ use PHPUnit\Framework\TestCase;
|
|||
|
||||
class ComplexTypeToolTest extends TestCase
|
||||
{
|
||||
public function testCheckCSV(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$csv = <<<CSV
|
||||
# Downloaded from 1.1.1.1
|
||||
|
||||
127.0.0.1
|
||||
"127.0.0.2"
|
||||
CSV;
|
||||
$results = $complexTypeTool->checkCSV($csv);
|
||||
$this->assertCount(2, $results);
|
||||
}
|
||||
|
||||
public function testCheckCSVTabulator(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$csv = <<<CSV
|
||||
###########################################################################################
|
||||
# Downloaded from 1.1.1.1
|
||||
###########################################################################################
|
||||
127.0.0.1\t127.0.0.3
|
||||
"127.0.0.2"
|
||||
58.214.25.190
|
||||
58.214.239.53
|
||||
CSV;
|
||||
$results = $complexTypeTool->checkCSV($csv, ['delimiter' => '\t']);
|
||||
$this->assertCount(5, $results);
|
||||
}
|
||||
|
||||
public function testCheckCSVValues(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$csv = <<<CSV
|
||||
127.0.0.1\t127.0.0.2
|
||||
127.0.0.3\t127.0.0.4
|
||||
CSV;
|
||||
$results = $complexTypeTool->checkCSV($csv, ['value' => '1', 'delimiter' => '\t']);
|
||||
$this->assertCount(2, $results);
|
||||
foreach (['127.0.0.1', '127.0.0.3'] as $k => $test) {
|
||||
$this->assertEquals($test, $results[$k]['value']);
|
||||
$this->assertEquals('ip-dst', $results[$k]['default_type']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testCheckCSVEmpty(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$results = $complexTypeTool->checkCSV('');
|
||||
$this->assertCount(0, $results);
|
||||
}
|
||||
|
||||
public function testCheckCSVEmptyLines(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$results = $complexTypeTool->checkCSV(",,,\t\n,,,,,");
|
||||
$this->assertCount(0, $results);
|
||||
}
|
||||
|
||||
public function testCheckCSVTestFile(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$results = $complexTypeTool->checkCSV(file_get_contents(__DIR__ . '/../../tests/event.csv'));
|
||||
$this->assertCount(37, $results);
|
||||
}
|
||||
|
||||
public function testCheckFreeTextHeader(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$results = $complexTypeTool->checkFreeText(<<<EOT
|
||||
$text = <<<EOT
|
||||
# LAST 1000 # UTC UPDATE 2020-07-13 08:15:00
|
||||
127.0.0.1,(127.0.0.2), <127.0.0.3>; "127.0.0.4" '127.0.0.5'
|
||||
EOT
|
||||
);
|
||||
127.0.0.1,(127.0.0.2), <127.0.0.3>; "127.0.0.4" "'127.0.0.5'"
|
||||
EOT;
|
||||
$results = $complexTypeTool->checkFreeText($text);
|
||||
$this->assertCount(5, $results);
|
||||
$this->assertEquals('127.0.0.1', $results[0]['value']);
|
||||
$this->assertEquals('ip-dst', $results[0]['default_type']);
|
||||
$this->assertEquals('127.0.0.2', $results[1]['value']);
|
||||
$this->assertEquals('ip-dst', $results[1]['default_type']);
|
||||
$this->assertEquals('127.0.0.3', $results[2]['value']);
|
||||
$this->assertEquals('ip-dst', $results[2]['default_type']);
|
||||
$this->assertEquals('127.0.0.4', $results[3]['value']);
|
||||
$this->assertEquals('ip-dst', $results[3]['default_type']);
|
||||
$this->assertEquals('127.0.0.5', $results[4]['value']);
|
||||
$this->assertEquals('ip-dst', $results[4]['default_type']);
|
||||
foreach (['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4', '127.0.0.5'] as $k => $test) {
|
||||
$this->assertEquals($test, $results[$k]['value']);
|
||||
$this->assertEquals('ip-dst', $results[$k]['default_type']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testCheckFreeTextIpv4(): void
|
||||
|
@ -267,6 +326,15 @@ EOT
|
|||
$this->assertEquals('url', $results[0]['default_type']);
|
||||
}
|
||||
|
||||
public function testCheckFreeTextUrlWithPort(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
$results = $complexTypeTool->checkFreeText('https://github.com:443/MISP/MISP');
|
||||
$this->assertCount(1, $results);
|
||||
$this->assertEquals('https://github.com:443/MISP/MISP', $results[0]['value']);
|
||||
$this->assertEquals('url', $results[0]['default_type']);
|
||||
}
|
||||
|
||||
public function testCheckFreeTextUrlWithoutProtocol(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
array(
|
||||
'field' => 'to_ids',
|
||||
'type' => 'checkbox',
|
||||
'label' => __("for Intrusion Detection System"),
|
||||
'label' => __("For Intrusion Detection System"),
|
||||
//'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
|
@ -75,7 +75,6 @@
|
|||
'type' => 'text',
|
||||
'hidden' => true
|
||||
),
|
||||
'<div id="extended_event_preview" style="width:446px;"></div>'
|
||||
),
|
||||
'submit' => array(
|
||||
'action' => $action,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<div>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<?php
|
||||
/*
|
||||
* Display a simple array.
|
||||
* The size of the keys array is considered for the width.
|
||||
* Expected input:
|
||||
* { keys: <array of string>, rows: <array of arrays>}
|
||||
*
|
||||
* Example:
|
||||
* {keys: ['id', 'name', 'score'], rows: [['1', 'test', '10'], ['2', 'john', '5']]}
|
||||
*
|
||||
*/
|
||||
$count = count($data['keys']);
|
||||
echo '<tr>';
|
||||
foreach ($data['keys'] as $key) {
|
||||
echo '<th>'.h($key).'</th>';
|
||||
}
|
||||
echo '</tr>';
|
||||
foreach ($data['rows'] as $row) {
|
||||
echo '<tr>';
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
if (isset($row[$i])) {
|
||||
echo '<td>'.h($row[$i]).'</td>';
|
||||
}
|
||||
}
|
||||
echo '</tr>';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,44 @@
|
|||
<div>
|
||||
<p>
|
||||
<?php
|
||||
/*
|
||||
* Display orgs logos
|
||||
* The input is a list of item.
|
||||
* Each item is expected to contain an org object with the name and id populated
|
||||
*
|
||||
* Example:
|
||||
* [{'Organisation' => array('name' => 'orgA', 'id' => 1)}, {'Organisation' => ...}]
|
||||
*
|
||||
*/
|
||||
foreach ($data as $org) {
|
||||
echo '<a href="/organisations/view/'.h($org['Organisation']['id']).'" title="'.h($org['Organisation']['name']).'" target="_blank">';
|
||||
$img_data = $this->OrgImg->getOrgImg(array('name' => $org['Organisation']['name'], 'id' => $org['Organisation']['id'], 'size' => 48), true, true);
|
||||
if (strncmp($img_data, "<span", 5) === 0) { // the org has not uploaded a logo
|
||||
// We simulate a Logo where we take the first letter of the name
|
||||
$letter = substr($org['Organisation']['name'],0,1);
|
||||
echo '<div class="logo-box">'.$letter.'</div>';
|
||||
} else {
|
||||
echo $img_data;
|
||||
}
|
||||
echo '</a>';
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style widget-scoped>
|
||||
.logo-box {
|
||||
display: inline-block;
|
||||
width: 44px;
|
||||
height: 29px;
|
||||
border: 2px solid white;
|
||||
background-color: rgb(240,240,240);
|
||||
color: rgb(0,136,204);
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
padding-top: 15px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
|
@ -9,8 +9,7 @@
|
|||
$mayModify = ($isSiteAdmin || ($isAclModify && $event['Event']['user_id'] == $me['id'] && $event['Orgc']['id'] == $me['org_id']) || ($isAclModifyOrg && $event['Orgc']['id'] == $me['org_id']));
|
||||
$mayPublish = ($isAclPublish && $event['Orgc']['id'] == $me['org_id']);
|
||||
$mayChangeCorrelation = !Configure::read('MISP.completely_disable_correlation') && ($isSiteAdmin || ($mayModify && Configure::read('MISP.allow_disabling_correlation')));
|
||||
$possibleAction = 'Proposal';
|
||||
if ($mayModify) $possibleAction = 'Attribute';
|
||||
$possibleAction = $mayModify ? 'attribute' : 'shadow_attribute';
|
||||
$all = false;
|
||||
if (isset($this->params->params['paging']['Event']['page'])) {
|
||||
if ($this->params->params['paging']['Event']['page'] == 0) $all = true;
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
'children' => array(
|
||||
array(
|
||||
'id' => 'create-button',
|
||||
'title' => $possibleAction === 'Attribute' ? __('Add attribute') : __('Add proposal'),
|
||||
'title' => $possibleAction === 'attribute' ? __('Add attribute') : __('Add proposal'),
|
||||
'fa-icon' => 'plus',
|
||||
//'onClick' => 'clickCreateButton',
|
||||
'onClick' => 'openGenericModal',
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
<?php
|
||||
$this->set('menuItem', $menuItem);
|
||||
$divider = $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
?>
|
||||
<div class="actions sideMenu">
|
||||
<ul class="nav nav-list">
|
||||
<?php
|
||||
|
@ -10,7 +14,6 @@
|
|||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'dashboardAdd',
|
||||
'url' => '#',
|
||||
'text' => __('Add Widget'),
|
||||
'onClick' => array(
|
||||
'function' => 'openGenericModalPost',
|
||||
|
@ -19,7 +22,6 @@
|
|||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'dashboardImport',
|
||||
'url' => '#',
|
||||
'text' => __('Import Config JSON'),
|
||||
'onClick' => array(
|
||||
'function' => 'openGenericModal',
|
||||
|
@ -28,7 +30,6 @@
|
|||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'dashboardExport',
|
||||
'url' => '#',
|
||||
'text' => __('Export Config JSON'),
|
||||
'onClick' => array(
|
||||
'function' => 'openGenericModal',
|
||||
|
@ -37,7 +38,6 @@
|
|||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'dashboardSave',
|
||||
'url' => '#',
|
||||
'text' => __('Save Dashboard Config'),
|
||||
'onClick' => array(
|
||||
'function' => 'openGenericModal',
|
||||
|
@ -51,9 +51,9 @@
|
|||
));
|
||||
break;
|
||||
case 'event':
|
||||
$dataEventId = isset($event['Event']['id']) ? h($event['Event']['id']) : 0;
|
||||
echo '<div id="hiddenSideMenuData" class="hidden" data-event-id="' . $dataEventId . '"></div>';
|
||||
if (in_array($menuItem, array('addAttribute', 'addObject', 'addAttachment', 'addIOC', 'addThreatConnect', 'populateFromTemplate', 'merge'))) {
|
||||
$eventId = intval($event['Event']['id']);
|
||||
echo '<div id="hiddenSideMenuData" class="hidden" data-event-id="' . $eventId . '"></div>';
|
||||
if (in_array($menuItem, array('editEvent', 'addAttribute', 'addObject', 'addAttachment', 'addIOC', 'addThreatConnect', 'populateFromTemplate', 'merge'))) {
|
||||
// we can safely assume that mayModify is true if coming from these actions, as they require it in the controller and the user has already passed that check
|
||||
$mayModify = true;
|
||||
if ($isAclPublish) $mayPublish = true;
|
||||
|
@ -68,49 +68,47 @@
|
|||
if ($menuItem === 'enrichmentResults') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'enrichmentResults',
|
||||
'url' => '#',
|
||||
'text' => __('Enrichment Module Result')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
if ($menuItem === 'freetextResults') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'freetextResults',
|
||||
'url' => '#',
|
||||
'text' => __('Freetext Import Result')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'viewEvent',
|
||||
'url' => '/events/view/' . $event['Event']['id'],
|
||||
'url' => '/events/view/' . $eventId,
|
||||
'text' => __('View Event')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'viewGraph',
|
||||
'url' => '/events/viewGraph/' . $event['Event']['id'],
|
||||
'url' => '/events/viewGraph/' . $eventId,
|
||||
'text' => __('View Correlation Graph')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'eventLog',
|
||||
'url' => '/logs/event_index/' . $event['Event']['id'],
|
||||
'url' => '/logs/event_index/' . $eventId,
|
||||
'text' => __('View Event History')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
if ($isSiteAdmin || (isset($mayModify) && $mayModify)) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'editEvent',
|
||||
'url' => '/events/edit/' . $event['Event']['id'],
|
||||
'url' => '/events/edit/' . $eventId,
|
||||
'text' => __('Edit Event')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
|
||||
'url' => '/events/delete/' . h($event['Event']['id']),
|
||||
'url' => '/events/delete/' . $eventId,
|
||||
'text' => __('Delete Event'),
|
||||
'message' => __('Are you sure you want to delete # %s?', h($event['Event']['id']))
|
||||
'message' => __('Are you sure you want to delete event #%s?', $eventId)
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'addAttribute',
|
||||
'url' => '/attributes/add/' . $event['Event']['id'],
|
||||
'url' => '/attributes/add/' . $eventId,
|
||||
'text' => __('Add Attribute')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
|
@ -118,75 +116,75 @@
|
|||
'text' => __('Add Object'),
|
||||
'onClick' => array(
|
||||
'function' => 'popoverPopup',
|
||||
'params' => array('this', h($event['Event']['id']), 'objectTemplates', 'objectMetaChoice')
|
||||
'params' => array('this', $eventId, 'objectTemplates', 'objectMetaChoice')
|
||||
),
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'addAttachment',
|
||||
'url' => '/attributes/add_attachment/' . $event['Event']['id'],
|
||||
'url' => '/attributes/add_attachment/' . $eventId,
|
||||
'text' => __('Add Attachment')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'getPopup',
|
||||
'params' => array($event['Event']['id'], 'events', 'importChoice')
|
||||
'params' => array($eventId, 'events', 'importChoice')
|
||||
),
|
||||
'text' => __('Populate from...')
|
||||
));
|
||||
if ($menuItem === 'populateFromtemplate') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/templates/populateEventFromTemplate/' . $template_id . '/' . $event['Event']['id'],
|
||||
'url' => '/templates/populateEventFromTemplate/' . $template_id . '/' . $eventId,
|
||||
'text' => __('Populate From Template')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'genericPopup',
|
||||
'params' => array($baseurl . '/events/enrichEvent/' . $event['Event']['id'], '#confirmation_box')
|
||||
'params' => array($baseurl . '/events/enrichEvent/' . $eventId, '#confirmation_box')
|
||||
),
|
||||
'text' => __('Enrich Event')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'merge',
|
||||
'url' => '/events/merge/' . $event['Event']['id'],
|
||||
'url' => '/events/merge/' . $eventId,
|
||||
'text' => __('Merge attributes from...')
|
||||
));
|
||||
}
|
||||
if (($isSiteAdmin && (!isset($mayModify) || !$mayModify)) || (!isset($mayModify) || !$mayModify)) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'proposeAttribute',
|
||||
'url' => '/shadow_attributes/add/' . $event['Event']['id'],
|
||||
'url' => '/shadow_attributes/add/' . $eventId,
|
||||
'text' => __('Propose Attribute')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'proposeAttachment',
|
||||
'url' => '/shadow_attributes/add_attachment/' . $event['Event']['id'],
|
||||
'url' => '/shadow_attributes/add_attachment/' . $eventId,
|
||||
'text' => __('Propose Attachment')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
$publishButtons = ' hidden';
|
||||
if (isset($event['Event']['published']) && 0 == $event['Event']['published'] && ($isSiteAdmin || (isset($mayPublish) && $mayPublish))) $publishButtons = "";
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'publishPopup',
|
||||
'params' => array($event['Event']['id'], 'alert')
|
||||
'params' => array($eventId, 'alert')
|
||||
),
|
||||
'class' => 'publishButtons not-published ' . $publishButtons,
|
||||
'class' => 'publishButtons not-published' . $publishButtons,
|
||||
'text' => __('Publish Event')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'publishPopup',
|
||||
'params' => array($event['Event']['id'], 'publish')
|
||||
'params' => array($eventId, 'publish')
|
||||
),
|
||||
'class' => 'publishButtons not-published ' . $publishButtons,
|
||||
'class' => 'publishButtons not-published' . $publishButtons,
|
||||
'text' => __('Publish (no email)')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'publishPopup',
|
||||
'params' => array($event['Event']['id'], 'unpublish')
|
||||
'params' => array($eventId, 'unpublish')
|
||||
),
|
||||
'class' => (isset($event['Event']['published']) && (1 == $event['Event']['published'] && $mayModify)) ? '' : 'hidden',
|
||||
'text' => __('Unpublish')
|
||||
|
@ -195,7 +193,7 @@
|
|||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'publishPopup',
|
||||
'params' => array($event['Event']['id'], 'sighting')
|
||||
'params' => array($eventId, 'sighting')
|
||||
),
|
||||
'class' => 'publishButtons',
|
||||
'text' => __('Publish Sightings')
|
||||
|
@ -206,13 +204,13 @@
|
|||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'delegatePopup',
|
||||
'params' => array($event['Event']['id'])
|
||||
'params' => array($eventId)
|
||||
),
|
||||
'text' => __('Delegate Publishing')
|
||||
));
|
||||
}
|
||||
if (isset($delegationRequest) && $delegationRequest && ($isSiteAdmin || ($isAclPublish && ($me['org_id'] == $delegationRequest['EventDelegation']['org_id'] || $me['org_id'] == $delegationRequest['EventDelegation']['requester_org_id'])))) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
if ($isSiteAdmin || ($isAclPublish && ($me['org_id'] == $delegationRequest['EventDelegation']['org_id']))) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
|
@ -229,22 +227,23 @@
|
|||
),
|
||||
'text' => __('Discard Delegation Request')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
}
|
||||
if (Configure::read('Plugin.ZeroMQ_enable') && $isAclZmq) {
|
||||
if ($isAclZmq && Configure::read('Plugin.ZeroMQ_enable')) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
|
||||
'url' => '/events/pushEventToZMQ/' . h($event['Event']['id']),
|
||||
'url' => '/events/pushEventToZMQ/' . $eventId,
|
||||
'text' => __('Publish event to ZMQ'),
|
||||
'message' => __('Are you sure you wish to republish the current event to the ZMQ channel?')
|
||||
));
|
||||
}
|
||||
if (Configure::read('Plugin.Kafka_enable') &&
|
||||
if ($isAclKafka &&
|
||||
Configure::read('Plugin.Kafka_enable') &&
|
||||
Configure::read('Plugin.Kafka_event_notifications_enable') &&
|
||||
Configure::read('Plugin.Kafka_event_notifications_topic') &&
|
||||
$isAclKafka) {
|
||||
Configure::read('Plugin.Kafka_event_notifications_topic')
|
||||
) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
|
||||
'url' => '/events/pushEventToKafka/' . h($event['Event']['id']),
|
||||
'url' => '/events/pushEventToKafka/' . $eventId,
|
||||
'text' => __('Publish event to Kafka'),
|
||||
'message' => __('Are you sure you wish to republish the current event to the Kafka topic?')
|
||||
));
|
||||
|
@ -252,18 +251,18 @@
|
|||
if (!empty($event['Orgc']['local'])) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'contact',
|
||||
'url' => '/events/contact/' . $event['Event']['id'],
|
||||
'url' => '/events/contact/' . $eventId,
|
||||
'text' => __('Contact Reporter')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'getPopup',
|
||||
'params' => array($event['Event']['id'], 'events', 'exportChoice')
|
||||
'params' => array($eventId, 'events', 'exportChoice')
|
||||
),
|
||||
'text' => __('Download as...')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/events/index',
|
||||
'text' => __('List Events')
|
||||
|
@ -330,7 +329,7 @@
|
|||
'text' => __('REST client')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'listAttributes',
|
||||
'url' => '/attributes/index',
|
||||
|
@ -342,7 +341,7 @@
|
|||
'text' => __('Search Attributes')
|
||||
));
|
||||
if ($menuItem == 'searchAttributes2') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'onClick' => array(
|
||||
'function' => 'getPopup',
|
||||
|
@ -351,7 +350,7 @@
|
|||
'text' => __('Download as...')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'viewProposals',
|
||||
'url' => '/shadow_attributes/index/all:0',
|
||||
|
@ -367,7 +366,7 @@
|
|||
'url' => '/event_delegations/index/context:pending',
|
||||
'text' => __('View delegation requests')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/events/export',
|
||||
'text' => __('Export')
|
||||
|
@ -401,7 +400,7 @@
|
|||
));
|
||||
}
|
||||
if ($menuItem === 'edit') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/admin/regexp/edit/' . h($id),
|
||||
'text' => __('Edit Regexp')
|
||||
|
@ -468,7 +467,7 @@
|
|||
));
|
||||
}
|
||||
if ($menuItem == 'edit') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/admin/whitelists/edit' . h($id),
|
||||
'text' => __('Edit Whitelist')
|
||||
|
@ -491,7 +490,7 @@
|
|||
'url' => '/users/change_pw',
|
||||
'text' => __('Change Password')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
} else if((Configure::read('Plugin.CustomAuth_custom_password_reset'))) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'custom_pw_reset',
|
||||
|
@ -561,7 +560,7 @@
|
|||
'text' => __('Add Sharing Group')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'userGuide',
|
||||
'url' => '/pages/display/doc/general',
|
||||
|
@ -630,7 +629,7 @@
|
|||
));
|
||||
}
|
||||
if ($menuItem === 'edit' && $isSiteAdmin) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'edit',
|
||||
'url' => '/servers/edit/' . h($id),
|
||||
|
@ -707,7 +706,7 @@
|
|||
'text' => __('Delete User'),
|
||||
'message' => __('Are you sure you want to delete # %s? It is highly recommended to never delete users but to disable them instead.', h($id))
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
if ($isSiteAdmin && $menuItem === 'editRole') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
|
@ -721,7 +720,7 @@
|
|||
'text' => __('Delete Role'),
|
||||
'message' => __('Are you sure you want to delete # %s?', h($id))
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
if ($isSiteAdmin) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
|
@ -757,7 +756,7 @@
|
|||
'text' => __('Contact Users')
|
||||
));
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
if ($isSiteAdmin) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'addOrg',
|
||||
|
@ -794,7 +793,7 @@
|
|||
'url' => '/organisations/index',
|
||||
'text' => __('List Organisations')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'addRole',
|
||||
'url' => '/admin/roles/add',
|
||||
|
@ -807,7 +806,7 @@
|
|||
'text' => __('List Roles')
|
||||
));
|
||||
if ($isSiteAdmin) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/servers/serverSettings',
|
||||
'text' => __('Server Settings & Maintenance')
|
||||
|
@ -820,14 +819,14 @@
|
|||
'url' => '/servers/updateProgress',
|
||||
'text' => __('Update Progress')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
if (Configure::read('MISP.background_jobs')) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'jobs',
|
||||
'url' => '/jobs/index',
|
||||
'text' => __('Jobs')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'tasks',
|
||||
'url' => '/tasks',
|
||||
|
@ -889,7 +888,7 @@
|
|||
'url' => '/posts/add/thread/' . h($thread_id),
|
||||
'text' => __('Add Post')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
}
|
||||
if ($menuItem === 'edit') {
|
||||
|
@ -903,7 +902,7 @@
|
|||
'url' => '/threads/view/' . h($id),
|
||||
'text' => __('Edit Post')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/threads/index',
|
||||
|
@ -934,7 +933,6 @@
|
|||
if ($menuItem === 'edit') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'edit',
|
||||
'url' => '#',
|
||||
'text' => __('Edit Tag')
|
||||
));
|
||||
}
|
||||
|
@ -1026,7 +1024,7 @@
|
|||
'url' => '/decayingModel/import',
|
||||
'text' => __('Import Decaying Model')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/decayingModel/add',
|
||||
'text' => __('Add Decaying Model')
|
||||
|
@ -1035,7 +1033,7 @@
|
|||
'url' => '/decayingModel/decayingTool',
|
||||
'text' => __('Decaying Models Tool')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_divider');
|
||||
echo $divider;
|
||||
}
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'url' => '/decayingModel/index',
|
||||
|
@ -1138,7 +1136,6 @@
|
|||
if ($menuItem === 'edit') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'edit',
|
||||
'url' => '#',
|
||||
'text' => __('Edit News Item')
|
||||
));
|
||||
}
|
||||
|
@ -1232,8 +1229,3 @@
|
|||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#li<?php echo h($menuItem); ?>').addClass("active");
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,46 +1,42 @@
|
|||
<?php
|
||||
$a = '';
|
||||
if (!empty($element_id)) {
|
||||
$element_id = 'id="li' . $element_id . '"';
|
||||
} else {
|
||||
if (!empty($url)) {
|
||||
$urlparts = explode('/', $url);
|
||||
$element_id = 'id="li' . h(end($urlparts)) . '"';
|
||||
$active = $this->get('menuItem');
|
||||
if (empty($element_id) && !empty($url)) {
|
||||
$urlparts = explode('/', $url);
|
||||
$element_id = end($urlparts);
|
||||
}
|
||||
if ($active === $element_id) {
|
||||
$class .= ' active';
|
||||
}
|
||||
if (!empty($element_id)) {
|
||||
$li = ' id="li' . h($element_id) . '"';
|
||||
} else {
|
||||
$li = '';
|
||||
}
|
||||
if (!empty($class)) {
|
||||
$li .= ' class="' . h(trim($class)) . '"';
|
||||
}
|
||||
if (empty($url)) {
|
||||
$a = 'href="#"';
|
||||
} else if (strpos($url, '://') !== false) {
|
||||
$a = 'href="' . h($url) . '"';
|
||||
} else {
|
||||
$a = 'href="' . $this->get('baseurl') . h($url) . '"';
|
||||
}
|
||||
if (!empty($onClick)) {
|
||||
$params = '';
|
||||
foreach ($onClick['params'] as $param) {
|
||||
if (!empty($params)) {
|
||||
$params .= ', ';
|
||||
}
|
||||
if ($param === 'this') {
|
||||
$params .= $param;
|
||||
} else {
|
||||
$element_id = '';
|
||||
$params .= "'" . h($param) . "'";
|
||||
}
|
||||
}
|
||||
if (empty($url)) {
|
||||
$a = 'href="#"';
|
||||
} else if (strpos($url, '://') !== null) {
|
||||
$a = 'href="' . h($url) . '"';
|
||||
} else {
|
||||
$a = 'href="' . $baseurl . h($url) . '"';
|
||||
}
|
||||
if (!empty($class)) {
|
||||
$class = 'class="' . h($class) . '"';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
if (!empty($onClick)) {
|
||||
$params = '';
|
||||
foreach ($onClick['params'] as $param) {
|
||||
if (!empty($params)) {
|
||||
$params .= ', ';
|
||||
}
|
||||
if ($param === 'this') {
|
||||
$params .= $param;
|
||||
} else {
|
||||
$params .= "'" . h($param) . "'";
|
||||
}
|
||||
}
|
||||
$a .= sprintf(' onClick="%s(%s)"', $onClick['function'], $params);
|
||||
}
|
||||
if (!empty($download)) {
|
||||
$download = 'download="' . h($download) . '"';
|
||||
} else {
|
||||
$download = '';
|
||||
}
|
||||
|
||||
echo sprintf('<li %s %s><a %s %s>%s</a></li>', $element_id, $class, $a, $download, h($text));
|
||||
?>
|
||||
$a .= sprintf(' onclick="%s(%s)"', $onClick['function'], $params);
|
||||
}
|
||||
if (!empty($download)) {
|
||||
$a .= ' download="' . h($download) . '"';
|
||||
}
|
||||
echo "<li$li><a $a>" . h($text) . '</a></li>';
|
||||
|
|
|
@ -1,32 +1,21 @@
|
|||
<?php
|
||||
$a = '';
|
||||
if (!empty($element_id)) {
|
||||
$element_id = 'id="li' . $element_id . '"';
|
||||
if (!empty($element_id)) {
|
||||
$li = ' id="li' . $element_id . '"';
|
||||
} else {
|
||||
if (!empty($url)) {
|
||||
$urlparts = explode('/', $url);
|
||||
$li = ' id="li' . h(end($urlparts)) . '"';
|
||||
} else {
|
||||
if (!empty($url)) {
|
||||
$urlparts = explode('/', $url);
|
||||
$element_id = 'id="li' . h(end($urlparts)) . '"';
|
||||
} else {
|
||||
$element_id = '';
|
||||
}
|
||||
$li = '';
|
||||
}
|
||||
if (empty($url)) {
|
||||
$a = '';
|
||||
} else if (strpos($url, '://') !== null) {
|
||||
$a = h($url);
|
||||
} else {
|
||||
$a = $baseurl . h($url);
|
||||
}
|
||||
if (!empty($class)) {
|
||||
$class = 'class="' . h($class) . '"';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
$post_link = $this->Form->postLink(
|
||||
__('%s', $text),
|
||||
$url,
|
||||
null,
|
||||
empty($message) ? null : $message
|
||||
);
|
||||
echo sprintf('<li %s %s>%s</li>', $element_id, $class, $post_link);
|
||||
?>
|
||||
}
|
||||
if (!empty($class)) {
|
||||
$li .= ' class="' . h($class) . '"';
|
||||
}
|
||||
$post_link = $this->Form->postLink(
|
||||
$text,
|
||||
$url,
|
||||
null,
|
||||
empty($message) ? null : $message
|
||||
);
|
||||
echo "<li$li>$post_link</li>";
|
||||
|
|
|
@ -1,141 +1,128 @@
|
|||
<div class="shadow_attributes <?php if (!isset($ajax) || !$ajax) echo 'form';?>">
|
||||
<?php echo $this->Form->create('ShadowAttribute', array('url' => '/shadow_attributes/add/' . $event_id));?>
|
||||
<fieldset>
|
||||
<legend><?php echo __('Add Proposal'); ?></legend>
|
||||
<div id="formWarning" class="message ajaxMessage"></div>
|
||||
<div class="add_attribute_fields">
|
||||
<?php
|
||||
echo $this->Form->hidden('event_id');
|
||||
echo $this->Form->input('category', array(
|
||||
<?php
|
||||
echo $this->element('genericElements/Form/genericForm', array(
|
||||
'form' => $this->Form,
|
||||
'data' => array(
|
||||
'title' => __('Add Proposal'),
|
||||
'model' => 'ShadowAttribute',
|
||||
'fields' => array(
|
||||
array(
|
||||
'field' => 'event_id',
|
||||
'class' => 'org-id-picker-hidden-field',
|
||||
'type' => 'text',
|
||||
'hidden' => true
|
||||
),
|
||||
array(
|
||||
'field' => 'category',
|
||||
'class' => 'input',
|
||||
'empty' => __('(choose one)'),
|
||||
'div' => 'input',
|
||||
'label' => __('Category ') . $this->element('formInfo', array('type' => 'category')),
|
||||
));
|
||||
echo $this->Form->input('type', array(
|
||||
'empty' => __('(first choose category)'),
|
||||
'label' => __('Type ') . $this->element('formInfo', array('type' => 'type')),
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('value', array(
|
||||
'type' => 'textarea',
|
||||
'error' => array('escape' => false),
|
||||
'class' => 'input-xxlarge clear'
|
||||
));
|
||||
echo $this->Form->input('comment', array(
|
||||
'type' => 'text',
|
||||
'label' => __('Contextual Comment'),
|
||||
'error' => array('escape' => false),
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge'
|
||||
));
|
||||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'checked' => true,
|
||||
'label' => __('for Intrusion Detection System'),
|
||||
));
|
||||
echo $this->Form->input('batch_import', array(
|
||||
'type' => 'checkbox',
|
||||
));
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'options' => $categories,
|
||||
'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
'field' => 'type',
|
||||
'class' => 'input',
|
||||
'empty' => __('(choose category first)'),
|
||||
'options' => $types
|
||||
),
|
||||
array(
|
||||
'field'=> 'value',
|
||||
'type' => 'textarea',
|
||||
'class' => 'input span6',
|
||||
'div' => 'input clear'
|
||||
),
|
||||
array(
|
||||
'field' => 'comment',
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
echo $this->Form->input('last_seen', array(
|
||||
'class' => 'input span6',
|
||||
'div' => 'input clear',
|
||||
'label' => __("Contextual Comment")
|
||||
),
|
||||
array(
|
||||
'field' => 'to_ids',
|
||||
'type' => 'checkbox',
|
||||
'label' => __("For Intrusion Detection System"),
|
||||
//'stayInLine' => 1
|
||||
),
|
||||
array(
|
||||
'field' => 'batch_import',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
array(
|
||||
'field' => 'first_seen',
|
||||
'type' => 'text',
|
||||
'div' => 'input hidden',
|
||||
'required' => false,
|
||||
));
|
||||
?>
|
||||
<div id="bothSeenSliderContainer"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<p style="color:red;font-weight:bold;display:none;<?php if ($ajax) echo 'text-align:center;'; ?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a classified nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
|
||||
<?php if (isset($ajax) && $ajax): ?>
|
||||
<div class="overlay_spacing">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="vertical-align:top">
|
||||
<span tite="<?php echo __('Propose');?>" role="button" tabindex="0" aria-label="<?php echo __('Propose');?>" id="submitButton" class="btn btn-primary" onClick="submitPopoverForm('<?php echo $event_id;?>', 'propose')"><?php echo __('Propose');?></span>
|
||||
</td>
|
||||
<td style="width:540px;">
|
||||
<p style="color:red;font-weight:bold;display:none;<?php if (isset($ajax) && $ajax) echo "text-align:center;"?>" id="warning-message"><?php echo __('Warning: You are about to share data that is of a sensitive nature (Attribution / targeting data). Make sure that you are authorised to share this.');?></p>
|
||||
</td>
|
||||
<td style="vertical-align:top;">
|
||||
<span class="btn btn-inverse" id="cancel_attribute_add"><?php echo __('Cancel');?></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
else:
|
||||
echo $this->Form->button(__('Propose'), array('class' => 'btn btn-primary'));
|
||||
endif;
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
$event['Event']['id'] = $this->request->data['ShadowAttribute']['event_id'];
|
||||
if (!$ajax) {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
|
||||
}
|
||||
|
||||
echo $this->element('form_seen_input');
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
<?php
|
||||
$formInfoTypes = array('category' => 'Category', 'type' => 'Type');
|
||||
echo 'var formInfoFields = ' . json_encode($formInfoTypes) . PHP_EOL;
|
||||
foreach ($formInfoTypes as $formInfoType => $humanisedName) {
|
||||
echo 'var ' . $formInfoType . 'FormInfoValues = {' . PHP_EOL;
|
||||
foreach ($info[$formInfoType] as $key => $formInfoData) {
|
||||
echo '"' . $key . '": "<span class=\"blue bold\">' . h($formInfoData['key']) . '</span>: ' . h($formInfoData['desc']) . '<br />",' . PHP_EOL;
|
||||
}
|
||||
echo '}' . PHP_EOL;
|
||||
}
|
||||
?>
|
||||
//
|
||||
//Generate Category / Type filtering array
|
||||
//
|
||||
var category_type_mapping = new Array();
|
||||
<?php
|
||||
foreach ($categoryDefinitions as $category => $def) {
|
||||
echo "category_type_mapping['" . addslashes($category) . "'] = {";
|
||||
$first = true;
|
||||
foreach ($def['types'] as $type) {
|
||||
if ($first) $first = false;
|
||||
else echo ', ';
|
||||
echo "'" . addslashes($type) . "' : '" . addslashes($type) . "'";
|
||||
}
|
||||
echo "}; \n";
|
||||
}
|
||||
'hidden' => true
|
||||
),
|
||||
array(
|
||||
'field' => 'last_seen',
|
||||
'type' => 'text',
|
||||
'hidden' => true
|
||||
),
|
||||
),
|
||||
'submit' => array(
|
||||
'action' => 'add',
|
||||
'text' => __('Propose'),
|
||||
'ajaxSubmit' => sprintf(
|
||||
'submitPopoverForm(%s, %s, 0, 1)',
|
||||
"'" . h($event_id) . "'",
|
||||
"'add'"
|
||||
)
|
||||
),
|
||||
'metaFields' => array(
|
||||
'<div id="bothSeenSliderContainer" style="height: 170px;"></div>'
|
||||
)
|
||||
)
|
||||
));
|
||||
if (!$ajax) {
|
||||
$event = ['Event' => ['id' => $event_id ]];
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var category_type_mapping = <?= json_encode(array_map(function($value) {
|
||||
return array_combine($value['types'], $value['types']);
|
||||
}, $categoryDefinitions)); ?>;
|
||||
|
||||
$(document).ready(function() {
|
||||
initPopoverContent('ShadowAttribute');
|
||||
$("#ShadowAttributeCategory").on('change', function(e) {
|
||||
formCategoryChanged('ShadowAttribute');
|
||||
if ($(this).val() === 'Attribution' || $(this).val() === 'Targeting data') {
|
||||
$("#warning-message").show();
|
||||
} else {
|
||||
$("#warning-message").hide();
|
||||
}
|
||||
});
|
||||
|
||||
$("#ShadowAttributeCategory, #ShadowAttributeType").change(function() {
|
||||
initPopoverContent('ShadowAttribute');
|
||||
});
|
||||
|
||||
<?php if ($ajax): ?>
|
||||
$('#cancel_attribute_add').click(function() {
|
||||
cancelPopoverForm();
|
||||
$('#ShadowAttributeCategory').change(function() {
|
||||
formCategoryChanged('ShadowAttribute');
|
||||
$('#ShadowAttributeType').chosen('destroy').chosen();
|
||||
});
|
||||
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
$(function() {
|
||||
$('#ShadowAttributeType').closest('form').submit(function( event ) {
|
||||
if ($('#ShadowAttributeType').val() === 'datetime') {
|
||||
// add timezone of the browser if not set
|
||||
var allowLocalTZ = true;
|
||||
var $valueInput = $('#ShadowAttributeValue')
|
||||
var dateValue = moment($valueInput.val())
|
||||
if (dateValue.isValid()) {
|
||||
if (dateValue.creationData().format !== "YYYY-MM-DDTHH:mm:ssZ" && dateValue.creationData().format !== "YYYY-MM-DDTHH:mm:ss.SSSSZ") {
|
||||
// Missing timezone data
|
||||
var confirm_message = '<?php echo __('Timezone missing, auto-detected as: ') ?>' + dateValue.format('Z')
|
||||
confirm_message += '<?php echo '\r\n' . __('The following value will be submitted instead: '); ?>' + dateValue.toISOString(allowLocalTZ)
|
||||
if (confirm(confirm_message)) {
|
||||
$valueInput.val(dateValue.toISOString(allowLocalTZ));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var textStatus = '<?php echo __('Value is not a valid datetime. Expected format YYYY-MM-DDTHH:mm:ssZ') ?>'
|
||||
showMessage('fail', textStatus);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
<?php if (!$ajax): ?>
|
||||
$('#ShadowAttributeType').chosen();
|
||||
$('#ShadowAttributeCategory').chosen();
|
||||
<?php else: ?>
|
||||
$('#genericModal').on('shown', function() {
|
||||
$('#ShadowAttributeType').chosen();
|
||||
$('#ShadowAttributeCategory').chosen();
|
||||
})
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
<?php echo $this->element('form_seen_input'); ?>
|
||||
<?php echo $this->Js->writeBuffer(); // Write cached scripts
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('to_ids', array(
|
||||
'label' => __('IDS Signature?'),
|
||||
'label' => __('For Intrusion Detection System'),
|
||||
));
|
||||
echo $this->Form->input('first_seen', array(
|
||||
'type' => 'text',
|
||||
|
|
|
@ -29,7 +29,7 @@ from cybox.objects.network_connection_object import NetworkConnection
|
|||
from cybox.objects.network_socket_object import NetworkSocket
|
||||
from cybox.objects.pipe_object import Pipe
|
||||
from cybox.objects.port_object import Port
|
||||
from cybox.objects.process_object import Process
|
||||
from cybox.objects.process_object import ChildPIDList, ImageInfo, PortList, Process
|
||||
from cybox.objects.socket_address_object import SocketAddress
|
||||
from cybox.objects.system_object import System, NetworkInterface, NetworkInterfaceList
|
||||
from cybox.objects.unix_user_account_object import UnixUserAccount
|
||||
|
@ -918,12 +918,27 @@ class StixBuilder(object):
|
|||
if feature in attributes_dict:
|
||||
setattr(process_object, feature.replace('-', '_'), attributes_dict[feature][0])
|
||||
if 'child-pid' in attributes_dict:
|
||||
# child-pid = attributes['child-pid']
|
||||
for child in attributes['child-pid']:
|
||||
process_object.child_pid_list.append(child)
|
||||
# if 'port' in attributes_dict:
|
||||
# for port in attributes['port']:
|
||||
# process_object.port_list.append(self.create_port_object(port['value']))
|
||||
for child in attributes_dict['child-pid']:
|
||||
try:
|
||||
process_object.child_pid_list.append(child)
|
||||
except AttributeError:
|
||||
process_object.child_pid_list = ChildPIDList()
|
||||
process_object.child_pid_list.append(child)
|
||||
if 'port' in attributes_dict:
|
||||
for port in attributes_dict['port']:
|
||||
port_object = self.create_port_object(port)
|
||||
try:
|
||||
process_object.port_list.append(port_object)
|
||||
except AttributeError:
|
||||
process_object.port_list = PortList()
|
||||
process_object.port_list.append(port_object)
|
||||
for key, feature in zip(('image', 'command-line'), ('file_name', 'command_line')):
|
||||
if key in attributes_dict:
|
||||
try:
|
||||
setattr(process_object.image_info, feature, attributes_dict[key])
|
||||
except AttributeError:
|
||||
process_object.image_info = ImageInfo()
|
||||
setattr(process_object.image_info, feature, attributes_dict[key][0])
|
||||
uuid = misp_object['uuid']
|
||||
process_object.parent.id_ = "{}:ProcessObject-{}".format(self.namespace_prefix, uuid)
|
||||
observable = Observable(process_object)
|
||||
|
|
|
@ -406,9 +406,14 @@ class StixParser():
|
|||
if properties.child_pid_list:
|
||||
for child in properties.child_pid_list:
|
||||
attributes.append(["text", child.value, "child-pid"])
|
||||
# if properties.port_list:
|
||||
# for port in properties.port_list:
|
||||
# attributes.append(["src-port", port.port_value.value, "port"])
|
||||
if properties.port_list:
|
||||
for port in properties.port_list:
|
||||
attributes.append(["port", port.port_value.value, "port"])
|
||||
if properties.image_info:
|
||||
if properties.image_info.file_name:
|
||||
attributes.append(["filename", properties.image_info.file_name.value, "image"])
|
||||
if properties.image_info.command_line:
|
||||
attributes.append(["text", properties.image_info.command_line.value, "command-line"])
|
||||
if properties.network_connection_list:
|
||||
references = []
|
||||
for connection in properties.network_connection_list:
|
||||
|
|
|
@ -3908,13 +3908,14 @@ function getFormInfoContent(property, field) {
|
|||
|
||||
function formCategoryChanged(id) {
|
||||
// fill in the types
|
||||
var options = $('#' + id +'Type').prop('options');
|
||||
$('option', $('#' + id +'Type')).remove();
|
||||
$.each(category_type_mapping[$('#' + id +'Category').val()], function(val, text) {
|
||||
var $type = $('#' + id + 'Type');
|
||||
var options = $type.prop('options');
|
||||
$('option', $type).remove();
|
||||
$.each(category_type_mapping[$('#' + id + 'Category').val()], function(val, text) {
|
||||
options[options.length] = new Option(text, val);
|
||||
});
|
||||
// enable the form element
|
||||
$('#AttributeType').prop('disabled', false);
|
||||
$type.prop('disabled', false);
|
||||
}
|
||||
|
||||
function malwareCheckboxSetter(context) {
|
||||
|
|
Loading…
Reference in New Issue