mirror of https://github.com/MISP/MISP
Merge remote-tracking branch 'origin/develop' into tomking2_feature/propagate_tag_deletion
commit
646d921d67
|
@ -50,6 +50,8 @@ app/Lib/EventWarning/Custom/*
|
|||
!/app/files/misp-objects/*
|
||||
!/app/files/misp-decaying-models
|
||||
!/app/files/misp-decaying-models/*
|
||||
!/app/files/misp-workflow-blueprints
|
||||
!/app/files/misp-workflow-blueprints/*
|
||||
/app/files/scripts/*.pyc
|
||||
/app/files/scripts/*.py~
|
||||
/app/files/scripts/__pycache__
|
||||
|
|
|
@ -48,3 +48,6 @@
|
|||
[submodule "app/files/scripts/python-maec"]
|
||||
path = app/files/scripts/python-maec
|
||||
url = https://github.com/MAECProject/python-maec
|
||||
[submodule "app/files/misp-workflow-blueprints"]
|
||||
path = app/files/misp-workflow-blueprints
|
||||
url = https://github.com/MISP/misp-workflow-blueprints
|
||||
|
|
|
@ -3593,6 +3593,7 @@ x86_64-debian-buster
|
|||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-ubuntu-hirsute
|
||||
x86_64-ubuntu-jammy
|
||||
x86_64-kali-2021.4
|
||||
x86_64-kali-2022.1
|
||||
x86_64-kali-2022.2
|
||||
|
@ -3640,6 +3641,12 @@ if [[ "${FLAVOUR}" == "ubuntu" ]]; then
|
|||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "22.04" ]]; then
|
||||
echo "Install on Ubuntu 22.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
upgradeToPHP74
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "18.10" ]]; then
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; Generated by RHash v1.3.9 on 2021-12-25 at 14:54.47
|
||||
; Generated by RHash v1.4.2 on 2022-05-23 at 12:45.34
|
||||
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
|
||||
;
|
||||
; 161158 14:54.46 2021-12-25 INSTALL.sh
|
||||
INSTALL.sh A1EEC205071442B2C9B145E7B5A054FF24728EF4 DAF55446860994E3AE8589FB6F8EE33B015DBC454ADFC8D7F3E0B2F28AA8BBBD 4F6F43B200D0F9B35C53186B4AD26A1CCFEBB6FC961B19369E3D13A053C046340B6BF1673D14793B0FE7233ECA86993D D38C7FAF648C60DCEA4D9C64AB5EB4AE262B3F1625106670DC837D1AEC9AB302BCB21811CEE5B14845D841BCDCBF420FA800BDCDCA44B5F58196667022BBD94D
|
||||
; 160126 12:45.34 2022-05-23 INSTALL.sh
|
||||
INSTALL.sh 4296D40B11B3002DF3FDFD69A508ED5ECACB8C13 D32E5A4B0F37F4C937CD4F85927E998D917BCBE89E4E0E864FFD7EA09E29ADEF BD093D8018C351E3D3722646E269C4B60E6DA19F42150338CE6FD72FEE293B8B89AA69D48A84B19D3EFDDAE25EC9E646 ECACC3071E130058C3DDECC86E1CBF27DD4F11389D10F43B14293B1915F7A24F02D0DA51E299706A38C00F2D2A7505B0FE46E33B705E53594383CE65461F2B08
|
||||
|
|
|
@ -1 +1 @@
|
|||
c14654d71a2a369fb5852987b69ecd7774b7111d INSTALL.sh
|
||||
4296d40b11b3002df3fdfd69a508ed5ecacb8c13 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
621dd7fc21cc25631248a685a00d506a3aa1c2e29c11539870cf4efde499dcc9 INSTALL.sh
|
||||
d32e5a4b0f37f4c937cd4f85927e998d917bcbe89e4e0e864ffd7ea09e29adef INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
f348d5c019fea3c339b6076596ede2e55ea173cd1c25158d7e3d2cbb4d2d90950ac84ab3597bbaa50f199fd9850831db INSTALL.sh
|
||||
bd093d8018c351e3d3722646e269c4b60e6da19f42150338ce6fd72fee293b8b89aa69d48a84b19d3efddae25ec9e646 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
499e82451509739bbd5117a942f8a39f847310301c9e4dc0428eaa31560ff6b08bafa958fd22c01a3241afad7fcfedfeb7ae88d25f5fce299e921b49a4d644c1 INSTALL.sh
|
||||
ecacc3071e130058c3ddecc86e1cbf27dd4f11389d10f43b14293b1915f7a24f02d0da51e299706a38c00f2d2a7505b0fe46e33b705e53594383ce65461f2b08 INSTALL.sh
|
||||
|
|
|
@ -849,6 +849,7 @@ x86_64-debian-buster
|
|||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-ubuntu-hirsute
|
||||
x86_64-ubuntu-jammy
|
||||
x86_64-kali-2021.4
|
||||
x86_64-kali-2022.1
|
||||
x86_64-kali-2022.2
|
||||
|
@ -896,6 +897,12 @@ if [[ "${FLAVOUR}" == "ubuntu" ]]; then
|
|||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "22.04" ]]; then
|
||||
echo "Install on Ubuntu 22.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
upgradeToPHP74
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "18.10" ]]; then
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit b1892efb6a078d1370cee51c9103f3a591c628d2
|
||||
Subproject commit 3ca8717e6c7780718cd20328040799261a39a281
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":158}
|
||||
{"major":2, "minor":4, "hotfix":161}
|
||||
|
|
|
@ -71,6 +71,7 @@ $config = array(
|
|||
'enableOrgBlocklisting' => true,
|
||||
'log_client_ip' => false,
|
||||
'log_auth' => false,
|
||||
'store_api_access_time' => false,
|
||||
'disableUserSelfManagement' => false,
|
||||
'disable_user_login_change' => false,
|
||||
'disable_user_password_change' => false,
|
||||
|
|
|
@ -7,18 +7,35 @@ App::uses('JsonTool', 'Tools');
|
|||
/**
|
||||
* @property Server $Server
|
||||
* @property Feed $Feed
|
||||
* @property Warninglist $warninglist
|
||||
* @property AdminSetting $AdminSetting
|
||||
* @property Taxonomy $Taxonomy
|
||||
* @property Warninglist $Warninglist
|
||||
* @property Attribute $Attribute
|
||||
* @property Job $Job
|
||||
*/
|
||||
class AdminShell extends AppShell
|
||||
{
|
||||
public $uses = array('Event', 'Post', 'Attribute', 'Job', 'User', 'Task', 'Allowedlist', 'Server', 'Organisation', 'AdminSetting', 'Galaxy', 'Taxonomy', 'Warninglist', 'Noticelist', 'ObjectTemplate', 'Bruteforce', 'Role', 'Feed', 'SharingGroupBlueprint');
|
||||
public $uses = [
|
||||
'Event', 'Post', 'Attribute', 'Job', 'User', 'Task', 'Allowedlist', 'Server', 'Organisation',
|
||||
'AdminSetting', 'Galaxy', 'Taxonomy', 'Warninglist', 'Noticelist', 'ObjectTemplate', 'Bruteforce',
|
||||
'Role', 'Feed', 'SharingGroupBlueprint', 'Correlation', 'OverCorrelatingValue'
|
||||
];
|
||||
|
||||
public $tasks = ['ConfigLoad'];
|
||||
|
||||
public function getOptionParser()
|
||||
{
|
||||
$parser = parent::getOptionParser();
|
||||
$parser->addSubcommand('updateJSON', array(
|
||||
'help' => __('Update the JSON definitions of MISP.'),
|
||||
));
|
||||
$parser->addSubcommand('updateWarningLists', array(
|
||||
'help' => __('Update the JSON definition of warninglists.'),
|
||||
));
|
||||
$parser->addSubcommand('updateTaxonomies', array(
|
||||
'help' => __('Update the JSON definition of taxonomies.'),
|
||||
));
|
||||
$parser->addSubcommand('setSetting', [
|
||||
'help' => __('Set setting in PHP config file.'),
|
||||
'parser' => [
|
||||
|
@ -94,30 +111,29 @@ class AdminShell extends AppShell
|
|||
}
|
||||
|
||||
$jobId = $this->args[0];
|
||||
$this->loadModel('Job');
|
||||
$this->Job->id = $jobId;
|
||||
$this->loadModel('Attribute');
|
||||
$this->Attribute->generateCorrelation($jobId, 0);
|
||||
$this->Job->saveField('progress', 100);
|
||||
$this->Job->saveField('message', 'Job done.');
|
||||
$this->Job->saveField('status', 4);
|
||||
$this->Attribute->generateCorrelation($jobId);
|
||||
}
|
||||
|
||||
public function jobGenerateOccurrences()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
if (empty($this->args[0])) {
|
||||
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Generate over-correlation occurrences'] . PHP_EOL);
|
||||
}
|
||||
|
||||
$jobId = $this->args[0];
|
||||
$this->OverCorrelatingValue->generateOccurrences($jobId);
|
||||
}
|
||||
|
||||
public function jobPurgeCorrelation()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
if (empty($this->args[0])) {
|
||||
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Purge correlation'] . PHP_EOL);
|
||||
}
|
||||
|
||||
$jobId = $this->args[0];
|
||||
$this->loadModel('Job');
|
||||
$this->Job->id = $jobId;
|
||||
$this->loadModel('Attribute');
|
||||
$this->Attribute->purgeCorrelations();
|
||||
$this->Job->saveField('progress', 100);
|
||||
$this->Job->saveField('message', 'Job done.');
|
||||
$this->Job->saveField('status', 4);
|
||||
$this->Job->saveStatus($jobId);
|
||||
}
|
||||
|
||||
public function jobGenerateShadowAttributeCorrelation()
|
||||
|
@ -278,22 +294,27 @@ class AdminShell extends AppShell
|
|||
|
||||
public function updateTaxonomies()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
$result = $this->Taxonomy->update();
|
||||
$successes = count(!empty($result['success']) ? $result['success'] : []);
|
||||
$fails = count(!empty($result['fails']) ? $result['fails'] : []);
|
||||
$message = '';
|
||||
if ($successes == 0 && $fails == 0) {
|
||||
$message = __('All taxonomies are up to date already.');
|
||||
} elseif ($successes == 0 && $fails > 0) {
|
||||
$successes = empty($result['success']) ? 0 : count($result['success']);
|
||||
$fails = empty($result['fails']) ? 0 : count($result['fails']);
|
||||
|
||||
if ($successes === 0 && $fails === 0) {
|
||||
$message = __('All taxonomies are up to date already.');
|
||||
} elseif ($successes === 0 && $fails > 0) {
|
||||
$message = __('Could not update any of the taxonomies.');
|
||||
} elseif ($successes > 0 ) {
|
||||
} else {
|
||||
$message = __('Successfully updated %s taxonomies.', $successes);
|
||||
if ($fails != 0) {
|
||||
if ($fails !== 0) {
|
||||
$message .= __(' However, could not update %s taxonomies.', $fails);
|
||||
}
|
||||
}
|
||||
echo $message . PHP_EOL;
|
||||
$this->out($message);
|
||||
if ($fails) {
|
||||
$this->out(__('Fails:'));
|
||||
foreach ($result['fails'] as $fail) {
|
||||
$this->out("{$fail['namespace']}: {$fail['fail']}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function enableTaxonomyTags()
|
||||
|
@ -312,11 +333,16 @@ class AdminShell extends AppShell
|
|||
|
||||
public function updateWarningLists()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
$result = $this->Warninglist->update();
|
||||
$success = count($result['success']);
|
||||
$fails = count($result['fails']);
|
||||
echo "$success warninglists updated, $fails fails" . PHP_EOL;
|
||||
$this->out("$success warninglists updated, $fails fails");
|
||||
if ($fails) {
|
||||
$this->out(__('Fails:'));
|
||||
foreach ($result['fails'] as $fail) {
|
||||
$this->out("{$fail['name']}: {$fail['fail']}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function updateNoticeLists()
|
||||
|
@ -1178,4 +1204,38 @@ class AdminShell extends AppShell
|
|||
);
|
||||
$this->out($message);
|
||||
}
|
||||
|
||||
public function truncateTable()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
if (!isset($this->args[0])) {
|
||||
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Truncate table correlation'] . PHP_EOL);
|
||||
}
|
||||
$userId = $this->args[0];
|
||||
if ($userId) {
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
} else {
|
||||
$user = [
|
||||
'id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'Organisation' => [
|
||||
'name' => 'SYSTEM'
|
||||
]
|
||||
];
|
||||
}
|
||||
if (empty($this->args[1])) {
|
||||
die('Usage: ' . $this->Server->command_line_functions['console_admin_tasks']['data']['Truncate table correlation'] . PHP_EOL);
|
||||
}
|
||||
if (!empty($this->args[2])) {
|
||||
$jobId = $this->args[2];
|
||||
}
|
||||
$table = trim($this->args[1]);
|
||||
$this->Correlation->truncate($user, $table);
|
||||
if ($jobId) {
|
||||
$this->Job->id = $jobId;
|
||||
$this->Job->saveField('progress', 100);
|
||||
$this->Job->saveField('date_modified', date("Y-m-d H:i:s"));
|
||||
$this->Job->saveField('message', __('Database truncated: ' . $table));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ require_once 'AppShell.php';
|
|||
* @property Job $Job
|
||||
* @property Tag $Tag
|
||||
* @property Server $Server
|
||||
* @property Correlation $Correlation
|
||||
*/
|
||||
class EventShell extends AppShell
|
||||
{
|
||||
|
@ -39,11 +40,17 @@ class EventShell extends AppShell
|
|||
'event_id' => ['help' => __('Event ID'), 'required' => true],
|
||||
'user_id' => ['help' => __('User ID'), 'required' => true],
|
||||
],
|
||||
'options' => [
|
||||
'send' => ['help' => __('Send email to given user'), 'boolean' => true],
|
||||
],
|
||||
],
|
||||
]);
|
||||
$parser->addSubcommand('duplicateTags', [
|
||||
'help' => __('Show duplicate tags'),
|
||||
]);
|
||||
$parser->addSubcommand('generateTopCorrelations', [
|
||||
'help' => __('Generate top correlations'),
|
||||
]);
|
||||
$parser->addSubcommand('mergeTags', [
|
||||
'help' => __('Merge tags'),
|
||||
'parser' => [
|
||||
|
@ -603,6 +610,7 @@ class EventShell extends AppShell
|
|||
public function testEventNotificationEmail()
|
||||
{
|
||||
list($eventId, $userId) = $this->args;
|
||||
$send = $this->param('send');
|
||||
|
||||
$user = $this->getUser($userId);
|
||||
$eventForUser = $this->Event->fetchEvent($user, [
|
||||
|
@ -622,10 +630,16 @@ class EventShell extends AppShell
|
|||
App::uses('SendEmail', 'Tools');
|
||||
App::uses('GpgTool', 'Tools');
|
||||
$sendEmail = new SendEmail(GpgTool::initializeGpg());
|
||||
$sendEmail->setTransport('Debug');
|
||||
if (!$send) {
|
||||
$sendEmail->setTransport('Debug');
|
||||
}
|
||||
$result = $sendEmail->sendToUser(['User' => $user], null, $emailTemplate);
|
||||
|
||||
echo $result['contents']['headers'] . "\n\n" . $result['contents']['message'] . "\n";
|
||||
if ($send) {
|
||||
var_dump($result);
|
||||
} else {
|
||||
echo $result['contents']['headers'] . "\n\n" . $result['contents']['message'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,17 +658,20 @@ class EventShell extends AppShell
|
|||
|
||||
public function generateTopCorrelations()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
$jobId = $this->args[0];
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$job['Job']['progress'] = 1;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
$job['Job']['message'] = __('Generating top correlations list.');
|
||||
$this->Job->save($job);
|
||||
$result = $this->Correlation->generateTopCorrelations($jobId);
|
||||
$job['Job']['progress'] = 100;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
$job['Job']['message'] = __('Job done.');
|
||||
$this->Job->save($job);
|
||||
$jobId = $this->args[0] ?? null;
|
||||
if ($jobId) {
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$job['Job']['progress'] = 1;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
$job['Job']['message'] = __('Generating top correlations list.');
|
||||
$this->Job->save($job);
|
||||
}
|
||||
$this->Correlation->generateTopCorrelations($jobId);
|
||||
if ($jobId) {
|
||||
$job['Job']['progress'] = 100;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
$job['Job']['message'] = __('Job done.');
|
||||
$this->Job->save($job);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,55 @@ class Ls22Shell extends AppShell
|
|||
),
|
||||
),
|
||||
]);
|
||||
$parser->addSubcommand('checkSyncConnections', [
|
||||
'help' => __('Check the given sync connection(s) for the given server(s).'),
|
||||
'parser' => array(
|
||||
'options' => array(
|
||||
'instances' => [
|
||||
'help' => 'Path to the instance file, by default "instances.csv" from the local directory',
|
||||
'short' => 'i',
|
||||
'required' => true
|
||||
],
|
||||
'misp_url_filter' => [
|
||||
'help' => 'The url of the instance to execute changes on. If not set, all are updated.',
|
||||
'short' => 'm',
|
||||
'required' => false
|
||||
],
|
||||
'synced_misp_url_filter' => [
|
||||
'help' => 'The sync connection to modify on each valid instance (as selected by the misp_url_filter). If not set, all sync connections on the selected instances will be updated.',
|
||||
'short' => 's',
|
||||
'required' => false
|
||||
]
|
||||
),
|
||||
),
|
||||
]);
|
||||
$parser->addSubcommand('modifySyncConnection', [
|
||||
'help' => __('Modify sync connection(s).'),
|
||||
'parser' => array(
|
||||
'options' => array(
|
||||
'instances' => [
|
||||
'help' => 'Path to the instance file, by default "instances.csv" from the local directory',
|
||||
'short' => 'i',
|
||||
'required' => true
|
||||
],
|
||||
'misp_url_filter' => [
|
||||
'help' => 'The url of the instance to execute changes on. If not set, all are updated.',
|
||||
'short' => 'm',
|
||||
'required' => false
|
||||
],
|
||||
'synced_misp_url_filter' => [
|
||||
'help' => 'The sync connection to modify on each valid instance (as selected by the misp_url_filter). If not set, all sync connections on the selected instances will be updated.',
|
||||
'short' => 's',
|
||||
'required' => false
|
||||
],
|
||||
'json' => [
|
||||
'help' => 'JSON delta to push (such as \'{"push": 1}\').',
|
||||
'short' => 'j',
|
||||
'required' => true
|
||||
]
|
||||
),
|
||||
),
|
||||
]);
|
||||
$parser->addSubcommand('addWarninglist', [
|
||||
'help' => __('Inject warninglist'),
|
||||
'parser' => array(
|
||||
|
@ -104,6 +153,11 @@ class Ls22Shell extends AppShell
|
|||
'help' => 'Upper bound of the date. Accepts timestamp or date distance (such as 1d or 5h). Defaults to unbounded.',
|
||||
'short' => 't',
|
||||
'required' => false
|
||||
],
|
||||
'org' => [
|
||||
'help' => 'Name the org that should be evaluated. If not set, all will be included.',
|
||||
'short' => 'o',
|
||||
'required' => false
|
||||
]
|
||||
),
|
||||
),
|
||||
|
@ -111,6 +165,103 @@ class Ls22Shell extends AppShell
|
|||
return $parser;
|
||||
}
|
||||
|
||||
public function checkSyncConnections()
|
||||
{
|
||||
$this->__getInstances($this->param('instances'));
|
||||
$results = [];
|
||||
$instanceFilter = $this->param('misp_url_filter');
|
||||
$syncedInstanceFilter = $this->param('synced_misp_url_filter');
|
||||
foreach ($this->__servers as $server) {
|
||||
if (!empty($instanceFilter) && strtolower(trim($server['Server']['url'])) !== strtolower(trim($instanceFilter))) {
|
||||
continue;
|
||||
}
|
||||
$HttpSocket = $this->Server->setupHttpSocket($server, null);
|
||||
$request = $this->Server->setupSyncRequest($server, 'Server');
|
||||
$start_time = microtime(true);
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/servers/index', false, $request);
|
||||
$baseline = round((microtime(true) - $start_time) * 1000);
|
||||
if (!$response->isOk()) {
|
||||
$this->out($server['Server']['url'] . ': ' . '<error>Connection or auth failed</error>', 1, Shell::NORMAL);
|
||||
continue;
|
||||
}
|
||||
$synced_servers = json_decode($response->body, true);
|
||||
foreach ($synced_servers as $synced_server) {
|
||||
$success = false;
|
||||
if (empty($syncedInstanceFilter) || strtolower($synced_server['Server']['url']) === strtolower($syncedInstanceFilter)) {
|
||||
$start_time = microtime(true);
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/servers/testConnection/' . $synced_server['Server']['id'], '{}', $request);
|
||||
$execution_time = round((microtime(true) - $start_time) * 1000) - $baseline;
|
||||
if ($response->isOk()) {
|
||||
$success = true;
|
||||
}
|
||||
$this->out(
|
||||
sprintf(
|
||||
'%s connection to %s: %s (%sms)',
|
||||
$server['Server']['url'],
|
||||
$synced_server['Server']['url'],
|
||||
sprintf(
|
||||
'<%s>%s</%s>',
|
||||
$success ? 'info' : 'error',
|
||||
$success ? 'Success' : 'Failed',
|
||||
$success ? 'info' : 'error'
|
||||
),
|
||||
$execution_time
|
||||
),
|
||||
1,
|
||||
Shell::NORMAL
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function modifySyncConnection()
|
||||
{
|
||||
$this->__getInstances($this->param('instances'));
|
||||
$results = [];
|
||||
$instanceFilter = $this->param('misp_url_filter');
|
||||
$syncedInstanceFilter = $this->param('synced_misp_url_filter');
|
||||
$json = $this->param('json');
|
||||
foreach ($this->__servers as $server) {
|
||||
if (!empty($instanceFilter) && strtolower(trim($server['Server']['url'])) !== strtolower(trim($instanceFilter))) {
|
||||
continue;
|
||||
}
|
||||
$HttpSocket = $this->Server->setupHttpSocket($server, null);
|
||||
$request = $this->Server->setupSyncRequest($server, 'Server');
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/servers/index', false, $request);
|
||||
if (!$response->isOk()) {
|
||||
$this->out($server['Server']['url'] . ': ' . '<error>Connection or auth failed</error>', 1, Shell::NORMAL);
|
||||
}
|
||||
$synced_servers = json_decode($response->body, true);
|
||||
$success = false;
|
||||
foreach ($synced_servers as $synced_server) {
|
||||
if (empty($syncedInstanceFilter) || strtolower($synced_server['Server']['url']) === strtolower($syncedInstanceFilter)) {
|
||||
debug($json);
|
||||
$response = $HttpSocket->post($server['Server']['url'] . '/servers/edit/' . $synced_server['Server']['id'], $json, $request);
|
||||
debug($response->body);
|
||||
if ($response->isOk()) {
|
||||
$success = true;
|
||||
}
|
||||
$this->out(
|
||||
sprintf(
|
||||
'%s connection to %s: %s',
|
||||
$server['Server']['url'],
|
||||
$synced_server['Server']['url'],
|
||||
sprintf(
|
||||
'<%s>%s</%s>',
|
||||
$success ? 'info' : 'error',
|
||||
$success ? 'Success' : 'Failed',
|
||||
$success ? 'info' : 'error'
|
||||
)
|
||||
),
|
||||
1,
|
||||
Shell::NORMAL
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function enableTaxonomy()
|
||||
{
|
||||
$taxonomyToEnable = $this->param('taxonomy');
|
||||
|
@ -162,16 +313,29 @@ class Ls22Shell extends AppShell
|
|||
$HttpSocket = $this->Server->setupHttpSocket($server, null);
|
||||
$request = $this->Server->setupSyncRequest($server, 'Server');
|
||||
$start_time = microtime(true);
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/users/view/me', false, $request);
|
||||
$execution_time = round((microtime(true) - $start_time) * 1000);
|
||||
$statusWrapped = sprintf(
|
||||
'<%s>%s</%s>',
|
||||
$response->isOk() ? 'info' : 'error',
|
||||
$response->isOk() ? 'OK (' . $execution_time . 'ms)' : 'Failed. (' . $response->code . ')',
|
||||
$response->isOk() ? 'info' : 'error'
|
||||
);
|
||||
$fatal_error = false;
|
||||
try {
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/users/view/me', false, $request);
|
||||
} catch (Exception $e) {
|
||||
$fatal_error = true;
|
||||
echo "\x07";
|
||||
$statusWrapped = sprintf(
|
||||
'<error>%s %s: %s</error>',
|
||||
'Something went wrong while trying to reach',
|
||||
$server['Server']['url'],
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
if (!$fatal_error) {
|
||||
$execution_time = round((microtime(true) - $start_time) * 1000);
|
||||
$statusWrapped = sprintf(
|
||||
'<%s>%s</%s>',
|
||||
$response->isOk() ? 'info' : 'error',
|
||||
$response->isOk() ? 'OK (' . $execution_time . 'ms)' : 'Failed. (' . $response->code . ')',
|
||||
$response->isOk() ? 'info' : 'error'
|
||||
);
|
||||
}
|
||||
$this->out($server['Server']['url'] . ': ' . $statusWrapped, 1, Shell::NORMAL);
|
||||
$results[$server['Server']['url']] = $response->isOk() ? $execution_time : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,28 +379,30 @@ class Ls22Shell extends AppShell
|
|||
}
|
||||
$HttpSocket = $this->Server->setupHttpSocket($server, null);
|
||||
$request = $this->Server->setupSyncRequest($server);
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/organisations/index', false, $request);
|
||||
$response = $HttpSocket->get($server['Server']['url'] . '/organisations/index/scope:all', false, $request);
|
||||
$orgs = json_decode($response->body(), true);
|
||||
$this->out(__('Organisations fetched. %d found.', count($orgs)), 1, Shell::VERBOSE);
|
||||
$org_mapping = [];
|
||||
foreach ($orgs as $org) {
|
||||
$name = explode(' ', $org['Organisation']['name']);
|
||||
if ($name[0] !== 'BT') {
|
||||
if (!empty($this->param('org')) && $org['Organisation']['name'] !== $this->param('org')) {
|
||||
continue;
|
||||
}
|
||||
if ($org['Organisation']['name'] === 'YT') {
|
||||
continue;
|
||||
}
|
||||
$org_mapping[$org['Organisation']['name']] = $org['Organisation']['id'];
|
||||
}
|
||||
if (!empty($this->param['from'])) {
|
||||
$time_range[] = $this->param['from'];
|
||||
}
|
||||
if (!empty($this->param['to'])) {
|
||||
if (empty($time_range)) {
|
||||
$time_range[] = '365d';
|
||||
}
|
||||
$time_range[] = $this->param['to'];
|
||||
}
|
||||
foreach ($org_mapping as $org_name => $org_id) {
|
||||
$time_range = [];
|
||||
if (!empty($this->param['from'])) {
|
||||
$time_range[] = $this->param['from'];
|
||||
}
|
||||
if (!empty($this->param['to'])) {
|
||||
if (empty($time_range)) {
|
||||
$time_range[] = '365d';
|
||||
}
|
||||
$time_range[] = $this->param['to'];
|
||||
}
|
||||
$params = [
|
||||
'org' => $org_id
|
||||
];
|
||||
|
@ -256,7 +422,8 @@ class Ls22Shell extends AppShell
|
|||
'other' => 0,
|
||||
'attribute_attack' => 0,
|
||||
'attribute_other' => 0,
|
||||
'score' => 0
|
||||
'score' => 0,
|
||||
'warnings' => 0
|
||||
];
|
||||
foreach ($events['response'] as $event) {
|
||||
if (!empty($event['Event']['Tag'])) {
|
||||
|
@ -290,6 +457,9 @@ class Ls22Shell extends AppShell
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!empty($attribute['warnings'])) {
|
||||
$result[$org_name]['warnings'] += 1;
|
||||
}
|
||||
}
|
||||
$results[$org_name]['attribute_count'] += count($event['Event']['Attribute']);
|
||||
if (!empty($event['Event']['Object'])) {
|
||||
|
@ -319,11 +489,18 @@ class Ls22Shell extends AppShell
|
|||
foreach ($results as $k => $result) {
|
||||
$totalCount = $result['attribute_count'] + $result['object_count'];
|
||||
if ($totalCount) {
|
||||
if (empty($result['warnings'])) {
|
||||
$results[$k]['metrics']['warnings'] = 100;
|
||||
} else if (100 * $result['warnings'] < $result['attribute_count']) {
|
||||
$results[$k]['metrics']['warnings'] = 50;
|
||||
} else {
|
||||
$results[$k]['metrics']['warnings'] = 0;
|
||||
}
|
||||
$results[$k]['metrics']['connectedness'] = 100 * ($result['connected_elements'] / ($result['attribute_count'] + $result['object_count']));
|
||||
$results[$k]['metrics']['attack_weight'] = 100 * (2*($result['attack']) + $result['attribute_attack']) / ($result['attribute_count'] + $result['object_count']);
|
||||
$results[$k]['metrics']['other_weight'] = 100 * (2*($result['other']) + $result['attribute_other']) / ($result['attribute_count'] + $result['object_count']);
|
||||
}
|
||||
foreach (['connectedness', 'attack_weight', 'other_weight'] as $metric) {
|
||||
foreach (['connectedness', 'attack_weight', 'other_weight', 'warnings'] as $metric) {
|
||||
if (empty($results[$k]['metrics'][$metric])) {
|
||||
$results[$k]['metrics'][$metric] = 0;
|
||||
}
|
||||
|
@ -331,8 +508,17 @@ class Ls22Shell extends AppShell
|
|||
$results[$k]['metrics'][$metric] = 100;
|
||||
}
|
||||
}
|
||||
$results[$k]['score'] = round(40 * $results[$k]['metrics']['connectedness'] + 40 * $results[$k]['metrics']['attack_weight'] + 20 * $results[$k]['metrics']['other_weight']) / 100;
|
||||
$scores[$k] = $results[$k]['score'];
|
||||
$results[$k]['score'] = round(
|
||||
20 * $results[$k]['metrics']['warnings'] +
|
||||
20 * $results[$k]['metrics']['connectedness'] +
|
||||
40 * $results[$k]['metrics']['attack_weight'] +
|
||||
20 * $results[$k]['metrics']['other_weight']
|
||||
) / 100;
|
||||
$scores[$k]['total'] = $results[$k]['score'];
|
||||
$scores[$k]['warnings'] = round(20 * $results[$k]['metrics']['warnings']);
|
||||
$scores[$k]['connectedness'] = round(20 * $results[$k]['metrics']['connectedness']);
|
||||
$scores[$k]['attack_weight'] = round(40 * $results[$k]['metrics']['attack_weight']);
|
||||
$scores[$k]['other_weight'] = round(20 * $results[$k]['metrics']['other_weight']);
|
||||
}
|
||||
arsort($scores, SORT_DESC);
|
||||
$this->out(str_repeat('=', 128), 1, Shell::NORMAL);
|
||||
|
@ -344,18 +530,34 @@ class Ls22Shell extends AppShell
|
|||
), 1, Shell::NORMAL);
|
||||
$this->out(str_repeat('=', 128), 1, Shell::NORMAL);
|
||||
foreach ($scores as $org => $score) {
|
||||
$score_string = str_repeat('█', round($score));
|
||||
$score_string[0] = str_repeat('█', round($score['warnings']/100));
|
||||
$score_string[1] = str_repeat('█', round($score['connectedness']/100));
|
||||
$score_string[2] = str_repeat('█', round($score['attack_weight']/100));
|
||||
$score_string[3] = str_repeat('█', round($score['other_weight']/100));
|
||||
$this->out(sprintf(
|
||||
'| %s | %s | %s |',
|
||||
str_pad($org, 10, ' ', STR_PAD_RIGHT),
|
||||
sprintf(
|
||||
'<info>%s</info>%s',
|
||||
$score_string,
|
||||
str_repeat(' ', 100 - mb_strlen($score_string))
|
||||
'<error>%s</error><warning>%s</warning><question>%s</question><info>%s</info>%s',
|
||||
$score_string[0],
|
||||
$score_string[1],
|
||||
$score_string[2],
|
||||
$score_string[3],
|
||||
str_repeat(' ', 100 - mb_strlen(implode('', $score_string)))
|
||||
),
|
||||
str_pad($score . '%', 8, ' ', STR_PAD_RIGHT)
|
||||
str_pad($score['total'] . '%', 8, ' ', STR_PAD_RIGHT)
|
||||
), 1, Shell::NORMAL);
|
||||
}
|
||||
$this->out(str_repeat('=', 128), 1, Shell::NORMAL);
|
||||
$this->out(sprintf(
|
||||
'| Legend: %s %s %s %s %s |',
|
||||
'<error>█: Warnings</error>',
|
||||
'<warning>█: Connectedness</warning>',
|
||||
'<question>█: ATT&CK context</question>',
|
||||
'<info>█: Other Context</info>',
|
||||
str_repeat(' ', 52)
|
||||
), 1, Shell::NORMAL);
|
||||
$this->out(str_repeat('=', 128), 1, Shell::NORMAL);
|
||||
file_put_contents(APP . 'tmp/report.json', json_encode($results, JSON_PRETTY_PRINT));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once 'AppShell.php';
|
||||
|
||||
class WorkflowShell extends AppShell {
|
||||
|
||||
public $uses = ['Job', 'Workflow'];
|
||||
public $tasks = ['ConfigLoad'];
|
||||
|
||||
public function executeWorkflowForTrigger()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
if (empty($this->args[0]) || empty($this->args[1]) || empty($this->args[2]) || empty($this->args[3])) {
|
||||
die(__('Invalid number of arguments.'));
|
||||
}
|
||||
|
||||
$trigger_id = $this->args[0];
|
||||
$data = JsonTool::decode($this->args[1]);
|
||||
$logging = JsonTool::decode($this->args[2]);
|
||||
$jobId = $this->args[3];
|
||||
|
||||
$blockingErrors = [];
|
||||
$executionSuccess = $this->Workflow->executeWorkflowForTrigger($trigger_id, $data, $blockingErrors);
|
||||
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$job['Job']['progress'] = 100;
|
||||
$job['Job']['status'] = Job::STATUS_COMPLETED;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
if ($executionSuccess) {
|
||||
$job['Job']['message'] = __('Workflow for trigger `%s` completed execution', $trigger_id);
|
||||
} else {
|
||||
$errorMessage = implode(', ', $blockingErrors);
|
||||
$message = __('Error while executing workflow for trigger `%s`: %s. %s%s', $trigger_id, $logging['message'], PHP_EOL . __('Returned message: %s', $errorMessage));
|
||||
$job['Job']['message'] = $message;
|
||||
}
|
||||
$this->Job->save($job);
|
||||
}
|
||||
|
||||
public function walkGraph()
|
||||
{
|
||||
$this->ConfigLoad->execute();
|
||||
if (empty($this->args[0]) || empty($this->args[1]) || empty($this->args[2]) || empty($this->args[3])) {
|
||||
die(__('Invalid number of arguments.'));
|
||||
}
|
||||
|
||||
$workflow_id = (int)$this->args[0];
|
||||
$workflow = $this->Workflow->fetchWorkflow($workflow_id);
|
||||
$node_id_to_exec = (int)$this->args[1];
|
||||
$roamingData = JsonTool::decode($this->args[2]);
|
||||
$for_path = $this->args[3];
|
||||
$jobId = $this->args[4];
|
||||
|
||||
$concurrentErrors = [];
|
||||
$walkResult = [];
|
||||
$executionSuccess = $this->Workflow->walkGraph(
|
||||
$workflow,
|
||||
$node_id_to_exec,
|
||||
$for_path,
|
||||
$roamingData,
|
||||
$concurrentErrors,
|
||||
$walkResult
|
||||
);
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$job['Job']['progress'] = 100;
|
||||
$job['Job']['status'] = Job::STATUS_COMPLETED;
|
||||
$job['Job']['date_modified'] = date("Y-m-d H:i:s");
|
||||
if ($executionSuccess) {
|
||||
$job['Job']['message'] = __('Workflow concurrent task executed %s nodes starting from node %s.', count($walkResult['executed_nodes']), $node_id_to_exec);
|
||||
} else {
|
||||
$message = __('Error while executing workflow concurrent task. %s', PHP_EOL . implode(', ', $concurrentErrors));
|
||||
$this->Workflow->logExecutionError($workflow, $message);
|
||||
$job['Job']['message'] = $message;
|
||||
}
|
||||
$this->Job->save($job);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ App::uses('Controller', 'Controller');
|
|||
App::uses('File', 'Utility');
|
||||
App::uses('RequestRearrangeTool', 'Tools');
|
||||
App::uses('BlowfishConstantPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('BetterCakeEventManager', 'Tools');
|
||||
|
||||
/**
|
||||
* Application Controller
|
||||
|
@ -34,8 +35,8 @@ class AppController extends Controller
|
|||
|
||||
public $helpers = array('OrgImg', 'FontAwesome', 'UserName');
|
||||
|
||||
private $__queryVersion = '139';
|
||||
public $pyMispVersion = '2.4.157';
|
||||
private $__queryVersion = '144';
|
||||
public $pyMispVersion = '2.4.160';
|
||||
public $phpmin = '7.2';
|
||||
public $phprec = '7.4';
|
||||
public $phptoonew = '8.0';
|
||||
|
@ -434,6 +435,10 @@ class AppController extends Controller
|
|||
);
|
||||
$this->Log->save($log);
|
||||
}
|
||||
$storeAPITime = Configure::read('MISP.store_api_access_time');
|
||||
if (!empty($storeAPITime) && $storeAPITime) {
|
||||
$this->User->updateAPIAccessTime($user);
|
||||
}
|
||||
$this->Session->renew();
|
||||
$this->Session->write(AuthComponent::$sessionKey, $user);
|
||||
$this->isApiAuthed = true;
|
||||
|
@ -810,8 +815,8 @@ class AppController extends Controller
|
|||
ConnectionManager::create('default', $db->config);
|
||||
}
|
||||
$dataSource = $dataSourceConfig['datasource'];
|
||||
if (!in_array($dataSource, array('Database/Mysql', 'Database/Postgres', 'Database/MysqlObserver'))) {
|
||||
throw new Exception('datasource not supported: ' . $dataSource);
|
||||
if (!in_array($dataSource, ['Database/Mysql', 'Database/Postgres', 'Database/MysqlObserver', 'Database/MysqlExtended'], true)) {
|
||||
throw new Exception('Datasource not supported: ' . $dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -908,11 +913,11 @@ class AppController extends Controller
|
|||
/**
|
||||
* generic function to standardise on the collection of parameters. Accepts posted request objects, url params, named url params
|
||||
* @param array $options
|
||||
* @param $exception
|
||||
* @param CakeResponse $exception
|
||||
* @param array $data
|
||||
* @return array|false|mixed
|
||||
* @return array|false
|
||||
*/
|
||||
protected function _harvestParameters($options, &$exception = null, $data = array())
|
||||
protected function _harvestParameters($options, &$exception = null, $data = [])
|
||||
{
|
||||
$request = $options['request'] ?? $this->request;
|
||||
if ($request->is('post')) {
|
||||
|
@ -958,14 +963,15 @@ class AppController extends Controller
|
|||
}
|
||||
}
|
||||
}
|
||||
foreach ($data as $k => $v) {
|
||||
if (!is_array($data[$k])) {
|
||||
$data[$k] = trim($data[$k]);
|
||||
if (strpos($data[$k], '||')) {
|
||||
$data[$k] = explode('||', $data[$k]);
|
||||
foreach ($data as &$v) {
|
||||
if (is_string($v)) {
|
||||
$v = trim($v);
|
||||
if (strpos($v, '||')) {
|
||||
$v = explode('||', $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($v);
|
||||
if (!empty($options['additional_delimiters'])) {
|
||||
if (!is_array($options['additional_delimiters'])) {
|
||||
$options['additional_delimiters'] = array($options['additional_delimiters']);
|
||||
|
@ -975,6 +981,7 @@ class AppController extends Controller
|
|||
foreach ($options['additional_delimiters'] as $delim) {
|
||||
if (strpos($v, $delim) !== false) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($found) {
|
||||
|
@ -1257,17 +1264,17 @@ class AppController extends Controller
|
|||
]);
|
||||
}
|
||||
}
|
||||
/** @var TmpFileTool $final */
|
||||
$final = $model->restSearch($user, $returnFormat, $filters, false, false, $elementCounter, $renderView);
|
||||
if (!empty($renderView) && !empty($final)) {
|
||||
if ($renderView) {
|
||||
$this->layout = false;
|
||||
$final = json_decode($final->intoString(), true);
|
||||
foreach ($final as $key => $data) {
|
||||
$this->set($key, $data);
|
||||
}
|
||||
$this->set($final);
|
||||
$this->render('/Events/module_views/' . $renderView);
|
||||
} else {
|
||||
$filename = $this->RestSearch->getFilename($filters, $scope, $responseType);
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true, $filename, array('X-Result-Count' => $elementCounter, 'X-Export-Module-Used' => $returnFormat, 'X-Response-Format' => $responseType));
|
||||
$headers = ['X-Result-Count' => $elementCounter, 'X-Export-Module-Used' => $returnFormat, 'X-Response-Format' => $responseType];
|
||||
return $this->RestResponse->viewData($final, $responseType, false, true, $filename, $headers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1293,21 +1300,24 @@ class AppController extends Controller
|
|||
* Returns true if user can modify given event.
|
||||
*
|
||||
* @param array $event
|
||||
* @param array|null $user If empty, currently logged user will be used
|
||||
* @return bool
|
||||
*/
|
||||
protected function __canModifyEvent(array $event)
|
||||
protected function __canModifyEvent(array $event, $user = null)
|
||||
{
|
||||
if (!isset($event['Event'])) {
|
||||
throw new InvalidArgumentException('Passed object does not contain an Event.');
|
||||
}
|
||||
|
||||
if ($this->userRole['perm_site_admin']) {
|
||||
$user = $user ?: $this->Auth->user();
|
||||
|
||||
if ($user['Role']['perm_site_admin']) {
|
||||
return true;
|
||||
}
|
||||
if ($this->userRole['perm_modify_org'] && $event['Event']['orgc_id'] == $this->Auth->user()['org_id']) {
|
||||
if ($user['Role']['perm_modify_org'] && $event['Event']['orgc_id'] == $user['org_id']) {
|
||||
return true;
|
||||
}
|
||||
if ($this->userRole['perm_modify'] && $event['Event']['user_id'] == $this->Auth->user()['id']) {
|
||||
if ($user['Role']['perm_modify'] && $event['Event']['user_id'] == $user['id']) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1438,6 +1448,27 @@ class AppController extends Controller
|
|||
return parent::_getViewObject();
|
||||
}
|
||||
|
||||
public function getEventManager()
|
||||
{
|
||||
if (empty($this->_eventManager)) {
|
||||
$this->_eventManager = new BetterCakeEventManager();
|
||||
$this->_eventManager->attach($this->Components);
|
||||
$this->_eventManager->attach($this);
|
||||
}
|
||||
return $this->_eventManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close session without writing changes to them and return current user.
|
||||
* @return array
|
||||
*/
|
||||
protected function _closeSession()
|
||||
{
|
||||
$user = $this->Auth->user();
|
||||
session_abort();
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode JSON with proper error handling.
|
||||
* @param string $dataToDecode
|
||||
|
@ -1446,18 +1477,34 @@ class AppController extends Controller
|
|||
protected function _jsonDecode($dataToDecode)
|
||||
{
|
||||
try {
|
||||
if (defined('JSON_THROW_ON_ERROR')) {
|
||||
// JSON_THROW_ON_ERROR is supported since PHP 7.3
|
||||
return json_decode($dataToDecode, true, 512, JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
$decoded = json_decode($dataToDecode, true);
|
||||
if ($decoded === null) {
|
||||
throw new UnexpectedValueException('Could not parse JSON: ' . json_last_error_msg(), json_last_error());
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
return JsonTool::decode($dataToDecode);
|
||||
} catch (Exception $e) {
|
||||
throw new HttpException('Invalid JSON input. Make sure that the JSON input is a correctly formatted JSON string. This request has been blocked to avoid an unfiltered request.', 405, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mimics what PaginateComponent::paginate() would do, when Model::paginate() is not called
|
||||
*
|
||||
* @param integer $page
|
||||
* @param integer $limit
|
||||
* @param integer $current
|
||||
* @param string $type
|
||||
* @return void
|
||||
*/
|
||||
protected function __setPagingParams(int $page, int $limit, int $current, string $type = 'named')
|
||||
{
|
||||
$this->request->params['paging'] = [
|
||||
'Correlation' => [
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
'current' => $current,
|
||||
'pageCount' => 0,
|
||||
'prevPage' => $page > 1,
|
||||
'nextPage' => $current >= $limit,
|
||||
'options' => [],
|
||||
'paramType' => $type
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,6 +52,7 @@ class AuditLogsController extends AppController
|
|||
'GalaxyClusterRelation',
|
||||
'News',
|
||||
'Warninglist',
|
||||
'Workflow',
|
||||
];
|
||||
|
||||
public $paginate = [
|
||||
|
@ -67,9 +68,9 @@ class AuditLogsController extends AppController
|
|||
],
|
||||
];
|
||||
|
||||
public function __construct($id = false, $table = null, $ds = null)
|
||||
public function __construct($request = null, $response = null)
|
||||
{
|
||||
parent::__construct($id, $table, $ds);
|
||||
parent::__construct($request, $response);
|
||||
$this->actions = [
|
||||
AuditLog::ACTION_ADD => __('Add'),
|
||||
AuditLog::ACTION_EDIT => __('Edit'),
|
||||
|
@ -99,7 +100,22 @@ class AuditLogsController extends AppController
|
|||
$this->paginate['fields'][] = 'request_id';
|
||||
}
|
||||
|
||||
$this->paginate['conditions'] = $this->__searchConditions();
|
||||
$params = $this->IndexFilter->harvestParameters([
|
||||
'ip',
|
||||
'user',
|
||||
'request_id',
|
||||
'authkey_id',
|
||||
'model',
|
||||
'model_id',
|
||||
'event_id',
|
||||
'model_title',
|
||||
'action',
|
||||
'org',
|
||||
'created',
|
||||
'request_type',
|
||||
]);
|
||||
|
||||
$this->paginate['conditions'] = $this->__searchConditions($params);
|
||||
$list = $this->paginate();
|
||||
|
||||
if ($this->_isRest()) {
|
||||
|
@ -133,32 +149,27 @@ class AuditLogsController extends AppController
|
|||
|
||||
public function eventIndex($eventId, $org = null)
|
||||
{
|
||||
$this->loadModel('Event');
|
||||
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $eventId);
|
||||
$event = $this->AuditLog->Event->fetchSimpleEvent($this->Auth->user(), $eventId);
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException('Invalid event.');
|
||||
}
|
||||
|
||||
$this->paginate['conditions'] = $this->__createEventIndexConditions($event);
|
||||
|
||||
$params = $this->IndexFilter->harvestParameters(['created', 'org']);
|
||||
if ($org) {
|
||||
$org = $this->AuditLog->Organisation->fetchOrg($org);
|
||||
if ($org) {
|
||||
$this->paginate['conditions']['AND']['org_id'] = $org['id'];
|
||||
} else {
|
||||
$this->paginate['conditions']['AND']['org_id'] = -1;
|
||||
}
|
||||
$params['org'] = $org;
|
||||
}
|
||||
$this->paginate['conditions'][] = $this->__searchConditions($params);
|
||||
|
||||
$list = $this->paginate();
|
||||
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
// Remove all user info about users from different org
|
||||
$this->loadModel('User');
|
||||
$orgUserIds = $this->User->find('column', array(
|
||||
$orgUserIds = $this->User->find('column', [
|
||||
'conditions' => ['User.org_id' => $this->Auth->user('org_id')],
|
||||
'fields' => ['User.id'],
|
||||
));
|
||||
]);
|
||||
foreach ($list as $k => $item) {
|
||||
if ($item['AuditLog']['user_id'] == 0) {
|
||||
continue;
|
||||
|
@ -199,15 +210,13 @@ class AuditLogsController extends AppController
|
|||
|
||||
public function returnDates($org = 'all')
|
||||
{
|
||||
if (!$this->Auth->user('Role')['perm_sharing_group'] && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
|
||||
if ($org !== 'all' && $org !== $this->Auth->user('Organisation')['name']) {
|
||||
$user = $this->_closeSession();
|
||||
if (!$user['Role']['perm_sharing_group'] && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
|
||||
if ($org !== 'all' && $org !== $user['Organisation']['name']) {
|
||||
throw new MethodNotAllowedException('Invalid organisation.');
|
||||
}
|
||||
}
|
||||
|
||||
// Fetching dates can be slow, so to allow concurrent requests, we can close sessions to release session lock
|
||||
session_write_close();
|
||||
|
||||
$data = $this->AuditLog->returnDates($org);
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
}
|
||||
|
@ -215,23 +224,8 @@ class AuditLogsController extends AppController
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function __searchConditions()
|
||||
private function __searchConditions(array $params)
|
||||
{
|
||||
$params = $this->IndexFilter->harvestParameters([
|
||||
'ip',
|
||||
'user',
|
||||
'request_id',
|
||||
'authkey_id',
|
||||
'model',
|
||||
'model_id',
|
||||
'event_id',
|
||||
'model_title',
|
||||
'action',
|
||||
'org',
|
||||
'created',
|
||||
'request_type',
|
||||
]);
|
||||
|
||||
$qbRules = [];
|
||||
foreach ($params as $key => $value) {
|
||||
if ($key === 'model' && strpos($value, ':') !== false) {
|
||||
|
@ -351,7 +345,7 @@ class AuditLogsController extends AppController
|
|||
return ['event_id' => $event['Event']['id']];
|
||||
}
|
||||
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), [
|
||||
$event = $this->AuditLog->Event->fetchEvent($this->Auth->user(), [
|
||||
'eventid' => $event['Event']['id'],
|
||||
'sgReferenceOnly' => 1,
|
||||
'deleted' => [0, 1],
|
||||
|
|
|
@ -125,7 +125,7 @@ class CerebratesController extends AppController
|
|||
$this->set('title', __('Sync organisation information'));
|
||||
$this->set('question', __('Are you sure you want to download and add / update the remote organisations from the Cerebrate node?'));
|
||||
$this->set('actionName', __('Pull all'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ class CerebratesController extends AppController
|
|||
$this->set('title', __('Sync sharing group information'));
|
||||
$this->set('question', __('Are you sure you want to download and add / update the remote sharing group from the Cerebrate node?'));
|
||||
$this->set('actionName', __('Pull all'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ class CerebratesController extends AppController
|
|||
$this->set('title', __('Download organisation information'));
|
||||
$this->set('question', __('Are you sure you want to download and add / update the remote organisation?'));
|
||||
$this->set('actionName', __('Download'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ class CerebratesController extends AppController
|
|||
$this->set('title', __('Download sharing group information'));
|
||||
$this->set('question', __('Are you sure you want to download and add / update the remote sharing group?'));
|
||||
$this->set('actionName', __('Download'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,8 +97,12 @@ class ACLComponent extends Component
|
|||
'view' => []
|
||||
],
|
||||
'correlations' => [
|
||||
'generateOccurrences' => [],
|
||||
'generateTopCorrelations' => [],
|
||||
'top' => []
|
||||
'overCorrelations' => [],
|
||||
'switchEngine' => [],
|
||||
'top' => [],
|
||||
'truncate' => []
|
||||
],
|
||||
'cryptographicKeys' => [
|
||||
'add' => ['perm_add'],
|
||||
|
@ -232,7 +236,6 @@ class ACLComponent extends Component
|
|||
'getEventGraphTags' => array('*'),
|
||||
'getEventGraphGeneric' => array('*'),
|
||||
'getEventTimeline' => array('*'),
|
||||
'genDistributionGraph' => array('*'),
|
||||
'getDistributionGraph' => array('*'),
|
||||
'getReferenceData' => array('*'),
|
||||
'getReferences' => array('*'),
|
||||
|
@ -340,7 +343,6 @@ class ACLComponent extends Component
|
|||
),
|
||||
'galaxyClusters' => array(
|
||||
'add' => array('perm_galaxy_editor'),
|
||||
'attachToEvent' => array('perm_tagger'),
|
||||
'delete' => array('perm_galaxy_editor'),
|
||||
'detach' => array('perm_tagger'),
|
||||
'edit' => array('perm_galaxy_editor'),
|
||||
|
@ -501,6 +503,7 @@ class ACLComponent extends Component
|
|||
'servers' => array(
|
||||
'add' => array(),
|
||||
'dbSchemaDiagnostic' => array(),
|
||||
'dbConfiguration' => array(),
|
||||
'cache' => array(),
|
||||
'changePriority' => array(),
|
||||
'checkout' => array(),
|
||||
|
@ -671,6 +674,7 @@ class ACLComponent extends Component
|
|||
'view' => array('*'),
|
||||
'unhideTag' => array('perm_tagger'),
|
||||
'hideTag' => array('perm_tagger'),
|
||||
'normalizeCustomTagsToTaxonomyFormat' => [],
|
||||
),
|
||||
'templateElements' => array(
|
||||
'add' => array('perm_template'),
|
||||
|
@ -740,6 +744,7 @@ class ACLComponent extends Component
|
|||
'verifyGPG' => array(),
|
||||
'view' => array('*'),
|
||||
'getGpgPublicKey' => array('*'),
|
||||
'unsubscribe' => ['*'],
|
||||
),
|
||||
'userSettings' => array(
|
||||
'index' => array('*'),
|
||||
|
@ -764,6 +769,32 @@ class ACLComponent extends Component
|
|||
'export' => ['*'],
|
||||
'import' => ['perm_warninglist'],
|
||||
),
|
||||
'workflows' => [
|
||||
'index'=> [],
|
||||
'rebuildRedis'=> [],
|
||||
'edit'=> [],
|
||||
'delete'=> [],
|
||||
'view'=> [],
|
||||
'editor'=> [],
|
||||
'triggers'=> [],
|
||||
'moduleIndex'=> [],
|
||||
'moduleView'=> [],
|
||||
'toggleModule'=> [],
|
||||
'checkGraph'=> [],
|
||||
'executeWorkflow'=> [],
|
||||
'debugToggleField'=> [],
|
||||
'massToggleField'=> [],
|
||||
],
|
||||
'workflowBlueprints' => [
|
||||
'add' => [],
|
||||
'delete' => [],
|
||||
'edit' => [],
|
||||
'export' => [],
|
||||
'import' => [],
|
||||
'index' => [],
|
||||
'update' => [],
|
||||
'view' => [],
|
||||
],
|
||||
'allowedlists' => array(
|
||||
'admin_add' => array('perm_regexp_access'),
|
||||
'admin_delete' => array('perm_regexp_access'),
|
||||
|
@ -981,6 +1012,8 @@ class ACLComponent extends Component
|
|||
|
||||
private function __findAllFunctions()
|
||||
{
|
||||
$functionsToIgnore = ['beforeFilter', 'afterFilter', 'beforeRender', 'getEventManager'];
|
||||
|
||||
$functionFinder = '/function[\s\n]+(\S+)[\s\n]*\(/';
|
||||
$dir = new Folder(APP . 'Controller');
|
||||
$files = $dir->find('.*\.php');
|
||||
|
@ -991,11 +1024,11 @@ class ACLComponent extends Component
|
|||
$controllerName = '*';
|
||||
}
|
||||
$functionArray = array();
|
||||
$fileContents = file_get_contents(APP . 'Controller' . DS . $file);
|
||||
$fileContents = FileAccessTool::readFromFile(APP . 'Controller' . DS . $file);
|
||||
$fileContents = preg_replace('/\/\*[^\*]+?\*\//', '', $fileContents);
|
||||
preg_match_all($functionFinder, $fileContents, $functionArray);
|
||||
foreach ($functionArray[1] as $function) {
|
||||
if ($function[0] !== '_' && $function !== 'beforeFilter' && $function !== 'afterFilter' && $function !== 'beforeRender') {
|
||||
if ($function[0] !== '_' && !in_array($function, $functionsToIgnore, true)) {
|
||||
$results[$controllerName][] = $function;
|
||||
}
|
||||
}
|
||||
|
@ -1016,8 +1049,7 @@ class ACLComponent extends Component
|
|||
$missing = array();
|
||||
foreach ($results as $controller => $functions) {
|
||||
foreach ($functions as $function) {
|
||||
if (!isset(self::ACL_LIST[$controller])
|
||||
|| !in_array($function, array_keys(self::ACL_LIST[$controller]))) {
|
||||
if (!isset(self::ACL_LIST[$controller]) || !in_array($function, array_keys(self::ACL_LIST[$controller]))) {
|
||||
$missing[$controller][] = $function;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
<?php
|
||||
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
|
||||
|
||||
class BlowfishConstantPasswordHasher extends BlowfishPasswordHasher
|
||||
class BlowfishConstantPasswordHasher extends AbstractPasswordHasher
|
||||
{
|
||||
/**
|
||||
* @param string $password
|
||||
* @return string
|
||||
*/
|
||||
public function hash($password)
|
||||
{
|
||||
$hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
if ($hash === false) {
|
||||
throw new RuntimeException('Could not generate hashed password');
|
||||
}
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
* @param string $hashedPassword
|
||||
|
@ -10,6 +23,6 @@ class BlowfishConstantPasswordHasher extends BlowfishPasswordHasher
|
|||
*/
|
||||
public function check($password, $hashedPassword)
|
||||
{
|
||||
return hash_equals($hashedPassword, Security::hash($password, 'blowfish', $hashedPassword));
|
||||
return password_verify($password, $hashedPassword);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,27 +10,29 @@ class IndexFilterComponent extends Component
|
|||
public $Controller;
|
||||
public $isRest = null;
|
||||
|
||||
public function initialize(Controller $controller) {
|
||||
public function initialize(Controller $controller)
|
||||
{
|
||||
$this->Controller = $controller;
|
||||
}
|
||||
|
||||
// generic function to standardise on the collection of parameters. Accepts posted request objects, url params, named url params
|
||||
public function harvestParameters($paramArray, &$exception = array())
|
||||
public function harvestParameters($paramArray, &$exception = [])
|
||||
{
|
||||
$data = array();
|
||||
if (!empty($this->Controller->request->is('post'))) {
|
||||
if (empty($this->Controller->request->data)) {
|
||||
$request = $this->Controller->request;
|
||||
$data = [];
|
||||
if ($request->is('post')) {
|
||||
if (empty($request->data)) {
|
||||
$exception = $this->Controller->RestResponse->throwException(
|
||||
400,
|
||||
__('Either specify the search terms in the url, or POST a json with the filter parameters.'),
|
||||
'/' . $this->Controller->request->params['controller'] . '/' . $this->Controller->action
|
||||
'/' . $request->params['controller'] . '/' . $this->Controller->action
|
||||
);
|
||||
return false;
|
||||
} else {
|
||||
if (isset($this->Controller->request->data['request'])) {
|
||||
$data = $this->Controller->request->data['request'];
|
||||
if (isset($request->data['request'])) {
|
||||
$data = $request->data['request'];
|
||||
} else {
|
||||
$data = $this->Controller->request->data;
|
||||
$data = $request->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,19 +45,20 @@ class IndexFilterComponent extends Component
|
|||
$data[$p] = $options['ordered_url_params'][$p];
|
||||
$data[$p] = str_replace(';', ':', $data[$p]);
|
||||
}
|
||||
if (isset($this->Controller->params['named'][$p])) {
|
||||
$data[$p] = str_replace(';', ':', $this->Controller->params['named'][$p]);
|
||||
if (isset($request->params['named'][$p])) {
|
||||
$data[$p] = str_replace(';', ':', $request->params['named'][$p]);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($data as $k => $v) {
|
||||
if (!is_array($data[$k])) {
|
||||
$data[$k] = trim($data[$k]);
|
||||
if (strpos($data[$k], '||')) {
|
||||
$data[$k] = explode('||', $data[$k]);
|
||||
foreach ($data as &$v) {
|
||||
if (is_string($v)) {
|
||||
$v = trim($v);
|
||||
if (strpos($v, '||')) {
|
||||
$v = explode('||', $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($v);
|
||||
if (!empty($options['additional_delimiters'])) {
|
||||
if (!is_array($options['additional_delimiters'])) {
|
||||
$options['additional_delimiters'] = array($options['additional_delimiters']);
|
||||
|
@ -65,6 +68,7 @@ class IndexFilterComponent extends Component
|
|||
foreach ($options['additional_delimiters'] as $delim) {
|
||||
if (strpos($v, $delim) !== false) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($found) {
|
||||
|
|
|
@ -479,39 +479,70 @@ class RestResponseComponent extends Component
|
|||
return [];
|
||||
}
|
||||
|
||||
public function saveFailResponse($controller, $action, $id = false, $validationErrors, $format = false, $data = null)
|
||||
/**
|
||||
* @param string $controller
|
||||
* @param string $action
|
||||
* @param int|false $id
|
||||
* @param mixed $validationErrors
|
||||
* @param string|false $format
|
||||
* @param mixed $data
|
||||
* @return CakeResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function saveFailResponse($controller, $action, $id, $validationErrors, $format = false, $data = null)
|
||||
{
|
||||
$response = array();
|
||||
$action = $this->__dissectAdminRouting($action);
|
||||
$stringifiedAction = $action['action'];
|
||||
if (isset(self::CONVERT_ACTION_TO_MESSAGE[$controller][$action['action']])) {
|
||||
$stringifiedAction = self::CONVERT_ACTION_TO_MESSAGE[$controller][$action['action']];
|
||||
if (isset(self::CONVERT_ACTION_TO_MESSAGE[$controller][$stringifiedAction])) {
|
||||
$stringifiedAction = self::CONVERT_ACTION_TO_MESSAGE[$controller][$stringifiedAction];
|
||||
}
|
||||
$response['saved'] = false;
|
||||
$response['name'] = 'Could not ' . $stringifiedAction . ' ' . Inflector::singularize($controller);
|
||||
$response['message'] = $response['name'];
|
||||
$message = 'Could not ' . $stringifiedAction . ' ' . Inflector::singularize($controller);
|
||||
|
||||
$response = [
|
||||
'saved' => false,
|
||||
'name' => $message,
|
||||
'message' => $message,
|
||||
'url' => $this->__generateURL($action, $controller, $id),
|
||||
'errors' => $validationErrors,
|
||||
];
|
||||
if ($data !== null) {
|
||||
$response['data'] = $data;
|
||||
}
|
||||
$response['url'] = $this->__generateURL($action, $controller, $id);
|
||||
$response['errors'] = $validationErrors;
|
||||
if ($id) {
|
||||
$response['id'] = $id;
|
||||
}
|
||||
return $this->__sendResponse($response, 403, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controller
|
||||
* @param string $action
|
||||
* @param int|false $id
|
||||
* @param string|false $format
|
||||
* @param string|false $message
|
||||
* @param mixed $data
|
||||
* @return CakeResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function saveSuccessResponse($controller, $action, $id = false, $format = false, $message = false, $data = null)
|
||||
{
|
||||
$action = $this->__dissectAdminRouting($action);
|
||||
if (!$message) {
|
||||
$message = Inflector::singularize($controller) . ' ' . $action['action'] . ((substr($action['action'], -1) == 'e') ? 'd' : 'ed');
|
||||
$message = Inflector::singularize($controller) . ' ' . $action['action'] . ((substr($action['action'], -1) === 'e') ? 'd' : 'ed');
|
||||
}
|
||||
$response['saved'] = true;
|
||||
$response['success'] = true;
|
||||
$response['name'] = $message;
|
||||
$response['message'] = $response['name'];
|
||||
$response = [
|
||||
'saved' => true,
|
||||
'success' => true,
|
||||
'name' => $message,
|
||||
'message' => $message,
|
||||
'url' => $this->__generateURL($action, $controller, $id),
|
||||
];
|
||||
if ($data !== null) {
|
||||
$response['data'] = $data;
|
||||
}
|
||||
$response['url'] = $this->__generateURL($action, $controller, $id);
|
||||
if ($id) {
|
||||
$response['id'] = $id;
|
||||
}
|
||||
return $this->__sendResponse($response, 200, $format);
|
||||
}
|
||||
|
||||
|
@ -527,7 +558,7 @@ class RestResponseComponent extends Component
|
|||
*/
|
||||
private function __sendResponse($response, $code, $format = false, $raw = false, $download = false, $headers = array())
|
||||
{
|
||||
$format = strtolower($format);
|
||||
$format = !empty($format) ? strtolower($format) : 'json';
|
||||
if ($format === 'application/xml' || $format === 'xml') {
|
||||
if (!$raw) {
|
||||
if (isset($response[0])) {
|
||||
|
@ -550,11 +581,7 @@ class RestResponseComponent extends Component
|
|||
} elseif ($format === 'csv' || $format === 'text/csv') {
|
||||
$type = 'csv';
|
||||
} else {
|
||||
if (empty($format)) {
|
||||
$type = 'json';
|
||||
} else {
|
||||
$type = $format;
|
||||
}
|
||||
$type = $format;
|
||||
$dumpSql = !empty($this->Controller->sql_dump) && Configure::read('debug') > 1;
|
||||
if (!$raw) {
|
||||
if (is_string($response)) {
|
||||
|
@ -601,10 +628,16 @@ class RestResponseComponent extends Component
|
|||
}
|
||||
|
||||
if ($response instanceof TmpFileTool) {
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
$etag = '"' . $response->hash('sha1') . '"';
|
||||
if ($_SERVER['HTTP_IF_NONE_MATCH'] === $etag) {
|
||||
return new CakeResponse(['status' => 304]);
|
||||
}
|
||||
$headers['ETag'] = $etag;
|
||||
}
|
||||
if ($this->signContents) {
|
||||
$this->CryptographicKey = ClassRegistry::init('CryptographicKey');
|
||||
$data = $response->intoString();
|
||||
$headers['x-pgp-signature'] = base64_encode($this->CryptographicKey->signWithInstanceKey($data));
|
||||
$headers['x-pgp-signature'] = $this->sign($data);
|
||||
$cakeResponse = new CakeResponse(['body' => $data, 'status' => $code, 'type' => $type]);
|
||||
} else {
|
||||
App::uses('CakeResponseFile', 'Tools');
|
||||
|
@ -612,9 +645,18 @@ class RestResponseComponent extends Component
|
|||
$cakeResponse->file($response);
|
||||
}
|
||||
} else {
|
||||
$cakeResponse = new CakeResponse(array('body' => $response, 'status' => $code, 'type' => $type));
|
||||
// Check if resource was changed when `If-None-Match` header is send and return 304 Not Modified
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
$etag = '"' . sha1($response) . '"';
|
||||
if ($_SERVER['HTTP_IF_NONE_MATCH'] === $etag) {
|
||||
return new CakeResponse(['status' => 304]);
|
||||
}
|
||||
// Generate etag just when HTTP_IF_NONE_MATCH is set
|
||||
$headers['ETag'] = $etag;
|
||||
}
|
||||
$cakeResponse = new CakeResponse(['body' => $response, 'status' => $code, 'type' => $type]);
|
||||
if ($this->signContents) {
|
||||
$headers['x-pgp-signature'] = base64_encode($this->CryptographicKey->signWithInstanceKey($response));
|
||||
$headers['x-pgp-signature'] = $this->sign($response);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,6 +681,25 @@ class RestResponseComponent extends Component
|
|||
return $cakeResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $response
|
||||
* @return string Signature as base64 encoded string
|
||||
* @throws Crypt_GPG_BadPassphraseException
|
||||
* @throws Crypt_GPG_Exception
|
||||
* @throws Crypt_GPG_KeyNotFoundException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function sign($response)
|
||||
{
|
||||
/** @var CryptographicKey $cryptographicKey */
|
||||
$cryptographicKey = ClassRegistry::init('CryptographicKey');
|
||||
$signature = $cryptographicKey->signWithInstanceKey($response);
|
||||
if (!$signature) {
|
||||
throw new Exception('Could not sign data.');
|
||||
}
|
||||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if request comes from automatic tool (like other MISP instance or PyMISP) or AJAX
|
||||
* @return bool
|
||||
|
|
|
@ -122,8 +122,8 @@ class CorrelationExclusionsController extends AppController
|
|||
} else {
|
||||
$this->set('title', __('Clean up correlations'));
|
||||
$this->set('question', __('Execute the cleaning of all correlations that are at odds with the exclusion rules? This will delete all matching correlations.'));
|
||||
$this->set('actionName', 'clean');
|
||||
$this->layout = 'ajax';
|
||||
$this->set('actionName', __('Clean'));
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@ class CorrelationsController extends AppController
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->__setPagingParams($query['page'], $query['limit'], count($data), 'named');
|
||||
|
||||
$this->set('age', $age);
|
||||
$this->set('age_unit', $unit);
|
||||
$this->set('data', $data);
|
||||
|
@ -72,4 +75,147 @@ class CorrelationsController extends AppController
|
|||
$this->redirect(['controller' => 'correlations', 'action' => 'top']);
|
||||
}
|
||||
}
|
||||
|
||||
public function overCorrelations()
|
||||
{
|
||||
$query = [
|
||||
'limit' => 50,
|
||||
'page' => 1,
|
||||
'order' => 'occurrence desc'
|
||||
];
|
||||
foreach (array_keys($query) as $custom_param) {
|
||||
if (isset($this->params['named'][$custom_param])) {
|
||||
$query[$custom_param] = $this->params['named'][$custom_param];
|
||||
}
|
||||
}
|
||||
if (isset($this->params['named']['scope'])) {
|
||||
$limit = $this->Correlation->OverCorrelatingValue->getLimit();
|
||||
if ($this->params['named']['scope'] === 'over_correlating') {
|
||||
$query['conditions'][] = ['occurrence >=' => $limit];
|
||||
} else if ($this->params['named']['scope'] === 'not_over_correlating') {
|
||||
$query['conditions'][] = ['occurrence <' => $limit];
|
||||
}
|
||||
}
|
||||
$data = $this->Correlation->OverCorrelatingValue->getOverCorrelations($query);
|
||||
$data = $this->Correlation->attachExclusionsToOverCorrelations($data);
|
||||
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($data, 'json');
|
||||
} else {
|
||||
$this->__setPagingParams($query['page'], $query['limit'], count($data), 'named');
|
||||
$this->set('data', $data);
|
||||
$this->set('title_for_layout', __('Index of over correlating values'));
|
||||
$this->set('menuData', [
|
||||
'menuList' => 'correlationExclusions',
|
||||
'menuItem' => 'over'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function switchEngine(string $engine)
|
||||
{
|
||||
$this->loadModel('Server');
|
||||
if (!isset($this->Correlation->validEngines[$engine])) {
|
||||
throw new MethodNotAllowedException(__('Not a valid engine choice. Please make sure you pass one of the following: ', implode(', ', array_keys($this->Correlation->validEngines))));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
$setting = $this->Server->getSettingData('MISP.correlation_engine');
|
||||
$result = $this->Server->serverSettingsEditValue($this->Auth->user(), $setting, $engine);
|
||||
if ($result === true) {
|
||||
$message = __('Engine switched.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Correlations', 'switchEngine', false, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(['controller' => 'servers', 'action' => 'serverSettings', 'correlations']);
|
||||
}
|
||||
} else {
|
||||
$message = __('Couldn\'t switch to the requested engine.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Correlations', 'switchEngine', false, $message, $this->response->type());
|
||||
} else {
|
||||
$this->Flash->error($message);
|
||||
$this->redirect(['controller' => 'servers', 'action' => 'serverSettings', 'correlations']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->set('engine', $engine);
|
||||
$this->render('ajax/switch_engine_confirmation');
|
||||
}
|
||||
}
|
||||
|
||||
public function truncate(string $engine)
|
||||
{
|
||||
if (!isset($this->Correlation->validEngines[$engine])) {
|
||||
throw new MethodNotAllowedException(__('Not a valid engine choice. Please make sure you pass one of the following: ', implode(', ', array_keys($this->Correlation->validEngines))));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
if (!Configure::read('MISP.background_jobs')) {
|
||||
$result = $this->Correlation->truncate($this->Auth->user(), $engine);
|
||||
$message = $result ? __('Table truncated.') : __('Could not truncate table');
|
||||
if ($this->_isRest()) {
|
||||
if ($result) {
|
||||
$this->RestResponse->saveSuccessResponse('Correlations', 'truncate', false, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->RestResponse->saveFailResponse('Correlations', 'truncate', false, $message, $this->response->type());
|
||||
}
|
||||
} else {
|
||||
$this->Flash->{$result ? 'success' : 'error'}($message);
|
||||
$this->redirect(['controller' => 'servers', 'action' => 'serverSettings', 'correlations']);
|
||||
}
|
||||
} else {
|
||||
$job = ClassRegistry::init('Job');
|
||||
$jobId = $job->createJob(
|
||||
'SYSTEM',
|
||||
Job::WORKER_DEFAULT,
|
||||
'truncate table',
|
||||
$this->Correlation->validEngines[$engine],
|
||||
'Job created.'
|
||||
);
|
||||
|
||||
$this->Correlation->Attribute->getBackgroundJobsTool()->enqueue(
|
||||
BackgroundJobsTool::DEFAULT_QUEUE,
|
||||
BackgroundJobsTool::CMD_ADMIN,
|
||||
[
|
||||
'truncateTable',
|
||||
$this->Auth->user('id'),
|
||||
$engine,
|
||||
$jobId
|
||||
],
|
||||
true,
|
||||
$jobId
|
||||
);
|
||||
|
||||
$message = __('Job queued. You can view the progress if you navigate to the active jobs view (Administration -> Jobs).');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Correlations', 'truncate', false, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(['controller' => 'servers', 'action' => 'serverSettings', 'correlations']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->set('engine', $engine);
|
||||
$this->set('table_name', $this->Correlation->validEngines[$engine]);
|
||||
$this->render('ajax/truncate_confirmation');
|
||||
}
|
||||
}
|
||||
|
||||
public function generateOccurrences()
|
||||
{
|
||||
$this->loadModel('OverCorrelatingValue');
|
||||
$this->OverCorrelatingValue->generateOccurrencesRouter();
|
||||
$message = __('Job queued.');
|
||||
if (Configure::read('MISP.background_jobs')) {
|
||||
$message = __('Job queued.');
|
||||
} else {
|
||||
$message = __('Over-correlations counted successfully.');
|
||||
}
|
||||
if (!$this->_isRest()) {
|
||||
$this->Flash->info($message);
|
||||
$this->redirect(['controller' => 'correlations', 'action' => 'overCorrelations']);
|
||||
} else {
|
||||
return $this->RestResponse->saveSuccessResponse('Correlations', 'generateOccurrences', false, $this->response->type(), $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ class CryptographicKeysController extends AppController
|
|||
nl2br(h($key['CryptographicKey']['key_data']))
|
||||
)
|
||||
);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/display');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,17 +12,20 @@ class DashboardsController extends AppController
|
|||
public function beforeFilter()
|
||||
{
|
||||
parent::beforeFilter();
|
||||
$this->Security->unlockedActions = array_merge(array('renderWidget', 'getForm'), $this->Security->unlockedActions);
|
||||
$this->Security->unlockedActions[] = 'renderWidget';
|
||||
$this->Security->unlockedActions[] = 'getForm';
|
||||
if ($this->request->action === 'renderWidget') {
|
||||
$this->Security->doNotGenerateToken = true;
|
||||
}
|
||||
}
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999
|
||||
);
|
||||
|
||||
public function index($template_id = false)
|
||||
{
|
||||
$this->loadModel('UserSetting');
|
||||
if (empty($template_id)) {
|
||||
$params = array(
|
||||
'conditions' => array(
|
||||
|
@ -30,7 +33,7 @@ class DashboardsController extends AppController
|
|||
'UserSetting.setting' => 'dashboard'
|
||||
)
|
||||
);
|
||||
$userSettings = $this->UserSetting->find('first', $params);
|
||||
$userSettings = $this->User->UserSetting->find('first', $params);
|
||||
} else {
|
||||
$dashboardTemplate = $this->Dashboard->getDashboardTemplate($this->Auth->user(), $template_id);
|
||||
if (empty($dashboardTemplate)) {
|
||||
|
@ -80,7 +83,6 @@ class DashboardsController extends AppController
|
|||
// continue, we just don't load the widget
|
||||
}
|
||||
}
|
||||
$this->layout = 'dashboard';
|
||||
$this->set('widgets', $widgets);
|
||||
}
|
||||
|
||||
|
@ -112,22 +114,20 @@ class DashboardsController extends AppController
|
|||
public function updateSettings()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$this->UserSetting = ClassRegistry::init('UserSetting');
|
||||
if (!isset($this->request->data['Dashboard']['value'])) {
|
||||
throw new InvalidArgumentException(__('No setting data found.'));
|
||||
}
|
||||
$data = array(
|
||||
'UserSetting' => array(
|
||||
'user_id' => $this->Auth->user('id'),
|
||||
'setting' => 'dashboard',
|
||||
'value' => $this->request->data['Dashboard']['value']
|
||||
)
|
||||
);
|
||||
$result = $this->UserSetting->setSetting($this->Auth->user(), $data);
|
||||
$result = $this->User->UserSetting->setSetting($this->Auth->user(), $data);
|
||||
if ($result) {
|
||||
return $this->RestResponse->saveSuccessResponse('Dashboard', 'updateSettings', false, false, __('Settings updated.'));
|
||||
}
|
||||
return $this->RestResponse->saveFailResponse('Dashboard', 'updateSettings', false, $this->UserSetting->validationErrors, $this->response->type());
|
||||
return $this->RestResponse->saveFailResponse('Dashboard', 'updateSettings', false, $this->User->UserSetting->validationErrors, $this->response->type());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ class DashboardsController extends AppController
|
|||
}
|
||||
|
||||
$user = $this->Auth->user();
|
||||
@session_write_close(); // allow concurrent AJAX requests (session hold lock by default)
|
||||
@session_abort(); // allow concurrent AJAX requests (session hold lock by default)
|
||||
|
||||
if (empty($this->request->data['data'])) {
|
||||
$this->request->data = array('data' => $this->request->data);
|
||||
|
@ -237,7 +237,6 @@ class DashboardsController extends AppController
|
|||
|
||||
public function saveTemplate($update = false)
|
||||
{
|
||||
$this->loadModel('UserSetting');
|
||||
if (!empty($update)) {
|
||||
$conditions = array('Dashboard.id' => $update);
|
||||
if (Validation::uuid($update)) {
|
||||
|
@ -260,7 +259,7 @@ class DashboardsController extends AppController
|
|||
}
|
||||
$data = $this->request->data;
|
||||
if (empty($update)) { // save the template stored in user setting and make it persistent
|
||||
$data['value'] = $this->UserSetting->getSetting($this->Auth->user('id'), 'dashboard');
|
||||
$data['value'] = $this->User->UserSetting->getSetting($this->Auth->user('id'), 'dashboard');
|
||||
}
|
||||
$result = $this->Dashboard->saveDashboardTemplate($this->Auth->user(), $data, $update);
|
||||
if ($this->_isRest()) {
|
||||
|
@ -279,7 +278,6 @@ class DashboardsController extends AppController
|
|||
} else {
|
||||
$this->layout = false;
|
||||
}
|
||||
$this->loadModel('User');
|
||||
$permFlags = array(0 => __('Unrestricted'));
|
||||
foreach ($this->User->Role->permFlags as $perm_flag => $perm_data) {
|
||||
$permFlags[$perm_flag] = $perm_data['text'];
|
||||
|
|
|
@ -14,8 +14,8 @@ class EventReportsController extends AppController
|
|||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'order' => array(
|
||||
'EventReport.event_id' => 'ASC',
|
||||
'EventReport.name' => 'ASC'
|
||||
'EventReport.event_id' => 'ASC',
|
||||
'EventReport.name' => 'ASC'
|
||||
),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
|
@ -78,8 +78,9 @@ class EventReportsController extends AppController
|
|||
if (!$this->_isRest()) {
|
||||
throw new MethodNotAllowedException(__('This function can only be reached via the API.'));
|
||||
}
|
||||
$report = $this->EventReport->simpleFetchById($this->Auth->user(), $reportId);
|
||||
$proxyMISPElements = $this->EventReport->getProxyMISPElements($this->Auth->user(), $report['EventReport']['event_id']);
|
||||
$user = $this->_closeSession();
|
||||
$report = $this->EventReport->simpleFetchById($user, $reportId);
|
||||
$proxyMISPElements = $this->EventReport->getProxyMISPElements($user, $report['EventReport']['event_id']);
|
||||
return $this->RestResponse->viewData($proxyMISPElements, $this->response->type());
|
||||
}
|
||||
|
||||
|
@ -139,7 +140,7 @@ class EventReportsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This function can only be reached via AJAX.'));
|
||||
} else {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('report', $report);
|
||||
$this->render('ajax/delete');
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ class EventReportsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This function can only be reached via AJAX.'));
|
||||
} else {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('report', $report);
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ class EventReportsController extends AppController
|
|||
$reports = $this->EventReport->find('all', [
|
||||
'recursive' => -1,
|
||||
'conditions' => $compiledConditions,
|
||||
'contain' => $this->EventReport->defaultContain,
|
||||
'contain' => EventReport::DEFAULT_CONTAIN,
|
||||
]);
|
||||
return $this->RestResponse->viewData($reports, $this->response->type());
|
||||
} else {
|
||||
|
@ -201,6 +202,8 @@ class EventReportsController extends AppController
|
|||
$fetcherModule = $this->EventReport->isFetchURLModuleEnabled();
|
||||
$this->set('importModuleEnabled', is_array($fetcherModule));
|
||||
$this->render('ajax/indexForEvent');
|
||||
} else {
|
||||
$this->set('title_for_layout', __('Event Reports'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +233,7 @@ class EventReportsController extends AppController
|
|||
return $this->__getFailResponseBasedOnContext($errorMessage, array(), 'applySuggestions', $reportId);
|
||||
}
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('reportId', $reportId);
|
||||
$this->render('ajax/extractAllFromReport');
|
||||
}
|
||||
|
@ -286,7 +289,7 @@ class EventReportsController extends AppController
|
|||
return $this->__getFailResponseBasedOnContext($errorMessage, array(), 'applySuggestions', $reportId);
|
||||
}
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/replaceSuggestionInReport');
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +328,7 @@ class EventReportsController extends AppController
|
|||
}
|
||||
$this->set('importModuleEnabled', is_array($fetcherModule));
|
||||
$this->set('event_id', $event_id);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/importReportFromUrl');
|
||||
}
|
||||
|
||||
|
@ -367,7 +370,7 @@ class EventReportsController extends AppController
|
|||
}
|
||||
}
|
||||
$this->set('event_id', $eventId);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/reportFromEvent');
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class EventsController extends AppController
|
|||
'sort', 'direction', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'attributeFilter', 'page',
|
||||
'searchFor', 'proposal', 'correlation', 'warning', 'deleted', 'includeRelatedTags', 'includeDecayScore', 'distribution',
|
||||
'taggedAttributes', 'galaxyAttachedAttributes', 'objectType', 'attributeType', 'feed', 'server', 'toIDS',
|
||||
'sighting', 'includeSightingdb', 'warninglistId'
|
||||
'sighting', 'includeSightingdb', 'warninglistId', 'correlationId',
|
||||
);
|
||||
|
||||
// private
|
||||
|
@ -52,11 +52,12 @@ class EventsController extends AppController
|
|||
'taggedAttributes' => '',
|
||||
'galaxyAttachedAttributes' => '',
|
||||
'warninglistId' => '',
|
||||
'correlationId' => '',
|
||||
);
|
||||
|
||||
// private
|
||||
const DEFAULT_HIDDEN_INDEX_COLUMNS = [
|
||||
'timestmap',
|
||||
'timestamp',
|
||||
'publish_timestamp'
|
||||
];
|
||||
|
||||
|
@ -107,7 +108,7 @@ class EventsController extends AppController
|
|||
$this->paginate = Set::merge($this->paginate, array('conditions' => $conditions));
|
||||
}
|
||||
|
||||
if ($this->request->action === 'checkLocks') {
|
||||
if (in_array($this->request->action, ['checkLocks', 'getDistributionGraph'], true)) {
|
||||
$this->Security->doNotGenerateToken = true;
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +619,7 @@ class EventsController extends AppController
|
|||
if (empty($usersToMatch)) {
|
||||
$nothing = true;
|
||||
} else {
|
||||
$this->paginate['conditions']['AND'][] = ['Event.user_id' => array_unique($usersToMatch)];
|
||||
$this->paginate['conditions']['AND'][] = ['Event.user_id' => array_unique($usersToMatch, SORT_REGULAR)];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -749,7 +750,7 @@ class EventsController extends AppController
|
|||
$this->set('analysisLevels', $this->Event->analysisLevels);
|
||||
$this->set('distributionLevels', $this->Event->distributionLevels);
|
||||
$this->set('shortDist', $this->Event->shortDist);
|
||||
$this->set('distributionData', $this->genDistributionGraph(-1));
|
||||
$this->set('distributionData', $this->__genDistributionGraph(-1));
|
||||
$this->set('urlparams', $urlparams);
|
||||
$this->set('passedArgsArray', $passedArgsArray);
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
|
@ -1210,46 +1211,7 @@ class EventsController extends AppController
|
|||
$this->set('tags', $tagNames);
|
||||
$this->set('tagJSON', json_encode($tagJSON));
|
||||
$this->set('rules', $rules);
|
||||
$this->layout = 'ajax';
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a value on an attribute level for a specific field.
|
||||
*
|
||||
* @param array $attribute An attribute
|
||||
* @param array $fields List of keys in attribute to search in
|
||||
* @param array $searchParts Values to search
|
||||
* @return bool Returns true on match
|
||||
*/
|
||||
private function __valueInFieldAttribute($attribute, $fields, $searchParts)
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
if (strpos($field, 'Tag') === 0) {
|
||||
if (empty($attribute['AttributeTag'])) {
|
||||
continue;
|
||||
}
|
||||
$fieldValues = Hash::extract($attribute, 'AttributeTag.{n}.' . $field);
|
||||
foreach ($fieldValues as $fieldValue) {
|
||||
$fieldValue = mb_strtolower($fieldValue);
|
||||
foreach ($searchParts as $s) {
|
||||
if (strpos($fieldValue, $s) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isset($attribute[$field])) {
|
||||
continue;
|
||||
}
|
||||
$fieldValue = mb_strtolower($attribute[$field]);
|
||||
foreach ($searchParts as $s) {
|
||||
if (strpos($fieldValue, $s) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
$this->layout = false;
|
||||
}
|
||||
|
||||
public function viewEventAttributes($id, $all = false)
|
||||
|
@ -1258,7 +1220,10 @@ class EventsController extends AppController
|
|||
'paramArray' => self::ACCEPTED_FILTERING_NAMED_PARAMS,
|
||||
'named_params' => $this->request->params['named']
|
||||
);
|
||||
$filters = $this->_harvestParameters($filterData);
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
if ($exception) {
|
||||
return $exception;
|
||||
}
|
||||
|
||||
// Remove default filters
|
||||
foreach ($filters as $filterName => $filterValue) {
|
||||
|
@ -1277,10 +1242,10 @@ class EventsController extends AppController
|
|||
'fetchFullClusters' => false,
|
||||
'includeAllTags' => true,
|
||||
'includeGranularCorrelations' => true,
|
||||
'includeEventCorrelations' => false,
|
||||
'includeEventCorrelations' => true, // event correlations are need for filtering
|
||||
'noEventReports' => true, // event reports for view are loaded dynamically
|
||||
'noSightings' => true,
|
||||
'includeServerCorrelations' => $filters['includeServerCorrelations'] ?? 1.
|
||||
'includeServerCorrelations' => $filters['includeServerCorrelations'] ?? 1,
|
||||
];
|
||||
if (isset($filters['extended'])) {
|
||||
$conditions['extended'] = 1;
|
||||
|
@ -1294,7 +1259,7 @@ class EventsController extends AppController
|
|||
if (isset($filters['deleted'])) {
|
||||
if ($filters['deleted'] == 1) { // both
|
||||
$conditions['deleted'] = [0, 1];
|
||||
} elseif ($filters['deleted'] == 0) { // not-deleted only
|
||||
} elseif ($filters['deleted'] == 0) { // not-deleted only (default)
|
||||
$conditions['deleted'] = 0;
|
||||
} else { // only deleted
|
||||
$conditions['deleted'] = 1;
|
||||
|
@ -1404,7 +1369,7 @@ class EventsController extends AppController
|
|||
$advancedFiltering = $this->__checkIfAdvancedFiltering($filters);
|
||||
$this->set('advancedFilteringActive', $advancedFiltering['active'] ? 1 : 0);
|
||||
$this->set('advancedFilteringActiveRules', $advancedFiltering['activeRules']);
|
||||
$this->set('mayModify', $this->__canModifyEvent($event));
|
||||
$this->set('mayModify', $this->__canModifyEvent($event, $user));
|
||||
$this->set('mayPublish', $this->__canPublishEvent($event));
|
||||
$this->response->disableCache();
|
||||
|
||||
|
@ -1418,7 +1383,7 @@ class EventsController extends AppController
|
|||
}
|
||||
|
||||
if (!empty($filters['includeSightingdb']) && Configure::read('Plugin.Sightings_sighting_db_enable')) {
|
||||
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($this->Auth->user()));
|
||||
$this->set('sightingdbs', $this->Sightingdb->getSightingdbList($user));
|
||||
}
|
||||
$this->set('currentUri', $this->request->here);
|
||||
$this->layout = false;
|
||||
|
@ -1658,10 +1623,10 @@ class EventsController extends AppController
|
|||
$this->set('object_count', $objectCount);
|
||||
$this->set('warnings', $this->Event->generateWarnings($event));
|
||||
$this->set('menuData', array('menuList' => 'event', 'menuItem' => 'viewEvent'));
|
||||
$this->set('mayModify', $this->__canModifyEvent($event));
|
||||
$this->set('mayModify', $this->__canModifyEvent($event, $user));
|
||||
$this->set('mayPublish', $this->__canPublishEvent($event));
|
||||
try {
|
||||
$instanceKey = $this->Event->CryptographicKey->ingestInstanceKey();
|
||||
$instanceKey = $event['Event']['protected'] ? $this->Event->CryptographicKey->ingestInstanceKey() : null;
|
||||
} catch (Exception $e) {
|
||||
$instanceKey = null;
|
||||
}
|
||||
|
@ -1672,21 +1637,13 @@ class EventsController extends AppController
|
|||
private function __eventViewCommon(array $user)
|
||||
{
|
||||
$this->set('defaultFilteringRules', self::DEFAULT_FILTERING_RULE);
|
||||
$this->set('typeGroups', array_keys($this->Event->Attribute->typeGroupings));
|
||||
$this->set('typeGroups', array_keys(Attribute::TYPE_GROUPINGS));
|
||||
|
||||
$orgTable = $this->Event->Orgc->find('list', array(
|
||||
'fields' => array('Orgc.id', 'Orgc.name')
|
||||
));
|
||||
$this->set('orgTable', $orgTable);
|
||||
|
||||
$this->loadModel('Warninglist');
|
||||
$warninglists = $this->Warninglist->find('list', [
|
||||
'fields' => ['Warninglist.id', 'Warninglist.name'],
|
||||
'order' => ['Warninglist.name'],
|
||||
'conditions' => ['Warninglist.enabled' => true],
|
||||
]);
|
||||
$this->set('warninglists', $warninglists);
|
||||
|
||||
$dataForView = array(
|
||||
'Attribute' => array('attrDescriptions' => 'fieldDescriptions', 'distributionDescriptions' => 'distributionDescriptions', 'distributionLevels' => 'distributionLevels', 'shortDist' => 'shortDist'),
|
||||
'Event' => array('eventDescriptions' => 'fieldDescriptions', 'analysisDescriptions' => 'analysisDescriptions', 'analysisLevels' => 'analysisLevels')
|
||||
|
@ -2008,7 +1965,7 @@ class EventsController extends AppController
|
|||
* @param string $searchFor
|
||||
* @param string|false $filterColumnsOverwrite
|
||||
*/
|
||||
private function __applyQueryString(&$event, $searchFor, $filterColumnsOverwrite=false)
|
||||
private function __applyQueryString(&$event, $searchFor, $filterColumnsOverwrite = false)
|
||||
{
|
||||
// filtering on specific columns is specified
|
||||
if ($filterColumnsOverwrite !== false) {
|
||||
|
@ -2016,7 +1973,7 @@ class EventsController extends AppController
|
|||
} else {
|
||||
$filterColumnsOverwrite = Configure::read('MISP.event_view_filter_fields') ?: 'id,uuid,value,comment,type,category,Tag.name';
|
||||
$filterValue = array_map('trim', explode(",", $filterColumnsOverwrite));
|
||||
$validFilters = array('id', 'uuid', 'value', 'comment', 'type', 'category', 'Tag.name');
|
||||
$validFilters = ['id', 'uuid', 'value', 'comment', 'type', 'category', 'Tag.name'];
|
||||
foreach ($filterValue as $k => $v) {
|
||||
if (!in_array($v, $validFilters, true)) {
|
||||
unset($filterValue[$k]);
|
||||
|
@ -2027,41 +1984,81 @@ class EventsController extends AppController
|
|||
$searchParts = explode('|', mb_strtolower($searchFor));
|
||||
|
||||
// search in all attributes
|
||||
foreach ($event['Attribute'] as $k => $attribute) {
|
||||
if (!$this->__valueInFieldAttribute($attribute, $filterValue, $searchParts)) {
|
||||
unset($event['Attribute'][$k]);
|
||||
$foundAttributes = [];
|
||||
foreach ($event['Attribute'] as $attribute) {
|
||||
if ($this->__valueInFieldAttribute($attribute, $filterValue, $searchParts)) {
|
||||
$foundAttributes[] = $attribute;
|
||||
}
|
||||
}
|
||||
$event['Attribute'] = array_values($event['Attribute']);
|
||||
$event['Attribute'] = $foundAttributes;
|
||||
|
||||
// search in all attributes
|
||||
foreach ($event['ShadowAttribute'] as $k => $proposals) {
|
||||
if (!$this->__valueInFieldAttribute($proposals, $filterValue, $searchParts)) {
|
||||
unset($event['ShadowAttribute'][$k]);
|
||||
// search in all proposals
|
||||
$foundProposals = [];
|
||||
foreach ($event['ShadowAttribute'] as $proposals) {
|
||||
if ($this->__valueInFieldAttribute($proposals, $filterValue, $searchParts)) {
|
||||
$foundProposals[] = $proposals;
|
||||
}
|
||||
}
|
||||
$event['ShadowAttribute'] = array_values($event['ShadowAttribute']);
|
||||
$event['ShadowAttribute'] = $foundProposals;
|
||||
|
||||
// search for all attributes in object
|
||||
foreach ($event['Object'] as $k => $object) {
|
||||
if ($this->__valueInFieldAttribute($object, ['id', 'uuid', 'name', 'comment'], $searchParts)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($object['Attribute'] as $k2 => $attribute) {
|
||||
if (!$this->__valueInFieldAttribute($attribute, $filterValue, $searchParts)) {
|
||||
unset($event['Object'][$k]['Attribute'][$k2]);
|
||||
$foundAttributes = [];
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
if ($this->__valueInFieldAttribute($attribute, $filterValue, $searchParts)) {
|
||||
$foundAttributes[] = $attribute;
|
||||
}
|
||||
}
|
||||
if (empty($event['Object'][$k]['Attribute'])) {
|
||||
// remove object if empty
|
||||
unset($event['Object'][$k]);
|
||||
if (empty($foundAttributes)) {
|
||||
unset($event['Object'][$k]); // remove object if contains no attributes
|
||||
} else {
|
||||
$event['Object'][$k]['Attribute'] = array_values($event['Object'][$k]['Attribute']);
|
||||
$event['Object'][$k]['Attribute'] = $foundAttributes;
|
||||
}
|
||||
}
|
||||
$event['Object'] = array_values($event['Object']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a value on an attribute level for a specific field.
|
||||
*
|
||||
* @param array $attribute An attribute
|
||||
* @param array $fields List of keys in attribute to search in
|
||||
* @param array $searchParts Values to search (OR)
|
||||
* @return bool Returns true on match
|
||||
*/
|
||||
private function __valueInFieldAttribute($attribute, $fields, $searchParts)
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
if ($field === 'Tag.name') {
|
||||
if (empty($attribute['AttributeTag'])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($attribute['AttributeTag'] as $fieldValue) {
|
||||
$fieldValue = mb_strtolower($fieldValue['Tag']['name']);
|
||||
foreach ($searchParts as $s) {
|
||||
if (strpos($fieldValue, $s) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isset($attribute[$field])) {
|
||||
continue;
|
||||
}
|
||||
$fieldValue = mb_strtolower($attribute[$field]);
|
||||
foreach ($searchParts as $s) {
|
||||
if (strpos($fieldValue, $s) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// look in the parameters if we are doing advanced filtering or not
|
||||
private function __checkIfAdvancedFiltering($filters)
|
||||
{
|
||||
|
@ -2335,36 +2332,38 @@ class EventsController extends AppController
|
|||
{
|
||||
if ($this->request->is('post')) {
|
||||
$results = array();
|
||||
if (!empty($this->data)) {
|
||||
if (!isset($this->data['Event']['submittedfile'])) {
|
||||
if (!empty($this->request->data)) {
|
||||
if (!empty($this->request->data['Event']['filecontent'])) {
|
||||
$data = $this->request->data['Event']['filecontent'];
|
||||
$isXml = $data[0] === '<';
|
||||
} elseif (isset($this->request->data['Event']['submittedfile'])) {
|
||||
$file = $this->request->data['Event']['submittedfile'];
|
||||
if ($file['error'] === UPLOAD_ERR_NO_FILE) {
|
||||
$this->Flash->error(__('No file was uploaded.'));
|
||||
$this->redirect(['controller' => 'events', 'action' => 'add_misp_export']);
|
||||
}
|
||||
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if (($ext !== 'xml' && $ext !== 'json') && $file['size'] > 0 && is_uploaded_file($file['tmp_name'])) {
|
||||
$log = ClassRegistry::init('Log');
|
||||
$log->createLogEntry($this->Auth->user(), 'file_upload', 'Event', 0, 'MISP export file upload failed', 'File details: ' . json_encode($file));
|
||||
$this->Flash->error(__('You may only upload MISP XML or MISP JSON files.'));
|
||||
throw new MethodNotAllowedException(__('File upload failed or file does not have the expected extension (.xml / .json).'));
|
||||
}
|
||||
|
||||
$isXml = $ext === 'xml';
|
||||
$data = FileAccessTool::readFromFile($file['tmp_name'], $file['size']);
|
||||
} else {
|
||||
throw new MethodNotAllowedException(__('No file uploaded.'));
|
||||
}
|
||||
|
||||
$file = $this->data['Event']['submittedfile'];
|
||||
if ($file['error'] === UPLOAD_ERR_NO_FILE) {
|
||||
$this->Flash->error(__('No file was uploaded.'));
|
||||
$this->redirect(['controller' => 'events', 'action' => 'add_misp_export']);
|
||||
}
|
||||
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if (($ext !== 'xml' && $ext !== 'json') && $file['size'] > 0 && is_uploaded_file($file['tmp_name'])) {
|
||||
$log = ClassRegistry::init('Log');
|
||||
// #TODO Think about whether we want to Localize Log entries.
|
||||
$log->createLogEntry($this->Auth->user(), 'file_upload', 'Event', 0, 'MISP export file upload failed', 'File details: ' . json_encode($file));
|
||||
$this->Flash->error(__('You may only upload MISP XML or MISP JSON files.'));
|
||||
throw new MethodNotAllowedException(__('File upload failed or file does not have the expected extension (.xml / .json).'));
|
||||
}
|
||||
|
||||
$isXml = $ext === 'xml';
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$data = FileAccessTool::readFromFile($file['tmp_name'], $file['size']);
|
||||
$takeOwnership = Configure::read('MISP.take_ownership_xml_import')
|
||||
&& (isset($this->data['Event']['takeownership']) && $this->data['Event']['takeownership'] == 1);
|
||||
&& (isset($this->request->data['Event']['takeownership']) && $this->request->data['Event']['takeownership'] == 1);
|
||||
|
||||
try {
|
||||
$results = $this->Event->addMISPExportFile($this->Auth->user(), $data, $isXml, $takeOwnership, $this->data['Event']['publish']);
|
||||
$results = $this->Event->addMISPExportFile($this->Auth->user(), $data, $isXml, $takeOwnership, $this->request->data['Event']['publish']);
|
||||
} catch (Exception $e) {
|
||||
$this->log("Exception during processing MISP file import '{$file['name']}': {$e->getMessage()}");
|
||||
$this->log("Exception during processing MISP file import: {$e->getMessage()}");
|
||||
$this->Flash->error(__('Could not process MISP export file. Probably file content is invalid.'));
|
||||
$this->redirect(['controller' => 'events', 'action' => 'add_misp_export']);
|
||||
}
|
||||
|
@ -2961,8 +2960,12 @@ class EventsController extends AppController
|
|||
$result = $this->Event->publishRouter($event['Event']['id'], null, $this->Auth->user());
|
||||
if (!Configure::read('MISP.background_jobs')) {
|
||||
if (!is_array($result)) {
|
||||
// redirect to the view event page
|
||||
$message = __('Event published without alerts');
|
||||
if ($result === true) {
|
||||
$message = __('Event published without alerts');
|
||||
} else {
|
||||
$message = __('Event publishing failed due to a blocking module failing. The reason for the failure: %s', $result);
|
||||
$errors['Module'] = 'Module failure.';
|
||||
}
|
||||
} else {
|
||||
$lastResult = array_pop($result);
|
||||
$resultString = (count($result) > 0) ? implode(', ', $result) . ' and ' . $lastResult : $lastResult;
|
||||
|
@ -2970,11 +2973,6 @@ class EventsController extends AppController
|
|||
$message = __('Event published but not pushed to %s, re-try later. If the issue persists, make sure that the correct sync user credentials are used for the server link and that the sync user on the remote server has authentication privileges.', $resultString);
|
||||
}
|
||||
} else {
|
||||
// update the DB to set the published flag
|
||||
// for background jobs, this should be done already
|
||||
$event['Event']['published'] = 1;
|
||||
$event['Event']['publish_timestamp'] = time();
|
||||
$this->Event->save($event, true, ['id', 'published', 'publish_timestamp', 'info']); // info field is required because of SysLogLogableBehavior
|
||||
$message = 'Job queued';
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
|
@ -2984,7 +2982,11 @@ class EventsController extends AppController
|
|||
return $this->RestResponse->saveSuccessResponse('Events', 'publish', $event['Event']['id'], false, $message);
|
||||
}
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
if (!empty($errors)) {
|
||||
$this->Flash->error($message);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
}
|
||||
$this->redirect(array('action' => 'view', $event['Event']['id']));
|
||||
}
|
||||
} else {
|
||||
|
@ -3021,13 +3023,19 @@ class EventsController extends AppController
|
|||
$errors['failed_servers'] = $result;
|
||||
$message = __('Not published given no connection to %s but email sent to all participants.', $resultString);
|
||||
}
|
||||
|
||||
} elseif (!is_bool($emailResult)) {
|
||||
// Performs all the actions required to publish an event
|
||||
$result = $this->Event->publishRouter($event['Event']['id'], null, $this->Auth->user());
|
||||
if (!is_array($result)) {
|
||||
if ($result === true) {
|
||||
$message = __('Published but no email sent given GnuPG is not configured.');
|
||||
$errors['GnuPG'] = 'GnuPG not set up.';
|
||||
} else {
|
||||
$message = $result;
|
||||
$errors['Module'] = 'Module failure.';
|
||||
}
|
||||
// redirect to the view event page
|
||||
$message = __('Published but no email sent given GnuPG is not configured.');
|
||||
$errors['GnuPG'] = 'GnuPG not set up.';
|
||||
} else {
|
||||
$lastResult = array_pop($result);
|
||||
$resultString = (count($result) > 0) ? implode(', ', $result) . ' and ' . $lastResult : $lastResult;
|
||||
|
@ -3154,9 +3162,6 @@ class EventsController extends AppController
|
|||
public function automation($legacy = false)
|
||||
{
|
||||
// Simply display a static view
|
||||
if (!$this->userRole['perm_auth']) {
|
||||
$this->redirect(array('controller' => 'events', 'action' => 'index'));
|
||||
}
|
||||
App::uses('BroExport', 'Export');
|
||||
$export = new BroExport();
|
||||
$temp = $export->mispTypes;
|
||||
|
@ -3184,7 +3189,7 @@ class EventsController extends AppController
|
|||
}
|
||||
$rpzSettings = $this->Server->retrieveCurrentSettings('Plugin', 'RPZ_');
|
||||
$this->set('rpzSettings', $rpzSettings);
|
||||
$this->set('hashTypes', array_keys($this->Event->Attribute->hashTypes));
|
||||
$this->set('hashTypes', array_keys(Attribute::FILE_HASH_TYPES));
|
||||
if ($legacy) {
|
||||
$this->render('legacy_automation');
|
||||
}
|
||||
|
@ -3274,7 +3279,10 @@ class EventsController extends AppController
|
|||
$exportTypes[$k]['progress'] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$exportTypes = [];
|
||||
}
|
||||
|
||||
$this->set('sigTypes', array_keys($this->Event->Attribute->typeDefinitions));
|
||||
$this->set('export_types', $exportTypes);
|
||||
}
|
||||
|
@ -3314,47 +3322,65 @@ class EventsController extends AppController
|
|||
return $difference . " " . $periods[$j] . " ago";
|
||||
}
|
||||
|
||||
public function restSearchExport($id=null, $returnFormat=null)
|
||||
public function restSearchExport($id = null, $returnFormat = null)
|
||||
{
|
||||
if (is_null($returnFormat)) {
|
||||
if (is_numeric($id)) {
|
||||
$idList = [$id];
|
||||
} else {
|
||||
$idList = json_decode($id, true);
|
||||
}
|
||||
if ($returnFormat === null) {
|
||||
$exportFormats = [
|
||||
'attack' => __('Attack matrix'),
|
||||
'attack-sightings' => __('Attack matrix by sightings'),
|
||||
'context' => __('Aggregated context data'),
|
||||
'context-markdown' => __('Aggregated context data as Markdown'),
|
||||
'csv' => __('CSV'),
|
||||
'hashes' => __('Hashes'),
|
||||
'hosts' => __('Hosts file'),
|
||||
'json' => __('MISP JSON'),
|
||||
'netfilter' => __('Netfilter'),
|
||||
'opendata' => __('Open data'),
|
||||
'openioc' => __('OpenIOC'),
|
||||
'rpz' => __('RPZ'),
|
||||
'snort' => __('Snort rules'),
|
||||
'stix' => __('STIX 1 XML'),
|
||||
'stix-json' => __('STIX 1 JSON'),
|
||||
'stix2' => __('STIX 2'),
|
||||
'suricata' => __('Suricata rules'),
|
||||
'text' => __('Text file'),
|
||||
'xml' => __('MISP XML'),
|
||||
'yara' => __('YARA rules'),
|
||||
'yara-json' => __('YARA rules (JSON)'),
|
||||
];
|
||||
|
||||
$idList = is_numeric($id) ? [$id] : $this->_jsonDecode($id);
|
||||
if (empty($idList)) {
|
||||
throw new NotFoundException(__('Invalid input.'));
|
||||
}
|
||||
$this->set('idList', $idList);
|
||||
$this->set('exportFormats', array_keys($this->Event->validFormats));
|
||||
$this->set('exportFormats', $exportFormats);
|
||||
$this->render('ajax/eventRestSearchExportConfirmationForm');
|
||||
} else {
|
||||
$returnFormat = empty($this->Event->validFormats[$returnFormat]) ? 'json' : $returnFormat;
|
||||
$returnFormat = !isset($this->Event->validFormats[$returnFormat]) ? 'json' : $returnFormat;
|
||||
$idList = $id;
|
||||
if (!is_array($idList)) {
|
||||
if (is_numeric($idList) || Validation::uuid($idList)) {
|
||||
$idList = array($idList);
|
||||
} else {
|
||||
$idList = $this->Event->jsonDecode($idList);
|
||||
$idList = $this->_jsonDecode($idList);
|
||||
}
|
||||
}
|
||||
if (empty($idList)) {
|
||||
throw new NotFoundException(__('Invalid input.'));
|
||||
}
|
||||
$filters = [
|
||||
'eventid' => $idList
|
||||
'eventid' => $idList,
|
||||
'published' => [true, false], // fetch published and unpublished events
|
||||
];
|
||||
|
||||
$elementCounter = 0;
|
||||
$renderView = false;
|
||||
$validFormat = $this->Event->validFormats[$returnFormat];
|
||||
$responseType = $validFormat[0];
|
||||
$responseType = $this->Event->validFormats[$returnFormat][0];
|
||||
$final = $this->Event->restSearch($this->Auth->user(), $returnFormat, $filters, false, false, $elementCounter, $renderView);
|
||||
if (!empty($renderView) && !empty($final)) {
|
||||
if ($renderView) {
|
||||
$final = json_decode($final->intoString(), true);
|
||||
foreach ($final as $key => $data) {
|
||||
$this->set($key, $data);
|
||||
}
|
||||
$this->set($final);
|
||||
$this->set('responseType', $responseType);
|
||||
$this->set('returnFormat', $returnFormat);
|
||||
$this->set('renderView', $renderView);
|
||||
|
@ -3933,7 +3959,7 @@ class EventsController extends AppController
|
|||
}
|
||||
$this->set('event_id', $event['Event']['id']);
|
||||
if ($this->request->is('get')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->request->data['Attribute']['event_id'] = $event['Event']['id'];
|
||||
|
||||
} else if ($this->request->is('post')) {
|
||||
|
@ -4098,29 +4124,31 @@ class EventsController extends AppController
|
|||
|
||||
public function filterEventIdsForPush()
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
$incomingIDs = array();
|
||||
$incomingEvents = array();
|
||||
foreach ($this->request->data as $event) {
|
||||
$incomingIDs[] = $event['Event']['uuid'];
|
||||
$incomingEvents[$event['Event']['uuid']] = $event['Event']['timestamp'];
|
||||
}
|
||||
$events = $this->Event->find('all', array(
|
||||
'conditions' => array('Event.uuid' => $incomingIDs),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Event.uuid', 'Event.timestamp', 'Event.locked'),
|
||||
));
|
||||
foreach ($events as $event) {
|
||||
if ($event['Event']['timestamp'] >= $incomingEvents[$event['Event']['uuid']]) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
continue;
|
||||
}
|
||||
if ($event['Event']['locked'] == 0) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
}
|
||||
}
|
||||
return $this->RestResponse->viewData(array_keys($incomingEvents), $this->response->type());
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException(__('This endpoint requires a POST request.'));
|
||||
}
|
||||
|
||||
$incomingUuids = [];
|
||||
$incomingEvents = [];
|
||||
foreach ($this->request->data as $event) {
|
||||
$incomingUuids[] = $event['Event']['uuid'];
|
||||
$incomingEvents[$event['Event']['uuid']] = $event['Event']['timestamp'];
|
||||
}
|
||||
$events = $this->Event->find('all', [
|
||||
'conditions' => ['Event.uuid' => $incomingUuids],
|
||||
'recursive' => -1,
|
||||
'fields' => ['Event.uuid', 'Event.timestamp', 'Event.locked'],
|
||||
]);
|
||||
foreach ($events as $event) {
|
||||
if ($event['Event']['timestamp'] >= $incomingEvents[$event['Event']['uuid']]) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
continue;
|
||||
}
|
||||
if ($event['Event']['locked'] == 0) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
}
|
||||
}
|
||||
return $this->RestResponse->viewData(array_keys($incomingEvents), $this->response->type());
|
||||
}
|
||||
|
||||
public function checkuuid($uuid)
|
||||
|
@ -4647,18 +4675,16 @@ class EventsController extends AppController
|
|||
|
||||
public function viewGraph($id)
|
||||
{
|
||||
// Event data are fetched by 'updateGraph', here we need just metadata.
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array(
|
||||
'eventid' => $id,
|
||||
'metadata' => true,
|
||||
));
|
||||
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $id);
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Invalid Event.'));
|
||||
}
|
||||
|
||||
$this->set('event', $event[0]);
|
||||
$this->set('event', $event);
|
||||
$this->set('scope', 'event');
|
||||
$this->set('id', $id);
|
||||
$this->set('mayModify', $this->__canModifyEvent($event));
|
||||
$this->set('mayPublish', $this->__canPublishEvent($event));
|
||||
$this->set('id', $event['Event']['id']);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4673,8 +4699,9 @@ class EventsController extends AppController
|
|||
|
||||
public function updateGraph($id, $type = 'event')
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
$validTools = array('event', 'galaxy', 'tag');
|
||||
if (!in_array($type, $validTools)) {
|
||||
if (!in_array($type, $validTools, true)) {
|
||||
throw new MethodNotAllowedException(__('Invalid type.'));
|
||||
}
|
||||
$this->loadModel('Taxonomy');
|
||||
|
@ -4682,18 +4709,17 @@ class EventsController extends AppController
|
|||
App::uses('CorrelationGraphTool', 'Tools');
|
||||
$grapher = new CorrelationGraphTool();
|
||||
$data = $this->request->is('post') ? $this->request->data : array();
|
||||
$grapher->construct($this->Event, $this->Taxonomy, $this->GalaxyCluster, $this->Auth->user(), $data);
|
||||
$grapher->construct($this->Event, $this->Taxonomy, $this->GalaxyCluster, $user, $data);
|
||||
$json = $grapher->buildGraphJson($id, $type);
|
||||
array_walk_recursive($json, function (&$item, $key) {
|
||||
if (!mb_detect_encoding($item, 'utf-8', true)) {
|
||||
$item = utf8_encode($item);
|
||||
}
|
||||
});
|
||||
$this->response->type('json');
|
||||
return new CakeResponse(array('body' => json_encode($json), 'status' => 200, 'type' => 'json'));
|
||||
return $this->RestResponse->viewData($json, 'json');
|
||||
}
|
||||
|
||||
private function genDistributionGraph($id, $type = 'event', $extended = 0, $user = null)
|
||||
private function __genDistributionGraph($id, $type = 'event', $extended = 0, $user = null)
|
||||
{
|
||||
$validTools = array('event');
|
||||
if (!in_array($type, $validTools)) {
|
||||
|
@ -4749,12 +4775,9 @@ class EventsController extends AppController
|
|||
|
||||
public function getDistributionGraph($id, $type = 'event')
|
||||
{
|
||||
// Close session without writing changes to them.
|
||||
$user = $this->Auth->user();
|
||||
session_abort();
|
||||
|
||||
$user = $this->_closeSession();
|
||||
$extended = isset($this->params['named']['extended']) ? 1 : 0;
|
||||
$json = $this->genDistributionGraph($id, $type, $extended, $user);
|
||||
$json = $this->__genDistributionGraph($id, $type, $extended, $user);
|
||||
return $this->RestResponse->viewData($json, 'json');
|
||||
}
|
||||
|
||||
|
@ -4876,7 +4899,7 @@ class EventsController extends AppController
|
|||
return $this->RestResponse->viewData($json, 'json');
|
||||
}
|
||||
|
||||
public function viewGalaxyMatrix($scope_id, $galaxy_id, $scope='event', $disable_picking=false)
|
||||
public function viewGalaxyMatrix($scope_id, $galaxy_id, $scope='event', $disable_picking=false, $extended=false)
|
||||
{
|
||||
$this->loadModel('Galaxy');
|
||||
$mitreAttackGalaxyId = $this->Galaxy->getMitreAttackGalaxyId();
|
||||
|
@ -4921,10 +4944,18 @@ class EventsController extends AppController
|
|||
}
|
||||
|
||||
if ($scope !== 'tag_collection') {
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId, 'metadata' => true));
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId, 'metadata' => true, 'extended' => $extended));
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Event not found or you are not authorised to view it.'));
|
||||
}
|
||||
if ($extended) {
|
||||
$eventIds = array();
|
||||
$eventIds[] = $eventId;
|
||||
foreach ($event[0]['Event']['extensionEvents'] as $extensionEvent) {
|
||||
$eventIds[] = $extensionEvent['id'];
|
||||
}
|
||||
$eventId = $eventIds;
|
||||
}
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores($this->Auth->user(), $eventId, $matrixTags);
|
||||
$scoresDataEvent = $this->Event->EventTag->getTagScores($eventId, $matrixTags);
|
||||
$maxScore = 0;
|
||||
|
@ -5103,7 +5134,14 @@ class EventsController extends AppController
|
|||
if (!Configure::read('Plugin.' . $type . '_services_enable')) {
|
||||
throw new MethodNotAllowedException(__('%s services are not enabled.', $type));
|
||||
}
|
||||
$attribute = $this->Event->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array('Attribute.id' => $attribute_id), 'flatten' => 1));
|
||||
$attribute = $this->Event->Attribute->fetchAttributes($this->Auth->user(), [
|
||||
'conditions' => [
|
||||
'Attribute.id' => $attribute_id
|
||||
],
|
||||
'flatten' => 1,
|
||||
'includeEventTags' => 1,
|
||||
'contain' => ['Event' => ['fields' => ['distribution', 'sharing_group_id']]],
|
||||
]);
|
||||
if (empty($attribute)) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or you are not authorised to see it.'));
|
||||
}
|
||||
|
@ -5164,7 +5202,7 @@ class EventsController extends AppController
|
|||
if (!empty($options)) {
|
||||
$data['config'] = $options;
|
||||
}
|
||||
$result = $this->Module->queryModuleServer($data, false, $type);
|
||||
$result = $this->Module->queryModuleServer($data, false, $type, false, $attribute[0]);
|
||||
if (!$result) {
|
||||
throw new InternalErrorException(__('%s service not reachable.', $type));
|
||||
}
|
||||
|
@ -5210,7 +5248,7 @@ class EventsController extends AppController
|
|||
if (!empty($options)) {
|
||||
$data['config'] = $options;
|
||||
}
|
||||
$result = $this->Module->queryModuleServer($data, false, $type);
|
||||
$result = $this->Module->queryModuleServer($data, false, $type, false, $attribute[0]);
|
||||
if (!$result) {
|
||||
throw new InternalErrorException(__('%s service not reachable.', $type));
|
||||
}
|
||||
|
@ -5480,7 +5518,7 @@ class EventsController extends AppController
|
|||
if ($event['Event']['disable_correlation']) {
|
||||
$event['Event']['disable_correlation'] = 0;
|
||||
$this->Event->save($event);
|
||||
$this->Event->Attribute->generateCorrelation(false, 0, $event['Event']['id']);
|
||||
$this->Event->Attribute->generateCorrelation(false, $event['Event']['id']);
|
||||
} else {
|
||||
$event['Event']['disable_correlation'] = 1;
|
||||
$this->Event->save($event);
|
||||
|
@ -5500,7 +5538,8 @@ class EventsController extends AppController
|
|||
|
||||
public function checkPublishedStatus($id)
|
||||
{
|
||||
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $id, ['fields' => 'Event.published']);
|
||||
$user = $this->_closeSession();
|
||||
$event = $this->Event->fetchSimpleEvent($user, $id, ['fields' => 'Event.published']);
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Invalid event'));
|
||||
}
|
||||
|
@ -5594,24 +5633,25 @@ class EventsController extends AppController
|
|||
|
||||
public function getEventInfoById($id)
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
if (empty($id)) {
|
||||
throw new MethodNotAllowedException(__('Invalid ID.'));
|
||||
}
|
||||
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $id, [
|
||||
$event = $this->Event->fetchSimpleEvent($user, $id, [
|
||||
'fields' => ['Event.id', 'Event.info', 'Event.threat_level_id', 'Event.analysis'],
|
||||
'contain' => ['EventTag' => ['Tag.id', 'Tag.name', 'Tag.colour'], 'ThreatLevel.name'],
|
||||
]);
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($event, $this->response->type());
|
||||
} else {
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
}
|
||||
$this->set('analysisLevels', $this->Event->analysisLevels);
|
||||
$this->set('validUuid', Validation::uuid($id));
|
||||
$this->set('id', $id);
|
||||
$this->set('event', $event);
|
||||
}
|
||||
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = false;
|
||||
}
|
||||
$this->set('analysisLevels', $this->Event->analysisLevels);
|
||||
$this->set('validUuid', Validation::uuid($id));
|
||||
$this->set('id', $id);
|
||||
$this->set('event', $event);
|
||||
}
|
||||
|
||||
public function enrichEvent($id)
|
||||
|
@ -5650,7 +5690,7 @@ class EventsController extends AppController
|
|||
} else {
|
||||
$this->loadModel('Module');
|
||||
$modules = $this->Module->getEnabledModules($this->Auth->user(), 'expansion');
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('modules', $modules);
|
||||
$this->render('ajax/enrich_event');
|
||||
}
|
||||
|
@ -5693,9 +5733,7 @@ class EventsController extends AppController
|
|||
|
||||
public function checkLocks($id, $timestamp)
|
||||
{
|
||||
// Close session without writing changes to them.
|
||||
$user = $this->Auth->user();
|
||||
session_abort();
|
||||
$user = $this->_closeSession();
|
||||
|
||||
$event = $this->Event->find('first', array(
|
||||
'recursive' => -1,
|
||||
|
@ -6065,6 +6103,10 @@ class EventsController extends AppController
|
|||
|
||||
public function runTaxonomyExclusivityCheck($id)
|
||||
{
|
||||
if (Configure::read('MISP.disable_taxonomy_consistency_checks')) {
|
||||
return $this->RestResponse->saveFailResponse('Events', 'runTaxonomyExclusivityCheck', null, 'Taxonomy consistency checks are disabled, set `MISP.disable_taxonomy_consistency_checks` to `false` to enable them.', 'json');
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
if (is_numeric($id)) {
|
||||
$conditions = array('eventid' => $id);
|
||||
|
@ -6220,7 +6262,7 @@ class EventsController extends AppController
|
|||
__('Are you sure you want to switch the event to unprotected mode? Unprotected mode is the default behaviour of MISP events, with creation and modification being purely limited by the distribution mechanism and eligible sync users.')
|
||||
);
|
||||
$this->set('actionName', $protect ? __('Switch to protected mode') : __('Remove protected mode'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ class FavouriteTagsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException('This action is available via AJAX only.');
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/getToggleField');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
/**
|
||||
* @property Galaxy $Galaxy
|
||||
*/
|
||||
class GalaxiesController extends AppController
|
||||
{
|
||||
public $components = array('Session', 'RequestHandler');
|
||||
|
@ -316,17 +319,17 @@ class GalaxiesController extends AppController
|
|||
|
||||
public function selectGalaxy($target_id, $target_type='event', $namespace='misp', $noGalaxyMatrix = false)
|
||||
{
|
||||
$this->_closeSession();
|
||||
$mitreAttackGalaxyId = $this->Galaxy->getMitreAttackGalaxyId();
|
||||
$local = !empty($this->params['named']['local']) ? $this->params['named']['local'] : '0';
|
||||
$eventid = !empty($this->params['named']['eventid']) ? $this->params['named']['eventid'] : '0';
|
||||
$conditions = $namespace === '0' ? array() : array('namespace' => $namespace);
|
||||
$conditions[] = [
|
||||
'enabled' => true
|
||||
];
|
||||
if(!$local) {
|
||||
$conditions[] = [
|
||||
'local_only' => 0
|
||||
];
|
||||
|
||||
$conditions = ['enabled' => true];
|
||||
if ($namespace !== '0') {
|
||||
$conditions['namespace'] = $namespace;
|
||||
}
|
||||
if (!$local) {
|
||||
$conditions['local_only'] = false;
|
||||
}
|
||||
$galaxies = $this->Galaxy->find('all', array(
|
||||
'recursive' => -1,
|
||||
|
@ -380,21 +383,21 @@ class GalaxiesController extends AppController
|
|||
|
||||
public function selectGalaxyNamespace($target_id, $target_type='event', $noGalaxyMatrix = false)
|
||||
{
|
||||
$namespaces = $this->Galaxy->find('list', array(
|
||||
$this->_closeSession();
|
||||
$namespaces = $this->Galaxy->find('column', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('namespace', 'namespace'),
|
||||
'fields' => array('namespace'),
|
||||
'conditions' => array('enabled' => 1),
|
||||
'group' => array('namespace'),
|
||||
'unique' => true,
|
||||
'order' => array('namespace asc')
|
||||
));
|
||||
$local = !empty($this->params['named']['local']) ? '1' : '0';
|
||||
$eventid = !empty($this->params['named']['eventid']) ? $this->params['named']['eventid'] : '0';
|
||||
$items = array();
|
||||
$noGalaxyMatrix = $noGalaxyMatrix ? '1' : '0';
|
||||
$items[] = array(
|
||||
$items = [[
|
||||
'name' => __('All namespaces'),
|
||||
'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/0' . '/' . $noGalaxyMatrix . '/local:' . $local . '/eventid:' . $eventid
|
||||
);
|
||||
]];
|
||||
foreach ($namespaces as $namespace) {
|
||||
$items[] = array(
|
||||
'name' => $namespace,
|
||||
|
@ -411,7 +414,7 @@ class GalaxiesController extends AppController
|
|||
|
||||
public function selectCluster($target_id, $target_type = 'event', $selectGalaxy = false)
|
||||
{
|
||||
$conditions = array();
|
||||
$user = $this->_closeSession();
|
||||
$conditions = array(
|
||||
'OR' => array(
|
||||
'GalaxyCluster.published' => true,
|
||||
|
@ -427,92 +430,79 @@ class GalaxiesController extends AppController
|
|||
if ($selectGalaxy) {
|
||||
$conditions['GalaxyCluster.galaxy_id'] = $selectGalaxy;
|
||||
}
|
||||
$local = !empty($this->params['named']['local']) ? $this->params['named']['local'] : '0';
|
||||
$data = $this->Galaxy->GalaxyCluster->fetchGalaxyClusters($this->Auth->user(), array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('value', 'description', 'source', 'type', 'id', 'uuid'),
|
||||
'order' => array('value asc'),
|
||||
), false);
|
||||
$clusters = array();
|
||||
$cluster_ids = array();
|
||||
foreach ($data as $k => $cluster) {
|
||||
$cluster_ids[] = $cluster['GalaxyCluster']['id'];
|
||||
}
|
||||
$data = array_column($this->Galaxy->GalaxyCluster->fetchGalaxyClusters($user, array(
|
||||
'conditions' => $conditions,
|
||||
'fields' => array('value', 'description', 'source', 'type', 'id', 'uuid'),
|
||||
'order' => array('value asc'),
|
||||
)), 'GalaxyCluster');
|
||||
$synonyms = $this->Galaxy->GalaxyCluster->GalaxyElement->find('all', array(
|
||||
'conditions' => array(
|
||||
'GalaxyElement.galaxy_cluster_id' => $cluster_ids,
|
||||
'GalaxyElement.key' => 'synonyms'
|
||||
'GalaxyElement.key' => 'synonyms',
|
||||
$conditions
|
||||
),
|
||||
'fields' => ['GalaxyElement.galaxy_cluster_id', 'GalaxyElement.value'],
|
||||
'contain' => 'GalaxyCluster',
|
||||
'recursive' => -1
|
||||
));
|
||||
$sorted_synonyms = array();
|
||||
$sortedSynonyms = array();
|
||||
foreach ($synonyms as $synonym) {
|
||||
$sorted_synonyms[$synonym['GalaxyElement']['galaxy_cluster_id']][] = $synonym;
|
||||
$sortedSynonyms[$synonym['GalaxyElement']['galaxy_cluster_id']][] = $synonym['GalaxyElement']['value'];
|
||||
}
|
||||
foreach ($data as $k => $cluster) {
|
||||
$cluster['GalaxyCluster']['synonyms_string'] = array();
|
||||
if (!empty($sorted_synonyms[$cluster['GalaxyCluster']['id']])) {
|
||||
foreach ($sorted_synonyms[$cluster['GalaxyCluster']['id']] as $element) {
|
||||
$cluster['GalaxyCluster']['synonyms_string'][] = $element['GalaxyElement']['value'];
|
||||
$cluster['GalaxyElement'][] = $element['GalaxyElement'];
|
||||
}
|
||||
unset($sorted_synonyms[$cluster['GalaxyCluster']['id']]);
|
||||
$clusters = [];
|
||||
foreach ($data as $cluster) {
|
||||
if (!empty($sortedSynonyms[$cluster['id']])) {
|
||||
$cluster['synonyms_string'] = implode(', ', $sortedSynonyms[$cluster['id']]);
|
||||
}
|
||||
$cluster['GalaxyCluster']['synonyms_string'] = implode(', ', $cluster['GalaxyCluster']['synonyms_string']);
|
||||
unset($cluster['GalaxyElement']);
|
||||
$clusters[$cluster['GalaxyCluster']['type']][$cluster['GalaxyCluster']['uuid']] = $cluster['GalaxyCluster'];
|
||||
$clusters[$cluster['type']][$cluster['uuid']] = $cluster;
|
||||
}
|
||||
ksort($clusters);
|
||||
$this->set('target_id', $target_id);
|
||||
$this->set('target_type', $target_type);
|
||||
|
||||
$items = array();
|
||||
foreach ($clusters as $namespace => $cluster_data) {
|
||||
foreach ($cluster_data as $k => $cluster) {
|
||||
$name = $cluster['value'];
|
||||
foreach ($clusters as $cluster_data) {
|
||||
foreach ($cluster_data as $cluster) {
|
||||
$optionName = $cluster['value'];
|
||||
if ($cluster['synonyms_string'] !== '') {
|
||||
$synom = __('Synonyms: ') . $cluster['synonyms_string'];
|
||||
$optionName .= $cluster['synonyms_string'] !== '' ? ' (' . $cluster['synonyms_string'] . ')' : '';
|
||||
} else {
|
||||
$synom = '';
|
||||
if (isset($cluster['synonyms_string'])) {
|
||||
$optionName .= ' (' . $cluster['synonyms_string'] . ')';
|
||||
}
|
||||
$itemParam = array(
|
||||
'name' => $optionName,
|
||||
'value' => $cluster['id'],
|
||||
'template' => array(
|
||||
'name' => $name,
|
||||
'name' => $cluster['value'],
|
||||
'infoExtra' => $cluster['description'],
|
||||
),
|
||||
'additionalData' => array(
|
||||
'uuid' => $cluster['uuid']
|
||||
)
|
||||
);
|
||||
if ($cluster['synonyms_string'] !== '') {
|
||||
$itemParam['template']['infoContextual'] = $synom;
|
||||
if (isset($cluster['synonyms_string'])) {
|
||||
$itemParam['template']['infoContextual'] = __('Synonyms: ') . $cluster['synonyms_string'];
|
||||
}
|
||||
$items[] = $itemParam;
|
||||
unset($cluster_data[$k]);
|
||||
}
|
||||
}
|
||||
$onClickForm = 'quickSubmitGalaxyForm';
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($items, $this->response->type());
|
||||
} else {
|
||||
$this->set('items', $items);
|
||||
$this->set('options', array( // set chosen (select picker) options
|
||||
'functionName' => $onClickForm,
|
||||
'multiple' => $target_type == 'galaxyClusterRelation' ? 0 : '-1',
|
||||
'select_options' => array(
|
||||
'additionalData' => array(
|
||||
'target_id' => $target_id,
|
||||
'target_type' => $target_type,
|
||||
'local' => $local
|
||||
)
|
||||
),
|
||||
));
|
||||
$this->render('ajax/cluster_choice');
|
||||
}
|
||||
$mirrorOnEventEnabled = Configure::read("MISP.enable_clusters_mirroring_from_attributes_to_event");
|
||||
$mirrorOnEvent = $mirrorOnEventEnabled && $target_type == 'attribute';
|
||||
$this->set('target_id', $target_id);
|
||||
$this->set('target_type', $target_type);
|
||||
$this->set('mirrorOnEvent', $mirrorOnEvent);
|
||||
$this->set('items', $items);
|
||||
$local = !empty($this->params['named']['local']) ? $this->params['named']['local'] : '0';
|
||||
$this->set('options', array( // set chosen (select picker) options
|
||||
'functionName' => 'quickSubmitGalaxyForm',
|
||||
'multiple' => $target_type == 'galaxyClusterRelation' ? 0 : '-1',
|
||||
'select_options' => array(
|
||||
'additionalData' => array(
|
||||
'target_id' => $target_id,
|
||||
'target_type' => $target_type,
|
||||
'local' => $local
|
||||
)
|
||||
),
|
||||
));
|
||||
$this->render('ajax/cluster_choice');
|
||||
}
|
||||
|
||||
public function attachCluster($target_id, $target_type = 'event')
|
||||
|
@ -526,7 +516,10 @@ class GalaxiesController extends AppController
|
|||
public function attachMultipleClusters($target_id, $target_type = 'event')
|
||||
{
|
||||
$local = !empty($this->params['named']['local']);
|
||||
$mirrorOnEventEnabled = Configure::read("MISP.enable_clusters_mirroring_from_attributes_to_event");
|
||||
$mirrorOnEvent = $mirrorOnEventEnabled && $target_type == 'attribute';
|
||||
$this->set('local', $local);
|
||||
$this->set('mirrorOnEvent', $mirrorOnEvent);
|
||||
if ($this->request->is('post')) {
|
||||
if ($target_id === 'selected') {
|
||||
$target_id_list = json_decode($this->request->data['Galaxy']['attribute_ids']);
|
||||
|
@ -534,14 +527,25 @@ class GalaxiesController extends AppController
|
|||
$target_id_list = array($target_id);
|
||||
}
|
||||
$cluster_ids = $this->request->data['Galaxy']['target_ids'];
|
||||
$mirrorOnEventRequested = $mirrorOnEvent && !empty($this->request->data['Galaxy']['mirror_on_event']);
|
||||
if (strlen($cluster_ids) > 0) {
|
||||
$cluster_ids = json_decode($cluster_ids, true);
|
||||
if ($cluster_ids === null || empty($cluster_ids)) {
|
||||
$cluster_ids = $this->_jsonDecode($cluster_ids);
|
||||
if (empty($cluster_ids)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Failed to parse request or no clusters picked.'))), 'status'=>200, 'type' => 'json'));
|
||||
}
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Failed to parse request.'))), 'status'=>200, 'type' => 'json'));
|
||||
}
|
||||
if ($mirrorOnEventRequested && !empty($target_id_list)) {
|
||||
$first_attribute_id = $target_id_list[0]; // We consider that all attributes to be tagged are contained in the same event.
|
||||
$this->loadModel('Attribute');
|
||||
$attribute = $this->Attribute->fetchAttributeSimple($this->Auth->user(), array('conditions' => array('Attribute.id' => $first_attribute_id), 'flatten' => 1));
|
||||
if (!empty($attribute['Attribute']['event_id'])) {
|
||||
$event_id = $attribute['Attribute']['event_id'];
|
||||
} else {
|
||||
return new CakeResponse(array('body' => json_encode(array('saved' => false, 'errors' => __('Failed to parse request. Could not fetch attribute'))), 'status' => 200, 'type' => 'json'));
|
||||
}
|
||||
}
|
||||
$result = "";
|
||||
if (!is_array($cluster_ids)) { // in case we only want to attach 1
|
||||
$cluster_ids = array($cluster_ids);
|
||||
|
@ -549,6 +553,9 @@ class GalaxiesController extends AppController
|
|||
foreach ($cluster_ids as $cluster_id) {
|
||||
foreach ($target_id_list as $target_id) {
|
||||
$result = $this->Galaxy->attachCluster($this->Auth->user(), $target_type, $target_id, $cluster_id, $local);
|
||||
if ($mirrorOnEventRequested) {
|
||||
$result = $result && $this->Galaxy->attachCluster($this->Auth->user(), 'event', $event_id, $cluster_id, $local);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
|
@ -558,6 +565,7 @@ class GalaxiesController extends AppController
|
|||
$this->redirect($this->referer());
|
||||
}
|
||||
} else {
|
||||
$this->set('local', $local);
|
||||
$this->set('target_id', $target_id);
|
||||
$this->set('target_type', $target_type);
|
||||
$this->layout = false;
|
||||
|
@ -586,29 +594,32 @@ class GalaxiesController extends AppController
|
|||
|
||||
public function showGalaxies($id, $scope = 'event')
|
||||
{
|
||||
$this->layout = 'ajax';
|
||||
$this->set('scope', $scope);
|
||||
if ($scope == 'event') {
|
||||
if ($scope === 'event') {
|
||||
$this->loadModel('Event');
|
||||
$object = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $id, 'metadata' => 1));
|
||||
if (empty($object)) {
|
||||
throw new MethodNotAllowedException('Invalid event.');
|
||||
throw new NotFoundException('Invalid event.');
|
||||
}
|
||||
$this->set('object', $object[0]);
|
||||
} elseif ($scope == 'attribute') {
|
||||
} elseif ($scope === 'attribute') {
|
||||
$this->loadModel('Attribute');
|
||||
$object = $this->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array('Attribute.id' => $id), 'flatten' => 1));
|
||||
if (empty($object)) {
|
||||
throw new MethodNotAllowedException('Invalid attribute.');
|
||||
throw new NotFoundException('Invalid attribute.');
|
||||
}
|
||||
$object[0] = $this->Attribute->Event->massageTags($this->Auth->user(), $object[0], 'Attribute');
|
||||
} elseif ($scope == 'tag_collection') {
|
||||
} elseif ($scope === 'tag_collection') {
|
||||
$this->loadModel('TagCollection');
|
||||
$object = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $id)));
|
||||
if (empty($object)) {
|
||||
throw new MethodNotAllowedException('Invalid Tag Collection.');
|
||||
throw new NotFoundException('Invalid Tag Collection.');
|
||||
}
|
||||
} else {
|
||||
throw new NotFoundException("Invalid scope.");
|
||||
}
|
||||
|
||||
$this->layout = false;
|
||||
$this->set('scope', $scope);
|
||||
$this->set('object', $object[0]);
|
||||
$this->render('/Events/ajax/ajaxGalaxies');
|
||||
}
|
||||
|
|
|
@ -72,8 +72,6 @@ class GalaxyClusterRelationsController extends AppController
|
|||
$this->paginate['contain'] = array('SharingGroup', 'SourceCluster' => ['Org', 'Orgc'], 'TargetCluster', 'GalaxyClusterRelationTag' => array('Tag'));
|
||||
$relations = $this->paginate();
|
||||
$relations = $this->GalaxyClusterRelation->removeNonAccessibleTargetCluster($this->Auth->user(), $relations);
|
||||
$this->loadModel('SharingGroup');
|
||||
$sgs = $this->SharingGroup->fetchAllAuthorised($this->Auth->user());
|
||||
$this->loadModel('Attribute');
|
||||
$distributionLevels = $this->Attribute->distributionLevels;
|
||||
unset($distributionLevels[5]);
|
||||
|
|
|
@ -155,7 +155,7 @@ class GalaxyClustersController extends AppController
|
|||
$this->set('custom_cluster_count', $customClusterCount);
|
||||
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/index');
|
||||
}
|
||||
}
|
||||
|
@ -545,162 +545,32 @@ class GalaxyClustersController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function attachToEvent($event_id, $tag_name)
|
||||
{
|
||||
$this->loadModel('Event');
|
||||
$this->Event->id = $event_id;
|
||||
$this->Event->recursive = -1;
|
||||
$event = $this->Event->read(array(), $event_id);
|
||||
if (empty($event)) {
|
||||
throw new MethodNotAllowedException('Invalid Event.');
|
||||
}
|
||||
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
|
||||
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['org_id'] && $this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
|
||||
throw new MethodNotAllowedException('Invalid Event.');
|
||||
}
|
||||
}
|
||||
$tag = $this->Event->EventTag->Tag->find('first', array('conditions' => array('Tag.name' => $tag_name), 'recursive' => -1));
|
||||
if (empty($tag)) {
|
||||
$this->Event->EventTag->Tag->create();
|
||||
$this->Event->EventTag->Tag->save(array('name' => $tag_name, 'colour' => '#0088cc', 'exportable' => 1));
|
||||
$tag_id = $this->Event->EventTag->Tag->id;
|
||||
} else {
|
||||
$tag_id = $tag['Tag']['id'];
|
||||
}
|
||||
$existingEventTag = $this->Event->EventTag->find('first', array('conditions' => array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $event_id), 'recursive' => -1));
|
||||
if (empty($existingEventTag)) {
|
||||
$cluster = $this->GalaxyCluster->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('GalaxyCluster.tag_name' => $existingEventTag['Tag']['name'])
|
||||
));
|
||||
$this->Event->EventTag->create();
|
||||
$this->Event->EventTag->save(array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $event_id));
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'model' => 'Event',
|
||||
'model_id' => $event_id,
|
||||
'email' => $this->Auth->user('email'),
|
||||
'action' => 'galaxy',
|
||||
'title' => 'Attached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') to event (' . $event_id . ')',
|
||||
'change' => ''
|
||||
));
|
||||
$event['Event']['published'] = 0;
|
||||
$date = new DateTime();
|
||||
$event['Event']['timestamp'] = $date->getTimestamp();
|
||||
$this->Event->save($event);
|
||||
$this->Flash->success('Galaxy attached.');
|
||||
} else {
|
||||
$this->Flash->error('Galaxy already attached.');
|
||||
}
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
||||
public function detach($target_id, $target_type, $tag_id)
|
||||
{
|
||||
$this->loadModel('Event');
|
||||
if ($target_type == 'attribute') {
|
||||
$attribute = $this->Event->Attribute->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('id', 'event_id'),
|
||||
'conditions' => array('Attribute.id' => $target_id)
|
||||
));
|
||||
if (empty($attribute)) {
|
||||
throw new MethodNotAllowedException('Invalid Attribute.');
|
||||
}
|
||||
$event_id = $attribute['Attribute']['event_id'];
|
||||
} elseif ($target_type == 'event') {
|
||||
$event_id = $target_id;
|
||||
} elseif ($target_type === 'tag_collection') {
|
||||
// pass
|
||||
} else {
|
||||
throw new MethodNotAllowedException('Invalid options');
|
||||
if ($this->request->is('ajax') && $this->request->is('get')) {
|
||||
$this->set('url', Router::url());
|
||||
return $this->render('/Elements/emptyForm', false);
|
||||
}
|
||||
|
||||
if ($target_type === 'tag_collection') {
|
||||
$tag_collection = $this->GalaxyCluster->Tag->TagCollectionTag->TagCollection->fetchTagCollection($this->Auth->user(), array(
|
||||
'conditions' => array('TagCollection.id' => $target_id),
|
||||
'contain' => array('Organisation', 'TagCollectionTag' => array('Tag'))
|
||||
));
|
||||
if (empty($tag_collection)) {
|
||||
throw new MethodNotAllowedException('Invalid Tag Collection');
|
||||
}
|
||||
$tag_collection = $tag_collection[0];
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
if (!$this->userRole['perm_tag_editor'] || $this->Auth->user('org_id') !== $tag_collection['TagCollection']['org_id']) {
|
||||
throw new MethodNotAllowedException('Invalid Tag Collection');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->Event->id = $event_id;
|
||||
$this->Event->recursive = -1;
|
||||
$event = $this->Event->read(array(), $event_id);
|
||||
if (empty($event)) {
|
||||
throw new MethodNotAllowedException('Invalid Event.');
|
||||
}
|
||||
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
|
||||
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['org_id'] && $this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
|
||||
throw new MethodNotAllowedException('Invalid Event.');
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->request->allowMethod(['post']);
|
||||
|
||||
if ($target_type == 'attribute') {
|
||||
$existingTargetTag = $this->Event->Attribute->AttributeTag->find('first', array(
|
||||
'conditions' => array('AttributeTag.tag_id' => $tag_id, 'AttributeTag.attribute_id' => $target_id),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
} elseif ($target_type == 'event') {
|
||||
$existingTargetTag = $this->Event->EventTag->find('first', array(
|
||||
'conditions' => array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $target_id),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
} elseif ($target_type == 'tag_collection') {
|
||||
$existingTargetTag = $this->GalaxyCluster->Tag->TagCollectionTag->find('first', array(
|
||||
'conditions' => array('TagCollectionTag.tag_id' => $tag_id, 'TagCollectionTag.tag_collection_id' => $target_id),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
}
|
||||
|
||||
if (empty($existingTargetTag)) {
|
||||
$this->Flash->error('Galaxy not attached.');
|
||||
} else {
|
||||
$cluster = $this->GalaxyCluster->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('GalaxyCluster.tag_name' => $existingTargetTag['Tag']['name'])
|
||||
));
|
||||
if ($target_type == 'event') {
|
||||
$result = $this->Event->EventTag->delete($existingTargetTag['EventTag']['id']);
|
||||
} elseif ($target_type == 'attribute') {
|
||||
$result = $this->Event->Attribute->AttributeTag->delete($existingTargetTag['AttributeTag']['id']);
|
||||
} elseif ($target_type == 'tag_collection') {
|
||||
$result = $this->GalaxyCluster->Tag->TagCollectionTag->delete($existingTargetTag['TagCollectionTag']['id']);
|
||||
}
|
||||
if ($result) {
|
||||
$event['Event']['published'] = 0;
|
||||
$date = new DateTime();
|
||||
$event['Event']['timestamp'] = $date->getTimestamp();
|
||||
$this->Event->save($event);
|
||||
$this->Flash->success('Galaxy successfully detached.');
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => $this->Auth->user('Organisation')['name'],
|
||||
'model' => ucfirst($target_type),
|
||||
'model_id' => $target_id,
|
||||
'email' => $this->Auth->user('email'),
|
||||
'action' => 'galaxy',
|
||||
'title' => 'Detached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') from ' . $target_type . ' (' . $target_id . ')',
|
||||
'change' => ''
|
||||
));
|
||||
try {
|
||||
$this->GalaxyCluster->Galaxy->detachClusterByTagId($this->Auth->user(), $target_id, $target_type, $tag_id);
|
||||
} catch (NotFoundException $e) {
|
||||
if (!$this->request->is('ajax')) {
|
||||
$this->Flash->error($e->getMessage());
|
||||
} else {
|
||||
$this->Flash->error('Could not detach galaxy from event.');
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$message = __('Galaxy successfully detached.');
|
||||
|
||||
if ($this->request->is('ajax')) {
|
||||
return $this->RestResponse->viewData(['saved' => true, 'check_publish' => true, 'success' => $message], 'json');
|
||||
}
|
||||
|
||||
$this->Flash->success($message);
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class GalaxyElementsController extends AppController
|
|||
$this->set('JSONElements', $expanded);
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/index');
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class GalaxyElementsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This function can only be reached via AJAX.'));
|
||||
} else {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('elementId', $elementId);
|
||||
$this->render('ajax/delete');
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ class GalaxyElementsController extends AppController
|
|||
}
|
||||
$this->set('clusterId', $clusterId);
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/flattenJson');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,15 @@ class JobsController extends AppController
|
|||
),
|
||||
);
|
||||
|
||||
public function beforeFilter()
|
||||
{
|
||||
parent::beforeFilter();
|
||||
|
||||
if ($this->request->action === 'getGenerateCorrelationProgress') {
|
||||
$this->Security->doNotGenerateToken = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function index($queue = false)
|
||||
{
|
||||
if (!Configure::read('MISP.background_jobs')) {
|
||||
|
@ -24,9 +33,9 @@ class JobsController extends AppController
|
|||
$this->loadModel('Server');
|
||||
$issueCount = 0;
|
||||
$workers = $this->Server->workerDiagnostics($issueCount);
|
||||
$queues = array('email', 'default', 'cache', 'prio', 'update');
|
||||
$queues = ['email', 'default', 'cache', 'prio', 'update'];
|
||||
if ($queue && in_array($queue, $queues, true)) {
|
||||
$this->paginate['conditions'] = array('Job.worker' => $queue);
|
||||
$this->paginate['conditions'] = ['Job.worker' => $queue];
|
||||
}
|
||||
$jobs = $this->paginate();
|
||||
foreach ($jobs as &$job) {
|
||||
|
@ -37,9 +46,9 @@ class JobsController extends AppController
|
|||
$job['Job']['job_status'] = 'Unknown';
|
||||
$job['Job']['failed'] = null;
|
||||
}
|
||||
if(Configure::read('SimpleBackgroundJobs.enabled')){
|
||||
if (Configure::read('SimpleBackgroundJobs.enabled')) {
|
||||
$job['Job']['worker_status'] = true;
|
||||
}else{
|
||||
} else {
|
||||
$job['Job']['worker_status'] = isset($workers[$job['Job']['worker']]) && $workers[$job['Job']['worker']]['ok'];
|
||||
}
|
||||
}
|
||||
|
@ -78,20 +87,27 @@ class JobsController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function getGenerateCorrelationProgress($id)
|
||||
public function getGenerateCorrelationProgress($ids)
|
||||
{
|
||||
$job = $this->Job->find('first', [
|
||||
'fields' => ['progress', 'process_id'],
|
||||
'conditions' => ['id' => $id],
|
||||
$this->_closeSession();
|
||||
|
||||
$ids = explode(",", $ids);
|
||||
$jobs = $this->Job->find('all', [
|
||||
'fields' => ['id', 'progress', 'process_id'],
|
||||
'conditions' => ['id' => $ids],
|
||||
'recursive' => -1,
|
||||
]);
|
||||
if (!$job) {
|
||||
throw new NotFoundException("Job with ID `$id` not found");
|
||||
if (empty($jobs)) {
|
||||
throw new NotFoundException('No jobs found');
|
||||
}
|
||||
|
||||
$output = [];
|
||||
foreach ($jobs as $job) {
|
||||
$output[$job['Job']['id']] = [
|
||||
'job_status' => $this->__getJobStatus($job['Job']['process_id']),
|
||||
'progress' => (int)$job['Job']['progress'],
|
||||
];
|
||||
}
|
||||
$output = [
|
||||
'job_status' => $this->__getJobStatus($job['Job']['process_id']),
|
||||
'progress' => (int)$job['Job']['progress'],
|
||||
];
|
||||
return $this->RestResponse->viewData($output, 'json');
|
||||
}
|
||||
|
||||
|
|
|
@ -30,17 +30,17 @@ class LogsController extends AppController
|
|||
|
||||
public function admin_index()
|
||||
{
|
||||
$paramArray = array('id', 'title', 'created', 'model', 'model_id', 'action', 'user_id', 'change', 'email', 'org', 'description', 'ip');
|
||||
$filterData = array(
|
||||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => func_get_args()
|
||||
);
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
if ($this->_isRest()) {
|
||||
$paramArray = array('id', 'title', 'created', 'model', 'model_id', 'action', 'user_id', 'change', 'email', 'org', 'description', 'ip');
|
||||
$filterData = array(
|
||||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => func_get_args()
|
||||
);
|
||||
$exception = false;
|
||||
$filters = $this->_harvestParameters($filterData, $exception);
|
||||
unset($filterData);
|
||||
if ($filters === false) {
|
||||
return $exception;
|
||||
}
|
||||
|
@ -100,6 +100,9 @@ class LogsController extends AppController
|
|||
if (isset($this->params['named']['filter']) && in_array($this->params['named']['filter'], array_keys($validFilters))) {
|
||||
$this->paginate['conditions']['Log.action'] = $validFilters[$this->params['named']['filter']]['values'];
|
||||
}
|
||||
foreach ($filters as $key => $value) {
|
||||
$this->paginate['conditions']["Log.$key"] = $value;
|
||||
}
|
||||
$this->set('validFilters', $validFilters);
|
||||
$this->set('filter', isset($this->params['named']['filter']) ? $this->params['named']['filter'] : false);
|
||||
$this->set('list', $this->paginate());
|
||||
|
@ -389,6 +392,7 @@ class LogsController extends AppController
|
|||
'Galaxy',
|
||||
'GalaxyCluster',
|
||||
'GalaxyClusterRelation',
|
||||
'Workflow',
|
||||
];
|
||||
sort($models);
|
||||
$models = array('' => 'ALL') + $this->_arrayToValuesIndexArray($models);
|
||||
|
|
|
@ -168,7 +168,7 @@ class NoticelistsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException('This action is available via AJAX only.');
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/getToggleField');
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ class ObjectReferencesController extends AppController
|
|||
$this->set('relationships', $relationships);
|
||||
$this->set('event', $event);
|
||||
$this->set('objectId', $object['Object']['id']);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/add');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class ObjectTemplateElementsController extends AppController
|
|||
$this->paginate['conditions'] = array('ObjectTemplateElement.object_template_id' => $id);
|
||||
$elements = $this->paginate();
|
||||
$this->set('list', $elements);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/view_elements');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,18 +9,28 @@ class ObjectTemplatesController extends AppController
|
|||
public $components = array('RequestHandler', 'Session');
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'order' => array(
|
||||
'Object.id' => 'desc'
|
||||
),
|
||||
'contain' => array(
|
||||
'Organisation' => array('fields' => array('Organisation.id', 'Organisation.name', 'Organisation.uuid'))
|
||||
),
|
||||
'recursive' => -1
|
||||
'limit' => 60,
|
||||
'order' => array(
|
||||
'Object.id' => 'desc'
|
||||
),
|
||||
'contain' => array(
|
||||
'Organisation' => array('fields' => array('Organisation.id', 'Organisation.name', 'Organisation.uuid'))
|
||||
),
|
||||
'recursive' => -1
|
||||
);
|
||||
|
||||
public function objectMetaChoice($event_id)
|
||||
public function beforeFilter()
|
||||
{
|
||||
parent::beforeFilter();
|
||||
if (in_array($this->request->action, ['objectMetaChoice', 'objectChoice'], true)) {
|
||||
$this->Security->doNotGenerateToken = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function objectMetaChoice($eventId)
|
||||
{
|
||||
session_abort();
|
||||
|
||||
$metas = $this->ObjectTemplate->find('column', array(
|
||||
'conditions' => array('ObjectTemplate.active' => 1),
|
||||
'fields' => array('ObjectTemplate.meta-category'),
|
||||
|
@ -28,7 +38,6 @@ class ObjectTemplatesController extends AppController
|
|||
'unique' => true,
|
||||
));
|
||||
|
||||
$eventId = h($event_id);
|
||||
$items = [[
|
||||
'name' => __('All Objects'),
|
||||
'value' => $this->baseurl . "/ObjectTemplates/objectChoice/$eventId/0"
|
||||
|
@ -36,7 +45,7 @@ class ObjectTemplatesController extends AppController
|
|||
foreach ($metas as $meta) {
|
||||
$items[] = array(
|
||||
'name' => $meta,
|
||||
'value' => $this->baseurl . "/ObjectTemplates/objectChoice/$eventId/" . h($meta)
|
||||
'value' => $this->baseurl . "/ObjectTemplates/objectChoice/$eventId/$meta",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -49,7 +58,8 @@ class ObjectTemplatesController extends AppController
|
|||
|
||||
public function objectChoice($event_id, $category=false)
|
||||
{
|
||||
$this->ObjectTemplate->populateIfEmpty($this->Auth->user());
|
||||
$user = $this->_closeSession();
|
||||
$this->ObjectTemplate->populateIfEmpty($user);
|
||||
$conditions = array('ObjectTemplate.active' => 1);
|
||||
if ($category !== false && $category !== "0") {
|
||||
$conditions['meta-category'] = $category;
|
||||
|
@ -158,7 +168,7 @@ class ObjectTemplatesController extends AppController
|
|||
'conditions' => array('ObjectTemplateElement.object_template_id' => $id)
|
||||
));
|
||||
$this->set('list', $elements);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/view_elements');
|
||||
}
|
||||
|
||||
|
@ -293,7 +303,7 @@ class ObjectTemplatesController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException('This action is available via AJAX only.');
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/getToggleField');
|
||||
}
|
||||
|
||||
|
|
|
@ -600,7 +600,7 @@ class ObjectsController extends AppController
|
|||
}
|
||||
$this->set('value', $result);
|
||||
$this->set('field', $field);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/objectViewFieldForm');
|
||||
}
|
||||
|
||||
|
@ -632,7 +632,7 @@ class ObjectsController extends AppController
|
|||
if (!$this->__canModifyEvent($object)) {
|
||||
throw new NotFoundException(__('Invalid object'));
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
if ($field == 'distribution') {
|
||||
$distributionLevels = $this->MispObject->shortDist;
|
||||
unset($distributionLevels[4]);
|
||||
|
@ -728,10 +728,9 @@ class ObjectsController extends AppController
|
|||
if (!isset($fieldName)) {
|
||||
throw new MethodNotAllowedException('No field requested.');
|
||||
}
|
||||
$fields = array('template_uuid', 'template_version', 'id', 'event_id');
|
||||
$params = array(
|
||||
'conditions' => array('Object.id' => $id),
|
||||
'fields' => $fields,
|
||||
'fields' => array('template_uuid', 'template_version', 'id', 'event_id'),
|
||||
'flatten' => 1,
|
||||
'contain' => array(
|
||||
'Event'
|
||||
|
@ -741,9 +740,8 @@ class ObjectsController extends AppController
|
|||
$object = $this->MispObject->fetchObjects($this->Auth->user(), $params);
|
||||
if (empty($object)) {
|
||||
throw new NotFoundException(__('Invalid object'));
|
||||
} else {
|
||||
$object = $object[0];
|
||||
}
|
||||
$object = $object[0];
|
||||
if (!$this->__canModifyEvent($object)) {
|
||||
throw new ForbiddenException(__('You do not have permission to do that.'));
|
||||
}
|
||||
|
@ -768,25 +766,30 @@ class ObjectsController extends AppController
|
|||
}
|
||||
|
||||
// check if fields can be added
|
||||
foreach($object['Attribute'] as $i => $objAttr) {
|
||||
foreach($object['Attribute'] as $objAttr) {
|
||||
$objectAttrFromTemplate = $template['ObjectTemplateElement'][0];
|
||||
if ($objAttr['object_relation'] == $fieldName && !$objectAttrFromTemplate['multiple']) {
|
||||
throw new NotFoundException(__('Invalid field'));
|
||||
}
|
||||
}
|
||||
$template = $this->MispObject->prepareTemplate($template, $object);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('object', $object['Object']);
|
||||
$template_element = $template['ObjectTemplateElement'][0];
|
||||
unset($template_element['value']); // avoid filling if multiple
|
||||
$this->set('template_element', $template_element);
|
||||
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
|
||||
$distributionData = $this->MispObject->Attribute->fetchDistributionData($this->Auth->user());
|
||||
$this->set('distributionData', $distributionData);
|
||||
$info = array();
|
||||
foreach ($distributionData['levels'] as $key => $value) {
|
||||
$info['distribution'][$key] = array('key' => $value, 'desc' => $this->MispObject->Event->Attribute->distributionDescriptions[$key]['formdesc']);
|
||||
|
||||
$info = ['category' => [], 'distribution' => []];
|
||||
foreach ($this->MispObject->Attribute->categoryDefinitions as $key => $value) {
|
||||
$info['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
$this->set('info', $info);
|
||||
foreach ($this->MispObject->Attribute->distributionLevels as $key => $value) {
|
||||
$info['distribution'][$key] = $this->MispObject->Attribute->distributionDescriptions[$key]['formdesc'];
|
||||
}
|
||||
|
||||
$this->set('fieldDesc', $info);
|
||||
$this->render('ajax/quickAddAttributeForm');
|
||||
} else if ($this->request->is('post') || $this->request->is('put')) {
|
||||
return $this->edit($this->request->data['Object']['id'], false, true);
|
||||
|
|
|
@ -39,7 +39,7 @@ class PostsController extends AppController
|
|||
$event_id = 0;
|
||||
$post_id = 0;
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
}
|
||||
// we have a target type and a target id. The target id defines what type of object we want to attach this event to (is it a reply to another post,
|
||||
// did someone add a post to a thread, does a thread for the event exist already, etc.
|
||||
|
|
|
@ -949,7 +949,14 @@ class ServersController extends AppController
|
|||
public function serverSettingsReloadSetting($setting, $id)
|
||||
{
|
||||
$pathToSetting = explode('.', $setting);
|
||||
if (strpos($setting, 'Plugin.Enrichment') !== false || strpos($setting, 'Plugin.Import') !== false || strpos($setting, 'Plugin.Export') !== false || strpos($setting, 'Plugin.Cortex') !== false) {
|
||||
if (
|
||||
strpos($setting, 'Plugin.Enrichment') !== false ||
|
||||
strpos($setting, 'Plugin.Import') !== false ||
|
||||
strpos($setting, 'Plugin.Export') !== false ||
|
||||
strpos($setting, 'Plugin.Cortex') !== false ||
|
||||
strpos($setting, 'Plugin.Action') !== false ||
|
||||
strpos($setting, 'Plugin.Workflow') !== false
|
||||
) {
|
||||
$settingObject = $this->Server->getCurrentServerSettings();
|
||||
} else {
|
||||
$settingObject = $this->Server->serverSettings;
|
||||
|
@ -997,7 +1004,13 @@ class ServersController extends AppController
|
|||
$gpgErrors = array(0 => __('OK'), 1 => __('FAIL: settings not set'), 2 => __('FAIL: Failed to load GnuPG'), 3 => __('FAIL: Issues with the key/passphrase'), 4 => __('FAIL: sign failed'));
|
||||
$proxyErrors = array(0 => __('OK'), 1 => __('not configured (so not tested)'), 2 => __('Getting URL via proxy failed'));
|
||||
$zmqErrors = array(0 => __('OK'), 1 => __('not enabled (so not tested)'), 2 => __('Python ZeroMQ library not installed correctly.'), 3 => __('ZeroMQ script not running.'));
|
||||
$sessionErrors = array(0 => __('OK'), 1 => __('High'), 2 => __('Alternative setting used'), 3 => __('Test failed'));
|
||||
$sessionErrors = array(
|
||||
0 => __('OK'),
|
||||
1 => __('Too many expired sessions in the database, please clear the expired sessions'),
|
||||
2 => __('PHP session handler is using the default file storage. This is not recommended, please use the redis or database storage'),
|
||||
8 => __('Alternative setting used'),
|
||||
9 => __('Test failed')
|
||||
);
|
||||
$moduleErrors = array(0 => __('OK'), 1 => __('System not enabled'), 2 => __('No modules found'));
|
||||
$backgroundJobsErrors = array(
|
||||
0 => __('OK'),
|
||||
|
@ -1060,6 +1073,11 @@ class ServersController extends AppController
|
|||
$diagnostic_errors = 0;
|
||||
App::uses('File', 'Utility');
|
||||
App::uses('Folder', 'Utility');
|
||||
if ($tab === 'correlations') {
|
||||
$this->loadModel('Correlation');
|
||||
$correlation_metrics = $this->Correlation->collectMetrics();
|
||||
$this->set('correlation_metrics', $correlation_metrics);
|
||||
}
|
||||
if ($tab === 'files') {
|
||||
$files = $this->Server->grabFiles();
|
||||
$this->set('files', $files);
|
||||
|
@ -1141,6 +1159,7 @@ class ServersController extends AppController
|
|||
// get the DB diagnostics
|
||||
$dbDiagnostics = $this->Server->dbSpaceUsage();
|
||||
$dbSchemaDiagnostics = $this->Server->dbSchemaDiagnostic();
|
||||
$dbConfiguration = $this->Server->dbConfiguration();
|
||||
|
||||
$redisInfo = $this->Server->redisInfo();
|
||||
|
||||
|
@ -1149,10 +1168,8 @@ class ServersController extends AppController
|
|||
$moduleStatus[$type] = $this->Server->moduleDiagnostics($diagnostic_errors, $type);
|
||||
}
|
||||
|
||||
// check the size of the session table
|
||||
$sessionCount = 0;
|
||||
$sessionStatus = $this->Server->sessionDiagnostics($diagnostic_errors, $sessionCount);
|
||||
$this->set('sessionCount', $sessionCount);
|
||||
// get php session diagnostics
|
||||
$sessionStatus = $this->Server->sessionDiagnostics($diagnostic_errors);
|
||||
|
||||
$this->loadModel('AttachmentScan');
|
||||
try {
|
||||
|
@ -1163,7 +1180,7 @@ class ServersController extends AppController
|
|||
|
||||
$securityAudit = (new SecurityAudit())->run($this->Server);
|
||||
|
||||
$view = compact('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'redisInfo', 'attachmentScan', 'securityAudit');
|
||||
$view = compact('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'dbConfiguration', 'redisInfo', 'attachmentScan', 'securityAudit');
|
||||
} else {
|
||||
$view = [];
|
||||
}
|
||||
|
@ -1204,6 +1221,7 @@ class ServersController extends AppController
|
|||
'readableFiles' => $readableFiles,
|
||||
'dbDiagnostics' => $dbDiagnostics,
|
||||
'dbSchemaDiagnostics' => $dbSchemaDiagnostics,
|
||||
'dbConfiguration' => $dbConfiguration,
|
||||
'redisInfo' => $redisInfo,
|
||||
'finalSettings' => $dumpResults,
|
||||
'extensions' => $extensions,
|
||||
|
@ -1441,7 +1459,6 @@ class ServersController extends AppController
|
|||
}
|
||||
$this->set('id', $id);
|
||||
}
|
||||
|
||||
$setting = $this->Server->getSettingData($settingName);
|
||||
if ($setting === false) {
|
||||
throw new NotFoundException(__('Setting %s is invalid.', $settingName));
|
||||
|
@ -1913,7 +1930,7 @@ class ServersController extends AppController
|
|||
$dbVersion = $this->AdminSetting->getSetting('db_version');
|
||||
$updateProgress = $this->Server->getUpdateProgress();
|
||||
$updateProgress['db_version'] = $dbVersion;
|
||||
$maxUpdateNumber = max(array_keys($this->Server->db_changes));
|
||||
$maxUpdateNumber = max(array_keys(Server::DB_CHANGES));
|
||||
$updateProgress['complete_update_remaining'] = max($maxUpdateNumber - $dbVersion, 0);
|
||||
$updateProgress['update_locked'] = $this->Server->isUpdateLocked();
|
||||
$updateProgress['lock_remaining_time'] = $this->Server->getLockRemainingTime();
|
||||
|
@ -2202,6 +2219,17 @@ class ServersController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
public function dbConfiguration()
|
||||
{
|
||||
$dbConfiguration = $this->Server->dbConfiguration();
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($dbConfiguration, $this->response->type());
|
||||
} else {
|
||||
$this->set('dbConfiguration', $dbConfiguration);
|
||||
$this->render('/Elements/healthElements/db_config_diagnostic');
|
||||
}
|
||||
}
|
||||
|
||||
public function cspReport()
|
||||
{
|
||||
if (!$this->request->is('post')) {
|
||||
|
|
|
@ -254,7 +254,7 @@ class ShadowAttributesController extends AppController
|
|||
{
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->set('ajax', true);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
} else {
|
||||
$this->set('ajax', false);
|
||||
}
|
||||
|
@ -406,27 +406,14 @@ class ShadowAttributesController extends AppController
|
|||
}
|
||||
$this->set('event_id', $event['Event']['id']);
|
||||
// combobox for types
|
||||
$types = array_keys($this->ShadowAttribute->typeDefinitions);
|
||||
foreach ($types as $key => $value) {
|
||||
if (in_array($value, array('malware-sample', 'attachment'))) {
|
||||
unset($types[$key]);
|
||||
}
|
||||
}
|
||||
$types = $this->ShadowAttribute->Attribute->getNonAttachmentTypes();
|
||||
$types = $this->_arrayToValuesIndexArray($types);
|
||||
$this->set('types', $types);
|
||||
// combobox for categories
|
||||
$categories = array_keys($this->ShadowAttribute->Event->Attribute->categoryDefinitions);
|
||||
$categories = array_keys($this->ShadowAttribute->Attribute->categoryDefinitions);
|
||||
$categories = $this->_arrayToValuesIndexArray($categories);
|
||||
$this->set('categories', $categories);
|
||||
|
||||
$fieldDesc = ['category' => [], 'type' => []];
|
||||
foreach ($this->ShadowAttribute->categoryDefinitions as $key => $value) {
|
||||
$fieldDesc['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
foreach ($this->ShadowAttribute->typeDefinitions as $key => $value) {
|
||||
$fieldDesc['type'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
$this->set('fieldDesc', $fieldDesc);
|
||||
$this->__common();
|
||||
$this->set('categoryDefinitions', $this->ShadowAttribute->categoryDefinitions);
|
||||
}
|
||||
|
||||
|
@ -531,19 +518,19 @@ class ShadowAttributesController extends AppController
|
|||
}
|
||||
} else {
|
||||
$shadowAttribute = array(
|
||||
'ShadowAttribute' => array(
|
||||
'value' => $filename,
|
||||
'category' => $this->request->data['ShadowAttribute']['category'],
|
||||
'type' => 'attachment',
|
||||
'event_id' => $this->request->data['ShadowAttribute']['event_id'],
|
||||
'comment' => $this->request->data['ShadowAttribute']['comment'],
|
||||
'data' => base64_encode($tmpfile->read()),
|
||||
'to_ids' => 0,
|
||||
'email' => $this->Auth->user('email'),
|
||||
'org_id' => $this->Auth->user('org_id'),
|
||||
'event_uuid' => $event['Event']['uuid'],
|
||||
'event_org_id' => $event['Event']['orgc_id'],
|
||||
)
|
||||
'ShadowAttribute' => array(
|
||||
'value' => $filename,
|
||||
'category' => $this->request->data['ShadowAttribute']['category'],
|
||||
'type' => 'attachment',
|
||||
'event_id' => $this->request->data['ShadowAttribute']['event_id'],
|
||||
'comment' => $this->request->data['ShadowAttribute']['comment'],
|
||||
'data' => base64_encode($tmpfile->read()),
|
||||
'to_ids' => 0,
|
||||
'email' => $this->Auth->user('email'),
|
||||
'org_id' => $this->Auth->user('org_id'),
|
||||
'event_uuid' => $event['Event']['uuid'],
|
||||
'event_org_id' => $event['Event']['orgc_id'],
|
||||
)
|
||||
);
|
||||
$this->ShadowAttribute->create();
|
||||
$r = $this->ShadowAttribute->save($shadowAttribute);
|
||||
|
@ -593,17 +580,14 @@ class ShadowAttributesController extends AppController
|
|||
|
||||
$categories = $this->_arrayToValuesIndexArray($selectedCategories);
|
||||
$this->set('categories', $categories);
|
||||
foreach ($this->ShadowAttribute->categoryDefinitions as $key => $value) {
|
||||
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
}
|
||||
foreach ($this->ShadowAttribute->typeDefinitions as $key => $value) {
|
||||
$info['type'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
}
|
||||
$this->set('info', $info);
|
||||
$this->__common();
|
||||
$this->set('attrDescriptions', $this->ShadowAttribute->fieldDescriptions);
|
||||
$this->set('typeDefinitions', $this->ShadowAttribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->ShadowAttribute->categoryDefinitions);
|
||||
$this->set('isMalwareSampleCategory', $isMalwareSampleCategory);
|
||||
$this->set('mayModify', $this->__canModifyEvent($event));
|
||||
$this->set('event', $event);
|
||||
$this->set('title_for_layout', __('Propose attachment'));
|
||||
}
|
||||
|
||||
// Propose an edit to an attribute
|
||||
|
@ -623,7 +607,7 @@ class ShadowAttributesController extends AppController
|
|||
$existingAttribute = $existingAttribute[0];
|
||||
|
||||
// Check if the attribute is an attachment, if yes, block the type and the value fields from being edited.
|
||||
if ('attachment' == $existingAttribute['Attribute']['type'] || 'malware-sample' == $existingAttribute['Attribute']['type']) {
|
||||
if ($this->ShadowAttribute->Attribute->typeIsAttachment($existingAttribute['Attribute']['type'])) {
|
||||
$this->set('attachment', true);
|
||||
$attachment = true;
|
||||
} else {
|
||||
|
@ -718,12 +702,7 @@ class ShadowAttributesController extends AppController
|
|||
}
|
||||
|
||||
// combobox for types
|
||||
$types = array_keys($this->ShadowAttribute->typeDefinitions);
|
||||
foreach ($types as $key => $value) {
|
||||
if (in_array($value, array('malware-sample', 'attachment'))) {
|
||||
unset($types[$key]);
|
||||
}
|
||||
}
|
||||
$types = $this->ShadowAttribute->Attribute->getNonAttachmentTypes();
|
||||
if ($existingAttribute['Attribute']['object_id']) {
|
||||
$this->set('objectAttribute', true);
|
||||
} else {
|
||||
|
@ -732,15 +711,10 @@ class ShadowAttributesController extends AppController
|
|||
$types = $this->_arrayToValuesIndexArray($types);
|
||||
$this->set('types', $types);
|
||||
// combobox for categories
|
||||
$categories = $this->_arrayToValuesIndexArray(array_keys($this->ShadowAttribute->Event->Attribute->categoryDefinitions));
|
||||
$categories = $this->_arrayToValuesIndexArray(array_keys($this->ShadowAttribute->Attribute->categoryDefinitions));
|
||||
$categories = $this->_arrayToValuesIndexArray($categories);
|
||||
foreach ($this->ShadowAttribute->Event->Attribute->categoryDefinitions as $key => $value) {
|
||||
$info['category'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
}
|
||||
foreach ($this->ShadowAttribute->Event->Attribute->typeDefinitions as $key => $value) {
|
||||
$info['type'][$key] = array('key' => $key, 'desc' => isset($value['formdesc'])? $value['formdesc'] : $value['desc']);
|
||||
}
|
||||
$categoryDefinitions = $this->ShadowAttribute->Event->Attribute->categoryDefinitions;
|
||||
|
||||
$categoryDefinitions = $this->ShadowAttribute->Attribute->categoryDefinitions;
|
||||
if ($existingAttribute['Attribute']['object_id']) {
|
||||
foreach ($categoryDefinitions as $k => $v) {
|
||||
if (!in_array($existingAttribute['Attribute']['type'], $v['types'])) {
|
||||
|
@ -754,10 +728,22 @@ class ShadowAttributesController extends AppController
|
|||
}
|
||||
}
|
||||
$this->set('categories', $categories);
|
||||
$this->set('info', $info);
|
||||
$this->__common();
|
||||
$this->set('attrDescriptions', $this->ShadowAttribute->fieldDescriptions);
|
||||
$this->set('typeDefinitions', $this->ShadowAttribute->typeDefinitions);
|
||||
$this->set('categoryDefinitions', $this->ShadowAttribute->Event->Attribute->categoryDefinitions);
|
||||
$this->set('categoryDefinitions', $this->ShadowAttribute->Attribute->categoryDefinitions);
|
||||
}
|
||||
|
||||
private function __common()
|
||||
{
|
||||
$fieldDesc = ['category' => [], 'type' => []];
|
||||
foreach ($this->ShadowAttribute->categoryDefinitions as $key => $value) {
|
||||
$fieldDesc['category'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
foreach ($this->ShadowAttribute->typeDefinitions as $key => $value) {
|
||||
$fieldDesc['type'][$key] = isset($value['formdesc']) ? $value['formdesc'] : $value['desc'];
|
||||
}
|
||||
$this->set('fieldDesc', $fieldDesc);
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
|
|
|
@ -151,7 +151,7 @@ class SharingGroupBlueprintsController extends AppController
|
|||
$this->set('title', __('Execute Sharing Group Blueprint'));
|
||||
$this->set('question', __('Are you sure you want to (re)create a sharing group based on the Sharing Group Blueprint?'));
|
||||
$this->set('actionName', __('Execute'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ class SharingGroupBlueprintsController extends AppController
|
|||
$this->set('title', __('Detach Sharing Group Blueprint'));
|
||||
$this->set('question', __('Are you sure you want to detach the associated sharing group from this Sharing Group Blueprint? This action is irreversible.'));
|
||||
$this->set('actionName', __('Detach'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/genericTemplates/confirm');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,7 +260,7 @@ class SharingGroupsController extends AppController
|
|||
public function index($passive = false)
|
||||
{
|
||||
$passive = $passive === 'true';
|
||||
$authorizedSgIds = $this->SharingGroup->fetchAllAuthorised($this->Auth->user());
|
||||
$authorizedSgIds = $this->SharingGroup->authorizedIds($this->Auth->user());
|
||||
$this->paginate['conditions'][] = array('SharingGroup.id' => $authorizedSgIds);
|
||||
$this->paginate['conditions'][] = array('SharingGroup.active' => $passive === true ? 0 : 1);
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ class SightingsController extends AppController
|
|||
}
|
||||
|
||||
$this->set('csv', $statistics['csv']['all']);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/view_sightings');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,29 +13,29 @@ class TagCollectionsController extends AppController
|
|||
);
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'order' => array(
|
||||
'TagCollection.name' => 'ASC'
|
||||
'limit' => 60,
|
||||
'order' => array(
|
||||
'TagCollection.name' => 'ASC'
|
||||
),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'TagCollectionTag' => array(
|
||||
'Tag'
|
||||
),
|
||||
'recursive' => -1,
|
||||
'contain' => array(
|
||||
'TagCollectionTag' => array(
|
||||
'Tag'
|
||||
),
|
||||
'Organisation' => array(
|
||||
'fields' => array(
|
||||
'Organisation.id',
|
||||
'Organisation.name',
|
||||
'Organisation.uuid'
|
||||
)
|
||||
),
|
||||
'User' => array(
|
||||
'fields' => array(
|
||||
'User.email',
|
||||
'User.id'
|
||||
)
|
||||
'Organisation' => array(
|
||||
'fields' => array(
|
||||
'Organisation.id',
|
||||
'Organisation.name',
|
||||
'Organisation.uuid'
|
||||
)
|
||||
),
|
||||
'User' => array(
|
||||
'fields' => array(
|
||||
'User.email',
|
||||
'User.id'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function add()
|
||||
|
@ -387,7 +387,7 @@ class TagCollectionsController extends AppController
|
|||
$this->set('tag_id', $tag_id);
|
||||
$this->set('model', 'tag_collection');
|
||||
$this->set('model_name', $tagCollection['TagCollection']['name']);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/Attributes/ajax/tagRemoveConfirmation');
|
||||
} else {
|
||||
$rearrangeRules = array(
|
||||
|
@ -446,7 +446,6 @@ class TagCollectionsController extends AppController
|
|||
|
||||
public function index()
|
||||
{
|
||||
//$this->Auth->user('Role')['perm_site_admin']);
|
||||
$conditions = array();
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions = array(
|
||||
|
@ -512,9 +511,9 @@ class TagCollectionsController extends AppController
|
|||
}
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($list, $this->response->type());
|
||||
} else {
|
||||
$this->set('list', $list);
|
||||
}
|
||||
$this->set('list', $list);
|
||||
$this->set('title_for_layout', __('Tag Collections'));
|
||||
}
|
||||
|
||||
public function getRow($id)
|
||||
|
|
|
@ -349,9 +349,10 @@ class TagsController extends AppController
|
|||
|
||||
public function showEventTag($id)
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
$this->loadModel('Taxonomy');
|
||||
|
||||
$event = $this->Tag->EventTag->Event->fetchSimpleEvent($this->Auth->user(), $id, [
|
||||
$event = $this->Tag->EventTag->Event->fetchSimpleEvent($user, $id, [
|
||||
'fields' => ['Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.user_id'],
|
||||
'contain' => [
|
||||
'EventTag' => array(
|
||||
|
@ -364,24 +365,26 @@ class TagsController extends AppController
|
|||
throw new NotFoundException(__('Invalid event.'));
|
||||
}
|
||||
// Remove galaxy tags
|
||||
$event = $this->Tag->EventTag->Event->massageTags($this->Auth->user(), $event, 'Event', false, true);
|
||||
$event = $this->Tag->removeGalaxyClusterTags($user, $event);
|
||||
|
||||
$this->set('tags', $event['EventTag']);
|
||||
$this->set('missingTaxonomies', $this->Tag->EventTag->Event->missingTaxonomies($event));
|
||||
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($event['EventTag']);
|
||||
$this->set('tagConflicts', $tagConflicts);
|
||||
$this->set('event', $event);
|
||||
$this->layout = 'ajax';
|
||||
$this->set('mayModify', $this->__canModifyEvent($event, $user));
|
||||
$this->layout = false;
|
||||
$this->render('/Events/ajax/ajaxTags');
|
||||
}
|
||||
|
||||
public function showAttributeTag($id)
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
$this->helpers[] = 'TextColour';
|
||||
$this->loadModel('Attribute');
|
||||
$this->loadModel('Taxonomy');
|
||||
|
||||
$attributes = $this->Attribute->fetchAttributes($this->Auth->user(), [
|
||||
$attributes = $this->Attribute->fetchAttributes($user, [
|
||||
'conditions' => ['Attribute.id' => $id],
|
||||
'includeAllTags' => true,
|
||||
'flatten' => true,
|
||||
|
@ -394,7 +397,7 @@ class TagsController extends AppController
|
|||
}
|
||||
$attribute = $attributes[0];
|
||||
// Remove galaxy tags
|
||||
$attribute = $this->Tag->EventTag->Event->massageTags($this->Auth->user(), $attribute, 'Attribute', false, true);
|
||||
$attribute = $this->Tag->removeGalaxyClusterTags($user, $attribute, 'Attribute');
|
||||
$attributeTags = $attribute['AttributeTag'];
|
||||
|
||||
$this->set('event', ['Event' => $attribute['Event']]);
|
||||
|
@ -402,7 +405,8 @@ class TagsController extends AppController
|
|||
$this->set('attributeId', $id);
|
||||
$tagConflicts = $this->Taxonomy->checkIfTagInconsistencies($attributeTags);
|
||||
$this->set('tagConflicts', $tagConflicts);
|
||||
$this->layout = 'ajax';
|
||||
$this->set('mayModify', $this->__canModifyEvent($attribute, $user));
|
||||
$this->layout = false;
|
||||
$this->render('/Attributes/ajax/ajaxAttributeTags');
|
||||
}
|
||||
|
||||
|
@ -435,7 +439,7 @@ class TagsController extends AppController
|
|||
'conditions' => array('Event.id' => $id)
|
||||
));
|
||||
$this->set('event', $event);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/Events/ajax/ajaxTags');
|
||||
}
|
||||
|
||||
|
@ -456,13 +460,11 @@ class TagsController extends AppController
|
|||
|
||||
public function selectTaxonomy($id, $scope = 'event')
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
|
||||
throw new NotFoundException('You don\'t have permission to do that.');
|
||||
}
|
||||
$user = $this->_closeSession();
|
||||
$localFlag = !empty($this->params['named']['local']) ? '/local:1' : '';
|
||||
$items = array();
|
||||
$favourites = $this->Tag->FavouriteTag->find('count', array('conditions' => array('FavouriteTag.user_id' => $this->Auth->user('id'))));
|
||||
if ($favourites) {
|
||||
$hasFavourites = $this->Tag->FavouriteTag->hasAny(array('FavouriteTag.user_id' => $user['id']));
|
||||
if ($hasFavourites) {
|
||||
$items[] = array(
|
||||
'name' => __('Favourite Tags'),
|
||||
'value' => $this->baseurl . "/tags/selectTag/" . h($id) . "/favourites/" . h($scope) . $localFlag
|
||||
|
@ -484,11 +486,11 @@ class TagsController extends AppController
|
|||
);
|
||||
|
||||
$this->loadModel('Taxonomy');
|
||||
$options = $this->Taxonomy->find('list', array('conditions' => array('enabled' => true), 'fields' => array('namespace'), 'order' => array('Taxonomy.namespace ASC')));
|
||||
foreach ($options as $k => $option) {
|
||||
$taxonomies = $this->Taxonomy->find('list', array('conditions' => array('enabled' => true), 'fields' => array('namespace'), 'order' => array('Taxonomy.namespace ASC')));
|
||||
foreach ($taxonomies as $taxonomyId => $name) {
|
||||
$items[] = array(
|
||||
'name' => __('Taxonomy Library') . ":" . h($option),
|
||||
'value' => $this->baseurl . "/tags/selectTag/" . h($id) . "/" . h($k) . "/" . h($scope . $localFlag)
|
||||
'name' => __('Taxonomy Library') . ":" . h($name),
|
||||
'value' => $this->baseurl . "/tags/selectTag/" . h($id) . "/" . h($taxonomyId) . "/" . h($scope) . $localFlag
|
||||
);
|
||||
}
|
||||
$this->set('items', $items);
|
||||
|
@ -502,6 +504,7 @@ class TagsController extends AppController
|
|||
|
||||
public function selectTag($id, $taxonomy_id, $scope = 'event', $filterData = '')
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
$this->loadModel('Taxonomy');
|
||||
$expanded = array();
|
||||
$this->set('taxonomy_id', $taxonomy_id);
|
||||
|
@ -527,87 +530,81 @@ class TagsController extends AppController
|
|||
$expanded[$tagCollection['TagCollection']['id']] .= sprintf(' (%s)', $tagList);
|
||||
}
|
||||
}
|
||||
} elseif ($taxonomy_id === '0') { // custom tags
|
||||
$temp = $this->Taxonomy->getAllTaxonomyTags(true, $user, true, true, $local_tag);
|
||||
$tags = array();
|
||||
foreach ($temp as $tag) {
|
||||
$tags[$tag['Tag']['id']] = $tag['Tag'];
|
||||
}
|
||||
unset($temp);
|
||||
$expanded = $tags;
|
||||
} elseif ($taxonomy_id === 'favourites') {
|
||||
$tags = array();
|
||||
$conditions = array(
|
||||
'FavouriteTag.user_id' => $user['id'],
|
||||
'Tag.org_id' => array(0, $user['org_id']),
|
||||
'Tag.user_id' => array(0, $user['id']),
|
||||
'Tag.hide_tag' => 0,
|
||||
);
|
||||
if (!$local_tag) {
|
||||
$conditions['Tag.local_only'] = 0;
|
||||
}
|
||||
$favTags = $this->Tag->FavouriteTag->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag'),
|
||||
'order' => array('Tag.name asc')
|
||||
));
|
||||
foreach ($favTags as $favTag) {
|
||||
$tags[$favTag['FavouriteTag']['tag_id']] = $favTag['Tag'];
|
||||
$expanded = $tags;
|
||||
}
|
||||
} elseif ($taxonomy_id === 'all') { // all tags
|
||||
$conditions = [
|
||||
'Tag.is_galaxy' => 0,
|
||||
'Tag.hide_tag' => 0,
|
||||
];
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions['Tag.org_id'] = array(0, $user['org_id']);
|
||||
$conditions['Tag.user_id'] = array(0, $user['id']);
|
||||
}
|
||||
if (!$local_tag) {
|
||||
$conditions['Tag.local_only'] = 0;
|
||||
}
|
||||
$tags = $this->Tag->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'order' => array('name asc'),
|
||||
'fields' => array('Tag.id', 'Tag.name', 'Tag.colour')
|
||||
));
|
||||
$tags = array_column(array_column($tags, 'Tag'), null, "id");
|
||||
$expanded = $tags;
|
||||
} else {
|
||||
if ($taxonomy_id === '0') {
|
||||
$temp = $this->Taxonomy->getAllTaxonomyTags(true, $this->Auth->user(), true, true, $local_tag);
|
||||
$tags = array();
|
||||
foreach ($temp as $tag) {
|
||||
$tags[$tag['Tag']['id']] = $tag['Tag'];
|
||||
}
|
||||
unset($temp);
|
||||
$expanded = $tags;
|
||||
} elseif ($taxonomy_id === 'favourites') {
|
||||
$tags = array();
|
||||
$conditions = array(
|
||||
'FavouriteTag.user_id' => $this->Auth->user('id'),
|
||||
'Tag.org_id' => array(0, $this->Auth->user('org_id')),
|
||||
'Tag.user_id' => array(0, $this->Auth->user('id')),
|
||||
'Tag.hide_tag' => 0,
|
||||
);
|
||||
if (!$local_tag) {
|
||||
$conditions['Tag.local_only'] = 0;
|
||||
}
|
||||
$favTags = $this->Tag->FavouriteTag->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag'),
|
||||
'order' => array('Tag.name asc')
|
||||
));
|
||||
foreach ($favTags as $favTag) {
|
||||
$tags[$favTag['FavouriteTag']['tag_id']] = $favTag['Tag'];
|
||||
$expanded = $tags;
|
||||
}
|
||||
} elseif ($taxonomy_id === 'all') {
|
||||
$conditions = [
|
||||
'Tag.name NOT LIKE' => 'misp-galaxy:%',
|
||||
'Tag.hide_tag' => 0,
|
||||
];
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions['Tag.org_id'] = array(0, $this->Auth->user('org_id'));
|
||||
$conditions['Tag.user_id'] = array(0, $this->Auth->user('id'));
|
||||
}
|
||||
if (!$local_tag) {
|
||||
$conditions['Tag.local_only'] = 0;
|
||||
}
|
||||
$allTags = $this->Tag->find('all', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'order' => array('name asc'),
|
||||
'fields' => array('Tag.id', 'Tag.name', 'Tag.colour')
|
||||
));
|
||||
$tags = array();
|
||||
foreach ($allTags as $tag) {
|
||||
$tags[$tag['Tag']['id']] = $tag['Tag'];
|
||||
}
|
||||
unset($allTags);
|
||||
$expanded = $tags;
|
||||
} else {
|
||||
$taxonomies = $this->Taxonomy->getTaxonomy($taxonomy_id);
|
||||
$tags = array();
|
||||
if (!empty($taxonomies['entries'])) {
|
||||
$isSiteAdmin = $this->_isSiteAdmin();
|
||||
foreach ($taxonomies['entries'] as $entry) {
|
||||
if (!empty($entry['existing_tag']['Tag'])) {
|
||||
$tag = $entry['existing_tag']['Tag'];
|
||||
if ($tag['hide_tag']) {
|
||||
continue; // do not include hidden tags
|
||||
}
|
||||
if ($tag['local_only'] && !$local_tag) {
|
||||
continue; // we skip the local tags for global entries
|
||||
}
|
||||
if (!$isSiteAdmin) {
|
||||
// Skip all tags that this user cannot use for tagging, determined by the org restriction on tags
|
||||
if ($tag['org_id'] != '0' && $tag['org_id'] != $this->Auth->user('org_id')) {
|
||||
continue;
|
||||
}
|
||||
if ($tag['user_id'] != '0' && $tag['user_id'] != $this->Auth->user('id')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$tags[$tag['id']] = $tag;
|
||||
$expanded[$tag['id']] = $entry['expanded'];
|
||||
$taxonomies = $this->Taxonomy->getTaxonomy($taxonomy_id);
|
||||
$tags = array();
|
||||
if (!empty($taxonomies['entries'])) {
|
||||
$isSiteAdmin = $this->_isSiteAdmin();
|
||||
foreach ($taxonomies['entries'] as $entry) {
|
||||
if (!empty($entry['existing_tag']['Tag'])) {
|
||||
$tag = $entry['existing_tag']['Tag'];
|
||||
if ($tag['hide_tag']) {
|
||||
continue; // do not include hidden tags
|
||||
}
|
||||
if ($tag['local_only'] && !$local_tag) {
|
||||
continue; // we skip the local tags for global entries
|
||||
}
|
||||
if (!$isSiteAdmin) {
|
||||
// Skip all tags that this user cannot use for tagging, determined by the org restriction on tags
|
||||
if ($tag['org_id'] != '0' && $tag['org_id'] != $user['org_id']) {
|
||||
continue;
|
||||
}
|
||||
if ($tag['user_id'] != '0' && $tag['user_id'] != $user['id']) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$tags[$tag['id']] = $tag;
|
||||
$expanded[$tag['id']] = $entry['expanded'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +623,7 @@ class TagsController extends AppController
|
|||
$items = array();
|
||||
foreach ($tags as $k => $tag) {
|
||||
$tagName = $tag['name'];
|
||||
$choice_id = $k;
|
||||
$choice_id = (int)$k;
|
||||
if ($taxonomy_id === 'collections') {
|
||||
$choice_id = 'collection_' . $choice_id;
|
||||
}
|
||||
|
@ -664,7 +661,7 @@ class TagsController extends AppController
|
|||
),
|
||||
));
|
||||
$this->set('local', !empty($this->params['named']['local']));
|
||||
$this->render('ajax/select_tag');
|
||||
$this->render('/Elements/generic_picker');
|
||||
}
|
||||
|
||||
public function tagStatistics($percentage = false, $keysort = false)
|
||||
|
@ -1003,6 +1000,7 @@ class TagsController extends AppController
|
|||
|
||||
public function search($tag = false, $strictTagNameOnly = false, $searchIfTagExists = true)
|
||||
{
|
||||
$user = $this->_closeSession();
|
||||
if (isset($this->request->data['Tag'])) {
|
||||
$this->request->data = $this->request->data['Tag'];
|
||||
}
|
||||
|
@ -1022,7 +1020,7 @@ class TagsController extends AppController
|
|||
$tag[$k] = strtolower($t);
|
||||
$conditionsCluster['OR'][] = array('LOWER(GalaxyCluster.value)' => $tag[$k]);
|
||||
}
|
||||
foreach ($tag as $k => $t) {
|
||||
foreach ($tag as $t) {
|
||||
$conditionsCluster['OR'][] = array('AND' => array('GalaxyElement.key' => 'synonyms', 'LOWER(GalaxyElement.value) LIKE' => $t));
|
||||
}
|
||||
$elements = $this->GalaxyCluster->GalaxyElement->find('all', array(
|
||||
|
@ -1033,7 +1031,7 @@ class TagsController extends AppController
|
|||
foreach ($elements as $element) {
|
||||
$tag[] = strtolower($element['GalaxyCluster']['tag_name']);
|
||||
}
|
||||
foreach ($tag as $k => $t) {
|
||||
foreach ($tag as $t) {
|
||||
$conditions['OR'][] = array('LOWER(Tag.name) LIKE' => $t);
|
||||
}
|
||||
} else {
|
||||
|
@ -1067,7 +1065,7 @@ class TagsController extends AppController
|
|||
$tags[$k]['Taxonomy'] = $taxonomy['Taxonomy'];
|
||||
$tags[$k]['TaxonomyPredicate'] = $taxonomy['TaxonomyPredicate'][0];
|
||||
}
|
||||
$cluster = $this->GalaxyCluster->getCluster($t['Tag']['name'], $this->Auth->user());
|
||||
$cluster = $this->GalaxyCluster->getCluster($t['Tag']['name'], $user);
|
||||
if (!empty($cluster)) {
|
||||
$dataFound = true;
|
||||
$tags[$k]['GalaxyCluster'] = $cluster['GalaxyCluster'];
|
||||
|
|
|
@ -270,9 +270,9 @@ class TaxonomiesController extends AppController
|
|||
$message = __('Could not update any of the taxonomy libraries');
|
||||
} else {
|
||||
$flashType = 'success';
|
||||
$message = __('Successfully updated ') . $successes . __(' taxonomy libraries.');
|
||||
$message = __('Successfully updated %s taxonomy libraries.', $successes);
|
||||
if ($fails != 0) {
|
||||
$message .= __(' However, could not update ') . $fails . __(' taxonomy libraries.');
|
||||
$message .= __(' However, could not update %s taxonomy libraries.', $fails);
|
||||
}
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
|
@ -494,7 +494,7 @@ class TaxonomiesController extends AppController
|
|||
$this->set('required', !$taxonomy['Taxonomy']['required']);
|
||||
$this->set('id', $id);
|
||||
$this->autoRender = false;
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/toggle_required');
|
||||
}
|
||||
|
||||
|
@ -594,4 +594,14 @@ class TaxonomiesController extends AppController
|
|||
|
||||
return $taxonomyIds;
|
||||
}
|
||||
|
||||
|
||||
public function normalizeCustomTagsToTaxonomyFormat()
|
||||
{
|
||||
$this->request->allowMethod(['post', 'put']);
|
||||
$conversionResult = $this->Taxonomy->normalizeCustomTagsToTaxonomyFormat();
|
||||
$this->Flash->success(__('%s tags successfully converted. %s row updated.', $conversionResult['tag_converted'], $conversionResult['row_updated']));
|
||||
$this->redirect(array('controller' => 'taxonomies', 'action' => 'index'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class TemplateElementsController extends AppController
|
|||
$this->loadModel('Attribute');
|
||||
$this->set('validTypeGroups', $this->Attribute->validTypeGroups);
|
||||
$this->set('id', $id);
|
||||
$this->layout = 'ajaxTemplate';
|
||||
$this->layout = false;
|
||||
$this->set('elements', $templateElements);
|
||||
$mayModify = false;
|
||||
if ($this->_isSiteAdmin() || $template['Template']['org'] == $this->Auth->user('Organisation')['name']) {
|
||||
|
@ -57,7 +57,7 @@ class TemplateElementsController extends AppController
|
|||
throw new MethodNotAllowedException('This action is for ajax requests only.');
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/template_element_add_choices');
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ class TemplateElementsController extends AppController
|
|||
$this->set('categoryArray', $categoryArray);
|
||||
$this->set('categories', $categories);
|
||||
}
|
||||
$this->layout = 'ajaxTemplate';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/template_element_add_' . $type);
|
||||
} elseif ($this->request->is('post')) {
|
||||
$pos = $this->TemplateElement->lastPosition($id);
|
||||
|
@ -210,7 +210,7 @@ class TemplateElementsController extends AppController
|
|||
$this->set('categoryArray', $categoryArray);
|
||||
$this->set('categories', $categories);
|
||||
}
|
||||
$this->layout = 'ajaxTemplate';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/template_element_edit_' . $type);
|
||||
} elseif ($this->request->is('post') || $this->request->is('put')) {
|
||||
$this->request->data[$ModelType]['id'] = $templateElement[$ModelType][0]['id'];
|
||||
|
|
|
@ -139,7 +139,7 @@ class ThreadsController extends AppController
|
|||
}
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('/Elements/eventdiscussion');
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class ThreadsController extends AppController
|
|||
{
|
||||
$this->loadModel('Posts');
|
||||
$this->loadModel('SharingGroup');
|
||||
$sgids = $this->SharingGroup->fetchAllAuthorised($this->Auth->user());
|
||||
$sgids = $this->SharingGroup->authorizedIds($this->Auth->user());
|
||||
$conditions = null;
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions['AND']['OR'] = array(
|
||||
|
|
|
@ -118,6 +118,24 @@ class UsersController extends AppController
|
|||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Something went wrong, please try again later.')), 'status'=>200, 'type' => 'json'));
|
||||
}
|
||||
|
||||
public function unsubscribe($code)
|
||||
{
|
||||
$user = $this->Auth->user();
|
||||
|
||||
if (!hash_equals($this->User->unsubscribeCode($user), rtrim($code, '.'))) {
|
||||
$this->Flash->error(__('Invalid unsubscribe code.'));
|
||||
$this->redirect(['action' => 'view', 'me']);
|
||||
}
|
||||
|
||||
if ($user['autoalert']) {
|
||||
$this->User->updateField($this->Auth->user(), 'autoalert', false);
|
||||
$this->Flash->success(__('Successfully unsubscribed from event alert.'));
|
||||
} else {
|
||||
$this->Flash->info(__('Already unsubscribed from event alert.'));
|
||||
}
|
||||
$this->redirect(['action' => 'view', 'me']);
|
||||
}
|
||||
|
||||
public function edit()
|
||||
{
|
||||
$currentUser = $this->User->find('first', array(
|
||||
|
@ -427,6 +445,7 @@ class UsersController extends AppController
|
|||
'expiration',
|
||||
'current_login',
|
||||
'last_login',
|
||||
'last_api_access',
|
||||
'force_logout',
|
||||
'date_created',
|
||||
'date_modified'
|
||||
|
@ -541,7 +560,7 @@ class UsersController extends AppController
|
|||
$rules = $this->_arrayToValuesIndexArray($rules);
|
||||
$this->set('rules', $rules);
|
||||
$this->set('baseurl', Configure::read('MISP.baseurl'));
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
}
|
||||
|
||||
public function admin_view($id = null)
|
||||
|
@ -631,21 +650,19 @@ class UsersController extends AppController
|
|||
if (isset($this->request->data['User']['password'])) {
|
||||
$this->request->data['User']['confirm_password'] = $this->request->data['User']['password'];
|
||||
}
|
||||
$default_publish_alert = Configure::check('MISP.default_publish_alert') ? Configure::read('MISP.default_publish_alert') : 0;
|
||||
$defaults = array(
|
||||
'external_auth_required' => 0,
|
||||
'external_auth_key' => '',
|
||||
'server_id' => 0,
|
||||
'gpgkey' => '',
|
||||
'certif_public' => '',
|
||||
'autoalert' => $default_publish_alert,
|
||||
'contactalert' => 0,
|
||||
'disabled' => 0,
|
||||
'newsread' => 0,
|
||||
'change_pw' => 1,
|
||||
'authkey' => (new RandomTool())->random_str(true, 40),
|
||||
'termsaccepted' => 0,
|
||||
'org_id' => $this->Auth->user('org_id')
|
||||
'external_auth_required' => 0,
|
||||
'external_auth_key' => '',
|
||||
'server_id' => 0,
|
||||
'gpgkey' => '',
|
||||
'certif_public' => '',
|
||||
'autoalert' => $this->User->defaultPublishAlert(),
|
||||
'contactalert' => 0,
|
||||
'disabled' => 0,
|
||||
'newsread' => 0,
|
||||
'change_pw' => 1,
|
||||
'termsaccepted' => 0,
|
||||
'org_id' => $this->Auth->user('org_id'),
|
||||
);
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (!isset($this->request->data['User'][$key])) {
|
||||
|
@ -654,15 +671,14 @@ class UsersController extends AppController
|
|||
}
|
||||
}
|
||||
$this->request->data['User']['date_created'] = time();
|
||||
$this->request->data['User']['date_modified'] = time();
|
||||
if (!array_key_exists($this->request->data['User']['role_id'], $syncRoles)) {
|
||||
$this->request->data['User']['server_id'] = 0;
|
||||
}
|
||||
$this->User->create();
|
||||
// set invited by
|
||||
$this->loadModel('Role');
|
||||
$this->Role->recursive = -1;
|
||||
$chosenRole = $this->Role->findById($this->request->data['User']['role_id']);
|
||||
$chosenRole = $this->User->Role->find('first', [
|
||||
'conditions' => ['id' => $this->request->data['User']['role_id']],
|
||||
]);
|
||||
if (empty($chosenRole)) {
|
||||
throw new MethodNotAllowedException('Invalid role');
|
||||
}
|
||||
|
@ -682,9 +698,6 @@ class UsersController extends AppController
|
|||
$this->request->data['User']['newsread'] = 0;
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$this->request->data['User']['org_id'] = $this->Auth->user('org_id');
|
||||
$this->loadModel('Role');
|
||||
$this->Role->recursive = -1;
|
||||
$chosenRole = $this->Role->findById($this->request->data['User']['role_id']);
|
||||
if (
|
||||
$chosenRole['Role']['perm_site_admin'] == 1 ||
|
||||
$chosenRole['Role']['perm_regexp_access'] == 1 ||
|
||||
|
@ -804,8 +817,7 @@ class UsersController extends AppController
|
|||
$this->set('isSiteAdmin', $this->_isSiteAdmin());
|
||||
$this->set('default_role_id', $default_role_id);
|
||||
$this->set('servers', $servers);
|
||||
$this->set(compact('roles'));
|
||||
$this->set(compact('syncRoles'));
|
||||
$this->set(compact('roles', 'syncRoles'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -932,9 +944,9 @@ class UsersController extends AppController
|
|||
$fields[] = 'role_id';
|
||||
}
|
||||
if (!$this->_isSiteAdmin() && isset($this->request->data['User']['role_id'])) {
|
||||
$this->loadModel('Role');
|
||||
$this->Role->recursive = -1;
|
||||
$chosenRole = $this->Role->findById($this->request->data['User']['role_id']);
|
||||
$chosenRole = $this->User->Role->find('first', [
|
||||
'conditions' => ['id' => $this->request->data['User']['role_id']],
|
||||
]);
|
||||
if (empty($chosenRole) || (($chosenRole['Role']['id'] != $allowedRole) && ($chosenRole['Role']['perm_site_admin'] == 1 || $chosenRole['Role']['perm_regexp_access'] == 1 || $chosenRole['Role']['perm_sync'] == 1))) {
|
||||
throw new Exception('You are not authorised to assign that role to a user.');
|
||||
}
|
||||
|
@ -1047,8 +1059,7 @@ class UsersController extends AppController
|
|||
$this->set('servers', $servers);
|
||||
$this->set('orgs', $orgs);
|
||||
$this->set('id', $id);
|
||||
$this->set(compact('roles'));
|
||||
$this->set(compact('syncRoles'));
|
||||
$this->set(compact('roles', 'syncRoles'));
|
||||
$this->set('canChangeLogin', $this->__canChangeLogin());
|
||||
$this->set('canChangePassword', $this->__canChangePassword());
|
||||
}
|
||||
|
@ -1058,9 +1069,6 @@ class UsersController extends AppController
|
|||
if (!$this->request->is('post') && !$this->request->is('delete')) {
|
||||
throw new MethodNotAllowedException(__('Action not allowed, post or delete request expected.'));
|
||||
}
|
||||
if (!$this->_isAdmin()) {
|
||||
throw new Exception('Administrators only.');
|
||||
}
|
||||
$this->User->id = $id;
|
||||
$conditions = array('User.id' => $id);
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
|
@ -1383,16 +1391,16 @@ class UsersController extends AppController
|
|||
|
||||
public function histogram($selected = null)
|
||||
{
|
||||
//if (!$this->request->is('ajax') && !$this->_isRest()) throw new MethodNotAllowedException('This function can only be accessed via AJAX or the API.');
|
||||
$user = $this->_closeSession();
|
||||
if ($selected == '[]') {
|
||||
$selected = null;
|
||||
}
|
||||
$selectedTypes = array();
|
||||
if ($selected) {
|
||||
$selectedTypes = json_decode($selected);
|
||||
$selectedTypes = $this->_jsonDecode($selected);
|
||||
}
|
||||
if (!$this->_isSiteAdmin() && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
|
||||
$org_ids = array($this->Auth->user('org_id'));
|
||||
$org_ids = array($user['org_id']);
|
||||
} else {
|
||||
$org_ids = $this->User->Event->find('column', array(
|
||||
'fields' => array('Event.orgc_id'),
|
||||
|
@ -1403,12 +1411,7 @@ class UsersController extends AppController
|
|||
'fields' => array('Organisation.id', 'Organisation.name'),
|
||||
'conditions' => array('Organisation.id' => $org_ids)
|
||||
));
|
||||
$orgs = array(0 => 'All organisations');
|
||||
foreach ($org_ids as $v) {
|
||||
if (!empty($orgs_temp[$v])) {
|
||||
$orgs[$v] = $orgs_temp[$v];
|
||||
}
|
||||
}
|
||||
$orgs = array(0 => 'All organisations') + $orgs_temp;
|
||||
$data = array();
|
||||
$max = 1;
|
||||
foreach ($orgs as $org_id => $org_name) {
|
||||
|
@ -1481,7 +1484,7 @@ class UsersController extends AppController
|
|||
|
||||
$this->set('typeDb', $typeDb);
|
||||
$this->set('sigTypes', $sigTypes);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
}
|
||||
|
||||
public function terms()
|
||||
|
@ -1491,17 +1494,36 @@ class UsersController extends AppController
|
|||
$this->Flash->success(__('You accepted the Terms and Conditions.'));
|
||||
$this->redirect(array('action' => 'routeafterlogin'));
|
||||
}
|
||||
|
||||
$termsFile = Configure::read('MISP.terms_file');
|
||||
if (empty($termsFile)) {
|
||||
throw new NotFoundException(__("MISP Terms and Conditions are not defined"));
|
||||
}
|
||||
|
||||
$termsDownload = (bool)Configure::read('MISP.terms_download');
|
||||
if (!$termsDownload) {
|
||||
$termsFilePath = APP . 'files' . DS . 'terms' . DS . basename($termsFile);
|
||||
try {
|
||||
$termsContent = FileAccessTool::readFromFile($termsFilePath);
|
||||
} catch (Exception $e) {
|
||||
$termsContent = false;
|
||||
}
|
||||
$this->set("termsContent", $termsContent);
|
||||
}
|
||||
|
||||
$this->set("termsDownload", $termsDownload);
|
||||
$this->set('termsaccepted', $this->Auth->user('termsaccepted'));
|
||||
}
|
||||
|
||||
public function downloadTerms()
|
||||
{
|
||||
if (!Configure::read('MISP.terms_file')) {
|
||||
$termsFile = APP ."View/Users/terms";
|
||||
} else {
|
||||
$termsFile = APP . 'files' . DS . 'terms' . DS . Configure::read('MISP.terms_file');
|
||||
$termsFile = Configure::read('MISP.terms_file');
|
||||
if (empty($termsFile)) {
|
||||
throw new NotFoundException(__("MISP Terms and Conditions are not defined"));
|
||||
}
|
||||
$this->response->file($termsFile, array('download' => true, 'name' => Configure::read('MISP.terms_file')));
|
||||
|
||||
$termsFilePath = APP . 'files' . DS . 'terms' . DS . basename($termsFile);
|
||||
$this->response->file($termsFilePath, ['download' => true, 'name' => $termsFile]);
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
|
@ -1588,9 +1610,6 @@ class UsersController extends AppController
|
|||
|
||||
public function admin_email($isPreview=false)
|
||||
{
|
||||
if (!$this->_isAdmin()) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$isPostOrPut = $this->request->is('post') || $this->request->is('put');
|
||||
$conditions = array();
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
|
@ -1600,17 +1619,11 @@ class UsersController extends AppController
|
|||
// harvest parameters
|
||||
if ($isPostOrPut) {
|
||||
$recipient = $this->request->data['User']['recipient'];
|
||||
} else {
|
||||
$recipient = isset($this->params['named']['recipient']) ? $this->params['named']['recipient'] : null;
|
||||
}
|
||||
if ($isPostOrPut) {
|
||||
$recipientEmailList = $this->request->data['User']['recipientEmailList'];
|
||||
} else {
|
||||
$recipientEmailList = isset($this->params['named']['recipientEmailList']) ? $this->params['named']['recipientEmailList'] : null;
|
||||
}
|
||||
if ($isPostOrPut) {
|
||||
$orgNameList = $this->request->data['User']['orgNameList'];
|
||||
} else {
|
||||
$recipient = isset($this->params['named']['recipient']) ? $this->params['named']['recipient'] : null;
|
||||
$recipientEmailList = isset($this->params['named']['recipientEmailList']) ? $this->params['named']['recipientEmailList'] : null;
|
||||
$orgNameList = isset($this->params['named']['orgNameList']) ? $this->params['named']['orgNameList'] : null;
|
||||
}
|
||||
|
||||
|
@ -1637,7 +1650,7 @@ class UsersController extends AppController
|
|||
$users = $this->User->find('all', array('recursive' => -1, 'order' => array('email ASC'), 'conditions' => $conditions));
|
||||
// User has filled in his contact form, send out the email.
|
||||
if ($isPostOrPut) {
|
||||
$this->request->data['User']['message'] = $this->User->adminMessageResolve($this->request->data['User']['message']);
|
||||
$this->request->data['User']['message'] = $this->__replaceEmailVariables($this->request->data['User']['message']);
|
||||
$failures = '';
|
||||
foreach ($users as $user) {
|
||||
$password = $this->User->generateRandomPassword();
|
||||
|
@ -1684,11 +1697,11 @@ class UsersController extends AppController
|
|||
$textsToFetch = array('newUserText', 'passwordResetText');
|
||||
$this->loadModel('Server');
|
||||
foreach ($textsToFetch as $text) {
|
||||
${$text} = Configure::read('MISP.' . $text);
|
||||
if (!${$text}) {
|
||||
${$text} = $this->Server->serverSettings['MISP'][$text]['value'];
|
||||
$value = Configure::read('MISP.' . $text);
|
||||
if (!$value) {
|
||||
$value = $this->Server->serverSettings['MISP'][$text]['value'];
|
||||
}
|
||||
$this->set($text, ${$text});
|
||||
$this->set($text, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1723,7 +1736,7 @@ class UsersController extends AppController
|
|||
$error = 'No encryption key found for the user and the instance posture blocks non encrypted e-mails from being sent.';
|
||||
}
|
||||
$this->set('error', $error);
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->set('user', $user);
|
||||
$this->set('firstTime', $firstTime);
|
||||
$this->render('ajax/passwordResetConfirmationForm');
|
||||
|
@ -1780,9 +1793,7 @@ class UsersController extends AppController
|
|||
|
||||
// Email construction
|
||||
$body = Configure::read('Security.email_otp_text') ?: $this->Server->serverSettings['Security']['email_otp_text']['value'];
|
||||
$body = str_replace('$misp', Configure::read('MISP.baseurl'), $body);
|
||||
$body = str_replace('$org', Configure::read('MISP.org'), $body);
|
||||
$body = str_replace('$contact', Configure::read('MISP.contact'), $body);
|
||||
$body = $this->__replaceEmailVariables($body);
|
||||
$body = str_replace('$validity', $validity, $body);
|
||||
$body = str_replace('$otp', $otp, $body);
|
||||
$body = str_replace('$ip', $this->__getClientIP(), $body);
|
||||
|
@ -2051,7 +2062,6 @@ class UsersController extends AppController
|
|||
private function __statisticsUsers($params = array())
|
||||
{
|
||||
$this->loadModel('Organisation');
|
||||
$this->loadModel('User');
|
||||
$this_month = strtotime(date('Y/m') . '/01');
|
||||
$this_year = strtotime(date('Y') . '/01/01');
|
||||
$ranges = array(
|
||||
|
@ -2103,12 +2113,13 @@ class UsersController extends AppController
|
|||
|
||||
public function tagStatisticsGraph()
|
||||
{
|
||||
$this->_closeSession();
|
||||
$this->loadModel('EventTag');
|
||||
$tags = $this->EventTag->getSortedTagList();
|
||||
$this->loadModel('Taxonomy');
|
||||
$taxonomies = $this->Taxonomy->find('list', array(
|
||||
'conditions' => array('enabled' => true),
|
||||
'fields' => array('Taxonomy.namespace')
|
||||
'conditions' => array('enabled' => true),
|
||||
'fields' => array('Taxonomy.namespace')
|
||||
));
|
||||
$flatData = array();
|
||||
$tagIds = $this->EventTag->Tag->find('list', array('fields' => array('Tag.name', 'Tag.id')));
|
||||
|
@ -2138,7 +2149,6 @@ class UsersController extends AppController
|
|||
}
|
||||
$treemap['children'][] = $newElement;
|
||||
}
|
||||
$taxonomyColourCodes = array();
|
||||
$taxonomies = array_merge(array('custom'), $taxonomies);
|
||||
if ($this->_isRest()) {
|
||||
$data = array(
|
||||
|
@ -2147,12 +2157,11 @@ class UsersController extends AppController
|
|||
);
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
} else {
|
||||
$this->set('taxonomyColourCodes', $taxonomyColourCodes);
|
||||
$this->set('taxonomies', $taxonomies);
|
||||
$this->set('flatData', $flatData);
|
||||
$this->set('treemap', $treemap);
|
||||
$this->set('tags', $tags);
|
||||
$this->layout = 'treemap';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/tag_statistics_graph');
|
||||
}
|
||||
}
|
||||
|
@ -2337,6 +2346,7 @@ class UsersController extends AppController
|
|||
|
||||
public function searchGpgKey($email = false)
|
||||
{
|
||||
session_abort();
|
||||
if (!$email) {
|
||||
throw new NotFoundException('No email provided.');
|
||||
}
|
||||
|
@ -2345,7 +2355,6 @@ class UsersController extends AppController
|
|||
throw new NotFoundException('No keys found for given email at keyserver.');
|
||||
}
|
||||
$this->set('keys', $keys);
|
||||
$this->autorender = false;
|
||||
$this->layout = false;
|
||||
$this->render('ajax/fetchpgpkey');
|
||||
}
|
||||
|
@ -2764,4 +2773,17 @@ class UsersController extends AppController
|
|||
}
|
||||
return !Configure::read('MISP.disable_user_login_change');
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces $misp, $org and $contact variables in emails
|
||||
* @param string $body
|
||||
* @return string
|
||||
*/
|
||||
private function __replaceEmailVariables($body)
|
||||
{
|
||||
$body = str_replace('$misp', Configure::read('MISP.baseurl'), $body);
|
||||
$body = str_replace('$org', Configure::read('MISP.org'), $body);
|
||||
$body = str_replace('$contact', Configure::read('MISP.contact'), $body);
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -321,7 +321,7 @@ class WarninglistsController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action is available via AJAX only.'));
|
||||
}
|
||||
$this->layout = 'ajax';
|
||||
$this->layout = false;
|
||||
$this->render('ajax/getToggleField');
|
||||
}
|
||||
|
||||
|
@ -360,9 +360,7 @@ class WarninglistsController extends AppController
|
|||
|
||||
public function import()
|
||||
{
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException(__('This function only accepts POST requests.'));
|
||||
}
|
||||
$this->request->allowMethod(['post']);
|
||||
|
||||
if (empty($this->request->data)) {
|
||||
throw new BadRequestException(__('No valid data received.'));
|
||||
|
@ -378,11 +376,11 @@ class WarninglistsController extends AppController
|
|||
throw new BadRequestException(__('No valid data received: `list` field is not array'));
|
||||
}
|
||||
|
||||
$id = $this->Warninglist->import($this->request->data);
|
||||
if (is_int($id)) {
|
||||
try {
|
||||
$id = $this->Warninglist->import($this->request->data);
|
||||
return $this->RestResponse->saveSuccessResponse('Warninglist', 'import', $id, false, __('Warninglist imported'));
|
||||
} else {
|
||||
return $this->RestResponse->saveFailResponse('Warninglist', 'import', false, $id);
|
||||
} catch (Exception $e) {
|
||||
return $this->RestResponse->saveFailResponse('Warninglist', 'import', false, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
class WorkflowBlueprintsController extends AppController
|
||||
{
|
||||
public $components = array(
|
||||
'RequestHandler'
|
||||
);
|
||||
|
||||
public function update($force = false)
|
||||
{
|
||||
$this->request->allowMethod(['post', 'put']);
|
||||
$this->WorkflowBlueprint->update($force);
|
||||
$message = __('Default workflow blueprints updated');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('WorkflowBlueprint', 'update', false, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
$this->redirect(array('controller' => 'workflowBlueprints', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$params = [
|
||||
'filters' => ['name', 'uuid', 'timestamp'],
|
||||
'quickFilters' => ['name', 'uuid'],
|
||||
];
|
||||
$this->CRUD->index($params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('menuData', ['menuList' => 'workflowBlueprints', 'menuItem' => 'index']);
|
||||
}
|
||||
|
||||
public function add($fromEditor = false)
|
||||
{
|
||||
$params = [
|
||||
'beforeSave' => function(array $blueprint) {
|
||||
$blueprint['WorkflowBlueprint']['default'] = false;
|
||||
return $blueprint;
|
||||
},
|
||||
];
|
||||
$this->CRUD->add($params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('fromEditor', !empty($fromEditor));
|
||||
$this->set('menuData', ['menuList' => 'workflowBlueprints', 'menuItem' => 'add']);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$params = [
|
||||
'beforeSave' => function (array $blueprint) {
|
||||
$blueprint['WorkflowBlueprint']['default'] = false;
|
||||
return $blueprint;
|
||||
},
|
||||
];
|
||||
$this->CRUD->edit($id, $params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->request->data['WorkflowBlueprint']['data'] = JsonTool::encode($this->data['WorkflowBlueprint']['data']);
|
||||
$this->set('menuData', ['menuList' => 'workflowBlueprints', 'menuItem' => 'edit']);
|
||||
$this->set('id', $id);
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$params = [
|
||||
];
|
||||
$this->CRUD->delete($id, $params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('menuData', ['menuList' => 'workflowBlueprints', 'menuItem' => 'delete']);
|
||||
}
|
||||
|
||||
public function view($id)
|
||||
{
|
||||
$filters = $this->IndexFilter->harvestParameters(['format']);
|
||||
if (!empty($filters['format'])) {
|
||||
if ($filters['format'] == 'dot') {
|
||||
$dot = $this->WorkflowBlueprint->getDotNotation($id);
|
||||
return $this->RestResponse->viewData($dot, $this->response->type());
|
||||
} else if ($filters['format'] == 'mermaid') {
|
||||
$mermaid = $this->WorkflowBlueprint->getMermaid($id);
|
||||
return $this->RestResponse->viewData($mermaid, $this->response->type());
|
||||
}
|
||||
}
|
||||
$this->CRUD->view($id, [
|
||||
]);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->set('menuData', ['menuList' => 'workflowBlueprints', 'menuItem' => 'view']);
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$workflowBlueprintData = JsonTool::decode($this->request->data['WorkflowBlueprint']['data']);
|
||||
if ($workflowBlueprintData === null) {
|
||||
throw new MethodNotAllowedException(__('Error while decoding JSON'));
|
||||
}
|
||||
$this->request->data['WorkflowBlueprint']['data'] = JsonTool::encode($workflowBlueprintData);
|
||||
$this->add();
|
||||
}
|
||||
}
|
||||
|
||||
public function export($id)
|
||||
{
|
||||
$workflowBlueprint = $this->WorkflowBlueprint->find('first', [
|
||||
'conditions' => [
|
||||
'id' => $id,
|
||||
]
|
||||
]);
|
||||
$content = JsonTool::encode($workflowBlueprint, JSON_PRETTY_PRINT);
|
||||
$this->response->body($content);
|
||||
$this->response->type('json');
|
||||
$this->response->download(sprintf('blueprint_%s_%s.json', str_replace(' ', '-', strtolower($workflowBlueprint['WorkflowBlueprint']['name'])), time()));
|
||||
return $this->response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,428 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
class WorkflowsController extends AppController
|
||||
{
|
||||
public $components = array(
|
||||
'RequestHandler'
|
||||
);
|
||||
|
||||
private $toggleableFields = ['enabled'];
|
||||
|
||||
public function beforeFilter()
|
||||
{
|
||||
parent::beforeFilter();
|
||||
$this->Security->unlockedActions[] = 'checkGraph';
|
||||
$requirementErrors = [];
|
||||
if (empty(Configure::read('MISP.background_jobs'))) {
|
||||
$requirementErrors[] = __('Background workers must be enabled to use workflows');
|
||||
$this->render('error');
|
||||
}
|
||||
if (empty(Configure::read('Plugin.Workflow_enable'))) {
|
||||
$requirementErrors[] = __('The workflow plugin must be enabled to use workflows. Go to `/servers/serverSettings/Plugin` the enable the `Plugin.Workflow` setting');
|
||||
$this->render('error');
|
||||
}
|
||||
try {
|
||||
$this->Workflow->setupRedisWithException();
|
||||
} catch (Exception $e) {
|
||||
$requirementErrors[] = $e->getMessage();
|
||||
}
|
||||
if (!empty($requirementErrors)) {
|
||||
$this->set('requirementErrors', $requirementErrors);
|
||||
$this->render('error');
|
||||
}
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$params = [
|
||||
'filters' => ['name', 'uuid'],
|
||||
'quickFilters' => ['name', 'uuid'],
|
||||
];
|
||||
$this->CRUD->index($params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('menuData', array('menuList' => 'workflows', 'menuItem' => 'index'));
|
||||
}
|
||||
|
||||
public function rebuildRedis()
|
||||
{
|
||||
$this->Workflow->rebuildRedis();
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$this->set('id', $id);
|
||||
$savedWorkflow = $this->Workflow->fetchWorkflow($id);
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$newWorkflow = $this->request->data;
|
||||
$newWorkflow['Workflow']['data'] = JsonTool::decode($newWorkflow['Workflow']['data']);
|
||||
$newWorkflow = $this->__applyDataFromSavedWorkflow($newWorkflow, $savedWorkflow);
|
||||
$result = $this->Workflow->editWorkflow($newWorkflow);
|
||||
$redirectTarget = ['action' => 'view', $id];
|
||||
if (!empty($result['errors'])) {
|
||||
return $this->__getFailResponseBasedOnContext($result['errors'], null, 'edit', $this->Workflow->id, $redirectTarget);
|
||||
} else {
|
||||
$successMessage = __('Workflow saved.');
|
||||
$savedWorkflow = $result['saved'];
|
||||
return $this->__getSuccessResponseBasedOnContext($successMessage, $savedWorkflow, 'edit', false, $redirectTarget);
|
||||
}
|
||||
} else {
|
||||
$savedWorkflow['Workflow']['data'] = JsonTool::encode($savedWorkflow['Workflow']['data']);
|
||||
$this->request->data = $savedWorkflow;
|
||||
}
|
||||
|
||||
$this->set('menuData', array('menuList' => 'workflows', 'menuItem' => 'edit'));
|
||||
$this->render('add');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$params = [
|
||||
];
|
||||
$this->CRUD->delete($id, $params);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
}
|
||||
|
||||
public function view($id)
|
||||
{
|
||||
$filters = $this->IndexFilter->harvestParameters(['format']);
|
||||
if (!empty($filters['format'])) {
|
||||
if ($filters['format'] == 'dot') {
|
||||
$dot = $this->Workflow->getDotNotation($id);
|
||||
return $this->RestResponse->viewData($dot, $this->response->type());
|
||||
} else if ($filters['format'] == 'mermaid') {
|
||||
$mermaid = $this->Workflow->getMermaid($id);
|
||||
return $this->RestResponse->viewData($mermaid, $this->response->type());
|
||||
}
|
||||
}
|
||||
$this->CRUD->view($id, [
|
||||
]);
|
||||
if ($this->IndexFilter->isRest()) {
|
||||
return $this->restResponsePayload;
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->set('menuData', array('menuList' => 'workflows', 'menuItem' => 'view'));
|
||||
}
|
||||
|
||||
public function editor($id)
|
||||
{
|
||||
$trigger_id = false;
|
||||
$workflow = false;
|
||||
if (is_numeric($id)) {
|
||||
$workflow_id = $id;
|
||||
} else {
|
||||
$trigger_id = $id;
|
||||
}
|
||||
$modules = $this->Workflow->getModulesByType();
|
||||
if (!empty($trigger_id)) {
|
||||
$trigger_ids = Hash::extract($modules['modules_trigger'], '{n}.id');
|
||||
if (!in_array($trigger_id, $trigger_ids)) {
|
||||
return $this->__getFailResponseBasedOnContext(
|
||||
[__('Unkown trigger %s', $trigger_id)],
|
||||
null,
|
||||
'add',
|
||||
$trigger_id,
|
||||
['controller' => 'workflows', 'action' => 'triggers']
|
||||
);
|
||||
}
|
||||
$workflow = $this->Workflow->fetchWorkflowByTrigger($trigger_id, false);
|
||||
if (empty($workflow)) { // Workflow do not exists yet. Create it.
|
||||
$result = $this->Workflow->addWorkflow([
|
||||
'name' => sprintf('Workflow for trigger %s', $trigger_id),
|
||||
'data' => $this->Workflow->genGraphDataForTrigger($trigger_id),
|
||||
'trigger_id' => $trigger_id,
|
||||
]);
|
||||
if (!empty($result['errors'])) {
|
||||
return $this->__getFailResponseBasedOnContext(
|
||||
[__('Could not create workflow for trigger %s', $trigger_id), $result['errors']],
|
||||
null,
|
||||
'add',
|
||||
$trigger_id,
|
||||
['controller' => 'workflows', 'action' => 'editor']
|
||||
);
|
||||
}
|
||||
$workflow = $this->Workflow->fetchWorkflowByTrigger($trigger_id, false);
|
||||
}
|
||||
} else {
|
||||
$workflow = $this->Workflow->fetchWorkflow($workflow_id);
|
||||
}
|
||||
$modules = $this->Workflow->attachNotificationToModules($modules, $workflow);
|
||||
$this->loadModel('WorkflowBlueprint');
|
||||
$workflowBlueprints = $this->WorkflowBlueprint->find('all');
|
||||
$workflowBlueprints = array_map(function($blueprint) {
|
||||
return $this->WorkflowBlueprint->attachModuleDataToBlueprint($blueprint);
|
||||
}, $workflowBlueprints);
|
||||
$this->set('selectedWorkflow', $workflow);
|
||||
$this->set('workflowTriggerId', $trigger_id);
|
||||
$this->set('modules', $modules);
|
||||
$this->set('workflowBlueprints', $workflowBlueprints);
|
||||
}
|
||||
|
||||
public function executeWorkflow($workflow_id)
|
||||
{
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$blockingErrors = [];
|
||||
$data = JsonTool::decode($this->request->data['Workflow']['data']);
|
||||
$result = $this->Workflow->executeWorkflow($workflow_id, $data, $blockingErrors);
|
||||
if (!empty($logging) && empty($result['success'])) {
|
||||
$logging['message'] = !empty($logging['message']) ? $logging['message'] : __('Error while executing workflow.');
|
||||
$errorMessage = implode(', ', $blockingErrors);
|
||||
$this->Workflow->loadLog()->createLogEntry('SYSTEM', $logging['action'], $logging['model'], $logging['id'], $logging['message'], __('Returned message: %s', $errorMessage));
|
||||
}
|
||||
return $this->RestResponse->viewData([
|
||||
'success' => $result['success'],
|
||||
'outcome' => $result['outcomeText'],
|
||||
], $this->response->type());
|
||||
}
|
||||
$this->render('ajax/executeWorkflow');
|
||||
}
|
||||
|
||||
public function triggers()
|
||||
{
|
||||
$triggers = $this->Workflow->getModulesByType('trigger');
|
||||
$triggers = $this->Workflow->attachWorkflowToTriggers($triggers);
|
||||
$data = $triggers;
|
||||
App::uses('CustomPaginationTool', 'Tools');
|
||||
$customPagination = new CustomPaginationTool();
|
||||
$customPagination->truncateAndPaginate($data, $this->params, 'Workflow', true);
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
}
|
||||
|
||||
$this->set('data', $data);
|
||||
$this->set('menuData', ['menuList' => 'workflows', 'menuItem' => 'index_trigger']);
|
||||
}
|
||||
|
||||
public function moduleIndex()
|
||||
{
|
||||
$modules = $this->Workflow->getModulesByType();
|
||||
$errorWhileLoading = $this->Workflow->getModuleLoadingError();
|
||||
$this->Module = ClassRegistry::init('Module');
|
||||
$mispModules = $this->Module->getModules('Action');
|
||||
$this->set('module_service_error', !is_array($mispModules));
|
||||
$filters = $this->IndexFilter->harvestParameters(['type', 'actiontype', 'enabled']);
|
||||
$moduleType = $filters['type'] ?? 'action';
|
||||
$actionType = $filters['actiontype'] ?? 'all';
|
||||
$enabledState = $filters['enabled'] ?? false;
|
||||
if ($moduleType == 'all' || $moduleType == 'custom') {
|
||||
$data = array_merge(
|
||||
$modules["modules_action"],
|
||||
$modules["modules_logic"]
|
||||
);
|
||||
} else {
|
||||
$data = $modules["modules_{$moduleType}"];
|
||||
}
|
||||
if ($actionType == 'mispmodule') {
|
||||
$data = array_filter($data, function($module) {
|
||||
return !empty($module['is_misp_module']);
|
||||
});
|
||||
} else if ($actionType == 'blocking') {
|
||||
$data = array_filter($data, function ($module) {
|
||||
return !empty($module['blocking']);
|
||||
});
|
||||
} else if ($moduleType == 'custom') {
|
||||
$data = array_filter($data, function ($module) {
|
||||
return !empty($module['is_custom']);
|
||||
});
|
||||
}
|
||||
if ($enabledState !== false) {
|
||||
$moduleType = !empty($enabledState) ? 'enabled' : 'disabled';
|
||||
$data = array_filter($data, function ($module) use ($enabledState) {
|
||||
return !empty($enabledState) ? empty($module['disabled']) : !empty($module['disabled']);
|
||||
});
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
}
|
||||
App::uses('CustomPaginationTool', 'Tools');
|
||||
$customPagination = new CustomPaginationTool();
|
||||
$params = $customPagination->createPaginationRules($data, $this->passedArgs, 'Workflow');
|
||||
$params = $customPagination->applyRulesOnArray($data, $params, 'Workflow');
|
||||
$params['options'] = array_merge($params['options'], $filters);
|
||||
$this->params['paging'] = [$this->modelClass => $params];
|
||||
$this->set('data', $data);
|
||||
$this->set('indexType', $moduleType);
|
||||
$this->set('actionType', $actionType);
|
||||
$this->set('errorWhileLoading', $errorWhileLoading);
|
||||
$this->set('menuData', ['menuList' => 'workflows', 'menuItem' => 'index_module']);
|
||||
}
|
||||
|
||||
public function moduleView($module_id)
|
||||
{
|
||||
$module = $this->Workflow->getModuleByID($module_id);
|
||||
if (empty($module)) {
|
||||
throw new NotFoundException(__('Invalid trigger ID'));
|
||||
}
|
||||
$is_trigger = $module['module_type'] == 'trigger';
|
||||
if ($is_trigger) {
|
||||
$module = $this->Workflow->attachWorkflowToTriggers([$module])[0];
|
||||
$module['listening_workflows'] = $this->Workflow->getListeningWorkflowForTrigger($module);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($module, $this->response->type());
|
||||
}
|
||||
$this->set('data', $module);
|
||||
$this->set('menuData', ['menuList' => 'workflows', 'menuItem' => 'view_module']);
|
||||
}
|
||||
|
||||
public function toggleModule($module_id, $enabled, $is_trigger=false)
|
||||
{
|
||||
$this->request->allowMethod(['post', 'put']);
|
||||
$saved = $this->Workflow->toggleModule($module_id, $enabled, $is_trigger);
|
||||
if ($saved) {
|
||||
return $this->__getSuccessResponseBasedOnContext(
|
||||
__('%s module %s', ($enabled ? 'Enabled' : 'Disabled'), $module_id),
|
||||
null,
|
||||
'toggle_module',
|
||||
$module_id,
|
||||
['action' => (!empty($is_trigger) ? 'triggers' : 'moduleIndex')]
|
||||
);
|
||||
} else {
|
||||
return $this->__getFailResponseBasedOnContext(
|
||||
__('Could not %s module %s', ($enabled ? 'Enabled' : 'Disabled'), $module_id),
|
||||
null,
|
||||
'toggle_module',
|
||||
$module_id,
|
||||
['action' => (!empty($is_trigger) ? 'triggers' : 'moduleIndex')]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function debugToggleField($workflow_id, $enabled)
|
||||
{
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action is available via AJAX only.'));
|
||||
}
|
||||
$this->layout = false;
|
||||
$this->render('ajax/getDebugToggleField');
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$success = $this->Workflow->toggleDebug($workflow_id, $enabled);
|
||||
if (!empty($success)) {
|
||||
return $this->__getSuccessResponseBasedOnContext(
|
||||
__('%s debug mode', ($enabled ? __('Enabled') : __('Disabled'))),
|
||||
null,
|
||||
'toggle_debug',
|
||||
$workflow_id,
|
||||
['action' => 'triggers']
|
||||
);
|
||||
} else {
|
||||
return $this->__getFailResponseBasedOnContext(
|
||||
__('Could not %s debug mode', ($enabled ? __('enable') : __('disable'))),
|
||||
null,
|
||||
'toggle_debug',
|
||||
$workflow_id,
|
||||
['action' => 'triggers']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function massToggleField($fieldName, $enabled, $is_trigger=false)
|
||||
{
|
||||
if (!in_array($fieldName, $this->toggleableFields)) {
|
||||
throw new MethodNotAllowedException(__('The field `%s` cannot be toggled', $fieldName));
|
||||
}
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$module_ids = JsonTool::decode($this->request->data['Workflow']['module_ids']);
|
||||
$enabled_count = $this->Workflow->toggleModules($module_ids, $enabled, $is_trigger);
|
||||
if (!empty($enabled_count)) {
|
||||
return $this->__getSuccessResponseBasedOnContext(
|
||||
__('%s %s modules', ($enabled ? 'Enabled' : 'Disabled'), $enabled_count),
|
||||
null,
|
||||
'toggle_module',
|
||||
$module_ids,
|
||||
['action' => (!empty($is_trigger) ? 'triggers' : 'moduleIndex')]
|
||||
);
|
||||
} else {
|
||||
return $this->__getFailResponseBasedOnContext(
|
||||
__('Could not %s modules', ($enabled ? 'enable' : 'disable')),
|
||||
null,
|
||||
'toggle_module',
|
||||
$module_ids,
|
||||
['action' => (!empty($is_trigger) ? 'triggers' : 'moduleIndex')]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function __getSuccessResponseBasedOnContext($message, $data = null, $action = '', $id = false, $redirect = array())
|
||||
{
|
||||
if ($this->_isRest()) {
|
||||
if (!is_null($data)) {
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
} else {
|
||||
return $this->RestResponse->saveSuccessResponse('Workflow', $action, $id, false, $message);
|
||||
}
|
||||
} elseif ($this->request->is('ajax')) {
|
||||
return $this->RestResponse->saveSuccessResponse('Workflow', $action, $id, false, $message, $data);
|
||||
} else {
|
||||
$this->Flash->success($message);
|
||||
$this->redirect($redirect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private function __getFailResponseBasedOnContext($message, $data = null, $action = '', $id = false, $redirect = array())
|
||||
{
|
||||
if (is_array($message)) {
|
||||
$message = implode(', ', $message);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
if ($data !== null) {
|
||||
return $this->RestResponse->viewData($data, $this->response->type());
|
||||
} else {
|
||||
return $this->RestResponse->saveFailResponse('Workflow', $action, $id, $message);
|
||||
}
|
||||
} elseif ($this->request->is('ajax')) {
|
||||
return $this->RestResponse->saveFailResponse('Workflow', $action, $id, $message, false, $data);
|
||||
} else {
|
||||
$this->Flash->error($message);
|
||||
$this->redirect($redirect);
|
||||
}
|
||||
}
|
||||
|
||||
private function __applyDataFromSavedWorkflow($newWorkflow, $savedWorkflow)
|
||||
{
|
||||
if (!isset($newWorkflow['Workflow'])) {
|
||||
$newWorkflow = ['Workflow' => $newWorkflow];
|
||||
}
|
||||
$ignoreFieldList = ['id', 'uuid'];
|
||||
foreach (Workflow::CAPTURE_FIELDS_EDIT as $field) {
|
||||
if (!in_array($field, $ignoreFieldList) && isset($newWorkflow['Workflow'][$field])) {
|
||||
$savedWorkflow['Workflow'][$field] = $newWorkflow['Workflow'][$field];
|
||||
}
|
||||
}
|
||||
return $savedWorkflow;
|
||||
}
|
||||
|
||||
public function checkGraph()
|
||||
{
|
||||
$this->request->allowMethod(['post']);
|
||||
$graphData = JsonTool::decode($this->request->data['graph']);
|
||||
$cycles = [];
|
||||
$isAcyclic = $this->Workflow->workflowGraphTool->isAcyclic($graphData, $cycles);
|
||||
$edgesMultipleOutput = [];
|
||||
$hasMultipleOutputConnection = $this->Workflow->workflowGraphTool->hasMultipleOutputConnection($graphData, $edgesMultipleOutput);
|
||||
$edgesWarnings = [];
|
||||
$hasPathWarnings = $this->Workflow->hasPathWarnings($graphData, $edgesWarnings);
|
||||
$data = [
|
||||
'is_acyclic' => [
|
||||
'is_acyclic' => $isAcyclic,
|
||||
'cycles' => $cycles,
|
||||
],
|
||||
'multiple_output_connection' => [
|
||||
'has_multiple_output_connection' => $hasMultipleOutputConnection,
|
||||
'edges' => $edgesMultipleOutput,
|
||||
],
|
||||
'path_warnings' => [
|
||||
'has_path_warnings' => $hasPathWarnings,
|
||||
'edges' => $edgesWarnings,
|
||||
],
|
||||
];
|
||||
return $this->RestResponse->viewData($data, 'json');
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ class RecentSightingsWidget
|
|||
else $type = "Expiration";
|
||||
|
||||
$output = $attribute->{'value'} . " (id: " . $attribute->{'id'} . ") in " . $event->{'info'} . " (id: " . $event->{'id'} . ")";
|
||||
$data[] = array( 'title' => __($type), 'value' => $output,
|
||||
$data[] = array( 'title' => $type, 'value' => $output,
|
||||
'html' => sprintf(
|
||||
' (Event <a href="%s%s">%s</a>)',
|
||||
Configure::read('MISP.baseurl') . '/events/view/', $event->{'id'},
|
||||
|
|
|
@ -7,7 +7,8 @@ class DefaultWarning
|
|||
public $functions = [
|
||||
'emptyEventCheck',
|
||||
'contextCheck',
|
||||
'tlpDistributionCheck'
|
||||
'tlpDistributionCheck',
|
||||
'taxonomyInconsistenciesCheck'
|
||||
];
|
||||
|
||||
function __construct()
|
||||
|
@ -47,6 +48,13 @@ class DefaultWarning
|
|||
}
|
||||
}
|
||||
|
||||
public function taxonomyInconsistenciesCheck(array $event, array &$warnings)
|
||||
{
|
||||
if (Configure::read('MISP.disable_taxonomy_consistency_checks')) {
|
||||
$warnings[__('Tags')][] = __('Taxonomy consistency checks are disabled in the configuration, set `MISP.disable_taxonomy_consistency_checks` to `false` to enable them.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tagName
|
||||
* @return void
|
||||
|
@ -55,7 +63,7 @@ class DefaultWarning
|
|||
{
|
||||
$lowerTagName = trim(strtolower($tagName));
|
||||
if (substr($lowerTagName, 0, 4) === 'tlp:') {
|
||||
if (!in_array($lowerTagName, ['tlp:white', 'tlp:green', 'tlp:amber', 'tlp:red', 'tlp:ex:chr'], true)) {
|
||||
if (!in_array($lowerTagName, ['tlp:white', 'tlp:green', 'tlp:amber', 'tlp:red', 'tlp:ex:chr', 'tlp:clear', 'tlp:amber+strict'], true)) {
|
||||
$warnings['TLP'][] = __('Unknown TLP tag, please refer to the TLP taxonomy as to what is valid, otherwise filtering rules created by your partners may miss your intent.');
|
||||
} else if ($lowerTagName !== $tagName) {
|
||||
$warnings['TLP'][] = __('TLP tag with invalid formatting: Make sure that you only use TLP tags from the taxonomy. Custom tags with invalid capitalisation, white spaces or other artifacts will break synchronisation and filtering rules intended for the correct taxonomy derived tags.');
|
||||
|
|
|
@ -6,16 +6,16 @@ class HashesExport
|
|||
'flatten' => 1
|
||||
);
|
||||
|
||||
public $validTypes = array(
|
||||
const VALID_TYPES = array(
|
||||
'simple' => array(
|
||||
'md5', 'sha1', 'sha256', 'sha224', 'sha512', 'sha512/224', 'sha512/256', 'ssdeep', 'imphash', 'tlsh',
|
||||
'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'pehash', 'authentihash',
|
||||
'impfuzzy'
|
||||
'md5', 'sha1', 'sha256', 'sha224', 'sha384', 'sha512', 'sha512/224', 'sha512/256', 'sha3-224', 'sha3-256',
|
||||
'sha3-384', 'sha3-512', 'ssdeep', 'imphash', 'tlsh', 'x509-fingerprint-sha1', 'x509-fingerprint-md5',
|
||||
'x509-fingerprint-sha256', 'pehash', 'authentihash', 'impfuzzy'
|
||||
),
|
||||
'composite' => array(
|
||||
'malware-sample', 'filename|md5', 'filename|sha1', 'filename|sha256', 'filename|sha224', 'filename|sha512',
|
||||
'filename|sha512/224', 'filename|sha512/256', 'filename|ssdeep', 'filename|imphash', 'filename|tlsh',
|
||||
'x509-fingerprint-sha1', 'x509-fingerprint-md5', 'x509-fingerprint-sha256', 'filename|pehash',
|
||||
'filename|sha512/224', 'filename|sha512/256', 'filename|sha3-224', 'filename|sha3-256', 'filename|sha3-384',
|
||||
'filename|sha3-512', 'filename|ssdeep', 'filename|imphash', 'filename|tlsh', 'filename|pehash',
|
||||
'filename|authentihash', 'filename|impfuzzy'
|
||||
)
|
||||
);
|
||||
|
@ -23,18 +23,17 @@ class HashesExport
|
|||
public function handler($data, $options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
if (in_array($data['Attribute']['type'], $this->validTypes['composite'])) {
|
||||
if (in_array($data['Attribute']['type'], self::VALID_TYPES['composite'], true)) {
|
||||
return explode('|', $data['Attribute']['value'])[1];
|
||||
} else if (in_array($data['Attribute']['type'], $this->validTypes['simple'])) {
|
||||
} else if (in_array($data['Attribute']['type'], self::VALID_TYPES['simple'], true)) {
|
||||
return $data['Attribute']['value'];
|
||||
}
|
||||
}
|
||||
if ($options['scope'] === 'Event') {
|
||||
} else if ($options['scope'] === 'Event') {
|
||||
$result = array();
|
||||
foreach ($data['Attribute'] as $attribute) {
|
||||
if (in_array($attribute['type'], $this->validTypes['composite'])) {
|
||||
if (in_array($attribute['type'], self::VALID_TYPES['composite'], true)) {
|
||||
$result[] = explode('|', $attribute['value'])[1];
|
||||
} else if (in_array($attribute['type'], $this->validTypes['simple'])) {
|
||||
} else if (in_array($attribute['type'], self::VALID_TYPES['simple'], true)) {
|
||||
$result[] = $attribute['value'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class JsonExport
|
||||
{
|
||||
public $non_restrictive_export = true;
|
||||
public $non_restrictive_export = true;
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
|
@ -11,17 +11,17 @@ class JsonExport
|
|||
*/
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return $this->__attributeHandler($data, $options);
|
||||
} else if($options['scope'] === 'Event') {
|
||||
return $this->__eventHandler($data, $options);
|
||||
} else if($options['scope'] === 'Object') {
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return $this->__attributeHandler($data, $options);
|
||||
} else if ($options['scope'] === 'Event') {
|
||||
return $this->__eventHandler($data, $options);
|
||||
} else if ($options['scope'] === 'Object') {
|
||||
return $this->__objectHandler($data, $options);
|
||||
} else if($options['scope'] === 'Sighting') {
|
||||
return $this->__sightingsHandler($data, $options);
|
||||
} else if($options['scope'] === 'GalaxyCluster') {
|
||||
return $this->__galaxyClusterHandler($data, $options);
|
||||
}
|
||||
} else if ($options['scope'] === 'Sighting') {
|
||||
return $this->__sightingsHandler($data, $options);
|
||||
} else if ($options['scope'] === 'GalaxyCluster') {
|
||||
return $this->__galaxyClusterHandler($data, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,66 +29,68 @@ class JsonExport
|
|||
* @param array $options
|
||||
* @return Generator
|
||||
*/
|
||||
private function __eventHandler($event, $options = array())
|
||||
private function __eventHandler($event, $options = array())
|
||||
{
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
return JSONConverterTool::streamConvert($event);
|
||||
}
|
||||
|
||||
private function __objectHandler($object, $options = array()) {
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
return json_encode(JSONConverterTool::convertObject($object, false, true));
|
||||
return JSONConverterTool::streamConvert($event);
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
$tagTypes = array('AttributeTag', 'EventTag');
|
||||
foreach($tagTypes as $tagType) {
|
||||
if (isset($attribute[$tagType])) {
|
||||
foreach ($attribute[$tagType] as $tk => $tag) {
|
||||
if ($tagType === 'EventTag') {
|
||||
$attribute[$tagType][$tk]['Tag']['inherited'] = 1;
|
||||
}
|
||||
$attribute['Tag'][] = $attribute[$tagType][$tk]['Tag'];
|
||||
}
|
||||
unset($attribute[$tagType]);
|
||||
}
|
||||
}
|
||||
unset($attribute['value1']);
|
||||
unset($attribute['value2']);
|
||||
return json_encode($attribute);
|
||||
}
|
||||
private function __objectHandler($object, $options = array())
|
||||
{
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
return JsonTool::encode(JSONConverterTool::convertObject($object, false, true));
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
$tagTypes = array('AttributeTag', 'EventTag');
|
||||
foreach ($tagTypes as $tagType) {
|
||||
if (isset($attribute[$tagType])) {
|
||||
foreach ($attribute[$tagType] as $tag) {
|
||||
if ($tagType === 'EventTag') {
|
||||
$tag['Tag']['inherited'] = 1;
|
||||
}
|
||||
$attribute['Tag'][] = $tag['Tag'];
|
||||
}
|
||||
unset($attribute[$tagType]);
|
||||
}
|
||||
}
|
||||
unset($attribute['value1']);
|
||||
unset($attribute['value2']);
|
||||
return JsonTool::encode($attribute);
|
||||
}
|
||||
|
||||
private function __sightingsHandler($sighting, $options = array())
|
||||
{
|
||||
return json_encode($sighting);
|
||||
return JsonTool::encode($sighting);
|
||||
}
|
||||
|
||||
private function __galaxyClusterHandler($cluster, $options = array())
|
||||
{
|
||||
return json_encode($cluster);
|
||||
return JsonTool::encode($cluster);
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return '{"response": {"Attribute": [';
|
||||
} else {
|
||||
return '{"response": [';
|
||||
}
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return '{"response": {"Attribute": [';
|
||||
} else {
|
||||
return '{"response": [';
|
||||
}
|
||||
}
|
||||
|
||||
public function footer($options = array())
|
||||
{
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return ']}}' . PHP_EOL;
|
||||
} else {
|
||||
return ']}' . PHP_EOL;
|
||||
}
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
return ']}}' . PHP_EOL;
|
||||
} else {
|
||||
return ']}' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
public function separator()
|
||||
|
|
|
@ -7,84 +7,125 @@ class NidsExport
|
|||
public $classtype = 'trojan-activity';
|
||||
|
||||
public $format = ""; // suricata (default), snort
|
||||
|
||||
public $supportedObjects = array('network-connection', 'ddos');
|
||||
|
||||
public $checkWhitelist = true;
|
||||
public $checkWhitelist = true;
|
||||
|
||||
public $additional_params = array(
|
||||
'contain' => array(
|
||||
'Event' => array(
|
||||
'fields' => array('threat_level_id')
|
||||
)
|
||||
),
|
||||
'flatten' => 1
|
||||
);
|
||||
public $additional_params = array(
|
||||
'contain' => array(
|
||||
'Event' => array(
|
||||
'fields' => array('threat_level_id')
|
||||
)
|
||||
),
|
||||
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
$continue = empty($format);
|
||||
$this->checkWhitelist = false;
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
$this->export(
|
||||
array($data),
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
} else if ($options['scope'] === 'Event') {
|
||||
if (!empty($data['EventTag'])) {
|
||||
$data['Event']['EventTag'] = $data['EventTag'];
|
||||
}
|
||||
if (!empty($data['Attribute'])) {
|
||||
$this->__convertFromEventFormat($data['Attribute'], $data, $options, $continue);
|
||||
}
|
||||
if (!empty($data['Object'])) {
|
||||
foreach ($data['Object'] as $object) {
|
||||
$this->__convertFromEventFormat($object['Attribute'], $data, $options, $continue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
|
||||
private function __convertFromEventFormat($attributes, $event, $options = array(), $continue = false) {
|
||||
$rearranged = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeTag = array();
|
||||
if (!empty($attribute['AttributeTag'])) {
|
||||
$attributeTag = $attribute['AttributeTag'];
|
||||
unset($attribute['AttributeTag']);
|
||||
}
|
||||
$rearranged[] = array(
|
||||
'Attribute' => $attribute,
|
||||
'AttributeTag' => $attributeTag,
|
||||
'Event' => $event['Event']
|
||||
);
|
||||
}
|
||||
$this->export(
|
||||
$rearranged,
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
return true;
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
$continue = empty($format);
|
||||
$this->checkWhitelist = false;
|
||||
if ($options['scope'] === 'Attribute') {
|
||||
$this->export(
|
||||
array($data),
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
} else if ($options['scope'] === 'Event') {
|
||||
if (!empty($data['EventTag'])) {
|
||||
$data['Event']['EventTag'] = $data['EventTag'];
|
||||
}
|
||||
if (!empty($data['Attribute'])) {
|
||||
$this->__convertFromEventFormat($data['Attribute'], $data, $options, $continue);
|
||||
}
|
||||
if (!empty($data['Object'])) {
|
||||
$this->__convertFromEventFormatObject($data['Object'], $data, $options, $continue);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
private function __convertFromEventFormat($attributes, $event, $options = array(), $continue = false) {
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
$this->explain();
|
||||
return '';
|
||||
}
|
||||
$rearranged = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeTag = array();
|
||||
if (!empty($attribute['AttributeTag'])) {
|
||||
$attributeTag = $attribute['AttributeTag'];
|
||||
unset($attribute['AttributeTag']);
|
||||
}
|
||||
$rearranged[] = array(
|
||||
'Attribute' => $attribute,
|
||||
'AttributeTag' => $attributeTag,
|
||||
'Event' => $event['Event']
|
||||
);
|
||||
}
|
||||
$this->export(
|
||||
$rearranged,
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
return true;
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return implode ("\n", $this->rules);
|
||||
}
|
||||
}
|
||||
|
||||
public function separator()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
private function __convertFromEventFormatObject($objects, $event, $options = array(), $continue = false) {
|
||||
|
||||
$rearranged = array();
|
||||
foreach ($objects as $object) {
|
||||
|
||||
if(in_array($object['name'], $this->supportedObjects)){
|
||||
|
||||
$objectTag = array();
|
||||
|
||||
foreach($object['Attribute'] as $attribute) {
|
||||
|
||||
if (!empty($attribute['AttributeTag'])) {
|
||||
$objectTag = array_merge($objectTag, $attribute['AttributeTag']);
|
||||
unset($attribute['AttributeTag']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$rearranged[] = array(
|
||||
'Attribute' => $object, // Using 'Attribute' instead of 'Object' to comply with function export
|
||||
'AttributeTag' => $objectTag, // Using 'AttributeTag' instead of 'ObjectTag' to comply with function export
|
||||
'Event' => $event['Event']
|
||||
);
|
||||
|
||||
} else { // In case no custom export exists for the object, the approach falls back to the attribute case
|
||||
$this->__convertFromEventFormat($object['Attribute'], $event, $options, $continue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->export(
|
||||
$rearranged,
|
||||
$options['user']['nids_sid'],
|
||||
$options['returnFormat'],
|
||||
$continue
|
||||
);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function header($options = array())
|
||||
{
|
||||
$this->explain();
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return implode ("\n", $this->rules);
|
||||
}
|
||||
|
||||
public function separator()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function explain()
|
||||
{
|
||||
|
@ -93,7 +134,7 @@ class NidsExport
|
|||
$this->rules[] = '# These NIDS rules contain some variables that need to exist in your configuration.';
|
||||
$this->rules[] = '# Make sure you have set:';
|
||||
$this->rules[] = '#';
|
||||
$this->rules[] = '# $HOME_NET - Your internal network range';
|
||||
$this->rules[] = '# $HOME_NET - Your internal network range';
|
||||
$this->rules[] = '# $EXTERNAL_NET - The network considered as outside';
|
||||
$this->rules[] = '# $SMTP_SERVERS - All your internal SMTP servers';
|
||||
$this->rules[] = '# $HTTP_PORTS - The ports used to contain HTTP traffic (not required with suricata export)';
|
||||
|
@ -106,10 +147,10 @@ class NidsExport
|
|||
public function export($items, $startSid, $format="suricata", $continue = false)
|
||||
{
|
||||
$this->format = $format;
|
||||
if ($this->checkWhitelist && !isset($this->Whitelist)) {
|
||||
$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) {
|
||||
|
@ -119,20 +160,20 @@ class NidsExport
|
|||
foreach ($items as $item) {
|
||||
// retrieve all tags for this item to add them to the msg
|
||||
$tagsArray = [];
|
||||
if (!empty($item['AttributeTag'])) {
|
||||
foreach ($item['AttributeTag'] as $tag_attr) {
|
||||
if (array_key_exists('name', $tag_attr['Tag'])) {
|
||||
array_push($tagsArray, $tag_attr['Tag']['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($item['Event']['EventTag'])) {
|
||||
foreach ($item['Event']['EventTag'] as $tag_event) {
|
||||
if (array_key_exists('name', $tag_event['Tag'])) {
|
||||
array_push($tagsArray, $tag_event['Tag']['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($item['AttributeTag'])) {
|
||||
foreach ($item['AttributeTag'] as $tag_attr) {
|
||||
if (array_key_exists('name', $tag_attr['Tag'])) {
|
||||
array_push($tagsArray, $tag_attr['Tag']['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($item['Event']['EventTag'])) {
|
||||
foreach ($item['Event']['EventTag'] as $tag_event) {
|
||||
if (array_key_exists('name', $tag_event['Tag'])) {
|
||||
array_push($tagsArray, $tag_event['Tag']['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$ruleFormatMsgTags = implode(",", $tagsArray);
|
||||
|
||||
# proto src_ip src_port direction dst_ip dst_port msg rule_content tag sid rev
|
||||
|
@ -142,69 +183,180 @@ class NidsExport
|
|||
|
||||
$sid = $startSid + ($item['Attribute']['id'] * 10); // leave 9 possible rules per attribute type
|
||||
$sid++;
|
||||
switch ($item['Attribute']['type']) {
|
||||
// LATER nids - test all the snort attributes
|
||||
// LATER nids - add the tag keyword in the rules to capture network traffic
|
||||
// LATER nids - sanitize every $attribute['value'] to not conflict with snort
|
||||
case 'ip-dst':
|
||||
$this->ipDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-src':
|
||||
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-dst|port':
|
||||
$this->ipDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-src|port':
|
||||
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email':
|
||||
$this->emailSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
$this->emailDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-src':
|
||||
$this->emailSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-dst':
|
||||
$this->emailDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-subject':
|
||||
$this->emailSubjectRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-attachment':
|
||||
$this->emailAttachmentRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'domain':
|
||||
$this->domainRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'domain|ip':
|
||||
$this->domainIpRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'hostname':
|
||||
$this->hostnameRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'url':
|
||||
$this->urlRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'user-agent':
|
||||
$this->userAgentRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ja3-fingerprint-md5':
|
||||
$this->ja3Rule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ja3s-fingerprint-md5': // Atribute type doesn't exists yet (2020-12-10) but ready when created.
|
||||
$this->ja3sRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'snort':
|
||||
$this->snortRule($ruleFormat, $item['Attribute'], $sid, $ruleFormatMsg, $ruleFormatReference);
|
||||
// no break
|
||||
default:
|
||||
break;
|
||||
|
||||
if(!empty($item['Attribute']['type'])) { // item is an 'Attribute'
|
||||
|
||||
switch ($item['Attribute']['type']) {
|
||||
// LATER nids - test all the snort attributes
|
||||
// LATER nids - add the tag keyword in the rules to capture network traffic
|
||||
// LATER nids - sanitize every $attribute['value'] to not conflict with snort
|
||||
case 'ip-dst':
|
||||
$this->ipDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-src':
|
||||
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-dst|port':
|
||||
$this->ipDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ip-src|port':
|
||||
$this->ipSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email':
|
||||
$this->emailSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
$sid++;
|
||||
$this->emailDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-src':
|
||||
$this->emailSrcRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-dst':
|
||||
$this->emailDstRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-subject':
|
||||
$this->emailSubjectRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'email-attachment':
|
||||
$this->emailAttachmentRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'domain':
|
||||
$this->domainRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'domain|ip':
|
||||
$this->domainIpRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'hostname':
|
||||
$this->hostnameRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'url':
|
||||
$this->urlRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'user-agent':
|
||||
$this->userAgentRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ja3-fingerprint-md5':
|
||||
$this->ja3Rule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ja3s-fingerprint-md5': // Atribute type doesn't exists yet (2020-12-10) but ready when created.
|
||||
$this->ja3sRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'snort':
|
||||
$this->snortRule($ruleFormat, $item['Attribute'], $sid, $ruleFormatMsg, $ruleFormatReference);
|
||||
// no break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else if(!empty($item['Attribute']['name'])) { // Item is an 'Object'
|
||||
|
||||
switch ($item['Attribute']['name']) {
|
||||
case 'network-connection':
|
||||
$this->networkConnectionRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
case 'ddos':
|
||||
$this->ddosRule($ruleFormat, $item['Attribute'], $sid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->rules;
|
||||
}
|
||||
|
||||
public function networkConnectionRule($ruleFormat, $object, &$sid)
|
||||
{
|
||||
|
||||
$attributes = NidsExport::getObjectAttributes($object);
|
||||
|
||||
if(!array_key_exists('layer4-protocol', $attributes)){
|
||||
$attributes['layer4-protocol'] = 'ip'; // If layer-4 protocol is unknown, we roll-back to layer-3 ('ip')
|
||||
}
|
||||
if(!array_key_exists('ip-src', $attributes)){
|
||||
$attributes['ip-src'] = '$HOME_NET'; // If ip-src is unknown, we roll-back to $HOME_NET
|
||||
}
|
||||
if(!array_key_exists('ip-dst', $attributes)){
|
||||
$attributes['ip-dst'] = '$HOME_NET'; // If ip-dst is unknown, we roll-back to $HOME_NET
|
||||
}
|
||||
if(!array_key_exists('src-port', $attributes)){
|
||||
$attributes['src-port'] = 'any'; // If src-port is unknown, we roll-back to 'any'
|
||||
}
|
||||
if(!array_key_exists('dst-port', $attributes)){
|
||||
$attributes['dst-port'] = 'any'; // If dst-port is unknown, we roll-back to 'any'
|
||||
}
|
||||
|
||||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
false,
|
||||
$attributes['layer4-protocol'], // proto
|
||||
$attributes['ip-src'], // src_ip
|
||||
$attributes['src-port'], // src_port
|
||||
'->', // direction
|
||||
$attributes['ip-dst'], // dst_ip
|
||||
$attributes['dst-port'], // dst_port
|
||||
'Network connection between ' . $attributes['ip-src'] . ' and ' . $attributes['ip-dst'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function ddosRule($ruleFormat, $object, &$sid)
|
||||
{
|
||||
|
||||
$attributes = NidsExport::getObjectAttributes($object);
|
||||
|
||||
if(!array_key_exists('protocol', $attributes)){
|
||||
$attributes['protocol'] = 'ip'; // If protocol is unknown, we roll-back to 'ip'
|
||||
}
|
||||
if(!array_key_exists('ip-src', $attributes)){
|
||||
$attributes['ip-src'] = '$HOME_NET'; // If ip-src is unknown, we roll-back to $HOME_NET
|
||||
}
|
||||
if(!array_key_exists('ip-dst', $attributes)){
|
||||
$attributes['ip-dst'] = '$HOME_NET'; // If ip-dst is unknown, we roll-back to $HOME_NET
|
||||
}
|
||||
if(!array_key_exists('src-port', $attributes)){
|
||||
$attributes['src-port'] = 'any'; // If src-port is unknown, we roll-back to 'any'
|
||||
}
|
||||
if(!array_key_exists('dst-port', $attributes)){
|
||||
$attributes['dst-port'] = 'any'; // If dst-port is unknown, we roll-back to 'any'
|
||||
}
|
||||
|
||||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
false,
|
||||
$attributes['protocol'], // proto
|
||||
$attributes['ip-src'], // src_ip
|
||||
$attributes['src-port'], // src_port
|
||||
'->', // direction
|
||||
$attributes['ip-dst'], // dst_ip
|
||||
$attributes['dst-port'], // dst_port
|
||||
'DDOS attack detected between ' . $attributes['ip-src'] . ' and ' . $attributes['ip-dst'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public static function getObjectAttributes($object)
|
||||
{
|
||||
|
||||
$attributes = array();
|
||||
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
$attributes[$attribute['object_relation']] = $attribute['value'];
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
public function domainIpRule($ruleFormat, $attribute, &$sid)
|
||||
{
|
||||
$values = explode('|', $attribute['value']);
|
||||
|
@ -225,17 +377,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'ip', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
$ipport[0], // dst_ip
|
||||
$ipport[1], // dst_port
|
||||
'Outgoing To IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'ip', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
$ipport[0], // dst_ip
|
||||
$ipport[1], // dst_port
|
||||
'Outgoing To IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -246,17 +398,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'ip', // proto
|
||||
$ipport[0], // src_ip
|
||||
$ipport[1], // src_port
|
||||
'->', // direction
|
||||
'$HOME_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Incoming From IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'ip', // proto
|
||||
$ipport[0], // src_ip
|
||||
$ipport[1], // src_port
|
||||
'->', // direction
|
||||
'$HOME_NET', // dst_ip
|
||||
'any', // dst_port
|
||||
'Incoming From IP: ' . $attribute['value'], // msg
|
||||
'', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -268,17 +420,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Source Email Address: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Source Email Address: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -290,17 +442,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Destination Email Address: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Destination Email Address: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -313,17 +465,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Subject', // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Subject', // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -336,17 +488,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Attachment', // msg
|
||||
$content, // rule_content // LATER nids - test and finetune this snort rule https://secure.wikimedia.org/wikipedia/en/wiki/MIME#Content-Disposition
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$EXTERNAL_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$SMTP_SERVERS', // dst_ip
|
||||
'25', // dst_port
|
||||
'Bad Email Attachment', // msg
|
||||
$content, // rule_content // LATER nids - test and finetune this snort rule https://secure.wikimedia.org/wikipedia/en/wiki/MIME#Content-Disposition
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -358,33 +510,33 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Hostname: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests
|
||||
|
@ -392,17 +544,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Hostname: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -414,33 +566,33 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'udp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'any', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'any', // dst_ip
|
||||
'53', // dst_port
|
||||
'Domain: ' . $attribute['value'], // msg
|
||||
$content. ' flow:established;', // rule_content
|
||||
'', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
$sid++;
|
||||
// also do http requests,
|
||||
|
@ -448,17 +600,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP Domain: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -473,17 +625,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP URL: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing HTTP URL: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -495,17 +647,17 @@ class NidsExport
|
|||
$this->rules[] = sprintf(
|
||||
$ruleFormat,
|
||||
($overruled) ? '#OVERRULED BY WHITELIST# ' : '',
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing User-Agent: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
'tcp', // proto
|
||||
'$HOME_NET', // src_ip
|
||||
'any', // src_port
|
||||
'->', // direction
|
||||
'$EXTERNAL_NET', // dst_ip
|
||||
'$HTTP_PORTS', // dst_port
|
||||
'Outgoing User-Agent: ' . $attribute['value'], // msg
|
||||
$content, // rule_content
|
||||
'tag:session,600,seconds;', // tag
|
||||
$sid, // sid
|
||||
1 // rev
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -527,37 +679,37 @@ class NidsExport
|
|||
$tmpRule = str_replace(array("\r","\n"), " ", $attribute['value']);
|
||||
|
||||
// rebuild the rule by overwriting the different keywords using preg_replace()
|
||||
// sid - '/sid\s*:\s*[0-9]+\s*;/'
|
||||
// rev - '/rev\s*:\s*[0-9]+\s*;/'
|
||||
// sid - '/sid\s*:\s*[0-9]+\s*;/'
|
||||
// rev - '/rev\s*:\s*[0-9]+\s*;/'
|
||||
// classtype - '/classtype:[a-zA-Z_-]+;/'
|
||||
// msg - '/msg\s*:\s*".*?"\s*;/'
|
||||
// msg - '/msg\s*:\s*".*?"\s*;/'
|
||||
// reference - '/reference\s*:\s*.+?;/'
|
||||
// tag - '/tag\s*:\s*.+?;/'
|
||||
// tag - '/tag\s*:\s*.+?;/'
|
||||
$replaceCount = array();
|
||||
$tmpRule = preg_replace('/sid\s*:\s*[0-9]+\s*;/', 'sid:' . $sid . ';', $tmpRule, -1, $replaceCount['sid']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
$tmpRule = preg_replace('/rev\s*:\s*[0-9]+\s*;/', 'rev:1;', $tmpRule, -1, $replaceCount['rev']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
$tmpRule = preg_replace('/classtype:[a-zA-Z_-]+;/', 'classtype:' . $this->classtype . ';', $tmpRule, -1, $replaceCount['classtype']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
$tmpRule = preg_replace('/msg\s*:\s*"(.*?)"\s*;/', sprintf($ruleFormatMsg, 'snort-rule | $1') . ';', $tmpRule, -1, $replaceCount['msg']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
$tmpRule = preg_replace('/reference\s*:\s*.+?;/', $ruleFormatReference . ';', $tmpRule, -1, $replaceCount['reference']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
$tmpRule = preg_replace('/reference\s*:\s*.+?;/', $ruleFormatReference . ';', $tmpRule, -1, $replaceCount['reference']);
|
||||
if (null == $tmpRule) {
|
||||
return false;
|
||||
} // don't output the rule on error with the regex
|
||||
} // don't output the rule on error with the regex
|
||||
// FIXME nids - implement priority overwriting
|
||||
|
||||
// some values were not replaced, so we need to add them ourselves, and insert them in the rule
|
||||
|
@ -667,13 +819,13 @@ class NidsExport
|
|||
|
||||
public function checkWhitelist($value)
|
||||
{
|
||||
if ($this->checkWhitelist && is_array($this->whitelist)) {
|
||||
foreach ($this->whitelist as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->checkWhitelist && is_array($this->whitelist)) {
|
||||
foreach ($this->whitelist as $wlitem) {
|
||||
if (preg_match($wlitem, $value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,10 +387,11 @@ class AttachmentTool
|
|||
* @param string $data
|
||||
* @param int $maxWidth
|
||||
* @param int $maxHeight
|
||||
* @param string $outputFormat Can be 'png' or 'webp'
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function resizeImage($data, $maxWidth, $maxHeight)
|
||||
public function resizeImage($data, $maxWidth, $maxHeight, $outputFormat = 'png')
|
||||
{
|
||||
$image = imagecreatefromstring($data);
|
||||
if ($image === false) {
|
||||
|
@ -425,7 +426,16 @@ class AttachmentTool
|
|||
|
||||
// Output image to string
|
||||
ob_start();
|
||||
imagepng($imageThumbnail, null, 9);
|
||||
if ($outputFormat === 'webp') {
|
||||
if (!function_exists('imagewebp')) {
|
||||
throw new InvalidArgumentException("Webp image format is not supported.");
|
||||
}
|
||||
imagewebp($imageThumbnail);
|
||||
} elseif ($outputFormat === 'png') {
|
||||
imagepng($imageThumbnail, null, 9);
|
||||
} else {
|
||||
throw new InvalidArgumentException("Unsupported image format $outputFormat.");
|
||||
}
|
||||
$imageData = ob_get_clean();
|
||||
imagedestroy($imageThumbnail);
|
||||
|
||||
|
@ -460,7 +470,8 @@ class AttachmentTool
|
|||
*/
|
||||
public function attachmentDirIsS3()
|
||||
{
|
||||
return substr(Configure::read('MISP.attachments_dir'), 0, 2) === "s3";
|
||||
$attachmentsDir = Configure::read('MISP.attachments_dir');
|
||||
return $attachmentsDir && substr($attachmentsDir, 0, 2) === "s3";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -407,7 +407,7 @@ class AttributeValidationTool
|
|||
case 'dns-soa-email':
|
||||
case 'jabber-id':
|
||||
// we don't use the native function to prevent issues with partial email addresses
|
||||
if (preg_match("#^.*\@.*\..*$#i", $value)) {
|
||||
if (preg_match("#^.[^\s]*\@.*\..*$#i", $value)) {
|
||||
return true;
|
||||
}
|
||||
return __('Email address has an invalid format. Please double check the value or select type "other".');
|
||||
|
|
|
@ -7,17 +7,17 @@ App::uses('BackgroundJob', 'Tools/BackgroundJobs');
|
|||
|
||||
/**
|
||||
* BackgroundJobs Tool
|
||||
*
|
||||
*
|
||||
* Utility class to queue jobs, run them and monitor workers.
|
||||
*
|
||||
*
|
||||
* To run a worker manually (debug only):
|
||||
* $ ./Console/cake start_worker [queue]
|
||||
*
|
||||
*
|
||||
* It is recommended to run these commands with [Supervisor](http://supervisord.org).
|
||||
* `Supervisor` has an extensive feature set to manage scripts as services,
|
||||
* such as autorestart, parallel execution, logging, monitoring and much more.
|
||||
* `Supervisor` has an extensive feature set to manage scripts as services,
|
||||
* such as autorestart, parallel execution, logging, monitoring and much more.
|
||||
* All can be managed via the terminal or a XML-RPC API.
|
||||
*
|
||||
*
|
||||
* Use the following configuration as a template for the services:
|
||||
* /etc/supervisor/conf.d/misp-workers.conf:
|
||||
* [group:misp-workers]
|
||||
|
@ -27,14 +27,14 @@ App::uses('BackgroundJob', 'Tools/BackgroundJobs');
|
|||
* [program:default]
|
||||
* command=/var/www/MISP/app/Console/cake start_worker default
|
||||
* process_name=%(program_name)s_%(process_num)02d
|
||||
* numprocs=5 ; adjust the amount of parallel workers to your MISP usage
|
||||
* numprocs=5 ; adjust the amount of parallel workers to your MISP usage
|
||||
* autostart=true
|
||||
* autorestart=true
|
||||
* redirect_stderr=false
|
||||
* stderr_logfile=/var/www/MISP/app/tmp/logs/misp-workers-errors.log
|
||||
* stdout_logfile=/var/www/MISP/app/tmp/logs/misp-workers.log
|
||||
* user=www-data
|
||||
*
|
||||
*
|
||||
*/
|
||||
class BackgroundJobsTool
|
||||
{
|
||||
|
@ -73,18 +73,21 @@ class BackgroundJobsTool
|
|||
const
|
||||
CMD_EVENT = 'event',
|
||||
CMD_SERVER = 'server',
|
||||
CMD_ADMIN = 'admin';
|
||||
CMD_ADMIN = 'admin',
|
||||
CMD_WORKFLOW = 'workflow';
|
||||
|
||||
const ALLOWED_COMMANDS = [
|
||||
self::CMD_EVENT,
|
||||
self::CMD_SERVER,
|
||||
self::CMD_ADMIN
|
||||
self::CMD_ADMIN,
|
||||
self::CMD_WORKFLOW,
|
||||
];
|
||||
|
||||
const CMD_TO_SHELL_DICT = [
|
||||
self::CMD_EVENT => 'EventShell',
|
||||
self::CMD_SERVER => 'ServerShell',
|
||||
self::CMD_ADMIN => 'AdminShell'
|
||||
self::CMD_ADMIN => 'AdminShell',
|
||||
self::CMD_WORKFLOW => 'WorkflowShell',
|
||||
];
|
||||
|
||||
const JOB_STATUS_PREFIX = 'job_status';
|
||||
|
@ -176,7 +179,7 @@ class BackgroundJobsTool
|
|||
/**
|
||||
* Enqueue a Job using the CakeResque.
|
||||
* @deprecated
|
||||
*
|
||||
*
|
||||
* @param string $queue Name of the queue to enqueue the job to.
|
||||
* @param string $class Class of the job.
|
||||
* @param array $args Arguments passed to the job.
|
||||
|
@ -212,9 +215,9 @@ class BackgroundJobsTool
|
|||
*
|
||||
* @param string $queue Queue name, e.g. 'default'.
|
||||
* @param int $timeout Time to block the read if the queue is empty.
|
||||
* Must be less than your configured `read_write_timeout`
|
||||
* Must be less than your configured `read_write_timeout`
|
||||
* for the redis connection.
|
||||
*
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function dequeue($queue, int $timeout = 30)
|
||||
|
@ -262,7 +265,7 @@ class BackgroundJobsTool
|
|||
* Clear all the queue's jobs.
|
||||
*
|
||||
* @param string $queue Queue name, e.g. 'default'.
|
||||
*
|
||||
*
|
||||
* @return boolean True on success, false on failure.
|
||||
*/
|
||||
public function clearQueue($queue): bool
|
||||
|
@ -309,7 +312,7 @@ class BackgroundJobsTool
|
|||
* Get the number of jobs inside a queue.
|
||||
*
|
||||
* @param string $queue Queue name, e.g. 'default'.
|
||||
*
|
||||
*
|
||||
* @return integer Number of jobs.
|
||||
*/
|
||||
public function getQueueSize(string $queue): int
|
||||
|
@ -327,7 +330,7 @@ class BackgroundJobsTool
|
|||
* Update job
|
||||
*
|
||||
* @param BackgroundJob $job
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update(BackgroundJob $job)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
class BetterCakeEventManager extends CakeEventManager
|
||||
{
|
||||
/**
|
||||
* This method is similar as original dispatch, but do not return newly created event. With returning event, there is
|
||||
* big memory leak in PHP at least for PHP version 7.4.19.
|
||||
* @param CakeEvent $event
|
||||
*/
|
||||
public function dispatch($event)
|
||||
{
|
||||
$listeners = $this->listeners($event->name());
|
||||
if (empty($listeners)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($listeners as $listener) {
|
||||
if ($event->isStopped()) {
|
||||
break;
|
||||
}
|
||||
if ($listener['passParams'] === true) {
|
||||
$result = call_user_func_array($listener['callable'], $event->data);
|
||||
} else {
|
||||
$result = $listener['callable']($event);
|
||||
}
|
||||
if ($result === false) {
|
||||
$event->stopPropagation();
|
||||
}
|
||||
if ($result !== null) {
|
||||
$event->result = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $eventKey
|
||||
* @return array
|
||||
*/
|
||||
public function listeners($eventKey)
|
||||
{
|
||||
if ($this->_isGlobal) {
|
||||
$localListeners = [];
|
||||
} else {
|
||||
$localListeners = $this->_listeners[$eventKey] ?? [];
|
||||
}
|
||||
|
||||
$globalListeners = static::instance()->prioritisedListeners($eventKey);
|
||||
|
||||
$priorities = array_merge(array_keys($globalListeners), array_keys($localListeners));
|
||||
$priorities = array_unique($priorities, SORT_REGULAR);
|
||||
asort($priorities);
|
||||
|
||||
$result = [];
|
||||
foreach ($priorities as $priority) {
|
||||
if (isset($globalListeners[$priority])) {
|
||||
$result = array_merge($result, $globalListeners[$priority]);
|
||||
}
|
||||
if (isset($localListeners[$priority])) {
|
||||
$result = array_merge($result, $localListeners[$priority]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -31,14 +31,14 @@ class ComplexTypeTool
|
|||
)
|
||||
);
|
||||
|
||||
const HEX_HASH_TYPES = array(
|
||||
32 => array('single' => array('md5', 'imphash', 'x509-fingerprint-md5'), 'composite' => array('filename|md5', 'filename|imphash')),
|
||||
40 => array('single' => array('sha1', 'pehash', 'x509-fingerprint-sha1', 'cdhash'), 'composite' => array('filename|sha1', 'filename|pehash')),
|
||||
56 => array('single' => array('sha224', 'sha512/224'), 'composite' => array('filename|sha224', 'filename|sha512/224')),
|
||||
64 => array('single' => array('sha256', 'authentihash', 'sha512/256', 'x509-fingerprint-sha256'), 'composite' => array('filename|sha256', 'filename|authentihash', 'filename|sha512/256')),
|
||||
96 => array('single' => array('sha384'), 'composite' => array('filename|sha384')),
|
||||
128 => array('single' => array('sha512'), 'composite' => array('filename|sha512'))
|
||||
);
|
||||
const HEX_HASH_TYPES = [
|
||||
32 => ['single' => ['md5', 'imphash', 'x509-fingerprint-md5', 'ja3-fingerprint-md5'], 'composite' => ['filename|md5', 'filename|imphash']],
|
||||
40 => ['single' => ['sha1', 'pehash', 'x509-fingerprint-sha1', 'cdhash'], 'composite' => ['filename|sha1', 'filename|pehash']],
|
||||
56 => ['single' => ['sha224', 'sha512/224'], 'composite' => ['filename|sha224', 'filename|sha512/224']],
|
||||
64 => ['single' => ['sha256', 'authentihash', 'sha512/256', 'x509-fingerprint-sha256'], 'composite' => ['filename|sha256', 'filename|authentihash', 'filename|sha512/256']],
|
||||
96 => ['single' => ['sha384'], 'composite' => ['filename|sha384']],
|
||||
128 => ['single' => ['sha512'], 'composite' => ['filename|sha512']],
|
||||
];
|
||||
|
||||
private $__tlds = null;
|
||||
|
||||
|
|
|
@ -83,14 +83,14 @@ class CustomPaginationTool
|
|||
$items = array_values($items);
|
||||
}
|
||||
|
||||
public function sortArray($items, $params, $escapeReindex = false)
|
||||
public function sortArray(array $items, $params, $escapeReindex = false)
|
||||
{
|
||||
if (isset($params['sort'])) {
|
||||
$sortArray = array();
|
||||
foreach ($items as $k => $item) {
|
||||
$sortArray[$k] = !empty(Hash::get($item, $params['sort'])) ? $item[$params['sort']] : '';
|
||||
$sortArray[$k] = !empty($item[$params['sort']]) ? $item[$params['sort']] : '';
|
||||
}
|
||||
if (empty($params['options']['direction']) || $params['options']['direction'] == 'asc') {
|
||||
if (empty($params['options']['direction']) || $params['options']['direction'] === 'asc') {
|
||||
asort($sortArray);
|
||||
} else {
|
||||
arsort($sortArray);
|
||||
|
@ -107,12 +107,13 @@ class CustomPaginationTool
|
|||
return $items;
|
||||
}
|
||||
|
||||
public function applyRulesOnArray(&$items, $options, $model, $sort = 'id', $focusKey = 'uuid', $escapeReindex = false)
|
||||
public function applyRulesOnArray(array &$items, $options, $model, $sort = 'id', $focusKey = 'uuid', $escapeReindex = false)
|
||||
{
|
||||
$params = $this->createPaginationRules($items, $options, $model, $sort, $focusKey);
|
||||
$items = $this->sortArray($items, $params, $escapeReindex);
|
||||
|
||||
if (!empty($params['options']['focus'])) {
|
||||
$focus = $params['options']['focus'];
|
||||
$focus = $params['options']['focus'];
|
||||
foreach ($items as $k => $item) {
|
||||
if ($item[$focusKey] === $focus) {
|
||||
$params['page'] = 1 + intval(floor($k / $params['limit']));
|
||||
|
@ -122,6 +123,7 @@ class CustomPaginationTool
|
|||
}
|
||||
unset($params['options']['focus']);
|
||||
}
|
||||
// Start array from one
|
||||
array_unshift($items, 'dummy');
|
||||
unset($items[0]);
|
||||
$this->truncateByPagination($items, $params);
|
||||
|
|
|
@ -96,7 +96,7 @@ class FileAccessTool
|
|||
* @param bool $createFolder
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function writeToFile($file, $content, $createFolder = false)
|
||||
public static function writeToFile($file, $content, $createFolder = false, $append = false)
|
||||
{
|
||||
$dir = dirname($file);
|
||||
if ($createFolder && !is_dir($dir)) {
|
||||
|
@ -105,7 +105,7 @@ class FileAccessTool
|
|||
}
|
||||
}
|
||||
|
||||
if (file_put_contents($file, $content, LOCK_EX) === false) {
|
||||
if (file_put_contents($file, $content, LOCK_EX | (!empty($append) ? FILE_APPEND : 0)) === false) {
|
||||
$freeSpace = disk_free_space($dir);
|
||||
throw new Exception("An error has occurred while attempt to write to file `$file`. Maybe not enough space? ($freeSpace bytes left)");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
class GraphvizDOTTool
|
||||
{
|
||||
const NODE_STYLE = [
|
||||
'trigger' => [
|
||||
'margin' => 0,
|
||||
'shape' => 'diamond',
|
||||
],
|
||||
'logic' => [
|
||||
'margin' => 0,
|
||||
'shape' => 'parallelogram',
|
||||
],
|
||||
'action' => [
|
||||
'margin' => 0,
|
||||
'shape' => 'box',
|
||||
],
|
||||
];
|
||||
const EDGE_STYLE = [
|
||||
];
|
||||
|
||||
/**
|
||||
* dot Get DOT language format of the provided graph
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dot(array $graph_data)
|
||||
{
|
||||
$parsedGraph = self::__parseGraph($graph_data);
|
||||
$str = self::__header();
|
||||
$str .= self::__nodes($parsedGraph['nodes']);
|
||||
$str .= self::__edges($parsedGraph['edges']);
|
||||
$str .= self::__footer();
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __parseGraph($graph_data)
|
||||
{
|
||||
$graphUtil = new GraphUtil($graph_data);
|
||||
$nodes = $graphUtil->graph;
|
||||
$edges = $graphUtil->edgeList;
|
||||
return [
|
||||
'nodes' => $nodes,
|
||||
'edges' => $edges,
|
||||
];
|
||||
}
|
||||
|
||||
private static function __header()
|
||||
{
|
||||
return 'digraph G {' . PHP_EOL;
|
||||
}
|
||||
|
||||
private static function __footer()
|
||||
{
|
||||
return '}';
|
||||
}
|
||||
|
||||
private static function __nodes($nodes)
|
||||
{
|
||||
$str = ' {' . PHP_EOL;
|
||||
foreach ($nodes as $node) {
|
||||
$str .= ' ' . self::__node($node);
|
||||
}
|
||||
$str .= ' }' . PHP_EOL;
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __node(array $node)
|
||||
{
|
||||
$node_attributes = self::NODE_STYLE[$node['data']['module_type']];
|
||||
$node_attributes['label'] = $node['data']['name'];
|
||||
$node_attributes_text = self::__arrayToAttributes($node_attributes);
|
||||
return sprintf('%s [%s]' . PHP_EOL, $node['id'], $node_attributes_text);
|
||||
}
|
||||
|
||||
private static function __edges($edges)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($edges as $source_id => $target_ids) {
|
||||
foreach ($target_ids as $target_id) {
|
||||
$str .= ' ' . self::__edge($source_id, $target_id);
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __edge($source_id, $target_id)
|
||||
{
|
||||
return sprintf('%s -> %s [%s]' . PHP_EOL, $source_id, $target_id, self::__arrayToAttributes(self::EDGE_STYLE));
|
||||
}
|
||||
|
||||
private static function __arrayToAttributes(array $list)
|
||||
{
|
||||
return implode(', ', array_map(function ($key, $value) {
|
||||
return sprintf('%s="%s"', $key, $value);
|
||||
}, array_keys($list), $list));
|
||||
}
|
||||
}
|
|
@ -187,11 +187,7 @@ class JSONConverterTool
|
|||
$resultArray = ': ' . $array . PHP_EOL;
|
||||
}
|
||||
if ($root) {
|
||||
$text = '';
|
||||
foreach ($resultArray as $r) {
|
||||
$text .= $r;
|
||||
}
|
||||
return $text;
|
||||
return implode('', $resultArray);
|
||||
} else {
|
||||
return $resultArray;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
App::uses('FontAwesomeHelper', 'View/Helper');
|
||||
require_once APP . 'Lib/Tools/WorkflowGraphTool.php';
|
||||
|
||||
class MermaidFlowchartTool
|
||||
{
|
||||
const NODE_STYLE = [
|
||||
'trigger' => '{{%s}}',
|
||||
'logic' => '[/%s/]',
|
||||
'action' => '[%s]',
|
||||
];
|
||||
|
||||
/**
|
||||
* dot Get DOT language format of the provided graph
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function mermaid(array $graph_data)
|
||||
{
|
||||
$parsedGraph = self::__parseGraph($graph_data);
|
||||
$str = self::__header();
|
||||
$str .= self::__nodes($parsedGraph['nodes'], $parsedGraph['edges']);
|
||||
$str .= self::__footer();
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __parseGraph($graph_data)
|
||||
{
|
||||
$graphUtil = new GraphUtil($graph_data);
|
||||
$nodes = Hash::combine($graphUtil->graph, '{n}.id', '{n}');
|
||||
$edges = $graphUtil->edgeList;
|
||||
return [
|
||||
'nodes' => $nodes,
|
||||
'edges' => $edges,
|
||||
];
|
||||
}
|
||||
|
||||
private static function __header()
|
||||
{
|
||||
return 'flowchart LR' . PHP_EOL;
|
||||
}
|
||||
|
||||
private static function __footer()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
private static function __nodes($nodes, $edges)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($nodes as $node) {
|
||||
$str .= self::__node($nodes, $node, $edges[$node['id']]);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __node(array $all_nodes, array $node, array $edges)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($edges as $target_id) {
|
||||
if (empty($all_nodes[$target_id])) {
|
||||
continue;
|
||||
}
|
||||
$target_node = $all_nodes[$target_id];
|
||||
$sourceNode = self::__singleNode($node);
|
||||
$targetNode = self::__singleNode($target_node);
|
||||
$str .= ' ' . sprintf('%s --> %s', $sourceNode, $targetNode) . PHP_EOL;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
private static function __singleNode(array $node)
|
||||
{
|
||||
$str = $node['id'];
|
||||
$icon = sprintf("%s:fa-%s ", FontAwesomeHelper::findNamespace($node['data']['module_data']['icon']), $node['data']['module_data']['icon']);
|
||||
$node_content = sprintf('"%s%s"',(!empty($node['data']['module_data']['icon']) ? "$icon " : ''), $node['name']);
|
||||
$str .= sprintf(
|
||||
self::NODE_STYLE[$node['data']['module_type']],
|
||||
$node_content
|
||||
);
|
||||
return $str;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
class ProcessException extends Exception
|
||||
{
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
private $stderr;
|
||||
|
||||
/** @var string */
|
||||
|
@ -10,13 +10,14 @@ class ProcessException extends Exception
|
|||
/**
|
||||
* @param string|array $command
|
||||
* @param int $returnCode
|
||||
* @param string $stderr
|
||||
* @param string|null $stderr
|
||||
* @param string $stdout
|
||||
*/
|
||||
public function __construct($command, $returnCode, $stderr, $stdout)
|
||||
{
|
||||
$commandForException = is_array($command) ? implode(' ', $command) : $command;
|
||||
$message = "Command '$commandForException' return error code $returnCode.\nSTDERR: '$stderr'\nSTDOUT: '$stdout'";
|
||||
$stderrToMessage = $stderr === null ? 'Logged to tmp/logs/exec-errors.log' : "'$stderr'";
|
||||
$message = "Command '$commandForException' finished with error code $returnCode.\nSTDERR: $stderrToMessage\nSTDOUT: '$stdout'";
|
||||
$this->stderr = $stderr;
|
||||
$this->stdout = $stdout;
|
||||
parent::__construct($message, $returnCode);
|
||||
|
@ -48,13 +49,13 @@ class ProcessTool
|
|||
public static function execute(array $command, $cwd = null, $stderrToFile = false)
|
||||
{
|
||||
$descriptorSpec = [
|
||||
1 => ["pipe", "w"], // stdout
|
||||
2 => ["pipe", "w"], // stderr
|
||||
1 => ['pipe', 'w'], // stdout
|
||||
2 => ['pipe', 'w'], // stderr
|
||||
];
|
||||
|
||||
if ($stderrToFile) {
|
||||
self::logMessage('Running command ' . implode(' ', $command));
|
||||
$descriptorSpec[2] = ["file", self::LOG_FILE, 'a'];
|
||||
$descriptorSpec[2] = ['file', self::LOG_FILE, 'a'];
|
||||
}
|
||||
|
||||
// PHP older than 7.4 do not support proc_open with array, so we need to convert values to string manually
|
||||
|
|
|
@ -62,9 +62,13 @@ class PubSubTool
|
|||
if ($response === null) {
|
||||
throw new Exception("No response from status command returned after 5 seconds.");
|
||||
}
|
||||
return json_decode(trim($response[1]), true);
|
||||
return JsonTool::decode(trim($response[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws ProcessException
|
||||
*/
|
||||
public function checkIfPythonLibInstalled()
|
||||
{
|
||||
$script = APP . 'files' . DS . 'scripts' . DS . 'mispzmq' . DS . 'mispzmqtest.py';
|
||||
|
@ -143,6 +147,12 @@ class PubSubTool
|
|||
return $this->pushToRedis('data:misp_json_warninglist', $warninglist);
|
||||
}
|
||||
|
||||
public function workflow_push(array $data)
|
||||
{
|
||||
$topic = 'data:misp_json_workflow';
|
||||
return $this->pushToRedis($topic, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string $type
|
||||
|
@ -301,7 +311,7 @@ class PubSubTool
|
|||
|
||||
$pluginConfig = Configure::read('Plugin');
|
||||
foreach ($settings as $key => $setting) {
|
||||
$temp = isset($pluginConfig['ZeroMQ_' . $key]) ? $pluginConfig['ZeroMQ_' . $key] : null;
|
||||
$temp = $pluginConfig['ZeroMQ_' . $key] ?? null;
|
||||
if ($temp) {
|
||||
$settings[$key] = $temp;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class QueryTool
|
|||
{
|
||||
$db = $model->getDataSource();
|
||||
$connection = $db->getConnection();
|
||||
if ($db->config['datasource'] === 'Database/Mysql' || $db->config['datasource'] === 'Database/MysqlObserver') {
|
||||
if (in_array($db->config['datasource'], ['Database/Mysql', 'Database/MysqlObserver', 'Database/MysqlExtended'])) {
|
||||
$query = $connection->prepare('DELETE FROM ' . $table . ' WHERE ' . $field . ' = :value');
|
||||
} elseif ($db->config['datasource'] == 'Database/Postgres' ) {
|
||||
$query = $connection->prepare('DELETE FROM "' . $table . '" WHERE "' . $field . '" = :value');
|
||||
|
|
|
@ -431,7 +431,7 @@ class SecurityAudit
|
|||
App::uses('CakeEmail', 'Network/Email');
|
||||
$email = new CakeEmail();
|
||||
$emailConfig = $email->config();
|
||||
if ($emailConfig['transport'] === 'Smtp' && $emailConfig['port'] == 25 && !$emailConfig['tls']) {
|
||||
if ($emailConfig['transport'] === 'Smtp' && $emailConfig['port'] == 25 && empty($emailConfig['tls'])) {
|
||||
$output['Email'][] = [
|
||||
'warning',
|
||||
__('STARTTLS is not enabled.'),
|
||||
|
|
|
@ -114,7 +114,7 @@ class CakeEmailExtended extends CakeEmail
|
|||
throw new InvalidArgumentException("Expected instance of CakeEmailBody, " . gettype($this->body) . " given.");
|
||||
}
|
||||
|
||||
$this->_boundary = md5(uniqid());
|
||||
$this->_boundary = md5(mt_rand());
|
||||
|
||||
$rendered = [];
|
||||
if (!empty($this->body->text)) {
|
||||
|
@ -191,7 +191,7 @@ class MimeMultipart
|
|||
public function __construct($subtype = 'mixed', $additionalTypes = array())
|
||||
{
|
||||
$this->subtype = $subtype;
|
||||
$this->boundary = md5(uniqid());
|
||||
$this->boundary = md5(mt_rand());
|
||||
$this->additionalTypes = $additionalTypes;
|
||||
}
|
||||
|
||||
|
@ -484,6 +484,10 @@ class SendEmail
|
|||
]);
|
||||
}
|
||||
|
||||
if ($body instanceof SendEmailTemplate && $body->listUnsubscribe()) {
|
||||
$email->addHeaders(['List-Unsubscribe' => "<{$body->listUnsubscribe()}>"]);
|
||||
}
|
||||
|
||||
$signed = false;
|
||||
if (Configure::read('GnuPG.sign')) {
|
||||
if (!$this->gpg) {
|
||||
|
|
|
@ -10,6 +10,9 @@ class SendEmailTemplate
|
|||
/** @var string|null */
|
||||
private $referenceId;
|
||||
|
||||
/** @var string */
|
||||
private $listUnsubscribe;
|
||||
|
||||
/** @var string|null */
|
||||
private $subject;
|
||||
|
||||
|
@ -31,6 +34,18 @@ class SendEmailTemplate
|
|||
$this->referenceId = $referenceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $listUnsubscribe
|
||||
* @return string|void
|
||||
*/
|
||||
public function listUnsubscribe($listUnsubscribe = null)
|
||||
{
|
||||
if ($listUnsubscribe === null) {
|
||||
return $this->listUnsubscribe;
|
||||
}
|
||||
$this->listUnsubscribe = $listUnsubscribe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subject from template. Must be called after render method.
|
||||
* @param string|null $subject
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
App::uses('SyncTool', 'Tools');
|
||||
App::uses('JsonTool', 'Tools');
|
||||
|
||||
class ServerSyncTool
|
||||
{
|
||||
|
@ -8,8 +9,11 @@ class ServerSyncTool
|
|||
FEATURE_ORG_RULE = 'org_rule',
|
||||
FEATURE_FILTER_SIGHTINGS = 'filter_sightings',
|
||||
FEATURE_PROPOSALS = 'proposals',
|
||||
FEATURE_PROTECTED_EVENT = 'protected_event',
|
||||
FEATURE_POST_TEST = 'post_test',
|
||||
FEATURE_PROTECTED_EVENT = 'protected_event';
|
||||
FEATURE_EDIT_OF_GALAXY_CLUSTER = 'edit_of_galaxy_cluster',
|
||||
PERM_SYNC = 'perm_sync',
|
||||
PERM_GALAXY_EDITOR = 'perm_galaxy_editor';
|
||||
|
||||
/** @var array */
|
||||
private $server;
|
||||
|
@ -89,6 +93,17 @@ class ServerSyncTool
|
|||
return $this->get($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @return HttpSocketResponseExtended
|
||||
* @throws HttpSocketHttpException
|
||||
* @throws HttpSocketJsonException
|
||||
*/
|
||||
public function filterEventIdsForPush(array $events)
|
||||
{
|
||||
return $this->post('/events/filterEventIdsForPush', $events);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $event
|
||||
* @return HttpSocketResponseExtended
|
||||
|
@ -164,6 +179,39 @@ class ServerSyncTool
|
|||
return $this->post('/attributes/restSearch.json', $rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $rules
|
||||
* @return HttpSocketResponseExtended
|
||||
* @throws HttpSocketHttpException
|
||||
* @throws HttpSocketJsonException
|
||||
*/
|
||||
public function galaxyClusterSearch(array $rules)
|
||||
{
|
||||
return $this->post('/galaxy_clusters/restSearch', $rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $galaxyClusterId Galaxy Cluster ID or UUID
|
||||
* @return HttpSocketResponseExtended
|
||||
* @throws HttpSocketHttpException
|
||||
*/
|
||||
public function fetchGalaxyCluster($galaxyClusterId)
|
||||
{
|
||||
return $this->get('/galaxy_clusters/view/' . $galaxyClusterId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cluster
|
||||
* @return HttpSocketResponseExtended
|
||||
* @throws HttpSocketHttpException
|
||||
* @throws HttpSocketJsonException
|
||||
*/
|
||||
public function pushGalaxyCluster(array $cluster)
|
||||
{
|
||||
$logMessage = "Pushing Galaxy Cluster #{$cluster['GalaxyCluster']['id']} to Server #{$this->serverId()}";
|
||||
return $this->post('/galaxies/pushCluster', [$cluster], $logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return HttpSocketResponseExtended
|
||||
|
@ -332,6 +380,12 @@ class ServerSyncTool
|
|||
case self::FEATURE_PROTECTED_EVENT:
|
||||
$version = explode('.', $info['version']);
|
||||
return $version[0] == 2 && $version[1] == 4 && $version[2] > 155;
|
||||
case self::FEATURE_EDIT_OF_GALAXY_CLUSTER:
|
||||
return isset($info['perm_galaxy_editor']);
|
||||
case self::PERM_SYNC:
|
||||
return isset($info['perm_sync']) && $info['perm_sync'];
|
||||
case self::PERM_GALAXY_EDITOR:
|
||||
return isset($info['perm_galaxy_editor']) && $info['perm_galaxy_editor'];
|
||||
default:
|
||||
throw new InvalidArgumentException("Invalid flag `$flag` provided");
|
||||
}
|
||||
|
@ -373,7 +427,7 @@ class ServerSyncTool
|
|||
private function post($url, $data, $logMessage = null)
|
||||
{
|
||||
$protectedMode = !empty($data['Event']['protected']);
|
||||
$data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$data = JsonTool::encode($data);
|
||||
|
||||
if ($logMessage && !empty(Configure::read('Security.sync_audit'))) {
|
||||
$pushLogEntry = sprintf(
|
||||
|
|
|
@ -192,6 +192,19 @@ class TmpFileTool
|
|||
return fstat($this->tmpfile)['size'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $algo
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function hash($algo)
|
||||
{
|
||||
$this->rewind();
|
||||
$hash = hash_init($algo);
|
||||
hash_update_stream($hash, $this->tmpfile);
|
||||
return hash_final($hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
|
||||
/**
|
||||
* WorkflowFormatConverterTool convert passed data into the MISP core format with these additional properties:
|
||||
* - Attributes are encapsulated in the Event they belong to as well as their object (if applicable)
|
||||
* - Events have an additional key `_AttributeFlattened` which combines both Attribute and ObjectAttribute in the same array
|
||||
* - Attributes have an additional key `_allTags` which group both AttributeTag and EventTag.
|
||||
* - Tags in this `_allTags` key have an additional flag `inherited` indicating if the tag has been propagated from the Event to the Attribute
|
||||
*/
|
||||
class WorkflowFormatConverterTool
|
||||
{
|
||||
private static $fakeSiteAdminUser = ['Role' => ['perm_site_admin' => true]];
|
||||
|
||||
public static function convert(array $data, $scope=''): array
|
||||
{
|
||||
if (empty($scope)) {
|
||||
$scope = self::__guessScopeFromData($data);
|
||||
}
|
||||
$converted = [];
|
||||
switch ($scope) {
|
||||
case 'event':
|
||||
$converted = self::__convertEvent($data);
|
||||
break;
|
||||
case 'attribute':
|
||||
$converted = self::__convertAttribute($data);
|
||||
break;
|
||||
case 'object':
|
||||
$converted = self::__convertObject($data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$converted = self::__includeFlattenedAttributes($converted);
|
||||
return $converted;
|
||||
}
|
||||
|
||||
private static function __convertEvent(array $event): array
|
||||
{
|
||||
$converted = [];
|
||||
$converted = JSONConverterTool::convert($event, false, true);
|
||||
return $converted;
|
||||
}
|
||||
|
||||
private static function __convertObject(array $object): array
|
||||
{
|
||||
$converted = [];
|
||||
$convertedObject = JSONConverterTool::convertObject($object, false, true);
|
||||
$convertedObject = ['Object' => $convertedObject['Object']];
|
||||
$converted = self::__encapsulateEntityWithEvent($convertedObject);
|
||||
return $converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* __convertAttribute Convert and clean an attribute. May also transform the attribute into an Object if applicable.
|
||||
* However, the object will not be full and will only contain the attribute
|
||||
*
|
||||
* @param array $attribute
|
||||
* @return array
|
||||
*/
|
||||
private static function __convertAttribute(array $attribute): array
|
||||
{
|
||||
$allTags = [];
|
||||
if (!empty($attribute['EventTag'])) {
|
||||
foreach ($attribute['AttributeTag'] as $attributeTag) {
|
||||
$attributeTag['Tag']['inherited'] = false;
|
||||
$allTags[] = $attributeTag['Tag'];
|
||||
}
|
||||
foreach ($attribute['EventTag'] as $eventTag) {
|
||||
$eventTag['Tag']['inherited'] = true;
|
||||
$allTags[] = $eventTag['Tag'];
|
||||
}
|
||||
}
|
||||
$convertedAttribute = JSONConverterTool::convertAttribute($attribute, true);
|
||||
$convertedAttribute['Attribute']['_allTags'] = $allTags;
|
||||
if ($convertedAttribute['Attribute']['object_id'] != 0) {
|
||||
$objectModel = ClassRegistry::init('MispObject');
|
||||
$object = $objectModel->fetchObjectSimple(self::$fakeSiteAdminUser, [
|
||||
'conditions' => [
|
||||
'Object.id' => $convertedAttribute['Attribute']['object_id'],
|
||||
],
|
||||
]);
|
||||
if (!empty($object)) {
|
||||
$object = $object[0]['Object'];
|
||||
$object['Attribute'][] = $convertedAttribute['Attribute'];
|
||||
$convertedAttribute = ['Object' => $object];
|
||||
} else {
|
||||
$convertedAttribute = ['Attribute' => $convertedAttribute['Attribute']];
|
||||
}
|
||||
} else {
|
||||
$convertedAttribute = ['Attribute' => $convertedAttribute['Attribute']];
|
||||
}
|
||||
$converted = self::__encapsulateEntityWithEvent($convertedAttribute);
|
||||
return $converted;
|
||||
}
|
||||
|
||||
private static function __encapsulateEntityWithEvent(array $data): array
|
||||
{
|
||||
$eventModel = ClassRegistry::init('Event');
|
||||
$event = $eventModel->fetchSimpleEvent(self::$fakeSiteAdminUser, $data['Attribute']['event_id'] ?? $data['Object']['event_id'], [
|
||||
'contain' => [
|
||||
'EventTag' => ['Tag']
|
||||
]
|
||||
]);
|
||||
if (empty($event)) {
|
||||
return [];
|
||||
}
|
||||
$event = self::__convertEvent($event);
|
||||
$event = $event['Event'];
|
||||
reset($data);
|
||||
$entityType = key($data);
|
||||
$event[$entityType][] = $data[$entityType];
|
||||
return ['Event' => $event];
|
||||
}
|
||||
|
||||
private static function __includeFlattenedAttributes(array $event): array
|
||||
{
|
||||
$attributes = $event['Event']['Attribute'] ?? [];
|
||||
$objectAttributes = Hash::extract($event['Event']['Object'] ?? [], '{n}.Attribute.{n}');
|
||||
$event['Event']['_AttributeFlattened'] = array_merge($attributes, $objectAttributes);
|
||||
return $event;
|
||||
}
|
||||
|
||||
private static function __guessScopeFromData(array $data)
|
||||
{
|
||||
if (isset($data['Object']) && !isset($data['Attribute'])) {
|
||||
return 'object';
|
||||
}
|
||||
if (!isset($data['Attribute'])) {
|
||||
return 'event';
|
||||
}
|
||||
if (!isset($data['Event'])) {
|
||||
return 'attribute';
|
||||
}
|
||||
if (isset($data['RelatedEvent']) || isset($data['Orgc']) || isset($data['Org'])) {
|
||||
return 'event';
|
||||
}
|
||||
if (!empty($data['Attribute'])) {
|
||||
return 'attribute';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,421 @@
|
|||
<?php
|
||||
|
||||
class CyclicGraphException extends Exception {}
|
||||
|
||||
class GraphUtil
|
||||
{
|
||||
public function __construct($graphData)
|
||||
{
|
||||
$this->graph = $graphData;
|
||||
$this->numberNodes = count($this->graph);
|
||||
$this->edgeList = $this->_buildEdgeList($graphData);
|
||||
$this->properties = [];
|
||||
}
|
||||
|
||||
private function _buildEdgeList($graphData): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($graphData as $node) {
|
||||
$list[(int)$node['id']] = [];
|
||||
foreach (($node['outputs'] ?? []) as $output_id => $outputs) {
|
||||
foreach ($outputs as $connections) {
|
||||
foreach ($connections as $connection) {
|
||||
$list[$node['id']][] = (int)$connection['node'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
private function _DFSUtil($node_id, &$color): bool
|
||||
{
|
||||
$color[$node_id] = 'GRAY';
|
||||
foreach ($this->edgeList[$node_id] as $i) {
|
||||
if ($color[$i] == 'GRAY') {
|
||||
$this->loopNode = $i;
|
||||
$this->properties[] = [$node_id, $i, __('Cycle')];
|
||||
return true;
|
||||
}
|
||||
if ($color[$i] == 'WHITE' && $this->_DFSUtil($i, $color)) {
|
||||
if (!is_null($this->loopNode)) {
|
||||
$this->properties[] = [$node_id, $i, __('Cycle')];
|
||||
if ($this->loopNode == $node_id) {
|
||||
$this->loopNode = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$color[$node_id] = 'BLACK';
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* isCyclic Return is the graph is cyclic, so if it contains a cycle.
|
||||
*
|
||||
* A directed graph G is acyclic if and only if a depth-first search of G yields no back edges.
|
||||
* Introduction to Algorithms, third edition By Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function isCyclic(): array
|
||||
{
|
||||
$this->properties = [];
|
||||
$color = [];
|
||||
foreach (array_keys($this->edgeList) as $node_id) {
|
||||
$color[$node_id] = 'WHITE';
|
||||
}
|
||||
|
||||
$this->loopNode = null;
|
||||
foreach (array_keys($this->edgeList) as $node_id) {
|
||||
if ($color[$node_id] == 'WHITE') {
|
||||
if ($this->_DFSUtil($node_id, $color)) {
|
||||
return [true, $this->properties];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [false, []];
|
||||
}
|
||||
|
||||
public function hasMultipleOutputConnection(): array
|
||||
{
|
||||
$edges = [];
|
||||
foreach ($this->graph as $node) {
|
||||
foreach (($node['outputs'] ?? []) as $output_id => $outputs) {
|
||||
foreach ($outputs as $connections) {
|
||||
if (count($connections) > 1 && empty($node['data']['multiple_output_connection'])) {
|
||||
$edges[$node['id']] = array_map(function ($connection) {
|
||||
return intval($connection['node']);
|
||||
}, $connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [!empty($edges), $edges];
|
||||
}
|
||||
}
|
||||
|
||||
class GraphWalker
|
||||
{
|
||||
private $graph;
|
||||
private $WorkflowModel;
|
||||
private $startNodeID;
|
||||
private $for_path;
|
||||
private $cursor;
|
||||
|
||||
const PATH_TYPE_BLOCKING = 'blocking';
|
||||
const PATH_TYPE_NON_BLOCKING = 'non-blocking';
|
||||
const PATH_TYPE_INCLUDE_LOGIC = 'include-logic';
|
||||
const ALLOWED_PATH_TYPES = [GraphWalker::PATH_TYPE_BLOCKING, GraphWalker::PATH_TYPE_NON_BLOCKING, GraphWalker::PATH_TYPE_INCLUDE_LOGIC];
|
||||
|
||||
public function __construct(array $graphData, $WorkflowModel, $startNodeID, $for_path=null)
|
||||
{
|
||||
$this->graph = $graphData;
|
||||
$this->WorkflowModel = $WorkflowModel;
|
||||
$this->startNodeID = $startNodeID;
|
||||
$this->for_path = $for_path;
|
||||
$this->triggersByNodeID = [];
|
||||
if (empty($this->graph[$startNodeID])) {
|
||||
throw new Exception(__('Could not find start node %s', $startNodeID));
|
||||
}
|
||||
$this->cursor = $startNodeID;
|
||||
}
|
||||
|
||||
private function getModuleClass($node)
|
||||
{
|
||||
$moduleClass = $this->loaded_classes[$node['data']['module_type']][$node['data']['id']] ?? null;
|
||||
return $moduleClass;
|
||||
}
|
||||
|
||||
private function _getPathType($node_id, $path_type)
|
||||
{
|
||||
$node = $this->graph[$node_id];
|
||||
if ($node['data']['module_type'] == 'logic' && $node['data']['id'] == 'concurrent-task') {
|
||||
return self::PATH_TYPE_NON_BLOCKING;
|
||||
}
|
||||
return $path_type;
|
||||
}
|
||||
|
||||
|
||||
private function _evaluateOutputs($node, WorkflowRoamingData $roamingData, $shouldExecuteLogicNode=true)
|
||||
{
|
||||
$allowed_outputs = ($node['outputs'] ?? []);
|
||||
if ($shouldExecuteLogicNode && $node['data']['module_type'] == 'logic') {
|
||||
$allowed_outputs = $this->_executeModuleLogic($node, $roamingData);
|
||||
}
|
||||
return $allowed_outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* _executeModuleLogic function
|
||||
*
|
||||
* @param array $node
|
||||
* @return array
|
||||
*/
|
||||
private function _executeModuleLogic(array $node, WorkflowRoamingData $roamingData): array
|
||||
{
|
||||
$outputs = ($node['outputs'] ?? []);
|
||||
if ($node['data']['id'] == 'if') {
|
||||
$useFirstOutput = $this->_evaluateIFCondition($node, $roamingData);
|
||||
return $useFirstOutput ? ['output_1' => $outputs['output_1']] : ['output_2' => $outputs['output_2']];
|
||||
} else if ($node['data']['id'] == 'concurrent-task') {
|
||||
$this->_evaluateConcurrentTask($node, $roamingData, $outputs['output_1']);
|
||||
return ['output_1' => []];
|
||||
} else {
|
||||
$useFirstOutput = $this->_evaluateCustomLogicCondition($node, $roamingData);
|
||||
return $useFirstOutput ? ['output_1' => $outputs['output_1']] : ['output_2' => $outputs['output_2']];
|
||||
}
|
||||
return $outputs;
|
||||
}
|
||||
|
||||
private function _evaluateIFCondition($node, WorkflowRoamingData $roamingData): bool
|
||||
{
|
||||
$result = $this->WorkflowModel->executeNode($node, $roamingData);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function _evaluateCustomLogicCondition($node, WorkflowRoamingData $roamingData): bool
|
||||
{
|
||||
$result = $this->WorkflowModel->executeNode($node, $roamingData);
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function _evaluateConcurrentTask($concurrent_node, WorkflowRoamingData $roamingData, array $connections)
|
||||
{
|
||||
foreach ($connections['connections'] as $connection) {
|
||||
$node_id_to_exec = (int)$connection['node'];
|
||||
$data = $roamingData->getData();
|
||||
$data['__node_id_to_exec'] = $node_id_to_exec;
|
||||
$data = $roamingData->setData($data);
|
||||
$this->WorkflowModel->executeNode($concurrent_node, $roamingData);
|
||||
}
|
||||
}
|
||||
|
||||
public function _walk($node_id, $path_type=null, array $path_list=[], WorkflowRoamingData $roamingData)
|
||||
{
|
||||
$this->cursor = $node_id;
|
||||
$node = $this->graph[$node_id];
|
||||
$shouldExecuteLogicNode = $path_type != self::PATH_TYPE_INCLUDE_LOGIC;
|
||||
if (!$shouldExecuteLogicNode) {
|
||||
yield ['node' => $node, 'path_type' => $path_type, 'path_list' => $path_list];
|
||||
} else if ($node['data']['module_type'] != 'trigger' && $node['data']['module_type'] != 'logic') { // trigger and logic nodes should not be returned as they are "control" nodes
|
||||
yield ['node' => $node, 'path_type' => $path_type, 'path_list' => $path_list];
|
||||
}
|
||||
$allowedOutputs = $this->_evaluateOutputs($node, $roamingData, $shouldExecuteLogicNode);
|
||||
foreach ($allowedOutputs as $output_id => $outputs) {
|
||||
if ($shouldExecuteLogicNode) {
|
||||
$path_type = $this->_getPathType($node_id, $path_type);
|
||||
}
|
||||
if (is_null($this->for_path) || $path_type == $this->for_path) {
|
||||
foreach ($outputs as $connections) {
|
||||
foreach ($connections as $connection_id => $connection) {
|
||||
$next_node_id = (int)$connection['node'];
|
||||
$current_path = $this->__genPathList($node_id, $output_id, $connection_id, $next_node_id);
|
||||
if (in_array($current_path, $path_list)) { // avoid loops
|
||||
continue;
|
||||
}
|
||||
$next_path_list = $path_list;
|
||||
$next_path_list[] = $current_path;
|
||||
yield from $this->_walk($next_node_id, $path_type, $next_path_list, $roamingData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function walk(WorkflowRoamingData $roamingData)
|
||||
{
|
||||
return $this->_walk($this->cursor, $this->for_path, [], $roamingData);
|
||||
}
|
||||
|
||||
private function __genPathList($source_id, $output_id, $connection_id, $next_node_id)
|
||||
{
|
||||
return sprintf('%s:%s:%s:%s', $source_id, $output_id, $connection_id, $next_node_id);
|
||||
}
|
||||
|
||||
public static function parsePathList($pathList): array
|
||||
{
|
||||
return array_map(function($path) {
|
||||
$split = explode(':', $path);
|
||||
return [
|
||||
'source_id' => $split[0],
|
||||
'output_id' => $split[1],
|
||||
'connection_id' => $split[2],
|
||||
'next_node_id' => $split[3],
|
||||
];
|
||||
}, $pathList);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowRoamingData
|
||||
{
|
||||
private $workflow_user;
|
||||
private $data;
|
||||
private $workflow;
|
||||
private $current_node;
|
||||
|
||||
public function __construct(array $workflow_user, array $data, array $workflow, int $current_node)
|
||||
{
|
||||
$this->workflow_user = $workflow_user;
|
||||
$this->data = $data;
|
||||
$this->workflow = $workflow;
|
||||
$this->current_node = $current_node;
|
||||
}
|
||||
|
||||
public function getUser(): array
|
||||
{
|
||||
return $this->workflow_user;
|
||||
}
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getWorkflow(): array
|
||||
{
|
||||
return $this->workflow;
|
||||
}
|
||||
|
||||
public function getCurrentNode(): int
|
||||
{
|
||||
return $this->current_node;
|
||||
}
|
||||
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function setCurrentNode(int $current_node)
|
||||
{
|
||||
$this->current_node = $current_node;
|
||||
}
|
||||
}
|
||||
|
||||
class WorkflowGraphTool
|
||||
{
|
||||
/**
|
||||
* extractTriggerFromWorkflow Return the trigger id (or full module) that are specified in the workflow
|
||||
*
|
||||
* @param array $workflow
|
||||
* @param bool $fullNode
|
||||
* @return int|array|null
|
||||
*/
|
||||
public static function extractTriggerFromWorkflow(array $graphData, bool $fullNode = false)
|
||||
{
|
||||
$triggers = self::extractTriggersFromWorkflow($graphData, $fullNode);
|
||||
if (empty($triggers)) {
|
||||
return null;
|
||||
}
|
||||
$node = $triggers[0];
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* extractTriggersFromWorkflow Return the list of triggers id (or full module) that are specified in the workflow
|
||||
*
|
||||
* @param array $workflow
|
||||
* @param bool $fullNode
|
||||
* @return array
|
||||
*/
|
||||
public static function extractTriggersFromWorkflow(array $graphData, bool $fullNode = false): array
|
||||
{
|
||||
$triggers = [];
|
||||
foreach ($graphData as $node) {
|
||||
if ($node['data']['module_type'] == 'trigger') {
|
||||
if (!empty($fullNode)) {
|
||||
$triggers[] = $node;
|
||||
} else {
|
||||
$triggers[] = $node['data']['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* extractConcurrentTasksFromWorkflow Return the list of concurrent-tasks's id (or full module) that are included in the workflow
|
||||
*
|
||||
* @param array $workflow
|
||||
* @param bool $fullNode
|
||||
* @return array
|
||||
*/
|
||||
public static function extractConcurrentTasksFromWorkflow(array $graphData, bool $fullNode = false): array
|
||||
{
|
||||
$nodes = [];
|
||||
foreach ($graphData as $node) {
|
||||
if ($node['data']['module_type'] == 'logic' && $node['data']['id'] == 'concurrent-task') {
|
||||
if (!empty($fullNode)) {
|
||||
$nodes[] = $node;
|
||||
} else {
|
||||
$nodes[] = $node['data']['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* isAcyclic Return if the graph contains a cycle
|
||||
*
|
||||
* @param array $graphData
|
||||
* @param array $cycles Get a list of cycle
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAcyclic(array $graphData, array &$cycles=[]): bool
|
||||
{
|
||||
$graphUtil = new GraphUtil($graphData);
|
||||
$result = $graphUtil->isCyclic();
|
||||
$isCyclic = $result[0];
|
||||
$cycles = $result[1];
|
||||
return !$isCyclic;
|
||||
}
|
||||
|
||||
/**
|
||||
* hasMultipleOutputConnection Return if the graph has multiple connection from a node output
|
||||
*
|
||||
* @param array $graphData
|
||||
* @param array $edges Get a list of edges from the same output
|
||||
* @return boolean
|
||||
*/
|
||||
public static function hasMultipleOutputConnection(array $graphData, array &$edges=[]): bool
|
||||
{
|
||||
$graphUtil = new GraphUtil($graphData);
|
||||
$result = $graphUtil->hasMultipleOutputConnection();
|
||||
$hasMultipleOutputConnection = $result[0];
|
||||
$edges = $result[1];
|
||||
return $hasMultipleOutputConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented getNodeIdForTrigger
|
||||
*
|
||||
* @param array $graphData
|
||||
* @param string $trigger_id
|
||||
* @return integer Return the ID of the node for the provided trigger and -1 if no nodes with this id was found.
|
||||
*/
|
||||
public static function getNodeIdForTrigger(array $graphData, $trigger_id): int
|
||||
{
|
||||
$trigger_node = WorkflowGraphTool::extractTriggerFromWorkflow($graphData, true);
|
||||
if ($trigger_node['data']['id'] == $trigger_id) {
|
||||
return $trigger_node['id'];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static function getRoamingData(array $user=[], array $data=[], array $workflow=[], int $node_id=-1)
|
||||
{
|
||||
return new WorkflowRoamingData($user, $data, $workflow, $node_id);
|
||||
}
|
||||
|
||||
public static function getWalkerIterator(array $graphData, $WorkflowModel, $startNodeID, $path_type=null, WorkflowRoamingData $roamingData)
|
||||
{
|
||||
if (!in_array($path_type, GraphWalker::ALLOWED_PATH_TYPES)) {
|
||||
return [];
|
||||
}
|
||||
$graphWalker = new GraphWalker($graphData, $WorkflowModel, $startNodeID, $path_type);
|
||||
return $graphWalker->walk($roamingData);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
include_once APP . 'Model/WorkflowModules/WorkflowBaseModule.php';
|
||||
|
||||
class Module_blueprint_action_module extends WorkflowBaseActionModule
|
||||
{
|
||||
public $blocking = false;
|
||||
public $disabled = true;
|
||||
public $id = 'blueprint-action-module';
|
||||
public $name = 'Blueprint action module';
|
||||
public $description = 'Lorem ipsum dolor, sit amet consectetur adipisicing elit.';
|
||||
public $icon = 'shapes';
|
||||
public $inputs = 1;
|
||||
public $outputs = 1;
|
||||
public $params = [];
|
||||
|
||||
public function exec(array $node, WorkflowRoamingData $roamingData, array &$errors = []): bool
|
||||
{
|
||||
parent::exec($node, $roamingData, $errors);
|
||||
// If $this->blocking == true, returning `false` will stop the execution.
|
||||
$errors[] = __('Execution stopped');
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
include_once APP . 'Model/WorkflowModules/WorkflowBaseModule.php';
|
||||
|
||||
class Module_blueprint_logic_module extends WorkflowBaseLogicModule
|
||||
{
|
||||
public $disabled = true;
|
||||
public $id = 'blueprint-logic-module';
|
||||
public $name = 'Blueprint logic module';
|
||||
public $description = 'Lorem ipsum dolor, sit amet consectetur adipisicing elit.';
|
||||
public $icon = 'shapes';
|
||||
public $inputs = 1;
|
||||
public $outputs = 2;
|
||||
public $params = [];
|
||||
|
||||
public function exec(array $node, WorkflowRoamingData $roamingData, array &$errors = []): bool
|
||||
{
|
||||
parent::exec($node, $roamingData, $errors);
|
||||
$params = $this->getParamsWithValues($node);
|
||||
$data = $roamingData->getData();
|
||||
// Returning true will make the execution flow take the first output of this module. Otherwise, the second output will be used.
|
||||
return true;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:10\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Czech\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1476,13 +1476,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1492,7 +1492,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2363,100 +2363,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4579,7 +4579,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr "Base64 kódovaný certifikát"
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5985,7 +5985,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8037,7 +8037,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:10\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Danish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1465,13 +1465,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1481,7 +1481,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2348,100 +2348,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4564,7 +4564,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5970,7 +5970,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8020,7 +8020,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:10\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: German\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -17,38 +17,38 @@ msgstr ""
|
|||
|
||||
#: Console/Command/APIShell.php:15
|
||||
msgid "The following API documentation is derived directly from [MISP RestResponseComponent's source code](app/Controller/Component/RestResponseComponent.php)"
|
||||
msgstr ""
|
||||
msgstr "Die folgende API-Dokumentation wird direkt von [MISP RestResponseComponents source code](app/Controller/Component/RestResponseComponent.php) abgeleitet"
|
||||
|
||||
#: Console/Command/APIShell.php:46
|
||||
msgid "Successfully saved API documentation"
|
||||
msgstr ""
|
||||
msgstr "API-Dokumentation erfolgreich gespeichert"
|
||||
|
||||
#: Console/Command/APIShell.php:48
|
||||
msgid "Could not save API documentation"
|
||||
msgstr ""
|
||||
msgstr "API Dokumentation konnte nicht gespeichert werden"
|
||||
|
||||
#: Console/Command/APIShell.php:59
|
||||
msgid "URL Parameters"
|
||||
msgstr ""
|
||||
msgstr "URL Parameter"
|
||||
|
||||
#: Console/Command/APIShell.php:63
|
||||
#: View/DecayingModel/index.ctp:84
|
||||
#: View/DecayingModel/view.ctp:40
|
||||
msgid "Parameters"
|
||||
msgstr ""
|
||||
msgstr "Parameter"
|
||||
|
||||
#: Console/Command/APIShell.php:65
|
||||
#: View/Elements/templateElements/templateRowAttribute.ctp:59
|
||||
msgid "Mandatory"
|
||||
msgstr ""
|
||||
msgstr "Verpflichtend"
|
||||
|
||||
#: Console/Command/APIShell.php:70
|
||||
msgid "Optional"
|
||||
msgstr ""
|
||||
msgstr "Optional"
|
||||
|
||||
#: Console/Command/APIShell.php:79
|
||||
msgid "API Documentation"
|
||||
msgstr ""
|
||||
msgstr "API Dokumentation"
|
||||
|
||||
#: Console/Command/APIShell.php:88
|
||||
#: View/Allowedlists/index.ctp:19
|
||||
|
@ -191,31 +191,31 @@ msgstr "Aktualisieren Sie die JSON-Definitionen von MISP."
|
|||
|
||||
#: Console/Command/AdminShell.php:20
|
||||
msgid "Set setting in PHP config file."
|
||||
msgstr ""
|
||||
msgstr "Einstellung in der PHP-Konfigurationsdatei festlegen."
|
||||
|
||||
#: Console/Command/AdminShell.php:23
|
||||
msgid "Setting name"
|
||||
msgstr ""
|
||||
msgstr "Name der Einstellung"
|
||||
|
||||
#: Console/Command/AdminShell.php:24
|
||||
msgid "Setting value"
|
||||
msgstr ""
|
||||
msgstr "Einstellungswert"
|
||||
|
||||
#: Console/Command/AdminShell.php:43
|
||||
msgid "Set if MISP instance is live and accessible for users."
|
||||
msgstr ""
|
||||
msgstr "Legen Sie fest, ob MISP Instanz live und für Benutzer zugänglich ist."
|
||||
|
||||
#: Console/Command/AdminShell.php:46
|
||||
msgid "Set Live state"
|
||||
msgstr ""
|
||||
msgstr "Live-Status festlegen"
|
||||
|
||||
#: Console/Command/AdminShell.php:51
|
||||
msgid "Reencrypt encrypted values in database (authkeys and sensitive system settings)."
|
||||
msgstr ""
|
||||
msgstr "Verschlüssele verschlüsselte Werte in der Datenbank (authkeys und sensitive Systemeinstellungen)."
|
||||
|
||||
#: Console/Command/AdminShell.php:54
|
||||
msgid "Old key. If not provided, current key will be used."
|
||||
msgstr ""
|
||||
msgstr "Alter Schlüssel. Wenn nicht angegeben wird, wird der aktuelle Schlüssel verwendet."
|
||||
|
||||
#: Console/Command/AdminShell.php:55
|
||||
msgid "New key. If not provided, new key will be generated."
|
||||
|
@ -1465,13 +1465,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1481,7 +1481,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2348,100 +2348,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4564,7 +4564,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5970,7 +5970,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8020,7 +8020,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:10\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -21,11 +21,11 @@ msgstr ""
|
|||
|
||||
#: Console/Command/APIShell.php:46
|
||||
msgid "Successfully saved API documentation"
|
||||
msgstr ""
|
||||
msgstr "Documentation de l'API enregistrée avec succès"
|
||||
|
||||
#: Console/Command/APIShell.php:48
|
||||
msgid "Could not save API documentation"
|
||||
msgstr ""
|
||||
msgstr "Impossible d'enregistrer la documentation de l'API"
|
||||
|
||||
#: Console/Command/APIShell.php:59
|
||||
msgid "URL Parameters"
|
||||
|
@ -48,7 +48,7 @@ msgstr "Facultatif"
|
|||
|
||||
#: Console/Command/APIShell.php:79
|
||||
msgid "API Documentation"
|
||||
msgstr ""
|
||||
msgstr "Documentation pour API"
|
||||
|
||||
#: Console/Command/APIShell.php:88
|
||||
#: View/Allowedlists/index.ctp:19
|
||||
|
@ -195,11 +195,11 @@ msgstr ""
|
|||
|
||||
#: Console/Command/AdminShell.php:23
|
||||
msgid "Setting name"
|
||||
msgstr ""
|
||||
msgstr "Nom du paramètre"
|
||||
|
||||
#: Console/Command/AdminShell.php:24
|
||||
msgid "Setting value"
|
||||
msgstr ""
|
||||
msgstr "Valeur de la configuration"
|
||||
|
||||
#: Console/Command/AdminShell.php:43
|
||||
msgid "Set if MISP instance is live and accessible for users."
|
||||
|
@ -1468,13 +1468,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1484,7 +1484,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2351,100 +2351,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr "JSON invalide"
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4567,7 +4567,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5973,7 +5973,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8023,7 +8023,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:08\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1466,13 +1466,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1482,7 +1482,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2349,100 +2349,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4565,7 +4565,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5971,7 +5971,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8021,7 +8021,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1460,13 +1460,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1476,7 +1476,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2341,100 +2341,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4557,7 +4557,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5963,7 +5963,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8012,7 +8012,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Korean\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -21,34 +21,34 @@ msgstr ""
|
|||
|
||||
#: Console/Command/APIShell.php:46
|
||||
msgid "Successfully saved API documentation"
|
||||
msgstr ""
|
||||
msgstr "API 설명서를 저장함"
|
||||
|
||||
#: Console/Command/APIShell.php:48
|
||||
msgid "Could not save API documentation"
|
||||
msgstr ""
|
||||
msgstr "API 설명서를 저장할 수 없음"
|
||||
|
||||
#: Console/Command/APIShell.php:59
|
||||
msgid "URL Parameters"
|
||||
msgstr ""
|
||||
msgstr "URL 매개변수"
|
||||
|
||||
#: Console/Command/APIShell.php:63
|
||||
#: View/DecayingModel/index.ctp:84
|
||||
#: View/DecayingModel/view.ctp:40
|
||||
msgid "Parameters"
|
||||
msgstr ""
|
||||
msgstr "매개변수"
|
||||
|
||||
#: Console/Command/APIShell.php:65
|
||||
#: View/Elements/templateElements/templateRowAttribute.ctp:59
|
||||
msgid "Mandatory"
|
||||
msgstr ""
|
||||
msgstr "필수 항목"
|
||||
|
||||
#: Console/Command/APIShell.php:70
|
||||
msgid "Optional"
|
||||
msgstr ""
|
||||
msgstr "옵션"
|
||||
|
||||
#: Console/Command/APIShell.php:79
|
||||
msgid "API Documentation"
|
||||
msgstr ""
|
||||
msgstr "API 설명서"
|
||||
|
||||
#: Console/Command/APIShell.php:88
|
||||
#: View/Allowedlists/index.ctp:19
|
||||
|
@ -104,7 +104,7 @@ msgstr ""
|
|||
#: View/Warninglists/index.ctp:56
|
||||
#: View/Warninglists/view.ctp:6
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
msgstr "이름"
|
||||
|
||||
#: Console/Command/APIShell.php:88
|
||||
#: View/Attributes/index.ctp:42
|
||||
|
@ -135,7 +135,7 @@ msgstr ""
|
|||
#: View/Warninglists/index.ctp:80
|
||||
#: View/Warninglists/view.ctp:10
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
msgstr "유형"
|
||||
|
||||
#: Console/Command/APIShell.php:88
|
||||
#: View/Cerebrates/index.ctp:25
|
||||
|
@ -183,7 +183,7 @@ msgstr ""
|
|||
#: View/Warninglists/index.ctp:67
|
||||
#: View/Warninglists/view.ctp:7
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
msgstr "설명"
|
||||
|
||||
#: Console/Command/AdminShell.php:17
|
||||
msgid "Update the JSON definitions of MISP."
|
||||
|
@ -336,7 +336,7 @@ msgstr ""
|
|||
#: Controller/UsersController.php:1357;2402
|
||||
#: Model/Dashboard.php:129
|
||||
msgid "Invalid user."
|
||||
msgstr ""
|
||||
msgstr "올바르지 않은 사용자."
|
||||
|
||||
#: Console/Command/AdminShell.php:668
|
||||
msgid "User has to be a site admin."
|
||||
|
@ -345,7 +345,8 @@ msgstr ""
|
|||
#: Console/Command/AdminShell.php:692
|
||||
msgid "\n"
|
||||
"Error: %s\n"
|
||||
msgstr ""
|
||||
msgstr "\n"
|
||||
"오류: %s\n"
|
||||
|
||||
#: Console/Command/AdminShell.php:694
|
||||
msgid "%s events purged.\n"
|
||||
|
@ -391,11 +392,11 @@ msgstr ""
|
|||
|
||||
#: Console/Command/DevShell.php:45
|
||||
msgid "Something went wrong."
|
||||
msgstr ""
|
||||
msgstr "알 수 없는 오류가 발생했습니다."
|
||||
|
||||
#: Console/Command/EventShell.php:23
|
||||
msgid "Import event from file into MISP."
|
||||
msgstr ""
|
||||
msgstr "파일에서 MISP로 이벤트를 가져옵니다."
|
||||
|
||||
#: Console/Command/EventShell.php:26
|
||||
msgid "User ID that will owner of uploaded event."
|
||||
|
@ -407,7 +408,7 @@ msgstr ""
|
|||
|
||||
#: Console/Command/EventShell.php:36
|
||||
msgid "Generate event notification email in EML format."
|
||||
msgstr ""
|
||||
msgstr "EML 형식으로 이벤트 알림 이메일을 생성합니다."
|
||||
|
||||
#: Console/Command/EventShell.php:39
|
||||
#: Controller/EventsController.php:1126
|
||||
|
@ -419,19 +420,19 @@ msgstr ""
|
|||
#: View/ShadowAttributes/index.ctp:40
|
||||
#: View/Sightings/ajax/list_sightings.ctp:13
|
||||
msgid "Event ID"
|
||||
msgstr ""
|
||||
msgstr "이벤트 ID"
|
||||
|
||||
#: Console/Command/EventShell.php:40
|
||||
msgid "User ID"
|
||||
msgstr ""
|
||||
msgstr "사용자 ID"
|
||||
|
||||
#: Console/Command/EventShell.php:45
|
||||
msgid "Show duplicate tags"
|
||||
msgstr ""
|
||||
msgstr "중복된 태그 표시"
|
||||
|
||||
#: Console/Command/EventShell.php:48
|
||||
msgid "Merge tags"
|
||||
msgstr ""
|
||||
msgstr "태그 병합"
|
||||
|
||||
#: Console/Command/EventShell.php:51
|
||||
msgid "Source tag ID or name. Source tag will be deleted."
|
||||
|
@ -443,7 +444,7 @@ msgstr ""
|
|||
|
||||
#: Console/Command/EventShell.php:106
|
||||
msgid "%s attribute or event tags changed"
|
||||
msgstr ""
|
||||
msgstr "%s 속성 또는 이벤트 태그가 변경되었습니다."
|
||||
|
||||
#: Console/Command/EventShell.php:125
|
||||
#: Controller/AttributesController.php:112;1186;1258;1389
|
||||
|
@ -457,7 +458,7 @@ msgstr "유효하지 않은 이벤트"
|
|||
|
||||
#: Console/Command/EventShell.php:593
|
||||
msgid "Recovering event %s"
|
||||
msgstr ""
|
||||
msgstr "이벤트 %s 가 복구 중입니다."
|
||||
|
||||
#: Console/Command/EventShell.php:598
|
||||
#: Controller/EventsController.php:5758
|
||||
|
@ -471,7 +472,7 @@ msgstr ""
|
|||
#: Console/Command/EventShell.php:656
|
||||
#: Model/Job.php:156
|
||||
msgid "Job done."
|
||||
msgstr ""
|
||||
msgstr "작업 완료."
|
||||
|
||||
#: Console/Command/LogShell.php:16
|
||||
msgid "Show statistics from audit logs."
|
||||
|
@ -487,27 +488,27 @@ msgstr ""
|
|||
|
||||
#: Console/Command/LogShell.php:25
|
||||
msgid "Path to output file"
|
||||
msgstr ""
|
||||
msgstr "출력 파일 경로"
|
||||
|
||||
#: Console/Command/LogShell.php:106;130
|
||||
msgid "Count:"
|
||||
msgstr ""
|
||||
msgstr "수:"
|
||||
|
||||
#: Console/Command/LogShell.php:107;131
|
||||
msgid "First:"
|
||||
msgstr ""
|
||||
msgstr "첫번째:"
|
||||
|
||||
#: Console/Command/LogShell.php:108;132
|
||||
msgid "Last:"
|
||||
msgstr ""
|
||||
msgstr "마지막:"
|
||||
|
||||
#: Console/Command/LogShell.php:111;135
|
||||
msgid "Data size:"
|
||||
msgstr ""
|
||||
msgstr "데이터 크기:"
|
||||
|
||||
#: Console/Command/LogShell.php:112;136
|
||||
msgid "Index size:"
|
||||
msgstr ""
|
||||
msgstr "색인 크기:"
|
||||
|
||||
#: Console/Command/LogShell.php:113;137
|
||||
msgid "Reclaimable size:"
|
||||
|
@ -515,15 +516,15 @@ msgstr ""
|
|||
|
||||
#: Console/Command/LogShell.php:146
|
||||
msgid "Compressed items:"
|
||||
msgstr ""
|
||||
msgstr "압축된 항목:"
|
||||
|
||||
#: Console/Command/LogShell.php:147
|
||||
msgid "Uncompressed size:"
|
||||
msgstr ""
|
||||
msgstr "압축해제된 크기:"
|
||||
|
||||
#: Console/Command/LogShell.php:148
|
||||
msgid "Compressed size:"
|
||||
msgstr ""
|
||||
msgstr "압축된 크기:"
|
||||
|
||||
#: Console/Command/PasswordShell.php:47
|
||||
msgid "override password change"
|
||||
|
@ -573,7 +574,7 @@ msgstr ""
|
|||
|
||||
#: Console/Command/StatisticsShell.php:250
|
||||
msgid "%s: %s %s%s"
|
||||
msgstr ""
|
||||
msgstr "%s: %s %s%s"
|
||||
|
||||
#: Console/Command/TrainingShell.php:682
|
||||
msgid "verbose mode"
|
||||
|
@ -605,7 +606,7 @@ msgstr ""
|
|||
|
||||
#: Console/Command/UserShell.php:34
|
||||
msgid "Immediately block user."
|
||||
msgstr ""
|
||||
msgstr "사용자 즉시 차단."
|
||||
|
||||
#: Console/Command/UserShell.php:37;45;53;65;73
|
||||
msgid "User ID or e-mail address."
|
||||
|
@ -613,7 +614,7 @@ msgstr ""
|
|||
|
||||
#: Console/Command/UserShell.php:42
|
||||
msgid "Unblock blocked user."
|
||||
msgstr ""
|
||||
msgstr "차단된 사용자 차단해제."
|
||||
|
||||
#: Console/Command/UserShell.php:50
|
||||
msgid "Change user password."
|
||||
|
@ -977,7 +978,7 @@ msgstr[0] ""
|
|||
#: View/TagCollections/import.ctp:20
|
||||
#: View/Users/admin_filter_user_index.ctp:62
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "추가"
|
||||
|
||||
#: Controller/AuditLogsController.php:76;118
|
||||
#: View/DecayingModel/decaying_tool.ctp:137
|
||||
|
@ -1030,11 +1031,11 @@ msgstr ""
|
|||
#: View/Users/admin_index.ctp:269
|
||||
#: View/Warninglists/index.ctp:165
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
msgstr "삭제"
|
||||
|
||||
#: Controller/AuditLogsController.php:79;121
|
||||
msgid "Undelete"
|
||||
msgstr ""
|
||||
msgstr "삭제 취소"
|
||||
|
||||
#: Controller/AuditLogsController.php:80;81;122
|
||||
#: Controller/EventsController.php:1127
|
||||
|
@ -1042,7 +1043,7 @@ msgstr ""
|
|||
#: View/Feeds/index.ctp:192
|
||||
#: View/Taxonomies/ajax/taxonomy_tags.ctp:52
|
||||
msgid "Tag"
|
||||
msgstr ""
|
||||
msgstr "태그"
|
||||
|
||||
#: Controller/AuditLogsController.php:82;83;123
|
||||
#: View/Elements/ajaxAttributeTags.ctp:29
|
||||
|
@ -1076,7 +1077,7 @@ msgstr ""
|
|||
#: Controller/AuditLogsController.php:132
|
||||
#: View/AuditLogs/admin_index.ctp:2
|
||||
msgid "Audit logs"
|
||||
msgstr ""
|
||||
msgstr "감사 로그"
|
||||
|
||||
#: Controller/AuditLogsController.php:185
|
||||
#: View/AuditLogs/event_index.ctp:2
|
||||
|
@ -1153,15 +1154,15 @@ msgstr ""
|
|||
#: View/Events/export.ctp:115;144
|
||||
#: View/Galaxies/export.ctp:45
|
||||
msgid "Download"
|
||||
msgstr ""
|
||||
msgstr "다운로드"
|
||||
|
||||
#: Controller/CerebratesController.php:301
|
||||
msgid "Sharing Group downloaded."
|
||||
msgstr ""
|
||||
msgstr "공유 그룹이 다운로드되었습니다."
|
||||
|
||||
#: Controller/CerebratesController.php:309
|
||||
msgid "Download sharing group information"
|
||||
msgstr ""
|
||||
msgstr "공유 그룹 정보 다운로드"
|
||||
|
||||
#: Controller/CerebratesController.php:310
|
||||
msgid "Are you sure you want to download and add / update the remote sharing group?"
|
||||
|
@ -1169,7 +1170,7 @@ msgstr ""
|
|||
|
||||
#: Controller/CommunitiesController.php:150
|
||||
msgid "Request sent."
|
||||
msgstr ""
|
||||
msgstr "요청이 전송되었습니다."
|
||||
|
||||
#: Controller/CommunitiesController.php:150
|
||||
msgid "Something went wrong and the request could not be sent."
|
||||
|
@ -1460,13 +1461,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1476,7 +1477,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -1752,7 +1753,7 @@ msgstr ""
|
|||
|
||||
#: Controller/EventsController.php:2256
|
||||
msgid "No file was uploaded."
|
||||
msgstr ""
|
||||
msgstr "업로드된 파일이 없습니다."
|
||||
|
||||
#: Controller/EventsController.php:2265
|
||||
msgid "You may only upload MISP XML or MISP JSON files."
|
||||
|
@ -1884,11 +1885,11 @@ msgstr "잘못된 이벤트 또는 권한이 없습니다."
|
|||
|
||||
#: Controller/EventsController.php:3501
|
||||
msgid "Nothing to add."
|
||||
msgstr ""
|
||||
msgstr "추가할 사항이 없습니다."
|
||||
|
||||
#: Controller/EventsController.php:3517
|
||||
msgid "Tag not found."
|
||||
msgstr ""
|
||||
msgstr "태그를 찾을 수 없습니다."
|
||||
|
||||
#: Controller/EventsController.php:3528
|
||||
msgid "Tag is already attached to this event."
|
||||
|
@ -1901,7 +1902,7 @@ msgstr ""
|
|||
#: Controller/EventsController.php:3546
|
||||
#: Controller/TagsController.php:843
|
||||
msgid "Invalid Tag. This tag can only be set as a local tag."
|
||||
msgstr ""
|
||||
msgstr "잘못된 태그입니다. 이 태그는 로컬 태그로만 설정할 수 있습니다."
|
||||
|
||||
#: Controller/EventsController.php:3587
|
||||
msgid ", but %s could not be added: %s"
|
||||
|
@ -1917,7 +1918,7 @@ msgstr ""
|
|||
|
||||
#: Controller/EventsController.php:4132
|
||||
msgid "Freetext Import"
|
||||
msgstr ""
|
||||
msgstr "Freetext 가져오기"
|
||||
|
||||
#: Controller/EventsController.php:4138
|
||||
msgid "Populate using a Template"
|
||||
|
@ -1925,11 +1926,11 @@ msgstr ""
|
|||
|
||||
#: Controller/EventsController.php:4144
|
||||
msgid "OpenIOC Import"
|
||||
msgstr ""
|
||||
msgstr "OpenIOC 가져오기"
|
||||
|
||||
#: Controller/EventsController.php:4149
|
||||
msgid "ThreatConnect Import"
|
||||
msgstr ""
|
||||
msgstr "ThreatConnect 가져오기"
|
||||
|
||||
#: Controller/EventsController.php:4154
|
||||
msgid "(Experimental) Forensic analysis - Mactime"
|
||||
|
@ -2043,11 +2044,11 @@ msgstr ""
|
|||
|
||||
#: Controller/EventsController.php:5489
|
||||
msgid "background job"
|
||||
msgstr ""
|
||||
msgstr "백그라운드 작업"
|
||||
|
||||
#: Controller/EventsController.php:5491
|
||||
msgid "external tool"
|
||||
msgstr ""
|
||||
msgstr "외부 도구"
|
||||
|
||||
#: Controller/EventsController.php:5497
|
||||
msgid "<b>Warning</b>: This event view is outdated. Please reload page to see latest changes."
|
||||
|
@ -2063,7 +2064,7 @@ msgstr ""
|
|||
|
||||
#: Controller/EventsController.php:5716
|
||||
msgid "%s event(s) deleted."
|
||||
msgstr ""
|
||||
msgstr "%s 이벤트가 삭제되었습니다."
|
||||
|
||||
#: Controller/EventsController.php:5756
|
||||
msgid "Recovery simulation complete. Event #%s can be recovered using %s log entries."
|
||||
|
@ -2143,7 +2144,7 @@ msgstr "피드 가져 오기가 완료되었습니다."
|
|||
|
||||
#: Controller/FeedsController.php:607
|
||||
msgid "No feed enabled."
|
||||
msgstr ""
|
||||
msgstr "활성화된 피드가 없습니다."
|
||||
|
||||
#: Controller/FeedsController.php:631;650
|
||||
#: Controller/ServersController.php:132
|
||||
|
@ -2216,7 +2217,7 @@ msgstr "잘못 된 피드 리스트를 받았습니다."
|
|||
|
||||
#: Controller/GalaxiesController.php:73
|
||||
msgid "Galaxies updated."
|
||||
msgstr ""
|
||||
msgstr "Galaxies가 업데이트 되었습니다."
|
||||
|
||||
#: Controller/GalaxiesController.php:88
|
||||
msgid "Default galaxy clusters dropped."
|
||||
|
@ -2224,7 +2225,7 @@ msgstr ""
|
|||
|
||||
#: Controller/GalaxiesController.php:146
|
||||
msgid "Galaxy deleted"
|
||||
msgstr ""
|
||||
msgstr "Galaxy가 삭제되었습니다."
|
||||
|
||||
#: Controller/GalaxiesController.php:154
|
||||
msgid "Could not delete Galaxy."
|
||||
|
@ -2268,7 +2269,7 @@ msgstr ""
|
|||
|
||||
#: Controller/GalaxiesController.php:327
|
||||
msgid "All sharing groups"
|
||||
msgstr ""
|
||||
msgstr "모든 공유 그룹"
|
||||
|
||||
#: Controller/GalaxiesController.php:356
|
||||
msgid "All clusters"
|
||||
|
@ -2293,7 +2294,7 @@ msgstr ""
|
|||
|
||||
#: Controller/GalaxyClusterBlocklistsController.php:75;97
|
||||
msgid "Invalid cluster IDs."
|
||||
msgstr ""
|
||||
msgstr "잘못된 클러스터 ID 입니다."
|
||||
|
||||
#: Controller/GalaxyClusterBlocklistsController.php:86
|
||||
msgid "Failed to delete GalaxyCluster from GalaxyClusterBlocklist. Error: "
|
||||
|
@ -2341,100 +2342,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
msgstr "잘못된 JSON 형식입니다."
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4557,7 +4558,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5963,7 +5964,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8012,7 +8013,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1465,13 +1465,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1481,7 +1481,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2348,100 +2348,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4564,7 +4564,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5970,7 +5970,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8020,7 +8020,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Polish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1476,13 +1476,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1492,7 +1492,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2363,100 +2363,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4579,7 +4579,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5985,7 +5985,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8037,7 +8037,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1466,13 +1466,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1482,7 +1482,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2349,100 +2349,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4565,7 +4565,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5971,7 +5971,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8021,7 +8021,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: misp\n"
|
||||
"PO-Revision-Date: 2022-01-05 08:09\n"
|
||||
"PO-Revision-Date: 2022-07-21 15:58\n"
|
||||
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -1467,13 +1467,13 @@ msgid "Event Report %s %s deleted"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "hard"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:133;136
|
||||
#: Controller/GalaxyClustersController.php:721;731
|
||||
#: Controller/GalaxyClustersController.php:722;732
|
||||
#: View/Objects/group_attributes_into_object.ctp:129
|
||||
msgid "soft"
|
||||
msgstr ""
|
||||
|
@ -1483,7 +1483,7 @@ msgid "Event Report %s could not be %s deleted.%sReasons: %s"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/EventReportsController.php:141;165;212;242;262;298
|
||||
#: Controller/GalaxyClustersController.php:745
|
||||
#: Controller/GalaxyClustersController.php:746
|
||||
#: Controller/GalaxyElementsController.php:83
|
||||
#: Controller/TaxonomiesController.php:531
|
||||
#: Controller/WarninglistsController.php:434
|
||||
|
@ -2350,100 +2350,100 @@ msgstr ""
|
|||
msgid "Galaxy cluster relationship could not be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:203
|
||||
#: Controller/GalaxyClustersController.php:204
|
||||
msgid "This cluster is not published. Users will not be able to use it"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:220;224
|
||||
#: Controller/GalaxyClustersController.php:221;225
|
||||
msgid "Invalid galaxy"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:283;284;391;392
|
||||
#: Controller/GalaxyClustersController.php:284;285;392;393
|
||||
msgid "Invalid JSON"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:314;427
|
||||
#: Controller/GalaxyClustersController.php:315;428
|
||||
msgid "Galaxy cluster saved"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:446
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: View/GalaxyClusters/add.ctp:72
|
||||
msgid "Valid JSON array or comma separated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:447
|
||||
#: Controller/GalaxyClustersController.php:448
|
||||
msgid "Valid JSON array composed from Object of the form {key: keyname, value: actualValue}"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:470
|
||||
#: Controller/GalaxyClustersController.php:471
|
||||
msgid "You can't publish a galaxy cluster that is already published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:473
|
||||
#: Controller/GalaxyClustersController.php:474
|
||||
msgid "Default galaxy cluster cannot be published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:479
|
||||
#: Controller/GalaxyClustersController.php:480
|
||||
msgid "Publish job queued. Job ID: %s"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:486
|
||||
#: Controller/GalaxyClustersController.php:487
|
||||
msgid "Could not publish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:493
|
||||
#: Controller/GalaxyClustersController.php:494
|
||||
msgid "Galaxy cluster published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:516
|
||||
#: Controller/GalaxyClustersController.php:517
|
||||
msgid "You can't unpublish a galaxy cluster that is not published"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:519
|
||||
#: Controller/GalaxyClustersController.php:520
|
||||
msgid "Default galaxy cluster cannot be unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:525
|
||||
#: Controller/GalaxyClustersController.php:526
|
||||
msgid "Could not unpublish galaxy cluster"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:532
|
||||
#: Controller/GalaxyClustersController.php:533
|
||||
msgid "Galaxy cluster unpublished"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:719
|
||||
#: Controller/GalaxyClustersController.php:720
|
||||
msgid "Galaxy cluster successfuly %s deleted%s."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:722
|
||||
#: Controller/GalaxyClustersController.php:723
|
||||
msgid " and added to the block list"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:731
|
||||
#: Controller/GalaxyClustersController.php:732
|
||||
msgid "Galaxy cluster could not be %s deleted."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:757
|
||||
#: Controller/GalaxyClustersController.php:758
|
||||
msgid "Galaxy cluster successfuly restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:765
|
||||
#: Controller/GalaxyClustersController.php:766
|
||||
msgid "Galaxy cluster could not be %s restored."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:774
|
||||
#: Controller/GalaxyClustersController.php:775
|
||||
msgid "This function can only be reached via POST."
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:917
|
||||
#: Controller/GalaxyClustersController.php:918
|
||||
msgid "Default galaxy cluster cannot be updated"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:920
|
||||
#: Controller/GalaxyClustersController.php:921
|
||||
msgid "Galaxy cluster is not a fork"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/GalaxyClustersController.php:951
|
||||
#: Controller/GalaxyClustersController.php:952
|
||||
msgid "Cluster updated to the newer version"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4566,7 +4566,7 @@ msgid "Base64 encoded certificate"
|
|||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1620
|
||||
msgid "A tad ID to attach to created events"
|
||||
msgid "A tag ID to attach to created events"
|
||||
msgstr ""
|
||||
|
||||
#: Controller/Component/RestResponseComponent.php:1633
|
||||
|
@ -5972,7 +5972,7 @@ msgid "Event publish is not banned"
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7584
|
||||
msgid "Reason: Could not reach redis to chech republish emailing ban status."
|
||||
msgid "Reason: Could not reach redis to check republish emailing ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:7597
|
||||
|
@ -8022,7 +8022,7 @@ msgid "User is not banned to sent email notification"
|
|||
msgstr ""
|
||||
|
||||
#: Model/User.php:1481
|
||||
msgid "Reason: Could not reach redis to chech user email notification ban status."
|
||||
msgid "Reason: Could not reach redis to check user email notification ban status."
|
||||
msgstr ""
|
||||
|
||||
#: Model/User.php:1493
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue