new: [SightingDB] Added integration with SightingDB

- Added configuration tool
- Added lookups from the event view
- Added includeSightingdb flag for the restSearch searches
- Added SightingDB search tool
- Added SightingDB connection test tool
pull/5390/head
iglocska 2019-11-06 21:20:04 +01:00
parent 48b30c5095
commit c4f1d4d15e
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
24 changed files with 1198 additions and 78 deletions

View File

@ -17,32 +17,16 @@ class CommunitiesController extends AppController
public function index()
{
$paramsToHarvest = array('context', 'value');
foreach ($paramsToHarvest as $param) {
if (!empty($this->params['named'][$param])) {
${$param} = $this->params['named'][$param];
} else if ($this->request->is('post') && !empty($this->request->data[$param])) {
${$param} = trim($this->request->data[$param]);
} else if ($param === 'context') {
${$param} = 'vetted';
}
}
$filterData = array(
'request' => $this->request,
'paramArray' => array('context', 'value'),
'named_params' => $this->params['named']
);
$exception = false;
$filters = $this->_harvestParameters($filterData, $exception);
$filters = $this->IndexFilter->harvestParameters(array('context', 'value'));
if (empty($filters['context'])) {
$filters['context'] = 'vetted';
}
if (!empty($value)) {
$value = strtolower($value);
if (!empty($filters['value'])) {
$filters['value'] = strtolower($filters['value']);
} else {
$value = false;
$filters['value'] = false;
}
$community_list = $this->Community->getCommunityList($context, $value);
$community_list = $this->Community->getCommunityList($filters['context'], $filters['value']);
//foreach ($community)
if ($this->_isRest()) {
@ -53,7 +37,6 @@ class CommunitiesController extends AppController
$customPagination->truncateAndPaginate($community_list, $this->params, $this->modelClass, true);
$this->set('community_list', $community_list);
$this->set('context', $filters['context']);
$this->set('passedArgs', json_encode($this->passedArgs, true));
}
public function view($id)

View File

@ -442,6 +442,14 @@ class ACLComponent extends Component
'viewSightings' => array('*'),
'quickAdd' => array('perm_sighting')
),
'sightingdb' => array(
'add' => array(),
'edit' => array(),
'delete' => array(),
'index' => array(),
'requestStatus' => array(),
'search' => array()
),
'tagCollections' => array(
'add' => array('perm_tag_editor'),
'addTag' => array('perm_tag_editor'),

View File

@ -25,8 +25,11 @@ class EventsController extends AppController
)
);
private $acceptedFilteringNamedParams = array('sort', 'direction', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'attributeFilter', 'extended', 'page',
'searchFor', 'proposal', 'correlation', 'warning', 'deleted', 'includeRelatedTags', 'includeDecayScore', 'distribution', 'taggedAttributes', 'galaxyAttachedAttributes', 'objectType', 'attributeType', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'feed', 'server', 'toIDS', 'sighting'
private $acceptedFilteringNamedParams = array(
'sort', 'direction', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'attributeFilter', 'extended', 'page',
'searchFor', 'proposal', 'correlation', 'warning', 'deleted', 'includeRelatedTags', 'includeDecayScore', 'distribution',
'taggedAttributes', 'galaxyAttachedAttributes', 'objectType', 'attributeType', 'focus', 'extended', 'overrideLimit',
'filterColumnsOverwrite', 'feed', 'server', 'toIDS', 'sighting', 'includeSightingdb'
);
public $defaultFilteringRules = array(
@ -1176,6 +1179,10 @@ class EventsController extends AppController
$sightingsData = $this->Event->getSightingData($event);
$this->set('sightingsData', $sightingsData);
$params = $this->Event->rearrangeEventForView($event, $filters, $all, $sightingsData);
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
$this->loadModel('Sightingdb');
$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();
@ -1229,6 +1236,7 @@ class EventsController extends AppController
if (isset($filters['deleted'])) {
$deleted = $filters['deleted'] == 2 ? 0 : 1;
}
$this->set('includeSightingdb', (!empty($filters['includeSightingdb'] && Configure::read('Plugin.Sightings_sighting_db_enable'))));
$this->set('deleted', $deleted);
$this->set('typeGroups', array_keys($this->Event->Attribute->typeGroupings));
$this->set('attributeFilter', isset($filters['attributeFilter']) ? $filters['attributeFilter'] : 'all');
@ -1250,6 +1258,9 @@ class EventsController extends AppController
}
$this->params->here = implode('/', $uriArray);
}
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($this->Auth->user()));
}
$this->set('sightingTypes', $this->Sighting->type);
$this->set('currentUri', $this->params->here);
$this->layout = false;
@ -1437,6 +1448,10 @@ class EventsController extends AppController
$sightingsData = $this->Event->getSightingData($event);
$this->set('sightingsData', $sightingsData);
$params = $this->Event->rearrangeEventForView($event, $filters, false, $sightingsData);
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
$this->loadModel('Sightingdb');
$event = $this->Sightingdb->attachToEvent($event, $this->Auth->user());
}
$this->params->params['paging'] = array($this->modelClass => $params);
$this->set('event', $event);
$dataForView = array(
@ -1516,6 +1531,10 @@ class EventsController extends AppController
$orgTable = $this->Event->Orgc->find('list', array(
'fields' => array('Orgc.id', 'Orgc.name')
));
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($this->Auth->user()));
}
$this->set('includeSightingdb', (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')));
$this->set('relatedEventCorrelationCount', $relatedEventCorrelationCount);
$this->set('oldest_timestamp', $oldest_timestamp);
$this->set('required_taxonomies', $this->Event->getRequiredTaxonomies());
@ -3417,7 +3436,7 @@ class EventsController extends AppController
'value', 'type', 'category', 'object_relation', 'org', 'tag', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments',
'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly', 'returnFormat',
'limit', 'page', 'requested_attributes', 'includeContext', 'headerless', 'includeWarninglistHits', 'attackGalaxy', 'deleted',
'excludeLocalTags', 'date'
'excludeLocalTags', 'date', 'includeSightingdb'
);
$filterData = array(
'request' => $this->request,

View File

@ -0,0 +1,224 @@
<?php
App::uses('AppController', 'Controller');
class SightingdbController extends AppController
{
public $components = array('Session', 'RequestHandler');
public $paginate = array(
'limit' => 60,
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
'order' => array(
'Sightingdb.id' => 'DESC'
),
'recursive' => -1,
'contain' => array('SightingdbOrg' => 'Organisation')
);
public function beforeFilter()
{
parent::beforeFilter();
$this->Security->unlockedActions = array('search');
}
public function add()
{
if ($this->request->is('post')) {
if (empty($this->request->data['Sightingdb'])) {
$this->request->data = array('Sightingdb' => $this->request->data);
}
$this->Sightingdb->create();
$result = $this->Sightingdb->save($this->request->data);
$message = $result ? __('SightingDB connection added.') : __('SightingDB connection could not be added.');
if ($result) {
if (isset($this->request->data['Sightingdb']['org_id'])) {
$this->Sightingdb->SightingdbOrg->resetOrgs($this->Sightingdb->id, $this->request->data['Sightingdb']['org_id']);
}
}
if ($this->_isRest()) {
if ($result) {
return $this->RestResponse->saveSuccessResponse('Sightingdb', 'add', $this->response->type(), $message);
} else {
return $this->RestResponse->saveFailResponse('Sightingdb', 'add', $message, $this->response->type());
}
} else {
if ($result) {
$this->Flash->success($message);
$this->redirect(array('action' => 'index'));
} else {
$message .= __(' Reason: %s', json_encode($this->Sightingdb->validationErrors, true));
$this->Flash->error($message);
}
}
}
$orgs = $this->Sightingdb->SightingdbOrg->Organisation->find('list', array(
'conditions' => array('Organisation.local' => 1),
'order' => array('LOWER(Organisation.name)'),
'fields' => array('Organisation.id', 'Organisation.name')
));
$this->set('orgs', $orgs);
}
public function edit($id)
{
$existingEntry = $this->Sightingdb->find('first', array(
'recursive' => -1,
'conditions' => array('Sightingdb.id' => $id),
'contain' => array('SightingdbOrg.org_id')
));
$existingEntry = $this->Sightingdb->extractOrgIds($existingEntry);
if (empty($id) || empty($existingEntry)) {
throw new NotFoundException(__('Invalid SightingDB entry.'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if (empty($this->request->data['Sightingdb'])) {
$this->request->data = array('Sightingdb' => $this->request->data);
}
$keys = array('host', 'port', 'description', 'name', 'owner', 'enabled', 'skip_proxy', 'ssl_skip_verification');
foreach ($keys as $key) {
if (!empty($this->request->data['Sightingdb'][$key])) {
$existingEntry['Sightingdb'][$key] = $this->request->data['Sightingdb'][$key];
}
}
$result = $this->Sightingdb->save($existingEntry);
if (isset($this->request->data['Sightingdb']['org_id'])) {
$this->Sightingdb->SightingdbOrg->resetOrgs($this->Sightingdb->id, $this->request->data['Sightingdb']['org_id']);
}
$message = $result ? __('SightingDB connection updated.') : __('SightingDB connection could not be updated.');
if ($this->_isRest()) {
if ($result) {
return $this->RestResponse->saveSuccessResponse('Sightingdb', 'edit', $id, $this->response->type(), $message);
} else {
return $this->RestResponse->saveFailResponse('Sightingdb', 'edit', $id, $message, $this->response->type());
}
} else {
if ($result) {
$this->Flash->success($message);
$this->redirect(array('action' => 'index'));
} else {
$message .= __(' Reason: %s', json_encode($this->Sightingdb->validationErrors, true));
$this->Flash->error($message);
}
}
} else {
$this->request->data = $existingEntry;
}
$orgs = $this->Sightingdb->SightingdbOrg->Organisation->find('list', array(
'conditions' => array('Organisation.local' => 1),
'order' => array('LOWER(Organisation.name)'),
'fields' => array('Organisation.id', 'Organisation.name')
));
$this->set('id', $id);
$this->set('orgs', $orgs);
$this->render('/Sightingdb/add');
}
public function delete($id)
{
$existingEntry = $this->Sightingdb->find('first', array(
'recursive' => -1,
'conditions' => array('Sightingdb.id' => $id)
));
if (empty($id) || empty($existingEntry)) {
throw new NotFoundException(__('Invalid SightingDB entry.'));
}
if ($this->request->is('post') || $this->request->is('delete')) {
$result = $this->Sightingdb->delete($existingEntry['Sightingdb']['id']);
if ($result) {
$message = __('SightingDB connection removed.');
} else {
$message = __('SightingDB connection could not be removed.');
}
if ($this->_isRest()) {
if ($result) {
return $this->RestResponse->saveSuccessResponse('Sightingdb', 'edit', $id, $this->response->type(), $message);
} else {
return $this->RestResponse->saveFailResponse('Sightingdb', 'edit', $id, $message, $this->response->type());
}
} else {
if ($result) {
$this->Flash->success($message);
$this->redirect(array('action' => 'index'));
} else {
$message .= __(' Reason: %s', json_encode($this->Sightingdb->validationErrors, true));
$this->Flash->error($message);
}
$this->redirect(array('action' => 'index'));
}
}
}
public function index()
{
$filters = $this->IndexFilter->harvestParameters(array('value'));
if (!empty($filters['value'])) {
if (is_array($filters['value'])) {
foreach ($filters['value'] as &$value) {
$value = '%' . strtolower($value) . '%';
}
} else {
$filters['value'] = '%' . strtolower($filters['value']) . '%';
}
$this->paginate['conditions']['AND'][] = array(
'OR' => array(
'Sightingdb.name LIKE' => $filters['value'],
'Sightingdb.owner LIKE' => $filters['value'],
'Sightingdb.host LIKE' => $filters['value']
)
);
}
if ($this->_isRest()) {
$params = array(
'contain' => $this->paginate['contain'],
'conditions' => empty($this->paginate['conditions']) ? array() : $this->paginate['conditions'],
);
$data = $this->Sightingdb->find('all', $params);
$data = $this->Sightingdb->extractOrgIdsFromList($data);
return $this->RestResponse->viewData($data, $this->response->type());
} else {
$this->set('data', $this->paginate());
}
}
public function requestStatus($id)
{
$result = $this->Sightingdb->requestStatus($id);
if (is_array($result)) {
return $this->RestResponse->viewData($result, $this->response->type());
} else {
return $this->RestResponse->saveFailResponse('Sightingdb', 'requestStatus', $id, $result, $this->response->type());
}
}
public function search($id)
{
if (empty($id)) {
throw new InvalidArgumentException(__('Pass a valid SightingDB ID'));
}
$sightingdb = $this->Sightingdb->find('first', array(
'recursive' => -1,
'conditions' => array('Sightingdb.id' => $id),
'contain' => array('SightingdbOrg')
));
if (empty($sightingdb)) {
throw new NotFoundException('Invalid sightingDB');
}
if (!empty($this->request->data['value'])) {
$requestValue = trim($this->request->data['value']);
$result = $this->Sightingdb->queryValues(array($requestValue => array()), $sightingdb);
if (!empty($result[$requestValue][$sightingdb['Sightingdb']['id']])) {
$result = $result[$requestValue][$sightingdb['Sightingdb']['id']];
$result = array(
'first_seen' => date('Y-m-d H:i:s', $result['first_seen']),
'last_seen' => date('Y-m-d H:i:s', $result['last_seen']),
'count' => $result['count']
);
} else {
$result = array('count' => 0);
}
} else {
$result = array('count' => 0);
}
return $this->RestResponse->viewData($result, $this->response->type());
}
}

View File

@ -35,7 +35,7 @@ class SyncTool
* @return HttpSocket
* @throws Exception
*/
private function createHttpSocket($params = array())
public function createHttpSocket($params = array())
{
// Use own CA PEM file
$caPath = Configure::read('MISP.ca_path');

View File

@ -76,7 +76,7 @@ class AppModel extends Model
21 => false, 22 => false, 23 => false, 24 => false, 25 => false, 26 => false,
27 => false, 28 => false, 29 => false, 30 => false, 31 => false, 32 => false,
33 => false, 34 => false, 35 => false, 36 => false, 37 => false, 38 => false,
39 => false, 40 => false, 41 => false
39 => false, 40 => false, 41 => false, 42 => false
);
public $advanced_updates_description = array(
@ -1268,6 +1268,33 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `roles` ADD `enforce_rate_limit` tinyint(1) NOT NULL DEFAULT 0;";
$sqlArray[] = "ALTER TABLE `roles` ADD `rate_limit_count` int(11) NOT NULL DEFAULT 0;";
break;
case 42:
$sqlArray[] = "CREATE TABLE IF NOT EXISTS sightingdbs (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` text,
`owner` varchar(255) DEFAULT '',
`host` varchar(255) DEFAULT 'http://localhost',
`port` int(11) DEFAULT 9999,
`timestamp` int(11) NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT 0,
`skip_proxy` tinyint(1) NOT NULL DEFAULT 0,
`ssl_skip_verification` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (id),
INDEX `name` (`name`),
INDEX `owner` (`owner`),
INDEX `host` (`host`),
INDEX `port` (`port`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
$sqlArray[] = "CREATE TABLE IF NOT EXISTS sightingdb_orgs (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sightingdb_id` int(11) NOT NULL,
`org_id` int(11) NOT NULL,
PRIMARY KEY (id),
INDEX `sightingdb_id` (`sightingdb_id`),
INDEX `org_id` (`org_id`)
) ENGINE=InnoDB;";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

View File

@ -4295,6 +4295,7 @@ class Attribute extends AppModel
'includeWarninglistHits' => !empty($filters['includeWarninglistHits']) ? $filters['includeWarninglistHits'] : 0,
'includeContext' => !empty($filters['includeContext']) ? $filters['includeContext'] : 0,
'includeSightings' => !empty($filters['includeSightings']) ? $filters['includeSightings'] : 0,
'includeSightingdb' => !empty($filters['includeSightingdb']) ? $filters['includeSightingdb'] : 0,
'includeCorrelations' => !empty($filters['includeCorrelations']) ? $filters['includeCorrelations'] : 0,
'includeDecayScore' => !empty($filters['includeDecayScore']) ? $filters['includeDecayScore'] : 0,
'includeFullModel' => !empty($filters['includeFullModel']) ? $filters['includeFullModel'] : 0,
@ -4378,6 +4379,10 @@ class Attribute extends AppModel
while ($continue) {
$this->Whitelist = ClassRegistry::init('Whitelist');
$results = $this->fetchAttributes($user, $params, $continue);
if ($params['includeSightingdb']) {
$this->Sightingdb = ClassRegistry::init('Sightingdb');
$results = $this->Sightingdb->attachToAttributes($results, $user);
}
$params['page'] += 1;
$results = $this->Whitelist->removeWhitelistedFromArray($results, true);
$results = array_values($results);

View File

@ -1827,7 +1827,8 @@ class Event extends AppModel
'excludeGalaxy',
'includeRelatedTags',
'excludeLocalTags',
'includeDecayScore'
'includeDecayScore',
'includeSightingdb'
);
if (!isset($options['excludeLocalTags']) && !empty($user['Role']['perm_sync']) && empty($user['Role']['perm_site_admin'])) {
$options['excludeLocalTags'] = 1;
@ -2270,6 +2271,10 @@ class Event extends AppModel
$event['ShadowAttribute'] = $this->Feed->attachFeedCorrelations($event['ShadowAttribute'], $user, $event['Event'], $overrideLimit, 'Server');
}
$event['Sighting'] = $this->Sighting->attachToEvent($event, $user);
if ($options['includeSightingdb']) {
$this->Sightingdb = ClassRegistry::init('Sightingdb');
$event = $this->Sightingdb->attachToEvent($event, $user);
}
// remove proposals to attributes that we cannot see
// if the shadow attribute wasn't moved within an attribute before, this is the case
if (isset($event['ShadowAttribute'])) {

View File

@ -1857,6 +1857,14 @@ class Server extends AppModel
'test' => 'testForNumeric',
'type' => 'numeric'
),
'Sightings_sighting_db_enable' => array(
'level' => 1,
'description' => __('Enable SightingDB integration.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'CustomAuth_enable' => array(
'level' => 2,
'description' => __('Enable this functionality if you would like to handle the authentication via an external tool and authenticate with MISP using a custom header.'),

View File

@ -272,6 +272,71 @@ class Sighting extends AppModel
return $sightings;
}
/*
* Loop through all attributes of an event, including those in objects
* and pass each value to SightingDB. If there's a hit, append the data
* directly to the attributes
*/
public function attachSightingDB($event, $user)
{
if (!empty(Configure::read('Plugin.Sightings_sighting_db_enable'))) {
$host = empty(Configure::read('Plugin.Sightings_sighting_db_host')) ? 'localhost' : Configure::read('Plugin.Sightings_sighting_db_host');
$port = empty(Configure::read('Plugin.Sightings_sighting_db_port')) ? 9999 : Configure::read('Plugin.Sightings_sighting_db_port');
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$params = array(
'ssl_verify_peer' => false,
'ssl_verify_peer_name' => false,
'ssl_verify_host' => false
);
$HttpSocket = $syncTool->createHttpSocket($params);
if (!empty($event['Attribute'])) {
$event['Attribute'] = $this->__attachSightingDBToAttribute($event['Attribute'], $user, $host, $port, $HttpSocket);
}
if (!empty($event['Object'])) {
foreach ($event['Object'] as &$object) {
if (!empty($object['Attribute'])) {
$object['Attribute'] = $this->__attachSightingDBToAttribute($object['Attribute'], $user, $host, $port, $HttpSocket);
}
}
}
}
return $event;
}
private function __attachSightingDBToAttribute($attributes, $user, $host, $port, $HttpSocket = false)
{
if (empty($HttpSocket)) {
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$params = array(
'ssl_allow_self_signed' => true,
'ssl_verify_peer' => false
);
$HttpSocket = $syncTool->createHttpSocket($params);
}
foreach($attributes as &$attribute) {
$response = $HttpSocket->get(
sprintf(
'%s:%s/r/all/%s?val=%s',
$host,
$port,
$attribute['type'],
rtrim(str_replace('/', '_', str_replace('+', '-', base64_encode($attribute['value']))), '=')
)
);
if ($response->code == 200) {
$responseData = json_decode($response->body, true);
if ($responseData !== false) {
if (!isset($responseData['error'])) {
$attribute['SightingDB'] = $responseData;
}
}
}
}
return $attributes;
}
public function saveSightings($id, $values, $timestamp, $user, $type = false, $source = false, $sighting_uuid = false)
{
$conditions = array();

376
app/Model/Sightingdb.php Normal file
View File

@ -0,0 +1,376 @@
<?php
App::uses('AppModel', 'Model');
App::uses('ConnectionManager', 'Model');
App::uses('Sanitize', 'Utility');
class Sightingdb extends AppModel
{
public $errors = array(
1 => 'Invalid SightingDB.',
2 => 'No response from SightingDB.',
3 => 'Invalid or unexpected response from SightingDB.',
4 => 'DNS error - name resolution error.',
5 => 'Could not connect to the SightingDB. Error unspecified.'
);
public $actsAs = array(
'SysLogLogable.SysLogLogable' => array(
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'),
'Trim',
'Containable',
);
public $validate = array(
'name' => array(
'notBlank' => array(
'rule' => array('notBlank'),
'required' => array('create'),
'message' => 'Name not set.'
)
),
'host' => array(
'notBlank' => array(
'rule' => array('notBlank'),
'required' => array('create'),
'message' => 'Host not set.'
)
),
'port' => array(
'numeric' => array(
'rule' => array('numeric'),
'message' => 'Port needs to be numeric.'
)
),
'owner' => array(
'notBlank' => array(
'rule' => array('notBlank'),
'required' => array('create'),
'message' => 'Owner not set.'
)
)
);
public $hasMany = array(
'SightingdbOrg' => array(
'className' => 'SightingdbOrg',
'foreignKey' => 'sightingdb_id',
'dependent' => true
)
);
private $__sightingdbs = false;
private $__connectionStatus = array();
/*
* Load all sightingDBs into a persistent array
* Helps with repeated lookups
*/
private function __loadSightingdbs($user)
{
$this->__sightingdbs = $this->find('all', array(
'recursive' => -1,
'contain' => array('SightingdbOrg'),
'conditions' => array('Sightingdb.enabled' => 1)
));
$this->__sightingdbs = $this->extractOrgIdsFromList($this->__sightingdbs);
foreach ($this->__sightingdbs as $k => $sightingdb) {
if (
empty($user['Role']['perm_site_admin']) &&
!empty($sightingdb['Sightingdb']['org_id']) &&
!in_array($user['org_id'], $sightingdb['Sightingdb']['org_id'])
) {
unset($this->__sightingdbs[$k]);
}
if (empty($this->__connectionStatus[$sightingdb['Sightingdb']['id']])) {
$this->__connectionStatus[$sightingdb['Sightingdb']['id']] = $this->requestStatus($sightingdb);
}
if (!is_array($this->__connectionStatus[$sightingdb['Sightingdb']['id']])) {
unset($this->__sightingdbs[$k]);
}
}
$this->__sightingdbs = array_values($this->__sightingdbs);
}
/*
* Loop through a list of attributes, and pass each value to SightingDB.
* If there's a hit, append the data directly to the attributes
*/
public function attachToAttributes($attributes, $user)
{
if (!empty(Configure::read('Plugin.Sightings_sighting_db_enable'))) {
if ($this->__sightingdbs === false) {
$this->__loadSightingdbs($user);
}
if (!empty($this->__sightingdbs)) {
$values = array();
foreach ($attributes as $attribute) {
$values[$attribute['Attribute']['value']] = array();
}
foreach ($this->__sightingdbs as $sightingdb) {
$values = $this->queryValues($values, $sightingdb);
}
foreach ($attributes as &$attribute) {
if (!empty($values[$attribute['Attribute']['value']])) {
$attribute['Attribute']['Sightingdb'] = array_values($values[$attribute['Attribute']['value']]);
}
}
}
}
return $attributes;
}
/*
* Loop through all attributes of an event, including those in objects
* and pass each value to SightingDB. If there's a hit, append the data
* directly to the attributes
*/
public function attachToEvent($event, $user)
{
if (!empty(Configure::read('Plugin.Sightings_sighting_db_enable'))) {
if ($this->__sightingdbs === false) {
$this->__loadSightingdbs($user);
}
if (!empty($this->__sightingdbs)) {
$values = $this->__collectValues($event);
foreach ($this->__sightingdbs as $sightingdb) {
$values = $this->queryValues($values, $sightingdb);
}
$event = $this->__attachValuesToEvent($event, $values);
}
}
return $event;
}
/*
* Extract all attribute values from an event.
* Also accepts the meta format from after pagination
*/
private function __collectValues($event)
{
$values = array();
if (!empty($event['Attribute'])) {
foreach ($event['Attribute'] as $attribute) {
$values[$attribute['value']] = array();
}
}
if (!empty($event['Object'])) {
foreach ($event['Object'] as $object) {
if (!empty($object['Attribute'])) {
foreach ($object['Attribute'] as $attribute) {
$values[$attribute['value']] = array();
}
}
}
}
if (!empty($event['objects'])) {
foreach ($event['objects'] as $object) {
if ($object['objectType'] === 'attribute') {
$values[$object['value']] = array();
} else if ($object['objectType'] === 'object') {
foreach ($object['Attribute'] as $attribute) {
$values[$attribute['value']] = array();
}
}
}
}
return $values;
}
/*
* Reattach the sightingDB results where applicable to all attriutes in an event
*/
private function __attachValuesToEvent($event, $values)
{
if (!empty($event['Attribute'])) {
foreach ($event['Attribute'] as &$attribute) {
if (!empty($values[$attribute['value']])) {
$attribute['Sightingdb'] = array_values($values[$attribute['value']]);
}
}
}
if (!empty($event['Object'])) {
foreach ($event['Object'] as &$object) {
if (!empty($object['Attribute'])) {
foreach ($object['Attribute'] as &$attribute) {
if (!empty($values[$attribute['value']])) {
$attribute['Sightingdb'] = array_values($values[$attribute['value']]);
}
}
}
}
}
if (!empty($event['objects'])) {
foreach ($event['objects'] as &$object) {
if ($object['objectType'] === 'attribute') {
if (!empty($values[$object['value']])) {
$object['Sightingdb'] = array_values($values[$object['value']]);
}
} else if ($object['objectType'] === 'object') {
foreach ($object['Attribute'] as &$attribute) {
if (!empty($values[$attribute['value']])) {
$attribute['Sightingdb'] = array_values($values[$attribute['value']]);
}
}
}
}
}
return $event;
}
/*
* Query the sightingDB for each value extracted
*/
public function queryValues($values, $sightingdb)
{
$host = $sightingdb['Sightingdb']['host'];
$port = $sightingdb['Sightingdb']['port'];
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$params = array(
'ssl_verify_peer' => empty($sightingdb['Sightingdb']['ssl_skip_verification']),
'ssl_verify_peer_name' => empty($sightingdb['Sightingdb']['ssl_skip_verification']),
'ssl_verify_host' => empty($sightingdb['Sightingdb']['ssl_skip_verification']),
'skip_proxy' => !empty($sightingdb['Sightingdb']['skip_proxy'])
);
$HttpSocket = $syncTool->createHttpSocket($params);
foreach ($values as $k => $value) {
try {
$response = $HttpSocket->get(
sprintf(
'%s:%s/r/all?val=%s',
$host,
$port,
hash('sha256', $k)
)
);
} catch (Exception $e) {
return $values;
}
if ($response->code == 200) {
$responseData = json_decode($response->body, true);
if ($responseData !== false && empty($responseData['error'])) {
$values[$k][$sightingdb['Sightingdb']['id']] = array(
'first_seen' => $responseData['first_seen'],
'last_seen' => $responseData['last_seen'],
'count' => $responseData['count'],
'sightingdb_id' => $sightingdb['Sightingdb']['id']
);
}
}
}
return $values;
}
/*
* Extract the org IDs from the sightingdbOrg objects and attach them to a simple list
*/
public function extractOrgIdsFromList($data)
{
foreach ($data as &$element) {
$element = $this->extractOrgIds($element);
}
return $data;
}
public function extractOrgIds($element)
{
if (isset($element['SightingdbOrg'])) {
$element['Sightingdb']['org_id'] = Hash::extract($element['SightingdbOrg'], '{n}.org_id');
unset($element['SightingdbOrg']);
}
return $element;
}
/*
* Query the SightingDB, returning:
* - implementation
* - version
* - vendor
* - author
* - measured response time
*/
public function requestStatus($sightingdb)
{
if (!is_array($sightingdb)) {
$sightingdb = $this->find('first', array(
'conditions' => array('Sightingdb.id' => $sightingdb),
'recursive' => -1
));
}
if (empty($sightingdb)) {
return __('Invalid SightingDB entry.');
}
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
$params = array(
'ssl_allow_self_signed' => true,
'ssl_verify_peer' => false,
'ssl_verify_peer_name' => false
);
$HttpSocket = $syncTool->createHttpSocket($params);
$start = microtime(true);
try {
$response = $HttpSocket->get(
sprintf(
'%s:%s/i',
$sightingdb['Sightingdb']['host'],
$sightingdb['Sightingdb']['port']
)
);
} catch (Exception $e) {
if (strpos($e->getMessage(), 'php_network_getaddresses') !== false) {
return __('Could not resolve Sightingdb address.');
} else {
return __('Something went wrong. Could not contact the SightingDB server.');
}
}
$response_time = round(1000*(microtime(true) - $start));
if ($response->code == 200) {
$responseData = json_decode($response->body, true);
if (!empty($responseData['implementation'])) {
$result = array();
$fields = array('implementation', 'version', 'vendor', 'author');
foreach ($fields as $field) {
$result[$field] = $responseData[$field];
}
$result['response_time'] = $response_time . 'ms';
return $result;
} else {
return __('The SightingDB returned an invalid response.');
}
} else {
return __('No response from the SightingDB server.');
}
}
/*
* Get a list of all valid sightingDBs for the user
*/
public function getSightingdbList($user)
{
$sightingdbs = $this->find('all', array(
'recursive' => -1,
'contain' => 'SightingdbOrg',
'conditions' => array('Sightingdb.enabled' => 1)
));
if (empty($sightingdbs)) {
return array();
}
$sightingdbs = $this->extractOrgIdsFromList($sightingdbs);
$toReturn = array();
foreach ($sightingdbs as $sightingdb) {
if (
!empty($user['Role']['perm_site_admin']) ||
empty($sightingdb['Sightingdb']['org_id']) ||
in_array($user['org_id'], $sightingdb['Sightingdb']['org_id']
)) {
$toReturn[$sightingdb['Sightingdb']['id']] = $sightingdb;
}
}
return $toReturn;
}
}

View File

@ -0,0 +1,57 @@
<?php
App::uses('AppModel', 'Model');
App::uses('ConnectionManager', 'Model');
App::uses('Sanitize', 'Utility');
class SightingdbOrg extends AppModel
{
public $belongsTo = array(
'Sightingdb' => array(
'className' => 'Sightingdb',
'foreignKey' => 'sightingdb_id'
),
'Organisation' => array(
'className' => 'Organisation',
'foreignKey' => 'org_id'
)
);
public $actsAs = array(
'SysLogLogable.SysLogLogable' => array(
'userModel' => 'User',
'userKey' => 'user_id',
'change' => 'full'),
'Trim',
'Containable',
);
public function resetOrgs($sightingdbId, $org_ids)
{
$sightingdb = $this->Sightingdb->find('first', array(
'conditions' => array('Sightingdb.id' => $sightingdbId),
'recursive' => -1
));
if (empty($sightingdb)) {
return false;
}
$this->deleteAll(array('SightingdbOrg.sightingdb_id' => $sightingdbId));
if (!empty($org_ids)) {
if (!is_array($org_ids)) {
$org_ids = explode(',', $org_ids);
}
foreach ($org_ids as $org_id) {
debug($org_id);
$this->create();
$this->save(
array(
'SightingdbOrg' => array(
'sightingdb_id' => $sightingdbId,
'org_id' => $org_id
)
)
);
}
}
return true;
}
}

View File

@ -318,44 +318,54 @@
</ul>
</td>
<td class="short">
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_placeholder" class = "inline-field-placeholder"></div>
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_solid" class="inline-field-solid">
<input type="checkbox" class="toids-toggle" id="toids_toggle_<?php echo h($object['id']); ?>" data-attribute-id="<?php echo h($object['id']); ?>" aria-label="<?php echo __('Toggle IDS flag');?>" title="<?php echo __('Toggle IDS flag');?>" <?php echo $object['to_ids'] ? 'checked' : ''; ?> >
</div>
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_placeholder" class = "inline-field-placeholder"></div>
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_solid" class="inline-field-solid">
<input type="checkbox" class="toids-toggle" id="toids_toggle_<?php echo h($object['id']); ?>" data-attribute-id="<?php echo h($object['id']); ?>" aria-label="<?php echo __('Toggle IDS flag');?>" title="<?php echo __('Toggle IDS flag');?>" <?php echo $object['to_ids'] ? 'checked' : ''; ?> >
</div>
</td>
<td class="short" onmouseenter="quickEditHover(this, '<?php echo $editScope; ?>', '<?php echo $object['id']; ?>', 'distribution', <?php echo $event['Event']['id'];?>);">
<?php
$turnRed = '';
if ($object['distribution'] == 0) $turnRed = 'style="color:red"';
?>
<div id = "Attribute_<?php echo $object['id']; ?>_distribution_placeholder" class = "inline-field-placeholder"></div>
<div id = "Attribute_<?php echo $object['id']; ?>_distribution_solid" <?php echo $turnRed; ?> class="inline-field-solid">
<?php
if ($object['distribution'] == 4):
$turnRed = '';
if ($object['distribution'] == 0) {
$turnRed = 'style="color:red"';
}
?>
<a href="/sharing_groups/view/<?php echo h($object['sharing_group_id']); ?>"><?php echo h($object['SharingGroup']['name']);?></a>
<?php
else:
echo h($shortDist[$object['distribution']]);
endif;
?>
</div>
<div id = "Attribute_<?php echo $object['id']; ?>_distribution_placeholder" class = "inline-field-placeholder"></div>
<div id = "Attribute_<?php echo $object['id']; ?>_distribution_solid" <?php echo $turnRed; ?> class="inline-field-solid">
<?php
if ($object['distribution'] == 4):
?>
<a href="/sharing_groups/view/<?php echo h($object['sharing_group_id']); ?>"><?php echo h($object['SharingGroup']['name']);?></a>
<?php
else:
echo h($shortDist[$object['distribution']]);
endif;
?>
</div>
</td>
<?php
echo $this->element('/Events/View/sighting_field', array(
'object' => $object,
'tr_class' => $tr_class,
'page' => $page
));
?>
<?php if (!empty($includeDecayScore)): ?>
<td class="decayingScoreField">
<div id = "Attribute_<?php echo h($object['id']); ?>_score_solid" class="inline-field-solid">
<?php echo $this->element('DecayingModels/View/attribute_decay_score', array('scope' => 'object', 'object' => $object, 'uselink' => true)); ?>
</div>
</td>
<?php endif; ?>
<td class="short action-links">
<?php
echo $this->element('/Events/View/sighting_field', array(
'object' => $object,
'tr_class' => $tr_class,
'page' => $page
));
if (!empty($includeSightingdb)) {
echo $this->element('/Events/View/sightingdb_field', array(
'object' => $object,
'tr_class' => $tr_class,
'page' => $page
));
}
if (!empty($includeDecayScore)): ?>
<td class="decayingScoreField">
<div id = "Attribute_<?php echo h($object['id']); ?>_score_solid" class="inline-field-solid">
<?php echo $this->element('DecayingModels/View/attribute_decay_score', array('scope' => 'object', 'object' => $object, 'uselink' => true)); ?>
</div>
</td>
<?php
endif;
?>
<td class="short action-links">
<?php
if ($object['deleted']):
if ($isSiteAdmin || $mayModify):

View File

@ -112,19 +112,24 @@
</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<?php if (!empty($includeDecayScore)): ?>
<td class="decayingScoreField">&nbsp;</td>
<?php endif; ?>
<?php
$paddedFields = array('includeSightingdb', 'includeDecayScore');
foreach ($paddedFields as $paddedField) {
if (!empty(${$paddedField})) {
echo '<td>&nbsp;</td>';
}
}
?>
<td class="short action-links">
<?php
if ($mayModify && empty($object['deleted'])) {
echo sprintf(
'<a href="%s/objects/edit/%s" title="Edit" aria-label="Edit" class="fa fa-edit icon-white useCursorPointer"></a>',
'<a href="%s/objects/edit/%s" title="Edit" aria-label="Edit" class="fa fa-edit white useCursorPointer"></a>',
$baseurl,
h($object['id'])
);
echo sprintf(
'<span class="fa fa-trash icon-white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
'<span class="fa fa-trash white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
(empty($event['Event']['publish_timestamp']) ? __('Permanently delete object') : __('Soft delete object')),
sprintf(
'deleteObject(\'objects\', \'delete\', \'%s\', \'%s\');',

View File

@ -174,9 +174,14 @@
<td class="shortish">&nbsp;</td>
<td class="shortish">&nbsp;</td>
<td class="short">&nbsp;</td>
<?php if (!empty($includeDecayScore)): ?>
<td class="decayingScoreField">&nbsp;</td>
<?php endif; ?>
<?php
$paddedFields = array('includeSightingdb', 'includeDecayScore');
foreach ($paddedFields as $paddedField) {
if (!empty(${$paddedField})) {
echo '<td>&nbsp;</td>';
}
}
?>
<td class="short action-links">
<?php
if (($event['Orgc']['id'] == $me['org_id'] && $mayModify) || $isSiteAdmin) {
@ -188,7 +193,7 @@
}
if (($event['Orgc']['id'] == $me['org_id'] && $mayModify) || $isSiteAdmin || ($object['org_id'] == $me['org_id'])) {
?>
<span class="fa fa-trash icon-white useCursorPointer" title="<?php echo __('Discard proposal');?>" role="button" tabindex="0" aria-label="<?php echo __('Discard proposal');?>" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<span class="fa fa-trash white useCursorPointer" title="<?php echo __('Discard proposal');?>" role="button" tabindex="0" aria-label="<?php echo __('Discard proposal');?>" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<?php
}
?>

View File

@ -79,7 +79,7 @@
}
if (($event['Orgc']['id'] == $me['org_id'] && $mayModify) || $isSiteAdmin || ($object['org_id'] == $me['org_id'])) {
?>
<span class="fa fa-trash icon-white useCursorPointer" title="<?php echo __('Discard proposal');?>" role="button" tabindex="0" aria-label="<?php echo __('Discard proposal');?>" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<span class="fa fa-trash white useCursorPointer" title="<?php echo __('Discard proposal');?>" role="button" tabindex="0" aria-label="<?php echo __('Discard proposal');?>" onClick="deleteObject('shadow_attributes', 'discard' ,'<?php echo $object['id']; ?>', '<?php echo $event['Event']['id']; ?>');"></span>
<?php
}
?>

View File

@ -0,0 +1,33 @@
<?php
$hits = array();
if (!empty($object['Sightingdb'])) {
foreach ($object['Sightingdb'] as $sightingdb_hit) {
$popover = array();
$popoverData = array(
'SightingDB' => $sightingdbs[$sightingdb_hit['sightingdb_id']]['Sightingdb']['name'],
'Count' => $sightingdb_hit['count'],
'First seen' => date('Y-m-d H:i:s', $sightingdb_hit['first_seen']),
'Last seen' => date('Y-m-d H:i:s', $sightingdb_hit['last_seen']),
'SightingDB owner' => $sightingdbs[$sightingdb_hit['sightingdb_id']]['Sightingdb']['owner'],
'SightingDB description' => $sightingdbs[$sightingdb_hit['sightingdb_id']]['Sightingdb']['description']
);
foreach ($popoverData as $k => $v) {
$popover[] = sprintf(
'<span class="bold black">%s</span>: <span class="blue">%s</span>',
h($k),
h($v)
);
}
$hits[] = sprintf(
'<span data-toggle="popover" data-content="%s" data-trigger="hover" data-placement="left"><span class="blue bold">%s</span>: %s</span>',
implode('<br />', h($popover)),
h($sightingdbs[$sightingdb_hit['sightingdb_id']]['Sightingdb']['name']),
h($sightingdb_hit['count'])
);
}
}
echo sprintf(
'<td class="short">%s</td>',
implode('<br />', $hits)
);
?>

View File

@ -163,10 +163,23 @@
<th title="<?php echo $attrDescriptions['distribution']['desc'];?>"><?php echo $this->Paginator->sort('distribution');?></th>
<th><?php echo __('Sightings');?></th>
<th><?php echo __('Activity');?></th>
<?php if ($includeDecayScore): ?>
<th class="decayingScoreField" title="<?php echo __('Decaying Score');?>"><?php echo __('Score');?></th>
<?php $fieldCount += 1; ?>
<?php endif; ?>
<?php
if ($includeSightingdb) {
echo sprintf(
'<th>%s</th>',
__('SightingDB')
);
$fieldCount += 1;
}
if ($includeDecayScore) {
sprintf(
'<th class="decayingScoreField" title="%s">%s</th>',
__('Decaying Score'),
__('Score')
);
$fieldCount += 1;
}
?>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php
@ -187,7 +200,8 @@
'page' => $page,
'fieldCount' => $fieldCount,
'includeRelatedTags' => !empty($includeRelatedTags) ? 1 : 0,
'includeDecayingScore' => !empty($includeDecayingScore) ? 1 : 0
'includeDecayingScore' => !empty($includeDecayingScore) ? 1 : 0,
'includeSightingdb' => !empty($includeSightingdb) ? 1 : 0
));
if (!empty($focus) && ($object['objectType'] == 'object' || $object['objectType'] == 'attribute') && $object['uuid'] == $focus) {
$focusedRow = $k;

View File

@ -100,7 +100,7 @@
'id' => 'multi-accept-button',
'title' => __('Accept selected Proposals'),
'class' => 'mass-proposal-select hidden',
'fa-icon' => 'check-circl',
'fa-icon' => 'check-circle',
'onClick' => 'multiSelectAction',
'onClickParams' => array($event['Event']['id'], 'acceptProposals')
),
@ -177,6 +177,15 @@
'onClick' => 'toggleBoolFilter',
'onClickParams' => array($urlHere, 'includeDecayScore')
),
array(
'id' => 'show_attribute_sightingdb',
'title' => __('Show SightingDB lookup results'),
'fa-icon' => 'binoculars',
'text' => __('SightingDB'),
'active' => empty($includeSightingdb) ? false : true,
'onClick' => 'toggleBoolFilter',
'onClickParams' => array($urlHere, 'includeSightingdb')
),
array(
'id' => 'show_attribute_context',
'title' => __('Show attribute context fields'),

View File

@ -261,6 +261,16 @@
'url' => '/feeds/searchCaches',
'requirement' => ($isSiteAdmin || $hostOrgUser)
),
array(
'text' => __('List SightingDB Connections'),
'url' => '/sightingdb/index',
'requirement' => ($isSiteAdmin)
),
array(
'text' => __('Add SightingDB Connection'),
'url' => '/sightingdb/add',
'requirement' => ($isSiteAdmin)
),
array(
'text' => __('List Communities'),
'url' => '/communities/index',

View File

@ -0,0 +1,69 @@
<?php
$modelForForm = 'Sightingdb';
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => __('Add SightingDB connection'),
'model' => 'Sightingdb',
'fields' => array(
array(
'field' => 'org_id',
'class' => 'org-id-picker-hidden-field',
'type' => 'text',
'hidden' => true
),
array(
'field' => 'name',
'class' => 'input-xxlarge'
),
array(
'field' => 'host',
'class' => 'input-xxlarge'
),
array(
'field' => 'port',
'class' => 'input'
),
array(
'field' => 'owner',
'class' => 'input-xxlarge'
),
array(
'field' => 'description',
'class' => 'input-xxlarge',
'type' => 'textarea'
),
array(
'field' => 'host_id',
'type' => 'hidden'
),
array(
'field' => 'enabled',
'type' => 'checkbox',
'default' => true
),
array(
'field' => 'skip_proxy',
'type' => 'checkbox',
'default' => false
),
array(
'field' => 'ssl_skip_verification',
'label' => 'Skip SSL verification',
'type' => 'checkbox',
'default' => false
)
),
'metaFields' => array(
$this->element('genericElements/org_picker', array('orgs' => $orgs, 'modelForForm' => $modelForForm))
),
'submit' => array(
'action' => $this->request->params['action']
)
)
));
?>
</div>
<?php
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'sightingdb', 'menuItem' => $this->request->params['action']));
?>

View File

@ -0,0 +1,133 @@
<?php
echo '<div class="index">';
echo $this->element('/genericElements/IndexTable/index_table', array(
'data' => array(
'data' => $data,
'top_bar' => array(
'children' => array(
array(
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value'
)
)
),
'fields' => array(
array(
'name' => __('Enabled'),
'sort' => 'Sightingdb.enabled',
'element' => 'boolean',
'class' => 'short',
'data_path' => 'Sightingdb.enabled'
),
array(
'name' => __('Id'),
'sort' => 'id',
'class' => 'short',
'data_path' => 'Sightingdb.id'
),
array(
'name' => __('Test'),
'class' => 'short',
'element' => 'tester',
'button' => __('Run'),
'button_class' => 'btn-mini btn-inverse',
'url' => '/sightingdb/requestStatus/',
'data_path' => 'Sightingdb.id'
),
array(
'name' => __('Quick Search'),
'class' => 'short',
'element' => 'tester',
'textInput' => 1,
'button_icon' => 'search',
'button_class' => 'btn-mini btn-inverse',
'url' => '/sightingdb/search/',
'data_path' => 'Sightingdb.id'
),
array(
'name' => __('Name'),
'data_path' => 'Sightingdb.name'
),
array(
'name' => __('Owner'),
'sort' => 'owner',
'class' => 'short',
'data_path' => 'Sightingdb.owner'
),
array(
'name' => __('Host'),
'sort' => 'host',
'data_path' => 'Sightingdb.host'
),
array(
'name' => __('Port'),
'class' => 'short',
'data_path' => 'Sightingdb.port'
),
array(
'name' => __('Skip Proxy'),
'class' => 'short',
'element' => 'boolean',
'data_path' => 'Sightingdb.skip_proxy'
),
array(
'name' => __('Skip SSL'),
'class' => 'short',
'element' => 'boolean',
'data_path' => 'Sightingdb.ssl_skip_verification'
),
array(
'name' => __('Description'),
'data_path' => 'Sightingdb.description'
),
array(
'name' => __('Restricted to'),
'class' => 'short',
'element' => 'org',
'data_path' => 'SightingdbOrg.{n}.Organisation'
)
),
'title' => __('SightingDB index'),
'description' => __('SightingDB is an alternate sighting database that MISP interconnects with. Configure connections to sighting databases below.'),
'actions' => array(
array(
'url' => '/sightingdb/edit',
'url_params_data_paths' => array(
'Sightingdb.id'
),
'icon' => 'edit'
),
array(
'url' => '/sightingdb/delete',
'url_params_data_paths' => array(
'Sightingdb.id'
),
'postLink' => 1,
'postLinkConfirm' => __('Are you sure you want to remove the connection to this SightingDB?'),
'icon' => 'trash'
)
)
)
));
echo '</div>';
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'sightingdb', 'menuItem' => 'index'));
?>
<script type="text/javascript">
var passedArgsArray = <?php echo $passedArgs; ?>;
if (passedArgsArray['context'] === undefined) {
passedArgsArray['context'] = 'pending';
}
$(document).ready(function() {
$('#quickFilterButton').click(function() {
runIndexQuickFilter('/context:' + passedArgsArray['context']);
});
$('#quickFilterField').on('keypress', function (e) {
if(e.which === 13) {
runIndexQuickFilter('/context:' + passedArgsArray['context']);
}
});
});
</script>

View File

@ -17,6 +17,10 @@ button .full-width {
width:100%;
}
.buttonResultField {
padding-bottom:10px;
}
.bottom-buffer {
margin-bottom:10px;
}

View File

@ -3000,6 +3000,58 @@ function sharingGroupPopulateFromJson() {
$('#SharingGroupDescription').text(jsonparsed.sharingGroup.description);
}
function runOnDemandAction(element, url, target, postFormField) {
var elementContainer = '#' + target;
var type = 'GET';
var data = '';
if (postFormField !== '') {
type = 'POST';
data = $('#' + postFormField).val();
data = {value: data}
}
$.ajax({
url: url,
type: type,
data: data,
beforeSend: function (XMLHttpRequest) {
$(elementContainer).html('Running...');
},
error: function(response) {
var result = JSON.parse(response.responseText);
$(elementContainer).empty();
$(elementContainer)
.append(
$('<div>')
.attr('class', 'bold red')
.text('Error ' + response.status + ':')
)
.append(
$('<div>')
.attr('class', 'bold')
.text(result.errors)
);
},
success: function(response) {
var result = JSON.parse(response);
$(elementContainer).empty();
for (var key in result) {
$(elementContainer).append(
$('<div>')
.append(
$('<span>')
.attr('class', 'bold')
.text(key + ': ')
).append(
$('<span>')
.attr('class', 'bold blue')
.text(result[key])
)
);
}
}
})
}
function testConnection(id) {
$.ajax({
url: '/servers/testConnection/' + id,
@ -3378,7 +3430,6 @@ function toggleBoolFilter(url, param) {
url += buildFilterURL(res);
url = url.replace(/view\//i, 'viewEventAttributes/');
$.ajax({
type:"get",
url:url,