Merge branch '2.4' into i18n

pull/4499/head
Steve Clement 2019-03-28 11:43:23 +01:00
commit 9402835e4e
217 changed files with 21102 additions and 8286 deletions

1
.gitignore vendored
View File

@ -72,6 +72,7 @@ tools/mkdocs
/app/Config/database.php
/app/Config/core.php
/app/Config/config.php
/app/Console/Command/training.json
/app/Lib/cakephp
/app/webroot/gpg.asc
/app/tmp/logs

View File

@ -710,6 +710,7 @@ CREATE TABLE IF NOT EXISTS `roles` (
`max_execution_time` VARCHAR(255) COLLATE utf8_bin DEFAULT "",
`restricted_to_site_admin` tinyint(1) NOT NULL DEFAULT 0,
`perm_publish_zmq` tinyint(1) NOT NULL DEFAULT 0,
`perm_publish_kafka` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
@ -1261,23 +1262,23 @@ INSERT INTO `feeds` (`id`, `provider`, `name`, `url`, `distribution`, `default`,
-- 7. Read Only - read
--
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (1, 'admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-- --------------------------------------------------------

View File

@ -309,13 +309,13 @@ COPY public.regexp (id, regexp, replacement, type) FROM stdin;
-- Data for Name: roles; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public.roles (id, name, created, modified, perm_add, perm_modify, perm_modify_org, perm_publish, perm_delegate, perm_sync, perm_admin, perm_audit, perm_full, perm_auth, perm_site_admin, perm_regexp_access, perm_tagger, perm_template, perm_sharing_group, perm_tag_editor, perm_sighting, perm_object_template, default_role, memory_limit, max_execution_time, restricted_to_site_admin, perm_publish_zmq) FROM stdin;
1 admin 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t t t t t t t t t t t t t t f f t
2 Org Admin 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t f t t f t f f t t t t t f f f t
3 User 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t f f f f f f t f f f f f f t f t f f
4 Publisher 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t f f f f t f f f f f f t f f f t
5 Sync user 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t t f f f t f f f f t f t f f f t
6 Read Only 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 f f f f f f f f f t f f f f f f f f f f f
COPY public.roles (id, name, created, modified, perm_add, perm_modify, perm_modify_org, perm_publish, perm_delegate, perm_sync, perm_admin, perm_audit, perm_full, perm_auth, perm_site_admin, perm_regexp_access, perm_tagger, perm_template, perm_sharing_group, perm_tag_editor, perm_sighting, perm_object_template, default_role, memory_limit, max_execution_time, restricted_to_site_admin, perm_publish_zmq, perm_publish_kafka) FROM stdin;
1 admin 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t t t t t t t t t t t t t t f f t t
2 Org Admin 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t f t t f t f f t t t t t f f f t t
3 User 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t f f f f f f t f f f f f f t f t f f f
4 Publisher 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t f f f f t f f f f f f t f f f t t
5 Sync user 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 t t t t t t f f f t f f f f t f t f f f t t
6 Read Only 2018-11-27 06:22:00+00 2018-11-27 06:22:00+00 f f f f f f f f f t f f f f f f f f f f f f
\.

View File

@ -1134,7 +1134,8 @@ CREATE TABLE public.roles (
memory_limit character varying(255) DEFAULT ''::character varying,
max_execution_time character varying(255) DEFAULT ''::character varying,
restricted_to_site_admin boolean DEFAULT false NOT NULL,
perm_publish_zmq boolean DEFAULT false NOT NULL
perm_publish_zmq boolean DEFAULT false NOT NULL,
perm_publish_kafka boolean DEFAULT false NOT NULL
);

View File

@ -237,3 +237,8 @@ Optional features
-------------------
# MISP has a new pub/sub feature, using ZeroMQ. To enable it, simply run the following command
pip install pyzmq
# MISP has a feature for publishing events to Kafka. To enable it, simply run the following commands
apt-get install librdkafka-dev php-dev
pecl install rdkafka
find /etc -name php.ini | while read f; do echo 'extension=rdkafka.so' | tee -a "$f"; done

View File

@ -253,3 +253,8 @@ Optional features
pip install pyzmq
# ZeroMQ depends on the Python client for Redis
pip install redis
# MISP has a feature for publishing events to Kafka. To enable it, simply run the following commands
apt-get install librdkafka-dev php-dev
pecl install rdkafka
find /etc -name php.ini | while read f; do echo 'extension=rdkafka.so' | tee -a "$f"; done

View File

@ -270,6 +270,11 @@ sudo pip install pyzmq
# ZeroMQ depends on the Python client for Redis
sudo pip install redis
# MISP has a feature for publishing events to Kafka. To enable it, simply run the following commands
apt-get install librdkafka-dev php-dev
pecl install rdkafka
find /etc -name php.ini | while read f; do echo 'extension=rdkafka.so' | tee -a "$f"; done
# For the experimental ssdeep correlations, run the following installation:
# installing ssdeep
wget http://downloads.sourceforge.net/project/ssdeep/ssdeep-2.13/ssdeep-2.13.tar.gz

2
PyMISP

@ -1 +1 @@
Subproject commit 166ef3866dfefbc2456a394b55fb5f9819f257b8
Subproject commit 64bcaad0e578129543cdffad532a232722615f6c

View File

@ -1 +1 @@
{"major":2, "minor":4, "hotfix":103}
{"major":2, "minor":4, "hotfix":104}

View File

@ -0,0 +1,585 @@
<?php
/*
* Reset a password
*
* arg0 = email
* arg1 = new password
*/
class TrainingShell extends AppShell {
public $uses = array('User', 'Organisation', 'Server');
private $__currentUrl = false;
private $__currentAuthKey = false;
private $__simulate = false;
private $__config = false;
private $__report = array();
private $__verbose = false;
private $__interactive = false;
public function simulate()
{
$this->__simulate = true;
$this->setup();
}
public function setup()
{
$this->__verbose = !empty($this->params['verbose']);
$this->__interactive = !empty($this->params['interactive']);
$this->__config = file_get_contents(APP . 'Console/Command/training.json');
if (empty($this->__config)) {
echo 'No config file found. Make sure that training.json exists and is configured.';
die();
}
$this->__config = json_decode($this->__config, true);
$this->__report = array();
for ($i = $this->__config['ID_start']; $i < ($this->__config['ID_start'] + $this->__config['number_of_misps_to_configure']); $i++) {
$id = $i;
if ($this->__config['ID_zero_out']) {
if ($id < 10) {
$id = '0' . $id;
}
}
$this->__currentUrl = str_replace('$ID', $id, $this->__config['server_blueprint']);
if ($this->__interactive) {
$question = sprintf('Configure instance at %s?', $this->__currentUrl);
$input = $this->__user_input($question, array('y', 'n'));
if ($input === 'n') {
$this->__printReport('Stopping execution. Data created so far:' . PHP_EOL . PHP_EOL);
die();
}
}
if ($this->__verbose) {
echo 'INFO - Instance to configure' . $this->__currentUrl . PHP_EOL;
}
$org = $this->__createOrgFromBlueprint($id);
$this->__setSetting('MISP.host_org_id', $org['Organisation']['remote_org_id'], $id, $org['Organisation']['name']);
$this->__report['servers'][$this->__currentUrl]['host_org_id'] = $org['Organisation']['remote_org_id'];
$this->__report['remote_orgs'][] = array('id' => $org['Organisation']['remote_org_id'], 'name' => $org['Organisation']['name']);
$role_id = $this->__createRole($this->__config['role_blueprint']);
$this->__report['servers'][$this->__currentUrl]['training_role_id'] = $role_id;
$sync_user = $this->__createSyncUserLocally($org['Organisation']['remote_org_id'], $org['Organisation']['name']);
$this->__report['users'][] = $sync_user;
$local_host_org = $this->__getLocalHostOrgId();
$hub_org_id_on_remote = $this->__createOrg($local_host_org);
$external_baseurl = empty(Configure::read('MISP.external_baseurl')) ? Configure::read('MISP.baseurl') : Configure::read('MISP.external_baseurl');
$this->__report['servers'][$this->__currentUrl]['sync_connections'][] = $this->__addSyncConnection($external_baseurl, 'Exercise hub', $local_host_org, $hub_org_id_on_remote, $sync_user);
$this->__report['servers'][$this->__currentUrl]['users'] = $this->__createUsers($org['Organisation']['remote_org_id'], $role_id, $org['Organisation']['name'], $id);
if (!empty($this->__config['create_sync_both_ways'])) {
$this->__createReverseSyncConnection($org['Organisation']['id'], $org['Organisation']['name'], $local_host_org);
}
if (!empty($this->__config['create_admin_user'])) {
$this->__report['servers'][$this->__currentUrl['users']][] = $this->__addAdminUserRemotely($i, $org['Organisation']['name'], $org['Organisation']['remote_org_id']);
}
if (!empty($this->__config['settings'])) {
foreach ($this->__config['settings'] as $key => $value)
$this->__setSetting($key, $value, $id, $org['Organisation']['name']);
}
if ($this->__config['reset_admin_credentials']) {
$this->__report['servers'][$this->__currentUrl]['management_account'] = $this->__reset_admin_credentials($this->__report);
}
}
$this->__printReport('Setup complete. Please find the modifications below:' . PHP_EOL . PHP_EOL);
}
private function __createOrgFromBlueprint($id)
{
$org = str_replace('$ID', $id, $this->__config['org_blueprint']);
$org_id = $this->Organisation->createOrgFromName($org, 1, true);
$org_data = $this->Organisation->find('first', array(
'recursive' => -1,
'fields' => array('name', 'uuid', 'local'),
'conditions' => array('Organisation.id' => $org_id)
));
$org_data['Organisation']['remote_org_id'] = $this->__createOrg($org_data);
return $org_data;
}
private function __getLocalHostOrgId()
{
$org = $this->Organisation->find('first', array(
'recursive' => -1,
'conditions' => array(
'Organisation.id' => empty(Configure::read('MISP.host_org_id')) ? -1 : Configure::read('MISP.host_org_id')
),
'fields' => array(
'name', 'id', 'uuid'
)
));
if (empty($org)) {
$this->__printReport('Stopping execution, no host_org_id set on the current instance, or the setting points to a non-existing org. Data created so far:' . PHP_EOL . PHP_EOL);
die();
}
return $org;
}
private function __createReverseSyncConnection($remote_org_id_on_local, $org_name, $host_org_id_on_local)
{
$sync_user = $this->__addSyncUserRemotely();
$this->__report['servers'][$this->__currentUrl]['users'][] = $sync_user;
$sync_server = $this->__addSyncConnectionLocally($this->__currentUrl, $org_name . '_misp', $remote_org_id_on_local, $sync_user, $host_org_id_on_local);
if ($sync_server) {
$this->__report['sync'][] = $sync_server;
}
}
private function __printReport($message)
{
echo json_encode($this->__report, JSON_PRETTY_PRINT);
$this->__report = '';
return true;
}
private function __findRemoteRoleId($role_name)
{
$options = array(
'url' => $this->__currentUrl . '/roles/index',
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code == 200) {
$roles = json_decode($response->body, true);
foreach ($roles as $role) {
if ($role['Role']['name'] == $role_name) {
return $role['Role']['id'];
}
}
} else {
$this->__responseError($response, $options);
}
return false;
}
private function __getRemoteAdminUser()
{
$options = array(
'url' => $this->__currentUrl . '/users/view/me',
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code == 200) {
return json_decode($response->body, true);
} else {
$this->__responseError($response, $options);
}
return false;
}
private function __addAdminUserRemotely($i, $org, $remote_org_id)
{
$email = $this->__config['user_blueprint'];
$email = str_replace('$ORGNAME', $org, $email);
$email = str_replace('$ID', $i, $email);
$email = 'admin' . substr($email, strpos($email, '@'));
$admin_role_id = $this->__findRemoteRoleId('Admin');
if (!$admin_role_id) {
echo 'Remote instance lacks the required role (Admin).' . PHP_EOL ;
die();
}
$options = array(
'url' => $this->__currentUrl . '/admin/users/index/searchall:' . $email,
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
}
$newKey = $this->User->generateRandomPassword(32);
if (empty(json_decode($response->body, true))) {
$user = array(
'email' => $email,
'password' => $newKey,
'role_id' => $admin_role_id,
'org_id' => $remote_org_id
);
$options = array(
'url' => $this->__currentUrl . '/admin/users/add',
'method' => 'POST',
'body' => $user
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
if (!$this->__simulate) {
$user['authkey'] = $response_data['User']['authkey'];
}
}
} else {
$user = json_decode($response->body, true)[0]['User'];
}
return $user;
}
private function __addSyncUserRemotely()
{
$sync_user_role_id = $this->__findRemoteRoleId('Sync user');
if (!$sync_user_role_id) {
echo 'Remote instance lacks the required role (Sync user).' . PHP_EOL ;
die();
}
$remote_admin = $this->__getRemoteAdminUser();
if (!$remote_admin) {
echo 'Remote instance did not return the admin user\'s information.' . PHP_EOL ;
die();
}
$email = $remote_admin['User']['email'];
$email = 'sync' . substr($email, strpos($email, '@'));
$options = array(
'url' => $this->__currentUrl . '/admin/users/index/searchall:' . $email,
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
}
$newKey = $this->User->generateRandomPassword(32);
if (empty(json_decode($response->body, true))) {
$user = array(
'email' => $email,
'password' => $newKey,
'role_id' => $sync_user_role_id,
'org_id' => $remote_admin['User']['role_id']
);
$options = array(
'url' => $this->__currentUrl . '/admin/users/add',
'method' => 'POST',
'body' => $user
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
if (!$this->__simulate) {
$user['authkey'] = $response_data['User']['authkey'];
}
}
} else {
$user = json_decode($response->body, true)[0]['User'];
}
return $user;
}
private function __addSyncConnectionLocally($baseurl, $org_name, $remote_org_id_on_local, $sync_user)
{
$this->Server->create();
$server = array(
"name" => $org_name,
"url" => $baseurl,
"authkey" => $sync_user['authkey'],
"push" => 1,
"pull" => 1,
"remote_org_id" => $sync_user['org_id'],
"self_signed" => 1,
"org_id" => $host_org_id_on_local
);
$result = $this->Server->save($server);
if (!$result) {
echo sprintf(
'Could not add connection to %s. Reason: %s.' . PHP_EOL,
$baseurl,
json_encode($this->Server->validationErrors)
);
return false;
}
return $server;
}
private function __addSyncConnection($baseurl, $name, $local_host_org, $hub_org_id_on_remote, $sync_user)
{
$server = array(
'name' => $name,
'url' => $baseurl,
'authkey' => $sync_user['User']['authkey'],
'remote_org_id' => $hub_org_id_on_remote,
'push' => 1,
'pull' => 1,
'self_signed' => 1
);
$options = array(
'url' => $this->__currentUrl . '/servers/add',
'method' => 'POST',
'body' => $server
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
return array(
'url' => $response_data['Server']['url'],
'authkey' => $response_data['Server']['authkey']
);
}
}
private function __createSyncUserLocally($remote_org_id, $org)
{
$sync_role = $this->User->Role->find('first', array('recursive' => -1, 'conditions' => array('Role.name' => 'Sync user')));
$sync_role = $sync_role['Role']['id'];
$this->User->create();
$this->User->save(array(
'external_auth_required' => 0,
'external_auth_key' => '',
'server_id' => 0,
'gpgkey' => '',
'certif_public' => '',
'autoalert' => 0,
'contactalert' => 0,
'disabled' => 0,
'newsread' => 0,
'change_pw' => 1,
'authkey' => $this->User->generateAuthKey(),
'termsaccepted' => 0,
'org_id' => $remote_org_id,
'role_id' => $sync_role,
'email' => 'sync_user@' . $org . '.test'
));
$user = $this->User->find('first', array('recursive' => -1, 'conditions' => array('User.email' => 'sync_user@' . $org . '.test')));
return $user;
}
private function __responseError($response, $options)
{
echo sprintf(
"Received a non-200 response (%s). Aborting.\nQueried URL: %s\n Query type: %s\n Request payload: %s\n\n",
$response->code,
$options['url'],
$options['method'],
empty($options['body']) ? '' : json_encode($options['body'], JSON_PRETTY_PRINT)
);
if ($this->__interactive) {
$question = 'The above error can cause the issues to compound if you continue. For example, not creating an organisation that subsequently created users should belong to will fail. Would you like to continue?';
$input = $this->__user_input($question, array('y', 'n'));
if ($input === 'y') {
return true;
}
}
$this->__printReport('Setup failed. Output of what has been created:' . PHP_EOL . PHP_EOL);
die();
}
private function __createUsers($remote_org_id, $role_id, $org, $i)
{
$summary = array();
for ($j = 1; $j < (1 + $this->__config['user_count']); $j++) {
$email = $this->__config['user_blueprint'];
$email = str_replace('$ID', $i, $email);
$email = str_replace('$ORGNAME', $org, $email);
$email = str_replace('$USER_ITERATOR', $j, $email);
$options = array(
'url' => $this->__currentUrl . '/admin/users/index/searchall:' . $email,
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
}
$newKey = $this->User->generateRandomPassword(32);
if (empty(json_decode($response->body, true))) {
$user = array(
'email' => $email,
'password' => $newKey,
'role_id' => $role_id,
'org_id' => $remote_org_id
);
$options = array(
'url' => $this->__currentUrl . '/admin/users/add',
'method' => 'POST',
'body' => $user
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
if ($this->__simulate) {
$summary[] = $user;
} else {
$user['authkey'] = $response_data['User']['authkey'];
$summary[] = $user;
}
}
}
}
return $summary;
}
private function __createRole($blueprint)
{
$blueprint = array('Role' => $blueprint);
$options = array(
'url' => $this->__currentUrl . '/roles/index',
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code == 200) {
$roles = json_decode($response->body, true);
$found = false;
foreach ($roles as $role) {
if ($role['Role']['name'] == $blueprint['Role']['name']) {
return $role['Role']['id'];
}
}
$options = array(
'url' => $this->__currentUrl . '/admin/roles/add',
'method' => 'POST',
'body' => $blueprint
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
return $response_data['Role']['id'];
}
} else {
$this->__responseError($response, $options);
}
}
private function __reset_admin_credentials()
{
$credentials = array(
'authkey' => $this->User->generateAuthKey(),
'password' => $this->User->generateRandomPassword(32)
);
$this->__queryRemoteMISP(array(
'url' => $this->__currentUrl . '/admin/users/edit/1',
'body' => array('User' => array(
'password' => $credentials['password'],
'authkey' => $credentials['authkey']
)),
'method' => 'POST'
));
return $credentials;
}
private function __createOrg($org_data)
{
$options = array(
'url' => $this->__currentUrl . '/organisations/index.json',
'method' => 'GET'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
$response_data = json_decode($response->body, true);
$found = false;
foreach ($response_data as $existingOrg) {
if ($existingOrg['Organisation']['name'] == $org_data['Organisation']['name']) {
return $existingOrg['Organisation']['id'];
}
}
$options = array(
'body' => $org_data,
'url' => $this->__currentUrl . '/admin/organisations/add',
'method' => 'POST'
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
}
return $response_data['Organisation']['id'];
}
}
private function __user_input($question, $valid_input_options)
{
$valid_input = false;
while (!$valid_input) {
echo sprintf(
'%s (%s)' . PHP_EOL,
$question,
implode('/', $valid_input_options)
);
$handle = fopen ("php://stdin","r");
$input = trim(strtolower(fgets($handle)));
if (in_array($input, $valid_input_options)) {
$valid_input = true;
}
}
return $input;
}
private function __setSetting($key, $value, $i, $org)
{
$value = str_replace('$ID', $i, $value);
$value = str_replace('$ORGNAME', $org, $value);
$options = array(
'url' => $this->__currentUrl . '/servers/serverSettingsEdit/' . $key,
'method' => 'POST',
'body' => array('value' => $value)
);
$response = $this->__queryRemoteMISP($options, true);
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
return true;
}
}
private function __queryRemoteMISP($options, $returnFullResponse = false)
{
$params = array();
App::uses('HttpSocket', 'Network/Http');
$params['ssl_allow_self_signed'] = true;
$params['ssl_verify_peer_name'] = false;
$params['ssl_verify_peer'] = false;
$HttpSocket = new HttpSocket($params);
$request = array(
'header' => array(
'Authorization' => $this->__config['authkey'],
'Accept' => 'application/json',
'Content-Type' => 'application/json'
)
);
if ($this->__simulate) {
if ($this->__verbose) {
echo 'SIMULATION - query to be executed:' . PHP_EOL . json_encode($options) . PHP_EOL . ' using request object:' . PHP_EOL . json_encode($request) . PHP_EOL . PHP_EOL;
}
$response = new class{};
$response->code = 200;
$response->body = '{"id": 666, "Organisation": {"id": 666}, "User": {"id": 666, "email": "foo"}, "Role": {"id": 666}, "Server": {"url": "https://foo.bar", "authkey": "bla"}}';
return $response;
} else {
if ($this->__verbose) {
echo 'EXEC - query to be executed:' . PHP_EOL . json_encode($options) . PHP_EOL . ' using request object:' . PHP_EOL . json_encode($request) . PHP_EOL . PHP_EOL;
}
if ($options['method'] === 'POST') {
$response = $HttpSocket->post($options['url'], json_encode($options['body']), $request);
} else {
$response = $HttpSocket->get($options['url'], '', $request);
}
if ($returnFullResponse) {
return $response;
}
if ($response->code != 200) {
$this->__responseError($response, $options);
} else {
return json_decode($response->body, true);
}
}
}
public function getOptionParser()
{
$parser = parent::getOptionParser();
$parser->addOption('verbose', array(
'short' => 'v',
'help' => __('verbose mode'),
'boolean' => 1
))->addOption('interactive', array(
'short' => 'i',
'help' => __('interactive mode'),
'boolean' => 1
));
return $parser;
}
}

View File

@ -0,0 +1,43 @@
{
"ID_start": 1,
"ID_zero_out": 0,
"number_of_misps_to_configure": 5,
"reset_admin_credentials": 1,
"create_sync_both_ways": 0,
"create_admin_user": 0,
"settings": {
},
"authkey": "111111111111111111111111111111111",
"server_blueprint": "https://my_remote_misp$ID",
"user_blueprint": "user$USER_ITERATOR@user.$ORGNAME.test",
"user_count": 2,
"org_blueprint": "org$ID",
"role_blueprint": {
"name": "training_participant",
"perm_add": true,
"perm_modify": true,
"perm_modify_org": true,
"perm_publish": true,
"perm_delegate": true,
"perm_sync": true,
"perm_admin": true,
"perm_audit": true,
"perm_auth": true,
"perm_site_admin": false,
"perm_regexp_access": true,
"perm_tagger": true,
"perm_template": true,
"perm_sharing_group": true,
"perm_tag_editor": true,
"perm_sighting": true,
"perm_object_template": true,
"default_role": false,
"memory_limit": "",
"max_execution_time": "",
"restricted_to_site_admin": false,
"perm_publish_zmq": true,
"permission": "3",
"permission_description": "training_participant"
}
}

View File

@ -44,9 +44,9 @@ class AppController extends Controller
public $debugMode = false;
public $helpers = array('Utility', 'OrgImg');
public $helpers = array('Utility', 'OrgImg', 'FontAwesome');
private $__queryVersion = '60';
private $__queryVersion = '64';
public $pyMispVersion = '2.4.103';
public $phpmin = '7.0';
public $phprec = '7.2';
@ -442,6 +442,7 @@ class AppController extends Controller
$this->set('isAclSharingGroup', $role['perm_sharing_group']);
$this->set('isAclSighting', isset($role['perm_sighting']) ? $role['perm_sighting'] : false);
$this->set('isAclZmq', isset($role['perm_publish_zmq']) ? $role['perm_publish_zmq'] : false);
$this->set('isAclKafka', isset($role['perm_publish_kafka']) ? $role['perm_publish_kafka'] : false);
$this->userRole = $role;
} else {
$this->set('me', false);

View File

@ -254,6 +254,10 @@ class AttributesController extends AppController
}
foreach ($attributes as $k => $attribute) {
if (empty($attribute['blocked'])) {
if (!empty($attribute['encrypt'])) {
$attribute = $this->Attribute->onDemandEncrypt($attribute);
}
$attributes[$k] = $attribute;
$this->Attribute->set($attribute);
$result = $this->Attribute->validates();
if (!$result) {
@ -2890,23 +2894,30 @@ class AttributesController extends AppController
foreach ($modules['modules'] as $temp) {
if ($temp['name'] == $type) {
$found = true;
$format = (isset($temp['mispattributes']['format']) ? $temp['mispattributes']['format'] : 'simplified');
if (isset($temp['meta']['config'])) {
foreach ($temp['meta']['config'] as $conf) {
$options[$conf] = Configure::read('Plugin.Enrichment_' . $type . '_' . $conf);
}
}
break;
}
}
if (!$found) {
throw new MethodNotAllowedException(__('No valid enrichment options found for this attribute.'));
}
$data = array('module' => $type, $attribute[0]['Attribute']['type'] => $attribute[0]['Attribute']['value']);
$data = array('module' => $type);
if ($persistent) {
$data['persistent'] = 1;
}
if (!empty($options)) {
$data['config'] = $options;
}
if ($format == 'misp_standard') {
$data['attribute'] = $attribute[0]['Attribute'];
} else {
$data[$attribute[0]['Attribute']['type']] = $attribute[0]['Attribute']['value'];
}
$data = json_encode($data);
$result = $this->Module->queryModuleServer('/query', $data, true);
if ($result) {
@ -2988,10 +2999,6 @@ class AttributesController extends AppController
public function addTag($id = false, $tag_id = false)
{
if (!$this->request->is('post')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that. Only POST requests are accepted.')), 'status' => 200, 'type' => 'json'));
}
$rearrangeRules = array(
'request' => false,
'Attribute' => false,
@ -3007,140 +3014,148 @@ class AttributesController extends AppController
if ($id === 'selected') {
$idList = json_decode($this->request->data['attribute_ids'], true);
}
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
if (!is_numeric($tag_id)) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
// try to parse json array
$tag_ids = json_decode($tag_id);
if ($tag_ids !== null) { // can decode json
$tag_id_list = array();
foreach ($tag_ids as $tag_id) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_id_list[] = $tag_id;
}
}
} else {
$tag = $this->Event->EventTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
}
if (!isset($idList)) {
$idList = array($id);
}
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
$success = 0;
$fails = 0;
foreach ($idList as $id) {
$this->Attribute->id = $id;
if (!$this->Attribute->exists()) {
throw new NotFoundException(__('Invalid attribute'));
}
$this->Attribute->read();
if (!$this->_isSiteAdmin() && $this->Attribute->data['Event']['orgc_id'] !== $this->Auth->user('org_id')) {
$fails++;
continue;
}
if ($this->Attribute->data['Attribute']['deleted']) {
throw new NotFoundException(__('Invalid attribute'));
}
$eventId = $this->Attribute->data['Attribute']['event_id'];
$this->Attribute->Event->recursive = -1;
$event = $this->Attribute->Event->read(array(), $eventId);
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'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status' => 200, 'type' => 'json'));
}
}
if (!$this->_isRest()) {
$this->Attribute->Event->insertLock($this->Auth->user(), $eventId);
}
$this->Attribute->recursive = -1;
foreach ($tag_id_list as $tag_id) {
$this->Attribute->AttributeTag->Tag->id = $tag_id;
if (!$this->Attribute->AttributeTag->Tag->exists()) {
$fails++;
continue;
}
$tag = $this->Attribute->AttributeTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->Attribute->AttributeTag->find('first', array(
'conditions' => array(
'attribute_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
$this->autoRender = false;
if (!empty($found)) {
$fails++;
continue;
}
$this->Attribute->AttributeTag->create();
if ($this->Attribute->AttributeTag->save(array('attribute_id' => $id, 'tag_id' => $tag_id, 'event_id' => $eventId))) {
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Attribute->Event->save($event);
$this->Attribute->data['Attribute']['timestamp'] = $date->getTimestamp();
$this->Attribute->save($this->Attribute->data);
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'Attribute', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to attribute (' . $id . ')', 'Attribute (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success++;
} else {
$fails++;
}
}
}
if ($fails == 0) {
if ($success == 1) {
$message = 'Tag added.';
} else {
$message = $success . ' tags added.';
}
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message, 'check_publish' => true)), 'status' => 200, 'type' => 'json'));
if (!$this->request->is('post')) {
$this->set('object_id', $id);
$this->set('scope', 'Attribute');
$this->layout = false;
$this->autoRender = false;
$this->render('/Events/add_tag');
} else {
if ($fails == 1) {
$message = 'Tag could not be added.';
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
if (!is_numeric($tag_id)) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
// try to parse json array
$tag_ids = json_decode($tag_id);
if ($tag_ids !== null) { // can decode json
$tag_id_list = array();
foreach ($tag_ids as $tag_id) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_id_list[] = $tag_id;
}
}
} else {
$tag = $this->Event->EventTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
}
if (!isset($idList)) {
$idList = array($id);
}
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
$success = 0;
$fails = 0;
foreach ($idList as $id) {
$this->Attribute->id = $id;
if (!$this->Attribute->exists()) {
throw new NotFoundException(__('Invalid attribute'));
}
$this->Attribute->read();
if (!$this->_isSiteAdmin() && $this->Attribute->data['Event']['orgc_id'] !== $this->Auth->user('org_id')) {
$fails++;
continue;
}
if ($this->Attribute->data['Attribute']['deleted']) {
throw new NotFoundException(__('Invalid attribute'));
}
$eventId = $this->Attribute->data['Attribute']['event_id'];
$this->Attribute->Event->recursive = -1;
$event = $this->Attribute->Event->read(array(), $eventId);
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'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status' => 200, 'type' => 'json'));
}
}
if (!$this->_isRest()) {
$this->Attribute->Event->insertLock($this->Auth->user(), $eventId);
}
$this->Attribute->recursive = -1;
foreach ($tag_id_list as $tag_id) {
$this->Attribute->AttributeTag->Tag->id = $tag_id;
if (!$this->Attribute->AttributeTag->Tag->exists()) {
$fails++;
continue;
}
$tag = $this->Attribute->AttributeTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->Attribute->AttributeTag->find('first', array(
'conditions' => array(
'attribute_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
$this->autoRender = false;
if (!empty($found)) {
$fails++;
continue;
}
$this->Attribute->AttributeTag->create();
if ($this->Attribute->AttributeTag->save(array('attribute_id' => $id, 'tag_id' => $tag_id, 'event_id' => $eventId))) {
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Attribute->Event->save($event);
$this->Attribute->data['Attribute']['timestamp'] = $date->getTimestamp();
$this->Attribute->save($this->Attribute->data);
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'Attribute', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to attribute (' . $id . ')', 'Attribute (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success++;
} else {
$fails++;
}
}
}
if ($fails == 0) {
if ($success == 1) {
$message = 'Tag added.';
} else {
$message = $success . ' tags added.';
}
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $message, 'check_publish' => true)), 'status' => 200, 'type' => 'json'));
} else {
$message = $fails . ' tags could not be added.';
if ($fails == 1) {
$message = 'Tag could not be added.';
} else {
$message = $fails . ' tags could not be added.';
}
if ($success > 0) {
$message .= ' However, ' . $success . ' tag(s) were added.';
}
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $message)), 'status' => 200, 'type' => 'json'));
}
if ($success > 0) {
$message .= ' However, ' . $success . ' tag(s) were added.';
}
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $message)), 'status' => 200, 'type' => 'json'));
}
}

View File

@ -115,10 +115,12 @@ class ACLComponent extends Component
'getEventGraphReferences' => array('*'),
'getEventGraphTags' => array('*'),
'getEventGraphGeneric' => array('*'),
'genDistributionGraph' => array('*'),
'getDistributionGraph' => array('*'),
'getReferenceData' => array('*'),
'getReferences' => array('*'),
'getObjectTemplate' => array('*'),
'handleModuleResults' => array('*'),
'hids' => array('*'),
'index' => array('*'),
'importChoice' => array('*'),
@ -129,6 +131,7 @@ class ACLComponent extends Component
'proposalEventIndex' => array('*'),
'publish' => array('perm_publish'),
'pushEventToZMQ' => array('perm_publish_zmq'),
'pushEventToKafka' => array('perm_publish_kafka'),
'pushProposals' => array('perm_sync'),
'queryEnrichment' => array('perm_add'),
'removePivot' => array('*'),
@ -180,6 +183,7 @@ class ACLComponent extends Component
'galaxies' => array(
'attachCluster' => array('perm_tagger'),
'attachMultipleClusters' => array('perm_tagger'),
'delete' => array(),
'index' => array('*'),
'selectGalaxy' => array('perm_tagger'),
'selectGalaxyNamespace' => array('perm_tagger'),
@ -194,7 +198,8 @@ class ACLComponent extends Component
'delete' => array('perm_site_admin'),
'detach' => array('perm_tagger'),
'index' => array('*'),
'view' => array('*')
'view' => array('*'),
'viewGalaxyMatrix' => array('*')
),
'galaxyElements' => array(
'index' => array('*')
@ -303,6 +308,10 @@ class ACLComponent extends Component
'cleanRegexModifiers' => array('perm_regexp_access'),
'index' => array('*'),
),
'restClientHistory' => array(
'delete' => array('*'),
'index' => array('*')
),
'roles' => array(
'admin_add' => array(),
'admin_delete' => array(),
@ -325,6 +334,7 @@ class ACLComponent extends Component
'getGit' => array(),
'getInstanceUUID' => array('perm_sync'),
'getPyMISPVersion' => array('*'),
'getSubmodulesStatus' => array('perm_site_admin'),
'getVersion' => array('*'),
'index' => array('OR' => array('perm_sync', 'perm_admin')),
'postTest' => array('perm_sync'),
@ -432,6 +442,7 @@ class ACLComponent extends Component
'taxonomyMassConfirmation' => array('perm_tagger'),
'taxonomyMassHide' => array('perm_tagger'),
'taxonomyMassUnhide' => array('perm_tagger'),
'toggleRequired' => array('perm_site_admin'),
'update' => array(),
'view' => array('*'),
'unhideTag' => array('perm_tagger'),

View File

@ -26,7 +26,7 @@ class EventsController extends AppController
);
private $acceptedFilteringNamedParams = array('sort', 'direction', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'attributeFilter', 'extended', 'page',
'searchFor', 'attributeFilter', 'proposal', 'correlation', 'warning', 'deleted', 'includeRelatedTags', 'distribution', 'taggedAttributes', 'galaxyAttachedAttributes', 'objectType', 'attributeType', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'feed', 'server', 'toIDS'
'searchFor', 'proposal', 'correlation', 'warning', 'deleted', 'includeRelatedTags', 'distribution', 'taggedAttributes', 'galaxyAttachedAttributes', 'objectType', 'attributeType', 'focus', 'extended', 'overrideLimit', 'filterColumnsOverwrite', 'feed', 'server', 'toIDS'
);
public $defaultFilteringRules = array(
@ -868,6 +868,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));
if ($this->params['ext'] === 'csv') {
App::uses('CsvExport', 'Export');
$export = new CsvExport();
@ -1456,6 +1457,7 @@ class EventsController extends AppController
$orgTable = $this->Event->Orgc->find('list', array(
'fields' => array('Orgc.id', 'Orgc.name')
));
$this->set('required_taxonomies', $this->Event->getRequiredTaxonomies());
$this->set('orgTable', $orgTable);
$this->set('currentUri', $attributeUri);
$this->set('filters', $filters);
@ -2362,6 +2364,18 @@ class EventsController extends AppController
$result = $this->Event->save($event, array('fieldList' => $fieldList));
if ($result) {
$message = __('Event unpublished.');
$kafkaTopic = Configure::read('Plugin.Kafka_event_publish_notifications_topic');
if (Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_event_publish_notifications_enable') && !empty($kafkaTopic)) {
$kafkaPubTool = $this->Event->getKafkaPubTool();
$params = array('eventid' => $id);
if (Configure::read('Plugin.Kafka_include_attachments')) {
$params['includeAttachments'] = 1;
}
$pubEvent = $this->Event->fetchEvent($this->Auth->user(), $params);
if (!empty($pubEvent)) {
$kafkaPubTool->publishJson($kafkaTopic, $pubEvent[0], 'unpublish');
}
}
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('events', 'unpublish', $id, false, $message);
} else {
@ -2399,6 +2413,13 @@ class EventsController extends AppController
$errors = array();
// only allow form submit CSRF protection.
if ($this->request->is('post') || $this->request->is('put')) {
if (!$this->_isRest()) {
$publishable = $this->Event->checkIfPublishable($id);
if ($publishable !== true) {
$this->Flash->error(__('Could not publish event - no tag for required taxonomies missing: %s', implode(', ', $publishable)));
$this->redirect(array('action' => 'view', $id));
}
}
// Performs all the actions required to publish an event
$result = $this->Event->publishRouter($id, null, $this->Auth->user());
if (!Configure::read('MISP.background_jobs')) {
@ -2666,16 +2687,10 @@ class EventsController extends AppController
$this->Event->export_types[$k]['progress'] = 0;
}
}
$this->set('export_types', $this->Event->export_types);
// generate the list of Attribute types
$this->loadModel('Attribute');
$this->set('sigTypes', array_keys($this->Attribute->typeDefinitions));
} else {
// generate the list of Attribute types
$this->loadModel('Attribute');
$this->set('sigTypes', array_keys($this->Attribute->typeDefinitions));
$this->render('/Events/export_alternate');
}
$this->loadModel('Attribute');
$this->set('sigTypes', array_keys($this->Attribute->typeDefinitions));
$this->set('export_types', $this->Event->export_types);
}
public function downloadExport($type, $extra = null)
@ -3530,9 +3545,6 @@ class EventsController extends AppController
public function addTag($id = false, $tag_id = false)
{
if (!$this->request->is('post')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
$rearrangeRules = array(
'request' => false,
'Event' => false,
@ -3545,112 +3557,120 @@ class EventsController extends AppController
if ($id === false) {
$id = $this->request->data['event'];
}
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
$conditions = array('LOWER(Tag.name) LIKE' => strtolower(trim($tag_id)));
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 (!is_numeric($tag_id)) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_ids = json_decode($tag_id);
if ($tag_ids !== null) { // can decode json
$tag_id_list = array();
foreach ($tag_ids as $tag_id) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_id_list[] = $tag_id;
}
}
} else {
$tag = $this->Event->EventTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
}
$this->Event->recursive = -1;
$event = $this->Event->read(array(), $id);
if (empty($event)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid event.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
}
$this->autoRender = false;
$error = false;
$success = false;
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
foreach ($tag_id_list as $tag_id) {
$this->Event->EventTag->Tag->id = $tag_id;
if (!$this->Event->EventTag->Tag->exists()) {
$error = __('Invalid Tag.');
continue;
}
$tag = $this->Event->EventTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->Event->EventTag->find('first', array(
'conditions' => array(
'event_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
if (!empty($found)) {
$error = __('Tag is already attached to this event.');
continue;
}
$this->Event->EventTag->create();
if ($this->Event->EventTag->save(array('event_id' => $id, 'tag_id' => $tag_id))) {
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Event->save($event);
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'Event', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to event (' . $id . ')', 'Event (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success = __('Tag(s) added.');
} else {
$fail = __('Tag could not be added.');
}
}
if ($success) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('Tag(s) added.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} elseif (empty($fail)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('All tags are already present, nothing to add.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
if (!$this->request->is('post')) {
$this->set('object_id', $id);
$this->set('scope', 'Event');
$this->layout = false;
$this->autoRender = false;
$this->render('/Events/add_tag');
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $fail)), 'status'=>200, 'type' => 'json'));
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
if (!$this->_isSiteAdmin() && !$this->userRole['perm_sync']) {
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $event['Event']['orgc_id'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
}
$conditions = array('LOWER(Tag.name) LIKE' => strtolower(trim($tag_id)));
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 (!is_numeric($tag_id)) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_ids = json_decode($tag_id);
if ($tag_ids !== null) { // can decode json
$tag_id_list = array();
foreach ($tag_ids as $tag_id) {
if (preg_match('/^collection_[0-9]+$/i', $tag_id)) {
$tagChoice = explode('_', $tag_id)[1];
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $tagChoice)));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag Collection.')), 'status'=>200, 'type' => 'json'));
}
$tag_id_list = array();
foreach ($tagCollection[0]['TagCollectionTag'] as $tagCollectionTag) {
$tag_id_list[] = $tagCollectionTag['tag_id'];
}
} else {
$tag_id_list[] = $tag_id;
}
}
} else {
$tag = $this->Event->EventTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
}
$this->autoRender = false;
$error = false;
$success = false;
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
foreach ($tag_id_list as $tag_id) {
$this->Event->EventTag->Tag->id = $tag_id;
if (!$this->Event->EventTag->Tag->exists()) {
$error = __('Invalid Tag.');
continue;
}
$tag = $this->Event->EventTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->Event->EventTag->find('first', array(
'conditions' => array(
'event_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
if (!empty($found)) {
$error = __('Tag is already attached to this event.');
continue;
}
$this->Event->EventTag->create();
if ($this->Event->EventTag->save(array('event_id' => $id, 'tag_id' => $tag_id))) {
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Event->save($event);
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'Event', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to event (' . $id . ')', 'Event (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success = __('Tag(s) added.');
} else {
$fail = __('Tag could not be added.');
}
}
if ($success) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('Tag(s) added.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} elseif (empty($fail)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('All tags are already present, nothing to add.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $fail)), 'status'=>200, 'type' => 'json'));
}
}
}
@ -4667,8 +4687,7 @@ class EventsController extends AppController
return new CakeResponse(array('body' => json_encode($json), 'status' => 200, 'type' => 'json'));
}
public function getDistributionGraph($id, $type = 'event')
{
private function genDistributionGraph($id, $type = 'event', $extended = 0) {
$validTools = array('event');
if (!in_array($type, $validTools)) {
throw new MethodNotAllowedException(__('Invalid type.'));
@ -4677,9 +4696,6 @@ class EventsController extends AppController
$this->loadModel('Organisation');
App::uses('DistributionGraphTool', 'Tools');
$grapher = new DistributionGraphTool();
$data = $this->request->is('post') ? $this->request->data : array();
$extended = isset($this->params['named']['extended']) ? 1 : 0;
$servers = $this->Server->find('list', array(
'fields' => array('name'),
@ -4692,6 +4708,13 @@ class EventsController extends AppController
$item = utf8_encode($item);
}
});
return $json;
}
public function getDistributionGraph($id, $type = 'event')
{
$extended = isset($this->params['named']['extended']) ? 1 : 0;
$json = $this->genDistributionGraph($id, $type, $extended);
$this->response->type('json');
return new CakeResponse(array('body' => json_encode($json), 'status' => 200, 'type' => 'json'));
}
@ -4915,7 +4938,6 @@ class EventsController extends AppController
App::uses('ColourGradientTool', 'Tools');
$gradientTool = new ColourGradientTool();
$colours = $gradientTool->createGradientFromValues($scores);
$this->set('eventId', $eventId);
$this->set('target_type', $scope);
$this->set('columnOrders', $killChainOrders);
@ -4998,12 +5020,12 @@ class EventsController extends AppController
if (empty($attribute)) {
throw new MethodNotAllowedException(__('Attribute not found or you are not authorised to see it.'));
}
$this->loadModel('Module');
$enabledModules = $this->Module->getEnabledModules($this->Auth->user(), false, $type);
if (!is_array($enabledModules) || empty($enabledModules)) {
throw new MethodNotAllowedException(__('No valid %s options found for this attribute.', $type));
}
if ($this->request->is('ajax')) {
$this->loadModel('Module');
$enabledModules = $this->Module->getEnabledModules($this->Auth->user(), false, $type);
if (!is_array($enabledModules) || empty($enabledModules)) {
throw new MethodNotAllowedException(__('No valid %s options found for this attribute.', $type));
}
$modules = array();
foreach ($enabledModules['modules'] as $module) {
if (in_array($attribute[0]['Attribute']['type'], $module['mispattributes']['input'])) {
@ -5016,65 +5038,16 @@ class EventsController extends AppController
$this->set('type', $type);
$this->render('ajax/enrichmentChoice');
} else {
$this->loadModel('Module');
$enabledModules = $this->Module->getEnabledModules($this->Auth->user(), false, $type);
if (!is_array($enabledModules) || empty($enabledModules)) {
throw new MethodNotAllowedException(__('no valid %s options found for this attribute.', $type));
}
$options = array();
foreach ($enabledModules['modules'] as $temp) {
if ($temp['name'] == $module) {
$format = (isset($temp['mispattributes']['format']) ? $temp['mispattributes']['format'] : 'simplified');
if (isset($temp['meta']['config'])) {
foreach ($temp['meta']['config'] as $conf) {
$options[$conf] = Configure::read('Plugin.' . $type . '_' . $module . '_' . $conf);
}
}
}
}
$data = array('module' => $module, $attribute[0]['Attribute']['type'] => $attribute[0]['Attribute']['value'], 'event_id' => $attribute[0]['Attribute']['event_id'], 'attribute_uuid' => $attribute[0]['Attribute']['uuid']);
if ($this->Event->Attribute->typeIsAttachment($attribute[0]['Attribute']['type'])) {
$data['data'] = $this->Event->Attribute->base64EncodeAttachment($attribute[0]['Attribute']);
}
if (!empty($options)) {
$data['config'] = $options;
}
$data = json_encode($data);
$result = $this->Module->queryModuleServer('/query', $data, false, $type);
if (!$result) {
throw new MethodNotAllowedException(__('%s service not reachable.', $type));
}
if (isset($result['error'])) {
$this->Flash->error($result['error']);
}
if (!is_array($result)) {
throw new Exception($result);
}
$resultArray = $this->Event->handleModuleResult($result, $attribute[0]['Attribute']['event_id']);
if (isset($result['comment']) && $result['comment'] != "") {
$importComment = $result['comment'];
} else {
$importComment = $attribute[0]['Attribute']['value'] . __(': Enriched via the %s', $module) . ($type != 'Enrichment' ? ' ' . $type : '') . ' module';
}
$typeCategoryMapping = array();
foreach ($this->Event->Attribute->categoryDefinitions as $k => $cat) {
foreach ($cat['types'] as $type) {
$typeCategoryMapping[$type][$k] = $k;
}
}
foreach ($resultArray as $key => $result) {
$options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false
);
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
if (isset($result['data'])) {
App::uses('FileAccessTool', 'Tools');
$fileAccessTool = new FileAccessTool();
$tmpdir = Configure::read('MISP.tmpdir') ? Configure::read('MISP.tmpdir') : '/tmp';
$tempFile = $fileAccessTool->createTempFile($tmpdir, $prefix = 'MISP');
$fileAccessTool->writeToFile($tempFile, $result['data']);
$resultArray[$key]['data'] = basename($tempFile) . '|' . filesize($tempFile);
break;
}
}
$distributions = $this->Event->Attribute->distributionLevels;
@ -5084,18 +5057,141 @@ class EventsController extends AppController
}
$this->set('distributions', $distributions);
$this->set('sgs', $sgs);
$this->set('type', $type);
$this->set('event', array('Event' => $attribute[0]['Event']));
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
$this->set('typeCategoryMapping', $typeCategoryMapping);
$this->set('title', 'Enrichment Results');
$this->set('importComment', $importComment);
$this->render('resolved_attributes');
if ($format == 'misp_standard') {
$this->__queryEnrichment($attribute, $module, $options, $type);
} else {
$this->__queryOldEnrichment($attribute, $module, $options, $type);
}
}
}
private function __queryEnrichment($attribute, $module, $options, $type)
{
if ($this->Event->Attribute->typeIsAttachment($attribute[0]['Attribute']['type'])) {
$attribute[0]['Attribute']['data'] = $this->Event->Attribute->base64EncodeAttachment($attribute[0]['Attribute']);
}
$event_id = $attribute[0]['Event']['id'];
$data = array('module' => $module, 'attribute' => $attribute[0]['Attribute'], 'event_id' => $event_id);
if (!empty($options)) {
$data['config'] = $options;
}
$data = json_encode($data);
$result = $this->Module->queryModuleServer('/query', $data, false, $type);
if (!$result) {
throw new MethodNotAllowedException(__('%s service not reachable.', $type));
}
if (isset($result['error'])) {
$this->Flash->error($result['error']);
}
if (!is_array($result)) {
throw new Exception($result);
}
$attributes = array();
$objects = array();
if (isset($result['results']['Attribute']) && !empty($result['results']['Attribute'])) {
foreach ($result['results']['Attribute'] as $tmp_attribute) {
array_push($attributes, $this->Event->Attribute->captureAttribute($tmp_attribute, $event_id, $this->Auth->user()));
}
unset($result['results']['Attribute']);
}
if (isset($result['results']['Object']) && !empty($result['results']['Object'])) {
foreach ($result['results']['Object'] as $tmp_object) {
$this->Event->Object->captureObject($tmp_object, $event_id, $this->Auth->user());
array_push($objects, $tmp_object);
}
unset($result['results']['Object']);
}
if (empty($attributes) && empty($objects)) {
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type);
} else {
$this->set('attributeValue', $attribute[0]['Attribute']['value']);
$this->set('module', $module);
$event = array('Event' => $attribute[0]['Event']);
$event['Attribute'] = $attributes;
$event['Object'] = $objects;
$this->set('event', $event);
if (!empty($result['results'])) {
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type, $event = true, $render_name = 'resolved_misp_format');
} else {
$this->set('menuItem', 'enrichmentResults');
$this->set('title', 'Enrichment Results');
$this->render('resolved_misp_format');
}
}
}
private function __queryOldEnrichment($attribute, $module, $options, $type)
{
$data = array('module' => $module, $attribute[0]['Attribute']['type'] => $attribute[0]['Attribute']['value'], 'event_id' => $attribute[0]['Attribute']['event_id'], 'attribute_uuid' => $attribute[0]['Attribute']['uuid']);
if ($this->Event->Attribute->typeIsAttachment($attribute[0]['Attribute']['type'])) {
$data['data'] = $this->Event->Attribute->base64EncodeAttachment($attribute[0]['Attribute']);
}
if (!empty($options)) {
$data['config'] = $options;
}
$data = json_encode($data);
$result = $this->Module->queryModuleServer('/query', $data, false, $type);
if (!$result) {
throw new MethodNotAllowedException(__('%s service not reachable.', $type));
}
if (isset($result['error'])) {
$this->Flash->error($result['error']);
}
if (!is_array($result)) {
throw new Exception($result);
}
$this->__handleSimplifiedFormat($attribute, $module, $options, $result, $type);
}
private function __handleSimplifiedFormat($attribute, $module, $options, $result, $type, $event = false, $renderName = 'resolved_attributes')
{
$resultArray = $this->Event->handleModuleResult($result, $attribute[0]['Attribute']['event_id']);
if (isset($result['comment']) && $result['comment'] != "") {
$importComment = $result['comment'];
} else {
$importComment = $attribute[0]['Attribute']['value'] . __(': Enriched via the %s', $module) . ($type != 'Enrichment' ? ' ' . $type : '') . ' module';
}
$typeCategoryMapping = array();
foreach ($this->Event->Attribute->categoryDefinitions as $k => $cat) {
foreach ($cat['types'] as $type) {
$typeCategoryMapping[$type][$k] = $k;
}
}
foreach ($resultArray as $key => $result) {
$options = array(
'conditions' => array('OR' => array('Attribute.value1' => $result['value'], 'Attribute.value2' => $result['value'])),
'fields' => array('Attribute.type', 'Attribute.category', 'Attribute.value', 'Attribute.comment'),
'order' => false
);
$resultArray[$key]['related'] = $this->Event->Attribute->fetchAttributes($this->Auth->user(), $options);
if (isset($result['data'])) {
App::uses('FileAccessTool', 'Tools');
$fileAccessTool = new FileAccessTool();
$tmpdir = Configure::read('MISP.tmpdir') ? Configure::read('MISP.tmpdir') : '/tmp';
$tempFile = $fileAccessTool->createTempFile($tmpdir, $prefix = 'MISP');
$fileAccessTool->writeToFile($tempFile, $result['data']);
$resultArray[$key]['data'] = basename($tempFile) . '|' . filesize($tempFile);
}
}
$this->set('type', $type);
if (!$event){
$this->set('event', array('Event' => $attribute[0]['Event']));
}
$this->set('resultArray', $resultArray);
$this->set('typeList', array_keys($this->Event->Attribute->typeDefinitions));
$this->set('defaultCategories', $this->Event->Attribute->defaultCategories);
$this->set('typeCategoryMapping', $typeCategoryMapping);
$this->set('title', 'Enrichment Results');
$this->set('importComment', $importComment);
$this->render($renderName);
}
public function handleModuleResults($eventId)
{
debug($eventId);
debug($this->request->event);
}
public function importModule($module, $eventId)
{
$this->loadModel('Module');
@ -5351,6 +5447,59 @@ class EventsController extends AppController
}
}
public function pushEventToKafka($id)
{
if ($this->request->is('Post')) {
$message = 'Kafka event publishing not enabled.';
if (Configure::read('Plugin.Kafka_enable')) {
$kafkaEventTopic = Configure::read('Plugin.Kafka_event_notifications_topic');
$event = $this->Event->quickFetchEvent(array('eventid' => $id));
if (Configure::read('Plugin.Kafka_event_notifications_enable') && !empty($kafkaEventTopic)) {
$kafkaPubTool = $this->Event->getKafkaPubTool();
if (!empty($event)) {
$kafkaPubTool->publishJson($kafkaEventTopic, $event, 'manual_publish');
$success = 1;
$message = 'Event published to Kafka';
} else {
$success = 0;
$message = 'Invalid event.';
}
}
$kafkaPubTopic = Configure::read('Plugin.Kafka_event_publish_notifications_topic');
if (!empty($event['Event']['published']) && Configure::read('Plugin.Kafka_event_publish_notifications_enable') && !empty($kafkaPubTopic)) {
$kafkaPubTool = $this->Event->getKafkaPubTool();
$params = array('eventid' => $id);
if (Configure::read('Plugin.Kafka_include_attachments')) {
$params['includeAttachments'] = 1;
}
$event = $this->Event->fetchEvent($this->Auth->user(), $params);
if (!empty($event)) {
$kafkaPubTool->publishJson($kafkaPubTopic, $event[0], 'manual_publish');
if (!isset($success)) {
$success = 1;
$message = 'Event published to Kafka';
}
} else {
$success = 0;
$message = 'Invalid event.';
}
}
}
} else {
$message = 'This functionality is only available via POST requests';
}
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Events', 'pushEventToKafka', $id, $this->response->type(), $message);
} else {
if (!empty($success)) {
$this->Flash->success($message);
} else {
$this->Flash->error($message);
}
$this->redirect($this->referer());
}
}
public function getEventInfoById($id)
{
if (empty($id)) {

View File

@ -77,6 +77,38 @@ class GalaxiesController extends AppController
}
}
public function delete($id)
{
if (!is_numeric($id)) {
throw new NotFoundException('Invalid galaxy.');
}
$galaxy = $this->Galaxy->find('first', array(
'recursive' => -1,
'conditions' => array('Galaxy.id' => $id)
));
if (empty($galaxy)) {
throw new NotFoundException('Invalid galaxy.');
}
$result = $this->Galaxy->delete($id);
if ($result) {
$message = 'Galaxy deleted';
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Galaxy', 'delete', false, $this->response->type(), $message);
} else {
$this->Flash->success($message);
$this->redirect(array('controller' => 'galaxies', 'action' => 'index'));
}
} else {
$message = 'Could not delete Galaxy.';
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Galaxy', 'delete', false, $message);
} else {
$this->Flash->success($message);
$this->redirect($this->referer());
}
}
}
public function selectGalaxy($target_id, $target_type='event', $namespace='misp')
{
$mitreAttackGalaxyId = $this->Galaxy->getMitreAttackGalaxyId();
@ -238,34 +270,42 @@ class GalaxiesController extends AppController
public function attachMultipleClusters($target_id, $target_type = 'event')
{
if ($target_id === 'selected') {
$target_id_list = json_decode($this->request->data['Galaxy']['attribute_ids']);
} else {
$target_id_list = array($target_id);
}
$cluster_ids = $this->request->data['Galaxy']['target_ids'];
if (!empty($cluster_ids)) {
$cluster_ids = json_decode($cluster_ids, true);
if ($cluster_ids === null) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'error' => __('Failed to parse request.'))), 'status'=>200, 'type' => 'json'));
if ($this->request->is('post')) {
if ($target_id === 'selected') {
$target_id_list = json_decode($this->request->data['Galaxy']['attribute_ids']);
} else {
$target_id_list = array($target_id);
}
$cluster_ids = $this->request->data['Galaxy']['target_ids'];
if (!empty($cluster_ids)) {
$cluster_ids = json_decode($cluster_ids, true);
if ($cluster_ids === null) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'error' => __('Failed to parse request.'))), 'status'=>200, 'type' => 'json'));
}
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'error' => __('No clusters picked.'))), 'status'=>200, 'type' => 'json'));
}
$result = "";
if (!is_array($cluster_ids)) { // in case we only want to attach 1
$cluster_ids = array($cluster_ids);
}
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);
}
}
if ($this->request->is('ajax')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result, 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} else {
$this->Flash->info($result);
$this->redirect($this->referer());
}
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'error' => __('No clusters picked.'))), 'status'=>200, 'type' => 'json'));
}
$result = "";
if (!is_array($cluster_ids)) { // in case we only want to attach 1
$cluster_ids = array($cluster_ids);
}
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);
}
}
if ($this->request->is('ajax')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result, 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} else {
$this->Flash->info($result);
$this->redirect($this->referer());
$this->set('target_id', $target_id);
$this->set('target_type', $target_type);
$this->layout = false;
$this->autoRender = false;
$this->render('/Galaxies/ajax/attach_multiple_clusters');
}
}

View File

@ -356,4 +356,107 @@ class GalaxyClustersController extends AppController
}
}
}
public function viewGalaxyMatrix($id) {
if (!$this->request->is('ajax')) {
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
}
$cluster = $this->GalaxyCluster->find('first', array(
'conditions' => array('id' => $id)
));
if (empty($cluster)) {
throw new Exception("Invalid Galaxy Cluster.");
}
$this->loadModel('Event');
$mitreAttackGalaxyId = $this->GalaxyCluster->Galaxy->getMitreAttackGalaxyId();
$attackPatternTagNames = $this->GalaxyCluster->find('list', array(
'conditions' => array('galaxy_id' => $mitreAttackGalaxyId),
'fields' => array('tag_name')
));
$cluster = $cluster['GalaxyCluster'];
$tag_name = $cluster['tag_name'];
// fetch all attribute ids having the requested cluster
$attributeIds = $this->Event->Attribute->AttributeTag->find('list', array(
'contain' => array('Tag'),
'conditions' => array(
'Tag.name' => $tag_name
),
'fields' => array('attribute_id'),
'recursive' => -1
));
// fetch all related tags belonging to attack pattern
$attributeTags = $this->Event->Attribute->AttributeTag->find('all', array(
'contain' => array('Tag'),
'conditions' => array(
'attribute_id' => $attributeIds,
'Tag.name' => $attackPatternTagNames
),
'fields' => array('Tag.name, COUNT(DISTINCT event_id) as tag_count'),
'recursive' => -1,
'group' => array('Tag.name')
));
// fetch all event ids having the requested cluster
$eventIds = $this->Event->EventTag->find('list', array(
'contain' => array('Tag'),
'conditions' => array(
'Tag.name' => $tag_name
),
'fields' => array('event_id'),
'recursive' => -1
));
// fetch all related tags belonging to attack pattern
$eventTags = $this->Event->EventTag->find('all', array(
'contain' => array('Tag'),
'conditions' => array(
'event_id' => $eventIds,
'Tag.name' => $attackPatternTagNames
),
'fields' => array('Tag.name, COUNT(DISTINCT event_id) as tag_count'),
'recursive' => -1,
'group' => array('Tag.name')
));
$scores = array();
foreach ($attributeTags as $tag) {
$tagName = $tag['Tag']['name'];
$scores[$tagName] = intval($tag[0]['tag_count']);
}
foreach ($eventTags as $tag) {
$tagName = $tag['Tag']['name'];
if (isset($scores[$tagName])) {
$scores[$tagName] = $scores[$tagName] + intval($tag[0]['tag_count']);
} else {
$scores[$tagName] = intval($tag[0]['tag_count']);
}
}
$maxScore = count($scores) > 0 ? max(array_values($scores)) : 0;
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId);
$tabs = $matrixData['tabs'];
$matrixTags = $matrixData['matrixTags'];
$killChainOrders = $matrixData['killChain'];
$instanceUUID = $matrixData['instance-uuid'];
App::uses('ColourGradientTool', 'Tools');
$gradientTool = new ColourGradientTool();
$colours = $gradientTool->createGradientFromValues($scores);
$this->set('target_type', 'attribute');
$this->set('columnOrders', $killChainOrders);
$this->set('tabs', $tabs);
$this->set('scores', $scores);
$this->set('maxScore', $maxScore);
if (!empty($colours)) {
$this->set('colours', $colours['mapping']);
$this->set('interpolation', $colours['interpolation']);
}
$this->set('pickingMode', false);
$this->set('defaultTabName', 'mitre-attack');
$this->set('removeTrailling', 2);
$this->render('cluster_matrix');
}
}

12
app/Controller/NewsController.php Normal file → Executable file
View File

@ -48,10 +48,10 @@ class NewsController extends AppController
$this->request->data['News']['user_id'] = 0;
}
if ($this->News->save($this->request->data)) {
$this->Flash->success('News item added.');
$this->Flash->success(__('News item added.'));
$this->redirect(array('action' => 'index'));
} else {
$this->Flash->error('The news item could not be added.');
$this->Flash->error(__('The news item could not be added.'));
}
}
}
@ -65,10 +65,10 @@ class NewsController extends AppController
if ($this->request->is('post') || $this->request->is('put')) {
$this->request->data['News']['id'] = $id;
if ($this->News->save($this->request->data)) {
$this->Flash->success('News item updated.');
$this->Flash->success(__('News item updated.'));
$this->redirect(array('action' => 'index'));
} else {
$this->Flash->error('Could not update news item.');
$this->Flash->error(__('Could not update news item.'));
}
} else {
$this->request->data = $this->News->read(null, $id);
@ -86,10 +86,10 @@ class NewsController extends AppController
throw new NotFoundException('Invalid news item');
}
if ($this->News->delete()) {
$this->Flash->success('News item deleted.');
$this->Flash->success(__('News item deleted.'));
$this->redirect(array('action' => 'index'));
}
$this->Flash->error('News item could not be deleted.');
$this->Flash->error(__('News item could not be deleted.'));
$this->redirect(array('action' => 'index'));
}
}

View File

@ -198,7 +198,9 @@ class ObjectsController extends AppController
$object['Attribute'][$k]['event_id'] = $eventId;
$this->MispObject->Event->Attribute->set($attribute);
if (!$this->MispObject->Event->Attribute->validates()) {
$error = 'Could not save object as at least one attribute has failed validation (' . $attribute['object_relation'] . '). ' . json_encode($this->MispObject->Event->Attribute->validationErrors);
if ($this->MispObject->Event->Attribute->validationErrors['value'][0] !== 'Composite type found but the value not in the composite (value1|value2) format.') {
$error = 'Could not save object as at least one attribute has failed validation (' . $attribute['object_relation'] . '). ' . json_encode($this->MispObject->Event->Attribute->validationErrors);
}
}
}
}

View File

@ -25,7 +25,7 @@ class OrganisationsController extends AppController
public function index()
{
if (!$this->Auth->user('Role')['perm_sharing_group'] && Configure::read('Security.hide_organisation_index_from_users')) {
throw new MethodNotAllowedException('This feature is disabled on this instance for normal users.');
throw new MethodNotAllowedException(__('This feature is disabled on this instance for normal users.'));
}
$conditions = array();
// We can either index all of the organisations existing on this instance (default)
@ -130,14 +130,14 @@ class OrganisationsController extends AppController
));
return $this->RestResponse->viewData($org, $this->response->type());
} else {
$this->Flash->success('The organisation has been successfully added.');
$this->Flash->success(__('The organisation has been successfully added.'));
$this->redirect(array('admin' => false, 'action' => 'index'));
}
} else {
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Organisations', 'admin_add', false, $this->Organisation->validationErrors, $this->response->type());
} else {
$this->Flash->error('The organisation could not be added.');
$this->Flash->error(__('The organisation could not be added.'));
}
}
} else {
@ -152,7 +152,7 @@ class OrganisationsController extends AppController
{
$this->Organisation->id = $id;
if (!$this->Organisation->exists()) {
throw new NotFoundException('Invalid organisation');
throw new NotFoundException(__('Invalid organisation'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->_isRest()) {
@ -191,7 +191,7 @@ class OrganisationsController extends AppController
));
return $this->RestResponse->viewData($org, $this->response->type());
} else {
$this->Flash->success('Organisation updated.');
$this->Flash->success(__('Organisation updated.'));
$this->redirect(array('admin' => false, 'action' => 'view', $this->Organisation->id));
}
} else {
@ -206,7 +206,7 @@ class OrganisationsController extends AppController
));
$this->set('duplicate_org', $duplicate_org['Organisation']['id']);
}
$this->Flash->error('The organisation could not be updated.');
$this->Flash->error(__('The organisation could not be updated.'));
}
}
} else {
@ -227,11 +227,11 @@ class OrganisationsController extends AppController
public function admin_delete($id)
{
if (!$this->request->is('post')) {
throw new MethodNotAllowedException('Action not allowed, post request expected.');
throw new MethodNotAllowedException(__('Action not allowed, post request expected.'));
}
$this->Organisation->id = $id;
if (!$this->Organisation->exists()) {
throw new NotFoundException('Invalid organisation');
throw new NotFoundException(__('Invalid organisation'));
}
$org = $this->Organisation->find('first', array(
@ -272,19 +272,19 @@ class OrganisationsController extends AppController
if (Validation::uuid($id)) {
$temp = $this->Organisation->find('first', array('recursive' => -1, 'fields' => array('Organisation.id'), 'conditions' => array('Organisation.uuid' => $id)));
if (empty($temp)) {
throw new NotFoundException('Invalid organisation.');
throw new NotFoundException(__('Invalid organisation.'));
}
$id = $temp['Organisation']['id'];
} elseif (!is_numeric($id)) {
$temp = $this->Organisation->find('first', array('recursive' => -1, 'fields' => array('Organisation.id'), 'conditions' => array('Organisation.name' => urldecode($id))));
if (empty($temp)) {
throw new NotFoundException('Invalid organisation.');
throw new NotFoundException(__('Invalid organisation.'));
}
$id = $temp['Organisation']['id'];
}
$this->Organisation->id = $id;
if (!$this->Organisation->exists()) {
throw new NotFoundException('Invalid organisation');
throw new NotFoundException(__('Invalid organisation'));
}
$fullAccess = false;
$fields = array('id', 'name', 'date_created', 'date_modified', 'type', 'nationality', 'sector', 'contacts', 'description', 'local', 'uuid', 'restricted_to_domain');
@ -311,7 +311,7 @@ class OrganisationsController extends AppController
'conditions' => array('ShadowAttribute.org_id' => $org['Organisation']['id'])
));
if (empty($proposal)) {
throw new NotFoundException('Invalid organisation');
throw new NotFoundException(__('Invalid organisation'));
}
}
}
@ -344,12 +344,12 @@ class OrganisationsController extends AppController
{
$this->Organisation->id = $id;
if (!$this->Organisation->exists()) {
throw new NotFoundException('Invalid organisation');
throw new NotFoundException(__('Invalid organisation'));
}
$org = $this->Organisation->find('first', array('conditions' => array('id' => $id), 'fields' => array('landingpage', 'name')));
$landingpage = $org['Organisation']['landingpage'];
if (empty($landingpage)) {
$landingpage = "No landing page has been created for this organisation.";
$landingpage = __('No landing page has been created for this organisation.');
}
$this->set('landingPage', $landingpage);
$this->set('org', $org['Organisation']['name']);
@ -398,7 +398,7 @@ class OrganisationsController extends AppController
public function getUUIDs()
{
if (!$this->Auth->user('Role')['perm_sync']) {
throw new MethodNotAllowedException('This action is restricted to sync users');
throw new MethodNotAllowedException(__('This action is restricted to sync users'));
}
$temp = $this->Organisation->find('all', array(
'recursive' => -1,
@ -415,15 +415,15 @@ class OrganisationsController extends AppController
public function admin_merge($id, $target_id = false)
{
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException('You are not authorised to do that.');
throw new MethodNotAllowedException(__('You are not authorised to do that.'));
}
if ($this->request->is('Post')) {
$result = $this->Organisation->orgMerge($id, $this->request->data, $this->Auth->user());
if ($result) {
$this->Flash->success('The organisation has been successfully merged.');
$this->Flash->success(__('The organisation has been successfully merged.'));
$this->redirect(array('admin' => false, 'action' => 'view', $result));
} else {
$this->Flash->error('There was an error while merging the organisations. To find out more about what went wrong, refer to the audit logs. If you would like to revert the changes, you can find a .sql file ');
$this->Flash->error(__('There was an error while merging the organisations. To find out more about what went wrong, refer to the audit logs. If you would like to revert the changes, you can find a .sql file'));
}
$this->redirect(array('admin' => false, 'action' => 'index'));
} else {

View File

@ -0,0 +1,68 @@
<?php
App::uses('AppController', 'Controller');
class RestClientHistoryController extends AppController
{
public $components = array(
'Security',
'AdminCrud',
'RequestHandler'
);
public $paginate = array(
'limit' => 10,
'recursive' => -1
);
public function beforeFilter()
{
parent::beforeFilter();
$this->Security->unlockedActions = array('delete');
// We don't care about CSRF protection for deleting these entries.
}
public function index($bookmarked = false)
{
$params = array(
'recursive' => -1,
'conditions' => array(
'RestClientHistory.user_id' => $this->Auth->user('id')
),
'order' => array(
'RestClientHistory.timestamp' => 'DESC'
),
);
if ($bookmarked) {
$params['conditions']['RestClientHistory.bookmark'] = $bookmarked ? 1 : 0;
}
if ($this->_isRest()) {
$list = $this->RestClientHistory->find('all', $params);
} else {
$this->paginate = array_merge($this->paginate, $params);
$list = $this->paginate();
}
if ($this->_isRest()) {
return $this->RestResponse->viewData($list, $this->response->type());
} else {
$this->set('bookmarked', $bookmarked);
$this->set('list', $list);
$this->layout = false;
$this->autoRender = false;
$this->render('index');
}
}
public function delete($id)
{
$entry = $this->RestClientHistory->find('first', array(
'recursive' => -1,
'conditions' => array('RestClientHistory.id' => $id, 'RestClientHistory.user_id' => $this->Auth->user('id')),
));
if (empty($entry)) {
throw new NotFoundException(__('Invalid entry.'));
}
$this->RestClientHistory->delete($id);
return $this->RestResponse->saveSuccessResponse('RestClientHistory', 'delete', $id, false, __('Entry removed.'));
}
}

View File

@ -56,7 +56,7 @@ class RolesController extends AppController
));
return $this->RestResponse->viewData($role, $this->response->type());
} else {
$this->Flash->success('The Role has been saved');
$this->Flash->success(__('The Role has been saved'));
$this->redirect(array('action' => 'index'));
}
} else {
@ -82,7 +82,7 @@ class RolesController extends AppController
}
$this->Role->id = $id;
if (!$this->Role->exists() && !$this->request->is('get')) {
throw new NotFoundException('Invalid Role');
throw new NotFoundException(__('Invalid Role'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if (!isset($this->request->data['Role'])) {
@ -97,7 +97,7 @@ class RolesController extends AppController
));
return $this->RestResponse->viewData($role, $this->response->type());
} else {
$this->Flash->success('The Role has been saved');
$this->Flash->success(__('The Role has been saved'));
$this->redirect(array('action' => 'index'));
}
} else {
@ -148,7 +148,7 @@ class RolesController extends AppController
}
$this->Role->id = $id;
if (!$this->Role->exists()) {
throw new NotFoundException('Invalid Role');
throw new NotFoundException(__('Invalid Role'));
}
if ($this->Role->delete()) {
if ($this->_isRest()) {
@ -161,7 +161,7 @@ class RolesController extends AppController
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Roles', 'admin_delete', $id, $this->Role->validationErrors, $this->response->type());
} else {
$this->Flash->error('Role could not be deleted');
$this->Flash->error(__('Role could not be deleted'));
$this->redirect(array('action' => 'index'));
}
}
@ -197,7 +197,7 @@ class RolesController extends AppController
$this->loadModel('AdminSetting');
$result = $this->AdminSetting->changeSetting('default_role', $role_id);
if ($result === true) {
$message = $role_id ? 'Default role set.' : 'Default role unset.';
$message = $role_id ? __('Default role set.') : __('Default role unset.');
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Roles', 'admin_set_default', $role_id, $this->response->type(), $message);
} else {

View File

@ -215,7 +215,6 @@ class ServersController extends AppController
throw new MethodNotAllowedException('No remote org ID set. Please pass it as remote_org_id');
}
}
$fail = false;
if (empty(Configure::read('MISP.host_org_id'))) {
$this->request->data['Server']['internal'] = 0;
@ -240,7 +239,6 @@ class ServersController extends AppController
$this->Flash->error($error_msg);
}
}
if (!$fail) {
if ($this->_isRest()) {
$defaults = array(
@ -315,6 +313,12 @@ class ServersController extends AppController
$this->request->data['Server']['internal'] = 0;
}
$this->request->data['Server']['org_id'] = $this->Auth->user('org_id');
if (empty($this->request->data['Server']['push_rules'])) {
$this->request->data['Server']['push_rules'] = '[]';
}
if (empty($this->request->data['Server']['pull_rules'])) {
$this->request->data['Server']['pull_rules'] = '[]';
}
if ($this->Server->save($this->request->data)) {
if (isset($this->request->data['Server']['submitted_cert'])) {
$this->__saveCert($this->request->data, $this->Server->id, false);
@ -334,7 +338,7 @@ class ServersController extends AppController
}
} else {
if ($this->_isRest()) {
return $this->RestResponse->saveFailResponse('Servers', 'add', false, $this->Server->validationError, $this->response->type());
return $this->RestResponse->saveFailResponse('Servers', 'add', false, $this->Server->validationErrors, $this->response->type());
} else {
$this->Flash->error(__('The server could not be saved. Please, try again.'));
}
@ -384,7 +388,7 @@ class ServersController extends AppController
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
}
}
public function edit($id = null)
{
$this->Server->id = $id;
@ -646,7 +650,7 @@ class ServersController extends AppController
'status' => 0,
'retries' => 0,
'org' => $this->Auth->user('Organisation')['name'],
'message' => 'Pulling.',
'message' => __('Pulling.'),
);
$this->Job->save($data);
$jobId = $this->Job->id;
@ -721,7 +725,7 @@ class ServersController extends AppController
'status' => 0,
'retries' => 0,
'org' => $this->Auth->user('Organisation')['name'],
'message' => 'Pushing.',
'message' => __('Pushing.'),
);
$this->Job->save($data);
$jobId = $this->Job->id;
@ -759,12 +763,12 @@ class ServersController extends AppController
if (isset($server['Server'][$subm]['name'])) {
if ($this->request->data['Server'][$subm]['size'] != 0) {
if (!$this->Server->checkFilename($server['Server'][$subm]['name'])) {
throw new Exception('Filename not allowed');
throw new Exception(__('Filename not allowed'));
}
$file = new File($server['Server'][$subm]['name']);
$ext = $file->ext();
if (!$server['Server'][$subm]['size'] > 0) {
$this->Flash->error('Incorrect extension or empty file.');
$this->Flash->error(__('Incorrect extension or empty file.'));
$this->redirect(array('action' => 'index'));
}
@ -846,7 +850,7 @@ class ServersController extends AppController
'recursive' => -1,
'fields' => array('Organisation.id', 'Organisation.name')
));
return array_replace(array(0 => 'No organisation selected.'), $local_orgs);
return array_replace(array(0 => __('No organisation selected.')), $local_orgs);
}
public function serverSettings($tab=false)
@ -862,35 +866,35 @@ class ServersController extends AppController
'Security' => array('count' => 0, 'errors' => 0, 'severity' => 5),
'Plugin' => array('count' => 0, 'errors' => 0, 'severity' => 5)
);
$writeableErrors = array(0 => 'OK', 1 => 'not found', 2 => 'is not writeable');
$readableErrors = array(0 => 'OK', 1 => 'not readable');
$gpgErrors = array(0 => 'OK', 1 => 'FAIL: settings not set', 2 => 'FAIL: Failed to load GnuPG', 3 => 'FAIL: Issues with the key/passphrase', 4 => 'FAIL: encrypt 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.');
$stixOperational = array(0 => 'Some of the libraries related to STIX are not installed. Make sure that all libraries listed below are correctly installed.', 1 => 'OK');
$stixVersion = array(0 => 'Incorrect STIX version installed, found $current, expecting $expected', 1 => 'OK');
$stix2Version = array(0 => 'Incorrect STIX2 version installed, found $current, expecting $expected', 1 => 'OK');
$cyboxVersion = array(0 => 'Incorrect CyBox version installed, found $current, expecting $expected', 1 => 'OK');
$mixboxVersion = array(0 => 'Incorrect mixbox version installed, found $current, expecting $expected', 1 => 'OK');
$maecVersion = array(0 => 'Incorrect maec version installed, found $current, expecting $expected', 1 => 'OK');
$pymispVersion = array(0 => 'Incorrect PyMISP version installed, found $current, expecting $expected', 1 => 'OK');
$sessionErrors = array(0 => 'OK', 1 => 'High', 2 => 'Alternative setting used', 3 => 'Test failed');
$moduleErrors = array(0 => 'OK', 1 => 'System not enabled', 2 => 'No modules found');
$writeableErrors = array(0 => __('OK'), 1 => __('not found'), 2 => __('is not writeable'));
$readableErrors = array(0 => __('OK'), 1 => __('not readable'));
$gpgErrors = array(0 => __('OK'), 1 => __('FAIL: settings not set'), 2 => __('FAIL: Failed to load GnuPG'), 3 => __('FAIL: Issues with the key/passphrase'), 4 => __('FAIL: encrypt 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.'));
$stixOperational = array(0 => __('Some of the libraries related to STIX are not installed. Make sure that all libraries listed below are correctly installed.'), 1 => __('OK'));
$stixVersion = array(0 => __('Incorrect STIX version installed, found $current, expecting $expected'), 1 => __('OK'));
$stix2Version = array(0 => __('Incorrect STIX2 version installed, found $current, expecting $expected'), 1 => __('OK'));
$cyboxVersion = array(0 => __('Incorrect CyBox version installed, found $current, expecting $expected'), 1 => __('OK'));
$mixboxVersion = array(0 => __('Incorrect mixbox version installed, found $current, expecting $expected'), 1 => __('OK'));
$maecVersion = array(0 => __('Incorrect maec version installed, found $current, expecting $expected'), 1 => __('OK'));
$pymispVersion = array(0 => __('Incorrect PyMISP version installed, found $current, expecting $expected'), 1 => __('OK'));
$sessionErrors = array(0 => __('OK'), 1 => __('High'), 2 => __('Alternative setting used'), 3 => __('Test failed'));
$moduleErrors = array(0 => __('OK'), 1 => __('System not enabled'), 2 => __('No modules found'));
$finalSettings = $this->Server->serverSettingsRead();
$issues = array(
'errors' => array(
0 => array(
'value' => 0,
'description' => 'MISP will not operate correctly or will be unsecure until these issues are resolved.'
'description' => __('MISP will not operate correctly or will be unsecure until these issues are resolved.')
),
1 => array(
'value' => 0,
'description' => 'Some of the features of MISP cannot be utilised until these issues are resolved.'
'description' => __('Some of the features of MISP cannot be utilised until these issues are resolved.')
),
2 => array(
'value' => 0,
'description' => 'There are some optional tweaks that could be done to improve the looks of your MISP instance.'
'description' => __('There are some optional tweaks that could be done to improve the looks of your MISP instance.')
),
),
'deprecated' => array(),
@ -1137,15 +1141,29 @@ class ServersController extends AppController
}
}
public function getSubmodulesStatus() {
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException();
}
$this->set('submodules', $this->Server->getSubmodulesGitStatus());
$this->render('ajax/submoduleStatus');
}
public function serverSettingsEdit($setting_name, $id = false, $forceSave = false)
{
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException();
}
if (!isset($setting_name) || !isset($id)) {
if (!isset($setting_name)) {
throw new MethodNotAllowedException();
}
$this->set('id', $id);
if (!$this->_isRest()) {
if (!isset($id)) {
throw new MethodNotAllowedException();
}
$this->set('id', $id);
}
$setting = $this->Server->getSettingData($setting_name);
if ($this->request->is('get')) {
if ($setting != null) {
@ -1568,6 +1586,23 @@ class ServersController extends AppController
{
App::uses('SyncTool', 'Tools');
$params = array();
$this->loadModel('RestClientHistory');
$this->RestClientHistory->create();
$date = new DateTime();
$rest_history_item = array(
'org_id' => $this->Auth->user('org_id'),
'user_id' => $this->Auth->user('id'),
'headers' => $request['header'],
'body' => empty($request['body']) ? '' : $request['body'],
'url' => $request['url'],
'http_method' => $request['method'],
'use_full_path' => $request['use_full_path'],
'show_result' => $request['show_result'],
'skip_ssl' => $request['skip_ssl_validation'],
'bookmark' => $request['bookmark'],
'bookmark_name' => $request['name'],
'timestamp' => $date->getTimestamp()
);
if (!empty($request['url'])) {
if (empty($request['use_full_path'])) {
$path = preg_replace('#^(://|[^/?])+#', '', $request['url']);
@ -1581,6 +1616,8 @@ class ServersController extends AppController
}
if (!empty($request['skip_ssl_validation'])) {
$params['ssl_verify_peer'] = false;
$params['ssl_verify_host'] = false;
$params['ssl_allow_self_signed'] = true;
}
$params['timeout'] = 300;
App::uses('HttpSocket', 'Network/Http');
@ -1638,6 +1675,9 @@ class ServersController extends AppController
$view_data['data'] = 'Something went wrong.';
}
}
$rest_history_item['outcome'] = $response->code;
$this->RestClientHistory->save($rest_history_item);
$this->RestClientHistory->cleanup($this->Auth->user('id'));
return $view_data;
}
@ -1678,7 +1718,7 @@ misp.direct_call(relative_path, body)
$request['header']['Authorization'],
$verifyCert,
$relative,
(empty($request['body']) ? 'Null' : '\'' . $request['body'] . '\'')
(empty($request['body']) ? 'Null' : $request['body'])
);
return $python_script;
}

View File

@ -68,6 +68,7 @@ class ShadowAttributesController extends AppController
if (empty($shadow)) {
return array('false' => true, 'errors' => 'Proposal not found or you are not authorised to accept it.');
}
$this->ShadowAttribute->publishKafkaNotification('shadow_attribute', $shadow, 'accept');
$shadow = $shadow['ShadowAttribute'];
if ($this->ShadowAttribute->typeIsAttachment($shadow['type'])) {
$encodedFile = $this->ShadowAttribute->base64EncodeAttachment($shadow);
@ -229,6 +230,7 @@ class ShadowAttributesController extends AppController
if (empty($sa)) {
return false;
}
$this->ShadowAttribute->publishKafkaNotification('shadow_attribute', $sa, 'discard');
$eventId = $sa['ShadowAttribute']['event_id'];
$this->loadModel('Event');
$this->Event->Behaviors->detach('SysLogLogable.SysLogLogable');

View File

@ -227,9 +227,6 @@ class TagCollectionsController extends AppController
public function addTag($id = false, $tag_id = false)
{
if (!$this->request->is('post')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
$rearrangeRules = array(
'request' => false,
'TagCollection' => false,
@ -242,102 +239,110 @@ class TagCollectionsController extends AppController
if ($id === false) {
$id = $this->request->data['tag_collection'];
}
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
$conditions = array();
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 (!is_numeric($tag_id)) {
$tag_ids = json_decode($tag_id);
$tag_lookups = array();
foreach ($tag_ids as $temp) {
if (is_numeric($temp)) {
$tag_lookups['OR']['Tag.id'][] = $temp;
} else {
$tag_lookups['OR']['LOWER(Tag.name) LIKE'][] = strtolower(trim($tag_id));
}
}
if ($tag_ids !== null && is_array($tag_ids)) { // can decode json
$tag_ids = $this->TagCollection->TagCollectionTag->Tag->find('list', array(
'conditions' => array(
'AND' => array(
$conditions,
$tag_lookups
)
),
'fields' => array('Tag.id', 'Tag.id')
));
$tag_id_list = array_values($tag_ids);
if (empty($tag_id_list)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag(s).')), 'status'=>200, 'type' => 'json'));
}
} else {
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'conditions' => array('TagCollection.id' => $id)
));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid tag collection.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->_isSiteAdmin()) {
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $tagCollection['TagCollection']['org_id'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
}
$this->autoRender = false;
$error = false;
$success = false;
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
foreach ($tag_id_list as $tag_id) {
$this->TagCollection->TagCollectionTag->Tag->id = $tag_id;
if (!$this->TagCollection->TagCollectionTag->Tag->exists()) {
$error = __('Invalid Tag.');
continue;
}
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->TagCollection->TagCollectionTag->find('first', array(
'conditions' => array(
'tag_collection_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
if (!empty($found)) {
$error = __('Tag is already attached to this event.');
continue;
}
$this->TagCollection->TagCollectionTag->create();
if ($this->TagCollection->TagCollectionTag->save(array('tag_collection_id' => $id, 'tag_id' => $tag_id))) {
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'TagCollection', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to collection (' . $id . ')', 'Event (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success = __('Tag(s) added.');
} else {
$fail = __('Tag(s) could not be added.');
}
}
if ($success) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $success)), 'status'=>200, 'type' => 'json'));
} elseif (empty($fail)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('All tags are already present, nothing to add.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
if (!$this->request->is('post')) {
$this->set('object_id', $id);
$this->set('scope', 'TagCollection');
$this->layout = false;
$this->autoRender = false;
$this->render('/Events/add_tag');
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $fail)), 'status'=>200, 'type' => 'json'));
if ($tag_id === false) {
$tag_id = $this->request->data['tag'];
}
$conditions = array();
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 (!is_numeric($tag_id)) {
$tag_ids = json_decode($tag_id);
$tag_lookups = array();
foreach ($tag_ids as $temp) {
if (is_numeric($temp)) {
$tag_lookups['OR']['Tag.id'][] = $temp;
} else {
$tag_lookups['OR']['LOWER(Tag.name) LIKE'][] = strtolower(trim($tag_id));
}
}
if ($tag_ids !== null && is_array($tag_ids)) { // can decode json
$tag_ids = $this->TagCollection->TagCollectionTag->Tag->find('list', array(
'conditions' => array(
'AND' => array(
$conditions,
$tag_lookups
)
),
'fields' => array('Tag.id', 'Tag.id')
));
$tag_id_list = array_values($tag_ids);
if (empty($tag_id_list)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag(s).')), 'status'=>200, 'type' => 'json'));
}
} else {
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'conditions' => array('TagCollection.id' => $id)
));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid tag collection.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->_isSiteAdmin()) {
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $tagCollection['TagCollection']['org_id'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
}
$this->autoRender = false;
$error = false;
$success = false;
if (empty($tag_id_list)) {
$tag_id_list = array($tag_id);
}
foreach ($tag_id_list as $tag_id) {
$this->TagCollection->TagCollectionTag->Tag->id = $tag_id;
if (!$this->TagCollection->TagCollectionTag->Tag->exists()) {
$error = __('Invalid Tag.');
continue;
}
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array(
'conditions' => array('Tag.id' => $tag_id),
'recursive' => -1,
'fields' => array('Tag.name')
));
$found = $this->TagCollection->TagCollectionTag->find('first', array(
'conditions' => array(
'tag_collection_id' => $id,
'tag_id' => $tag_id
),
'recursive' => -1,
));
if (!empty($found)) {
$error = __('Tag is already attached to this event.');
continue;
}
$this->TagCollection->TagCollectionTag->create();
if ($this->TagCollection->TagCollectionTag->save(array('tag_collection_id' => $id, 'tag_id' => $tag_id))) {
$log = ClassRegistry::init('Log');
$log->createLogEntry($this->Auth->user(), 'tag', 'TagCollection', $id, 'Attached tag (' . $tag_id . ') "' . $tag['Tag']['name'] . '" to collection (' . $id . ')', 'Event (' . $id . ') tagged as Tag (' . $tag_id . ')');
$success = __('Tag(s) added.');
} else {
$fail = __('Tag(s) could not be added.');
}
}
if ($success) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $success)), 'status'=>200, 'type' => 'json'));
} elseif (empty($fail)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => __('All tags are already present, nothing to add.'), 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => $fail)), 'status'=>200, 'type' => 'json'));
}
}
}

View File

@ -476,6 +476,7 @@ class TagsController extends AppController
'fields' => array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.user_id'),
'conditions' => array('Event.id' => $id)
));
$this->set('required_taxonomies', $this->EventTag->Event->getRequiredTaxonomies());
$this->set('event', $event);
$this->layout = 'ajax';
$this->render('/Events/ajax/ajaxTags');

View File

@ -54,10 +54,24 @@ class TaxonomiesController extends AppController
$filter = isset($this->passedArgs['filter']) ? $this->passedArgs['filter'] : false;
$taxonomy = $this->Taxonomy->getTaxonomy($id, array('full' => true, 'filter' => $filter));
if (empty($taxonomy)) {
throw new NotFoundException('Taxonomy not found.');
throw new NotFoundException(__('Taxonomy not found.'));
}
$this->loadModel('EventTag');
$this->loadModel('AttributeTag');
foreach ($taxonomy['entries'] as $key => $value) {
$taxonomy['entries'][$key]['events'] = empty($value['existing_tag']) ? 0 : count($value['existing_tag']['EventTag']);
$count = 0;
if (!empty($value['existing_tag'])) {
foreach ($value['existing_tag'] as $et) {
$count = $this->EventTag->find('count', array(
'conditions' => array('EventTag.tag_id' => $et['id'])
));
$count_a = $this->AttributeTag->find('count', array(
'conditions' => array('AttributeTag.tag_id' => $et['id'])
));
}
}
$taxonomy['entries'][$key]['events'] = $count;
$taxonomy['entries'][$key]['attributes'] = $count_a;
}
$this->set('filter', $filter);
$customPagination = new CustomPaginationTool();
@ -82,7 +96,7 @@ class TaxonomiesController extends AppController
public function enable($id)
{
if (!$this->_isSiteAdmin() || !$this->request->is('Post')) {
throw new MethodNotAllowedException('You don\'t have permission to do that.');
throw new MethodNotAllowedException(__('You don\'t have permission to do that.'));
}
$taxonomy = $this->Taxonomy->find('first', array(
'recursive' => -1,
@ -105,7 +119,7 @@ class TaxonomiesController extends AppController
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Taxonomy', 'enable', $id, $this->response->type());
} else {
$this->Flash->success('Taxonomy enabled.');
$this->Flash->success(__('Taxonomy enabled.'));
$this->redirect($this->referer());
}
}
@ -113,7 +127,7 @@ class TaxonomiesController extends AppController
public function disable($id)
{
if (!$this->_isSiteAdmin() || !$this->request->is('Post')) {
throw new MethodNotAllowedException('You don\'t have permission to do that.');
throw new MethodNotAllowedException(__('You don\'t have permission to do that.'));
}
$taxonomy = $this->Taxonomy->find('first', array(
'recursive' => -1,
@ -137,7 +151,7 @@ class TaxonomiesController extends AppController
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Taxonomy', 'disable', $id, $this->response->type());
} else {
$this->Flash->success('Taxonomy disabled.');
$this->Flash->success(__('Taxonomy disabled.'));
$this->redirect($this->referer());
}
}
@ -145,7 +159,7 @@ class TaxonomiesController extends AppController
public function update()
{
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException('You don\'t have permission to do that.');
throw new MethodNotAllowedException(__('You don\'t have permission to do that.'));
}
$result = $this->Taxonomy->update();
$this->Log = ClassRegistry::init('Log');
@ -205,15 +219,15 @@ class TaxonomiesController extends AppController
$message = '';
if ($successes == 0 && $fails == 0) {
$flashType = 'info';
$message = 'All taxonomy libraries are up to date already.';
$message = __('All taxonomy libraries are up to date already.');
} elseif ($successes == 0) {
$flashType = 'error';
$message = 'Could not update any of the taxonomy libraries';
$message = __('Could not update any of the taxonomy libraries');
} else {
$flashType = 'success';
$message = 'Successfully updated ' . $successes . ' taxonomy libraries.';
$message = __('Successfully updated ') . $successes . __(' taxonomy libraries.');
if ($fails != 0) {
$message .= ' However, could not update ' . $fails . ' taxonomy libraries.';
$message .= __(' However, could not update ') . $fails . __(' taxonomy libraries.');
}
}
if ($this->_isRest()) {
@ -227,7 +241,7 @@ class TaxonomiesController extends AppController
public function addTag($taxonomy_id = false)
{
if ((!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) || !$this->request->is('post')) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
if ($taxonomy_id) {
$result = $this->Taxonomy->addTags($taxonomy_id);
@ -247,9 +261,9 @@ class TaxonomiesController extends AppController
$result = $this->Taxonomy->addTags($this->request->data['Tag']['taxonomy_id'], $this->request->data['Tag']['nameList']);
}
if ($result) {
$this->Flash->success('The tag(s) has been saved.');
$this->Flash->success(__('The tag(s) has been saved.'));
} else {
$this->Flash->error('The tag(s) could not be saved. Please, try again.');
$this->Flash->error(__('The tag(s) could not be saved. Please, try again.'));
}
$this->redirect($this->referer());
}
@ -257,7 +271,7 @@ class TaxonomiesController extends AppController
public function hideTag($taxonomy_id = false)
{
if ((!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) || !$this->request->is('post')) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
if ($taxonomy_id) {
$result = $this->Taxonomy->hideTags($taxonomy_id);
@ -277,9 +291,9 @@ class TaxonomiesController extends AppController
$result = $this->Taxonomy->hideTags($this->request->data['Tag']['taxonomy_id'], $this->request->data['Tag']['nameList']);
}
if ($result) {
$this->Flash->success('The tag(s) has been saved.');
$this->Flash->success(__('The tag(s) has been saved.'));
} else {
$this->Flash->error('The tag(s) could not be saved. Please, try again.');
$this->Flash->error(__('The tag(s) could not be saved. Please, try again.'));
}
$this->redirect($this->referer());
}
@ -287,7 +301,7 @@ class TaxonomiesController extends AppController
public function unhideTag($taxonomy_id = false)
{
if ((!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) || !$this->request->is('post')) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
if ($taxonomy_id) {
$result = $this->Taxonomy->unhideTags($taxonomy_id);
@ -307,9 +321,9 @@ class TaxonomiesController extends AppController
$result = $this->Taxonomy->unhideTags($this->request->data['Tag']['taxonomy_id'], $this->request->data['Tag']['nameList']);
}
if ($result) {
$this->Flash->success('The tag(s) has been saved.');
$this->Flash->success(__('The tag(s) has been saved.'));
} else {
$this->Flash->error('The tag(s) could not be saved. Please, try again.');
$this->Flash->error(__('The tag(s) could not be saved. Please, try again.'));
}
$this->redirect($this->referer());
}
@ -317,7 +331,7 @@ class TaxonomiesController extends AppController
public function disableTag($taxonomy_id = false)
{
if ((!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) || !$this->request->is('post')) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
if ($taxonomy_id) {
$result = $this->Taxonomy->disableTags($taxonomy_id);
@ -337,9 +351,9 @@ class TaxonomiesController extends AppController
$result = $this->Taxonomy->disableTags($this->request->data['Tag']['taxonomy_id'], $this->request->data['Tag']['nameList']);
}
if ($result) {
$this->Flash->success('The tag(s) has been hidden.');
$this->Flash->success(__('The tag(s) has been hidden.'));
} else {
$this->Flash->error('The tag(s) could not be hidden. Please, try again.');
$this->Flash->error(__('The tag(s) could not be hidden. Please, try again.'));
}
$this->redirect($this->referer());
}
@ -347,7 +361,7 @@ class TaxonomiesController extends AppController
public function taxonomyMassConfirmation($id)
{
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
$this->set('id', $id);
$this->render('ajax/taxonomy_mass_confirmation');
@ -356,7 +370,7 @@ class TaxonomiesController extends AppController
public function taxonomyMassHide($id)
{
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
$this->set('id', $id);
$this->render('ajax/taxonomy_mass_hide');
@ -365,7 +379,7 @@ class TaxonomiesController extends AppController
public function taxonomyMassUnhide($id)
{
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
throw new NotFoundException('You don\'t have permission to do that.');
throw new NotFoundException(__('You don\'t have permission to do that.'));
}
$this->set('id', $id);
$this->render('ajax/taxonomy_mass_unhide');
@ -376,10 +390,10 @@ class TaxonomiesController extends AppController
if ($this->request->is('post')) {
$result = $this->Taxonomy->delete($id, true);
if ($result) {
$this->Flash->success('Taxonomy successfuly deleted.');
$this->Flash->success(__('Taxonomy successfuly deleted.'));
$this->redirect(array('controller' => 'taxonomies', 'action' => 'index'));
} else {
$this->Flash->error('Taxonomy could not be deleted.');
$this->Flash->error(__('Taxonomy could not be deleted.'));
$this->redirect(array('controller' => 'taxonomies', 'action' => 'index'));
}
} else {
@ -387,8 +401,34 @@ class TaxonomiesController extends AppController
$this->set('id', $id);
$this->render('ajax/taxonomy_delete_confirmation');
} else {
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
throw new MethodNotAllowedException(__('This function can only be reached via AJAX.'));
}
}
}
public function toggleRequired($id)
{
$taxonomy = $this->Taxonomy->find('first', array(
'recursive' => -1,
'conditions' => array('Taxonomy.id' => $id)
));
if (empty($taxonomy)) {
return $this->RestResponse->saveFailResponse('Taxonomy', 'toggleRequired', $id, 'Invalid Taxonomy', $this->response->type());
}
if ($this->request->is('post')) {
$taxonomy['Taxonomy']['required'] = $this->request->data['Taxonomy']['required'];
$result = $this->Taxonomy->save($taxonomy);
if ($result) {
return $this->RestResponse->saveSuccessResponse('Taxonomy', 'toggleRequired', $id, $this->response->type());
} else {
return $this->RestResponse->saveFailResponse('Taxonomy', 'toggleRequired', $id, $this->validationError, $this->response->type());
}
} else {
$this->set('required', !$taxonomy['Taxonomy']['required']);
$this->set('id', $id);
$this->autoRender = false;
$this->layout = 'ajax';
$this->render('ajax/toggle_required');
}
}
}

View File

@ -1148,7 +1148,7 @@ class UsersController extends AppController
$this->_refreshAuth();
$this->redirect($this->referer());
} else {
return $this->RestResponse->saveSuccessResponse('User', 'resetauthkey', $id, $this->response->type(), 'User\'s authkey has been reset.');
return $this->RestResponse->saveSuccessResponse('User', 'resetauthkey', $id, $this->response->type(), 'Authkey updated: ' . $newkey);
}
}
@ -1553,7 +1553,7 @@ class UsersController extends AppController
public function statistics($page = 'data')
{
$this->set('page', $page);
$pages = array('data' => 'Usage data', 'orgs' => 'Organisations', 'users' => 'User and Organisation statistics', 'tags' => 'Tags', 'attributehistogram' => 'Attribute histogram', 'sightings' => 'Sightings toplists', 'attackMatrix' => 'ATT&CK Matrix');
$pages = array('data' => 'Usage data', 'orgs' => 'Organisations', 'users' => 'User and Organisation statistics', 'tags' => 'Tags', 'attributehistogram' => 'Attribute histogram', 'sightings' => 'Sightings toplists', 'galaxyMatrix' => 'Galaxy Matrix');
if (!$this->_isSiteAdmin() && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
unset($pages['orgs']);
}
@ -1578,8 +1578,8 @@ class UsersController extends AppController
}
} elseif ($page == 'sightings') {
$result = $this->__statisticsSightings($this->params['named']);
} elseif ($page == 'attackMatrix') {
$result = $this->__statisticsAttackMatrix($this->params['named']);
} elseif ($page == 'galaxyMatrix') {
$result = $this->__statisticsGalaxyMatrix($this->params['named']);
}
if ($this->_isRest()) {
return $result;
@ -1881,12 +1881,16 @@ class UsersController extends AppController
}
}
private function __statisticsAttackMatrix($params = array())
private function __statisticsGalaxyMatrix($params = array())
{
$this->loadModel('Event');
$this->loadModel('Galaxy');
$galaxy_id = $this->Galaxy->getMitreAttackGalaxyId();
$mitre_galaxy_id = $this->Galaxy->getMitreAttackGalaxyId();
if (isset($params['galaxy_id'])) {
$galaxy_id = $params['galaxy_id'];
} else {
$galaxy_id = $mitre_galaxy_id;
}
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
$tabs = $matrixData['tabs'];
@ -1903,7 +1907,7 @@ class UsersController extends AppController
$maxScore = max($scoresDataAttr['maxScore'], $scoresDataEvent['maxScore']);
$scores = $scoresData;
// FIXME: temporary fix: add the score of deprecated mitre galaxies to the new one (for the stats)
if ($matrixData['galaxy']['id'] == $galaxy_id) {
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
$mergedScore = array();
foreach ($scoresData as $tag => $v) {
$predicateValue = explode(':', $tag, 2)[1];
@ -1963,10 +1967,17 @@ class UsersController extends AppController
$this->set('interpolation', $colours['interpolation']);
}
$this->set('pickingMode', false);
$this->set('defaultTabName', "mitre-attack");
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
$this->set('defaultTabName', "mitre-attack");
}
$this->set('removeTrailling', 2);
$this->render('statistics_attackmatrix');
$this->set('galaxyName', $matrixData['galaxy']['name']);
$this->set('galaxyId', $matrixData['galaxy']['id']);
$matrixGalaxies = $this->Galaxy->getAllowedMatrixGalaxies();
$this->set('matrixGalaxies', $matrixGalaxies);
$this->render('statistics_galaxymatrix');
}
}

View File

@ -162,8 +162,8 @@ class BroExport
$orgName = $instanceString . ' (' . $item['Event']['uuid'] . ')' . ' - ' . $orgs[$item['Event']['orgc_id']];
}
$ruleFormatReference = Configure::read('MISP.baseurl') . '/events/view/' . $item['Event']['id'];
$ruleFormat = "%s\t%s\t" . $orgName . "\t" . $this->replaceIllegalChars($item['Event']['info']) . ". %s" . "\t" . $ruleFormatReference . "\t%s\t%s";
$rule = $this->__generateRule($item['Attribute'], $ruleFormat, $valueField, $whitelist);
$ruleFormat = "%s\t%s\t" . $orgName . "\t%s. %s\t" . $ruleFormatReference . "\t%s\t%s";
$rule = $this->__generateRule($item, $ruleFormat, $valueField, $whitelist);
if (!empty($rule)) {
$intel[] = $rule;
}
@ -171,32 +171,33 @@ class BroExport
return $intel;
}
private function __generateRule($attribute, $ruleFormat, $valueField, $whitelist = array())
private function __generateRule($item, $ruleFormat, $valueField, $whitelist = array())
{
if (isset($this->mapping[$attribute['type']])) {
if (empty($whitelist) || !$this->checkWhitelist($attribute['value'], $whitelist)) {
$brotype = $this->mapping[$attribute['type']]['brotype'];
if (isset($this->mapping[$attribute['type']]['alternate'])) {
if (preg_match($this->mapping[$attribute['type']]['alternate'][0], $attribute['value'])) {
$brotype = $this->mapping[$attribute['type']]['alternate'][1];
if (isset($this->mapping[$item['Attribute']['type']])) {
if (empty($whitelist) || !$this->checkWhitelist($item['Attribute']['value' . $valueField], $whitelist)) {
$brotype = $this->mapping[$item['Attribute']['type']]['brotype'];
if (isset($this->mapping[$item['Attribute']['type']]['alternate'])) {
if (preg_match($this->mapping[$item['Attribute']['type']]['alternate'][0], $item['Attribute']['value' . $valueField])) {
$brotype = $this->mapping[$item['Attribute']['type']]['alternate'][1];
}
}
if ($valueField == 2 && isset($this->mapping[$attribute['type']]['composite'])) {
$brotype = $this->mapping[$attribute['type']]['composite'];
if ($valueField == 2 && isset($this->mapping[$item['Attribute']['type']]['composite'])) {
$brotype = $this->mapping[$item['Attribute']['type']]['composite'];
}
$attribute['value'] = $this->replaceIllegalChars($attribute['value']); // substitute chars not allowed in rule
if (isset($this->mapping[$attribute['type']]['replace'])) {
$attribute['value'] = preg_replace(
$this->mapping[$attribute['type']]['replace'][0],
$this->mapping[$attribute['type']]['replace'][1],
$attribute['value']
$item['Attribute']['value' . $valueField] = $this->replaceIllegalChars($item['Attribute']['value' . $valueField]); // substitute chars not allowed in rule
if (isset($this->mapping[$item['Attribute']['type']]['replace'])) {
$item['Attribute']['value' . $valueField] = preg_replace(
$this->mapping[$item['Attribute']['type']]['replace'][0],
$this->mapping[$item['Attribute']['type']]['replace'][1],
$item['Attribute']['value' . $valueField]
);
}
return sprintf(
$ruleFormat,
$this->replaceIllegalChars($attribute['value']), // value - for composite values only the relevant element is taken
$this->replaceIllegalChars($item['Attribute']['value' . $valueField]), // value - for composite values only the relevant element is taken
'Intel::' . $brotype, // type
$this->replaceIllegalChars($attribute['comment']),
$this->replaceIllegalChars($item['Event']['info']),
$this->replaceIllegalChars($item['Attribute']['comment']),
'T', // meta.do_notice
'-' // meta.if_in
);

View File

@ -169,6 +169,7 @@ class RPZExport
public function buildHeader($rpzSettings)
{
$rpzSettings['serial'] = str_replace('$date', date('Ymd'), $rpzSettings['serial']);
$rpzSettings['serial'] = str_replace('$time', time(), $rpzSettings['serial']);
$header = '';
$header .= '$TTL ' . $rpzSettings['ttl'] . ';' . PHP_EOL;
$header .= '@ SOA ' . $rpzSettings['ns'] . ' ' . $rpzSettings['email'] . ' (' . $rpzSettings['serial'] . ' ' . $rpzSettings['refresh'] . ' ' . $rpzSettings['retry'] . ' ' . $rpzSettings['expiry'] . ' ' . $rpzSettings['minimum_ttl'] . ')' . PHP_EOL;

View File

@ -352,7 +352,7 @@ class ComplexTypeTool
// Phone numbers - for automatic recognition, needs to start with + or include dashes
if (!empty($input['raw'])) {
if ($input['raw'][0] === '+' || strpos($input['raw'], '-')) {
if (preg_match("#^(\+)?([0-9]{1,3}(\(0\))?)?[0-9\/\-]{5,}[0-9]$#i", $input['raw'])) {
if (!preg_match('#^[0-9]{4}-[0-9]{2}-[0-9]{2}$#i', $input['raw']) && preg_match("#^(\+)?([0-9]{1,3}(\(0\))?)?[0-9\/\-]{5,}[0-9]$#i", $input['raw'])) {
return array('types' => array('phone-number', 'prtn', 'whois-registrant-phone'), 'categories' => array('Other'), 'to_ids' => false, 'default_type' => 'phone-number', 'value' => $input['raw']);
}
}

View File

@ -16,8 +16,8 @@
// construct distribution info
$this->__json['distributionInfo'] = array();
$sgs = $this->__eventModel->SharingGroup->fetchAllAuthorised($this->__user, 'name', 1);
$this->__json['allSharingGroup'] = h(array_values($sgs));
$sgs = $this->__eventModel->SharingGroup->fetchAllAuthorised($this->__user, 'simplified', 1);
$this->__json['allSharingGroup'] = h($sgs);
$distributionLevels = $this->__eventModel->distributionLevels;
foreach ($distributionLevels as $key => $value) {
$this->__json['distributionInfo'][$key] = array('key' => h($value), 'desc' => h($this->__eventModel->distributionDescriptions[$key]['formdesc']), 'value' => h($key));
@ -59,6 +59,12 @@
$this->__json['additionalDistributionInfo'][$distributionLevel] = array();
}
$this->__json['additionalDistributionInfo'][$distributionLevel][h($data)] = 0; // set-alike
if ($distributionLevel == 4) {
if (!isset($this->__json['sharingGroupRepartition'][h($data)])) {
$this->__json['sharingGroupRepartition'][h($data)] = 0;
}
$this->__json['sharingGroupRepartition'][h($data)]++;
}
}
private function __addOtherDistributionInfo()
@ -124,17 +130,28 @@
public function get_distributions_graph($id)
{
$event = $this->__get_event($id);
$eventDist = $event['distribution'];
$eventSGName = $event['SharingGroupName'];
$this->__eventDistribution = $eventDist;
$this->__eventSharingGroupName = $eventSGName;
$this->__json['event'] = $this->init_array_distri();
$this->__json['attribute'] = $this->init_array_distri();
$this->__json['object'] = $this->init_array_distri();
$this->__json['obj_attr'] = $this->init_array_distri();
$this->__json['additionalDistributionInfo'] = $this->init_array_distri(array());
$this->__json['sharingGroupRepartition'] = array();
$this->__addOtherDistributionInfo();
// transform set into array
foreach (array_keys($this->__json['additionalDistributionInfo']) as $d) {
$this->__json['additionalDistributionInfo'][$d] = array_keys($this->__json['additionalDistributionInfo'][$d]);
}
if ($id === -1) {
return $this->__json;
}
$event = $this->__get_event($id);
$eventDist = $event['distribution'];
$eventSGName = $event['SharingGroupName'];
$this->__eventDistribution = $eventDist;
$this->__eventSharingGroupName = $eventSGName;
if (empty($event)) {
return $this->__json;
@ -188,13 +205,8 @@
unset($this->__json['distributionInfo'][5]); // inherit event.
$this->__addOtherDistributionInfo();
// transform set into array
foreach (array_keys($this->__json['additionalDistributionInfo']) as $d) {
$this->__json['additionalDistributionInfo'][$d] = array_keys($this->__json['additionalDistributionInfo'][$d]);
}
// transform set into array for SG (others are already done)
$this->__json['additionalDistributionInfo'][4] = array_keys($this->__json['additionalDistributionInfo'][4]);
return $this->__json;
}

View File

@ -0,0 +1,55 @@
<?php
class KafkaPubTool
{
private $rdkafka = false;
private function __error($msg)
{
error_log($msg, 3, APP . 'tmp' . DS . 'logs' . DS . 'kafka.error.log');
}
public function initTool($brokers, $config)
{
if (!$this->rdkafka) {
try {
$rdConf = new RdKafka\Conf();
foreach ($config as $key => $val) {
if (!empty($val)) {
$rdConf->set($key, $val);
}
}
$rdConf->setErrorCb(function ($kafka, $err, $reason) {
$this->__error(sprintf("%s (reason: %s)\n", rd_kafka_err2str($err), $reason));
});
$rdkafka = new RdKafka\Producer($rdConf);
if ($rdkafka->addBrokers($brokers) == 0) {
$this->__error("Could not add any Kafka brokers");
}
$this->rdkafka = $rdkafka;
} catch (Exception $e) {
$this->__error('Exception: ' . $e->getMessage() . "\n");
}
}
}
public function publishJson($topicName, $data, $action = false)
{
try {
if (!empty($action)) {
$data['action'] = $action;
}
$body = json_encode($data);
if (!$body) {
$this->__error("Error encoding to JSON: ". $data);
}
if (!empty($this->rdkafka)) {
$topic = $this->rdkafka->newTopic($topicName);
$topic->produce(RD_KAFKA_PARTITION_UA, 0, $body);
$this->rdkafka->poll(0);
}
} catch (Exception $e) {
$this->__error('Exception: ' . $e->getMessage() . "\n");
}
}
}

@ -1 +1 @@
Subproject commit ab5578dbc9f88e661d2b017489cd156fca961429
Subproject commit c4a51509c554a0762e8b4d9b3985fe042b445fe7

View File

@ -7345,21 +7345,8 @@ msgstr ""
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr ""
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
>>>>>>> 2.4
msgstr ""
#: View/Events/legacy_automation.ctp:312

View File

@ -7357,23 +7357,9 @@ msgstr "Events med datoen sat til en dato efter den der blev specificeret i fra
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
msgstr "Events med datoen sat til en dato før den angivne i feltet til (format: 2015-02-15)"
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:312
msgid "Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned."
msgstr "Begræns resultaterne ved hjælp af tidsstempel (på attributten). Eventuelle attributter med et tidsstempel nyere end den angivne tidsstempel returneres."
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
msgstr "Filter"
>>>>>>> 2.4
#: View/Events/legacy_automation.ctp:317
msgid "Only return attributes from events that have received a modification after the given timestamp."

File diff suppressed because it is too large Load Diff

View File

@ -7349,21 +7349,8 @@ msgstr ""
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
msgstr ""
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:312
msgid "Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned."
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
>>>>>>> 2.4
msgstr ""
#: View/Events/legacy_automation.ctp:317

0
app/Locale/fra/LC_MESSAGES/cake_dev.po Normal file → Executable file
View File

View File

@ -7364,23 +7364,9 @@ msgstr "Pour ne retourner qu'une liste d'attributs, utiliser la syntaxe suivante
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr "Événements avec une date définie à une date supérieure à celle spécifiée dans le champ \"from\" (format : 2015-02-15)"
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
msgstr "Événements avec une date définie à une date antérieure à celle spécifiée dans le champ \"to\" (format : 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
msgstr "Filtre"
>>>>>>> 2.4
#: View/Events/legacy_automation.ctp:312
msgid "Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned."

View File

@ -7350,23 +7350,9 @@ msgstr "Per ottenere una elenco di attributi, utilizzare la sintassi seguente"
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr "Eventi con data successiva a quella specificata nel capo da (formato: 2015-02-15)"
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
msgstr "Eventi con data precedente a quella specificata nel capo da (formato: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
msgstr "Filtro"
>>>>>>> 2.4
#: View/Events/legacy_automation.ctp:312
msgid "Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned."

View File

@ -7358,23 +7358,9 @@ msgstr "アトリビュートのリストを返すには、次のシンタック
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr "from 項目で指定された日付より後の日付のイベント (フォーマット: 2015-02-15)"
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
msgstr "to 項目に指定された日付より前の日付のイベント (フォーマット: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
msgstr "フィルター"
>>>>>>> 2.4
#: View/Events/legacy_automation.ctp:312
msgid "Restrict the results by the timestamp (of the attribute). Any attributes with a timestamp newer than the given timestamp will be returned."

View File

@ -7345,21 +7345,8 @@ msgstr ""
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr ""
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
>>>>>>> 2.4
msgstr ""
#: View/Events/legacy_automation.ctp:312

View File

@ -7345,21 +7345,8 @@ msgstr ""
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr ""
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
>>>>>>> 2.4
msgstr ""
#: View/Events/legacy_automation.ctp:312

File diff suppressed because it is too large Load Diff

View File

@ -7345,21 +7345,8 @@ msgstr ""
msgid "Events with the date set to a date after the one specified in the from field (format: 2015-02-15)"
msgstr ""
<<<<<<< HEAD
#: View/Events/legacy_automation.ctp:305
msgid "Events with the date set to a date before the one specified in the to field (format: 2015-02-15)"
=======
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
>>>>>>> 2.4
msgstr ""
#: View/Events/legacy_automation.ctp:312

View File

@ -7014,27 +7014,7 @@ msgstr ""
msgid "Delete selected Events"
msgstr ""
<<<<<<< HEAD
#: View/Events/index.ctp:73
=======
#: View/Events/index.ctp:44
msgid "Quickfilter"
msgstr ""
#: View/Events/index.ctp:95
msgid "Enter value to search"
msgstr ""
#: View/Events/index.ctp:44
#: View/Organisations/index.ctp:59
#: View/Servers/preview_index.ctp:45
#: View/Tags/index.ctp:56
#: View/Taxonomies/view.ctp:65
msgid "Filter"
msgstr ""
#: View/Events/index.ctp:58
>>>>>>> 2.4
msgid "My events only"
msgstr ""

View File

@ -30,6 +30,8 @@ class AppModel extends Model
public $loadedPubSubTool = false;
public $loadedKafkaPubTool = false;
public $start = 0;
public $inserted_ids = array();
@ -72,7 +74,8 @@ class AppModel extends Model
7 => false, 8 => false, 9 => false, 10 => false, 11 => false, 12 => false,
13 => false, 14 => false, 15 => false, 18 => false, 19 => false, 20 => false,
21 => false, 22 => false, 23 => false, 24 => false, 25 => false, 26 => false,
27 => false, 28 => false, 29 => false, 30 => false
27 => false, 28 => false, 29 => false, 30 => false, 31 => false, 32 => false,
33 => false, 34 => false
);
public function afterSave($created, $options = array())
@ -168,6 +171,9 @@ class AppModel extends Model
case 23:
$this->__bumpReferences();
break;
case 34:
$this->__fixServerPullPushRules();
break;
default:
$this->updateDatabase($command);
break;
@ -1096,6 +1102,34 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `galaxies` MODIFY COLUMN `kill_chain_order` text";
$sqlArray[] = "ALTER TABLE `feeds` ADD `force_to_ids` tinyint(1) NOT NULL DEFAULT 0;";
break;
case 31:
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `rest_client_histories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`org_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`headers` text,
`body` text,
`url` text,
`http_method` varchar(255),
`timestamp` int(11) NOT NULL DEFAULT 0,
`use_full_path` tinyint(1) DEFAULT 0,
`show_result` tinyint(1) DEFAULT 0,
`skip_ssl` tinyint(1) DEFAULT 0,
`outcome` int(11) NOT NULL,
`bookmark` tinyint(1) NOT NULL DEFAUlT 0,
`bookmark_name` varchar(255) NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `org_id` (`org_id`),
KEY `user_id` (`user_id`),
KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
break;
case 32:
$sqlArray[] = "ALTER TABLE `taxonomies` ADD `required` tinyint(1) NOT NULL DEFAULT 0;";
break;
case 33:
$sqlArray[] = "ALTER TABLE `roles` ADD `perm_publish_kafka` tinyint(1) NOT NULL DEFAULT 0;";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
@ -1506,6 +1540,36 @@ class AppModel extends Model
return $redis;
}
public function getKafkaPubTool()
{
if (!$this->loadedKafkaPubTool) {
$this->loadKafkaPubTool();
}
return $this->loadedKafkaPubTool;
}
public function loadKafkaPubTool()
{
App::uses('KafkaPubTool', 'Tools');
$kafkaPubTool = new KafkaPubTool();
$rdkafkaIni = Configure::read('Plugin.Kafka_rdkafka_config');
$kafkaConf = array();
if (!empty($rdkafkaIni)) {
$kafkaConf = parse_ini_file($rdkafkaIni);
}
$brokers = Configure::read('Plugin.Kafka_brokers');
$kafkaPubTool->initTool($brokers, $kafkaConf);
$this->loadedKafkaPubTool = $kafkaPubTool;
return true;
}
public function publishKafkaNotification($topicName, $data, $action = false) {
$kafkaTopic = Configure::read('Plugin.Kafka_' . $topicName . '_notifications_topic');
if (Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_' . $topicName . '_notifications_enable') && !empty($kafkaTopic)) {
$this->getKafkaPubTool()->publishJson($kafkaTopic, $data, $action);
}
}
public function getPubSubTool()
{
if (!$this->loadedPubSubTool) {
@ -1968,4 +2032,24 @@ class AppModel extends Model
}
return time() - ($delta * $multiplier);
}
private function __fixServerPullPushRules()
{
$this->Server = ClassRegistry::init('Server');
$servers = $this->Server->find('all', array('recursive' => -1));
foreach ($servers as $server) {
$changed = false;
if (empty($server['Server']['pull_rules'])) {
$server['Server']['pull_rules'] = '[]';
$changed = true;
}
if (empty($server['Server']['push_rules'])) {
$server['Server']['push_rules'] = '[]';
$changed = true;
}
if ($changed) {
$this->Server->save($server);
}
}
}
}

View File

@ -645,8 +645,10 @@ class Attribute extends AppModel
if (isset($this->data['Attribute']['type']) && $this->typeIsAttachment($this->data['Attribute']['type']) && !empty($this->data['Attribute']['data'])) {
$result = $result && $this->saveBase64EncodedAttachment($this->data['Attribute']); // TODO : is this correct?
}
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_attribute_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_attribute_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$attribute = $this->fetchAttribute($this->id);
if (!empty($attribute)) {
$user = array(
@ -663,10 +665,21 @@ class Attribute extends AppModel
if (!empty($this->data['Attribute']['deleted'])) {
$action = 'soft-delete';
}
if (Configure::read('Plugin.ZeroMQ_include_attachments') && $this->typeIsAttachment($attribute['Attribute']['type'])) {
$attribute['Attribute']['data'] = $this->base64EncodeAttachment($attribute['Attribute']);
if ($pubToZmq) {
if (Configure::read('Plugin.ZeroMQ_include_attachments') && $this->typeIsAttachment($attribute['Attribute']['type'])) {
$attribute['Attribute']['data'] = $this->base64EncodeAttachment($attribute['Attribute']);
}
$pubSubTool = $this->getPubSubTool();
$pubSubTool->attribute_save($attribute, $action);
unset($attribute['Attribute']['data']);
}
if ($pubToKafka) {
if (Configure::read('Plugin.Kafka_include_attachments') && $this->typeIsAttachment($attribute['Attribute']['type'])) {
$attribute['Attribute']['data'] = $this->base64EncodeAttachment($attribute['Attribute']);
}
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $attribute, $action);
}
$pubSubTool->attribute_save($attribute, $action);
}
}
if (Configure::read('MISP.enable_advanced_correlations') && in_array($this->data['Attribute']['type'], array('ip-src', 'ip-dst', 'domain-ip')) && strpos($this->data['Attribute']['value'], '/')) {
@ -712,6 +725,11 @@ class Attribute extends AppModel
$pubSubTool = $this->getPubSubTool();
$pubSubTool->attribute_save($this->data, 'delete');
}
$kafkaTopic = Configure::read('Plugin.Kafka_attribute_notifications_topic');
if (Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_attribute_notifications_enable') && !empty($kafkaTopic)) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $this->data, 'delete');
}
}
}
@ -2390,7 +2408,7 @@ class Attribute extends AppModel
'conditions' => $conditions, // array of conditions
'order' => 'Attribute.value' . $valueField . ' ASC',
'recursive' => -1, // int
'fields' => array('Attribute.id', 'Attribute.event_id', 'Attribute.type', 'Attribute.comment', 'Attribute.value' . $valueField . " as value"),
'fields' => array('Attribute.id', 'Attribute.event_id', 'Attribute.type', 'Attribute.category', 'Attribute.comment', 'Attribute.to_ids', 'Attribute.value', 'Attribute.value' . $valueField),
'contain' => array('Event' => array('fields' => array('Event.id', 'Event.threat_level_id', 'Event.orgc_id', 'Event.uuid'))),
'group' => array('Attribute.type', 'Attribute.value' . $valueField), // fields to GROUP BY
'enforceWarninglist' => $enforceWarninglist
@ -2885,7 +2903,7 @@ class Attribute extends AppModel
)
)
),
'fields' => array('ShadowAttribute.id')
'fields' => array('ShadowAttribute.id', 'ShadowAttribute.value', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.to_ids')
)
);
$params['contain'] = array_merge($params['contain'], $proposalRestriction);
@ -2999,7 +3017,7 @@ class Attribute extends AppModel
$results[$key]['Attribute']['event_uuid'] = $results[$key]['Event']['uuid'];
}
if ($proposals_block_attributes) {
$results = $this->__blockAttributeViaProposal($results, $key);
$this->__blockAttributeViaProposal($results, $key);
}
if ($options['withAttachments']) {
if ($this->typeIsAttachment($attribute['Attribute']['type'])) {
@ -3007,7 +3025,9 @@ class Attribute extends AppModel
$results[$key]['Attribute']['data'] = $encodedFile;
}
}
$attributes[] = $results[$key];
if (!empty($results[$key])) {
$attributes[] = $results[$key];
}
}
if (!empty($break)) {
break;
@ -3047,8 +3067,8 @@ class Attribute extends AppModel
if ($sa['value'] === $attributes[$k]['Attribute']['value'] &&
$sa['type'] === $attributes[$k]['Attribute']['type'] &&
$sa['category'] === $attributes[$k]['Attribute']['category'] &&
$sa['to_ids'] == 0 &&
$attribute['to_ids'] == 1
($sa['to_ids'] == 0 || $sa['to_ids'] == '') &&
$attributes[$k]['Attribute']['to_ids'] == 1
) {
unset($attributes[$k]);
}
@ -3056,7 +3076,6 @@ class Attribute extends AppModel
} else {
unset($attributes[$k]['ShadowAttribute']);
}
return $attributes;
}
// Method gets and converts the contents of a file passed along as a base64 encoded string with the original filename into a zip archive
@ -3194,13 +3213,7 @@ class Attribute extends AppModel
}
foreach ($attributes as $k => $attribute) {
if (!empty($attribute['encrypt']) && $attribute['encrypt']) {
if (strpos($attribute['value'], '|') !== false) {
$temp = explode('|', $attribute['value']);
$attribute['value'] = $temp[0];
}
$result = $this->handleMaliciousBase64($attribute['event_id'], $attribute['value'], $attribute['data'], array('md5'));
$attribute['data'] = $result['data'];
$attribute['value'] = $attribute['value'] . '|' . $result['md5'];
$attribute = $this->onDemandEncrypt($attribute);
}
if (!isset($attribute['distribution'])) {
$attribute['distribution'] = $defaultDistribution;
@ -3212,6 +3225,18 @@ class Attribute extends AppModel
return true;
}
public function onDemandEncrypt($attribute)
{
if (strpos($attribute['value'], '|') !== false) {
$temp = explode('|', $attribute['value']);
$attribute['value'] = $temp[0];
}
$result = $this->handleMaliciousBase64($attribute['event_id'], $attribute['value'], $attribute['data'], array('md5'));
$attribute['data'] = $result['data'];
$attribute['value'] = $attribute['value'] . '|' . $result['md5'];
return $attribute;
}
public function saveAndEncryptAttribute($attribute, $user = false)
{
$hashes = array('md5' => 'malware-sample', 'sha1' => 'filename|sha1', 'sha256' => 'filename|sha256');
@ -3580,6 +3605,9 @@ class Attribute extends AppModel
}
}
}
if (!empty($this->validationErrors)) {
$validationErrors = $this->validationErrors;
}
return $attribute;
}

View File

@ -30,8 +30,10 @@ class AttributeTag extends AppModel
public function afterSave($created, $options = array())
{
parent::afterSave($created, $options);
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('AttributeTag.id' => $this->id),
@ -40,15 +42,24 @@ class AttributeTag extends AppModel
$tag['Tag']['attribute_id'] = $tag['AttributeTag']['attribute_id'];
$tag['Tag']['event_id'] = $tag['AttributeTag']['event_id'];
$tag = array('Tag' => $tag['Tag']);
$pubSubTool->tag_save($tag, 'attached to attribute');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, 'attached to attribute');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, 'attached to attribute');
}
}
}
public function beforeDelete($cascade = true)
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
if (!empty($this->id)) {
$pubSubTool = $this->getPubSubTool();
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('AttributeTag.id' => $this->id),
@ -57,7 +68,14 @@ class AttributeTag extends AppModel
$tag['Tag']['attribute_id'] = $tag['AttributeTag']['attribute_id'];
$tag['Tag']['event_id'] = $tag['AttributeTag']['event_id'];
$tag = array('Tag' => $tag['Tag']);
$pubSubTool->tag_save($tag, 'detached from attribute');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, 'detached from attribute');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, 'detached from attribute');
}
}
}
}

View File

@ -354,10 +354,33 @@ class Event extends AppModel
$orgc = $this->Orgc->find('first', array('conditions' => array('Orgc.id' => $this->data['Event']['orgc_id']), 'recursive' => -1, 'fields' => array('Orgc.name')));
$this->EventBlacklist->save(array('event_uuid' => $this->data['Event']['uuid'], 'event_info' => $this->data['Event']['info'], 'event_orgc' => $orgc['Orgc']['name']));
if (!empty($this->data['Event']['id'])) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable')) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_event_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->event_save(array('Event' => $this->data['Event']), 'delete');
}
if (Configure::read('Plugin.Kafka_enable')) {
$kafkaEventTopic = Configure::read('Plugin.Kafka_event_notifications_topic');
if(Configure::read('Plugin.Kafka_event_notifications_enable') && !empty($kafkaEventTopic)) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaEventTopic, array('Event' => $this->data['Event']), 'delete');
}
$kafkaPubTopic = Configure::read('Plugin.Kafka_event_publish_notifications_topic');
if (!empty($this->data['Event']['published']) && Configure::read('Plugin.Kafka_event_publish_notifications_enable') && !empty($kafkaPubTopic)) {
$hostOrg = $this->Org->find('first', array('conditions' => array('name' => Configure::read('MISP.org')), 'fields' => array('id')));
if (!empty($hostOrg)) {
$user = array('org_id' => $hostOrg['Org']['id'], 'Role' => array('perm_sync' => 0, 'perm_audit' => 0, 'perm_site_admin' => 0), 'Organisation' => $hostOrg['Org']);
$params = array('eventid' => $this->data['Event']['id']);
if (Configure::read('Plugin.Kafka_include_attachments')) {
$params['includeAttachments'] = 1;
}
$fullEvent = $this->fetchEvent($user, $params);
if (!empty($fullEvent)) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaPubTopic, $fullEvent[0], 'delete');
}
}
}
}
}
}
@ -483,6 +506,9 @@ class Event extends AppModel
$pubSubTool->event_save($event, $created ? 'add' : 'edit');
}
}
if (empty($this->data['Event']['unpublishAction']) && empty($this->data['Event']['skip_kafka'])) {
$this->publishKafkaNotification('event', $this->quickFetchEvent($this->data['Event']['id']), $created ? 'add' : 'edit');
}
}
public function buildEventConditions($user)
@ -3874,20 +3900,37 @@ class Event extends AppModel
$event['Event']['published'] = 1;
$event['Event']['publish_timestamp'] = time();
$event['Event']['skip_zmq'] = 1;
$event['Event']['skip_kafka'] = 1;
$this->save($event, array('fieldList' => $fieldList));
}
if (Configure::read('Plugin.ZeroMQ_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_event_publish_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_event_publish_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$hostOrg = $this->Org->find('first', array('conditions' => array('name' => Configure::read('MISP.org')), 'fields' => array('id')));
if (!empty($hostOrg)) {
$user = array('org_id' => $hostOrg['Org']['id'], 'Role' => array('perm_sync' => 0, 'perm_audit' => 0, 'perm_site_admin' => 0), 'Organisation' => $hostOrg['Org']);
$params = array('eventid' => $id);
if (Configure::read('Plugin.ZeroMQ_include_attachments')) {
$params['includeAttachments'] = 1;
if ($pubToZmq) {
$params = array('eventid' => $id);
if (Configure::read('Plugin.ZeroMQ_include_attachments')) {
$params['includeAttachments'] = 1;
}
$fullEvent = $this->fetchEvent($user, $params);
if (!empty($fullEvent)) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->publishEvent($fullEvent[0], 'publish');
}
}
$fullEvent = $this->fetchEvent($user, $params);
if (!empty($fullEvent)) {
$pubSubTool->publishEvent($fullEvent[0], 'publish');
if ($pubToKafka) {
$params = array('eventid' => $id);
if (Configure::read('Plugin.Kafka_include_attachments')) {
$params['includeAttachments'] = 1;
}
$fullEvent = $this->fetchEvent($user, $params);
if (!empty($fullEvent)) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $fullEvent[0], 'publish');
}
}
}
}
@ -4836,7 +4879,8 @@ class Event extends AppModel
'name' => $object['name'],
'uuid' => $object['uuid'],
'id' => isset($object['id']) ? $object['id'] : 0,
'object_type' => $object['objectType']
'object_type' => $object['objectType'],
'relationship_type' => $reference['relationship_type']
);
}
}
@ -5996,4 +6040,47 @@ class Event extends AppModel
}
return true;
}
public function getRequiredTaxonomies()
{
$this->Taxonomy = ClassRegistry::init('Taxonomy');
$required_taxonomies = $this->Taxonomy->find('list', array(
'recursive' => -1,
'conditions' => array('Taxonomy.required' => 1, 'Taxonomy.enabled' => 1),
'fields' => array('Taxonomy.namespace')
));
return $required_taxonomies;
}
public function checkIfPublishable($id)
{
$required_taxonomies = $this->getRequiredTaxonomies();
if (!empty($required_taxonomies)) {
$tags = $this->EventTag->find('all', array(
'conditions' => array('EventTag.event_id' => $id),
'recursive' => -1,
'contain' => array('Tag')
));
$missing = array();
foreach ($required_taxonomies as $required_taxonomy) {
$found = false;
foreach ($tags as $tag) {
$name = explode(':', $tag['Tag']['name']);
if (count($name) > 1) {
if ($name[0] == $required_taxonomy) {
$found = true;
break;
}
}
}
if (!$found) {
$missing[] = $required_taxonomy;
}
}
if (!empty($missing)) {
return $missing;
}
}
return true;
}
}

View File

@ -26,8 +26,10 @@ class EventTag extends AppModel
public function afterSave($created, $options = array())
{
parent::afterSave($created, $options);
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('EventTag.id' => $this->id),
@ -35,15 +37,24 @@ class EventTag extends AppModel
));
$tag['Tag']['event_id'] = $tag['EventTag']['event_id'];
$tag = array('Tag' => $tag['Tag']);
$pubSubTool->tag_save($tag, 'attached to event');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, 'attached to event');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, 'attached to event');
}
}
}
public function beforeDelete($cascade = true)
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
if (!empty($this->id)) {
$pubSubTool = $this->getPubSubTool();
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('EventTag.id' => $this->id),
@ -51,7 +62,14 @@ class EventTag extends AppModel
));
$tag['Tag']['event_id'] = $tag['EventTag']['event_id'];
$tag = array('Tag' => $tag['Tag']);
$pubSubTool->tag_save($tag, 'detached from event');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, 'detached from event');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, 'detached from event');
}
}
}
}

View File

@ -177,14 +177,14 @@ class Galaxy extends AppModel
$elements[] = array(
$galaxyClusterId,
$key,
$v
strval($v)
);
}
} else {
$elements[] = array(
$this->GalaxyCluster->id,
$key,
$value
strval($value)
);
}
}
@ -383,6 +383,20 @@ class Galaxy extends AppModel
return empty($galaxy) ? 0 : $galaxy['Galaxy']['id'];
}
public function getAllowedMatrixGalaxies()
{
$conditions = array(
'NOT' => array(
'kill_chain_order' => ''
)
);
$galaxies = $this->find('all', array(
'recursive' => -1,
'conditions' => $conditions,
));
return $galaxies;
}
public function getMatrix($galaxy_id)
{
$conditions = array('Galaxy.id' => $galaxy_id);

View File

@ -56,7 +56,7 @@ class Job extends AppModel
$process_id = CakeResque::enqueue(
'cache',
$shell . 'Shell',
array('cache' . $type, $user['id'], $id, $extra, $extra2),
array('cachebro' . $type, $user['id'], $id, $extra, $extra2),
true
);
} else {

View File

@ -256,11 +256,13 @@ class Log extends AppModel
public function logData($data)
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_user_notifications_enable')) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_audit_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->publish($data, 'audit', 'log');
}
$this->publishKafkaNotification('audit', $data, 'log');
if (Configure::read('Plugin.ElasticSearch_logging_enable')) {
// send off our logs to distributed /dev/null
$logIndex = Configure::read("Plugin.ElasticSearch_log_index");

View File

@ -92,19 +92,31 @@ class MispObject extends AppModel
public function afterSave($created, $options = array())
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_attribute_notifications_enable')) {
if (empty($this->data['Object']['skip_zmq'])) {
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') &&
Configure::read('Plugin.ZeroMQ_object_notifications_enable') &&
empty($this->data['Object']['skip_zmq']);
$kafkaTopic = Configure::read('Plugin.Kafka_object_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') &&
Configure::read('Plugin.Kafka_object_notifications_enable') &&
!empty($kafkaTopic) &&
empty($this->data['Object']['skip_kafka']);
if ($pubToZmq || $pubToKafka) {
$object = $this->find('first', array(
'conditions' => array('Object.id' => $this->id),
'recursive' => -1
));
$action = $created ? 'add' : 'edit';
if (!empty($this->data['Object']['deleted'])) {
$action = 'soft-delete';
}
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$object = $this->find('first', array(
'conditions' => array('Object.id' => $this->id),
'recursive' => -1
));
$action = $created ? 'add' : 'edit';
if (!empty($this->data['Object']['deleted'])) {
$action = 'soft-delete';
}
$pubSubTool->object_save($object, $action);
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $object, $action);
}
}
return true;
}
@ -112,13 +124,22 @@ class MispObject extends AppModel
public function beforeDelete($cascade = true)
{
if (!empty($this->data['Object']['id'])) {
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_object_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_object_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_object_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_object_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$object = $this->find('first', array(
'recursive' => -1,
'conditions' => array('Object.id' => $this->data['Object']['id'])
));
$pubSubTool->object_save($object, 'delete');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->object_save($object, 'delete');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $object, 'delete');
}
}
}
}
@ -686,6 +707,7 @@ class MispObject extends AppModel
));
$object['Object']['timestamp'] = $date->getTimestamp();
$object['Object']['skip_zmq'] = 1;
$object['Object']['skip_kafka'] = 1;
$result = $this->save($object);
return $result;
}

View File

@ -55,8 +55,10 @@ class ObjectReference extends AppModel
public function afterSave($created, $options = array())
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_object_reference_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_object_reference_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_object_reference_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_object_reference_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$object_reference = $this->find('first', array(
'conditions' => array('ObjectReference.id' => $this->id),
'recursive' => -1
@ -65,7 +67,14 @@ class ObjectReference extends AppModel
if (!empty($this->data['ObjectReference']['deleted'])) {
$action = 'soft-delete';
}
$pubSubTool->object_reference_save($object_reference, $action);
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->object_reference_save($object_reference, $action);
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $object_reference, $action);
}
}
return true;
}

View File

@ -125,6 +125,8 @@ class Organisation extends AppModel
$pubSubTool = $this->getPubSubTool();
$pubSubTool->modified($this->data, 'organisation');
}
$action = $created ? 'add' : 'edit';
$this->publishKafkaNotification('organisation', $this->data, $action);
return true;
}

View File

@ -0,0 +1,40 @@
<?php
App::uses('AppModel', 'Model');
class RestClientHistory extends AppModel
{
public $belongsTo = array(
'Org' => array(
'className' => 'Organisation',
'foreignKey' => 'org_id',
'order' => array(),
'fields' => array('id', 'name', 'uuid')
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'order' => array(),
'fields' => array('id', 'email')
),
);
public function cleanup($user_id)
{
$list = $this->find('list', array(
'conditions' => array(
'RestClientHistory.user_id' => $user_id
),
'page' => 1,
'limit' => 10,
'order' => array('RestClientHistory.timestamp DESC'),
'fields' => array('RestClientHistory.id', 'RestClientHistory.timestamp')
));
$this->deleteAll(array(
'RestClientHistory.user_id' => $user_id,
'RestClientHistory.bookmark' => 0,
'NOT' => array(
'RestClientHistory.id' => array_keys($list)
)
));
}
}

View File

@ -140,6 +140,12 @@ class Role extends AppModel
'text' => 'ZMQ publisher',
'readonlyenabled' => false,
'title' => 'Allow users to publish data to the ZMQ pubsub channel via the publish event to ZMQ button.'
),
'perm_publish_kafka' => array(
'id' => 'RolePermPublishKafka',
'text' => 'Kafka publisher',
'readonlyenabled' => false,
'title' => 'Allow users to publish data to Kafka via the publish event to Kafka button.'
)
);

View File

@ -250,6 +250,15 @@ class Server extends AppModel
'type' => 'boolean',
'afterHook' => 'disableCacheAfterHook',
),
'disable_threat_level' => array(
'level' => 1,
'description' => __('Disable displaying / modifications to the threat level altogether on the instance (deprecated field).'),
'value' => false,
'null' => true,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'header' => array(
'level' => 3,
'description' => __('This setting is deprecated and can be safely removed.'),
@ -1266,7 +1275,7 @@ class Server extends AppModel
),
'RPZ_ns' => array(
'level' => 2,
'description' => '',
'description' => __('Nameserver'),
'value' => 'localhost.',
'errorMessage' => '',
'test' => 'testForEmpty',
@ -1288,6 +1297,214 @@ class Server extends AppModel
'test' => 'testForEmpty',
'type' => 'string',
),
'Kafka_enable' => array(
'level' => 2,
'description' => __('Enables or disables the Kafka pub feature of MISP. Make sure that you install the requirements for the plugin to work. Refer to the installation instructions for more information.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
),
'Kafka_brokers' => array(
'level' => 2,
'description' => __('A comma separated list of Kafka bootstrap brokers'),
'value' => 'kafka:9092',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string',
),
'Kafka_rdkafka_config' => array(
'level' => 2,
'description' => __('A path to an ini file with configuration options to be passed to rdkafka. Section headers in the ini file will be ignored.'),
'value' => '/etc/rdkafka.ini',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string',
),
'Kafka_include_attachments' => array(
'level' => 2,
'description' => __('Enable this setting to include the base64 encoded payloads of malware-samples/attachments in the output.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_event_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any event creations/edits/deletions.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_event_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing event creations/edits/deletions.'),
'value' => 'misp_event',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_event_publish_notifications_enable' => array(
'level' => 2,
'description' => __('If enabled it will publish to Kafka the event at the time that the event gets published in MISP. Event actions (creation or edit) will not be published to Kafka.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_event_publish_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing event information on publish.'),
'value' => 'misp_event_publish',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_object_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any object creations/edits/deletions.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_object_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing object creations/edits/deletions.'),
'value' => 'misp_object',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_object_reference_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any object reference creations/deletions.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_object_reference_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing object reference creations/deletions.'),
'value' => 'misp_object_reference',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_attribute_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any attribute creations/edits/soft deletions.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_attribute_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing attribute creations/edits/soft deletions.'),
'value' => 'misp_attribute',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_shadow_attribute_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any proposal creations/edits/deletions.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_shadow_attribute_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing proposal creations/edits/deletions.'),
'value' => 'misp_shadow_attribute',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_tag_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of any tag creations/edits/deletions as well as tags being attached to / detached from various MISP elements.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_tag_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing tag creations/edits/deletions as well as tags being attached to / detached from various MISP elements.'),
'value' => 'misp_tag',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_sighting_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of new sightings.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_sighting_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing sightings.'),
'value' => 'misp_sighting',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_user_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of new/modified users.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_user_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing new/modified users.'),
'value' => 'misp_user',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_organisation_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of new/modified organisations.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_organisation_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing new/modified organisations.'),
'value' => 'misp_organisation',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'Kafka_audit_notifications_enable' => array(
'level' => 2,
'description' => __('Enables or disables the publishing of log entries. Keep in mind, this can get pretty verbose depending on your logging settings.'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'Kafka_audit_notifications_topic' => array(
'level' => 2,
'description' => __('Topic for publishing log entries.'),
'value' => 'misp_audit',
'errorMessage' => '',
'test' => 'testForEmpty',
'type' => 'string'
),
'ZeroMQ_enable' => array(
'level' => 2,
'description' => __('Enables or disables the pub/sub feature of MISP. Make sure that you install the requirements for the plugin to work. Refer to the installation instructions for more information.'),
@ -1722,7 +1939,7 @@ class Server extends AppModel
),
'Cortex_services_enable' => array(
'level' => 0,
'description' => __('Enable/disable the import services'),
'description' => __('Enable/disable the Cortex services'),
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
@ -1739,7 +1956,7 @@ class Server extends AppModel
),
'Cortex_timeout' => array(
'level' => 1,
'description' => __('Set a timeout for the import services'),
'description' => __('Set a timeout for the Cortex services'),
'value' => 120,
'errorMessage' => '',
'test' => 'testForEmpty',
@ -1940,7 +2157,7 @@ class Server extends AppModel
if ($result) {
$successes[] = $eventId;
} else {
$fails[$eventId] = 'Failed (partially?) because of validation errors: '. json_encode($eventModel->validationErrors, true);
$fails[$eventId] = __('Failed (partially?) because of validation errors: ') . json_encode($eventModel->validationErrors, true);
}
} else {
if (!$existingEvent['Event']['locked'] && !$server['Server']['internal']) {
@ -1973,7 +2190,7 @@ class Server extends AppModel
$this->__checkIfPulledEventExistsAndAddOrUpdate($event, $eventId, $successes, $fails, $eventModel, $server, $user, $jobId);
} else {
// error
$fails[$eventId] = 'failed downloading the event';
$fails[$eventId] = __('failed downloading the event');
}
return true;
}
@ -4351,6 +4568,57 @@ class Server extends AppModel
return exec('git checkout ' . $mainBranch);
}
public function getSubmodulesGitStatus()
{
$submodulesNames = array('misp-galaxy', 'misp-taxonomies', 'misp-objects', 'misp-noticelist', 'misp-warninglists');
$status = array();
foreach ($submodulesNames as $submoduleName) {
$status[$submoduleName] = $this->getSubmoduleGitStatus($submoduleName);
}
return $status;
}
public function getSubmoduleGitStatus($submoduleName) {
$acceptedSubmodulesNames = array('misp-galaxy', 'misp-taxonomies', 'misp-objects', 'misp-noticelist', 'misp-warninglists');
$status = array();
if (in_array($submoduleName, $acceptedSubmodulesNames)) {
$path = $this->__getSubmodulePath($submoduleName);
$status = array(
'moduleName' => $submoduleName,
'current' => exec(sprintf('cd %s; git rev-parse HEAD', $path)),
'currentTimestamp' => exec(sprintf('cd %s; git log -1 --pretty=format:%%ct', $path)),
'remoteTimestamp' => exec('timeout 3 git log origin/2.4 -1 --pretty=format:%ct'),
'remote' => exec(sprintf('timeout 3 git ls-remote https://github.com/MISP/%s | head -1 | sed "s/HEAD//"', $submoduleName)),
'upToDate' => ''
);
if (!empty($status['remote'])) {
if ($status['remote'] == $status['current']) {
$status['upToDate'] = 'same';
} else {
$status['upToDate'] = 'older';
}
} else {
$status['upToDate'] = 'error';
}
$status['timeDiff'] = (new DateTime('@' . $status['remoteTimestamp']))->diff(new DateTime('@' . $status['currentTimestamp']));
}
return $status;
}
private function __getSubmodulePath($submoduleName) {
$base = APP . 'files' . DS;
switch ($submoduleName) {
case 'misp-taxonomies':
return $base . 'taxonomies';
case 'misp-noticelist':
return $base . 'noticelists';
case 'misp-warninglists':
return $base . 'warninglists';
default:
return $base . $submoduleName;
}
}
public function update($status)
{
$final = '';

View File

@ -277,6 +277,10 @@ class ShadowAttribute extends AppModel
} else {
$this->__afterSaveCorrelation($this->data['ShadowAttribute']);
}
if (empty($this->data['ShadowAttribute']['deleted'])) {
$action = $created ? 'add' : 'edit';
$this->publishKafkaNotification('shadow_attribute', $this->data, $action);
}
return $result;
}
@ -555,6 +559,7 @@ class ShadowAttribute extends AppModel
}
$fieldList = array('proposal_email_lock', 'id', 'info');
$event['Event']['skip_zmq'] = 1;
$event['Event']['skip_kafka'] = 1;
$this->Event->save($event, array('fieldList' => $fieldList));
}

View File

@ -60,8 +60,10 @@ class Sighting extends AppModel
public function afterSave($created, $options = array())
{
parent::afterSave($created, $options = array());
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_sighting_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_sighting_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_sighting_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_sighting_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$user = array(
'org_id' => -1,
'Role' => array(
@ -69,7 +71,14 @@ class Sighting extends AppModel
)
);
$sighting = $this->getSighting($this->id, $user);
$pubSubTool->sighting_save($sighting, 'add');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->sighting_save($sighting, 'add');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $sighting, 'add');
}
}
return true;
}
@ -77,8 +86,10 @@ class Sighting extends AppModel
public function beforeDelete($cascade = true)
{
parent::beforeDelete();
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_sighting_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_sighting_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_sighting_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_sighting_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$user = array(
'org_id' => -1,
'Role' => array(
@ -86,7 +97,14 @@ class Sighting extends AppModel
)
);
$sighting = $this->getSighting($this->id, $user);
$pubSubTool->sighting_save($sighting, 'delete');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->sighting_save($sighting, 'delete');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $sighting, 'delete');
}
}
}

View File

@ -90,27 +90,45 @@ class Tag extends AppModel
public function afterSave($created, $options = array())
{
parent::afterSave($created, $options);
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('Tag.id' => $this->id)
));
$action = $created ? 'add' : 'edit';
$pubSubTool->tag_save($tag, $action);
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, $action);
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, $action);
}
}
}
public function beforeDelete($cascade = true)
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable')) {
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_tag_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_tag_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_tag_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
if (!empty($this->id)) {
$pubSubTool = $this->getPubSubTool();
$tag = $this->find('first', array(
'recursive' => -1,
'conditions' => array('Tag.id' => $this->id)
));
$pubSubTool->tag_save($tag, 'delete');
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->tag_save($tag, 'delete');
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $tag, 'delete');
}
}
}
}

View File

@ -271,8 +271,10 @@ class User extends AppModel
public function afterSave($created, $options = array())
{
if (Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_user_notifications_enable')) {
$pubSubTool = $this->getPubSubTool();
$pubToZmq = Configure::read('Plugin.ZeroMQ_enable') && Configure::read('Plugin.ZeroMQ_user_notifications_enable');
$kafkaTopic = Configure::read('Plugin.Kafka_user_notifications_topic');
$pubToKafka = Configure::read('Plugin.Kafka_enable') && Configure::read('Plugin.Kafka_user_notifications_enable') && !empty($kafkaTopic);
if ($pubToZmq || $pubToKafka) {
if (!empty($this->data)) {
$user = $this->data;
if (!isset($user['User'])) {
@ -298,7 +300,14 @@ class User extends AppModel
unset($user['User']['password']);
unset($user['User']['confirm_password']);
}
$pubSubTool->modified($user, 'user', $action);
if ($pubToZmq) {
$pubSubTool = $this->getPubSubTool();
$pubSubTool->modified($user, 'user', $action);
}
if ($pubToKafka) {
$kafkaPubTool = $this->getKafkaPubTool();
$kafkaPubTool->publishJson($kafkaTopic, $user, $action);
}
}
}
return true;

12
app/View/Attributes/index.ctp Normal file → Executable file
View File

@ -46,7 +46,7 @@
$headers = array(
$this->Paginator->sort('date'),
$this->Paginator->sort('event_id'),
$this->Paginator->sort('Event.orgc_id', 'Org'),
$this->Paginator->sort('Event.orgc_id', __('Org')),
$this->Paginator->sort('category'),
$this->Paginator->sort('type'),
$this->Paginator->sort('value'),
@ -56,18 +56,14 @@
__('Correlate'),
__('Related Events'),
__('Feed hits'),
sprintf('<span title="%s">%s</th>', $attrDescriptions['signature']['desc'], $this->Paginator->sort('IDS')),
$this->Paginator->sort('distribution'),
sprintf('<span title="%s">%s', $attrDescriptions['signature']['desc'], $this->Paginator->sort('IDS')),
sprintf('<span title="%s">%s', $attrDescriptions['distribution']['desc'], $this->Paginator->sort('distribution')),
__('Sightings'),
__('Activity'),
__('Actions')
);
foreach ($headers as $k => &$header) {
if ($k == (count($headers)-1)) {
$header = sprintf('<th title="%s">%s</th>', $attrDescriptions['signature']['desc'], $header);
} else {
$header = sprintf('<th>%s</th>', $header);
}
$header = sprintf('<th>%s</th>', $header);
}
$rows = array(
sprintf('<tr>%s</tr>', implode('', $headers))

View File

@ -35,7 +35,7 @@
?>
</fieldset>
<?php
echo $this->Form->button('Search', array('class' => 'btn btn-primary'));
echo $this->Form->button(__('Search'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
?>
</div>

View File

@ -341,7 +341,7 @@
if ($isSiteAdmin || $mayModify):
?>
<span class="icon-repeat useCursorPointer" title="<?php echo __('Restore attribute');?>" role="button" tabindex="0" aria-label="<?php echo __('Restore attribute');?>" onClick="deleteObject('attributes', 'restore', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="icon-trash useCursorPointer" title="<?php echo __('Permanently delete attribute');?>" role="button" tabindex="0" aria-label="i<?php echo __('Permanently delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Permanently delete attribute');?>" role="button" tabindex="0" aria-label="i<?php echo __('Permanently delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
endif;
else:
@ -357,8 +357,8 @@
<?php
endif;
?>
<a href="<?php echo $baseurl;?>/shadow_attributes/edit/<?php echo $object['id']; ?>" title="<?php echo __('Propose Edit');?>" class="icon-share useCursorPointer"></a>
<span class="icon-trash useCursorPointer" title="<?php echo __('Propose Deletion');?>" role="button" tabindex="0" aria-label="Propose deletion" onClick="deleteObject('shadow_attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<a href="<?php echo $baseurl;?>/shadow_attributes/edit/<?php echo $object['id']; ?>" title="<?php echo __('Propose Edit');?>" class="fa fa-comment useCursorPointer"></a>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Propose Deletion');?>" role="button" tabindex="0" aria-label="Propose deletion" onClick="deleteObject('shadow_attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
if ($isSiteAdmin):
?>
@ -377,15 +377,15 @@
<?php
endif;
?>
<a href="<?php echo $baseurl;?>/attributes/edit/<?php echo $object['id']; ?>" title="<?php echo __('Edit');?>" class="icon-edit useCursorPointer"></a>
<a href="<?php echo $baseurl;?>/attributes/edit/<?php echo $object['id']; ?>" title="<?php echo __('Edit');?>" class="fa fa-edit useCursorPointer"></a>
<?php
if (empty($event['Event']['publish_timestamp'])):
?>
<span class="icon-trash useCursorPointer" title="<?php echo __('Permanently delete attribute');?>" role="button" tabindex="0" aria-label="i<?php echo __('Permanently delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Permanently delete attribute');?>" role="button" tabindex="0" aria-label="i<?php echo __('Permanently delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']) . '/true'; ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
else:
?>
<span class="icon-trash useCursorPointer" title="<?php echo __('Soft-delete attribute');?>" role="button" tabindex="0" aria-label="<?php echo __('Soft-delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Soft-delete attribute');?>" role="button" tabindex="0" aria-label="<?php echo __('Soft-delete attribute');?>" onClick="deleteObject('attributes', 'delete', '<?php echo h($object['id']); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<?php
endif;
endif;

View File

@ -116,12 +116,12 @@
<?php
if ($mayModify && empty($object['deleted'])) {
echo sprintf(
'<a href="%s/objects/edit/%s" title="Edit" class="icon-edit icon-white useCursorPointer"></a>',
'<a href="%s/objects/edit/%s" title="Edit" class="fa fa-edit icon-white useCursorPointer"></a>',
$baseurl,
h($object['id'])
);
echo sprintf(
'<span class="icon-trash icon-white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
'<span class="fa fa-trash icon-white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
(empty($event['Event']['publish_timestamp']) ? __('Permanently delete object') : __('Soft delete object')),
sprintf(
'deleteObject(\'objects\', \'delete\', \'%s\', \'%s\');',

View File

@ -48,7 +48,7 @@
<a class="bold white useCursorPointer <?php echo $reference['deleted'] ? 'strikethrough' : ''; ?>" onClick="pivotObjectReferences('<?php echo h($currentUri); ?>', '<?php echo $uuid; ?>')">
<?php echo h($reference['relationship_type']) . ' ' . $objectType . ' ' . $reference['referenced_id'] . h($output);?>
</a>
<span class="icon-trash icon-white useCursorPointer" title="<?php echo __('Delete object reference');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete object reference');?>" onClick="deleteObject('object_references', 'delete', '<?php echo h($idref); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<span class="fa fa-trash icon-white useCursorPointer" title="<?php echo __('Delete object reference');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete object reference');?>" onClick="deleteObject('object_references', 'delete', '<?php echo h($idref); ?>', '<?php echo h($event['Event']['id']); ?>');"></span>
<br />
<?php
endforeach;

View File

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

View File

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

View File

@ -24,7 +24,7 @@
endif;
if ($isSiteAdmin):
?>
<th class="filter"><?php echo $this->Paginator->sort('owner org');?></th>
<th class="filter"><?php echo $this->Paginator->sort('owner org', __('Owner org'));?></th>
<?php
endif;
endif;
@ -36,7 +36,7 @@
<?php if (Configure::read('MISP.tagging')): ?>
<th class="filter"><?php echo __('Tags');?></th>
<?php endif; ?>
<th title="<?php echo __('Attribute Count');?>"><?php echo $this->Paginator->sort('attribute_count', '#Attr.');?></th>
<th title="<?php echo __('Attribute Count');?>"><?php echo $this->Paginator->sort('attribute_count', __('#Attr.'));?></th>
<?php if (Configure::read('MISP.showCorrelationsOnIndex')):?>
<th title="<?php echo __('Correlation Count');?>"><?php echo __('#Corr.');?></th>
<?php endif; ?>
@ -50,14 +50,14 @@
<th title="<?php echo __('Post Count');?>"><?php echo __('#Posts');?></th>
<?php endif; ?>
<?php if ($isSiteAdmin): ?>
<th><?php echo $this->Paginator->sort('user_id', 'Email');?></th>
<th><?php echo $this->Paginator->sort('user_id', __('Email'));?></th>
<?php endif; ?>
<th class="filter"><?php echo $this->Paginator->sort('date', null, array('direction' => 'desc'));?></th>
<th class="filter"><?php echo $this->Paginator->sort('info');?></th>
<th title="<?php echo $eventDescriptions['distribution']['desc'];?>">
<?php echo $this->Paginator->sort('distribution');?>
</th>
<th class="actions">Actions</th>
<th class="actions"><?php echo __('Actions');?></th>
</tr>
<?php foreach ($events as $event): ?>
@ -214,6 +214,16 @@
echo h($shortDist[$event['Event']['distribution']]);
endif;
?>
<?php
echo sprintf(
'<it type="button" title="%s" class="%s" aria-hidden="true" style="font-size: x-small;" data-event-distribution="%s" data-event-distribution-name="%s" data-scope-id="%s"></it>',
'Toggle advanced sharing network viewer',
'fa fa-share-alt useCursorPointer distributionNetworkToggle',
h($event['Event']['distribution']),
$event['Event']['distribution'] == 4 ? h($event['SharingGroup']['name']) : h($shortDist[$event['Event']['distribution']]),
h($event['Event']['id'])
)
?>
</td>
<td class="short action-links">
<?php
@ -239,5 +249,11 @@
$('.select').on('change', function() {
listCheckboxesChecked();
});
$('.distributionNetworkToggle').each(function() {
$(this).distributionNetwork({
distributionData: <?php echo json_encode($distributionData); ?>,
});
});
});
</script>

2
app/View/Elements/Feeds/View/row_attribute.ctp Normal file → Executable file
View File

@ -84,7 +84,7 @@ if ($object['value'] == 'MERGE') debug($object);
</td>
<td class="short">
<div id = "Attribute_<?php echo $object['uuid']; ?>_to_ids_solid" class="inline-field-solid");">
<?php echo $object['to_ids'] ? 'Yes' : 'No'; ?>
<?php echo $object['to_ids'] ? __('Yes') : __('No'); ?>
</div>
</td>
</td>

View File

@ -38,7 +38,7 @@
<div id="attributeList" class="attributeListContainer">
<table class="table table-striped table-condensed">
<tr>
<th><?php echo $this->Paginator->sort('timestamp', 'Date');?></th>
<th><?php echo $this->Paginator->sort('timestamp', __('Date'));?></th>
<th><?php echo $this->Paginator->sort('category');?></th>
<th><?php echo $this->Paginator->sort('type');?></th>
<th><?php echo $this->Paginator->sort('value');?></th>

View File

@ -40,13 +40,14 @@
<td class="short action-links">
<?php
if ($isSiteAdmin || $me['org_id'] == $item['TagCollection']['org_id']) {
echo $this->Html->link('', array('action' => 'edit', $item['TagCollection']['id']), array('class' => 'icon-edit', 'title' => 'Edit'));
echo $this->Form->postLink('', array('action' => 'delete', $item['TagCollection']['id']), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete "%s"?', $item['TagCollection']['name']));
echo $this->Html->link('', array('action' => 'edit', $item['TagCollection']['id']), array('class' => 'fa fa-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('action' => 'delete', $item['TagCollection']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete "%s"?', $item['TagCollection']['name']));
}
echo sprintf(
'<a href="%s/tag_collections/view/%s.json" class="fa fa-cloud-download black" title="Download configuration" download="tag_collection_%s.json"></a>',
'<a href="%s/tag_collections/view/%s.json" class="fa fa-cloud-download black" title="%s" download="tag_collection_%s.json"></a>',
$baseurl,
h($item['TagCollection']['id']),
__('Download configuration'),
h($item['TagCollection']['id'])
);

View File

@ -85,13 +85,13 @@
<?php
if (($isAclAdmin && (($user['User']['org_id'] == $me['org_id'])) || ('1' == $me['id'])) || ($isSiteAdmin)):
?>
<span role="button" tabindex="0" aria-label="Initiate password refresh" title="<?php echo __('Initiate password refresh');?>" class="icon-refresh useCursorPointer" onClick="initiatePasswordReset('<?php echo $user['User']['id']; ?>');" title="<?php echo __('Create new credentials and inform user');?>" role="button" tabindex="0" aria-label="<?php echo __('Create new credentials and inform user');?>"></span>
<span role="button" tabindex="0" aria-label="Initiate password refresh" title="<?php echo __('Initiate password refresh');?>" class="fa fa-sync useCursorPointer" onClick="initiatePasswordReset('<?php echo $user['User']['id']; ?>');" title="<?php echo __('Create new credentials and inform user');?>" role="button" tabindex="0" aria-label="<?php echo __('Create new credentials and inform user');?>"></span>
<?php
echo $this->Html->link('', array('admin' => true, 'action' => 'edit', $user['User']['id']), array('class' => 'icon-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $user['User']['id']), array('class' => 'icon-trash', 'title' => __('Delete')), __('Are you sure you want to delete # %s? It is highly recommended to never delete users but to disable them instead.', $user['User']['id']));
echo $this->Html->link('', array('admin' => true, 'action' => 'edit', $user['User']['id']), array('class' => 'fa fa-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $user['User']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete # %s? It is highly recommended to never delete users but to disable them instead.', $user['User']['id']));
endif;
?>
<?php echo $this->Html->link('', array('admin' => true, 'action' => 'view', $user['User']['id']), array('class' => 'icon-list-alt', 'title' => __('View'))); ?>
<?php echo $this->Html->link('', array('admin' => true, 'action' => 'view', $user['User']['id']), array('class' => 'fa fa-eye', 'title' => __('View'))); ?>
</td>
</tr>
<?php

View File

@ -1,3 +1,24 @@
<?php
if (!empty($required_taxonomies)) {
foreach ($required_taxonomies as $k => $v) {
foreach ($tags as $tag) {
$temp_tag = explode(':', $tag['Tag']['name']);
if (count($temp_tag) > 1) {
if ($temp_tag[0] == $v) {
unset($required_taxonomies[$k]);
break;
}
}
}
}
if (!empty($required_taxonomies)) {
echo sprintf(
'Missing taxonomies: <span class="red bold">%s</span><br />',
implode(', ', $required_taxonomies)
);
}
}
?>
<span style="display:inline-block;">
<?php
$full = $isAclTagger && $tagAccess;

View File

@ -137,15 +137,15 @@
?>
<th class="context hidden"><?php echo $this->Paginator->sort('id');?></th>
<th class="context hidden">UUID</th>
<th><?php echo $this->Paginator->sort('timestamp', 'Date', array('direction' => 'desc'));?></th>
<th><?php echo $this->Paginator->sort('timestamp', __('Date'), array('direction' => 'desc'));?></th>
<?php
if ($extended):
?>
<th class="event_id"><?php echo $this->Paginator->sort('event_id', 'Event');?></th>
<th class="event_id"><?php echo $this->Paginator->sort('event_id', __('Event'));?></th>
<?php
endif;
?>
<th><?php echo $this->Paginator->sort('Org.name', 'Org'); ?>
<th><?php echo $this->Paginator->sort('Org.name', __('Org')); ?>
<th><?php echo $this->Paginator->sort('category');?></th>
<th><?php echo $this->Paginator->sort('type');?></th>
<th><?php echo $this->Paginator->sort('value');?></th>

View File

@ -75,6 +75,7 @@
'title' => __('Add new cluster to selected Attributes'),
'class' => 'mass-select hidden',
'fa-icon' => 'rebel',
'fa-source' => 'fab',
'onClick' => 'popoverPopup',
'onClickParams' => array('this', 'selected/attribute', 'galaxies', 'selectGalaxyNamespace')
),
@ -190,7 +191,7 @@
array(
'type' => 'search',
'fa-icon' => 'search',
'placeholder' => 'Enter value to search',
'placeholder' => __('Enter value to search'),
'data' => '',
'cancel' => array(
'fa-icon' => 'times',

View File

@ -86,16 +86,16 @@
<?php
if (!$isSiteAdmin) {
if ($post['user_id'] == $myuserid) {
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'icon-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'icon-trash', 'title' => __('Delete')), __('Are you sure you want to delete this post?'));
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'fa fa-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete this post?'));
} else {
?>
<a href="<?php echo $baseurl.'/posts/add/post/'.h($post['id']); ?>" class="icon-comment" title = "<?php echo __('Reply');?>"></a>
<?php
}
} else {
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'icon-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'fa fa-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'fa fa-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
?>
<a href = "<?php echo $baseurl.'/posts/add/post/'.h($post['id']); ?>" class="icon-comment" title = "<?php echo __('Reply');?>"></a>
<?php

10
app/View/Elements/galaxyQuickView.ctp Normal file → Executable file
View File

@ -5,7 +5,7 @@
<div style="margin-left:10px;">
<span title="<?php echo isset($galaxy['description']) ? h($galaxy['description']) : h($galaxy['name']);?>" class="bold blue" style="font-size:14px;">
<?php echo h($galaxy['name']); ?>&nbsp;
<a href="<?php echo $baseurl; ?>/galaxies/view/<?php echo h($galaxy['id']); ?>" class="icon-search" title="<?php echo __('View details about this galaxy');?>"></a>
<a href="<?php echo $baseurl; ?>/galaxies/view/<?php echo h($galaxy['id']); ?>" class="fa fa-search" title="<?php echo __('View details about this galaxy');?>"></a>
</span>
<?php
foreach ($galaxy['GalaxyCluster'] as $cluster):
@ -16,12 +16,12 @@
<span class="collapse-status" style="font-size: 16px;">+</span>
</span>
<span><?php echo h($cluster['value']); ?></span>
<a href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>" class="icon-search" title="<?php echo __('View details about this cluster');?>"></a>&nbsp;
<a href="<?php echo $baseurl; ?>/events/index/searchtag:<?php echo h($cluster['tag_id']); ?>" class="icon-th-list" title="<?php echo __('View all events containing this cluster.');?>"></a>
<a href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>" class="fa fa-search" title="<?php echo __('View details about this cluster');?>"></a>&nbsp;
<a href="<?php echo $baseurl; ?>/events/index/searchtag:<?php echo h($cluster['tag_id']); ?>" class="fa fa-list" title="<?php echo __('View all events containing this cluster.');?>"></a>
<?php
if ($isSiteAdmin || ($mayModify && $isAclTagger)) {
echo $this->Form->create(false, array('url' => $baseurl . '/galaxy_clusters/detach/' . ucfirst(h($target_id)) . '/' . h($target_type) . '/' . $cluster['tag_id'], 'style' => 'display: inline-block; margin: 0px;'));
echo '<it href="#" class="icon-trash useCursorPointer" role="button" tabindex="0" aria-label="' . __('detach') . '" title="' . __('Are you sure you want to detach %s from this event?', h($cluster['value'])) . '" onclick="popoverConfirm(this)"></it>';
echo '<it href="#" class="fa fa-trash useCursorPointer" role="button" tabindex="0" aria-label="' . __('detach') . '" title="' . __('Are you sure you want to detach %s from this event?', h($cluster['value'])) . '" onclick="popoverConfirm(this)"></it>';
echo $this->Form->end();
}
?>
@ -93,7 +93,7 @@
<?php
if ($isSiteAdmin || ($mayModify && $isAclTagger)):
?>
<span class="useCursorPointer btn btn-inverse addGalaxy" data-target-type="<?php echo h($target_type);?>" data-target-id="<?php echo h($target_id); ?>" role="button" tabindex="0" aria-label="Add new cluster" style="padding: 1px 5px !important;font-size: 12px !important;">Add</span>
<span class="useCursorPointer btn btn-inverse addGalaxy" data-target-type="<?php echo h($target_type);?>" data-target-id="<?php echo h($target_id); ?>" role="button" tabindex="0" aria-label="Add new cluster" style="padding: 1px 5px !important;font-size: 12px !important;"><?php echo __('Add'); ?></span>
<?php
endif;
?>

View File

@ -66,12 +66,12 @@
<span class="bold blue expandable useCursorPointer" data-toggle="popover" data-content="<?php echo h($popover_data); ?>">
<?php echo h($cluster['value']); ?>
</span>&nbsp;
<a href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>" class="icon-search" title="<?php echo __('View details about this cluster');?>"></a>&nbsp;
<a href="<?php echo $baseurl; ?>/events/index/searchtag:<?php echo h($cluster['tag_id']); ?>" class="icon-th-list" title="<?php echo __('View all events containing this cluster.');?>"></a>
<a href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>" class="fa fa-search" title="<?php echo __('View details about this cluster');?>"></a>&nbsp;
<a href="<?php echo $baseurl; ?>/events/index/searchtag:<?php echo h($cluster['tag_id']); ?>" class="fa fa-list" title="<?php echo __('View all events containing this cluster.');?>"></a>
<?php
if ($isSiteAdmin || ($mayModify && $isAclTagger)) {
echo $this->Form->create(false, array('url' => $baseurl . '/galaxy_clusters/detach/' . ucfirst(h($target_id)) . '/' . h($target_type) . '/' . h($cluster['tag_id']), 'style' => 'display: inline-block; margin: 0px;'));
echo '<span href="#" class="icon-trash useCursorPointer" title="' . __('Are you sure you want to detach %s from this %s?', h($cluster['value']), h($target_type)) . '" onclick="popoverConfirm(this)"></span>';
echo '<span href="#" class="fa fa-trash useCursorPointer" title="' . __('Are you sure you want to detach %s from this %s?', h($cluster['value']), h($target_type)) . '" onclick="popoverConfirm(this)"></span>';
echo $this->Form->end();
}
?>

View File

@ -42,7 +42,11 @@
empty($onClick) ? '' : $onClick, // pass $data['onClick'] for the function name to call and $data['onClickParams'] for the parameter list
empty($dataFields) ? '' : $dataFields,
empty($data['title']) ? '' : sprintf('title="%s"', h($data['title'])),
empty($data['fa-icon']) ? '' : sprintf('<i class="fa fa-%s"></i> ', $data['fa-icon']), // this has to be sanitised beforehand!
empty($data['fa-icon']) ? '' : sprintf(
'<i class="%s fa-%s"></i> ',
empty($data['fa-source']) ? 'fas' : h($data['fa-source']),
$data['fa-icon']
), // this has to be sanitised beforehand!
empty($data['html']) ? '' : $data['html'], // this has to be sanitised beforehand!
empty($data['text']) ? '' : h($data['text'])
);

View File

@ -17,6 +17,14 @@
'text' => __('Populate From Template')
));
}
if ($menuItem === 'enrichmentResults') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'enrichmentResults',
'url' => '#',
'text' => __('Enrichment Module Result')
));
echo $this->element('/genericElements/SideMenu/side_menu_divider');
}
if ($menuItem === 'freetextResults') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'freetextResults',
@ -173,6 +181,16 @@
'message' => __('Are you sure you wish to republish the current event to the ZMQ channel?')
));
}
if (Configure::read('Plugin.Kafka_enable') &&
Configure::read('Plugin.Kafka_event_notifications_enable') &&
Configure::read('Plugin.Kafka_event_notifications_topic') &&
$isAclKafka) {
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
'url' => '/events/pushEventToKafka/' . h($event['Event']['id']),
'text' => __('Publish event to Kafka'),
'message' => __('Are you sure you wish to republish the current event to the Kafka topic?')
));
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'contact',
'url' => '/events/contact/' . $event['Event']['id'],
@ -638,11 +656,6 @@
));
}
if ($menuItem === 'editOrg' || $menuItem === 'viewOrg') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'editOrg',
'url' => '/organisations/edit/' . h($id),
'text' => __('Edit Organisation')
));
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'viewOrg',
'url' => '/organisations/view/' . h($id),

