Merge branch '2.4' of github.com:MISP/MISP into 2.4

pull/5572/head
iglocska 2020-01-28 11:16:31 +01:00
commit f4a767c821
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
21 changed files with 432 additions and 273 deletions

View File

@ -119,7 +119,6 @@ $config = array(
'group_two' => 2,
'group_one' => 1,
),
'DefaultRoleId' => 3,
'DefaultOrg' => 'DEFAULT_ORG',
),
*/

View File

@ -280,6 +280,7 @@ class AdminShell extends AppShell
$setting = $this->Server->getSettingData($setting_name);
if (empty($setting)) {
echo 'Invalid setting "' . $setting_name . '". Please make sure that the setting that you are attempting to change exists and if a module parameter, the modules are running.' . PHP_EOL;
exit(1);
}
$result = $this->Server->serverSettingsEditValue($cli_user, $setting, $value);
if ($result === true) {
@ -528,7 +529,7 @@ class AdminShell extends AppShell
'db_version' => $dbVersion
);
$file = new File(ROOT . DS . 'db_schema.json', true);
$file->write(json_encode($data));
$file->write(json_encode($data, JSON_PRETTY_PRINT));
$file->close();
echo __("> Database schema dumped on disk") . PHP_EOL;
} else {

View File

@ -112,7 +112,14 @@ class AppController extends Controller
public function beforeFilter()
{
$this->Auth->loginRedirect = Configure::read('MISP.baseurl') . '/users/routeafterlogin';
$this->Auth->logoutRedirect = Configure::read('MISP.baseurl') . '/users/login';
$customLogout = Configure::read('Plugin.CustomAuth_custom_logout');
if ($customLogout) {
$this->Auth->logoutRedirect = $customLogout;
} else {
$this->Auth->logoutRedirect = Configure::read('MISP.baseurl') . '/users/login';
}
$this->__sessionMassage();
if (Configure::read('Security.allow_cors')) {
// Add CORS headers

View File

@ -1154,53 +1154,43 @@ class AttributesController extends AppController
public function viewPicture($id, $thumbnail=false)
{
if (Validation::uuid($id)) {
$temp = $this->Attribute->find('first', array(
'recursive' => -1,
'conditions' => array('Attribute.uuid' => $id),
'fields' => array('Attribute.id', 'Attribute.uuid')
));
if (empty($temp)) {
throw new NotFoundException(__('Invalid attribute'));
}
$id = $temp['Attribute']['id'];
} elseif (!is_numeric($id)) {
$conditions = array('Attribute.uuid' => $id);
} elseif (is_numeric($id)) {
$conditions = array('Attribute.id' => $id);
} else {
throw new NotFoundException(__('Invalid attribute id.'));
}
$this->Attribute->id = $id;
if (!$this->Attribute->exists()) {
throw new NotFoundException('Invalid attribute');
}
$conditions = array(
'conditions' => array(
'Attribute.id' => $id,
'Attribute.type' => 'attachment'
),
$conditions['Attribute.type'] = 'attachment';
$options = array(
'conditions' => $conditions,
'includeAllTags' => false,
'includeAttributeUuid' => true,
'flatten' => true
'flatten' => true,
);
if ($this->_isRest()) {
$conditions['withAttachments'] = true;
$options['withAttachments'] = true;
}
$attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $conditions);
$attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $options);
if (empty($attribute)) {
throw new MethodNotAllowedException('Invalid attribute');
}
$attribute = $attribute[0];
if (!$this->Attribute->isImage($attribute['Attribute'])) {
throw new NotFoundException("Attribute is not an image.");
}
if ($this->_isRest()) {
return $this->RestResponse->viewData($attribute['Attribute']['data'], $this->response->type());
} else {
$width = isset($this->request->params['named']['width']) ? $this->request->params['named']['width'] : 200;
$height = isset($this->request->params['named']['height']) ? $this->request->params['named']['height'] : 200;
$image_data = $this->Attribute->getPictureData($attribute, $thumbnail, $width, $height);
$extension = explode('.', $attribute['Attribute']['value']);
$extension = end($extension);
$this->response->type(strtolower(h($extension)));
$this->response->body($image_data);
$this->autoRender = false;
$imageData = $this->Attribute->getPictureData($attribute, $thumbnail, $width, $height);
$extension = pathinfo($attribute['Attribute']['value'], PATHINFO_EXTENSION);
return new CakeResponse(array('body' => $imageData, 'type' => strtolower($extension)));
}
}
@ -1652,7 +1642,7 @@ class AttributesController extends AppController
if (isset($this->request->data['Attribute'])) {
$this->request->data = $this->request->data['Attribute'];
}
$checkForEmpty = array('value', 'tags', 'uuid', 'org', 'type', 'category');
$checkForEmpty = array('value', 'tags', 'uuid', 'org', 'type', 'category', 'first_seen', 'last_seen');
foreach ($checkForEmpty as $field) {
if (empty($this->request->data[$field]) || $this->request->data[$field] === 'ALL') {
unset($this->request->data[$field]);
@ -1767,6 +1757,15 @@ class AttributesController extends AppController
$user = $this->Auth->user();
foreach ($attributes as $k => $attribute) {
$attributeId = $attribute['Attribute']['id'];
if ($this->Attribute->isImage($attribute['Attribute'])) {
if (extension_loaded('gd')) {
// if extension is loaded, the data is not passed to the view because it is asynchronously fetched
$attribute['Attribute']['image'] = true; // tell the view that it is an image despite not having the actual data
} else {
$attribute['Attribute']['image'] = $this->Attribute->base64EncodeAttachment($attribute['Attribute']);
}
$attributes[$k] = $attribute;
}
$attributes[$k]['Attribute']['AttributeTag'] = $attributes[$k]['AttributeTag'];
$attributes[$k]['Attribute'] = $this->Attribute->Event->massageTags($attributes[$k]['Attribute'], 'Attribute', $excludeGalaxy = false, $cullGalaxyTags = true);

View File

@ -286,6 +286,12 @@ class ObjectsController extends AppController
$result = $this->MispObject->saveObject($object, $eventId, $template, $this->Auth->user(), $errorBehaviour = 'halt');
if (is_numeric($result)) {
$this->MispObject->Event->unpublishEvent($eventId);
} else {
$object_validation_errors = array();
foreach($result as $field => $field_errors) {
$object_validation_errors[] = sprintf('%s: %s', $field, implode(', ', $field_errors));
}
$error = __('Object could not be saved.') . PHP_EOL . implode(PHP_EOL, $object_validation_errors);
}
} else {
$result = false;
@ -414,6 +420,14 @@ class ObjectsController extends AppController
}
$objectToSave = $this->MispObject->attributeCleanup($this->request->data);
$objectToSave = $this->MispObject->deltaMerge($object, $objectToSave, $onlyAddNewAttribute);
$error_message = __('Object could not be saved.');
if (!is_numeric($objectToSave)){
$object_validation_errors = array();
foreach($objectToSave as $field => $field_errors) {
$object_validation_errors[] = sprintf('%s: %s', $field, implode(', ', $field_errors));
}
$error_message = __('Object could not be saved.') . PHP_EOL . implode(PHP_EOL, $object_validation_errors);
}
// we pre-validate the attributes before we create an object at this point
// This allows us to stop the process and return an error (API) or return
// to the add form
@ -428,11 +442,10 @@ class ObjectsController extends AppController
$this->MispObject->Event->unpublishEvent($objectToSave['Object']['event_id']);
return $this->RestResponse->viewData($objectToSave, $this->response->type());
} else {
return $this->RestResponse->saveFailResponse('Objects', 'add', false, $id, $this->response->type());
return $this->RestResponse->saveFailResponse('Objects', 'edit', false, $id, $this->response->type());
}
} else {
$message = __('Object attributes saved.');
$error_message = __('Object attributes could not be saved.');
if ($this->request->is('ajax')) {
$this->autoRender = false;
if (is_numeric($objectToSave)) {

View File

@ -110,8 +110,13 @@ class ServersController extends AppController
if (empty($combinedArgs['limit'])) {
$combinedArgs['limit'] = 60;
}
$total_count = 0;
$events = $this->Server->previewIndex($id, $this->Auth->user(), $combinedArgs, $total_count);
try {
list($events, $total_count) = $this->Server->previewIndex($id, $this->Auth->user(), $combinedArgs);
} catch (Exception $e) {
$this->Flash->error(__('Download failed.') . ' ' . $e->getMessage());
$this->redirect(array('action' => 'index'));
}
$this->loadModel('Event');
$threat_levels = $this->Event->ThreatLevel->find('all');
$this->set('threatLevels', Set::combine($threat_levels, '{n}.ThreatLevel.id', '{n}.ThreatLevel.name'));
@ -122,11 +127,9 @@ class ServersController extends AppController
$params['pageCount'] = ceil($total_count / $params['limit']);
}
$this->params->params['paging'] = array($this->modelClass => $params);
if (is_array($events)) {
if (count($events) > 60) {
$customPagination->truncateByPagination($events, $params);
}
} else ($events = array());
if (count($events) > 60) {
$customPagination->truncateByPagination($events, $params);
}
$this->set('events', $events);
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
$this->set('analysisLevels', $this->Event->analysisLevels);
@ -150,12 +153,15 @@ class ServersController extends AppController
if (empty($server)) {
throw new NotFoundException('Invalid server ID.');
}
$event = $this->Server->previewEvent($serverId, $eventId);
// work on this in the future to improve the feedback
// 2 = wrong error code
if (is_numeric($event)) {
throw new NotFoundException('Invalid event.');
try {
$event = $this->Server->previewEvent($serverId, $eventId);
} catch (NotFoundException $e) {
throw new NotFoundException(__("Event '$eventId' not found."));
} catch (Exception $e) {
$this->Flash->error(__('Download failed.') . ' ' . $e->getMessage());
$this->redirect(array('action' => 'previewIndex', $serverId));
}
$this->loadModel('Event');
$params = $this->Event->rearrangeEventForView($event, $this->passedArgs, $all);
$this->params->params['paging'] = array('Server' => $params);

View File

@ -1782,60 +1782,100 @@ class Attribute extends AppModel
return $this->saveAttachment($attribute);
}
public function getPictureData($attribute, $thumbnail=false, $width=200, $height=200)
/**
* Currently, as image are considered files with JPG (JPEG), PNG or GIF extension.
* @param array $attribute
* @return bool
*/
public function isImage(array $attribute)
{
$extension = explode('.', $attribute['Attribute']['value']);
$extension = end($extension);
if (extension_loaded('gd')) {
if (!$thumbnail) {
$data = $this->getAttachment($attribute['Attribute']);
$image = ImageCreateFromString($data);
ob_start ();
switch ($extension) {
case 'gif':
// php-gd doesn't support animated gif. Skipping...
break;
case 'jpg':
case 'jpeg':
imagejpeg($image);
break;
case 'png':
imagepng($image);
break;
default:
break;
}
$image_data = $extension != 'gif' ? ob_get_contents() : $data;
ob_end_clean ();
} else { // thumbnail requested, resample picture with desired dimension and save result
$thumbnail_exists = $this->getAttachment($attribute['Attribute'], $path_suffix='_thumbnail');
if ($width == 200 && $height == 200 && $thumbnail_exists !== '') { // check if thumbnail already exists
$image_data = $thumbnail_exists;
} else {
$data = $this->getAttachment($attribute['Attribute']);
if ($extension == 'gif') {
$image_data = $data;
} else {
$image = ImageCreateFromString($data);
$extension = 'jpg';
$imageTC = ImageCreateTrueColor($width, $height);
ImageCopyResampled($imageTC, $image, 0, 0, 0, 0, $width, $height, ImageSX($image), ImageSY($image));
ob_start ();
imagejpeg ($imageTC);
$image_data = ob_get_contents();
ob_end_clean ();
imagedestroy($image);
imagedestroy($imageTC);
}
// save thumbnail for later reuse
$attribute['Attribute']['data'] = $image_data;
$this->saveAttachment($attribute['Attribute'], '_thumbnail');
return $attribute['type'] === 'attachment' &&
Validation::extension($attribute['value'], array('jpg', 'jpeg', 'png', 'gif'));
}
/**
* @param array $attribute
* @param bool $thumbnail
* @param int $maxWidth - When $thumbnail is true
* @param int $maxHeight - When $thumbnail is true
* @return string
* @throws Exception
*/
public function getPictureData(array $attribute, $thumbnail=false, $maxWidth=200, $maxHeight=200)
{
if ($thumbnail && extension_loaded('gd')) {
if ($maxWidth == 200 && $maxHeight == 200) {
// Return thumbnail directly if already exists
$imageData = $this->getAttachment($attribute['Attribute'], $path_suffix='_thumbnail');
if ($imageData !== '') {
return $imageData;
}
}
// Thumbnail doesn't exists, we need to generate it
$imageData = $this->getAttachment($attribute['Attribute']);
$imageData = $this->resizeImage($imageData, $maxWidth, $maxHeight);
// Save just when requested default thumbnail size
if ($maxWidth == 200 && $maxHeight == 200) {
$attribute['Attribute']['data'] = $imageData;
$this->saveAttachment($attribute['Attribute'], $path_suffix='_thumbnail');
}
} else {
$image_data = $this->getAttachment($attribute['Attribute']);
$imageData = $this->getAttachment($attribute['Attribute']);
}
return $image_data;
return $imageData;
}
/**
* @param string $data
* @param int $maxWidth
* @param int $maxHeight
* @return string
* @throws Exception
*/
private function resizeImage($data, $maxWidth, $maxHeight)
{
$image = imagecreatefromstring($data);
if ($image === false) {
throw new Exception("Image is not valid.");
}
$currentWidth = imagesx($image);
$currentHeight = imagesy($image);
// Compute thumbnail size with keeping ratio
if ($currentWidth > $currentHeight) {
$newWidth = min($currentWidth, $maxWidth);
$divisor = $currentWidth / $newWidth;
$newHeight = floor($currentHeight / $divisor);
} else {
$newHeight = min($currentHeight, $maxHeight);
$divisor = $currentHeight / $newHeight;
$newWidth = floor($currentWidth / $divisor);
}
$imageThumbnail = imagecreatetruecolor($newWidth, $newHeight);
// Allow transparent background
imagealphablending($imageThumbnail, false);
imagesavealpha($imageThumbnail, true);
$transparent = imagecolorallocatealpha($imageThumbnail, 255, 255, 255, 127);
imagefilledrectangle($imageThumbnail, 0, 0, $newWidth, $newHeight, $transparent);
// Resize image
imagecopyresampled($imageThumbnail, $image, 0, 0, 0, 0, $newWidth, $newHeight, $currentWidth, $currentHeight);
imagedestroy($image);
// Output image to string
ob_start();
imagepng($imageThumbnail, null, 9);
$imageData = ob_get_contents();
ob_end_clean();
imagedestroy($imageThumbnail);
return $imageData;
}
public function __beforeSaveCorrelation($a)

View File

@ -4925,7 +4925,7 @@ class Event extends AppModel
if (!$this->__fTool) {
$this->__fTool = new FinancialTool();
}
if ($object['type'] == 'attachment' && preg_match('/.*\.(jpg|png|jpeg|gif)$/i', $object['value'])) {
if ($this->Attribute->isImage($object)) {
if (!empty($object['data'])) {
$object['image'] = $object['data'];
} else {

View File

@ -142,32 +142,98 @@ class GalaxyCluster extends AppModel
*/
public function getCluster($name)
{
$conditions = array('LOWER(GalaxyCluster.tag_name)' => strtolower($name));
if (is_numeric($name)) {
$conditions = array('GalaxyCluster.id' => $name);
}
if (isset($this->__clusterCache[$name])) {
return $this->__clusterCache[$name];
}
$objects = array('Galaxy', 'GalaxyElement');
if (is_numeric($name)) {
$conditions = array('GalaxyCluster.id' => $name);
} else {
$conditions = array('LOWER(GalaxyCluster.tag_name)' => strtolower($name));
}
$cluster = $this->find('first', array(
'conditions' => $conditions,
'contain' => array('Galaxy', 'GalaxyElement')
));
if (!empty($cluster)) {
if (isset($cluster['Galaxy'])) {
$cluster['GalaxyCluster']['Galaxy'] = $cluster['Galaxy'];
unset($cluster['Galaxy']);
}
$elements = array();
foreach ($cluster['GalaxyElement'] as $element) {
if (!isset($elements[$element['key']])) {
$elements[$element['key']] = array($element['value']);
} else {
$elements[$element['key']][] = $element['value'];
$cluster = $this->postprocess($cluster);
}
$this->__clusterCache[$name] = $cluster;
return $cluster;
}
/**
* @param array $events
* @param bool $replace
* @return array
*/
public function attachClustersToEventIndex(array $events, $replace = false)
{
$clusterTagNames = array();
foreach ($events as $event) {
foreach ($event['EventTag'] as $k2 => $eventTag) {
if (substr($eventTag['Tag']['name'], 0, strlen('misp-galaxy:')) === 'misp-galaxy:') {
$clusterTagNames[] = strtolower($eventTag['Tag']['name']);
}
}
unset($cluster['GalaxyElement']);
}
$clusters = $this->find('all', array(
'conditions' => array('LOWER(GalaxyCluster.tag_name)' => $clusterTagNames),
'contain' => array('Galaxy', 'GalaxyElement'),
));
$clustersByTagName = array();
foreach ($clusters as $cluster) {
$clustersByTagName[strtolower($cluster['GalaxyCluster']['tag_name'])] = $cluster;
}
foreach ($events as $k => $event) {
foreach ($event['EventTag'] as $k2 => $eventTag) {
$tagName = strtolower($eventTag['Tag']['name']);
if (isset($clustersByTagName[$tagName])) {
$cluster = $this->postprocess($clustersByTagName[$tagName], $eventTag['Tag']['id']);
$cluster['GalaxyCluster']['tag_id'] = $eventTag['Tag']['id'];
$cluster['GalaxyCluster']['local'] = $eventTag['local'];
$events[$k]['GalaxyCluster'][] = $cluster['GalaxyCluster'];
if ($replace) {
unset($events[$k]['EventTag'][$k2]);
}
}
}
}
return $events;
}
/**
* @param array $cluster
* @param int|null $tagId
* @return array
*/
private function postprocess(array $cluster, $tagId = null)
{
if (isset($cluster['Galaxy'])) {
$cluster['GalaxyCluster']['Galaxy'] = $cluster['Galaxy'];
unset($cluster['Galaxy']);
}
$elements = array();
foreach ($cluster['GalaxyElement'] as $element) {
if (!isset($elements[$element['key']])) {
$elements[$element['key']] = array($element['value']);
} else {
$elements[$element['key']][] = $element['value'];
}
}
unset($cluster['GalaxyElement']);
$cluster['GalaxyCluster']['meta'] = $elements;
if ($tagId) {
$cluster['GalaxyCluster']['tag_id'] = $tagId;
} else {
$this->Tag = ClassRegistry::init('Tag');
$tag_id = $this->Tag->find(
'first',
@ -182,30 +248,9 @@ class GalaxyCluster extends AppModel
if (!empty($tag_id)) {
$cluster['GalaxyCluster']['tag_id'] = $tag_id['Tag']['id'];
}
$cluster['GalaxyCluster']['meta'] = $elements;
}
$this->__clusterCache[$name] = $cluster;
return $cluster;
}
public function attachClustersToEventIndex($events, $replace = false)
{
foreach ($events as $k => $event) {
foreach ($event['EventTag'] as $k2 => $eventTag) {
if (substr($eventTag['Tag']['name'], 0, strlen('misp-galaxy:')) === 'misp-galaxy:') {
$cluster = $this->getCluster($eventTag['Tag']['name']);
if ($cluster) {
$cluster['GalaxyCluster']['tag_id'] = $eventTag['Tag']['id'];
$cluster['GalaxyCluster']['local'] = $eventTag['local'];
$events[$k]['GalaxyCluster'][] = $cluster['GalaxyCluster'];
if ($replace) {
unset($events[$k]['EventTag'][$k2]);
}
}
}
}
}
return $events;
return $cluster;
}
public function getClusterTagsFromMeta($galaxyElements)

View File

@ -58,10 +58,34 @@ class MispObject extends AppModel
'rule' => 'isUnique',
'message' => 'The UUID provided is not unique',
'required' => 'create'
)
),
),
'first_seen' => array(
'rule' => array('datetimeOrNull'),
'required' => false,
'message' => array('Invalid ISO 8601 format')
),
'last_seen' => array(
'rule' => array('datetimeOrNull'),
'required' => false,
'message' => array('Invalid ISO 8601 format')
)
);
// check whether the variable is null or datetime
public function datetimeOrNull($fields)
{
$k = array_keys($fields)[0];
$seen = $fields[$k];
try {
new DateTime($seen);
$returnValue = true;
} catch (Exception $e) {
$returnValue = false;
}
return $returnValue || is_null($seen);
}
public function afterFind($results, $primary = false)
{
foreach ($results as $k => $v) {
@ -633,7 +657,10 @@ class MispObject extends AppModel
$forcedSeenOnElements['last_seen'] = $objectToSave['Object']['last_seen'];
}
$object = $this->syncObjectAndAttributeSeen($object, $forcedSeenOnElements, false);
$this->save($object);
$saveResult = $this->save($object);
if ($saveResult === false) {
return $this->validationErrors;
}
if (!$onlyAddNewAttribute) {
$checkFields = array('category', 'value', 'to_ids', 'distribution', 'sharing_group_id', 'comment', 'disable_correlation', 'first_seen', 'last_seen');

View File

@ -5131,23 +5131,16 @@ class Server extends AppModel
return 2;
}
/* returns an array with the events
* error codes:
* 1: received non json response
* 2: no route to host
* 3: empty result set
/**
* Returns an array with the events
* @param int $id
* @param $user - not used
* @param array $passedArgs
* @return array
* @throws Exception
*/
public function previewIndex($id, $user, $passedArgs, &$total_count = 0)
public function previewIndex($id, $user, array $passedArgs)
{
$server = $this->find('first', array(
'conditions' => array('Server.id' => $id),
));
if (empty($server)) {
return 2;
}
$HttpSocket = $this->setupHttpSocket($server);
$request = $this->setupSyncRequest($server);
$validArgs = array_merge(array('sort', 'direction', 'page', 'limit'), $this->validEventIndexFilters);
$urlParams = '';
foreach ($validArgs as $v) {
@ -5155,80 +5148,56 @@ class Server extends AppModel
$urlParams .= '/' . $v . ':' . $passedArgs[$v];
}
}
$uri = $server['Server']['url'] . '/events/index' . $urlParams;
$response = $HttpSocket->get($uri, $data = '', $request);
if (!empty($response->headers['X-Result-Count'])) {
$temp = $response->headers['X-Result-Count'];
$total_count = $temp;
}
if ($response->code == 200) {
try {
$events = json_decode($response->body, true);
} catch (Exception $e) {
return 1;
$relativeUri = '/events/index' . $urlParams;
list($events, $response) = $this->serverGetRequest($id, $relativeUri);
$totalCount = $response->getHeader('X-Result-Count') ?: 0;
foreach ($events as $k => $event) {
if (!isset($event['Orgc'])) {
$event['Orgc']['name'] = $event['orgc'];
}
if (!empty($events)) {
foreach ($events as $k => $event) {
if (!isset($event['Orgc'])) {
$event['Orgc']['name'] = $event['orgc'];
}
if (!isset($event['Org'])) {
$event['Org']['name'] = $event['org'];
}
if (!isset($event['EventTag'])) {
$event['EventTag'] = array();
}
$events[$k] = array('Event' => $event);
}
} else {
return 3;
if (!isset($event['Org'])) {
$event['Org']['name'] = $event['org'];
}
return $events;
if (!isset($event['EventTag'])) {
$event['EventTag'] = array();
}
$events[$k] = array('Event' => $event);
}
return 2;
return array($events, $totalCount);
}
/* returns an array with the events
* error codes:
* 1: received non-json response
* 2: no route to host
/**
* Returns an array with the event.
* @param int $serverId
* @param int $eventId
* @return array
* @throws Exception
*/
public function previewEvent($serverId, $eventId)
{
$server = $this->find('first', array(
'conditions' => array('Server.id' => $serverId),
));
if (empty($server)) {
return 2;
$relativeUri = '/events/' . $eventId;
list($event) = $this->serverGetRequest($serverId, $relativeUri);
if (!isset($event['Event']['Orgc'])) {
$event['Event']['Orgc']['name'] = $event['Event']['orgc'];
}
$HttpSocket = $this->setupHttpSocket($server);
$request = $this->setupSyncRequest($server);
$uri = $server['Server']['url'] . '/events/' . $eventId;
$response = $HttpSocket->get($uri, $data = '', $request);
if ($response->code == 200) {
try {
$event = json_decode($response->body, true);
} catch (Exception $e) {
return 1;
}
if (!isset($event['Event']['Orgc'])) {
$event['Event']['Orgc']['name'] = $event['Event']['orgc'];
}
if (isset($event['Event']['Orgc'][0])) {
$event['Event']['Orgc'] = $event['Event']['Orgc'][0];
}
if (!isset($event['Event']['Org'])) {
$event['Event']['Org']['name'] = $event['Event']['org'];
}
if (isset($event['Event']['Org'][0])) {
$event['Event']['Org'] = $event['Event']['Org'][0];
}
if (!isset($event['Event']['EventTag'])) {
$event['Event']['EventTag'] = array();
}
return $event;
if (isset($event['Event']['Orgc'][0])) {
$event['Event']['Orgc'] = $event['Event']['Orgc'][0];
}
return 2;
if (!isset($event['Event']['Org'])) {
$event['Event']['Org']['name'] = $event['Event']['org'];
}
if (isset($event['Event']['Org'][0])) {
$event['Event']['Org'] = $event['Event']['Org'][0];
}
if (!isset($event['Event']['EventTag'])) {
$event['Event']['EventTag'] = array();
}
return $event;
}
// Loops through all servers and checks which servers' push rules don't conflict with the given event.
@ -5789,6 +5758,53 @@ class Server extends AppModel
return $success;
}
/**
* @param int $serverId
* @param string $relativeUri
* @param HttpSocket|null $HttpSocket
* @return array
* @throws Exception
*/
private function serverGetRequest($serverId, $relativeUri, HttpSocket $HttpSocket = null)
{
$server = $this->find('first', array(
'conditions' => array('Server.id' => $serverId),
));
if ($server === null) {
throw new Exception(__("Server with ID '$serverId' not found."));
}
if (!$HttpSocket) {
$HttpSocket = $this->setupHttpSocket($server);
}
$request = $this->setupSyncRequest($server);
$uri = $server['Server']['url'] . $relativeUri;
$response = $HttpSocket->get($uri, array(), $request);
if ($response === false) {
throw new Exception(__("Could not reach '$uri'."));
} else if ($response->code == 404) { // intentional !=
throw new NotFoundException(__("Fetching the '$uri' failed with HTTP error 404: Not Found"));
} else if ($response->code == 405) { // intentional !=
$responseText = json_decode($response->body, true);
if ($responseText !== null) {
throw new Exception(sprintf(__("Fetching the '$uri' failed with HTTP error %s: %s"), $response->code, $responseText['message']));
}
}
if ($response->code != 200) { // intentional !=
throw new Exception(sprintf(__("Fetching the '$uri' failed with HTTP error %s: %s"), $response->code, $response->reasonPhrase));
}
$data = json_decode($response->body, true);
if ($data === null) {
throw new Exception(__('Could not parse JSON: ') . json_last_error_msg(), json_last_error());
}
return array($data, $response);
}
public function getRemoteUser($id)
{
$server = $this->find('first', array(

View File

@ -1373,7 +1373,7 @@ class User extends AppModel
$updatedUser['User']['id'],
$updatedUser['User']['email']
),
$fieldsResult = 'authkey(' . $oldKey . ') => (' . $newkey . ')',
$fieldsResult = ['authkey' => [$oldKey, $newkey]],
$updatedUser
);
if ($alert) {

View File

@ -138,13 +138,9 @@
<script type="text/javascript">
$(document).ready(function () {
$('.expandable').click(function() {
$(this).parent().children('div').toggle();
if ($(this).children('span').html() == '+') {
$(this).children('span').html('-');
} else {
$(this).children('span').html('+');
}
$('.expandable').popover({
html: true,
trigger: 'hover'
});
});
</script>

View File

@ -447,7 +447,7 @@
} else if((Configure::read('Plugin.CustomAuth_custom_password_reset'))) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'custom_pw_reset',
'url' => h(Configure::read('Plugin.CustomAuth_custom_password_reset')),
'url' => Configure::read('Plugin.CustomAuth_custom_password_reset'),
'text' => __('Reset Password')
));
}

View File

@ -419,15 +419,10 @@
)
)
),
array(
'url' => h(Configure::read('Plugin.CustomAuth_custom_logout')),
'text' => __('Log out'),
'requirement' => (Configure::read('Plugin.CustomAuth_custom_logout') && empty(Configure::read('Plugin.CustomAuth_disable_logout')))
),
array(
'url' => '/users/logout',
'text' => __('Log out'),
'requirement' => (!$externalAuthUser && empty(Configure::read('Plugin.CustomAuth_disable_logout')))
'requirement' => empty(Configure::read('Plugin.CustomAuth_disable_logout'))
)
);
}

View File

@ -86,10 +86,11 @@
<table class='table table-striped table-condensed'>
<tbody>
<tr>
<th><?php echo __('Import');?></th>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th class="hidden"><?php echo __('UUID');?></th>
<th><?php echo __('Tags');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
@ -102,8 +103,10 @@
?>
<tbody class='MISPObject'>
<tr class='tableHighlightBorderTop borderBlue blueRow' tabindex='0'>
<td colspan="7">
<input type="checkbox" class="ImportMISPObject" checked /> <span class="bold"><?php echo __('Import object');?></span><br />
<td class="short" style="width:40px;text-align:center;">
<input type="checkbox" class="ImportMISPObject" checked />
</td>
<td colspan="6">
<?php if(!empty($object['id'])) { ?>
<span class="bold"><?php echo __('ID: ');?></span><span class="ObjectID"><?php echo h($object['id']); ?></span><br />
<?php } ?>
@ -197,6 +200,7 @@
$border_position = ($attribute == $last_attribute ? 'Bottom' : 'Center');
?>
<tr class="ObjectAttribute tableHighlightBorder<?php echo $border_position; ?> borderBlue">
<td class="short" style="width:40px;text-align:center;"><input type="checkbox" class="ImportMISPObjectAttribute" checked /></td>
<td class="ObjectCategory"><?php echo (isset($attribute['category']) ? h($attribute['category']) : ''); ?></td>
<td class="short">
<span class="ObjectRelation bold"><?php echo h($attribute['object_relation']); ?></span>:
@ -213,7 +217,7 @@
}
}
?>
<td class="AttributeUuid short"><?php echo h($attribute['uuid']); ?></td>
<td class="AttributeUuid short hidden"><?php echo h($attribute['uuid']); ?></td>
<td style="max-width:150px;width:10px;">
<?php if (!empty($attribute['Tag'])) { ?>
<span class="objectAttributeTagContainer">
@ -277,10 +281,11 @@
<table class='table table-striped table-condensed'>
<tbody>
<tr>
<th><?php echo __('Import');?></th>
<th><?php echo __('Category');?></th>
<th><?php echo __('Type');?></th>
<th><?php echo __('Value');?></th>
<th><?php echo __('UUID');?></th>
<th class="hidden"><?php echo __('UUID');?></th>
<th><?php echo __('Tags');?></th>
<th><?php echo __('IDS');?></th>
<th><?php echo __('Disable Correlation');?></th>
@ -290,7 +295,10 @@
<?php
}
foreach ($event['Attribute'] as $a => $attribute) {
echo '<tr class="MISPAttribute">';
?>
<tr class="MISPAttribute">
<td class="short" style="width:40px;text-align:center;"><input type="checkbox" class="ImportMISPAttribute" checked /></td>
<?php
foreach (array('category', 'type') as $field) {
$field_header = 'class="Attribute' . ucfirst($field);
if (isset($attribute[$field])) {
@ -319,7 +327,7 @@
}
}
?>
<td class="AttributeUuid short"><?php echo h($attribute['uuid']); ?></td>
<td class="AttributeUuid short hidden"><?php echo h($attribute['uuid']); ?></td>
<td style="max-width:150px;width:10px;">
<?php if (!empty($attribute['Tag'])) { ?>
<span class="attributeTagContainer">

View File

@ -12,7 +12,7 @@
));
if (!empty($host_org_id) && !empty($this->request->data['Server']) && $this->request->data['Server']['remote_org_id'] == $host_org_id) {
echo sprintf(
'<div id="InternalDiv" class = "input clear" style="width:100%;"><hr /><p class="red" style="width:50%;">%s</p>%s</div>',
'<div id="InternalDiv" class = "input clear" style="width:100%%;"><hr /><p class="red" style="width:50%%;">%s</p>%s</div>',
__('You can set this instance up as an internal instance by checking the checkbox below. This means that any synchronisation between this instance and the remote will not be automatically degraded as it would in a normal synchronisation scenario. Please make sure that you own both instances and that you are OK with this otherwise dangerous change. This also requires that the current instance\'s host organisation and the remote sync organisation are the same.'),
$this->Form->input('internal', array(
'label' => __('Internal instance'),

View File

@ -1112,7 +1112,7 @@
"Feed": {
"id": "64",
"name": "This list contains all domains - A list for administrators to prevent mining in networks",
"provider": "CoinBlockerLists",
"provider": "ZeroDot1 - CoinBlockerLists",
"url": "https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/list.txt?inline=false",
"rules": "{\"tags\":{\"OR\":[],\"NOT\":[]},\"orgs\":{\"OR\":[],\"NOT\":[]}}",
"enabled": true,
@ -1137,7 +1137,7 @@
"Feed": {
"id": "65",
"name": "This list contains all optional domains - An additional list for administrators",
"provider": "CoinBlockerLists",
"provider": "ZeroDot1 - CoinBlockerLists",
"url": "https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/list_optional.txt?inline=false",
"rules": "",
"enabled": true,
@ -1162,7 +1162,7 @@
"Feed": {
"id": "66",
"name": "This list contains all browser mining domains - A list to prevent browser mining only",
"provider": "CoinBlockerLists",
"provider": "ZeroDot1 - CoinBlockerLists",
"url": "https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/list_browser.txt?inline=false",
"rules": "",
"enabled": true,
@ -1183,31 +1183,6 @@
"headers": ""
}
},
{
"Feed": {
"id": "68",
"name": "This list contains all IPs - A additional list for administrators to prevent mining in networks",
"provider": "CoinBlockerLists",
"url": "https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/MiningServerIPList.txt?inline=false",
"rules": "",
"enabled": true,
"distribution": "3",
"sharing_group_id": "0",
"tag_id": "0",
"default": false,
"source_format": "freetext",
"fixed_event": false,
"delta_merge": false,
"event_id": "0",
"publish": false,
"override_ids": false,
"settings": "{\"csv\":{\"value\":\"\",\"delimiter\":\",\"},\"common\":{\"excluderegex\":\"\"}}",
"input_source": "network",
"delete_local_file": false,
"lookup_visible": true,
"headers": ""
}
},
{
"Feed": {
"id": "69",
@ -1420,6 +1395,32 @@
"caching_enabled": true
}
},
{
"Feed": {
"id": "79",
"name": "malsilo.domain",
"provider": "MalSilo",
"url": "https://malsilo.gitlab.io/feeds/dumps/domain_list.txt",
"rules": "{\"tags\":{\"OR\":[],\"NOT\":[]},\"orgs\":{\"OR\":[],\"NOT\":[]}}",
"enabled": false,
"distribution": "3",
"sharing_group_id": "0",
"tag_id": "0",
"default": false,
"source_format": "csv",
"fixed_event": true,
"delta_merge": false,
"event_id": "0",
"publish": false,
"override_ids": false,
"settings": "{\"csv\":{\"value\":\"3\",\"delimiter\":\",\"},\"common\":{\"excluderegex\":\"\"}}",
"input_source": "network",
"delete_local_file": false,
"lookup_visible": true,
"headers": "",
"caching_enabled": true
}
},
{
"Feed": {
"id": "87",

@ -1 +1 @@
Subproject commit dbaab413b6b4680ae458a7d7a8ac6e1917fcc357
Subproject commit 6d078a88dd9f715ba90ccda10365fab585ec9c0f

View File

@ -2725,6 +2725,7 @@ function moduleResultsSubmit(id) {
$(this).find('.ObjectAttribute').each(function(a) {
var attribute_type = $(this).find('.AttributeType').text();
attribute = {
import_attribute: $(this).find('.ImportMISPObjectAttribute')[0].checked,
object_relation: $(this).find('.ObjectRelation').text(),
category: $(this).find('.AttributeCategory').text(),
type: attribute_type,
@ -2736,6 +2737,9 @@ function moduleResultsSubmit(id) {
distribution: $(this).find('.AttributeDistribution').val(),
sharing_group_id: $(this).find('.AttributeSharingGroup').val()
}
if (!attribute['import_attribute']) {
return true;
}
if (attribute['distribution'] != '4') {
attribute['sharing_group_id'] = '0';
}
@ -2778,6 +2782,7 @@ function moduleResultsSubmit(id) {
type_value = $(this).find('.AttributeType').text();
}
temp = {
import_attribute: $(this).find('.ImportMISPAttribute')[0].checked,
category: category_value,
type: type_value,
value: $(this).find('.AttributeValue').text(),
@ -2788,6 +2793,9 @@ function moduleResultsSubmit(id) {
distribution: $(this).find('.AttributeDistribution').val(),
sharing_group_id: $(this).find('.AttributeSharingGroup').val()
}
if (!temp['import_attribute']) {
return true;
}
if (temp['distribution'] != '4') {
temp['sharing_group_id'] = '0';
}

View File

@ -5346,8 +5346,8 @@
"attribute_tags": [
"id",
"attribute_id",
"tag_id",
"event_id"
"event_id",
"tag_id"
],
"attributes": [
"id",
@ -5535,8 +5535,7 @@
"distribution",
"sharing_group_id",
"first_seen",
"last_seen",
"comment"
"last_seen"
],
"org_blacklists": [
"id"
@ -5591,8 +5590,7 @@
"type",
"category",
"first_seen",
"last_seen",
"comment"
"last_seen"
],
"sharing_group_orgs": [
"id",