mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into 2.4
commit
a90eaec445
|
@ -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
|
||||
|
|
|
@ -16,11 +16,23 @@
|
|||
# 0/ Quick MISP Instance on Debian Based Linux - Status |
|
||||
#-------------------------------------------------------|
|
||||
#
|
||||
# 20190208: Kali Linux tested and working.
|
||||
# 20190302: Ubuntu 18.04.2 tested and working. -- sCl
|
||||
# 20190208: Kali Linux tested and working. -- sCl
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------------------------------|
|
||||
# 1/ For other Debian based Linux distributions, download script and run as **unprivileged** user |
|
||||
#-------------------------------------------------------------------------------------------------|
|
||||
#
|
||||
# The following installs only MISP-core:
|
||||
# $ curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh | bash -s -- -c
|
||||
#
|
||||
# This will install MISP Core and misp-modules (recommended)
|
||||
# $ curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh | bash -s -- -c -M
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------|
|
||||
# 1/ For Kali, download and run Installer Script |
|
||||
# 2/ For Kali, download and run Installer Script |
|
||||
#-------------------------------------------------------|
|
||||
#
|
||||
# To install MISP on Kali copy paste the following to your r00t shell:
|
||||
|
@ -29,13 +41,6 @@
|
|||
# The script is tested on a plain vanilla Kali Linux Boot CD and installs quite a few dependencies.
|
||||
#
|
||||
#
|
||||
#---------------------------------------------------------------------------------------------|
|
||||
# 2/ For other Debian based Linux distributions, download script and run as unprivileged user |
|
||||
#---------------------------------------------------------------------------------------------|
|
||||
#
|
||||
# $ wget -O ~/INSTALL.debian.sh https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh && bash ~/INSTALL.debian.sh -C
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------|
|
||||
# 3/ The following script has been partially autogenerated |
|
||||
#----------------------------------------------------------|
|
||||
|
@ -406,25 +411,14 @@ checkUsrLocalSrc () {
|
|||
else
|
||||
# TODO: The below might be shorter, more elegant and more modern
|
||||
#[[ -n $KALI ]] || [[ -n $UNATTENDED ]] && echo "Just do it"
|
||||
if [ "$KALI" == "1" -o "$UNATTENDED" == "1" ]; then
|
||||
ANSWER="y"
|
||||
else
|
||||
space
|
||||
echo "/usr/local/src need to be writeable by $MISP_USER for misp-modules, viper etc."
|
||||
echo -n "Permission to fix? (y/n) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
|
||||
space
|
||||
fi
|
||||
if [ "$ANSWER" == "y" ]; then
|
||||
sudo chmod 2775 /usr/local/src
|
||||
sudo chown root:staff /usr/local/src
|
||||
fi
|
||||
sudo chmod 2775 /usr/local/src
|
||||
sudo chown root:staff /usr/local/src
|
||||
fi
|
||||
else
|
||||
echo "/usr/local/src does not exist, creating."
|
||||
mkdir /usr/local/src
|
||||
mkdir -p /usr/local/src
|
||||
sudo chmod 2775 /usr/local/src
|
||||
# FIXME: This might fail on distros with no staff user
|
||||
sudo chown root:staff /usr/local/src
|
||||
fi
|
||||
}
|
||||
|
@ -783,7 +777,7 @@ genRCLOCAL () {
|
|||
|
||||
# Run PyMISP tests
|
||||
runTests () {
|
||||
sudo sed -i -E "s/url\ =\ (.*)/url\ =\ 'https:\/\/misp.local'/g" $PATH_TO_MISP/PyMISP/tests/testlive_comprehensive.py
|
||||
sudo sed -i -E "s~url\ =\ (.*)~url\ =\ '${MISP_BASEURL}'~g" $PATH_TO_MISP/PyMISP/tests/testlive_comprehensive.py
|
||||
sudo sed -i -E "s/key\ =\ (.*)/key\ =\ '${AUTH_KEY}'/g" $PATH_TO_MISP/PyMISP/tests/testlive_comprehensive.py
|
||||
sudo chown -R $WWW_USER:$WWW_USER $PATH_TO_MISP/PyMISP/
|
||||
|
||||
|
@ -1345,6 +1339,7 @@ mispmodules () {
|
|||
##sudo sed -i -e '$i \sudo -u www-data /var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s > /tmp/misp-modules_rc.local.log &\n' /etc/rc.local
|
||||
cd /usr/local/src/
|
||||
## TODO: checkUsrLocalSrc in main doc
|
||||
debug "Cloning misp-modules"
|
||||
$SUDO_USER git clone https://github.com/MISP/misp-modules.git
|
||||
cd misp-modules
|
||||
# some misp-modules dependencies
|
||||
|
@ -1490,17 +1485,20 @@ dashboardCAKE () {
|
|||
mail2misp () {
|
||||
debug "Installing Mail2${LBLUE}MISP${NC}"
|
||||
cd /usr/local/src/
|
||||
sudo apt-get install cmake libcaca-dev -y
|
||||
sudo apt-get install cmake libcaca-dev liblua5.3-dev -y
|
||||
$SUDO_USER git clone https://github.com/MISP/mail_to_misp.git
|
||||
$SUDO_USER git clone git://github.com/stricaud/faup.git faup
|
||||
sudo chown -R ${MISP_USER}:${MISP_USER} faup mail_to_misp
|
||||
cd faup
|
||||
# TODO Check permissions
|
||||
##$SUDO mkdir -p build
|
||||
$SUDO_USER git clone git://github.com/stricaud/gtcaca.git gtcaca
|
||||
sudo chown -R ${MISP_USER}:${MISP_USER} faup mail_to_misp gtcaca
|
||||
cd gtcaca
|
||||
$SUDO_USER mkdir -p build
|
||||
cd build
|
||||
$SUDO_USER cmake .. && $SUDO_USER make
|
||||
sudo make install
|
||||
cd ../../faup
|
||||
$SUDO_USER mkdir -p build
|
||||
cd build
|
||||
$SUDO_USER cmake .. && $SUDO_USER make
|
||||
##$SUDO cmake .. && $SUDO make
|
||||
sudo make install
|
||||
sudo ldconfig
|
||||
cd ../../mail_to_misp
|
||||
|
|
|
@ -16,11 +16,23 @@
|
|||
# 0/ Quick MISP Instance on Debian Based Linux - Status |
|
||||
#-------------------------------------------------------|
|
||||
#
|
||||
# 20190208: Kali Linux tested and working.
|
||||
# 20190302: Ubuntu 18.04.2 tested and working. -- sCl
|
||||
# 20190208: Kali Linux tested and working. -- sCl
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------------------------------|
|
||||
# 1/ For other Debian based Linux distributions, download script and run as **unprivileged** user |
|
||||
#-------------------------------------------------------------------------------------------------|
|
||||
#
|
||||
# The following installs only MISP-core:
|
||||
# $ curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh | bash -s -- -c
|
||||
#
|
||||
# This will install MISP Core and misp-modules (recommended)
|
||||
# $ curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh | bash -s -- -c -M
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------|
|
||||
# 1/ For Kali, download and run Installer Script |
|
||||
# 2/ For Kali, download and run Installer Script |
|
||||
#-------------------------------------------------------|
|
||||
#
|
||||
# To install MISP on Kali copy paste the following to your r00t shell:
|
||||
|
@ -29,13 +41,6 @@
|
|||
# The script is tested on a plain vanilla Kali Linux Boot CD and installs quite a few dependencies.
|
||||
#
|
||||
#
|
||||
#---------------------------------------------------------------------------------------------|
|
||||
# 2/ For other Debian based Linux distributions, download script and run as unprivileged user |
|
||||
#---------------------------------------------------------------------------------------------|
|
||||
#
|
||||
# $ wget -O ~/INSTALL.debian.sh https://raw.githubusercontent.com/MISP/MISP/2.4/INSTALL/INSTALL.debian.sh && bash ~/INSTALL.debian.sh -C
|
||||
#
|
||||
#
|
||||
#----------------------------------------------------------|
|
||||
# 3/ The following script has been partially autogenerated |
|
||||
#----------------------------------------------------------|
|
||||
|
|
|
@ -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);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
\.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit c35a2aea5544f323282b4737ce51b8fa4881b002
|
||||
Subproject commit c888af177f88af653ad395924a3b840ca22f0af4
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":102}
|
||||
{"major":2, "minor":4, "hotfix":104}
|
||||
|
|
|
@ -159,6 +159,7 @@ $config = array(
|
|||
//
|
||||
'ldapDefaultOrg' => '1', // uses 1st local org in MISP if undefined,
|
||||
'ldapAllowReferrals' => true, // allow or disallow chasing LDAP referrals
|
||||
//'ldapEmailField' => array('emailAddress, 'mail'), // Optional : fields from which the email address should be retrieved. Default to 'mail' only. If more than one field is set (e.g. 'emailAddress' and 'mail' in this example), only the first one will be used.
|
||||
),
|
||||
*/
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -1,34 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# TODO: Improve script to bring workers up that are not.
|
||||
# TODO: Put some logic inside if many worker PIDs are detected
|
||||
|
||||
# Extract base directory where this script is and cd into it
|
||||
cd "${0%/*}"
|
||||
|
||||
# Set to the current webroot owner
|
||||
WWW_USER=$(ls -l ../cake |awk {'print $3'}|tail -1)
|
||||
|
||||
# In most cases the owner of the cake script is also the user as which it should be executed.
|
||||
if [[ "$USER" != "$WWW_USER" ]]; then
|
||||
echo "You run this script as $USER and the owner of the cake command is $WWW_USER. This might be an issue."
|
||||
fi
|
||||
|
||||
# Check if run as root
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
if [[ "$EUID" -eq "0" ]]; then
|
||||
echo "Please DO NOT run the worker script as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##[[ $(../cake CakeResque.CakeResque stop --all |grep "not permitted" ; echo $?) != 1 ]] && echo "Either you have no permissions or CakeResque is not installed/configured" && exit 1
|
||||
|
||||
## FIXME: PIDs seem off by 1
|
||||
# Check which workers are currently running
|
||||
WORKERS_PID=$(ps a |grep CakeResque |grep -v grep |cut -f 1 -d\ )
|
||||
|
||||
if [[ ! -z $WORKERS_PID ]]; then
|
||||
for p in $WORKERS_PID; do
|
||||
WORKER_RUNNING=$(ps $p |grep CakeRes|grep -v grep |grep -o -e "QUEUE=.[a-z]*" |cut -f2 -d\')
|
||||
#echo "Worker $WORKER_RUNNING with PID $p"
|
||||
done
|
||||
# Check if jq is present and enable advanced checks
|
||||
if [[ "$(jq -V > /dev/null 2> /dev/null; echo $?)" != 0 ]]; then
|
||||
echo "jq is not installed, disabling advanced checks."
|
||||
ADVANCED="0"
|
||||
else
|
||||
ADVANCED="1"
|
||||
fi
|
||||
|
||||
../cake CakeResque.CakeResque stop --all
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue default
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue prio
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue cache
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue email
|
||||
../cake CakeResque.CakeResque startscheduler --interval 5
|
||||
if [[ "$ADVANCED" == "1" ]]; then
|
||||
for worker in `echo cache default email prio scheduler`; do
|
||||
workerStatus=$(../cake Admin getWorkers |tail -n +7 |jq -r ".$worker" |jq -r '.ok')
|
||||
PIDcount=$(../cake admin getWorkers |tail -n +7 |jq -r ".$worker.workers" |grep pid | wc -l)
|
||||
echo -n "$worker has $PIDcount PID(s)"
|
||||
if [[ "$workerStatus" != "true" ]]; then
|
||||
echo ", trying to restart."
|
||||
if [[ "$worker" != "scheduler" ]]; then
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue $worker
|
||||
else
|
||||
../cake CakeResque.CakeResque startscheduler --interval 5
|
||||
fi
|
||||
else
|
||||
echo ", up and running."
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
else
|
||||
|
||||
exit 0
|
||||
../cake CakeResque.CakeResque stop --all
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue default
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue prio
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue cache
|
||||
../cake CakeResque.CakeResque start --interval 5 --queue email
|
||||
../cake CakeResque.CakeResque startscheduler --interval 5
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# TODO: Put some logic inside if many worker PIDs are detected
|
||||
|
||||
# Extract base directory where this script is and cd into it
|
||||
cd "${0%/*}"
|
||||
|
||||
# Set to the current webroot owner
|
||||
WWW_USER=$(ls -l ../cake |awk {'print $3'}|tail -1)
|
||||
|
||||
# In most cases the owner of the cake script is also the user as which it should be executed.
|
||||
if [[ "$USER" != "$WWW_USER" ]]; then
|
||||
echo "You run this script as $USER and the owner of the cake command is $WWW_USER. This might be an issue."
|
||||
fi
|
||||
|
||||
# Check if run as root
|
||||
if [[ "$EUID" -eq "0" ]]; then
|
||||
echo "Please DO NOT run the worker script as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
../cake CakeResque.CakeResque stop --all
|
|
@ -46,8 +46,8 @@ class AppController extends Controller
|
|||
|
||||
public $helpers = array('Utility', 'OrgImg');
|
||||
|
||||
private $__queryVersion = '60';
|
||||
public $pyMispVersion = '2.4.102';
|
||||
private $__queryVersion = '63';
|
||||
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);
|
||||
|
|
|
@ -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) {
|
||||
|
@ -1171,7 +1175,7 @@ class AttributesController extends AppController
|
|||
throw new NotFoundException('Invalid attribute');
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
$conditions = array('conditions' => array('Attribute.id' => $id), 'withAttachments' => true);
|
||||
$conditions = array('conditions' => array('Attribute.id' => $id), 'withAttachments' => true, 'flatten' => true);
|
||||
$conditions['includeAllTags'] = false;
|
||||
$conditions['includeAttributeUuid'] = true;
|
||||
$attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $conditions);
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ class ACLComponent extends Component
|
|||
'getEventGraphReferences' => array('*'),
|
||||
'getEventGraphTags' => array('*'),
|
||||
'getEventGraphGeneric' => array('*'),
|
||||
'genDistributionGraph' => array('*'),
|
||||
'getDistributionGraph' => array('*'),
|
||||
'getReferenceData' => array('*'),
|
||||
'getReferences' => array('*'),
|
||||
|
@ -129,6 +130,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('*'),
|
||||
|
@ -165,6 +167,7 @@ class ACLComponent extends Component
|
|||
'disable' => array(),
|
||||
'edit' => array(),
|
||||
'enable' => array(),
|
||||
'feedCoverage' => array('*'),
|
||||
'fetchFromAllFeeds' => array(),
|
||||
'fetchFromFeed' => array(),
|
||||
'fetchSelectedFromFreetextIndex' => array(),
|
||||
|
@ -179,6 +182,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'),
|
||||
|
@ -193,7 +197,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('*')
|
||||
|
@ -302,6 +307,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(),
|
||||
|
@ -429,8 +438,13 @@ class ACLComponent extends Component
|
|||
'enable' => array(),
|
||||
'index' => array('*'),
|
||||
'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'),
|
||||
'hideTag' => array('perm_tagger'),
|
||||
),
|
||||
'templateElements' => array(
|
||||
'add' => array('perm_template'),
|
||||
|
|
|
@ -38,6 +38,17 @@ class ApacheAuthenticate extends BaseAuthenticate
|
|||
}
|
||||
return $returnCode;
|
||||
}
|
||||
|
||||
private function getEmailAddress($ldapEmailField, $ldapUserData)
|
||||
{
|
||||
// return the email address of an LDAP user if one of the fields in $ldapEmaiLField exists
|
||||
foreach($ldapEmailField as $field) {
|
||||
if (isset($ldapUserData[0][$field][0])) {
|
||||
return $ldapUserData[0][$field][0];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response)
|
||||
{
|
||||
|
@ -51,6 +62,7 @@ class ApacheAuthenticate extends BaseAuthenticate
|
|||
$ldaprdn = Configure::read('ApacheSecureAuth.ldapReaderUser'); // DN ou RDN LDAP
|
||||
$ldappass = Configure::read('ApacheSecureAuth.ldapReaderPassword');
|
||||
$ldapSearchFilter = Configure::read('ApacheSecureAuth.ldapSearchFilter');
|
||||
$ldapEmailField = Configure::read('ApacheSecureAuth.ldapEmailField');
|
||||
|
||||
// LDAP connection
|
||||
ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, Configure::read('ApacheSecureAuth.ldapNetworkTimeout', -1));
|
||||
|
@ -83,13 +95,17 @@ class ApacheAuthenticate extends BaseAuthenticate
|
|||
|
||||
$ldapUserData = ldap_get_entries($ldapconn, $result);
|
||||
|
||||
// the request returns only 1 field
|
||||
if (isset($ldapUserData[0]['mail'][0])) {
|
||||
// find the email address in the query's result
|
||||
// first if the ldapEmailField option is not specified, look for the email address in the default field
|
||||
if (!isset($ldapEmailField) && isset($ldapUserData[0]['mail'][0])) {
|
||||
// assign the real user for MISP
|
||||
$mispUsername = $ldapUserData[0]['mail'][0];
|
||||
} else if (isset($ldapEmailField)) {
|
||||
$mispUsername = $this->getEmailAddress($ldapEmailField, $ldapUserData);
|
||||
} else {
|
||||
die("User not found in LDAP");
|
||||
}
|
||||
|
||||
// close LDAP connection
|
||||
ldap_close($ldapconn);
|
||||
}
|
||||
|
|
|
@ -243,6 +243,10 @@ class RestResponseComponent extends Component
|
|||
'description' => "POST a body and a subject in a JSON to send an e-mail through MISP to the user ID given in the URL",
|
||||
'mandatory' => array('subject', 'body')
|
||||
),
|
||||
'change_pw' => array(
|
||||
'description' => "POST a password via a JSON object containing the password key to reset the given user\'s password.",
|
||||
'mandatory' => array('password')
|
||||
),
|
||||
'statistics' => array(
|
||||
'description' => 'Simply GET the url endpoint to view the API output of the statistics API. Additional statistics are available via the following tab-options similar to the UI: data, orgs, users, tags, attributehistogram, sightings, attackMatrix',
|
||||
'params' => array('tab'),
|
||||
|
|
|
@ -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(
|
||||
|
@ -296,19 +296,31 @@ class EventsController extends AppController
|
|||
$passedArgsArray = array();
|
||||
$urlparams = "";
|
||||
$overrideAbleParams = array('all', 'attribute', 'published', 'eventid', 'datefrom', 'dateuntil', 'org', 'eventinfo', 'tag', 'tags', 'distribution', 'sharinggroup', 'analysis', 'threatlevel', 'email', 'hasproposal', 'timestamp', 'publishtimestamp', 'publish_timestamp', 'minimal');
|
||||
$paginationParams = array('limit', 'page', 'sort', 'direction', 'order');
|
||||
$passedArgs = $this->passedArgs;
|
||||
if (isset($this->request->data)) {
|
||||
if (isset($this->request->data['request'])) {
|
||||
$this->request->data = $this->request->data['request'];
|
||||
}
|
||||
foreach ($overrideAbleParams as $oap) {
|
||||
if (isset($this->request->data['search' . $oap])) {
|
||||
$this->request->data[$oap] = $this->request->data['search' . $oap];
|
||||
foreach ($this->request->data as $k => $v) {
|
||||
if (substr($k, 0, 6) === 'search' && in_array(strtolower(substr($k, 6)), $overrideAbleParams)) {
|
||||
unset($this->request->data[$k]);
|
||||
$this->request->data[strtolower(substr($k, 6))] = $v;
|
||||
} else if (in_array(strtolower($k), $overrideAbleParams)) {
|
||||
unset($this->request->data[$k]);
|
||||
$this->request->data[strtolower($k)] = $v;
|
||||
}
|
||||
}
|
||||
foreach ($overrideAbleParams as $oap) {
|
||||
if (isset($this->request->data[$oap])) {
|
||||
$passedArgs['search' . $oap] = $this->request->data[$oap];
|
||||
}
|
||||
}
|
||||
foreach ($paginationParams as $paginationParam) {
|
||||
if (isset($this->request->data[$paginationParam])) {
|
||||
$passedArgs[$paginationParam] = $this->request->data[$paginationParam];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
// check each of the passed arguments whether they're a filter (could also be a sort for example) and if yes, add it to the pagination conditions
|
||||
|
@ -699,12 +711,6 @@ class EventsController extends AppController
|
|||
} else {
|
||||
$rules['order'] = array('Event.id' => 'DESC');
|
||||
}
|
||||
if (isset($passedArgs['limit'])) {
|
||||
$rules['limit'] = intval($passedArgs['limit']);
|
||||
}
|
||||
if (isset($passedArgs['page'])) {
|
||||
$rules['page'] = intval($passedArgs['page']);
|
||||
}
|
||||
$rules['contain'] = $this->paginate['contain'];
|
||||
if (isset($this->paginate['conditions'])) {
|
||||
$rules['conditions'] = $this->paginate['conditions'];
|
||||
|
@ -714,6 +720,12 @@ class EventsController extends AppController
|
|||
$rules['recursive'] = -1;
|
||||
$rules['fields'] = array('id', 'timestamp', 'published', 'uuid');
|
||||
}
|
||||
$paginationRules = array('page', 'limit', 'sort', 'direction', 'order');
|
||||
foreach ($paginationRules as $paginationRule) {
|
||||
if (isset($passedArgs[$paginationRule])) {
|
||||
$rules[$paginationRule] = $passedArgs[$paginationRule];
|
||||
}
|
||||
}
|
||||
if (empty($rules['limit'])) {
|
||||
$events = array();
|
||||
$i = 1;
|
||||
|
@ -856,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();
|
||||
|
@ -1444,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);
|
||||
|
@ -2350,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 {
|
||||
|
@ -2387,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')) {
|
||||
|
@ -3518,9 +3551,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,
|
||||
|
@ -3533,112 +3563,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'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4655,8 +4693,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.'));
|
||||
|
@ -4665,9 +4702,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'),
|
||||
|
@ -4680,6 +4714,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'));
|
||||
}
|
||||
|
@ -4903,7 +4944,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);
|
||||
|
@ -4986,12 +5026,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'])) {
|
||||
|
@ -5004,65 +5044,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;
|
||||
|
@ -5072,18 +5063,133 @@ 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 {
|
||||
$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 importModule($module, $eventId)
|
||||
{
|
||||
$this->loadModel('Module');
|
||||
|
@ -5339,6 +5445,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)) {
|
||||
|
|
|
@ -23,6 +23,7 @@ class FeedsController extends AppController
|
|||
{
|
||||
parent::beforeFilter();
|
||||
$this->Security->unlockedActions[] = 'previewIndex';
|
||||
$this->Security->unlockedActions[] = 'feedCoverage';
|
||||
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') != Configure::read('MISP.host_org_id')) {
|
||||
throw new MethodNotAllowedException(__('You don\'t have the required privileges to do that.'));
|
||||
}
|
||||
|
@ -88,12 +89,32 @@ class FeedsController extends AppController
|
|||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
$feed['Feed']['cached_elements'] = $this->Feed->getCachedElements($feed['Feed']['id']);
|
||||
$feed['Feed']['coverage_by_other_feeds'] = $this->Feed->getFeedCoverage($feed['Feed']['id'], 'feed', 'all') . '%';
|
||||
if ($this->_isRest()) {
|
||||
if (empty($feed['Tag']['id'])) {
|
||||
unset($feed['Tag']);
|
||||
}
|
||||
return $this->RestResponse->viewData($feed, $this->response->type());
|
||||
}
|
||||
$feeds = $this->Feed->getAllCachingEnabledFeeds($feed['Feed']['id'], true);
|
||||
$this->set('other_feeds', $feeds);
|
||||
$this->set('feed', $feed);
|
||||
}
|
||||
|
||||
public function feedCoverage($feedId)
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->Auth->user('org_id') == Configure::read('MISP.host_org_id')) {
|
||||
throw NotAllowedException('You don\'t have access to this feature.');
|
||||
}
|
||||
$feed = $this->Feed->find('first', array(
|
||||
'conditions' => array('Feed.id' => $feedId),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Tag')
|
||||
));
|
||||
$result = $this->Feed->getFeedCoverage($feed['Feed']['id'], 'feed', $this->request->data);
|
||||
return $this->RestResponse->viewData($result, $this->response->type());
|
||||
|
||||
}
|
||||
|
||||
public function importFeeds()
|
||||
|
@ -238,6 +259,7 @@ class FeedsController extends AppController
|
|||
throw new NotFoundException(__('Invalid feed.'));
|
||||
}
|
||||
$this->Feed->read();
|
||||
$this->set('feed', $this->Feed->data);
|
||||
$this->loadModel('Event');
|
||||
$sgs = $this->Event->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', 1);
|
||||
$distributionLevels = $this->Event->distributionLevels;
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.'));
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
@ -334,7 +332,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.'));
|
||||
}
|
||||
|
@ -1142,10 +1140,16 @@ class ServersController extends AppController
|
|||
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 +1572,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 +1602,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 +1661,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 +1704,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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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,69 @@ 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());
|
||||
}
|
||||
|
||||
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.'));
|
||||
}
|
||||
if ($taxonomy_id) {
|
||||
$result = $this->Taxonomy->hideTags($taxonomy_id);
|
||||
} else {
|
||||
if (isset($this->request->data['Taxonomy'])) {
|
||||
$this->request->data['Tag'] = $this->request->data['Taxonomy'];
|
||||
unset($this->request->data['Taxonomy']);
|
||||
}
|
||||
if (isset($this->request->data['Tag']['request'])) {
|
||||
$this->request->data['Tag'] = $this->request->data['Tag']['request'];
|
||||
}
|
||||
if (!isset($this->request->data['Tag']['nameList'])) {
|
||||
$this->request->data['Tag']['nameList'] = array($this->request->data['Tag']['name']);
|
||||
} else {
|
||||
$this->request->data['Tag']['nameList'] = json_decode($this->request->data['Tag']['nameList'], true);
|
||||
}
|
||||
$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.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The tag(s) could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
||||
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.'));
|
||||
}
|
||||
if ($taxonomy_id) {
|
||||
$result = $this->Taxonomy->unhideTags($taxonomy_id);
|
||||
} else {
|
||||
if (isset($this->request->data['Taxonomy'])) {
|
||||
$this->request->data['Tag'] = $this->request->data['Taxonomy'];
|
||||
unset($this->request->data['Taxonomy']);
|
||||
}
|
||||
if (isset($this->request->data['Tag']['request'])) {
|
||||
$this->request->data['Tag'] = $this->request->data['Tag']['request'];
|
||||
}
|
||||
if (!isset($this->request->data['Tag']['nameList'])) {
|
||||
$this->request->data['Tag']['nameList'] = array($this->request->data['Tag']['name']);
|
||||
} else {
|
||||
$this->request->data['Tag']['nameList'] = json_decode($this->request->data['Tag']['nameList'], true);
|
||||
}
|
||||
$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.'));
|
||||
} else {
|
||||
$this->Flash->error(__('The tag(s) could not be saved. Please, try again.'));
|
||||
}
|
||||
$this->redirect($this->referer());
|
||||
}
|
||||
|
@ -257,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);
|
||||
|
@ -277,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());
|
||||
}
|
||||
|
@ -287,21 +361,39 @@ 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');
|
||||
}
|
||||
|
||||
public function taxonomyMassHide($id)
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
|
||||
throw new NotFoundException(__('You don\'t have permission to do that.'));
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->render('ajax/taxonomy_mass_hide');
|
||||
}
|
||||
|
||||
public function taxonomyMassUnhide($id)
|
||||
{
|
||||
if (!$this->_isSiteAdmin() && !$this->userRole['perm_tagger']) {
|
||||
throw new NotFoundException(__('You don\'t have permission to do that.'));
|
||||
}
|
||||
$this->set('id', $id);
|
||||
$this->render('ajax/taxonomy_mass_unhide');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
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 {
|
||||
|
@ -309,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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,37 +173,63 @@ class UsersController extends AppController
|
|||
'recursive' => -1
|
||||
));
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
if (!isset($this->request->data['User'])) {
|
||||
$this->request->data = array('User' => $this->request->data);
|
||||
}
|
||||
$abortPost = false;
|
||||
if (Configure::read('Security.require_password_confirmation')) {
|
||||
if (!empty($this->request->data['User']['current_password'])) {
|
||||
$hashed = $this->User->verifyPassword($this->Auth->user('id'), $this->request->data['User']['current_password']);
|
||||
if (!$hashed) {
|
||||
$message = __('Invalid password. Please enter your current password to continue.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Users', 'change_pw', false, $message, $this->response->type());
|
||||
}
|
||||
$abortPost = true;
|
||||
$this->Flash->error('Invalid password. Please enter your current password to continue.');
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
unset($this->request->data['User']['current_password']);
|
||||
} else {
|
||||
} else if (!$this->_isRest()) {
|
||||
$message = __('Please enter your current password to continue.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Users', 'change_pw', false, $message, $this->response->type());
|
||||
}
|
||||
$abortPost = true;
|
||||
$this->Flash->info('Please enter your current password to continue.');
|
||||
$this->Flash->info($message);
|
||||
}
|
||||
}
|
||||
if (!$abortPost) {
|
||||
// What fields should be saved (allowed to be saved)
|
||||
$user['User']['change_pw'] = 0;
|
||||
$user['User']['password'] = $this->request->data['User']['password'];
|
||||
$user['User']['confirm_password'] = $this->request->data['User']['confirm_password'];
|
||||
if ($this->_isRest()) {
|
||||
$user['User']['confirm_password'] = $this->request->data['User']['password'];
|
||||
} else {
|
||||
$user['User']['confirm_password'] = $this->request->data['User']['confirm_password'];
|
||||
}
|
||||
$temp = $user['User']['password'];
|
||||
// Save the data
|
||||
if ($this->User->save($user)) {
|
||||
$this->Flash->success(__('Password Changed.'));
|
||||
$this->_refreshAuth();
|
||||
$message = __('Password Changed.');
|
||||
$this->__extralog("change_pw");
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('User', 'change_pw', false, $this->response->type(), $message);
|
||||
}
|
||||
$this->Flash->success($message);
|
||||
$this->_refreshAuth();
|
||||
$this->redirect(array('action' => 'view', $id));
|
||||
} else {
|
||||
$this->Flash->error(__('The password could not be updated. Make sure you meet the minimum password length / complexity requirements.'));
|
||||
$message = __('The password could not be updated. Make sure you meet the minimum password length / complexity requirements.');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('Users', 'change_pw', false, $message, $this->response->type());
|
||||
}
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->describe('Users', 'change_pw', false, $this->response->type());
|
||||
}
|
||||
$this->loadModel('Server');
|
||||
$this->set('complexity', !empty(Configure::read('Security.password_policy_complexity')) ? Configure::read('Security.password_policy_complexity') : $this->Server->serverSettings['Security']['password_policy_complexity']['value']);
|
||||
$this->set('length', !empty(Configure::read('Security.password_policy_length')) ? Configure::read('Security.password_policy_length') : $this->Server->serverSettings['Security']['password_policy_length']['value']);
|
||||
|
@ -1122,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1256,7 +1282,7 @@ class UsersController extends AppController
|
|||
} elseif ($action == 'edit') {
|
||||
$description = "User (" . $this->User->id . "): " . $this->data['User']['email'];
|
||||
} elseif ($action == 'change_pw') {
|
||||
$description = "User (" . $this->User->id . "): " . $this->data['User']['email'];
|
||||
$description = "User (" . $this->User->id . "): " . $this->Auth->user('email');
|
||||
$fieldsResult = "Password changed.";
|
||||
}
|
||||
|
||||
|
@ -1527,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']);
|
||||
}
|
||||
|
@ -1552,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;
|
||||
|
@ -1855,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'];
|
||||
|
@ -1877,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];
|
||||
|
@ -1937,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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -6624,6 +6624,10 @@ msgstr ""
|
|||
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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -6624,6 +6624,10 @@ msgstr ""
|
|||
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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
);
|
||||
|
||||
public function afterSave($created, $options = array())
|
||||
|
@ -1096,6 +1099,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 +1537,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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5702,14 +5746,20 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
if ($saved == 1) {
|
||||
$messageScopeSaved = Inflector::singularize($messageScope);
|
||||
} else {
|
||||
$messageScopeSaved = Inflector::pluralize($messageScope);
|
||||
}
|
||||
if ($failed > 0) {
|
||||
if ($failed == 1) {
|
||||
$message = $saved . ' ' . $messageScope . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. Reason for the failure: ' . json_encode($lastError);
|
||||
$messageScopeFailed = Inflector::singularize($messageScope);
|
||||
$message = $saved . ' ' . $messageScopeSaved . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScopeFailed . ' could not be saved. Reason for the failure: ' . json_encode($lastError);
|
||||
} else {
|
||||
$message = $saved . ' ' . $messageScope . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. This may be due to attributes with similar values already existing.';
|
||||
$message = $saved . ' ' . $messageScopeSaved . ' created' . $emailResult . '. ' . $failed . ' ' . $messageScope . ' could not be saved. This may be due to attributes with similar values already existing.';
|
||||
}
|
||||
} else {
|
||||
$message = $saved . ' ' . $messageScope . ' created' . $emailResult . '.';
|
||||
$message = $saved . ' ' . $messageScopeSaved . ' created' . $emailResult . '.';
|
||||
}
|
||||
if ($jobId) {
|
||||
if ($i % 20 == 0) {
|
||||
|
@ -5990,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('RandomTool', 'Tools');
|
||||
|
||||
class Feed extends AppModel
|
||||
{
|
||||
|
@ -1393,4 +1394,112 @@ class Feed extends AppModel
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFeedCoverage($id, $source_scope = 'feed', $dataset = 'all')
|
||||
{
|
||||
$redis = $this->setupRedis();
|
||||
if ($redis === false) {
|
||||
return 'Could not reach Redis.';
|
||||
}
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$feed_conditions = array('Feed.caching_enabled' => 1);
|
||||
$server_conditions = array('Server.caching_enabled' => 1);
|
||||
if ($source_scope === 'feed') {
|
||||
$feed_conditions['NOT'] = array('Feed.id' => $id);
|
||||
} else {
|
||||
$server_conditions['NOT'] = array('Server.id' => $id);
|
||||
}
|
||||
if ($dataset !== 'all') {
|
||||
if (empty($dataset['Feed'])) {
|
||||
$feed_conditions['OR'] = array('Feed.id' => -1);
|
||||
} else {
|
||||
$feed_conditions['OR'] = array('Feed.id' => $dataset['Feed']);
|
||||
}
|
||||
if (empty($dataset['Server'])) {
|
||||
$server_conditions['OR'] = array('Server.id' => -1);
|
||||
} else {
|
||||
$server_conditions['OR'] = array('Server.id' => $dataset['Server']);
|
||||
}
|
||||
}
|
||||
$other_feeds = $this->find('list', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $feed_conditions,
|
||||
'fields' => array('Feed.id', 'Feed.id')
|
||||
));
|
||||
$other_servers = $this->Server->find('list', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $server_conditions,
|
||||
'fields' => array('Server.id', 'Server.id')
|
||||
));
|
||||
$feed_element_count = $redis->scard('misp:feed_cache:' . $id);
|
||||
$temp_store = (new RandomTool())->random_str(false, 12);
|
||||
$params = array('misp:feed_temp:' . $temp_store);
|
||||
foreach ($other_feeds as $other_feed) {
|
||||
$params[] = 'misp:feed_cache:' . $other_feed;
|
||||
}
|
||||
foreach ($other_servers as $other_server) {
|
||||
$params[] = 'misp:server_cache:' . $other_server;
|
||||
}
|
||||
if (count($params) != 1 && $feed_element_count > 0) {
|
||||
call_user_func_array(array($redis, 'sunionstore'), $params);
|
||||
call_user_func_array(array($redis, 'sinterstore'), array('misp:feed_temp:' . $temp_store . '_intersect', 'misp:feed_cache:' . $id, 'misp:feed_temp:' . $temp_store));
|
||||
$cardinality_intersect = $redis->scard('misp:feed_temp:' . $temp_store . '_intersect');
|
||||
$coverage = round(100 * $cardinality_intersect / $feed_element_count, 2);
|
||||
$redis->del('misp:feed_temp:' . $temp_store);
|
||||
$redis->del('misp:feed_temp:' . $temp_store . '_intersect');
|
||||
} else {
|
||||
$coverage = 0;
|
||||
}
|
||||
return $coverage;
|
||||
}
|
||||
|
||||
public function getCachedElements($feedId)
|
||||
{
|
||||
$redis = $this->setupRedis();
|
||||
$cardinality = $redis->sCard('misp:feed_cache:' . $feedId);
|
||||
return $cardinality;
|
||||
}
|
||||
|
||||
public function getAllCachingEnabledFeeds($feedId, $intersectingOnly = false) {
|
||||
if ($intersectingOnly) {
|
||||
$redis = $this->setupRedis();
|
||||
}
|
||||
$result['Feed'] = $this->find('all', array(
|
||||
'conditions' => array(
|
||||
'Feed.id !=' => $feedId,
|
||||
'caching_enabled' => 1
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Feed.id', 'Feed.name', 'Feed.url')
|
||||
));
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$result['Server'] = $this->Server->find('all', array(
|
||||
'conditions' => array(
|
||||
'caching_enabled' => 1
|
||||
),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Server.id', 'Server.name', 'Server.url')
|
||||
));
|
||||
$scopes = array('Feed', 'Server');
|
||||
foreach ($scopes as $scope) {
|
||||
foreach ($result[$scope] as $k => $v) {
|
||||
$result[$scope][$k] = $v[$scope];
|
||||
}
|
||||
}
|
||||
if ($intersectingOnly) {
|
||||
foreach ($scopes as $scope) {
|
||||
if (!empty($result[$scope])) {
|
||||
foreach ($result[$scope] as $k => $feed) {
|
||||
$intersect = $redis->sInter('misp:feed_cache:' . $feedId, 'misp:' . lcfirst($scope) . '_cache:' . $feed['id']);
|
||||
if (empty($intersect)) {
|
||||
unset($result[$scope][$k]);
|
||||
} else {
|
||||
$result[$scope][$k]['matching_values'] = count($intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
|
@ -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.'
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -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.'),
|
||||
|
@ -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.'),
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,6 +362,72 @@ class Taxonomy extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function hideTags($id, $tagList = false)
|
||||
{
|
||||
if ($tagList && !is_array($tagList)) {
|
||||
$tagList = array($tagList);
|
||||
}
|
||||
$this->Tag = ClassRegistry::init('Tag');
|
||||
App::uses('ColourPaletteTool', 'Tools');
|
||||
$paletteTool = new ColourPaletteTool();
|
||||
$taxonomy = $this->__getTaxonomy($id, array('full' => true));
|
||||
$tags = $this->Tag->getTagsForNamespace($taxonomy['Taxonomy']['namespace']);
|
||||
$colours = $paletteTool->generatePaletteFromString($taxonomy['Taxonomy']['namespace'], count($taxonomy['entries']));
|
||||
foreach ($taxonomy['entries'] as $k => $entry) {
|
||||
$colour = $colours[$k];
|
||||
if (isset($entry['colour']) && !empty($entry['colour'])) {
|
||||
$colour = $entry['colour'];
|
||||
}
|
||||
if ($tagList) {
|
||||
foreach ($tagList as $tagName) {
|
||||
if ($tagName === $entry['tag']) {
|
||||
if (isset($tags[strtoupper($entry['tag'])])) {
|
||||
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $tagName, $colour, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isset($tags[strtoupper($entry['tag'])])) {
|
||||
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $entry['tag'], $colour, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unhideTags($id, $tagList = false)
|
||||
{
|
||||
if ($tagList && !is_array($tagList)) {
|
||||
$tagList = array($tagList);
|
||||
}
|
||||
$this->Tag = ClassRegistry::init('Tag');
|
||||
App::uses('ColourPaletteTool', 'Tools');
|
||||
$paletteTool = new ColourPaletteTool();
|
||||
$taxonomy = $this->__getTaxonomy($id, array('full' => true));
|
||||
$tags = $this->Tag->getTagsForNamespace($taxonomy['Taxonomy']['namespace']);
|
||||
$colours = $paletteTool->generatePaletteFromString($taxonomy['Taxonomy']['namespace'], count($taxonomy['entries']));
|
||||
foreach ($taxonomy['entries'] as $k => $entry) {
|
||||
$colour = $colours[$k];
|
||||
if (isset($entry['colour']) && !empty($entry['colour'])) {
|
||||
$colour = $entry['colour'];
|
||||
}
|
||||
if ($tagList) {
|
||||
foreach ($tagList as $tagName) {
|
||||
if ($tagName === $entry['tag']) {
|
||||
if (isset($tags[strtoupper($entry['tag'])])) {
|
||||
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $tagName, $colour, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isset($tags[strtoupper($entry['tag'])])) {
|
||||
$this->Tag->quickEdit($tags[strtoupper($entry['tag'])], $entry['tag'], $colour, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function listTaxonomies($options = array('full' => false, 'enabled' => false))
|
||||
{
|
||||
$recursive = -1;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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): ?>
|
||||
|
@ -79,11 +79,11 @@
|
|||
<?php
|
||||
if ($event['Event']['published'] == 1) {
|
||||
?>
|
||||
<a href="<?php echo $baseurl."/events/view/".$event['Event']['id'] ?>" title = "<?php echo __('View');?>"><i class="black fa fa-check"></i></a>
|
||||
<a href="<?php echo $baseurl."/events/view/".$event['Event']['id'] ?>" title = "<?php echo __('View');?>" aria-label = "<?php echo __('View');?>"><i class="black fa fa-check"></i></a>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<a href="<?php echo $baseurl."/events/view/".$event['Event']['id'] ?>" title = "<?php echo __('View');?>"><i class="black fa fa-times"></i></a>
|
||||
<a href="<?php echo $baseurl."/events/view/".$event['Event']['id'] ?>" title = "<?php echo __('View');?>" aria-label = "<?php echo __('View');?>"><i class="black fa fa-times"></i></a>
|
||||
<?php
|
||||
}?>
|
||||
</td>
|
||||
|
@ -135,7 +135,7 @@
|
|||
<span class="blue">
|
||||
|
||||
<a href="<?php echo $baseurl; ?>/events/index/searchtag:<?php echo h($cluster['tag_id']); ?>"><?php echo h($cluster['value']); ?></a>
|
||||
<a href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>"><i class="black fa fa-search"></i></a>
|
||||
<a aria-label="<?php echo __('View cluster');?>" href="<?php echo $baseurl; ?>/galaxy_clusters/view/<?php echo h($cluster['id']); ?>"><i class="black fa fa-search"></i></a>
|
||||
</span>
|
||||
<?php
|
||||
endforeach;
|
||||
|
@ -214,22 +214,32 @@
|
|||
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
|
||||
if (0 == $event['Event']['published'] && ($isSiteAdmin || ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id'])))
|
||||
echo $this->Form->postLink('', array('action' => 'alert', $event['Event']['id']), array('class' => 'black fa fa-upload', 'title' => __('Publish Event'), __('Are you sure this event is complete and everyone should be informed?')));
|
||||
echo $this->Form->postLink('', array('action' => 'alert', $event['Event']['id']), array('class' => 'black fa fa-upload', 'title' => __('Publish Event'), 'aria-label' => __('Publish Event')), __('Are you sure this event is complete and everyone should be informed?'));
|
||||
else if (0 == $event['Event']['published']) echo __('Not published');
|
||||
|
||||
if ($isSiteAdmin || ($isAclModify && $event['Event']['user_id'] == $me['id']) || ($isAclModifyOrg && $event['Event']['orgc_id'] == $me['org_id'])):
|
||||
?>
|
||||
<a href='<?php echo $baseurl."/events/edit/".$event['Event']['id'];?>' title = "<?php echo __('Edit');?>"><i class="black fa fa-edit"></i></a>
|
||||
<a href='<?php echo $baseurl."/events/edit/".$event['Event']['id'];?>' title = "<?php echo __('Edit');?>" aria-label = "<?php echo __('Edit');?>"><i class="black fa fa-edit"></i></a>
|
||||
<?php
|
||||
|
||||
echo $this->Form->postLink('', array('action' => 'delete', $event['Event']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete # %s?', $event['Event']['id']));
|
||||
echo $this->Form->postLink('', array('action' => 'delete', $event['Event']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to delete # %s?', $event['Event']['id']));
|
||||
endif;
|
||||
?>
|
||||
<a href='<?php echo $baseurl."/events/view/".$event['Event']['id'];?>' title = "<?php echo __('View');?>"><i class="fa black fa-eye"></i></a>
|
||||
<a href='<?php echo $baseurl."/events/view/".$event['Event']['id'];?>' title = "<?php echo __('View');?>" aria-label = "<?php echo __('View');?>"><i class="fa black fa-eye"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
@ -239,5 +249,11 @@
|
|||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
|
||||
$('.distributionNetworkToggle').each(function() {
|
||||
$(this).distributionNetwork({
|
||||
distributionData: <?php echo json_encode($distributionData); ?>,
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
$progress_bar = sprintf(
|
||||
'<div class="span11 progress" style="margin-left:0px;"><div id="feed_coverage_bar" class="bar" style="width: %s;">%s</div></div><div class="span1"> </div><br /><br />',
|
||||
(empty($feed['Feed']['coverage_by_selected_feeds']) ? h($feed['Feed']['coverage_by_other_feeds']) : h($feed['Feed']['coverage_by_selected_feeds'])),
|
||||
(empty($feed['Feed']['coverage_by_selected_feeds']) ? h($feed['Feed']['coverage_by_other_feeds']) : h($feed['Feed']['coverage_by_selected_feeds']))
|
||||
);
|
||||
echo sprintf(
|
||||
'<h3>%s</h3><p class="bold">%s</p>%s',
|
||||
__('Feed coverage tool'),
|
||||
__('Coverage by currently selected sources: '),
|
||||
$progress_bar
|
||||
);
|
||||
$options = array(
|
||||
'Server' => array(
|
||||
'left' => array(), 'right' => array()
|
||||
),
|
||||
'Feed' => array(
|
||||
'left' => array(), 'right' => array()
|
||||
)
|
||||
);
|
||||
//debug($other_feeds);
|
||||
foreach (array_keys($options) as $scope) {
|
||||
array_multisort(array_column($other_feeds[$scope], 'matching_values'), SORT_DESC, $other_feeds[$scope]);
|
||||
}
|
||||
foreach ($options as $scope => $temp) {
|
||||
if (!empty($other_feeds[$scope])) {
|
||||
foreach ($other_feeds[$scope] as $other_feed) {
|
||||
if (!empty($other_feed['exclude'])) {
|
||||
$options[$scope]['right'][$other_feed['name']] = $other_feed;
|
||||
} else {
|
||||
$options[$scope]['left'][$other_feed['name']] = $other_feed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($options as $scope => $data) {
|
||||
$temp = array('left' => array(), 'right' => array());
|
||||
foreach ($data as $side => $data_points) {
|
||||
if (!empty($data[$side])) {
|
||||
foreach ($data_points as $data_point) {
|
||||
$temp[$side][] = sprintf(
|
||||
'<option value=%s>%s</option>',
|
||||
h($data_point['id']),
|
||||
sprintf(
|
||||
'[%s%%] %s',
|
||||
round(100 * $data_point['matching_values'] / $feed['Feed']['cached_elements']),
|
||||
h($data_point['name'])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo sprintf(
|
||||
'<h4>%s</h4><div class="row-fluid"><div class="span5">%s</div><div class="span1" style="text-align:center;margin-top:50px;">%s</div><div class="span5">%s</div></div>',
|
||||
h($scope),
|
||||
sprintf(
|
||||
'<b class="bold">%s</b><select id="%s" class="picker-%s" style="width:100%%;" size="5" multiple="multiple" data-pickername="%s">%s</select>',
|
||||
__('Include'),
|
||||
h($scope) . 'Left',
|
||||
'left',
|
||||
h($scope),
|
||||
implode('', $temp['left'])
|
||||
),
|
||||
sprintf(
|
||||
'<button class="btn btn-inverse btn-small" onclick="generic_picker_move(%s, %s);" title="Include selected"><<</button>
|
||||
<button class="btn btn-inverse btn-small" onclick="generic_picker_move(%s, %s);" title="Include selected">>></button>',
|
||||
'\'' . h($scope) . '\'',
|
||||
"'left'",
|
||||
'\'' . h($scope) . '\'',
|
||||
"'right'"
|
||||
),
|
||||
|
||||
sprintf(
|
||||
'<b class="bold">%s</b><select id="%s" class="picker-%s" style="width:100%%;" size="5" multiple="multiple" data-pickername="%s">%s</select>',
|
||||
__('Exclude'),
|
||||
h($scope) . 'Right',
|
||||
'right',
|
||||
h($scope),
|
||||
implode('', $temp['right'])
|
||||
)
|
||||
);
|
||||
}
|
||||
echo sprintf(
|
||||
'<button class="btn btn-primary" onClick="submit_feed_overlap_tool(%s);">%s</button>',
|
||||
h($feed['Feed']['id']),
|
||||
__('Check coverage')
|
||||
);
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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' => '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 $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'])
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
?>
|
||||
|
|
|
@ -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),
|
||||
|
@ -884,11 +897,17 @@
|
|||
'download' => 'feed_index.json'
|
||||
));
|
||||
if ($isSiteAdmin) {
|
||||
if ($menuItem === 'edit') {
|
||||
if ($menuItem === 'edit' || $menuItem === 'view') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'edit',
|
||||
'url' => '/feeds/edit/' . h($feed['Feed']['id']),
|
||||
'text' => __('Edit Feed')
|
||||
));
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'view',
|
||||
'url' => '/feeds/view/' . h($feed['Feed']['id']),
|
||||
'text' => __('View Feed')
|
||||
));
|
||||
} else if ($menuItem === 'previewIndex') {
|
||||
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
|
||||
'element_id' => 'previewIndex',
|
||||
|
|
|
@ -105,7 +105,6 @@ function redrawChosenWithTemplate($select, $chosenContainer, eventType) {
|
|||
if (optionLength > 1000) {
|
||||
$chosenContainer.parent().find('.generic-picker-wrapper-warning-text').show(0)
|
||||
} else {
|
||||
console.log(eventType);
|
||||
$chosenContainer.find('.generic-picker-wrapper-warning-text').hide(0)
|
||||
var $matches;
|
||||
if (eventType == 'chosen:picked' || eventType == 'change') {
|
||||
|
@ -284,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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
'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'
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -33,17 +33,19 @@
|
|||
?>
|
||||
</div>
|
||||
<?php
|
||||
if (isset($this->request->data['Event']['threat_level_id'])) {
|
||||
$selected = $this->request->data['Event']['threat_level_id'];
|
||||
} else {
|
||||
$selected = Configure::read('MISP.default_event_threat_level') ? Configure::read('MISP.default_event_threat_level') : '4';
|
||||
}
|
||||
echo '<div class="input clear"></div>';
|
||||
if (empty(Configure::read('MISP.disable_threat_level'))) {
|
||||
if (isset($this->request->data['Event']['threat_level_id'])) {
|
||||
$selected = $this->request->data['Event']['threat_level_id'];
|
||||
} else {
|
||||
$selected = Configure::read('MISP.default_event_threat_level') ? Configure::read('MISP.default_event_threat_level') : '4';
|
||||
}
|
||||
|
||||
echo $this->Form->input('threat_level_id', array(
|
||||
'div' => 'input clear',
|
||||
'label' => __('Threat Level ') . $this->element('formInfo', array('type' => 'threat_level')),
|
||||
'selected' => $selected,
|
||||
));
|
||||
echo $this->Form->input('threat_level_id', array(
|
||||
'label' => __('Threat Level ') . $this->element('formInfo', array('type' => 'threat_level')),
|
||||
'selected' => $selected,
|
||||
));
|
||||
}
|
||||
echo $this->Form->input('analysis', array(
|
||||
'label' => __('Analysis ') . $this->element('formInfo', array('type' => 'analysis')),
|
||||
'options' => array($analysisLevels),
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
echo $this->Form->create($scope, array('url' => array('controller' => Inflector::tableize($scope), 'action' => 'addTag', $object_id)));
|
||||
if ($scope === 'Attribute') {
|
||||
echo $this->Form->input('attribute_ids', array());
|
||||
}
|
||||
echo $this->Form->input('tag', array('value' => 0));
|
||||
echo $this->Form->end();
|
||||
?>
|
|
@ -30,10 +30,12 @@ $mayPublish = ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']);
|
|||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->input('threat_level_id', array(
|
||||
'div' => 'input clear',
|
||||
echo '<div class="input clear"></div>';
|
||||
if (empty(Configure::read('MISP.disable_threat_level'))) {
|
||||
echo $this->Form->input('threat_level_id', array(
|
||||
'label' => __('Threat Level ') . $this->element('formInfo', array('type' => 'threat_level'))
|
||||
));
|
||||
));
|
||||
}
|
||||
echo $this->Form->input('analysis', array(
|
||||
'label' => __('Analysis ') . $this->element('formInfo', array('type' => 'analysis')),
|
||||
'options' => array($analysisLevels)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue