Merge branch 'feature/api_rework2' into 2.4

pull/3608/head
iglocska 2018-08-31 13:37:41 +02:00
commit 5f1edc9bad
10 changed files with 262 additions and 125 deletions

View File

@ -52,6 +52,7 @@ class AppController extends Controller
public $phprec = '7.0.16';
public $baseurl = '';
public $sql_dump = false;
// Used for _isAutomation(), a check that returns true if the controller & action combo matches an action that is a non-xml and non-json automation method
// This is used to allow authentication via headers for methods not covered by _isRest() - as that only checks for JSON and XML formats
@ -101,6 +102,9 @@ class AppController extends Controller
public function beforeFilter()
{
if (!empty($this->params['named']['sql'])) {
$this->sql_dump = 1;
}
// check for a supported datasource configuration
$dataSourceConfig = ConnectionManager::getDataSource('default')->config;
if (!isset($dataSourceConfig['encoding'])) {
@ -435,6 +439,14 @@ class AppController extends Controller
$this->ACL->checkAccess($this->Auth->user(), Inflector::variable($this->request->params['controller']), $this->action);
}
public function afterFilter()
{
if (Configure::read('debug') > 1 && !empty($this->sql_dump) && $this->_isRest()) {
$this->Log = ClassRegistry::init('Log');
echo json_encode($this->Log->getDataSource()->getLog(false, false), JSON_PRETTY_PRINT);
}
}
public function queryACL($debugType='findMissingFunctionNames', $content = false)
{
$this->autoRender = false;

View File

@ -118,7 +118,7 @@ class AttributesController extends AppController
foreach ($attribute['AttributeTag'] as $kat => $at) {
foreach ($tags as $ktag => $tag) {
if ($tag['Tag']['id'] == $at['tag_id']) {
$attributes[$k]['AttributeTag'][$kat]['Tag'] = $tag['Tag'];
$attributes[$k]['AttributeTag'][$kat]['Tag'] = $tag['Tag'];
}
}
}
@ -775,7 +775,7 @@ class AttributesController extends AppController
// 1/ iterate over all the sources, unique
// 2/ add uniques as 'Internal reference'
// 3/ if url format -> 'link'
// else 'comment'
// else 'comment'
$references = array();
foreach ($entries as $entry) {
if (empty($entry['Source'])) {
@ -2083,101 +2083,92 @@ class AttributesController extends AppController
}
public function restSearch($returnFormat = 'json', $value = false, $type = false, $category = false, $org = false, $tags = false, $from = false, $to = false, $last = false, $eventid = false, $withAttachments = false, $uuid = false, $publish_timestamp = false, $published = false, $timestamp = false, $enforceWarninglist = false, $to_ids = false, $deleted = false, $includeEventUuid = false, $event_timestamp = false, $threat_level_id = false) {
$paramArray = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'event_timestamp', 'threat_level_id');
$filterData = array(
'request' => $this->request,
'named_params' => $this->params['named'],
'paramArray' => $paramArray,
'ordered_url_params' => compact($paramArray)
);
$exception = false;
$filters = $this->_harvestParameters($filterData, $exception);
unset($filterData);
if ($filters === false) {
$paramArray = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'event_timestamp', 'threat_level_id');
$filterData = array(
'request' => $this->request,
'named_params' => $this->params['named'],
'paramArray' => $paramArray,
'ordered_url_params' => compact($paramArray)
);
$validFormats = array(
'openioc' => array('xml', 'OpeniocExport'),
'json' => array('json', 'JsonExport'),
'xml' => array('xml', 'XmlExport'),
'suricata' => array('txt', 'NidsSuricataExport'),
'snort' => array('txt', 'NidsSnortExport'),
'text' => array('txt', 'TextExport')
);
$exception = false;
$filters = $this->_harvestParameters($filterData, $exception);
unset($filterData);
if ($filters === false) {
return $exception;
}
$list = array();
$user = $this->_getApiAuthUser($returnFormat, $exception);
if ($user === false) {
}
$list = array();
$user = $this->_getApiAuthUser($returnFormat, $exception);
if ($user === false) {
return $exception;
}
if (isset($filters['returnFormat'])) {
}
if (isset($filters['returnFormat'])) {
$returnFormat = $filters['returnFormat'];
} else {
$returnFormat = 'json';
}
$conditions = $this->Attribute->buildFilterConditions($this->Auth->user(), $filters);
$params = array(
'conditions' => $conditions,
'fields' => array('Attribute.*', 'Event.org_id', 'Event.distribution'),
'withAttachments' => !empty($filters['withAttachments']) ? $filters['withAttachments'] : 0,
'enforceWarninglist' => !empty($filters['enforceWarninglist']) ? $filters['enforceWarninglist'] : 0,
'includeAllTags' => true,
'flatten' => 1,
'includeEventUuid' => !empty($filters['includeEventUuid']) ? $filters['includeEventUuid'] : 0,
);
if (!empty($filtes['deleted'])) {
$params['deleted'] = 1;
if ($params['deleted'] === 'only') {
$params['conditions']['AND'][] = array('Attribute.deleted' => 1);
$params['conditions']['AND'][] = array('Object.deleted' => 1);
}
}
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params);
$this->loadModel('Whitelist');
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
$validFormats = array(
'openioc' => 'OpeniocExport',
'json' => 'AttributeExport',
'xml' => 'AttributeExport'
);
$final = '';
App::uses($validFormats[$returnFormat], 'Export');
$exportTool = new $validFormats[$returnFormat]();
$exportToolParams = array(
'user' => $this->Auth->user(),
'params' => $params,
'returnFormat' => $returnFormat
);
$final .= $exportTool->header($exportToolParams);
$results = array_values($results);
foreach ($results as $k => $attribute) {
$final .= $exportTool->handler($attribute, $exportToolParams);
if ($k <= count($results)) {
$final .= $exportTool->separator($exportToolParams);
}
$conditions = $this->Attribute->buildFilterConditions($this->Auth->user(), $filters);
$params = array(
'conditions' => $conditions,
'fields' => array('Attribute.*', 'Event.org_id', 'Event.distribution'),
'withAttachments' => !empty($filters['withAttachments']) ? $filters['withAttachments'] : 0,
'enforceWarninglist' => !empty($filters['enforceWarninglist']) ? $filters['enforceWarninglist'] : 0,
'includeAllTags' => true,
'flatten' => 1,
'includeEventUuid' => !empty($filters['includeEventUuid']) ? $filters['includeEventUuid'] : 0,
);
if (!empty($filtes['deleted'])) {
$params['deleted'] = 1;
if ($params['deleted'] === 'only') {
$params['conditions']['AND'][] = array('Attribute.deleted' => 1);
$params['conditions']['AND'][] = array('Object.deleted' => 1);
}
}
App::uses($validFormats[$returnFormat][1], 'Export');
$exportTool = new $validFormats[$returnFormat][1]();
$exportToolParams = array(
'user' => $this->Auth->user(),
'params' => $params,
'returnFormat' => $returnFormat,
'scope' => 'Attribute'
);
if (!empty($exportTool->additional_params)) {
$params = array_merge($params, $exportTool->additional_params);
}
}
$final .= $exportTool->footer($exportToolParams);
/*
if ($returnFormat == 'openioc') {
App::uses('IOCExportTool', 'Tools');
$this->IOCExport = new IOCExportTool();
$results = $this->IOCExport->buildAll($this->Auth->user(), $results, 'attribute');
} else {
if (!empty($results)) {
$results = array('response' => array('Attribute' => $results));
foreach ($results['response']['Attribute'] as $k => $v) {
if (isset($results['response']['Attribute'][$k]['AttributeTag'])) {
foreach ($results['response']['Attribute'][$k]['AttributeTag'] as $tk => $tag) {
$results['response']['Attribute'][$k]['Attribute']['Tag'][$tk] = $tag['Tag'];
}
}
$results['response']['Attribute'][$k] = $results['response']['Attribute'][$k]['Attribute'];
unset(
$results['response']['Attribute'][$k]['value1'],
$results['response']['Attribute'][$k]['value2']
);
}
} else {
$results = array('response' => array('Attribute' => array()));
}
}
*/
$responseType = $this->response->type();
if ($returnFormat == 'openioc') {
$responseType = 'openioc';
}
return $this->RestResponse->viewData($final, $responseType, false, true);
$final = '';
$final .= $exportTool->header($exportToolParams);
$continue = false;
if (empty($params['limit'])) {
$params['limit'] = 10000;
$continue = true;
$params['page'] = 1;
}
$this->loadModel('Whitelist');
while ($continue) {
$results = $this->Attribute->fetchAttributes($this->Auth->user(), $params, $continue);
$params['page'] += 1;
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
$results = array_values($results);
$i = 0;
foreach ($results as $attribute) {
$temp = $exportTool->handler($attribute, $exportToolParams);
if ($temp !== '') {
$final .= $temp;
if ($i != count($results) -1) {
$final .= $exportTool->separator($exportToolParams);
}
}
$i++;
}
}
$final .= $exportTool->footer($exportToolParams);
$responseType = $validFormats[$returnFormat][0];
return $this->RestResponse->viewData($final, $responseType, false, true);
}
// returns an XML with attributes that belong to an event. The type of attributes to be returned can be restricted by type using the 3rd parameter.
@ -2229,7 +2220,7 @@ class AttributesController extends AppController
throw new UnauthorizedException(__('You don\'t have access to that event.'));
}
}
$this->response->type('xml'); // set the content type
$this->response->type('xml'); // set the content type
$this->layout = 'xml/default';
$this->header('Content-Disposition: download; filename="misp.search.attribute.results.xml"');
// check if user can see the event!
@ -2364,7 +2355,7 @@ class AttributesController extends AppController
throw new UnauthorizedException(__('You have to be logged in to do that.'));
}
}
$this->response->type('txt'); // set the content type
$this->response->type('txt'); // set the content type
$this->header('Content-Disposition: download; filename="misp.' . (is_array($type) ? 'multi' : $type) . '.txt"');
$this->layout = 'text/default';
$attributes = $this->Attribute->text($this->Auth->user(), $type, $tags, $eventId, $allowNonIDS, $from, $to, $last, $enforceWarninglist, $allowNotPublished);
@ -2458,7 +2449,7 @@ class AttributesController extends AppController
foreach ($eventIds as $k => $eventId) {
$values = array_merge_recursive($values, $this->Attribute->rpz($this->Auth->user(), $tags, $eventId, $from, $to, $enforceWarninglist));
}
$this->response->type('txt'); // set the content type
$this->response->type('txt'); // set the content type
$file = '';
if ($tags) {
$file = 'filtered.';

View File

@ -1635,15 +1635,9 @@ class ServersController extends AppController
private function __doRestQuery($request)
{
App::uses('SyncTool', 'Tools');
$params = array(
);
$params = array();
if (!empty($request['url'])) {
$path = parse_url($request['url'], PHP_URL_PATH);
$query = parse_url($request['url'], PHP_URL_QUERY);
if (!empty($query)) {
$path .= '?' . $query;
}
$path = preg_replace('#^(://|[^/?])+#', '', $request['url']);
$url = Configure::read('MISP.baseurl') . '/' . $path;
} else {
throw new InvalidArgumentException('Url not set.');

View File

@ -1,10 +1,23 @@
<?php
class AttributeExport
class JsonExport
{
public function handler($attribute, $options = array())
public function handler($data, $options = array())
{
if ($options['scope'] === 'Attribute') {
return $this->__attributeHandler($data, $options);
} else {
return $this->__eventHandler($data, $options);
}
}
private function __attributeHandler($attribute, $options = array())
{
$attribute = array_merge($attribute['Attribute'], $attribute);
unset($attribute['Attribute']);
if (isset($attribute['Object']) && empty($attribute['Object']['id'])) {
unset($attribute['Object']);
}
if (isset($attribute['AttributeTag'])) {
$attributeTags = array();
foreach ($attribute['AttributeTag'] as $tk => $tag) {
@ -15,7 +28,7 @@ class AttributeExport
unset($attribute['value2']);
}
return json_encode($attribute);
}
}
public function header($options = array())
{
@ -29,7 +42,7 @@ class AttributeExport
public function separator()
{
return ',' . PHP_EOL;
return ',';
}
}

View File

@ -8,6 +8,49 @@ class NidsExport
public $format = ""; // suricata (default), snort
public $checkWhitelist = true;
public $additional_params = array(
'contain' => array(
'Event' => array(
'fields' => array('threat_level_id')
)
)
);
public function handler($data, $options = array())
{
$continue = true;
$this->checkWhitelist = false;
if (empty($this->rules)) {
$continue = false;
}
if ($options['scope'] === 'Attribute') {
$this->export(
array($data),
$options['user']['nids_sid'],
$options['returnFormat'],
$continue
);
}
return '';
}
public function header($options = array())
{
return '';
}
public function footer()
{
return implode ("\n", $this->rules);
}
public function separator()
{
return '';
}
public function explain()
{
$this->rules[] = '# MISP export of IDS rules - optimized for '.$this->format;
@ -28,8 +71,10 @@ class NidsExport
public function export($items, $startSid, $format="suricata", $continue = false)
{
$this->format = $format;
$this->Whitelist = ClassRegistry::init('Whitelist');
$this->whitelist = $this->Whitelist->getBlockedValues();
if ($this->checkWhitelist && !isset($this->Whitelist)) {
$this->Whitelist = ClassRegistry::init('Whitelist');
$this->whitelist = $this->Whitelist->getBlockedValues();
}
// output a short explanation
if (!$continue) {
@ -105,7 +150,7 @@ class NidsExport
}
return $this->rules;
}
public function domainIpRule($ruleFormat, $attribute, &$sid)
{
$values = explode('|', $attribute['value']);
@ -558,11 +603,13 @@ class NidsExport
public function checkWhitelist($value)
{
foreach ($this->whitelist as $wlitem) {
if (preg_match($wlitem, $value)) {
return true;
}
}
if ($this->checkWhitelist) {
foreach ($this->whitelist as $wlitem) {
if (preg_match($wlitem, $value)) {
return true;
}
}
}
return false;
}

View File

@ -0,0 +1,27 @@
<?php
class TextExport
{
public function handler($data, $options = array())
{
if ($options['scope'] === 'Attribute') {
return $data['Attribute']['value'];
}
return '';
}
public function header($options = array())
{
return '';
}
public function footer()
{
return "\n";
}
public function separator()
{
return "\n";
}
}

View File

@ -0,0 +1,50 @@
<?php
class XmlExport
{
public function handler($data, $options = array())
{
if ($options['scope'] === 'Attribute') {
return $this->__attributeHandler($data, $options);
} else {
return $this->__eventHandler($data, $options);
}
}
private function __attributeHandler($attribute, $options = array())
{
$attribute = array_merge($attribute['Attribute'], $attribute);
unset($attribute['Event']);
unset($attribute['Attribute']);
if (isset($attribute['Object']) && empty($attribute['Object']['id'])) {
unset($attribute['Object']);
}
if (isset($attribute['AttributeTag'])) {
$attributeTags = array();
foreach ($attribute['AttributeTag'] as $tk => $tag) {
$attribute['Tag'][$tk] = $attribute['AttributeTag'][$tk]['Tag'];
}
unset($attribute['AttributeTag']);
unset($attribute['value1']);
unset($attribute['value2']);
}
$xmlObject = Xml::fromArray(array('Attribute' => $attribute), array('format' => 'tags'));
$xmlString = $xmlObject->asXML();
return substr($xmlString, strpos($xmlString, "\n") + 1);
}
public function header($options = array())
{
return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>';
}
public function footer()
{
return '</response>' . PHP_EOL;
}
public function separator()
{
return '';
}
}

View File

@ -1,4 +1,5 @@
<?php
class XMLConverterTool
{
private $__toEscape = array("&", "<", ">", "\"", "'");

View File

@ -2784,8 +2784,6 @@ class Attribute extends AppModel
}
if (isset($options['limit'])) {
$params['limit'] = $options['limit'];
} else {
$option['contain']['Event']['fields'] = array('id', 'info', 'org_id', 'orgc_id');
}
if (Configure::read('MISP.proposals_block_attributes') && isset($options['conditions']['AND']['Attribute.to_ids']) && $options['conditions']['AND']['Attribute.to_ids'] == 1) {
$this->bindModel(array('hasMany' => array('ShadowAttribute' => array('foreignKey' => 'old_id'))));

View File

@ -17,6 +17,8 @@ class Whitelist extends AppModel
),
);
public $whitelistedItems = false;
public $validate = array(
'name' => array(
'valueNotEmpty' => array(
@ -66,12 +68,14 @@ class Whitelist extends AppModel
public function getBlockedValues()
{
$Whitelists = $this->find('all', array('fields' => array('name')));
$toReturn = array();
foreach ($Whitelists as $item) {
$toReturn[] = $item['Whitelist']['name'];
}
return $toReturn;
if ($this->whitelistedItems !== false) {
$Whitelists = $this->find('all', array('fields' => array('name')));
$this->whitelistedItems = array();
foreach ($Whitelists as $item) {
$this->whitelistedItems[] = $item['Whitelist']['name'];
}
}
return $this->whitelistedItems;
}
public function removeWhitelistedFromArray($data, $isAttributeArray)