View File

@ -283,5 +283,4 @@ function submitFunction(clicked, callback) {
options_templates['<?php echo $select_id; ?>'] = <?php echo json_encode($option_templates); ?>;
options_additionalData['<?php echo $select_id; ?>'] = <?php echo json_encode($options_additionalData); ?>;
</script>
</div>

2
app/View/Elements/generic_table.ctp Normal file → Executable file
View File

@ -5,7 +5,7 @@
'before' => '$(".progress").show()',
'complete' => '$(".progress").hide()',
));
$title = sprintf('<h2>%s</h2>', Inflector::humanize($controller));
$title = sprintf('<h2>%s</h2>', $alias);
if (!empty($description)) {
$description = sprintf('<p>%s</p>', Inflector::humanize($description));
} else {

2
app/View/Elements/global_menu.ctp Normal file → Executable file
View File

@ -4,7 +4,7 @@
array(
'type' => 'root',
'url' => $baseurl . '/',
'html' => (Configure::read('MISP.home_logo') ? $logo = '<img src="' . $baseurl . '/img/custom/' . Configure::read('MISP.home_logo') . '" style="height:24px;">' : 'Home')
'html' => (Configure::read('MISP.home_logo') ? $logo = '<img src="' . $baseurl . '/img/custom/' . Configure::read('MISP.home_logo') . '" style="height:24px;">' : __('Home'))
),
array(
'type' => 'root',

View File

@ -55,12 +55,16 @@
$branchColour = $branch == '2.4' ? 'green' : 'red bold';
?>
<span class="<?php echo h($branchColour); ?>">
<?=($branch == '2.4') ? h($branch) : "You are not on a branch, Update MISP will fail"; ?>
<?=($branch == '2.4') ? h($branch) : __('You are not on a branch, Update MISP will fail'); ?>
</span>
</span><br />
<pre class="hidden green bold" id="gitResult"></pre>
<button title="<?php echo __('Pull the latest MISP version from github');?>" class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;" onClick = "updateMISP();"><?php echo __('Update MISP');?></button>
</div>
<h3><?php echo __('Submodules version');?><it id="refreshSubmoduleStatus" class="fa fa-refresh useCursorPointer" style="font-size: small; margin-left: 5px;"></it></h3>
<div id="divSubmoduleVersions" style="background-color:#f7f7f9;">
</div>
<h3><?php echo __('Writeable Directories and files');?></h3>
<p><?php echo __('The following directories and files have to be writeable for MISP to function properly. Make sure that the apache user has write privileges for the directories below.');?></p>
<p><b><?php echo __('Directories');?></b></p>
@ -332,7 +336,7 @@
<?php echo $this->Form->postLink('<span class="btn btn-inverse" style="padding-top:1px;padding-bottom:1px;">' . __('Clean cache') . '</span>', $baseurl . '/events/cleanModelCaches', array('escape' => false));?>
<h3><?php echo __('Overwritten objects');?></h3>
<p><?php echo __('Prior to 2.4.89, due to a bug a situation could occur where objects got overwritten on a sync pull. This tool allows you to inspect whether you are affected and if yes, remedy the issue.');?></p>
<a href="<?php echo $baseurl; ?>/objects/orphanedObjectDiagnostics"><span class="btn btn-inverse">Reconstruct overwritten objects</span></a>
<a href="<?php echo $baseurl; ?>/objects/orphanedObjectDiagnostics"><span class="btn btn-inverse"><?php echo __('Reconstruct overwritten objects');?></span></a>
<h3><?php echo __('Orphaned attributes');?></h3>
<p><?php echo __('In some rare cases attributes can remain in the database after an event is deleted becoming orphaned attributes. This means that they do not belong to any event, which can cause issues with the correlation engine (known cases include event deletion directly in the database without cleaning up the attributes and situations involving a race condition with an event deletion happening before all attributes are synchronised over).');?></p>
<div style="background-color:#f7f7f9;width:400px;">
@ -357,3 +361,17 @@
<span class="btn btn-inverse" role="button" tabindex="0" aria-label="<?php echo __('Check bad link on attachments');?>" title="<?php echo __('Check bad link on attachments');?>" style="padding-top:1px;padding-bottom:1px;" onClick="checkAttachments();"><?php echo __('Check bad link on attachments');?></span>
</div>
<script>
$(document).ready(function() {
updateSubModulesStatus();
});
$('#refreshSubmoduleStatus').click(function() { updateSubModulesStatus(); });
function updateSubModulesStatus() {
$('#divSubmoduleVersions').empty().append('<it class="fa fa-spin fa-spinner" style="font-size: large; left: 50%; top: 50%;"></it>');
$.get('<?php echo $baseurl . '/servers/getSubmodulesStatus/'; ?>', function(html){
$('#divSubmoduleVersions').html(html);
});
}
</script>

View File

@ -70,7 +70,7 @@
</td>
<td class="short">
<?php
echo $this->Form->postLink('', array('controller' => 'servers', 'action' => 'deleteFile' , $k , $f['filename']), array('class' => 'icon-trash', 'title' => __('Delete')), __('Are you sure you want to delete %s?', $f['filename']));
echo $this->Form->postLink('', array('controller' => 'servers', 'action' => 'deleteFile' , $k , $f['filename']), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete %s?', $f['filename']));
?>
</td>
</tr>
@ -89,7 +89,7 @@
?>
</fieldset>
<?php
echo $this->Form->button('Upload', array('class' => 'btn btn-primary'));
echo $this->Form->button(__('Upload'), array('class' => 'btn btn-primary'));
echo $this->Form->end();
endforeach;
?>

View File

@ -15,7 +15,7 @@
foreach ($tabs as $k => $tab) {
$data['children'][0]['children'][] = array(
'html' => sprintf(
'%s settings%s',
__('%s settings%s'),
ucfirst(h($k)),
($tab['errors'] == 0) ? '' : sprintf(
' (<span>%s%s</span>)',
@ -47,11 +47,11 @@
);
$data['children'][0]['children'][] = array(
'url' => '/servers/serverSettings/workers',
'title' => __('Download report'),
'title' => __('Workers'),
'active' => 'workers' == $active_tab,
'html' => sprintf(
'%s %s%s',
'<i class="fa fa-android"></i>',
'<i class="fab fa-android"></i>',
__('Workers'),
($workerIssueCount == 0) ? '' : sprintf(
' (<span>%s</span>)',
@ -65,10 +65,10 @@
'title' => __('Download report'),
'html' => '<i class="fa fa-download"></i>'
);
if ($active_tab && $active_tab !== 'diagnostics' && $active_tab !== 'files') {
if ($active_tab && !in_array($active_tab, array('diagnostics', 'files', 'workers'))) {
$data['children'][] = array(
'type' => 'live_search',
'placeholder' => 'Filter the table(s) below'
'placeholder' => __('Filter the table(s) below')
);
}
if (!$ajax) {

View File

@ -38,7 +38,7 @@
<?php
echo h($data['jobCount']);
if ($data['jobCount'] > 0 && $worker_array['controls']) {
echo $this->Form->postLink('<span class="icon-trash useCursorPointer"></span>', $baseurl . '/servers/clearWorkerQueue/' . h($type), array('escape' => false, 'inline' => true, 'style' => 'margin-left:2px;'));
echo $this->Form->postLink('<span class="fa fa-trash useCursorPointer"></span>', $baseurl . '/servers/clearWorkerQueue/' . h($type), array('escape' => false, 'inline' => true, 'style' => 'margin-left:2px;'));
}
?>
</span>
@ -103,7 +103,7 @@
<td class="actions short" style="<?php echo $style; ?>">
<?php
if ($worker_array['controls']) {
echo $this->Form->postLink('', '/servers/stopWorker/' . h($worker['pid']), array('class' => 'icon-trash' . $icon_modifier, 'title' => __('Stop (if still running) and remove this worker. This will immediately terminate any jobs that are being executed by it.')));
echo $this->Form->postLink('', '/servers/stopWorker/' . h($worker['pid']), array('class' => 'fa fa-trash' . $icon_modifier, 'title' => __('Stop (if still running) and remove this worker. This will immediately terminate any jobs that are being executed by it.')));
}
?>
</td>

2
app/View/Elements/serverRuleElements/pull.ctp Normal file → Executable file
View File

@ -35,7 +35,7 @@
</tr>
<tr>
<td style="width:120px;">
<p style="color:green;font-weight:bold;">Allowed Orgs (OR)</p>
<p style="color:green;font-weight:bold;"><?php echo __('Allowed Orgs (OR)');?></p>
<select id="orgspullLeftValues" size="5" multiple style="width:185px;">
</select>
</td>

View File

@ -98,11 +98,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('attribute' ,'<?php echo h($element_id); ?>');"></span>
<span class="fa fa-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('attribute' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -75,11 +75,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('file' ,'<?php echo h($element_id); ?>');"></span>
<span class="fa fa-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('file' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -32,11 +32,11 @@
if ($mayModify) {
echo $this->Form->create('TemplateElement', array('class' => 'inline-delete', 'style' => 'display:inline-block;', 'id' => 'TemplateElement_' . h($element_id) . '_delete', 'url' => array('action' => 'delete')));
?>
<span class="icon-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<span class="fa fa-trash useCursorPointer" title="<?php echo __('Delete template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Delete template element');?>" onClick="deleteObject('template_elements', 'delete' ,'<?php echo h($element_id); ?>', '<?php echo h($element['TemplateElement']['template_id']); ?>');"></span>
<?php
echo $this->Form->end();
?>
<span class="icon-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('text' ,'<?php echo h($element_id); ?>');"></span>
<span class="fa fa-edit useCursorPointer" title="<?php echo __('Edit template element');?>" role="button" tabindex="0" aria-label="<?php echo __('Edit template element');?>" onClick="editTemplateElement('text' ,'<?php echo h($element_id); ?>');"></span>
<?php
} else {
echo '&nbsp;';

View File

@ -8,7 +8,8 @@
<div class="spinner"></div>
<div class="loadingText"><?php echo __('Loading');?></div>
</div>
<div id="eventdistri_graph" data-event-id="<?php echo h($event['Event']['id']); ?>" data-event-distribution="<?php echo h($event['Event']['distribution']); ?>" data-user-manipulation="<?php echo $mayModify || $isSiteAdmin ? 'true' : 'false'; ?>" data-extended="<?php echo $extended; ?>">
<div id="eventdistri_graph" data-event-id="<?php echo h($event['Event']['id']); ?>" data-event-distribution="<?php echo h($event['Event']['distribution']); ?>" data-event-distribution-text="<?php echo $event['Event']['distribution'] == 4 ? h($event['SharingGroup']['name']) : h($distributionLevels[$event['Event']['distribution']]); ?>" data-user-manipulation="<?php echo $mayModify || $isSiteAdmin ? 'true' : 'false'; ?>" data-extended="<?php echo $extended; ?>">
<canvas id="distribution_graph_canvas" height="290px"width="400px"></canvas>
</div>
<div class="popupDistriSeparator"></div>

2
app/View/Elements/view_event_graph.ctp Normal file → Executable file
View File

@ -15,7 +15,7 @@
<label id="network-import" class="btn center-in-network-header network-control-btn"><span class="useCursorPointer fa fa-exchange" style="margin-right: 3px;"></span><?php echo __('Export')?></label>
<label id="network-history" class="btn center-in-network-header network-control-btn"><span class="useCursorPointer fa fa-history" style="margin-right: 3px;"></span><?php echo __('History')?></label>
<input type="text" id="network-typeahead" class="center-in-network-header network-typeahead flushright" data-provide="typeahead" size="20" placeholder="Search for an item">
<input type="text" id="network-typeahead" class="center-in-network-header network-typeahead flushright" data-provide="typeahead" size="20" placeholder="<?php echo __('Search for an item');?>">
</div>
<span class="shortcut-help btn btn-xs btn-info">?</span>

View File

@ -73,7 +73,7 @@ foreach($tabs as $tabName => $column):
</div>
<div class="attack-matrix-options matrix-div-submit submit-container">
<span class="btn btn-inverse btn-matrix-submit" role="button" style="padding: 1px 5px !important;font-size: 12px !important;font-weight: bold;"><?php echo __('Submit'); ?></span>
<span class="btn btn-inverse btn-matrix-submit" role="button" tabindex="0" style="padding: 1px 5px !important;font-size: 12px !important;font-weight: bold;"><?php echo __('Submit'); ?></span>
</div>
<div class="attack-matrix-options">

View File

@ -6,6 +6,7 @@
<?php
echo $this->Form->input('uuids', array(
'type' => 'textarea',
'label' => __('UUIDs'),
'div' => 'input clear',
'class' => 'input-xxlarge',
'placeholder' => __('Enter a single or a list of UUIDs')
@ -20,7 +21,7 @@
'type' => 'textarea',
'div' => 'input clear',
'class' => 'input-xxlarge',
'label' => 'Event info',
'label' => __('Event info'),
'placeholder' => __('(Optional) the event info of the event that you would like to block. It\'s best to leave this empty if you are adding a list of UUIDs.')
));
echo $this->Form->input('comment', array(

Some files were not shown because too many files have changed in this diff Show More