mirror of https://github.com/MISP/MISP
Merge remote-tracking branch 'upstream/2.4' into bug/galaxy_cluster
commit
8077eeaa3c
|
@ -20,7 +20,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ubuntu-20.04]
|
||||
php: ['7.2', '7.3', '7.4']
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
|
@ -66,9 +66,14 @@ jobs:
|
|||
run: |
|
||||
git submodule update --init --recursive
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install curl python3 python3-venv virtualenv python3-pip python3-nose python3-redis python3-lxml apache2 libapache2-mod-php$php_version php$php_version-xml php$php_version-mbstring php$php_version-mysql libfuzzy-dev libemail-address-perl libemail-outlook-message-perl
|
||||
sudo pip3 install --upgrade pip setuptools requests pyzmq poetry
|
||||
if [[ $php_version == "7.4" ]]; then
|
||||
# Repo is missing for unknown reason
|
||||
LC_ALL=C.UTF-8 sudo apt-add-repository ppa:ondrej/php -y
|
||||
fi
|
||||
sudo apt-get -y install curl python3 python3-zmq python3-requests python3-pip python3-nose python3-redis python3-lxml apache2 libapache2-mod-php$php_version libfuzzy-dev
|
||||
sudo pip3 install virtualenv # virtualenv must be instaled from pip and not from ubuntu pacckages
|
||||
sudo pip3 install --upgrade -r requirements.txt
|
||||
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
|
||||
sudo chown $USER:www-data $HOME/.composer
|
||||
pushd app
|
||||
sudo -H -u $USER php composer.phar install --no-progress
|
||||
|
@ -185,7 +190,7 @@ jobs:
|
|||
sudo chmod -R 777 ./tests
|
||||
# Start workers
|
||||
# Dirty install python stuff
|
||||
virtualenv -p python3 ./venv
|
||||
python3 -m virtualenv -p python3 ./venv
|
||||
sudo -E su $USER -c 'app/Console/cake Admin setSetting "MISP.python_bin" "$GITHUB_WORKSPACE/venv/bin/python"'
|
||||
. ./venv/bin/activate
|
||||
pushd cti-python-stix2
|
||||
|
@ -209,9 +214,11 @@ jobs:
|
|||
|
||||
- name: Run tests
|
||||
run: |
|
||||
source $HOME/.poetry/env # enable poetry binary
|
||||
./app/Vendor/bin/parallel-lint --exclude app/Lib/cakephp/ --exclude app/Vendor/ --exclude app/Lib/random_compat/ -e php,ctp app/
|
||||
./app/Vendor/bin/phpunit app/Test/ComplexTypeToolTest.php
|
||||
./app/Vendor/bin/phpunit app/Test/JSONConverterToolTest.php
|
||||
./app/Vendor/bin/phpunit app/Test/CidrToolTest.php
|
||||
|
||||
# Ensure the perms of config files
|
||||
sudo chown -R $USER:www-data `pwd`/app/Config
|
||||
|
|
|
@ -675,6 +675,7 @@ kaliSpaceSaver () {
|
|||
echo "${RED}Not implement${NC}"
|
||||
}
|
||||
|
||||
# FIXME: Kali now uses kali/kali instead of root/toor
|
||||
# Because Kali is l33t we make sure we DO NOT run as root
|
||||
kaliOnTheR0ckz () {
|
||||
totalRoot=$(df -k | grep /$ |awk '{ print $2 }')
|
||||
|
@ -776,6 +777,7 @@ installRNG () {
|
|||
kaliUpgrade () {
|
||||
debug "Running various Kali upgrade tasks"
|
||||
checkAptLock
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install --only-upgrade bash libc6 -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt autoremove -y
|
||||
}
|
||||
|
@ -1197,7 +1199,7 @@ installDepsPhp74 () {
|
|||
libapache2-mod-php \
|
||||
php php-cli \
|
||||
php-dev \
|
||||
php-json php-xml php-mysql php-opcache php-readline php-mbstring php-zip \
|
||||
php-json php-xml php-mysql php7.4-opcache php-readline php-mbstring php-zip \
|
||||
php-redis php-gnupg \
|
||||
php-intl php-bcmath \
|
||||
php-gd
|
||||
|
@ -1559,6 +1561,7 @@ coreCAKE () {
|
|||
# Various plugin sightings settings
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_policy" 0
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise" false
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_anonymise_as" 1
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_range" 365
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Plugin.Sightings_sighting_db_enable" false
|
||||
|
||||
|
@ -1766,6 +1769,7 @@ mispmodules () {
|
|||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install -I -r REQUIREMENTS
|
||||
sudo chgrp staff .
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install -I .
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install censys pyfaup
|
||||
|
||||
# Start misp-modules as a service
|
||||
sudo cp /usr/local/src/misp-modules/etc/systemd/system/misp-modules.service /etc/systemd/system/
|
||||
|
@ -2539,6 +2543,7 @@ mispmodulesRHEL () {
|
|||
# pip install
|
||||
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U -I -r REQUIREMENTS
|
||||
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install -U .
|
||||
$SUDO_WWW $PATH_TO_MISP/venv/bin/pip install pyfaup censys
|
||||
sudo yum install rubygem-rouge rubygem-asciidoctor zbar-devel opencv-devel -y
|
||||
|
||||
echo "[Unit]
|
||||
|
@ -2780,10 +2785,10 @@ installSupported () {
|
|||
# Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72
|
||||
elif [[ "$PHP_VER" == 7.3 ]]; then
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73
|
||||
elif [[ "$PHP_VER" == 7.4 ]]; then
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp74
|
||||
elif [[ "$PHP_VER" == 7.0 ]]; then
|
||||
# Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
|
@ -2885,7 +2890,7 @@ installSupported () {
|
|||
|
||||
# Main Kali Install function
|
||||
installMISPonKali () {
|
||||
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('')
|
||||
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('generic/supportFunctions.md')
|
||||
kaliUpgrade
|
||||
|
||||
# Set locale if not set - functionLocation('generic/supportFunctions.md')
|
||||
|
@ -2894,8 +2899,8 @@ installMISPonKali () {
|
|||
# Set Base URL - functionLocation('generic/supportFunctions.md')
|
||||
setBaseURL
|
||||
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
installDepsPhp73
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
installDepsPhp74
|
||||
|
||||
# Set custom Kali only variables and tweaks
|
||||
space
|
||||
|
@ -2913,12 +2918,12 @@ installMISPonKali () {
|
|||
installCoreDeps
|
||||
|
||||
debug "Enabling redis and gnupg modules"
|
||||
sudo phpenmod -v 7.3 redis
|
||||
sudo phpenmod -v 7.3 gnupg
|
||||
sudo phpenmod -v 7.4 redis
|
||||
sudo phpenmod -v 7.4 gnupg
|
||||
|
||||
debug "Apache2 ops: dismod: status - dissite: 000-default enmod: ssl rewrite headers php7.3 ensite: default-ssl"
|
||||
sudo a2dismod status
|
||||
sudo a2enmod ssl rewrite headers php7.3
|
||||
sudo a2enmod ssl rewrite headers php7.4
|
||||
sudo a2dissite 000-default
|
||||
sudo a2ensite default-ssl
|
||||
|
||||
|
@ -3021,26 +3026,18 @@ installMISPonKali () {
|
|||
|
||||
debug "Setting up database"
|
||||
if [[ ! -e /var/lib/mysql/misp/users.ibd ]]; then
|
||||
echo "
|
||||
set timeout 10
|
||||
spawn sudo mysql_secure_installation
|
||||
expect \"Enter current password for root (enter for none):\"
|
||||
send -- \"\r\"
|
||||
expect \"Set root password?\"
|
||||
send -- \"y\r\"
|
||||
expect \"New password:\"
|
||||
send -- \"${DBPASSWORD_ADMIN}\r\"
|
||||
expect \"Re-enter new password:\"
|
||||
send -- \"${DBPASSWORD_ADMIN}\r\"
|
||||
expect \"Remove anonymous users?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Disallow root login remotely?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Remove test database and access to it?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Reload privilege tables now?\"
|
||||
send -- \"y\r\"
|
||||
expect eof" | expect -f -
|
||||
# Kill the anonymous users
|
||||
sudo mysql -h $DBHOST -e "DROP USER IF EXISTS ''@'localhost'"
|
||||
# Because our hostname varies we'll use some Bash magic here.
|
||||
sudo mysql -h $DBHOST -e "DROP USER IF EXISTS ''@'$(hostname)'"
|
||||
# Kill off the demo database
|
||||
sudo mysql -h $DBHOST -e "DROP DATABASE IF EXISTS test"
|
||||
# No root remote logins
|
||||
sudo mysql -h $DBHOST -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')"
|
||||
# Make sure that NOBODY can access the server without a password
|
||||
sudo mysqladmin -h $DBHOST -u "${DBUSER_ADMIN}" password "${DBPASSWORD_ADMIN}"
|
||||
# Make our changes take effect
|
||||
sudo mysql -h $DBHOST -e "FLUSH PRIVILEGES"
|
||||
|
||||
sudo mysql -u $DBUSER_ADMIN -p$DBPASSWORD_ADMIN -e "CREATE DATABASE $DBNAME;"
|
||||
sudo mysql -u $DBUSER_ADMIN -p$DBPASSWORD_ADMIN -e "GRANT USAGE ON *.* TO $DBUSER_MISP@localhost IDENTIFIED BY '$DBPASSWORD_MISP';"
|
||||
|
@ -3291,9 +3288,7 @@ x86_64-debian-stretch
|
|||
x86_64-debian-buster
|
||||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-kali-2020.1
|
||||
x86_64-kali-2020.2
|
||||
x86_64-kali-2020.3
|
||||
x86_64-ubuntu-hirsute
|
||||
x86_64-kali-2020.4
|
||||
armv6l-raspbian-stretch
|
||||
armv7l-raspbian-stretch
|
||||
|
@ -3328,6 +3323,11 @@ if [[ "${FLAVOUR}" == "ubuntu" ]]; then
|
|||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "21.04" ]]; then
|
||||
echo "Install on Ubuntu 21.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "18.10" ]]; then
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; Generated by RHash v1.3.9 on 2021-01-15 at 16:07.48
|
||||
; Generated by RHash v1.3.9 on 2021-02-15 at 12:01.57
|
||||
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
|
||||
;
|
||||
; 137197 16:07.48 2021-01-15 INSTALL.sh
|
||||
INSTALL.sh AC931C9555B90E9C3B0935492DAA0E7EDC4B4394 E77AC1F6FA1B60AFAE910B86B59ACC5C33E2019D738B3E3380732FA51354D1AD C40E1D6E33EB14394C93E5C3FDFDC8DA66C2216AC0D22D1453578BD47AD052C84CB48EFDEA4F0769697A92A59FEA7E0F 8F5E59632C0B02F9CDAEE5B3B301697EA7ABFF8D1359673499689A4389A25D059625EBC2B650C114AD114A336ECA609A588FF6C6633FFDCE599F69A7717BD0F8
|
||||
; 137749 12:01.57 2021-02-15 INSTALL.sh
|
||||
INSTALL.sh 5C4651E28DAD85AFCB59E6914D8ACAB6E447BEB7 506B3B399D5B8EC140538054D9E78ABFA11A8AD45CE5E42AC77A72FB71762FDE 400AFBF6ACA765F314F4D044ABC28D3D94E38D6223F642E1BED3F8C7884CAA64BAA10647352E5BF94411DA8A6753D549 3AC6B5A002645E7F29547F1134BE3C744BFD3D1B253473702B9132E7CEC271474333407F7AA375996EAF9A9877E8E73A7D3C655DDC6E9C7A83F5DF37FA418FB6
|
||||
|
|
|
@ -1 +1 @@
|
|||
ac931c9555b90e9c3b0935492daa0e7edc4b4394 INSTALL.sh
|
||||
5c4651e28dad85afcb59e6914d8acab6e447beb7 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
e77ac1f6fa1b60afae910b86b59acc5c33e2019d738b3e3380732fa51354d1ad INSTALL.sh
|
||||
506b3b399d5b8ec140538054d9e78abfa11a8ad45ce5e42ac77a72fb71762fde INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
c40e1d6e33eb14394c93e5c3fdfdc8da66c2216ac0d22d1453578bd47ad052c84cb48efdea4f0769697a92a59fea7e0f INSTALL.sh
|
||||
400afbf6aca765f314f4d044abc28d3d94e38d6223f642e1bed3f8c7884caa64baa10647352e5bf94411da8a6753d549 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
8f5e59632c0b02f9cdaee5b3b301697ea7abff8d1359673499689a4389a25d059625ebc2b650c114ad114a336eca609a588ff6c6633ffdce599f69a7717bd0f8 INSTALL.sh
|
||||
3ac6b5a002645e7f29547f1134be3c744bfd3d1b253473702b9132e7cec271474333407f7aa375996eaf9a9877e8e73a7d3c655ddc6e9c7a83f5df37fa418fb6 INSTALL.sh
|
||||
|
|
|
@ -284,10 +284,10 @@ installSupported () {
|
|||
# Install PHP 7.2 Dependencies - functionLocation('INSTALL.ubuntu1804.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp72
|
||||
elif [[ "$PHP_VER" == 7.3 ]]; then
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp73
|
||||
elif [[ "$PHP_VER" == 7.4 ]]; then
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
[[ -n $CORE ]] || [[ -n $ALL ]] && installDepsPhp74
|
||||
elif [[ "$PHP_VER" == 7.0 ]]; then
|
||||
# Install PHP 7.0 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
|
@ -389,7 +389,7 @@ installSupported () {
|
|||
|
||||
# Main Kali Install function
|
||||
installMISPonKali () {
|
||||
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('')
|
||||
# Kali might have a bug on installs where libc6 is not up to date, this forces bash and libc to update - functionLocation('generic/supportFunctions.md')
|
||||
kaliUpgrade
|
||||
|
||||
# Set locale if not set - functionLocation('generic/supportFunctions.md')
|
||||
|
@ -398,8 +398,8 @@ installMISPonKali () {
|
|||
# Set Base URL - functionLocation('generic/supportFunctions.md')
|
||||
setBaseURL
|
||||
|
||||
# Install PHP 7.3 Dependencies - functionLocation('generic/supportFunctions.md')
|
||||
installDepsPhp73
|
||||
# Install PHP 7.4 Dependencies - functionLocation('INSTALL.ubuntu2004.md')
|
||||
installDepsPhp74
|
||||
|
||||
# Set custom Kali only variables and tweaks
|
||||
space
|
||||
|
@ -417,12 +417,12 @@ installMISPonKali () {
|
|||
installCoreDeps
|
||||
|
||||
debug "Enabling redis and gnupg modules"
|
||||
sudo phpenmod -v 7.3 redis
|
||||
sudo phpenmod -v 7.3 gnupg
|
||||
sudo phpenmod -v 7.4 redis
|
||||
sudo phpenmod -v 7.4 gnupg
|
||||
|
||||
debug "Apache2 ops: dismod: status - dissite: 000-default enmod: ssl rewrite headers php7.3 ensite: default-ssl"
|
||||
sudo a2dismod status
|
||||
sudo a2enmod ssl rewrite headers php7.3
|
||||
sudo a2enmod ssl rewrite headers php7.4
|
||||
sudo a2dissite 000-default
|
||||
sudo a2ensite default-ssl
|
||||
|
||||
|
@ -525,26 +525,18 @@ installMISPonKali () {
|
|||
|
||||
debug "Setting up database"
|
||||
if [[ ! -e /var/lib/mysql/misp/users.ibd ]]; then
|
||||
echo "
|
||||
set timeout 10
|
||||
spawn sudo mysql_secure_installation
|
||||
expect \"Enter current password for root (enter for none):\"
|
||||
send -- \"\r\"
|
||||
expect \"Set root password?\"
|
||||
send -- \"y\r\"
|
||||
expect \"New password:\"
|
||||
send -- \"${DBPASSWORD_ADMIN}\r\"
|
||||
expect \"Re-enter new password:\"
|
||||
send -- \"${DBPASSWORD_ADMIN}\r\"
|
||||
expect \"Remove anonymous users?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Disallow root login remotely?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Remove test database and access to it?\"
|
||||
send -- \"y\r\"
|
||||
expect \"Reload privilege tables now?\"
|
||||
send -- \"y\r\"
|
||||
expect eof" | expect -f -
|
||||
# Kill the anonymous users
|
||||
sudo mysql -h $DBHOST -e "DROP USER IF EXISTS ''@'localhost'"
|
||||
# Because our hostname varies we'll use some Bash magic here.
|
||||
sudo mysql -h $DBHOST -e "DROP USER IF EXISTS ''@'$(hostname)'"
|
||||
# Kill off the demo database
|
||||
sudo mysql -h $DBHOST -e "DROP DATABASE IF EXISTS test"
|
||||
# No root remote logins
|
||||
sudo mysql -h $DBHOST -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')"
|
||||
# Make sure that NOBODY can access the server without a password
|
||||
sudo mysqladmin -h $DBHOST -u "${DBUSER_ADMIN}" password "${DBPASSWORD_ADMIN}"
|
||||
# Make our changes take effect
|
||||
sudo mysql -h $DBHOST -e "FLUSH PRIVILEGES"
|
||||
|
||||
sudo mysql -u $DBUSER_ADMIN -p$DBPASSWORD_ADMIN -e "CREATE DATABASE $DBNAME;"
|
||||
sudo mysql -u $DBUSER_ADMIN -p$DBPASSWORD_ADMIN -e "GRANT USAGE ON *.* TO $DBUSER_MISP@localhost IDENTIFIED BY '$DBPASSWORD_MISP';"
|
||||
|
@ -795,9 +787,7 @@ x86_64-debian-stretch
|
|||
x86_64-debian-buster
|
||||
x86_64-ubuntu-bionic
|
||||
x86_64-ubuntu-focal
|
||||
x86_64-kali-2020.1
|
||||
x86_64-kali-2020.2
|
||||
x86_64-kali-2020.3
|
||||
x86_64-ubuntu-hirsute
|
||||
x86_64-kali-2020.4
|
||||
armv6l-raspbian-stretch
|
||||
armv7l-raspbian-stretch
|
||||
|
@ -832,6 +822,11 @@ if [[ "${FLAVOUR}" == "ubuntu" ]]; then
|
|||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "21.04" ]]; then
|
||||
echo "Install on Ubuntu 21.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
installSupported PHP="7.4" && exit || exit
|
||||
fi
|
||||
if [[ "${RELEASE}" == "18.10" ]]; then
|
||||
echo "Install on Ubuntu 18.10 partially supported, bye."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
2
PyMISP
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit 5b97b7d0158906cd0f646a7273a3ca5b1828cd15
|
||||
Subproject commit 9316420dc028a1ffc541986fc08793e669f2165e
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":137}
|
||||
{"major":2, "minor":4, "hotfix":139}
|
||||
|
|
|
@ -214,19 +214,24 @@ class AdminShell extends AppShell
|
|||
if (empty($user)) {
|
||||
echo 'User with ID: ' . $userId . ' not found' . PHP_EOL;
|
||||
$result = $this->ObjectTemplate->update();
|
||||
if ($result) {
|
||||
echo 'Object templates updated' . PHP_EOL;
|
||||
} else {
|
||||
echo 'Could not update object templates' . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
$result = $this->ObjectTemplate->update($user, false,false);
|
||||
if ($result) {
|
||||
echo 'Object templates updated' . PHP_EOL;
|
||||
} else {
|
||||
echo 'Could not update object templates' . PHP_EOL;
|
||||
}
|
||||
|
||||
$successes = count(!empty($result['success']) ? $result['success'] : []);
|
||||
$fails = count(!empty($result['fails']) ? $result['fails'] : []);
|
||||
$message = '';
|
||||
if ($successes == 0 && $fails == 0) {
|
||||
$message = __('All object templates are up to date already.');
|
||||
} elseif ($successes == 0 && $fails > 0) {
|
||||
$message = __('Could not update any of the object templates.');
|
||||
} elseif ($successes > 0 ) {
|
||||
$message = __('Successfully updated %s object templates.', $successes);
|
||||
if ($fails != 0) {
|
||||
$message .= __(' However, could not update %s object templates.', $fails);
|
||||
}
|
||||
}
|
||||
echo $message . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,7 @@ class EventShell extends AppShell
|
|||
public function import()
|
||||
{
|
||||
list($userId, $path) = $this->args;
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
if (empty($user)) {
|
||||
$this->error("User with ID $userId does not exists.");
|
||||
}
|
||||
$user = $this->getUser($userId);
|
||||
|
||||
if (!file_exists($path)) {
|
||||
$this->error("File '$path' does not exists.");
|
||||
|
@ -113,7 +110,7 @@ class EventShell extends AppShell
|
|||
$timeStart = time();
|
||||
$userId = $this->args[0];
|
||||
$id = $this->args[1];
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
$user = $this->getUser($userId);
|
||||
$this->Job->id = $id;
|
||||
$export_type = $this->args[2];
|
||||
file_put_contents('/tmp/test', $export_type);
|
||||
|
@ -204,10 +201,7 @@ class EventShell extends AppShell
|
|||
$jobId = $this->args[1];
|
||||
$eventId = $this->args[2];
|
||||
$oldpublish = $this->args[3];
|
||||
$user = $this->User->getUserById($userId);
|
||||
if (empty($user)) {
|
||||
die("Invalid user ID '$userId' provided.");
|
||||
}
|
||||
$user = $this->getUser($userId);
|
||||
$this->Event->sendAlertEmail($eventId, $user, $oldpublish, $jobId);
|
||||
}
|
||||
|
||||
|
@ -220,10 +214,7 @@ class EventShell extends AppShell
|
|||
$userId = $this->args[3];
|
||||
$processId = $this->args[4];
|
||||
|
||||
$user = $this->User->getUserById($userId);
|
||||
if (empty($user)) {
|
||||
die("Invalid user ID '$userId' provided.");
|
||||
}
|
||||
$user = $this->getUser($userId);
|
||||
$result = $this->Event->sendContactEmail($id, $message, $all, $user);
|
||||
$this->Job->saveStatus($processId, $result);
|
||||
}
|
||||
|
@ -305,10 +296,7 @@ class EventShell extends AppShell
|
|||
$passAlong = $this->args[1];
|
||||
$jobId = $this->args[2];
|
||||
$userId = $this->args[3];
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
if (empty($user)) {
|
||||
die("Invalid user ID '$userId' provided.");
|
||||
}
|
||||
$user = $this->getUser($userId);
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$this->Event->Behaviors->unload('SysLogLogable.SysLogLogable');
|
||||
$result = $this->Event->publish($id, $passAlong);
|
||||
|
@ -332,10 +320,7 @@ class EventShell extends AppShell
|
|||
$passAlong = $this->args[1];
|
||||
$jobId = $this->args[2];
|
||||
$userId = $this->args[3];
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
if (empty($user)) {
|
||||
die("Invalid user ID '$userId' provided.");
|
||||
}
|
||||
$user = $this->getUser($userId);
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$this->Event->Behaviors->unload('SysLogLogable.SysLogLogable');
|
||||
$result = $this->Event->publish_sightings($id, $passAlong);
|
||||
|
@ -359,7 +344,7 @@ class EventShell extends AppShell
|
|||
$jobId = $this->args[1];
|
||||
$userId = $this->args[2];
|
||||
$passAlong = $this->args[3];
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
$user = $this->getUser($userId);
|
||||
$job = $this->Job->read(null, $jobId);
|
||||
$this->GalaxyCluster = ClassRegistry::init('GalaxyCluster');
|
||||
$result = $this->GalaxyCluster->publish($clusterId, $passAlong=$passAlong);
|
||||
|
@ -383,8 +368,7 @@ class EventShell extends AppShell
|
|||
die('Usage: ' . $this->Server->command_line_functions['enrichment'] . PHP_EOL);
|
||||
}
|
||||
$userId = $this->args[0];
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
if (empty($user)) die('Invalid user.');
|
||||
$user = $this->getUser($userId);
|
||||
$eventId = $this->args[1];
|
||||
$modulesRaw = $this->args[2];
|
||||
try {
|
||||
|
@ -484,4 +468,17 @@ class EventShell extends AppShell
|
|||
$job['Job']['message'] = __('Recovery complete. Event #%s recovered, using %s log entries.', $id, $result);
|
||||
$this->Job->save($job);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return array
|
||||
*/
|
||||
private function getUser($userId)
|
||||
{
|
||||
$user = $this->User->getAuthUser($userId);
|
||||
if (empty($user)) {
|
||||
$this->error("User with ID $userId does not exists.");
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ class AppController extends Controller
|
|||
|
||||
public $helpers = array('OrgImg', 'FontAwesome', 'UserName', 'DataPathCollector');
|
||||
|
||||
private $__queryVersion = '122';
|
||||
public $pyMispVersion = '2.4.137';
|
||||
private $__queryVersion = '125';
|
||||
public $pyMispVersion = '2.4.138';
|
||||
public $phpmin = '7.2';
|
||||
public $phprec = '7.4';
|
||||
public $phptoonew = '8.0';
|
||||
|
|
|
@ -998,6 +998,7 @@ class AttributesController extends AppController
|
|||
'includeAllTags' => false,
|
||||
'includeAttributeUuid' => true,
|
||||
'flatten' => true,
|
||||
'deleted' => [0, 1]
|
||||
);
|
||||
|
||||
if ($this->_isRest()) {
|
||||
|
@ -1505,7 +1506,6 @@ class AttributesController extends AppController
|
|||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'paramArray' => $paramArray,
|
||||
'ordered_url_params' => @compact($paramArray),
|
||||
'additional_delimiters' => PHP_EOL
|
||||
);
|
||||
$exception = false;
|
||||
|
|
|
@ -346,7 +346,9 @@ class ACLComponent extends Component
|
|||
'view' => array('*'),
|
||||
),
|
||||
'galaxyElements' => array(
|
||||
'index' => array('*')
|
||||
'delete' => array('perm_galaxy_editor'),
|
||||
'flattenJson' => array('perm_galaxy_editor'),
|
||||
'index' => array('*'),
|
||||
),
|
||||
'jobs' => array(
|
||||
'cache' => array('*'),
|
||||
|
@ -412,6 +414,7 @@ class ACLComponent extends Component
|
|||
'edit' => array('perm_object_template'),
|
||||
'delete' => array('perm_object_template'),
|
||||
'getToggleField' => array(),
|
||||
'getRaw' => array('perm_object_template'),
|
||||
'objectChoice' => array('*'),
|
||||
'objectMetaChoice' => array('perm_add'),
|
||||
'view' => array('*'),
|
||||
|
@ -542,6 +545,7 @@ class ACLComponent extends Component
|
|||
'generateCorrelation' => array(),
|
||||
'index' => array('*'),
|
||||
'view' => array('*'),
|
||||
'viewPicture' => array('*'),
|
||||
),
|
||||
'sharingGroups' => array(
|
||||
'add' => array('perm_sharing_group'),
|
||||
|
|
|
@ -532,7 +532,9 @@ class RestResponseComponent extends Component
|
|||
$response['sql_dump'] = $this->Log->getDataSource()->getLog(false, false);
|
||||
}
|
||||
}
|
||||
$response = json_encode($response, JSON_PRETTY_PRINT);
|
||||
// Do not pretty print response for automatic tools
|
||||
$flags = $this->isAutomaticTool() ? JSON_UNESCAPED_UNICODE : JSON_PRETTY_PRINT;
|
||||
$response = json_encode($response, $flags);
|
||||
} else {
|
||||
if ($dumpSql) {
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
|
@ -582,6 +584,16 @@ class RestResponseComponent extends Component
|
|||
return $cakeResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if request comes from automatic tool, like other MISP instance or PyMISP
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutomaticTool()
|
||||
{
|
||||
$userAgent = CakeRequest::header('User-Agent');
|
||||
return $userAgent && (substr($userAgent, 0, 6) === 'PyMISP' || substr($userAgent, 0, 4) === 'MISP');
|
||||
}
|
||||
|
||||
private function __generateURL($action, $controller, $id)
|
||||
{
|
||||
$controller = Inflector::underscore(Inflector::pluralize($controller));
|
||||
|
@ -1806,8 +1818,6 @@ class RestResponseComponent extends Component
|
|||
private function __overwriteReturnFormat($scope, $action, &$field) {
|
||||
switch($scope) {
|
||||
case "Attribute":
|
||||
$field['values'] = array_keys(ClassRegistry::init($scope)->validFormats);
|
||||
break;
|
||||
case "Event":
|
||||
$field['values'] = array_keys(ClassRegistry::init($scope)->validFormats);
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
|
||||
/**
|
||||
* @property Dashboard $Dashboard
|
||||
*/
|
||||
class DashboardsController extends AppController
|
||||
{
|
||||
public $components = array('Session', 'RequestHandler');
|
||||
|
@ -147,47 +150,50 @@ class DashboardsController extends AppController
|
|||
|
||||
public function renderWidget($widget_id, $force = false)
|
||||
{
|
||||
if ($this->request->is('post')) {
|
||||
if (empty($this->request->data['data'])) {
|
||||
$this->request->data = array('data' => $this->request->data);
|
||||
|
||||
}
|
||||
if (empty($this->request->data['data'])) {
|
||||
throw new MethodNotAllowedException(__('You need to specify the widget to use along with the configuration.'));
|
||||
}
|
||||
$value = $this->request->data['data'];
|
||||
$dashboardWidget = $this->Dashboard->loadWidget($this->Auth->user(), $value['widget']);
|
||||
$this->layout = false;
|
||||
$this->set('title', $dashboardWidget->title);
|
||||
$redis = $this->Dashboard->setupRedis();
|
||||
$org_scope = $this->_isSiteAdmin() ? 0 : $this->Auth->user('org_id');
|
||||
$lookup_hash = hash('sha256', $value['widget'] . $value['config']);
|
||||
$data = $redis->get('misp:dashboard:' . $org_scope . ':' . $lookup_hash);
|
||||
if (!isset($dashboardWidget->cacheLifetime)) {
|
||||
$dashboardWidget->cacheLifetime = false;
|
||||
}
|
||||
if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
|
||||
$data = $dashboardWidget->handler($this->Auth->user(), json_decode($value['config'], true));
|
||||
if (!empty($dashboardWidget->cacheLifetime)) {
|
||||
$redis->set('misp:dashboard:' . $org_scope . ':' . $lookup_hash, json_encode(array('data' => $data)));
|
||||
$redis->expire('misp:dashboard:' . $org_scope . ':' . $lookup_hash, $dashboardWidget->cacheLifetime);
|
||||
}
|
||||
} else {
|
||||
$data = json_decode($data, true)['data'];
|
||||
}
|
||||
$valueConfig = json_decode($value['config'], true);
|
||||
$config = array(
|
||||
'render' => $dashboardWidget->render,
|
||||
'autoRefreshDelay' => empty($dashboardWidget->autoRefreshDelay) ? false : $dashboardWidget->autoRefreshDelay,
|
||||
'widget_config' => empty($valueConfig['widget_config']) ? array() : $valueConfig['widget_config']
|
||||
);
|
||||
$this->set('widget_id', $widget_id);
|
||||
$this->set('data', $data);
|
||||
$this->set('config', $config);
|
||||
$this->render('widget_loader');
|
||||
} else {
|
||||
if (!$this->request->is('post')) {
|
||||
throw new MethodNotAllowedException(__('This endpoint can only be reached via POST requests.'));
|
||||
}
|
||||
|
||||
@session_write_close(); // allow concurrent AJAX requests (session hold lock by default)
|
||||
|
||||
if (empty($this->request->data['data'])) {
|
||||
$this->request->data = array('data' => $this->request->data);
|
||||
}
|
||||
if (empty($this->request->data['data'])) {
|
||||
throw new MethodNotAllowedException(__('You need to specify the widget to use along with the configuration.'));
|
||||
}
|
||||
$value = $this->request->data['data'];
|
||||
$valueConfig = json_decode($value['config'], true);
|
||||
$dashboardWidget = $this->Dashboard->loadWidget($this->Auth->user(), $value['widget']);
|
||||
|
||||
$redis = $this->Dashboard->setupRedis();
|
||||
$org_scope = $this->_isSiteAdmin() ? 0 : $this->Auth->user('org_id');
|
||||
$lookup_hash = hash('sha256', $value['widget'] . $value['config']);
|
||||
$cacheKey = 'misp:dashboard:' . $org_scope . ':' . $lookup_hash;
|
||||
$data = $redis->get($cacheKey);
|
||||
if (!isset($dashboardWidget->cacheLifetime)) {
|
||||
$dashboardWidget->cacheLifetime = false;
|
||||
}
|
||||
if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
|
||||
$data = $dashboardWidget->handler($this->Auth->user(), $valueConfig);
|
||||
if (!empty($dashboardWidget->cacheLifetime)) {
|
||||
$redis->setex($cacheKey, $dashboardWidget->cacheLifetime, json_encode(array('data' => $data)));
|
||||
}
|
||||
} else {
|
||||
$data = json_decode($data, true)['data'];
|
||||
}
|
||||
$config = array(
|
||||
'render' => $dashboardWidget->render,
|
||||
'autoRefreshDelay' => empty($dashboardWidget->autoRefreshDelay) ? false : $dashboardWidget->autoRefreshDelay,
|
||||
'widget_config' => empty($valueConfig['widget_config']) ? array() : $valueConfig['widget_config']
|
||||
);
|
||||
|
||||
$this->layout = false;
|
||||
$this->set('title', $dashboardWidget->title);
|
||||
$this->set('widget_id', $widget_id);
|
||||
$this->set('data', $data);
|
||||
$this->set('config', $config);
|
||||
$this->render('widget_loader');
|
||||
}
|
||||
|
||||
public function import()
|
||||
|
@ -392,7 +398,7 @@ class DashboardsController extends AppController
|
|||
$element['User']['email'] = '';
|
||||
}
|
||||
}
|
||||
$this->set('passedArgs', $this->passedArgs);
|
||||
$this->set('passedArgs', json_encode($this->passedArgs));
|
||||
$this->set('data', $data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,12 +124,14 @@ class EventReportsController extends AppController
|
|||
{
|
||||
$report = $this->EventReport->fetchIfAuthorized($this->Auth->user(), $id, 'delete', $throwErrors=true, $full=false);
|
||||
if ($this->request->is('post')) {
|
||||
$errors = $this->EventReport->deleteReport($this->Auth->user(), $report, $hard=$hard);
|
||||
if (!empty($this->request->data['hard'])) {
|
||||
$hard = true;
|
||||
}
|
||||
$errors = $this->EventReport->deleteReport($this->Auth->user(), $report, $hard);
|
||||
$redirectTarget = $this->referer();
|
||||
if (empty($errors)) {
|
||||
$successMessage = __('Event Report %s %s deleted', $id, $hard ? __('hard') : __('soft'));
|
||||
$report = $hard ? null : $this->EventReport->simpleFetchById($this->Auth->user(), $id);
|
||||
return $this->__getSuccessResponseBasedOnContext($successMessage, $report, 'delete', $id, $redirectTarget);
|
||||
return $this->__getSuccessResponseBasedOnContext($successMessage, null, 'delete', $id, $redirectTarget);
|
||||
} else {
|
||||
$errorMessage = __('Event Report %s could not be %s deleted.%sReasons: %s', $id, $hard ? __('hard') : __('soft'), PHP_EOL, json_encode($errors));
|
||||
return $this->__getFailResponseBasedOnContext($errorMessage, array(), 'edit', $id, $redirectTarget);
|
||||
|
@ -153,8 +155,7 @@ class EventReportsController extends AppController
|
|||
$redirectTarget = $this->referer();
|
||||
if (empty($errors)) {
|
||||
$successMessage = __('Event Report %s restored', $id);
|
||||
$report = $this->EventReport->simpleFetchById($this->Auth->user(), $id);
|
||||
return $this->__getSuccessResponseBasedOnContext($successMessage, $report, 'restore', $id, $redirectTarget);
|
||||
return $this->__getSuccessResponseBasedOnContext($successMessage, null, 'restore', $id, $redirectTarget);
|
||||
} else {
|
||||
$errorMessage = __('Event Report %s could not be %s restored.%sReasons: %s', $id, PHP_EOL, json_encode($errors));
|
||||
return $this->__getFailResponseBasedOnContext($errorMessage, array(), 'restore', $id, $redirectTarget);
|
||||
|
|
|
@ -1612,17 +1612,17 @@ class EventsController extends AppController
|
|||
}
|
||||
|
||||
if ($this->_isRest()) {
|
||||
$this->set('event', $event);
|
||||
} else {
|
||||
$this->set('deleted', isset($deleted) ? ($deleted == 2 ? 0 : 1) : 0);
|
||||
$this->set('includeRelatedTags', (!empty($this->params['named']['includeRelatedTags'])) ? 1 : 0);
|
||||
$this->set('includeDecayScore', (!empty($this->params['named']['includeDecayScore'])) ? 1 : 0);
|
||||
|
||||
if ($this->_isSiteAdmin() && $event['Event']['orgc_id'] !== $this->Auth->user('org_id')) {
|
||||
$this->Flash->info(__('You are currently logged in as a site administrator and about to edit an event not belonging to your organisation. This goes against the sharing model of MISP. Use a normal user account for day to day work.'));
|
||||
}
|
||||
$this->__viewUI($event, $continue, $fromEvent);
|
||||
return $this->__restResponse($event);
|
||||
}
|
||||
|
||||
$this->set('deleted', isset($deleted) ? ($deleted == 2 ? 0 : 1) : 0);
|
||||
$this->set('includeRelatedTags', (!empty($this->params['named']['includeRelatedTags'])) ? 1 : 0);
|
||||
$this->set('includeDecayScore', (!empty($this->params['named']['includeDecayScore'])) ? 1 : 0);
|
||||
|
||||
if ($this->_isSiteAdmin() && $event['Event']['orgc_id'] !== $this->Auth->user('org_id')) {
|
||||
$this->Flash->info(__('You are currently logged in as a site administrator and about to edit an event not belonging to your organisation. This goes against the sharing model of MISP. Use a normal user account for day to day work.'));
|
||||
}
|
||||
$this->__viewUI($event, $continue, $fromEvent);
|
||||
}
|
||||
|
||||
private function __startPivoting($id, $info, $date)
|
||||
|
@ -1741,6 +1741,9 @@ class EventsController extends AppController
|
|||
|
||||
// search for all attributes in object
|
||||
foreach ($event['Object'] as $k => $object) {
|
||||
if ($this->__valueInFieldAttribute($object, ['id', 'uuid', 'name', 'comment'], $searchFor)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($object['Attribute'] as $k2 => $attribute) {
|
||||
if (!$this->__valueInFieldAttribute($attribute, $filterValue, $searchFor)) {
|
||||
unset($event['Object'][$k]['Attribute'][$k2]);
|
||||
|
@ -1914,9 +1917,7 @@ class EventsController extends AppController
|
|||
if (!empty($validationErrors)) {
|
||||
$event['errors'] = $validationErrors;
|
||||
}
|
||||
$this->set('event', $event);
|
||||
$this->render('view');
|
||||
return true;
|
||||
return $this->__restResponse($event);
|
||||
} else {
|
||||
// redirect to the view of the newly created event
|
||||
$this->Flash->success(__('The event has been saved'));
|
||||
|
@ -2168,9 +2169,12 @@ class EventsController extends AppController
|
|||
if (empty($source_event)) {
|
||||
throw new NotFoundException(__('Invalid source event.'));
|
||||
}
|
||||
$recovered_uuids = [];
|
||||
foreach ($source_event[0]['Attribute'] as &$attribute) {
|
||||
unset($attribute['id']);
|
||||
$originalUUID = $attribute['uuid'];
|
||||
$attribute['uuid'] = CakeText::uuid();
|
||||
$recovered_uuids[$originalUUID] = $attribute['uuid'];
|
||||
unset($attribute['ShadowAttribute']);
|
||||
$attribute['Tag'] = [];
|
||||
foreach ($attribute['AttributeTag'] as $aT) {
|
||||
|
@ -2181,10 +2185,14 @@ class EventsController extends AppController
|
|||
}
|
||||
foreach ($source_event[0]['Object'] as &$object) {
|
||||
unset($object['id']);
|
||||
$originalUUID = $object['uuid'];
|
||||
$object['uuid'] = CakeText::uuid();
|
||||
$recovered_uuids[$originalUUID] = $object['uuid'];
|
||||
foreach ($object['Attribute'] as &$attribute) {
|
||||
unset($attribute['id']);
|
||||
$originalUUID = $attribute['uuid'];
|
||||
$attribute['uuid'] = CakeText::uuid();
|
||||
$recovered_uuids[$originalUUID] = $attribute['uuid'];
|
||||
unset($attribute['ShadowAttribute']);
|
||||
$attribute['Tag'] = [];
|
||||
foreach ($attribute['AttributeTag'] as $aT) {
|
||||
|
@ -2194,21 +2202,39 @@ class EventsController extends AppController
|
|||
unset($attribute['AttributeTag']);
|
||||
}
|
||||
}
|
||||
foreach ($source_event[0]['Object'] as &$object) {
|
||||
foreach ($object['ObjectReference'] as &$reference) {
|
||||
if (isset($recovered_uuids[$object['uuid']])) {
|
||||
$reference['object_uuid'] = $recovered_uuids[$object['uuid']];
|
||||
}
|
||||
if (isset($recovered_uuids[$reference['referenced_uuid']])) {
|
||||
$reference['referenced_uuid'] = $recovered_uuids[$reference['referenced_uuid']];
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($source_event[0]['EventReport'] as &$report) {
|
||||
unset($report['id'], $report['event_id']);
|
||||
$report['uuid'] = CakeText::uuid();
|
||||
}
|
||||
$results = [
|
||||
'results' => [
|
||||
'Object' => $source_event[0]['Object'],
|
||||
'Attribute' => $source_event[0]['Attribute']
|
||||
'Attribute' => $source_event[0]['Attribute'],
|
||||
'EventReport' => $source_event[0]['EventReport']
|
||||
]
|
||||
];
|
||||
if ($this->_isRest()) {
|
||||
$this->loadModel('Log');
|
||||
$save_results = ['attributes' => 0, 'objects' => 0];
|
||||
$save_results = ['attributes' => 0, 'objects' => 0, 'eventReports' => 0];
|
||||
foreach ($results['results']['Attribute'] as $attribute) {
|
||||
$this->Event->Attribute->captureAttribute($attribute, $target_id, $this->Auth->user(), false, $this->Log);
|
||||
}
|
||||
foreach ($results['results']['Object'] as $object) {
|
||||
$this->Event->Object->captureObject($object, $target_id, $this->Auth->user(), $this->Log);
|
||||
}
|
||||
foreach ($results['results']['EventReport'] as $report) {
|
||||
$this->Event->EventReport->captureReport($this->Auth->user(), $report, $target_id);
|
||||
}
|
||||
$event = $this->Event->fetchEvent(
|
||||
$this->Auth->user(),
|
||||
[
|
||||
|
@ -2279,9 +2305,7 @@ class EventsController extends AppController
|
|||
$metadata = $this->request->param('named.metadata');
|
||||
$results = $this->Event->fetchEvent($this->Auth->user(), ['eventid' => $id, 'metadata' => $metadata]);
|
||||
$event = $results[0];
|
||||
$this->set('event', $event);
|
||||
$this->render('view');
|
||||
return true;
|
||||
return $this->__restResponse($event);
|
||||
} else {
|
||||
$message = 'Error';
|
||||
if ($this->_isRest()) {
|
||||
|
@ -3699,9 +3723,6 @@ class EventsController extends AppController
|
|||
|
||||
public function filterEventIdsForPush()
|
||||
{
|
||||
if (!$this->userRole['perm_sync']) {
|
||||
throw new MethodNotAllowedException(__('You do not have the permission to do that.'));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
$incomingIDs = array();
|
||||
$incomingEvents = array();
|
||||
|
@ -3714,16 +3735,16 @@ class EventsController extends AppController
|
|||
'recursive' => -1,
|
||||
'fields' => array('Event.uuid', 'Event.timestamp', 'Event.locked'),
|
||||
));
|
||||
foreach ($events as $k => $v) {
|
||||
if ($v['Event']['timestamp'] >= $incomingEvents[$v['Event']['uuid']]) {
|
||||
unset($incomingEvents[$v['Event']['uuid']]);
|
||||
foreach ($events as $event) {
|
||||
if ($event['Event']['timestamp'] >= $incomingEvents[$event['Event']['uuid']]) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
continue;
|
||||
}
|
||||
if ($v['Event']['locked'] == 0) {
|
||||
unset($incomingEvents[$v['Event']['uuid']]);
|
||||
if ($event['Event']['locked'] == 0) {
|
||||
unset($incomingEvents[$event['Event']['uuid']]);
|
||||
}
|
||||
}
|
||||
$this->set('result', array_keys($incomingEvents));
|
||||
return $this->RestResponse->viewData(array_keys($incomingEvents), $this->response->type());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4506,16 +4527,23 @@ class EventsController extends AppController
|
|||
if ($scope == 'event') {
|
||||
$eventId = $scope_id;
|
||||
} elseif ($scope == 'attribute') {
|
||||
$attribute = $this->Event->Attribute->fetchAttributes($this->Auth->user(), array(
|
||||
'conditions' => array('Attribute.id' => $scope_id),
|
||||
'fields' => array('event_id'),
|
||||
'flatten' => 1,
|
||||
));
|
||||
if (empty($attribute)) {
|
||||
throw new Exception("Invalid Attribute.");
|
||||
if ($scope_id == 'selected') {
|
||||
if (empty($this->params['named']['eventid'])) {
|
||||
throw new Exception("Invalid Event.");
|
||||
}
|
||||
$eventId = $this->params['named']['eventid'];
|
||||
} else {
|
||||
$attribute = $this->Event->Attribute->fetchAttributes($this->Auth->user(), array(
|
||||
'conditions' => array('Attribute.id' => $scope_id),
|
||||
'fields' => array('event_id'),
|
||||
'flatten' => 1,
|
||||
));
|
||||
if (empty($attribute)) {
|
||||
throw new Exception("Invalid Attribute.");
|
||||
}
|
||||
$attribute = $attribute[0];
|
||||
$eventId = $attribute['Attribute']['event_id'];
|
||||
}
|
||||
$attribute = $attribute[0];
|
||||
$eventId = $attribute['Attribute']['event_id'];
|
||||
} elseif ($scope == 'tag_collection') {
|
||||
$eventId = 0; // no event_id for tag_collection, consider all events
|
||||
} else {
|
||||
|
@ -5141,7 +5169,7 @@ class EventsController extends AppController
|
|||
if ($this->request->is('Post')) {
|
||||
if (Configure::read('Plugin.ZeroMQ_enable')) {
|
||||
$pubSubTool = $this->Event->getPubSubTool();
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $id));
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $id, 'includeAllTags' => true));
|
||||
if (!empty($event)) {
|
||||
$pubSubTool->publishEvent($event[0]);
|
||||
$success = 1;
|
||||
|
@ -5188,7 +5216,7 @@ class EventsController extends AppController
|
|||
$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);
|
||||
$params = array('eventid' => $id, 'includeAllTags' => true);
|
||||
if (Configure::read('Plugin.Kafka_include_attachments')) {
|
||||
$params['includeAttachments'] = 1;
|
||||
}
|
||||
|
@ -5681,4 +5709,37 @@ class EventsController extends AppController
|
|||
}
|
||||
return $this->RestResponse->viewData($allConflicts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $event
|
||||
* @return CakeResponseTmp
|
||||
* @throws Exception
|
||||
*/
|
||||
private function __restResponse(array $event)
|
||||
{
|
||||
$tmpFile = new TmpFileTool();
|
||||
|
||||
if ($this->request->is('json')) {
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
$converter = new JSONConverterTool();
|
||||
if ($this->RestResponse->isAutomaticTool()) {
|
||||
foreach ($converter->streamConvert($event) as $part) {
|
||||
$tmpFile->write($part);
|
||||
}
|
||||
} else {
|
||||
$tmpFile->write($converter->convert($event));
|
||||
}
|
||||
$format = 'json';
|
||||
} elseif ($this->request->is('xml')) {
|
||||
App::uses('XMLConverterTool', 'Tools');
|
||||
$converter = new XMLConverterTool();
|
||||
foreach ($converter->frameCollection($converter->convert($event)) as $chunk) {
|
||||
$tmpFile->write($chunk);
|
||||
}
|
||||
$format = 'xml';
|
||||
} else {
|
||||
throw new Exception("Invalid format, only JSON or XML is supported.");
|
||||
}
|
||||
return $this->RestResponse->viewData($tmpFile, $format, false, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,6 +267,7 @@ class GalaxiesController extends AppController
|
|||
{
|
||||
$mitreAttackGalaxyId = $this->Galaxy->getMitreAttackGalaxyId();
|
||||
$local = !empty($this->params['named']['local']) ? $this->params['named']['local'] : '0';
|
||||
$eventid = !empty($this->params['named']['eventid']) ? $this->params['named']['eventid'] : '0';
|
||||
$conditions = $namespace === '0' ? array() : array('namespace' => $namespace);
|
||||
$galaxies = $this->Galaxy->find('all', array(
|
||||
'recursive' => -1,
|
||||
|
@ -278,14 +279,14 @@ class GalaxiesController extends AppController
|
|||
$items = array(
|
||||
array(
|
||||
'name' => __('All clusters'),
|
||||
'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/0'. '/local:' . $local
|
||||
'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/0'. '/local:' . $local . '/eventid:' . $eventid
|
||||
)
|
||||
);
|
||||
foreach ($galaxies as $galaxy) {
|
||||
if (!isset($galaxy['Galaxy']['kill_chain_order']) || $noGalaxyMatrix) {
|
||||
$items[] = array(
|
||||
'name' => h($galaxy['Galaxy']['name']),
|
||||
'value' => $this->baseurl . "/galaxies/selectCluster/" . $target_id . '/' . $target_type . '/' . $galaxy['Galaxy']['id'] . '/local:' . $local,
|
||||
'value' => $this->baseurl . "/galaxies/selectCluster/" . $target_id . '/' . $target_type . '/' . $galaxy['Galaxy']['id'] . '/local:' . $local . '/eventid:' . $eventid,
|
||||
'template' => array(
|
||||
'preIcon' => 'fa-' . $galaxy['Galaxy']['icon'],
|
||||
'name' => $galaxy['Galaxy']['name'],
|
||||
|
@ -296,11 +297,12 @@ class GalaxiesController extends AppController
|
|||
$param = array(
|
||||
'name' => $galaxy['Galaxy']['name'],
|
||||
'functionName' => sprintf(
|
||||
"getMatrixPopup('%s', '%s', '%s/local:%s')",
|
||||
"getMatrixPopup('%s', '%s', '%s/local:%s/eventid:%s')",
|
||||
$target_type,
|
||||
$target_id,
|
||||
$galaxy['Galaxy']['id'],
|
||||
$local
|
||||
$local,
|
||||
$eventid
|
||||
),
|
||||
'isPill' => true,
|
||||
'isMatrix' => true
|
||||
|
@ -325,15 +327,17 @@ class GalaxiesController extends AppController
|
|||
'order' => array('namespace asc')
|
||||
));
|
||||
$local = !empty($this->params['named']['local']) ? '1' : '0';
|
||||
$eventid = !empty($this->params['named']['eventid']) ? $this->params['named']['eventid'] : '0';
|
||||
$items = array();
|
||||
$noGalaxyMatrix = $noGalaxyMatrix ? '1' : '0';
|
||||
$items[] = array(
|
||||
'name' => __('All namespaces'),
|
||||
'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/0' . '/' . $noGalaxyMatrix . '/local:' . $local
|
||||
'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/0' . '/' . $noGalaxyMatrix . '/local:' . $local . '/eventid:' . $eventid
|
||||
);
|
||||
foreach ($namespaces as $namespace) {
|
||||
$items[] = array(
|
||||
'name' => $namespace,
|
||||
'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/' . $namespace . '/' . $noGalaxyMatrix . '/local:' . $local
|
||||
'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/' . $namespace . '/' . $noGalaxyMatrix . '/local:' . $local . '/eventid:' . $eventid
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class GalaxyClustersController extends AppController
|
|||
$contextConditions['GalaxyCluster.deleted'] = true;
|
||||
}
|
||||
|
||||
$this->set('passedArgsArray', array('context' => $filters['context'], 'searchall' => isset($filters['searchall']) ? $filters['searchall'] : ''));
|
||||
$this->set('passedArgs', json_encode(array('context' => $filters['context'], 'searchall' => isset($filters['searchall']) ? $filters['searchall'] : '')));
|
||||
$this->set('context', $filters['context']);
|
||||
$searchConditions = array();
|
||||
if (empty($filters['searchall'])) {
|
||||
|
@ -972,7 +972,7 @@ class GalaxyClustersController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException('This function can only be reached via AJAX.');
|
||||
}
|
||||
$cluster = $this->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $id, 'view', $throwErrors=true, $full=true);
|
||||
$cluster = $this->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $id, 'view', true, true);
|
||||
$existingRelations = $this->GalaxyCluster->GalaxyClusterRelation->getExistingRelationships();
|
||||
$cluster = $this->GalaxyCluster->attachClusterToRelations($this->Auth->user(), $cluster);
|
||||
|
||||
|
@ -983,12 +983,8 @@ class GalaxyClustersController extends AppController
|
|||
|
||||
$this->set('existingRelations', $existingRelations);
|
||||
$this->set('cluster', $cluster);
|
||||
$relations = $this->GalaxyCluster->GalaxyClusterRelation->fetchRelations($this->Auth->user(), array(
|
||||
'conditions' => array(
|
||||
'GalaxyClusterRelation.galaxy_cluster_uuid' => $cluster['GalaxyCluster']['uuid']
|
||||
),
|
||||
'contain' => array('SharingGroup', 'TargetCluster', 'GalaxyClusterRelationTag' => array('Tag'))
|
||||
));
|
||||
$relations = $cluster['GalaxyCluster']['GalaxyClusterRelation'];
|
||||
$this->set('passedArgs', json_encode([]));
|
||||
$this->set('relations', $relations);
|
||||
$this->set('tree', $tree);
|
||||
$this->loadModel('Attribute');
|
||||
|
|
|
@ -16,14 +16,102 @@ class GalaxyElementsController extends AppController
|
|||
|
||||
public function index($clusterId)
|
||||
{
|
||||
$filters = $this->IndexFilter->harvestParameters(array('context', 'searchall'));
|
||||
$aclConditions = $this->GalaxyElement->buildClusterConditions($this->Auth->user(), $clusterId);
|
||||
$this->paginate['conditions'] = [$aclConditions];
|
||||
if (empty($filters['context'])) {
|
||||
$filters['context'] = 'all';
|
||||
}
|
||||
$searchConditions = array();
|
||||
if (empty($filters['searchall'])) {
|
||||
$filters['searchall'] = '';
|
||||
}
|
||||
if (strlen($filters['searchall']) > 0) {
|
||||
$searchall = '%' . strtolower($filters['searchall']) . '%';
|
||||
$searchConditions = array(
|
||||
'OR' => array(
|
||||
'LOWER(GalaxyElement.key) LIKE' => $searchall,
|
||||
'LOWER(GalaxyElement.value) LIKE' => $searchall,
|
||||
),
|
||||
);
|
||||
}
|
||||
$this->paginate['conditions'] = ['AND' => [$aclConditions, $searchConditions]];
|
||||
$this->paginate['contain'] = ['GalaxyCluster' => ['fields' => ['id', 'distribution', 'org_id']]];
|
||||
$clusters = $this->paginate();
|
||||
$this->set('list', $clusters);
|
||||
$elements = $this->paginate();
|
||||
$this->set('elements', $elements);
|
||||
$this->set('clusterId', $clusterId);
|
||||
$this->set('context', $filters['context']);
|
||||
$this->set('passedArgs', json_encode([
|
||||
'context' => $filters['context'],
|
||||
'searchall' => isset($filters['searchall']) ? $filters['searchall'] : ''
|
||||
]));
|
||||
$cluster = $this->GalaxyElement->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $clusterId, array('edit', 'delete'), false, false);
|
||||
$canModify = !empty($cluster['authorized']);
|
||||
$canModify = true;
|
||||
$this->set('canModify', $canModify);
|
||||
if ($filters['context'] == 'JSONView') {
|
||||
$expanded = $this->GalaxyElement->getExpandedJSONFromElements($elements);
|
||||
$this->set('JSONElements', $expanded);
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->render('ajax/index');
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($elementId)
|
||||
{
|
||||
$element = $this->GalaxyElement->find('first', array('conditions' => array('GalaxyElement.id' => $elementId)));
|
||||
if (empty($element)) {
|
||||
throw new Exception(__('Element not found'));
|
||||
}
|
||||
$this->set('element', $element);
|
||||
$clusterId = $element['GalaxyElement']['galaxy_cluster_id'];
|
||||
$cluster = $this->GalaxyElement->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $clusterId, array('edit'), true, false);
|
||||
if ($this->request->is('post')) {
|
||||
$deleteResult = $this->GalaxyElement->delete($elementId);
|
||||
if ($deleteResult) {
|
||||
$this->GalaxyElement->GalaxyCluster->editCluster($this->Auth->user(), $cluster, [], false);
|
||||
$message = __('Galaxy element %s deleted', $elementId);
|
||||
$this->Flash->success($message);
|
||||
} else {
|
||||
$message = __('Could not delete galaxy element');
|
||||
$this->Flash->error($message);
|
||||
}
|
||||
$this->redirect($this->referer());
|
||||
} else {
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This function can only be reached via AJAX.'));
|
||||
} else {
|
||||
$this->layout = 'ajax';
|
||||
$this->set('elementId', $elementId);
|
||||
$this->render('ajax/delete');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function flattenJson($clusterId)
|
||||
{
|
||||
$cluster = $this->GalaxyElement->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $clusterId, array('edit'), true, false);
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$json = $this->GalaxyElement->jsonDecode($this->request->data['GalaxyElement']['jsonData']);
|
||||
$flattened = Hash::flatten($json);
|
||||
$newElements = [];
|
||||
foreach ($flattened as $k => $v) {
|
||||
$newElements[] = ['key' => $k, 'value' => $v];
|
||||
}
|
||||
$cluster['GalaxyCluster']['GalaxyElement'] = $newElements;
|
||||
$errors = $this->GalaxyElement->GalaxyCluster->editCluster($this->Auth->user(), $cluster, [], false);
|
||||
if (empty($errors)) {
|
||||
return $this->RestResponse->saveSuccessResponse('GalaxyElement', 'flattenJson', $clusterId, false);
|
||||
} else {
|
||||
$message = implode(', ', $errors);
|
||||
return $this->RestResponse->saveFailResponse('GalaxyElement', 'flattenJson', $clusterId, $message, false);
|
||||
}
|
||||
}
|
||||
$this->set('clusterId', $clusterId);
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->layout = 'ajax';
|
||||
$this->render('ajax/flattenJson');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ class LogsController extends AppController
|
|||
}
|
||||
|
||||
// Shows a minimalistic history for the currently selected event
|
||||
public function event_index($id)
|
||||
public function event_index($id, $org = null)
|
||||
{
|
||||
$this->loadModel('Event');
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array(
|
||||
|
@ -183,6 +183,10 @@ class LogsController extends AppController
|
|||
);
|
||||
}
|
||||
|
||||
if ($org) {
|
||||
$conditions['org'] = $org;
|
||||
}
|
||||
|
||||
$this->paginate['fields'] = array('title', 'created', 'model', 'model_id', 'action', 'change', 'org', 'email');
|
||||
$this->paginate['conditions'] = $conditions;
|
||||
|
||||
|
@ -194,7 +198,7 @@ class LogsController extends AppController
|
|||
'fields' => array('User.email')
|
||||
));
|
||||
foreach ($list as $k => $item) {
|
||||
if (!in_array($item['Log']['email'], $orgEmails)) {
|
||||
if (!in_array($item['Log']['email'], $orgEmails, true)) {
|
||||
$list[$k]['Log']['email'] = '';
|
||||
}
|
||||
}
|
||||
|
@ -367,6 +371,8 @@ class LogsController extends AppController
|
|||
'EventTag',
|
||||
'Feed',
|
||||
'DecayingModel',
|
||||
'EventGraph',
|
||||
'EventReport',
|
||||
'MispObject',
|
||||
'Organisation',
|
||||
'Post',
|
||||
|
|
|
@ -298,4 +298,13 @@ class ObjectTemplatesController extends AppController
|
|||
$this->layout = 'ajax';
|
||||
$this->render('ajax/getToggleField');
|
||||
}
|
||||
|
||||
public function getRaw($uuidOrName)
|
||||
{
|
||||
$template = $this->ObjectTemplate->getRawFromDisk($uuidOrName);
|
||||
if (empty($template)) {
|
||||
throw new NotFoundException(__('Template not found'));
|
||||
}
|
||||
return $this->RestResponse->viewData($template, $this->response->type());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1042,35 +1042,35 @@ class ServersController extends AppController
|
|||
$this->set('branch', $gitStatus['branch']);
|
||||
$this->set('commit', $gitStatus['commit']);
|
||||
$this->set('latestCommit', $gitStatus['latestCommit']);
|
||||
|
||||
$phpSettings = array(
|
||||
'max_execution_time' => array(
|
||||
'explanation' => 'The maximum duration that a script can run (does not affect the background workers). A too low number will break long running scripts like comprehensive API exports',
|
||||
'recommended' => 300,
|
||||
'unit' => false
|
||||
'unit' => 'seconds',
|
||||
),
|
||||
'memory_limit' => array(
|
||||
'explanation' => 'The maximum memory that PHP can consume. It is recommended to raise this number since certain exports can generate a fair bit of memory usage',
|
||||
'recommended' => 2048,
|
||||
'unit' => 'M'
|
||||
'unit' => 'MB'
|
||||
),
|
||||
'upload_max_filesize' => array(
|
||||
'explanation' => 'The maximum size that an uploaded file can be. It is recommended to raise this number to allow for the upload of larger samples',
|
||||
'recommended' => 50,
|
||||
'unit' => 'M'
|
||||
'unit' => 'MB'
|
||||
),
|
||||
'post_max_size' => array(
|
||||
'explanation' => 'The maximum size of a POSTed message, this has to be at least the same size as the upload_max_filesize setting',
|
||||
'recommended' => 50,
|
||||
'unit' => 'M'
|
||||
'unit' => 'MB'
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($phpSettings as $setting => $settingArray) {
|
||||
$phpSettings[$setting]['value'] = ini_get($setting);
|
||||
if ($settingArray['unit']) {
|
||||
$phpSettings[$setting]['value'] = intval(rtrim($phpSettings[$setting]['value'], $phpSettings[$setting]['unit']));
|
||||
} else {
|
||||
$phpSettings[$setting]['value'] = intval($phpSettings[$setting]['value']);
|
||||
$phpSettings[$setting]['value'] = $this->Server->getIniSetting($setting);
|
||||
if ($phpSettings[$setting]['value'] && $settingArray['unit'] && $settingArray['unit'] === 'MB') {
|
||||
// convert basic unit to M
|
||||
$phpSettings[$setting]['value'] = (int) floor($phpSettings[$setting]['value'] / 1024 / 1024);
|
||||
}
|
||||
}
|
||||
$this->set('phpSettings', $phpSettings);
|
||||
|
@ -1342,17 +1342,20 @@ class ServersController extends AppController
|
|||
continue;
|
||||
}
|
||||
|
||||
$exception = null;
|
||||
try {
|
||||
$remote_event = $this->Event->downloadEventFromServer($local_event['Event']['uuid'], $server, null, true);
|
||||
$remote_event_id = $remote_event[0]['id'];
|
||||
$remoteEvent = $this->Event->downloadEventFromServer($local_event['Event']['uuid'], $server, null, true);
|
||||
} catch (Exception $e) {
|
||||
$remote_event_id = null;
|
||||
$remoteEvent = null;
|
||||
$exception = $e->getMessage();
|
||||
}
|
||||
$remoteEventId = isset($remoteEvent[0]['id']) ? $remoteEvent[0]['id'] : null;
|
||||
$remote_events[] = array(
|
||||
"server_id" => $server['Server']['id'],
|
||||
"server_name" => $server['Server']['name'],
|
||||
"url" => isset($remote_event_id) ? $server['Server']['url']."/events/view/".$remote_event_id : $server['Server']['url'],
|
||||
"remote_id" => isset($remote_event_id) ? $remote_event_id : false
|
||||
"url" => isset($remoteEventId) ? $server['Server']['url'] . "/events/view/" . $remoteEventId : $server['Server']['url'],
|
||||
"remote_id" => isset($remoteEventId) ? $remoteEventId : false,
|
||||
"exception" => $exception,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1652,10 +1655,6 @@ class ServersController extends AppController
|
|||
|
||||
public function testConnection($id = false)
|
||||
{
|
||||
if (!$this->Auth->user('Role')['perm_sync'] && !$this->Auth->user('Role')['perm_site_admin']) {
|
||||
throw new MethodNotAllowedException('You don\'t have permission to do that.');
|
||||
}
|
||||
|
||||
$server = $this->Server->find('first', ['conditions' => ['Server.id' => $id]]);
|
||||
if (!$server) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
|
|
|
@ -828,6 +828,52 @@ class ShadowAttributesController extends AppController
|
|||
$this->set('_serialize', array('ShadowAttribute'));
|
||||
}
|
||||
|
||||
public function viewPicture($id, $thumbnail=false)
|
||||
{
|
||||
$conditions['ShadowAttribute.id'] = $id;
|
||||
$conditions['ShadowAttribute.type'] = 'attachment';
|
||||
$options = array(
|
||||
'conditions' => $conditions,
|
||||
'includeAllTags' => false,
|
||||
'includeAttributeUuid' => true,
|
||||
'flatten' => true,
|
||||
'deleted' => [0, 1]
|
||||
);
|
||||
|
||||
|
||||
$sa = $this->ShadowAttribute->find('first', array(
|
||||
'recursive' => -1,
|
||||
'contain' => ['Event', 'Attribute'], // required because of conditions
|
||||
'fields' => array(
|
||||
'ShadowAttribute.id', 'ShadowAttribute.old_id', 'ShadowAttribute.event_id', 'ShadowAttribute.type', 'ShadowAttribute.category', 'ShadowAttribute.uuid', 'ShadowAttribute.to_ids', 'ShadowAttribute.value', 'ShadowAttribute.comment', 'ShadowAttribute.org_id', 'ShadowAttribute.first_seen', 'ShadowAttribute.last_seen',
|
||||
),
|
||||
'conditions' => $conditions,
|
||||
));
|
||||
if (empty($sa)) {
|
||||
throw new NotFoundException(__('Invalid proposal.'));
|
||||
}
|
||||
|
||||
if (!$this->ShadowAttribute->Attribute->isImage($sa['ShadowAttribute'])) {
|
||||
throw new NotFoundException("ShadowAttribute is not an image.");
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
if ($this->ShadowAttribute->typeIsAttachment($sa['ShadowAttribute']['type'])) {
|
||||
$encodedFile = $this->ShadowAttribute->base64EncodeAttachment($sa['ShadowAttribute']);
|
||||
$sa['ShadowAttribute']['data'] = $encodedFile;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($sa['ShadowAttribute']['data'], $this->response->type());
|
||||
} else {
|
||||
$width = isset($this->request->params['named']['width']) ? $this->request->params['named']['width'] : 200;
|
||||
$height = isset($this->request->params['named']['height']) ? $this->request->params['named']['height'] : 200;
|
||||
$imageData = $this->ShadowAttribute->getPictureData($sa, $thumbnail, $width, $height);
|
||||
$extension = pathinfo($sa['ShadowAttribute']['value'], PATHINFO_EXTENSION);
|
||||
return new CakeResponse(array('body' => $imageData, 'type' => strtolower($extension)));
|
||||
}
|
||||
}
|
||||
|
||||
public function index($eventId = false)
|
||||
{
|
||||
$conditions = array();
|
||||
|
|
|
@ -608,7 +608,7 @@ class SharingGroupsController extends AppController
|
|||
}
|
||||
}
|
||||
}
|
||||
if (false === $addServer) {
|
||||
if (false === $removeServer) {
|
||||
return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Server is not in the sharing group.', $this->response->type());
|
||||
}
|
||||
$result = $this->SharingGroup->SharingGroupServer->delete($removeServer);
|
||||
|
|
|
@ -41,7 +41,6 @@ class TagsController extends AppController
|
|||
'request' => $this->request,
|
||||
'named_params' => $this->params['named'],
|
||||
'paramArray' => ['favouritesOnly', 'filter', 'searchall', 'name', 'search', 'exclude_statistics'],
|
||||
'ordered_url_params' => @compact($paramArray)
|
||||
);
|
||||
$exception = false;
|
||||
$passedArgsArray = $this->_harvestParameters($filterData, $exception);
|
||||
|
@ -344,79 +343,33 @@ class TagsController extends AppController
|
|||
|
||||
public function view($id)
|
||||
{
|
||||
if ($this->_isRest()) {
|
||||
$contain = array('EventTag' => array('fields' => 'event_id'));
|
||||
$contain['AttributeTag'] = array('fields' => 'attribute_id');
|
||||
$tag = $this->Tag->find('first', array(
|
||||
'conditions' => array('id' => $id),
|
||||
'recursive' => -1,
|
||||
'contain' => $contain
|
||||
));
|
||||
if (empty($tag)) {
|
||||
throw new MethodNotAllowedException('Invalid Tag');
|
||||
}
|
||||
if (empty($tag['EventTag'])) {
|
||||
$tag['Tag']['count'] = 0;
|
||||
} else {
|
||||
$eventIDs = array();
|
||||
foreach ($tag['EventTag'] as $eventTag) {
|
||||
$eventIDs[] = $eventTag['event_id'];
|
||||
}
|
||||
$conditions = array('Event.id' => $eventIDs);
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions = array_merge(
|
||||
$conditions,
|
||||
array('OR' => array(
|
||||
array('AND' => array(
|
||||
array('Event.distribution >' => 0),
|
||||
array('Event.published =' => 1)
|
||||
)),
|
||||
array('Event.orgc_id' => $this->Auth->user('org_id'))
|
||||
))
|
||||
);
|
||||
}
|
||||
$events = $this->Tag->EventTag->Event->find('all', array(
|
||||
'fields' => array('Event.id', 'Event.distribution', 'Event.orgc_id'),
|
||||
'conditions' => $conditions
|
||||
));
|
||||
$tag['Tag']['count'] = count($events);
|
||||
}
|
||||
unset($tag['EventTag']);
|
||||
if (empty($tag['AttributeTag'])) {
|
||||
$tag['Tag']['attribute_count'] = 0;
|
||||
} else {
|
||||
$attributeIDs = array();
|
||||
foreach ($tag['AttributeTag'] as $attributeTag) {
|
||||
$attributeIDs[] = $attributeTag['attribute_id'];
|
||||
}
|
||||
$conditions = array('Attribute.id' => $attributeIDs);
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
$conditions = array_merge(
|
||||
$conditions,
|
||||
array('OR' => array(
|
||||
array('AND' => array(
|
||||
array('Attribute.deleted =' => 0),
|
||||
array('Attribute.distribution >' => 0),
|
||||
array('Event.distribution >' => 0),
|
||||
array('Event.published =' => 1)
|
||||
)),
|
||||
array('Event.orgc_id' => $this->Auth->user('org_id'))
|
||||
))
|
||||
);
|
||||
}
|
||||
$attributes = $this->Tag->AttributeTag->Attribute->find('all', array(
|
||||
'fields' => array('Attribute.id', 'Attribute.deleted', 'Attribute.distribution', 'Event.id', 'Event.distribution', 'Event.orgc_id'),
|
||||
'contain' => array('Event' => array('fields' => array('id', 'distribution', 'orgc_id'))),
|
||||
'conditions' => $conditions
|
||||
));
|
||||
$tag['Tag']['attribute_count'] = count($attributes);
|
||||
}
|
||||
unset($tag['AttributeTag']);
|
||||
$this->set('Tag', $tag['Tag']);
|
||||
$this->set('_serialize', 'Tag');
|
||||
} else {
|
||||
if (!$this->_isRest()) {
|
||||
throw new MethodNotAllowedException('This action is only for REST users.');
|
||||
}
|
||||
|
||||
$tag = $this->Tag->find('first', array(
|
||||
'conditions' => array('id' => $id),
|
||||
'recursive' => -1,
|
||||
'contain' => ['AttributeTag' => ['fields' => 'attribute_id']],
|
||||
));
|
||||
if (empty($tag)) {
|
||||
throw new MethodNotAllowedException('Invalid Tag');
|
||||
}
|
||||
|
||||
$tag['Tag']['count'] = $this->Tag->EventTag->countForTag($tag['Tag']['id'], $this->Auth->user());
|
||||
|
||||
if (empty($tag['AttributeTag'])) {
|
||||
$tag['Tag']['attribute_count'] = 0;
|
||||
} else {
|
||||
$attributeIDs = array_column($tag['AttributeTag'], 'attribute_id');
|
||||
$tag['Tag']['attribute_count'] = count($this->Tag->AttributeTag->Attribute->fetchAttributes($this->Auth->user(), [
|
||||
'conditions' => ['Attribute.id' => $attributeIDs],
|
||||
'list' => true,
|
||||
]));
|
||||
}
|
||||
unset($tag['AttributeTag']);
|
||||
|
||||
return $this->RestResponse->viewData($tag['Tag'], $this->response->type());
|
||||
}
|
||||
|
||||
public function showEventTag($id)
|
||||
|
|
|
@ -9,17 +9,17 @@ class TaxonomiesController extends AppController
|
|||
public $components = array('Session', 'RequestHandler');
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
|
||||
'contain' => array(
|
||||
'TaxonomyPredicate' => array(
|
||||
'fields' => array('TaxonomyPredicate.id'),
|
||||
'TaxonomyEntry' => array('fields' => array('TaxonomyEntry.id'))
|
||||
)
|
||||
),
|
||||
'order' => array(
|
||||
'Taxonomy.id' => 'DESC'
|
||||
),
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user van view/page.
|
||||
'contain' => array(
|
||||
'TaxonomyPredicate' => array(
|
||||
'fields' => array('TaxonomyPredicate.id', 'TaxonomyPredicate.value'),
|
||||
'TaxonomyEntry' => array('fields' => array('TaxonomyEntry.id', 'TaxonomyEntry.value'))
|
||||
)
|
||||
),
|
||||
'order' => array(
|
||||
'Taxonomy.id' => 'DESC'
|
||||
),
|
||||
);
|
||||
|
||||
public function index()
|
||||
|
@ -46,25 +46,15 @@ class TaxonomiesController extends AppController
|
|||
} else {
|
||||
$taxonomies = $this->paginate();
|
||||
}
|
||||
$this->loadModel('Tag');
|
||||
foreach ($taxonomies as $key => $taxonomy) {
|
||||
$total = 0;
|
||||
foreach ($taxonomy['TaxonomyPredicate'] as $predicate) {
|
||||
$total += empty($predicate['TaxonomyEntry']) ? 1 : count($predicate['TaxonomyEntry']);
|
||||
}
|
||||
$taxonomies[$key]['total_count'] = $total;
|
||||
$taxonomies[$key]['current_count'] = $this->Tag->find('count', array(
|
||||
'conditions' => array('lower(Tag.name) LIKE ' => strtolower($taxonomy['Taxonomy']['namespace']) . ':%', 'hide_tag' => 0),
|
||||
'recursive' => -1,
|
||||
));
|
||||
unset($taxonomies[$key]['TaxonomyPredicate']);
|
||||
}
|
||||
|
||||
$taxonomies = $this->__tagCount($taxonomies);
|
||||
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($taxonomies, $this->response->type());
|
||||
} else {
|
||||
$this->set('taxonomies', $taxonomies);
|
||||
$this->set('passedArgsArray', $this->passedArgs);
|
||||
}
|
||||
|
||||
$this->set('taxonomies', $taxonomies);
|
||||
$this->set('passedArgsArray', $this->passedArgs);
|
||||
}
|
||||
|
||||
public function view($id)
|
||||
|
@ -469,6 +459,53 @@ class TaxonomiesController extends AppController
|
|||
$this->render('ajax/toggle_required');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach tag counts.
|
||||
* @param array $taxonomies
|
||||
* @return array
|
||||
*/
|
||||
private function __tagCount(array $taxonomies)
|
||||
{
|
||||
$tags = [];
|
||||
foreach ($taxonomies as $taxonomyPos => $taxonomy) {
|
||||
$total = 0;
|
||||
foreach ($taxonomy['TaxonomyPredicate'] as $predicate) {
|
||||
if (isset($predicate['TaxonomyEntry']) && !empty($predicate['TaxonomyEntry'])) {
|
||||
foreach ($predicate['TaxonomyEntry'] as $entry) {
|
||||
$tag = mb_strtolower($taxonomy['Taxonomy']['namespace'] . ':' . $predicate['value'] . '="' . $entry['value'] . '"');
|
||||
$tags[$tag] = $taxonomyPos;
|
||||
$total++;
|
||||
}
|
||||
} else {
|
||||
$tag = mb_strtolower($taxonomy['Taxonomy']['namespace'] . ':' . $predicate['value']);
|
||||
$tags[$tag] = $taxonomyPos;
|
||||
$total++;
|
||||
}
|
||||
}
|
||||
$taxonomies[$taxonomyPos]['total_count'] = $total;
|
||||
$taxonomies[$taxonomyPos]['current_count'] = 0;
|
||||
unset($taxonomies[$taxonomyPos]['TaxonomyPredicate']);
|
||||
}
|
||||
|
||||
$this->loadModel('Tag');
|
||||
$existingTags = $this->Tag->find('column', [
|
||||
'fields' => ['Tag.name'],
|
||||
'conditions' => [
|
||||
'lower(Tag.name)' => array_keys($tags),
|
||||
'hide_tag' => 0
|
||||
],
|
||||
]);
|
||||
|
||||
foreach ($existingTags as $existingTag) {
|
||||
$existingTag = mb_strtolower($existingTag);
|
||||
if (isset($tags[$existingTag])) {
|
||||
$taxonomies[$tags[$existingTag]]['current_count']++;
|
||||
}
|
||||
}
|
||||
|
||||
return $taxonomies;
|
||||
}
|
||||
|
||||
private function __search($value)
|
||||
{
|
||||
$value = mb_strtolower(trim($value));
|
||||
|
|
|
@ -9,20 +9,20 @@ class WarninglistsController extends AppController
|
|||
public $components = array('Session', 'RequestHandler');
|
||||
|
||||
public $paginate = array(
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user can view/page.
|
||||
'contain' => array(
|
||||
'WarninglistType'
|
||||
),
|
||||
'order' => array(
|
||||
'Warninglist.id' => 'DESC'
|
||||
),
|
||||
'limit' => 60,
|
||||
'maxLimit' => 9999, // LATER we will bump here on a problem once we have more than 9999 events <- no we won't, this is the max a user can view/page.
|
||||
'contain' => array(
|
||||
'WarninglistType'
|
||||
),
|
||||
'order' => array(
|
||||
'Warninglist.id' => 'DESC'
|
||||
),
|
||||
'recursive' => -1,
|
||||
);
|
||||
|
||||
public function index()
|
||||
{
|
||||
$filters = $this->IndexFilter->harvestParameters(['value']);
|
||||
$this->paginate['recursive'] = -1;
|
||||
$filters = $this->IndexFilter->harvestParameters(['value', 'enabled']);
|
||||
if (!empty($filters['value'])) {
|
||||
$this->paginate['conditions'] = [
|
||||
'OR' => [
|
||||
|
@ -32,20 +32,20 @@ class WarninglistsController extends AppController
|
|||
]
|
||||
];
|
||||
}
|
||||
if (isset($filters['enabled'])) {
|
||||
$this->paginate['conditions'][] = ['Warninglist.enabled' => $filters['enabled']];
|
||||
}
|
||||
$warninglists = $this->paginate();
|
||||
foreach ($warninglists as &$warninglist) {
|
||||
$warninglist['Warninglist']['valid_attributes'] = array();
|
||||
foreach ($warninglist['WarninglistType'] as $type) {
|
||||
$warninglist['Warninglist']['valid_attributes'][] = $type['type'];
|
||||
}
|
||||
$warninglist['Warninglist']['valid_attributes'] = implode(', ', $warninglist['Warninglist']['valid_attributes']);
|
||||
$validAttributes = array_column($warninglist['WarninglistType'], 'type');
|
||||
$warninglist['Warninglist']['valid_attributes'] = implode(', ', $validAttributes);
|
||||
unset($warninglist['WarninglistType']);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
$this->set('Warninglists', $warninglists);
|
||||
$this->set('_serialize', array('Warninglists'));
|
||||
return $this->RestResponse->viewData(['Warninglists' => $warninglists], $this->response->type());
|
||||
} else {
|
||||
$this->set('warninglists', $warninglists);
|
||||
$this->set('passedArgsArray', $filters);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class CsseCovidTrendsWidget
|
|||
'date' => (empty($options['timeframe']) ? 10 : $options['timeframe']) . 'd'
|
||||
);
|
||||
$eventIds = $this->Event->filterEventIds($user, $params);
|
||||
$eventIds = array_reverse(array_values($eventIds));
|
||||
$eventIds = array_reverse($eventIds);
|
||||
$data = array();
|
||||
if (empty($options['type'])) {
|
||||
$options['type'] = 'confirmed';
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
class EventStreamWidget
|
||||
{
|
||||
public $title = 'Event Stream';
|
||||
public $render = 'Index';
|
||||
public $width = 4;
|
||||
public $height = 2;
|
||||
public $params = [
|
||||
'tags' => 'A list of tagnames to filter on. Comma separated list, prepend each tag with an exclamation mark to negate it.',
|
||||
'orgs' => 'A list of organisation names to filter on. Comma separated list, prepend each tag with an exclamation mark to negate it.',
|
||||
'published' => 'Boolean flag to filter on published events only',
|
||||
'limit' => 'How many events should be listed? Defaults to 5',
|
||||
'fields' => 'A list of fields that should be displayed. Valid fields: id, orgc, info, tags, threat_level, analysis, date. Default field selection ["id", "orgc", "info"]'
|
||||
];
|
||||
public $description = 'Monitor incoming events based on your own filters.';
|
||||
public $cacheLifetime = false;
|
||||
public $autoRefreshDelay = 5;
|
||||
private $__default_fields = ['id', 'orgc', 'info'];
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
$params = [
|
||||
'metadata' => 1,
|
||||
'limit' => 5,
|
||||
'page' => 1,
|
||||
'order' => 'Event.id DESC'
|
||||
];
|
||||
$field_options = [
|
||||
'id' => [
|
||||
'name' => '#',
|
||||
'url' => Configure::read('MISP.baseurl') . '/events/view',
|
||||
'element' => 'links',
|
||||
'data_path' => 'Event.id',
|
||||
'url_params_data_paths' => 'Event.id'
|
||||
],
|
||||
'orgc' => [
|
||||
'name' => 'Org',
|
||||
'data_path' => 'Orgc',
|
||||
'element' => 'org'
|
||||
],
|
||||
'info' => [
|
||||
'name' => 'Info',
|
||||
'data_path' => 'Event.info',
|
||||
],
|
||||
'tags' => [
|
||||
'name' => 'Tags',
|
||||
'data_path' => 'EventTag',
|
||||
'element' => 'tags',
|
||||
'scope' => 'feeds'
|
||||
],
|
||||
'threat_level' => [
|
||||
'name' => 'Threat Level',
|
||||
'data_path' => 'ThreatLevel.name'
|
||||
],
|
||||
'analysis' => [
|
||||
'name' => 'Analysis',
|
||||
'data_path' => 'Event.analysis',
|
||||
'element' => 'array_lookup_field',
|
||||
'arrayData' => [__('Initial'), __('Ongoing'), __('Complete')]
|
||||
],
|
||||
'date' => [
|
||||
'name' => 'Date',
|
||||
'data_path' => 'Event.date'
|
||||
],
|
||||
];
|
||||
$fields = [];
|
||||
if (empty($options['fields'])) {
|
||||
$options['fields'] = $this->__default_fields;
|
||||
}
|
||||
foreach ($options['fields'] as $field) {
|
||||
if (!empty($field_options[$field])) {
|
||||
$fields[] = $field_options[$field];
|
||||
}
|
||||
}
|
||||
foreach (['published', 'limit', 'tags', 'orgs'] as $field) {
|
||||
if (!empty($options[$field])) {
|
||||
$params[$field] = $options[$field];
|
||||
}
|
||||
}
|
||||
$data = $this->Event->fetchEvent($user, $params);
|
||||
return [
|
||||
'data' => $data,
|
||||
'fields' => $fields
|
||||
];
|
||||
}
|
||||
}
|
|
@ -7,41 +7,43 @@ class MispSystemResourceWidget
|
|||
public $width = 3;
|
||||
public $height = 3;
|
||||
public $params = array(
|
||||
'treshold' => 'Treshold for disk space'
|
||||
'threshold' => 'Threshold for disk space'
|
||||
);
|
||||
public $description = 'Basic widget showing some system server statistics.';
|
||||
public $cacheLifetime = false;
|
||||
public $autoRefreshDelay = 30;
|
||||
public $placeholder =
|
||||
'{
|
||||
"treshold": "85"
|
||||
"threshold": "85"
|
||||
}';
|
||||
|
||||
public function handler($user, $options = array())
|
||||
public function handler(array $user, $options = array())
|
||||
{
|
||||
// Keep BC with typo value
|
||||
$threshold = isset($options['threshold']) ? $options['threshold'] : (isset($options['treshold']) ? $options['treshold'] : 85);
|
||||
|
||||
$drive = round((1 - disk_free_space(getcwd())/disk_total_space(getcwd()))*100,2);
|
||||
$cwd = getcwd();
|
||||
$drive = round((1 - disk_free_space($cwd)/disk_total_space($cwd))*100,2);
|
||||
$driveFree = $drive . "%";
|
||||
$driveFreeClass = "";
|
||||
if ($drive > intval($options['treshold'])) {
|
||||
$driveFree = $drive . "% - [Above Treshhold]";
|
||||
if ($drive > intval($threshold)) {
|
||||
$driveFree = $drive . "% - [Above Threshold]";
|
||||
$driveFreeClass = "red";
|
||||
}
|
||||
|
||||
$sysload = sys_getloadavg();
|
||||
|
||||
preg_match('#MemFree:[\s\t]+([\d]+)\s+kB#', file_get_contents('/proc/meminfo'), $matches);
|
||||
$meminfo = file_get_contents('/proc/meminfo');
|
||||
preg_match('#MemFree:[\s\t]+([\d]+)\s+kB#', $meminfo, $matches);
|
||||
$memoryFree = $matches[1];
|
||||
preg_match('#MemTotal:[\s\t]+([\d]+)\s+kB#', file_get_contents('/proc/meminfo'), $matches);
|
||||
preg_match('#MemTotal:[\s\t]+([\d]+)\s+kB#', $meminfo, $matches);
|
||||
$memoryTotal = $matches[1];
|
||||
|
||||
$data = array(
|
||||
array( 'title' => __('User'), 'value' => $user['email']),
|
||||
array( 'title' => __('System'), 'value' => php_uname()),
|
||||
array( 'title' => __('Disk usage'), 'value' => h($driveFree), 'class' => $driveFreeClass),
|
||||
array( 'title' => __('Load'), 'value' => h($sysload[0] . " - " . $sysload[1] . " - " . $sysload[2])),
|
||||
array( 'title' => __('Memory'), 'value' => h(round($memoryFree/1024,2) . "M free (" . round((1 - $memoryFree/$memoryTotal)*100,2) . "% used)")),
|
||||
);
|
||||
array( 'title' => __('User'), 'value' => $user['email']),
|
||||
array( 'title' => __('System'), 'value' => php_uname()),
|
||||
array( 'title' => __('Disk usage'), 'value' => h($driveFree), 'class' => $driveFreeClass),
|
||||
array( 'title' => __('Load'), 'value' => h(implode(" - ", sys_getloadavg()))),
|
||||
array( 'title' => __('Memory'), 'value' => h(round($memoryFree / 1024,2) . " MB free (" . round((1 - $memoryFree/$memoryTotal)*100,2) . " % used)")),
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,36 +20,41 @@ class TrendingTagsWidget
|
|||
"include": ["misp-galaxy:", "my-internal-taxonomy"]
|
||||
}';
|
||||
public $description = 'Widget showing the trending tags over the past x seconds, along with the possibility to include/exclude tags.';
|
||||
public $cacheLifetime = 600;
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$this->Event = ClassRegistry::init('Event');
|
||||
$params = array(
|
||||
'metadata' => 1,
|
||||
'timestamp' => time() - (empty($options['time_window']) ? 8640000 : $options['time_window'])
|
||||
);
|
||||
/** @var Event $eventModel */
|
||||
$eventModel = ClassRegistry::init('Event');
|
||||
$threshold = empty($options['threshold']) ? 10 : $options['threshold'];
|
||||
$eventIds = $this->Event->filterEventIds($user, $params);
|
||||
$params['eventid'] = $eventIds;
|
||||
$events = array();
|
||||
$params = [
|
||||
'timestamp' => time() - (empty($options['time_window']) ? 8640000 : $options['time_window']),
|
||||
];
|
||||
$eventIds = $eventModel->filterEventIds($user, $params);
|
||||
|
||||
$tags = [];
|
||||
$tagColours = [];
|
||||
if (!empty($eventIds)) {
|
||||
$events = $this->Event->fetchEvent($user, $params);
|
||||
}
|
||||
$tags = array();
|
||||
$tagColours = array();
|
||||
foreach ($events as $event) {
|
||||
foreach ($event['EventTag'] as $et) {
|
||||
if ($this->checkTag($options, $et['Tag']['name'])) {
|
||||
if (empty($tags[$et['Tag']['name']])) {
|
||||
$tags[$et['Tag']['name']] = 1;
|
||||
$tagColours[$et['Tag']['name']] = $et['Tag']['colour'];
|
||||
} else {
|
||||
$tags[$et['Tag']['name']] += 1;
|
||||
}
|
||||
$eventTags = $eventModel->EventTag->find('all', [
|
||||
'conditions' => ['EventTag.event_id' => $eventIds],
|
||||
'contain' => ['Tag' => ['fields' => ['name', 'colour']]],
|
||||
'recursive' => -1,
|
||||
'fields' => ['id'],
|
||||
]);
|
||||
|
||||
foreach ($eventTags as $eventTag) {
|
||||
$tagName = $eventTag['Tag']['name'];
|
||||
if (isset($tags[$tagName])) {
|
||||
$tags[$tagName]++;
|
||||
} else if ($this->checkTag($options, $tagName)) {
|
||||
$tags[$tagName] = 1;
|
||||
$tagColours[$tagName] = $eventTag['Tag']['colour'];
|
||||
}
|
||||
}
|
||||
|
||||
arsort($tags);
|
||||
}
|
||||
arsort($tags);
|
||||
|
||||
$data['data'] = array_slice($tags, 0, $threshold);
|
||||
$data['colours'] = $tagColours;
|
||||
return $data;
|
||||
|
|
|
@ -6,6 +6,7 @@ class CsvExport
|
|||
public $default_fields = array('uuid', 'event_id', 'category', 'type', 'value', 'comment', 'to_ids', 'timestamp', 'object_relation', 'attribute_tag');
|
||||
public $default_obj_fields = array('object_uuid', 'object_name', 'object_meta-category');
|
||||
public $requested_fields = array();
|
||||
public $decaying_fields = array('decay_score_score', 'decay_score_decayed');
|
||||
public $non_restrictive_export = true;
|
||||
|
||||
public function handler($data, $options = array())
|
||||
|
@ -22,6 +23,9 @@ class CsvExport
|
|||
|
||||
public function modify_params($user, $params)
|
||||
{
|
||||
if (!empty($params['includeDecayScore'])) {
|
||||
$this->enable_decaying();
|
||||
}
|
||||
if (empty($params['contain'])) {
|
||||
$params['contain'] = array();
|
||||
}
|
||||
|
@ -36,6 +40,11 @@ class CsvExport
|
|||
return $params;
|
||||
}
|
||||
|
||||
public function enable_decaying()
|
||||
{
|
||||
$this->default_fields = array_merge($this->default_fields, $this->decaying_fields);
|
||||
}
|
||||
|
||||
private function __attributesHandler($attribute, $options)
|
||||
{
|
||||
$attribute = $this->__addMetadataToAttributeAtomic($attribute);
|
||||
|
@ -44,6 +53,17 @@ class CsvExport
|
|||
$attribute['object_name'] = $attribute['Object']['name'];
|
||||
$attribute['object_meta-category'] = $attribute['Object']['meta-category'];
|
||||
}
|
||||
if (!empty($attribute['decay_score'])) {
|
||||
$all_scores = Hash::extract($attribute, 'decay_score.{n}.score');
|
||||
$all_decayed = Hash::extract($attribute, 'decay_score.{n}.decayed');
|
||||
$avg_score = array_sum($all_scores)/count($all_scores);
|
||||
$avg_decayed = count(array_intersect([true], $all_decayed)) > 0;
|
||||
$attribute['decay_score_score'] = $avg_score;
|
||||
$attribute['decay_score_decayed'] = $avg_decayed;
|
||||
} else {
|
||||
$attribute['decay_score_score'] = 0;
|
||||
$attribute['decay_score_decayed'] = false;
|
||||
}
|
||||
return $this->__addLine($attribute, $options);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
class CidrTool
|
||||
{
|
||||
/** @var array */
|
||||
private $ipv4 = [];
|
||||
|
||||
/**
|
||||
* Minimum netmask for IPv4 in list. 33 because maximum netmask is 32..
|
||||
* @var int
|
||||
*/
|
||||
private $minimumIpv4Mask = 33;
|
||||
|
||||
/** @var array */
|
||||
private $ipv6 = [];
|
||||
|
||||
public function __construct(array $list)
|
||||
{
|
||||
$this->filterInputList($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value IPv4 or IPv6 address or range
|
||||
* @return false|string
|
||||
*/
|
||||
public function contains($value)
|
||||
{
|
||||
$valueMask = null;
|
||||
if (strpos($value, '/') !== false) {
|
||||
list($value, $valueMask) = explode('/', $value);
|
||||
}
|
||||
|
||||
$match = false;
|
||||
if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
// This code converts IP address to all possible CIDRs that can contains given IP address
|
||||
// and then check if given hash table contains that CIDR.
|
||||
$ip = ip2long($value);
|
||||
// Start from 1, because doesn't make sense to check 0.0.0.0/0 match
|
||||
for ($bits = $this->minimumIpv4Mask; $bits <= 32; $bits++) {
|
||||
$mask = -1 << (32 - $bits);
|
||||
$needle = long2ip($ip & $mask) . "/$bits";
|
||||
if (isset($this->ipv4[$needle])) {
|
||||
$match = $needle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$value = unpack('n*', inet_pton($value));
|
||||
foreach ($this->ipv6 as $netmask => $lv) {
|
||||
foreach ($lv as $l) {
|
||||
if ($this->ipv6InCidr($value, $l, $netmask)) {
|
||||
$match = inet_ntop($l) . "/$netmask";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($match && $valueMask) {
|
||||
$matchMask = explode('/', $match)[1];
|
||||
if ($valueMask < $matchMask) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using solution from https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/IpUtils.php
|
||||
*
|
||||
* @param array $ip
|
||||
* @param string $cidr
|
||||
* @param int $netmask
|
||||
* @return bool
|
||||
*/
|
||||
private function ipv6InCidr($ip, $cidr, $netmask)
|
||||
{
|
||||
$bytesAddr = unpack('n*', $cidr);
|
||||
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
|
||||
$left = $netmask - 16 * ($i - 1);
|
||||
$left = ($left <= 16) ? $left : 16;
|
||||
$mask = ~(0xffff >> $left) & 0xffff;
|
||||
if (($bytesAddr[$i] & $mask) != ($ip[$i] & $mask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out invalid IPv4 or IPv4 CIDR and append maximum netmask if no netmask is given.
|
||||
* @param array $list
|
||||
*/
|
||||
private function filterInputList(array $list)
|
||||
{
|
||||
foreach ($list as $v) {
|
||||
$parts = explode('/', $v, 2);
|
||||
$ipBytes = inet_pton($parts[0]);
|
||||
if ($ipBytes === false) {
|
||||
continue; // IP address part of CIDR is invalid
|
||||
}
|
||||
$maximumNetmask = strlen($ipBytes) === 4 ? 32 : 128;
|
||||
|
||||
if (isset($parts[1]) && ($parts[1] > $maximumNetmask || $parts[1] < 0)) {
|
||||
// Netmask part of CIDR is invalid
|
||||
continue;
|
||||
}
|
||||
|
||||
$mask = isset($parts[1]) ? $parts[1] : $maximumNetmask;
|
||||
if ($maximumNetmask === 32) {
|
||||
if ($mask < $this->minimumIpv4Mask) {
|
||||
$this->minimumIpv4Mask = (int)$mask;
|
||||
}
|
||||
if (!isset($parts[1])) {
|
||||
$v = "$v/$maximumNetmask"; // If CIDR doesnt contains '/', we will consider CIDR as /32
|
||||
}
|
||||
$this->ipv4[$v] = true;
|
||||
} else {
|
||||
$this->ipv6[$mask][] = $ipBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,13 +4,14 @@
|
|||
private $__lookupTables = array();
|
||||
private $__related_events = array();
|
||||
private $__related_attributes = array();
|
||||
private $__eventModel = false;
|
||||
/** @var Event */
|
||||
private $__eventModel;
|
||||
private $__taxonomyModel = false;
|
||||
private $__galaxyClusterModel = false;
|
||||
private $__user = false;
|
||||
private $__json = array();
|
||||
|
||||
public function construct($eventModel, $taxonomyModel, $galaxyClusterModel, $user, $json)
|
||||
public function construct(Event $eventModel, $taxonomyModel, $galaxyClusterModel, $user, $json)
|
||||
{
|
||||
$this->__eventModel = $eventModel;
|
||||
$this->__taxonomyModel = $taxonomyModel;
|
||||
|
@ -99,11 +100,11 @@
|
|||
{
|
||||
foreach ($objects as $k => $object) {
|
||||
$include = $full;
|
||||
if (!$include) {
|
||||
if (!$include && isset($object['Attribute'])) {
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
if (isset($this->__related_attributes[$attribute['id']])) {
|
||||
$include = true;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@ class ElasticSearchClient
|
|||
// Format timestamp
|
||||
$time = strftime("%Y-%m-%d %H:%M:%S", strtotime($document["Log"]["created"]));
|
||||
$document["Log"]["created"] = $time;
|
||||
if (empty($document["Log"]["ip"])) {
|
||||
$document["Log"]["ip"] = null;
|
||||
}
|
||||
$params = array(
|
||||
'index' => $index,
|
||||
'type' => $document_type,
|
||||
|
|
|
@ -77,6 +77,11 @@
|
|||
if (!($check1 && $check2)) {
|
||||
unset($event['Object'][$i]);
|
||||
}
|
||||
foreach($obj['ObjectReference'] as $j => $rel) {
|
||||
if ($rel['deleted']) {
|
||||
unset($event['Object'][$i]['ObjectReference'][$j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($event['Attribute'] as $i => $attr) {
|
||||
$check1 = $this->__satisfy_val_filtering($attr, false);
|
||||
|
@ -519,7 +524,7 @@
|
|||
public function get_reference_data($uuid)
|
||||
{
|
||||
$objectReference = $this->__refModel->ObjectReference->find('all', array(
|
||||
'conditions' => array('ObjectReference.uuid' => $uuid),
|
||||
'conditions' => array('ObjectReference.uuid' => $uuid, 'ObjectReference.deleted' => false),
|
||||
'recursive' => -1,
|
||||
//'fields' => array('ObjectReference.id', 'relationship_type', 'comment', 'referenced_uuid')
|
||||
));
|
||||
|
|
|
@ -107,7 +107,7 @@ class HttpSocketExtended extends HttpSocket
|
|||
}
|
||||
// Convert connection timeout to SocketException
|
||||
if (!empty($this->lastError)) {
|
||||
throw new SocketException($this->lastError['msg']);
|
||||
throw new SocketException($this->lastError['str']);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
|
|
@ -105,18 +105,19 @@ class JSONConverterTool
|
|||
}
|
||||
|
||||
/**
|
||||
* Event to JSON stream convertor.
|
||||
* Event to JSON convertor, but that is intended for machine to machine communication
|
||||
* @param array $event
|
||||
* @return Generator<string>
|
||||
*/
|
||||
public function streamConvert(array $event)
|
||||
{
|
||||
$event = $this->convert($event, false, true);
|
||||
|
||||
// Fast and inaccurate way how to check if event is too big for to convert in one call. This can be changed in future.
|
||||
$isBigEvent = (isset($event['Event']['Attribute']) ? count($event['Event']['Attribute']) : 0) +
|
||||
(isset($event['Event']['Object']) ? count($event['Event']['Object']) : 0) > 100;
|
||||
if (!$isBigEvent) {
|
||||
yield json_encode($event, JSON_PRETTY_PRINT);
|
||||
yield json_encode($event, JSON_UNESCAPED_UNICODE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,11 +128,11 @@ class JSONConverterTool
|
|||
yield ($firstKey === $key ? '' : ',') . json_encode($key) . ":[";
|
||||
$firstInnerKey = key($value);
|
||||
foreach ($value as $i => $attribute) {
|
||||
yield ($firstInnerKey === $i ? '' : ',') . json_encode($attribute);
|
||||
yield ($firstInnerKey === $i ? '' : ',') . json_encode($attribute, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
yield "]";
|
||||
} else {
|
||||
yield ($firstKey === $key ? '' : ',') . json_encode($key) . ":" . json_encode($value);
|
||||
yield ($firstKey === $key ? '' : ',') . json_encode($key) . ":" . json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
if (isset($event['errors'])) {
|
||||
|
|
|
@ -729,14 +729,14 @@ class SendEmail
|
|||
}
|
||||
|
||||
list($inputFile, $outputFile) = $this->createInputOutputFiles($body);
|
||||
$result = openssl_pkcs7_sign($inputFile->pwd(), $outputFile->pwd(), $certPublicSign, $keySign, array(), 0);
|
||||
$result = openssl_pkcs7_sign($inputFile->pwd(), $outputFile->pwd(), $certPublicSign, $keySign, array(), PKCS7_DETACHED);
|
||||
$inputFile->delete();
|
||||
|
||||
if ($result) {
|
||||
$data = $outputFile->read();
|
||||
$outputFile->delete();
|
||||
$parts = explode("\n\n", $data);
|
||||
return $parts[1] . "\n";
|
||||
return $parts[4] . "\n";
|
||||
|
||||
} else {
|
||||
$outputFile->delete();
|
||||
|
|
|
@ -14,7 +14,7 @@ class TmpFileTool
|
|||
public function __construct($maxInMemory = null)
|
||||
{
|
||||
if ($maxInMemory === null) {
|
||||
$maxInMemory = 2 * 1024 * 1024;
|
||||
$maxInMemory = 5 * 1024 * 1024;
|
||||
}
|
||||
$this->tmpfile = fopen("php://temp/maxmemory:$maxInMemory", "w+");
|
||||
if ($this->tmpfile === false) {
|
||||
|
|
|
@ -198,13 +198,18 @@ class XMLConverterTool
|
|||
$field = str_replace($this->__toEscape, $this->__escapeWith, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
* @param false $mispVersion
|
||||
* @return Generator
|
||||
*/
|
||||
public function frameCollection($input, $mispVersion = false)
|
||||
{
|
||||
$result = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>' . PHP_EOL;
|
||||
$result .= $input;
|
||||
yield '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . '<response>' . PHP_EOL;
|
||||
yield $input . PHP_EOL;
|
||||
if ($mispVersion) {
|
||||
$result .= '<xml_version>' . $mispVersion . '</xml_version>';
|
||||
yield '<xml_version>' . $mispVersion . '</xml_version>';
|
||||
}
|
||||
return $result . '</response>' . PHP_EOL;
|
||||
yield '</response>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d0c51b37422d0d2c99be74045d4439a674259308
|
||||
Subproject commit cf14e6546ec44e3369e3531add11fdb946656280
|
|
@ -4100,11 +4100,11 @@ msgid "Click this to download all network related attributes that you have acces
|
|||
msgstr ""
|
||||
|
||||
#: Model/Event.php:446
|
||||
msgid "Click this to download an a STIX document containing the STIX version of all events and attributes that you have access to."
|
||||
msgid "Click this to download a STIX document containing the STIX version of all events and attributes that you have access to."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:454
|
||||
msgid "Click this to download an a STIX2 document containing the STIX2 version of all events and attributes that you have access to."
|
||||
msgid "Click this to download a STIX2 document containing the STIX2 version of all events and attributes that you have access to."
|
||||
msgstr ""
|
||||
|
||||
#: Model/Event.php:462
|
||||
|
|
|
@ -12,6 +12,7 @@ App::uses('ComplexTypeTool', 'Tools');
|
|||
/**
|
||||
* @property Event $Event
|
||||
* @property AttributeTag $AttributeTag
|
||||
* @property Sighting $Sighting
|
||||
* @property-read array $typeDefinitions
|
||||
* @property-read array $categoryDefinitions
|
||||
*/
|
||||
|
@ -62,6 +63,7 @@ class Attribute extends AppModel
|
|||
|
||||
public $shortDist = array(0 => 'Organisation', 1 => 'Community', 2 => 'Connected', 3 => 'All', 4 => ' Sharing Group', 5 => 'Inherit');
|
||||
|
||||
private $exclusions = null;
|
||||
|
||||
public function __construct($id = false, $table = null, $ds = null)
|
||||
{
|
||||
|
@ -202,17 +204,17 @@ class Attribute extends AppModel
|
|||
'stringNotEmpty' => array(
|
||||
'rule' => array('stringNotEmpty')
|
||||
),
|
||||
'validComposite' => array(
|
||||
'rule' => array('validComposite'),
|
||||
'message' => 'Composite type found but the value not in the composite (value1|value2) format.'
|
||||
),
|
||||
'userdefined' => array(
|
||||
'rule' => array('validateAttributeValue'),
|
||||
'message' => 'Value not in the right type/format. Please double check the value or select type "other".'
|
||||
),
|
||||
'uniqueValue' => array(
|
||||
'rule' => array('valueIsUnique'),
|
||||
'message' => 'A similar attribute already exists for this event.'
|
||||
),
|
||||
'validComposite' => array(
|
||||
'rule' => array('validComposite'),
|
||||
'message' => 'Composite type found but the value not in the composite (value1|value2) format.'
|
||||
'rule' => array('valueIsUnique'),
|
||||
'message' => 'A similar attribute already exists for this event.'
|
||||
),
|
||||
'maxTextLength' => array(
|
||||
'rule' => array('maxTextLength')
|
||||
|
@ -602,7 +604,7 @@ class Attribute extends AppModel
|
|||
public function validComposite($fields)
|
||||
{
|
||||
$compositeTypes = $this->getCompositeTypes();
|
||||
if (in_array($this->data['Attribute']['type'], $compositeTypes)) {
|
||||
if (in_array($this->data['Attribute']['type'], $compositeTypes, true)) {
|
||||
if (substr_count($fields['value'], '|') !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1575,7 +1577,7 @@ class Attribute extends AppModel
|
|||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function resizeImage($data, $maxWidth, $maxHeight)
|
||||
public function resizeImage($data, $maxWidth, $maxHeight)
|
||||
{
|
||||
$image = imagecreatefromstring($data);
|
||||
if ($image === false) {
|
||||
|
@ -1764,15 +1766,12 @@ class Attribute extends AppModel
|
|||
if (!empty($a['value2'])) {
|
||||
$value .= '|' . $a['value2'];
|
||||
}
|
||||
if (empty($this->exclusions)) {
|
||||
if ($this->exclusions === null) {
|
||||
try {
|
||||
$redis = $this->setupRedisWithException();
|
||||
} catch (Exception $e) {
|
||||
$redisFail = true;
|
||||
}
|
||||
if (empty($redisFail)) {
|
||||
$this->Correlation = ClassRegistry::init('Correlation');
|
||||
$this->exclusions = $redis->sMembers('misp:correlation_exclusions');
|
||||
} catch (Exception $e) {
|
||||
$this->exclusions = [];
|
||||
}
|
||||
}
|
||||
foreach ($this->exclusions as $exclusion) {
|
||||
|
@ -1809,11 +1808,11 @@ class Attribute extends AppModel
|
|||
if (!empty($a['disable_correlation']) || Configure::read('MISP.completely_disable_correlation')) {
|
||||
return true;
|
||||
}
|
||||
if ($this->__preventExcludedCorrelations($a)) {
|
||||
// Don't do any correlation if the type is a non correlating type
|
||||
if (in_array($a['type'], $this->nonCorrelatingTypes, true)) {
|
||||
return true;
|
||||
}
|
||||
// Don't do any correlation if the type is a non correlating type
|
||||
if (in_array($a['type'], $this->nonCorrelatingTypes)) {
|
||||
if ($this->__preventExcludedCorrelations($a)) {
|
||||
return true;
|
||||
}
|
||||
if (!$event) {
|
||||
|
@ -2542,7 +2541,6 @@ class Attribute extends AppModel
|
|||
'recursive' => -1, // int
|
||||
'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,
|
||||
'flatten' => 1
|
||||
)
|
||||
|
@ -2944,9 +2942,7 @@ class Attribute extends AppModel
|
|||
if (!empty($attribute)) {
|
||||
if (!empty($attribute['AttributeTag'])) {
|
||||
foreach ($attribute['AttributeTag'] as $at) {
|
||||
if ($at['Tag']['exportable']) {
|
||||
$attribute['Attribute']['Tag'][] = $at['Tag'];
|
||||
}
|
||||
$attribute['Attribute']['Tag'][] = $at['Tag'];
|
||||
}
|
||||
}
|
||||
unset($attribute['AttributeTag']);
|
||||
|
@ -3092,7 +3088,7 @@ class Attribute extends AppModel
|
|||
$params['conditions']['AND'][] = $options['conditions'];
|
||||
}
|
||||
if (empty($options['flatten'])) {
|
||||
$params['conditions']['AND'][] = array('(Attribute.object_id + 0)' => 0);
|
||||
$params['conditions']['AND'][] = array('Attribute.object_id' => 0);
|
||||
}
|
||||
if (isset($options['order'])) {
|
||||
$params['order'] = $options['order'];
|
||||
|
@ -3127,7 +3123,7 @@ class Attribute extends AppModel
|
|||
$options['includeEventTags'] = true;
|
||||
}
|
||||
if (!$user['Role']['perm_sync'] || !isset($options['deleted']) || !$options['deleted']) {
|
||||
$params['conditions']['AND']['(Attribute.deleted + 0)'] = 0;
|
||||
$params['conditions']['AND']['Attribute.deleted'] = 0;
|
||||
} else {
|
||||
if ($options['deleted'] === "only") {
|
||||
$options['deleted'] = 1;
|
||||
|
@ -3979,7 +3975,7 @@ class Attribute extends AppModel
|
|||
}
|
||||
}
|
||||
if (!empty($attribute['Sighting'])) {
|
||||
$this->Sighting->captureSighting($attribute['Sighting'], $this->id, $eventId, $user);
|
||||
$this->Sighting->captureSightings($attribute['Sighting'], $this->id, $eventId, $user);
|
||||
}
|
||||
}
|
||||
if (!empty($this->validationErrors)) {
|
||||
|
|
|
@ -3,6 +3,7 @@ App::uses('AppModel', 'Model');
|
|||
|
||||
/**
|
||||
* @property Tag $Tag
|
||||
* @property Attribute $Attribute
|
||||
*/
|
||||
class AttributeTag extends AppModel
|
||||
{
|
||||
|
|
|
@ -34,9 +34,8 @@ class CorrelationExclusion extends AppModel
|
|||
return false;
|
||||
}
|
||||
$redis->del($this->key);
|
||||
$exclusions = $this->find('list', [
|
||||
'recursive' => -1,
|
||||
'fields' => ['id', 'value']
|
||||
$exclusions = $this->find('column', [
|
||||
'fields' => ['value']
|
||||
]);
|
||||
$redis->sAddArray($this->key, $exclusions);
|
||||
}
|
||||
|
@ -85,6 +84,7 @@ class CorrelationExclusion extends AppModel
|
|||
$this->Job = ClassRegistry::init('Job');
|
||||
$this->Job->id = $jobId;
|
||||
}
|
||||
$total = count($exclusions);
|
||||
foreach ($exclusions as $exclusion_chunk) {
|
||||
$i = 0;
|
||||
foreach ($exclusion_chunk as $exclusion) {
|
||||
|
|
|
@ -340,7 +340,7 @@ class Event extends AppModel
|
|||
'scope' => 'Event',
|
||||
'requiresPublished' => 1,
|
||||
'params' => array('returnFormat' => 'stix', 'includeAttachments' => 1),
|
||||
'description' => __('Click this to download an a STIX document containing the STIX version of all events and attributes that you have access to.')
|
||||
'description' => __('Click this to download a STIX document containing the STIX version of all events and attributes that you have access to.')
|
||||
),
|
||||
'stix2' => array(
|
||||
'extension' => '.json',
|
||||
|
@ -348,7 +348,7 @@ class Event extends AppModel
|
|||
'scope' => 'Event',
|
||||
'requiresPublished' => 1,
|
||||
'params' => array('returnFormat' => 'stix2', 'includeAttachments' => 1),
|
||||
'description' => __('Click this to download an a STIX2 document containing the STIX2 version of all events and attributes that you have access to.')
|
||||
'description' => __('Click this to download a STIX2 document containing the STIX2 version of all events and attributes that you have access to.')
|
||||
),
|
||||
'rpz' => array(
|
||||
'extension' => '.txt',
|
||||
|
@ -1325,7 +1325,7 @@ class Event extends AppModel
|
|||
if (!$eventReportSupportedByRemote) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
// Downgrade the object from connected communities to community only
|
||||
if (!$server['Server']['internal'] && $report['distribution'] == 2) {
|
||||
$report['distribution'] = 1;
|
||||
|
@ -1571,6 +1571,12 @@ class Event extends AppModel
|
|||
return $tempConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $user
|
||||
* @param array $params
|
||||
* @param int $result_count
|
||||
* @return array Event IDs, when `include_attribute_count` is enabled, then it is Event ID => Attribute count
|
||||
*/
|
||||
public function filterEventIds($user, &$params = array(), &$result_count = 0)
|
||||
{
|
||||
$conditions = $this->createEventConditions($user);
|
||||
|
@ -1654,14 +1660,9 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
$fields = array('Event.id');
|
||||
if (!empty($params['include_attribute_count'])) {
|
||||
$fields[] = 'Event.attribute_count';
|
||||
}
|
||||
$find_params = array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
'fields' => $fields
|
||||
);
|
||||
if (isset($params['order'])) {
|
||||
$find_params['order'] = $params['order'];
|
||||
|
@ -1674,7 +1675,13 @@ class Event extends AppModel
|
|||
$find_params['page'] = $params['page'];
|
||||
}
|
||||
}
|
||||
$results = $this->find('list', $find_params);
|
||||
if (!empty($params['include_attribute_count'])) {
|
||||
$find_params['fields'] = array('Event.id', 'Event.attribute_count');
|
||||
$results = $this->find('list', $find_params);
|
||||
} else {
|
||||
$find_params['fields'] = array('Event.id');
|
||||
$results = $this->find('column', $find_params);
|
||||
}
|
||||
if (!isset($params['limit'])) {
|
||||
$result_count = count($results);
|
||||
}
|
||||
|
@ -1845,7 +1852,10 @@ class Event extends AppModel
|
|||
'includeServerCorrelations',
|
||||
'includeWarninglistHits',
|
||||
'noEventReports', // do not include event report in event data
|
||||
'noShadowAttributes', // do not fetch proposals
|
||||
'noShadowAttributes', // do not fetch proposals,
|
||||
'limit',
|
||||
'page',
|
||||
'order'
|
||||
);
|
||||
if (!isset($options['excludeLocalTags']) && !empty($user['Role']['perm_sync']) && empty($user['Role']['perm_site_admin'])) {
|
||||
$options['excludeLocalTags'] = 1;
|
||||
|
@ -2130,6 +2140,15 @@ class Event extends AppModel
|
|||
unset($params['contain']['Object']);
|
||||
unset($params['contain']['EventReport']);
|
||||
}
|
||||
if (!empty($options['limit'])) {
|
||||
$params['limit'] = $options['limit'];
|
||||
}
|
||||
if (!empty($options['page'])) {
|
||||
$params['page'] = $options['page'];
|
||||
}
|
||||
if (!empty($options['order'])) {
|
||||
$params['order'] = $options['order'];
|
||||
}
|
||||
$results = $this->find('all', $params);
|
||||
if (empty($results)) {
|
||||
return array();
|
||||
|
@ -3085,16 +3104,18 @@ class Event extends AppModel
|
|||
$userCount = count($usersWithAccess);
|
||||
$this->UserSetting = ClassRegistry::init('UserSetting');
|
||||
foreach ($usersWithAccess as $k => $user) {
|
||||
if ($this->UserSetting->checkPublishFilter($user, $event)) {
|
||||
// Fetch event for user that will receive alert e-mail to respect all ACLs
|
||||
$eventForUser = $this->fetchEvent($user, [
|
||||
'eventid' => $id,
|
||||
'includeAllTags' => true,
|
||||
'includeEventCorrelations' => true,
|
||||
])[0];
|
||||
// Fetch event for user that will receive alert e-mail to respect all ACLs
|
||||
$eventForUser = $this->fetchEvent($user, [
|
||||
'eventid' => $id,
|
||||
'includeAllTags' => true,
|
||||
'includeEventCorrelations' => true,
|
||||
'noEventReports' => true,
|
||||
'noSightings' => true,
|
||||
])[0];
|
||||
|
||||
if ($this->UserSetting->checkPublishFilter($user, $eventForUser)) {
|
||||
$body = $this->__buildAlertEmailBody($eventForUser, $user, $oldpublish);
|
||||
$this->User->sendEmail(array('User' => $user), $body, $bodyNoEnc, $subject);
|
||||
$this->User->sendEmail(['User' => $user], $body, $bodyNoEnc, $subject);
|
||||
}
|
||||
if ($jobId) {
|
||||
$this->Job->saveProgress($jobId, null, $k / $userCount * 100);
|
||||
|
@ -3631,6 +3652,7 @@ class Event extends AppModel
|
|||
if (!$this->checkEventBlockRules($data)) {
|
||||
return 'Blocked by event block rules';
|
||||
}
|
||||
$breakOnDuplicate = !empty($data['Event']['breakOnDuplicate']);
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
if (empty($data['Event']['Attribute']) && empty($data['Event']['Object']) && !empty($data['Event']['published']) && empty($data['Event']['EventReport'])) {
|
||||
$this->Log->create();
|
||||
|
@ -3853,8 +3875,9 @@ class Event extends AppModel
|
|||
}
|
||||
$referencesToCapture = array();
|
||||
if (!empty($data['Event']['Object'])) {
|
||||
foreach ($data['Event']['Object'] as $object) {
|
||||
$result = $this->Object->captureObject($object, $this->id, $user, $this->Log, false);
|
||||
$objectDuplicateCache = [];
|
||||
foreach ($data['Event']['Object'] as $k => $object) {
|
||||
$result = $this->Object->captureObject($object, $this->id, $user, $this->Log, false, $breakOnDuplicate);
|
||||
}
|
||||
foreach ($data['Event']['Object'] as $object) {
|
||||
if (isset($object['ObjectReference'])) {
|
||||
|
@ -5583,6 +5606,9 @@ class Event extends AppModel
|
|||
}
|
||||
$event['Object'] = $objects;
|
||||
}
|
||||
if (!empty($result['results']['EventReport'])) {
|
||||
$event['EventReport'] = $result['results']['EventReport'];
|
||||
}
|
||||
foreach (array('Tag', 'Galaxy') as $field) {
|
||||
if (!empty($result['results'][$field])) {
|
||||
$event[$field] = $result['results'][$field];
|
||||
|
@ -5620,30 +5646,38 @@ class Event extends AppModel
|
|||
return $attribute;
|
||||
}
|
||||
|
||||
public function export($user = false, $module = false, $options = array())
|
||||
/**
|
||||
* @param array $user
|
||||
* @param string $module
|
||||
* @param array $options
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function export(array $user, $module, array $options = array())
|
||||
{
|
||||
if (empty($user)) {
|
||||
return 'Invalid user.';
|
||||
}
|
||||
if (empty($module)) {
|
||||
return 'Invalid module.';
|
||||
throw new InvalidArgumentException('Invalid module.');
|
||||
}
|
||||
$this->Module = ClassRegistry::init('Module');
|
||||
$module = $this->Module->getEnabledModule($module, 'Export');
|
||||
if (!is_array($module)) {
|
||||
throw new NotFoundException('Invalid module.');
|
||||
}
|
||||
// Export module can specify additional options for event fetch
|
||||
if (isset($module['meta']['fetch_options'])) {
|
||||
$options = array_merge($options, $module['meta']['fetch_options']);
|
||||
}
|
||||
$events = $this->fetchEvent($user, $options);
|
||||
if (empty($events)) {
|
||||
return 'Invalid event.';
|
||||
throw new NotFoundException('Invalid event.');
|
||||
}
|
||||
$standard_format = false;
|
||||
$modulePayload = array('module' => $module['name']);
|
||||
if (!empty($module['meta']['require_standard_format'])) {
|
||||
$standard_format = true;
|
||||
}
|
||||
if (isset($module['meta']['config'])) {
|
||||
foreach ($module['meta']['config'] as $conf) {
|
||||
$modulePayload['config'][$conf] = Configure::read('Plugin.Export_' . $module['name'] . '_' . $conf);
|
||||
}
|
||||
}
|
||||
$standard_format = !empty($module['meta']['require_standard_format']);
|
||||
if ($standard_format) {
|
||||
App::uses('JSONConverterTool', 'Tools');
|
||||
$converter = new JSONConverterTool();
|
||||
|
@ -5653,11 +5687,11 @@ class Event extends AppModel
|
|||
}
|
||||
$modulePayload['data'] = $events;
|
||||
$result = $this->Module->queryModuleServer($modulePayload, false, 'Export');
|
||||
return array(
|
||||
'data' => $result['data'],
|
||||
'extension' => $module['mispattributes']['outputFileExtension'],
|
||||
'response' => $module['mispattributes']['responseType']
|
||||
);
|
||||
return [
|
||||
'data' => $result['data'],
|
||||
'extension' => $module['mispattributes']['outputFileExtension'],
|
||||
'response' => $module['mispattributes']['responseType']
|
||||
];
|
||||
}
|
||||
|
||||
public function cacheSgids($user, $useCache = false)
|
||||
|
@ -6209,12 +6243,12 @@ class Event extends AppModel
|
|||
$this->Job->id = $jobId;
|
||||
|
||||
}
|
||||
$failed_attributes = $failed_objects = $failed_object_attributes = 0;
|
||||
$saved_attributes = $saved_objects = $saved_object_attributes = 0;
|
||||
$failed_attributes = $failed_objects = $failed_object_attributes = $failed_reports = 0;
|
||||
$saved_attributes = $saved_objects = $saved_object_attributes = $saved_reports = 0;
|
||||
$items_count = 0;
|
||||
$failed = array();
|
||||
$recovered_uuids = array();
|
||||
foreach (array('Attribute', 'Object') as $feature) {
|
||||
foreach (array('Attribute', 'Object', 'EventReport') as $feature) {
|
||||
if (isset($resolved_data[$feature])) {
|
||||
$items_count += count($resolved_data[$feature]);
|
||||
}
|
||||
|
@ -6430,7 +6464,27 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
if ($saved_attributes > 0 || $saved_objects > 0) {
|
||||
if (!empty($resolved_data['EventReport'])) {
|
||||
$total_reports = count($resolved_data['EventReport']);
|
||||
foreach ($resolved_data['EventReport'] as $i => $report) {
|
||||
$this->EventReport->create();
|
||||
$report['event_id'] = $id;
|
||||
if ($this->EventReport->save($report)) {
|
||||
$saved_reports++;
|
||||
} else {
|
||||
$failed_reports++;
|
||||
$lastReportError = $this->EventReport->validationErrors;
|
||||
}
|
||||
if ($jobId) {
|
||||
$current = ($i + 1);
|
||||
$this->Job->saveField('message', 'EventReport ' . $current . '/' . $total_reports);
|
||||
$this->Job->saveField('progress', ($current * 100 / $items_count));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$total_reports = 0;
|
||||
}
|
||||
if ($saved_attributes > 0 || $saved_objects > 0 || $saved_reports > 0) {
|
||||
$event = $this->find('first', array(
|
||||
'conditions' => array('Event.id' => $id),
|
||||
'recursive' => -1
|
||||
|
@ -6443,7 +6497,7 @@ class Event extends AppModel
|
|||
$this->save($event);
|
||||
}
|
||||
if ($event_level) {
|
||||
return $saved_attributes + $saved_object_attributes;
|
||||
return $saved_attributes + $saved_object_attributes + $saved_reports;
|
||||
}
|
||||
$message = '';
|
||||
if ($saved_attributes > 0) {
|
||||
|
@ -6489,6 +6543,17 @@ class Event extends AppModel
|
|||
}
|
||||
$message .= 'you can have a look at the module results view you just left, to compare.';
|
||||
}
|
||||
if ($saved_reports > 0) {
|
||||
$message .= $saved_reports . ' ' . $this->__apply_inflector($saved_reports, 'eventReport') . ' created. ';
|
||||
}
|
||||
if ($failed_reports > 0) {
|
||||
if ($failed_reports == 1) {
|
||||
$reason = ' eventReport could not be saved. Reason for the failure: ' . json_encode($lastReportError) . ' ';
|
||||
} else {
|
||||
$reason = ' eventReport could not be saved. ';
|
||||
}
|
||||
$message .= $failed_reports . $reason;
|
||||
}
|
||||
if ($jobId) {
|
||||
$this->Job->saveField('message', 'Processing complete. ' . $message);
|
||||
$this->Job->saveField('progress', 100);
|
||||
|
@ -6934,7 +6999,7 @@ class Event extends AppModel
|
|||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'title' => sprintf('Event fetch potential memory exhaustion. During the fetching of events, a large event (#%s) was detected that exceeds the available PHP memory. Consider raising the PHP max_memory setting to at least %sM', $largest_event_id, ceil($largest_event/$memory_scaling_factor)),
|
||||
'title' => sprintf('Event fetch potential memory exhaustion.' . PHP_EOL . 'During the fetching of events, a large event (#%s) was detected that exceeds the available PHP memory.' . PHP_EOL . 'Consider raising the PHP max_memory setting to at least %sM', $largest_event_id, ceil($largest_event/$memory_scaling_factor)),
|
||||
'change' => null,
|
||||
));
|
||||
}
|
||||
|
@ -7118,7 +7183,7 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* extractAllTagNames Returns all tag names attached to any elements in an event
|
||||
*
|
||||
|
|
|
@ -103,6 +103,9 @@ class EventReport extends AppModel
|
|||
$report = ['EventReport' => $report];
|
||||
}
|
||||
$report['EventReport']['event_id'] = $eventId;
|
||||
if (!empty($report['EventReport']['id'])) {
|
||||
unset($report['EventReport']['id']);
|
||||
}
|
||||
$report = $this->captureSG($user, $report);
|
||||
$this->create();
|
||||
$errors = $this->saveAndReturnErrors($report, ['fieldList' => $this->captureFields]);
|
||||
|
@ -114,7 +117,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* addReport Add a report
|
||||
*
|
||||
|
@ -131,7 +134,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* editReport Edit a report
|
||||
*
|
||||
|
@ -208,7 +211,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* restoreReport ACL-aware method to restore a report.
|
||||
*
|
||||
|
@ -235,7 +238,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return $report;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* buildACLConditions Generate ACL conditions for viewing the report
|
||||
*
|
||||
|
@ -299,7 +302,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fetchReports ACL-aware method. Basically find with ACL
|
||||
*
|
||||
|
@ -391,7 +394,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function reArrangeReport(array $report)
|
||||
{
|
||||
$rearrangeObjects = array('Event', 'SharingGroup');
|
||||
|
@ -548,7 +551,7 @@ class EventReport extends AppModel
|
|||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
public function applySuggestionsInText($contentWithSuggestions, array $attribute, $value)
|
||||
{
|
||||
$textToBeReplaced = "@[suggestion]($value)";
|
||||
|
@ -592,7 +595,7 @@ class EventReport extends AppModel
|
|||
'attribute' => $savedAttribute
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* transformFreeTextIntoReplacement
|
||||
*
|
||||
|
@ -704,7 +707,7 @@ class EventReport extends AppModel
|
|||
'replacementResult' => $replacementResult,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* extractWithReplacements Extract context information from report with special care for ATT&CK
|
||||
*
|
||||
|
|
|
@ -32,7 +32,10 @@ class Feed extends AppModel
|
|||
'rule' => array('urlOrExistingFilepath')
|
||||
),
|
||||
'provider' => 'valueNotEmpty',
|
||||
'name' => 'valueNotEmpty',
|
||||
'name' => [
|
||||
'rule' => 'valueNotEmpty',
|
||||
'required' => true,
|
||||
],
|
||||
'event_id' => array(
|
||||
'rule' => array('numeric'),
|
||||
'message' => 'Please enter a numeric event ID or leave this field blank.',
|
||||
|
@ -1469,7 +1472,7 @@ class Feed extends AppModel
|
|||
}
|
||||
}
|
||||
$this->create();
|
||||
if (!$this->save($feed, true, array('name', 'provider', 'url', 'rules', 'source_format', 'fixed_event', 'delta_merge', 'override_ids', 'publish', 'settings', 'tag_id', 'default', 'lookup_visible'))) {
|
||||
if (!$this->save($feed, true, array('name', 'provider', 'url', 'rules', 'source_format', 'fixed_event', 'delta_merge', 'override_ids', 'publish', 'settings', 'tag_id', 'default', 'lookup_visible', 'headers'))) {
|
||||
$results['fails']++;
|
||||
} else {
|
||||
$results['successes']++;
|
||||
|
|
|
@ -377,12 +377,23 @@ class Galaxy extends AppModel
|
|||
$result = $this->Tag->$connectorModel->save($toSave);
|
||||
if ($result) {
|
||||
if ($target_type !== 'tag_collection') {
|
||||
$date = new DateTime();
|
||||
if ($target_type === 'event') {
|
||||
$event = $target;
|
||||
} else if ($target_type === 'attribute') {
|
||||
$target['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
$this->Tag->AttributeTag->Attribute->save($target);
|
||||
if (!empty($target['Attribute']['object_id'])) {
|
||||
$container_object = $this->Tag->AttributeTag->Attribute->Object->find('first', [
|
||||
'recursive' => -1,
|
||||
'conditions' => ['id' => $target['Attribute']['object_id']]
|
||||
]);
|
||||
$container_object['Object']['timestamp'] = $date->getTimestamp();
|
||||
$this->Tag->AttributeTag->Attribute->Object->save($container_object);
|
||||
}
|
||||
}
|
||||
$this->Tag->EventTag->Event->insertLock($user, $event['Event']['id']);
|
||||
$event['Event']['published'] = 0;
|
||||
$date = new DateTime();
|
||||
$event['Event']['timestamp'] = $date->getTimestamp();
|
||||
$this->Tag->EventTag->Event->save($event);
|
||||
}
|
||||
|
|
|
@ -415,7 +415,7 @@ class GalaxyCluster extends AppModel
|
|||
}
|
||||
$saveSuccess = $this->save($cluster, array('fieldList' => $fieldList));
|
||||
if ($saveSuccess) {
|
||||
if (!empty($cluster['GalaxyCluster']['GalaxyElement'])) {
|
||||
if (isset($cluster['GalaxyCluster']['GalaxyElement'])) {
|
||||
$elementsToSave = array();
|
||||
foreach ($cluster['GalaxyCluster']['GalaxyElement'] as $element) { // transform cluster into Galaxy meta format
|
||||
$elementsToSave[$element['key']][] = $element['value'];
|
||||
|
@ -870,25 +870,23 @@ class GalaxyCluster extends AppModel
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|int $name Cluster name or ID
|
||||
* @param array $user
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getCluster($name, $user)
|
||||
{
|
||||
$isGalaxyTag = strpos($name, 'misp-galaxy:') === 0;
|
||||
if (!$isGalaxyTag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($this->__clusterCache[$name])) {
|
||||
return $this->__clusterCache[$name];
|
||||
}
|
||||
$conditions = array();
|
||||
if (is_numeric($name)) {
|
||||
$conditions[] = array('GalaxyCluster.id' => $name);
|
||||
$conditions = array('GalaxyCluster.id' => $name);
|
||||
} else {
|
||||
$conditions[] = array('LOWER(GalaxyCluster.tag_name)' => strtolower($name));
|
||||
$isGalaxyTag = strpos($name, 'misp-galaxy:') === 0;
|
||||
if (!$isGalaxyTag) {
|
||||
return null;
|
||||
}
|
||||
$conditions = array('LOWER(GalaxyCluster.tag_name)' => strtolower($name));
|
||||
}
|
||||
$cluster = $this->fetchGalaxyClusters($user, array(
|
||||
'conditions' => $conditions,
|
||||
|
|
|
@ -128,4 +128,14 @@ class GalaxyElement extends AppModel
|
|||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
public function getExpandedJSONFromElements($elements)
|
||||
{
|
||||
$keyedValue = [];
|
||||
foreach ($elements as $i => $element) {
|
||||
$keyedValue[$element['GalaxyElement']['key']][] = $element['GalaxyElement']['value'];
|
||||
}
|
||||
$expanded = Hash::expand($keyedValue);
|
||||
return $expanded;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -321,6 +321,17 @@ class MispObject extends AppModel
|
|||
);
|
||||
}
|
||||
$newObjectAttributeCount = count($newObjectAttributes);
|
||||
if (!empty($this->__objectDuplicationCheckCache['new'][$object['Object']['template_uuid']])) {
|
||||
foreach ($this->__objectDuplicationCheckCache['new'][$object['Object']['template_uuid']] as $previousNewObject) {
|
||||
if ($newObjectAttributeCount === count($previousNewObject)) {
|
||||
if (empty(array_diff($previousNewObject, $newObjectAttributes))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->__objectDuplicationCheckCache['new'][$object['Object']['template_uuid']][] = $newObjectAttributes;
|
||||
|
||||
if (!isset($this->__objectDuplicationCheckCache[$object['Object']['template_uuid']])) {
|
||||
$this->__objectDuplicationCheckCache[$object['Object']['template_uuid']] = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
|
@ -892,13 +903,13 @@ class MispObject extends AppModel
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
public function captureObject($object, $eventId, $user, $log = false, $unpublish = true)
|
||||
public function captureObject($object, $eventId, $user, $log = false, $unpublish = true, $breakOnDuplicate = false)
|
||||
{
|
||||
$this->create();
|
||||
if (!isset($object['Object'])) {
|
||||
$object = array('Object' => $object);
|
||||
}
|
||||
if (!empty($object['Object']['breakOnDuplicate'])) {
|
||||
if (!empty($object['Object']['breakOnDuplicate']) || $breakOnDuplicate) {
|
||||
$duplicate = $this->checkForDuplicateObjects($object, $eventId);
|
||||
if ($duplicate) {
|
||||
$log->create();
|
||||
|
@ -912,8 +923,8 @@ class MispObject extends AppModel
|
|||
'title' => 'Object dropped due to it being a duplicate and breakOnDuplicate being requested for Event ' . $eventId,
|
||||
'change' => 'Duplicate object found.',
|
||||
));
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (empty($log)) {
|
||||
$log = ClassRegistry::init('Log');
|
||||
|
|
|
@ -31,6 +31,8 @@ class ObjectTemplate extends AppModel
|
|||
public $validate = array(
|
||||
);
|
||||
|
||||
public $objectsDir = APP . 'files/misp-objects/objects';
|
||||
|
||||
public function afterFind($results, $primary = false)
|
||||
{
|
||||
foreach ($results as $k => $result) {
|
||||
|
@ -49,10 +51,9 @@ class ObjectTemplate extends AppModel
|
|||
|
||||
public function update($user = false, $type = false, $force = false)
|
||||
{
|
||||
$objectsDir = APP . 'files/misp-objects/objects';
|
||||
$directories = glob($objectsDir . '/*', GLOB_ONLYDIR);
|
||||
$directories = $this->getTemplateDirectoryPaths();
|
||||
foreach ($directories as $k => $dir) {
|
||||
$dir = str_replace($objectsDir, '', $dir);
|
||||
$dir = str_replace($this->objectsDir, '', $dir);
|
||||
$directories[$k] = $dir;
|
||||
}
|
||||
$updated = array();
|
||||
|
@ -60,10 +61,10 @@ class ObjectTemplate extends AppModel
|
|||
if ($type && '/' . $type != $dir) {
|
||||
continue;
|
||||
}
|
||||
if (!file_exists($objectsDir . DS . $dir . DS . 'definition.json')) {
|
||||
if (!file_exists($this->objectsDir . DS . $dir . DS . 'definition.json')) {
|
||||
continue;
|
||||
}
|
||||
$file = new File($objectsDir . DS . $dir . DS . 'definition.json');
|
||||
$file = new File($this->objectsDir . DS . $dir . DS . 'definition.json');
|
||||
$template = json_decode($file->read(), true);
|
||||
$file->close();
|
||||
if (!isset($template['version'])) {
|
||||
|
@ -316,4 +317,56 @@ class ObjectTemplate extends AppModel
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getRawFromDisk($uuidOrName)
|
||||
{
|
||||
$template = [];
|
||||
if (Validation::uuid($uuidOrName)) {
|
||||
foreach ($this->readTemplatesFromDisk() as $templateFromDisk) {
|
||||
if ($templateFromDisk['uuid'] == $uuidOrName) {
|
||||
$template = $templateFromDisk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$allTemplateNames = $this->getTemplateDirectoryPaths(false);
|
||||
if (in_array($uuidOrName, $allTemplateNames)) { // ensure the path is not out of scope
|
||||
$template = $this->readTemplateFromDisk($this->getFullPathFromTemplateName($uuidOrName));
|
||||
}
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
private function readTemplateFromDisk($path)
|
||||
{
|
||||
$file = new File($path, false);
|
||||
if (!$file->exists()) {
|
||||
return false;
|
||||
}
|
||||
$template = json_decode($file->read(), true);
|
||||
$file->close();
|
||||
return $template;
|
||||
}
|
||||
|
||||
private function readTemplatesFromDisk()
|
||||
{
|
||||
foreach ($this->getTemplateDirectoryPaths() as $dirpath) {
|
||||
$filepath = $dirpath . DS . 'definition.json';
|
||||
$template = $this->readTemplateFromDisk($filepath);
|
||||
if (isset($template['uuid'])) {
|
||||
yield $template;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getTemplateDirectoryPaths($fullPath=true)
|
||||
{
|
||||
$dir = new Folder($this->objectsDir, false);
|
||||
return $dir->read(true, false, $fullPath)[0];
|
||||
}
|
||||
|
||||
private function getFullPathFromTemplateName($templateName)
|
||||
{
|
||||
return $this->objectsDir . DS . $templateName . DS . 'definition.json';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -596,7 +596,8 @@ class Organisation extends AppModel
|
|||
{
|
||||
$countries = array_column($this->getCountryGalaxyCluster(), 'description');
|
||||
sort($countries);
|
||||
array_unshift($countries, 'Internation');
|
||||
array_unshift($countries, 'International');
|
||||
array_unshift($countries, 'Europe');
|
||||
return $countries;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3435,6 +3435,32 @@ class Server extends AppModel
|
|||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return PHP setting in basic unit (bytes).
|
||||
* @param string $setting
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function getIniSetting($setting)
|
||||
{
|
||||
$value = ini_get($setting);
|
||||
if ($value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch ($setting) {
|
||||
case 'memory_limit':
|
||||
case 'upload_max_filesize':
|
||||
case 'post_max_size':
|
||||
return (int)preg_replace_callback('/(-?\d+)(.?)/', function ($m) {
|
||||
return $m[1] * pow(1024, strpos('BKMG', $m[2]));
|
||||
}, strtoupper($value));
|
||||
case 'max_execution_time':
|
||||
return (int)$value;
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function killWorker($pid, $user)
|
||||
{
|
||||
if (!is_numeric($pid)) {
|
||||
|
@ -5416,7 +5442,7 @@ class Server extends AppModel
|
|||
),
|
||||
'obscure_subject' => array(
|
||||
'level' => 2,
|
||||
'description' => __('When enabled, subject in signed and encrypted e-mails will not send in unencrypted form.'),
|
||||
'description' => __('When enabled, the subject in signed and encrypted e-mails will not be sent in unencrypted form.'),
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
|
@ -5516,7 +5542,7 @@ class Server extends AppModel
|
|||
'level' => 0,
|
||||
'description' => __('Disabling this setting will remove all form tampering protection. Do not set this setting pretty much ever. You were warned.'),
|
||||
'value' => false,
|
||||
'errorMessage' => 'This setting leaves your users open to CSRF attacks. Do not please consider disabling this setting.',
|
||||
'errorMessage' => 'This setting leaves your users open to CSRF attacks. Please consider disabling this setting.',
|
||||
'test' => 'testBoolFalse',
|
||||
'type' => 'boolean',
|
||||
'null' => true
|
||||
|
@ -5559,7 +5585,7 @@ class Server extends AppModel
|
|||
],
|
||||
'auth_enforced' => [
|
||||
'level' => self::SETTING_OPTIONAL,
|
||||
'description' => __('This optional can be enabled if external auth provider is used and when set to true, it will disable default form authentication.'),
|
||||
'description' => __('This optionally can be enabled if an external auth provider is used. When set to true, it will disable the default form authentication.'),
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
|
|
|
@ -819,4 +819,49 @@ class ShadowAttribute extends AppModel
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function saveAttachment($shadowAttribute, $path_suffix='')
|
||||
{
|
||||
$result = $this->loadAttachmentTool()->saveShadow($shadowAttribute['event_id'], $shadowAttribute['id'], $shadowAttribute['data'], $path_suffix);
|
||||
if ($result) {
|
||||
$this->loadAttachmentScan()->backgroundScan(AttachmentScan::TYPE_SHADOW_ATTRIBUTE, $shadowAttribute);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $shadowAttribute
|
||||
* @param bool $thumbnail
|
||||
* @param int $maxWidth - When $thumbnail is true
|
||||
* @param int $maxHeight - When $thumbnail is true
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getPictureData(array $shadowAttribute, $thumbnail=false, $maxWidth=200, $maxHeight=200)
|
||||
{
|
||||
if ($thumbnail && extension_loaded('gd')) {
|
||||
if ($maxWidth == 200 && $maxHeight == 200) {
|
||||
// Return thumbnail directly if already exists
|
||||
try {
|
||||
return $this->getAttachment($shadowAttribute['ShadowAttribute'], $path_suffix = '_thumbnail');
|
||||
} catch (NotFoundException $e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
// Thumbnail doesn't exists, we need to generate it
|
||||
$imageData = $this->getAttachment($shadowAttribute['ShadowAttribute']);
|
||||
$imageData = $this->Attribute->resizeImage($imageData, $maxWidth, $maxHeight);
|
||||
|
||||
// Save just when requested default thumbnail size
|
||||
if ($maxWidth == 200 && $maxHeight == 200) {
|
||||
$shadowAttribute['ShadowAttribute']['data'] = $imageData;
|
||||
$this->saveAttachment($shadowAttribute['ShadowAttribute'], $path_suffix='_thumbnail');
|
||||
}
|
||||
} else {
|
||||
$imageData = $this->getAttachment($shadowAttribute['ShadowAttribute']);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
|
||||
/**
|
||||
* @property EventTag $EventTag
|
||||
* @property AttributeTag $AttributeTag
|
||||
*/
|
||||
class Tag extends AppModel
|
||||
{
|
||||
public $useTable = 'tags';
|
||||
|
@ -177,8 +181,8 @@ class Tag extends AppModel
|
|||
{
|
||||
$conditions = array();
|
||||
if (!$user['Role']['perm_site_admin']) {
|
||||
$conditions['Tag.org_id'] = array(0, $user['User']['org_id']);
|
||||
$conditions['Tag.user_id'] = array(0, $user['User']['id']);
|
||||
$conditions['Tag.org_id'] = array(0, $user['org_id']);
|
||||
$conditions['Tag.user_id'] = array(0, $user['id']);
|
||||
$conditions['Tag.hide_tag'] = 0;
|
||||
}
|
||||
return $this->find('all', array('conditions' => $conditions, 'recursive' => -1));
|
||||
|
|
|
@ -63,7 +63,7 @@ class TagCollection extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function fetchTagCollection($user, $params = array())
|
||||
public function fetchTagCollection(array $user, $params = array())
|
||||
{
|
||||
if (empty($user['Role']['perm_site_admin'])) {
|
||||
$params['conditions']['AND'][] = array(
|
||||
|
@ -104,8 +104,17 @@ class TagCollection extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function cullBlockedTags($user, $tagCollections)
|
||||
/**
|
||||
* @param array $user
|
||||
* @param array $tagCollections
|
||||
* @return array|
|
||||
*/
|
||||
public function cullBlockedTags(array $user, array $tagCollections)
|
||||
{
|
||||
if (empty($tagCollections)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$single = false;
|
||||
if (!isset($tagCollections[0])) {
|
||||
$tagCollections = array(0 => $tagCollections);
|
||||
|
|
|
@ -228,7 +228,7 @@ class Taxonomy extends AppModel
|
|||
|
||||
// returns all tags associated to a taxonomy
|
||||
// returns all tags not associated to a taxonomy if $inverse is true
|
||||
public function getAllTaxonomyTags($inverse = false, $user = false, $full = false)
|
||||
public function getAllTaxonomyTags($inverse = false, $user = false, $full = false, $hideUnselectable = true)
|
||||
{
|
||||
$this->Tag = ClassRegistry::init('Tag');
|
||||
$taxonomyIdList = $this->find('column', array('fields' => array('Taxonomy.id')));
|
||||
|
@ -243,7 +243,7 @@ class Taxonomy extends AppModel
|
|||
$conditions[] = array('Tag.user_id' => array(0, $user['id']));
|
||||
}
|
||||
}
|
||||
if (Configure::read('MISP.incoming_tags_disabled_by_default')) {
|
||||
if (Configure::read('MISP.incoming_tags_disabled_by_default') || $hideUnselectable) {
|
||||
$conditions['Tag.hide_tag'] = 0;
|
||||
}
|
||||
if ($full) {
|
||||
|
|
|
@ -230,25 +230,21 @@ class UserSetting extends AppModel
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the event is something the user is interested (to be alerted on)
|
||||
*
|
||||
/**
|
||||
* Check whether the event is something the user is interested (to be alerted on)
|
||||
* @param $user
|
||||
* @param $event
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPublishFilter($user, $event)
|
||||
public function checkPublishFilter(array $user, array $event)
|
||||
{
|
||||
$rule = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array(
|
||||
'UserSetting.user_id' => $user['id'],
|
||||
'UserSetting.setting' => 'publish_alert_filter'
|
||||
)
|
||||
));
|
||||
$rule = $this->getValueForUser($user['id'], 'publish_alert_filter');
|
||||
// We should return true if no setting has been configured, or there's a setting with an empty value
|
||||
if (empty($rule) || empty($rule['UserSetting']['value'])) {
|
||||
if (empty($rule)) {
|
||||
return true;
|
||||
}
|
||||
// recursively evaluate the boolean tree to true/false and return the value
|
||||
$result = $this->__recursiveConvert($rule['UserSetting']['value'], $event);
|
||||
$result = $this->__recursiveConvert($rule, $event);
|
||||
if (isset($result[0])) {
|
||||
return $result[0];
|
||||
} else {
|
||||
|
@ -256,7 +252,7 @@ class UserSetting extends AppModel
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Convert a complex rule set recursively
|
||||
* takes as params a rule branch and an event to check against
|
||||
* evaluate whether the rule set evaluates as true/false
|
||||
|
@ -284,9 +280,9 @@ class UserSetting extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
$toReturn []= $temp;
|
||||
$toReturn[] = $temp;
|
||||
} else {
|
||||
$toReturn []= $this->__checkEvent($k, $v, $event);
|
||||
$toReturn[] = $this->__checkEvent($k, $v, $event);
|
||||
}
|
||||
}
|
||||
return $toReturn;
|
||||
|
@ -303,6 +299,7 @@ class UserSetting extends AppModel
|
|||
* - Tag.name (checks against both event and attribute tags)
|
||||
* - Orgc.uuid
|
||||
* - Orgc.name
|
||||
* - ThreatLevel.name
|
||||
* Values passed can be used for direct string comparisons or alternatively
|
||||
* as substring matches by encapsulating the string in a pair of "%" characters
|
||||
* Each rule can take a list of values
|
||||
|
@ -332,6 +329,8 @@ class UserSetting extends AppModel
|
|||
Hash::extract($event, 'Object.{n}.Attribute.{n}.AttributeTag.{n}.Tag.name'),
|
||||
Hash::extract($event, 'EventTag.{n}.Tag.name')
|
||||
);
|
||||
} else if ($rule === 'ThreatLevel.name') {
|
||||
$values = [$event['ThreatLevel']['name']];
|
||||
}
|
||||
if (!empty($values)) {
|
||||
foreach ($values as $extracted_value) {
|
||||
|
@ -405,18 +404,14 @@ class UserSetting extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @param string $setting
|
||||
* @return array|mixed
|
||||
* @deprecated
|
||||
*/
|
||||
public function getSetting($user_id, $setting)
|
||||
{
|
||||
$setting = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array(
|
||||
'UserSetting.user_id' => $user_id,
|
||||
'UserSetting.setting' => $setting
|
||||
)
|
||||
));
|
||||
if (empty($setting)) {
|
||||
return array();
|
||||
}
|
||||
return $setting['UserSetting']['value'];
|
||||
return $this->getValueForUser($user_id, $setting) ?: [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('CidrTool', 'Tools');
|
||||
|
||||
/**
|
||||
* @property WarninglistType $WarninglistType
|
||||
|
@ -154,7 +155,7 @@ class Warninglist extends AppModel
|
|||
if (!empty($saveToCache)) {
|
||||
$pipe = $redis->multi(Redis::PIPELINE);
|
||||
foreach ($saveToCache as $attributeKey => $json) {
|
||||
$redis->setex($attributeKey, 3600, $json); // cache for one hour
|
||||
$redis->setex($attributeKey, 8 * 3600, $json); // cache for eight hour
|
||||
}
|
||||
$pipe->exec();
|
||||
}
|
||||
|
@ -164,6 +165,12 @@ class Warninglist extends AppModel
|
|||
|
||||
public function update()
|
||||
{
|
||||
$existingWarninglist = $this->find('all', [
|
||||
'fields' => ['id', 'name', 'version', 'enabled'],
|
||||
'recursive' => -1,
|
||||
]);
|
||||
$existingWarninglist = array_column(array_column($existingWarninglist, 'Warninglist'), null, 'name');
|
||||
|
||||
$directories = glob(APP . 'files' . DS . 'warninglists' . DS . 'lists' . DS . '*', GLOB_ONLYDIR);
|
||||
$updated = array('success' => [], 'fails' => []);
|
||||
foreach ($directories as $dir) {
|
||||
|
@ -179,17 +186,13 @@ class Warninglist extends AppModel
|
|||
} elseif (is_array($list['type'])) {
|
||||
$list['type'] = $list['type'][0];
|
||||
}
|
||||
$current = $this->find('first', array(
|
||||
'conditions' => array('name' => $list['name']),
|
||||
'recursive' => -1,
|
||||
'fields' => array('*')
|
||||
));
|
||||
if (empty($current) || $list['version'] > $current['Warninglist']['version']) {
|
||||
if (!isset($existingWarninglist[$list['name']]) || $list['version'] > $existingWarninglist[$list['name']]['version']) {
|
||||
$current = isset($existingWarninglist[$list['name']]) ? $existingWarninglist[$list['name']] : [];
|
||||
$result = $this->__updateList($list, $current);
|
||||
if (is_numeric($result)) {
|
||||
$updated['success'][$result] = array('name' => $list['name'], 'new' => $list['version']);
|
||||
if (!empty($current)) {
|
||||
$updated['success'][$result]['old'] = $current['Warninglist']['version'];
|
||||
$updated['success'][$result]['old'] = $current['version'];
|
||||
}
|
||||
} else {
|
||||
$updated['fails'][] = array('name' => $list['name'], 'fail' => json_encode($result));
|
||||
|
@ -221,10 +224,10 @@ class Warninglist extends AppModel
|
|||
$list['enabled'] = 0;
|
||||
$warninglist = array();
|
||||
if (!empty($current)) {
|
||||
if ($current['Warninglist']['enabled']) {
|
||||
if ($current['enabled']) {
|
||||
$list['enabled'] = 1;
|
||||
}
|
||||
$this->quickDelete($current['Warninglist']['id']);
|
||||
$this->quickDelete($current['id']);
|
||||
}
|
||||
$fieldsToSave = array('name', 'version', 'description', 'type', 'enabled');
|
||||
foreach ($fieldsToSave as $fieldToSave) {
|
||||
|
@ -398,39 +401,6 @@ class Warninglist extends AppModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out invalid IPv4 or IPv4 CIDR and append maximum netmaks if no netmask is given.
|
||||
* @param array $inputValues
|
||||
* @return array
|
||||
*/
|
||||
private function filterCidrList($inputValues)
|
||||
{
|
||||
$outputValues = [];
|
||||
foreach ($inputValues as $v) {
|
||||
$v = strtolower($v);
|
||||
$parts = explode('/', $v, 2);
|
||||
if (filter_var($parts[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
$maximumNetmask = 32;
|
||||
} else if (filter_var($parts[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$maximumNetmask = 128;
|
||||
} else {
|
||||
// IP address part of CIDR is invalid
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($parts[1])) {
|
||||
// If CIDR doesnt contains '/', we will consider CIDR as /32 for IPv4 or /128 for IPv6
|
||||
$v = "$v/$maximumNetmask";
|
||||
} else if ($parts[1] > $maximumNetmask || $parts[1] < 0) {
|
||||
// Netmask part of CIDR is invalid
|
||||
continue;
|
||||
}
|
||||
|
||||
$outputValues[$v] = true;
|
||||
}
|
||||
return $outputValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* For 'hostname', 'string' and 'cidr' warninglist type, values are just in keys to save memory.
|
||||
*
|
||||
|
@ -459,7 +429,7 @@ class Warninglist extends AppModel
|
|||
}
|
||||
$values = $output;
|
||||
} else if ($warninglist['Warninglist']['type'] === 'cidr') {
|
||||
$values = $this->filterCidrList($values);
|
||||
$values = new CidrTool($values);
|
||||
}
|
||||
|
||||
$this->entriesCache[$id] = $values;
|
||||
|
@ -497,7 +467,7 @@ class Warninglist extends AppModel
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $listValues
|
||||
* @param array|CidrTool $listValues
|
||||
* @param string $value
|
||||
* @param string $type
|
||||
* @param string $listType
|
||||
|
@ -512,7 +482,7 @@ class Warninglist extends AppModel
|
|||
}
|
||||
foreach ($value as $v) {
|
||||
if ($listType === 'cidr') {
|
||||
$result = $this->__evalCidrList($listValues, $v);
|
||||
$result = $listValues->contains($v);
|
||||
} elseif ($listType === 'string') {
|
||||
$result = $this->__evalString($listValues, $v);
|
||||
} elseif ($listType === 'substring') {
|
||||
|
@ -536,75 +506,6 @@ class Warninglist extends AppModel
|
|||
return $this->__checkValue($listValues, $value, '', $type) !== false;
|
||||
}
|
||||
|
||||
private function __evalCidrList($listValues, $value)
|
||||
{
|
||||
$valueMask = null;
|
||||
if (strpos($value, '/') !== false) {
|
||||
list($value, $valueMask) = explode('/', $value);
|
||||
}
|
||||
|
||||
$match = false;
|
||||
if (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||||
// This code converts IP address to all possible CIDRs that can contains given IP address
|
||||
// and then check if given hash table contains that CIDR.
|
||||
$ip = ip2long($value);
|
||||
// Start from 1, because doesn't make sense to check 0.0.0.0/0 match
|
||||
for ($bits = 1; $bits <= 32; $bits++) {
|
||||
$mask = -1 << (32 - $bits);
|
||||
$needle = long2ip($ip & $mask) . "/$bits";
|
||||
if (isset($listValues[$needle])) {
|
||||
$match = $needle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
foreach ($listValues as $lv => $foo) {
|
||||
if (strpos($lv, ':') !== false) { // Filter out IPv4 CIDR, IPv6 CIDR must contain colon
|
||||
if ($this->__ipv6InCidr($value, $lv)) {
|
||||
$match = $lv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($match && $valueMask) {
|
||||
$matchMask = explode('/', $match)[1];
|
||||
if ($valueMask < $matchMask) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using solution from https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/IpUtils.php
|
||||
*
|
||||
* @param string $ip
|
||||
* @param string $cidr
|
||||
* @return bool
|
||||
*/
|
||||
private function __ipv6InCidr($ip, $cidr)
|
||||
{
|
||||
list($address, $netmask) = explode('/', $cidr);
|
||||
|
||||
$bytesAddr = unpack('n*', inet_pton($address));
|
||||
$bytesTest = unpack('n*', inet_pton($ip));
|
||||
|
||||
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
|
||||
$left = $netmask - 16 * ($i - 1);
|
||||
$left = ($left <= 16) ? $left : 16;
|
||||
$mask = ~(0xffff >> $left) & 0xffff;
|
||||
if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for exact match.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/../Lib/Tools/CidrTool.php';
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CidrToolTest extends TestCase
|
||||
{
|
||||
public function testEmptyList(): void
|
||||
{
|
||||
$cidrTool = new CidrTool([]);
|
||||
$this->assertFalse($cidrTool->contains('1.2.3.4'));
|
||||
}
|
||||
|
||||
public function testIpv4Fullmask(): void
|
||||
{
|
||||
$cidrTool = new CidrTool(['1.2.3.4/32']);
|
||||
$this->assertEquals('1.2.3.4/32', $cidrTool->contains('1.2.3.4'));
|
||||
}
|
||||
|
||||
public function testIpv4WithoutNetmask(): void
|
||||
{
|
||||
$cidrTool = new CidrTool(['1.2.3.4']);
|
||||
$this->assertEquals('1.2.3.4/32', $cidrTool->contains('1.2.3.4'));
|
||||
}
|
||||
|
||||
public function testIpv4(): void
|
||||
{
|
||||
$cidrTool = new CidrTool(['10.0.0.0/8', '8.0.0.0/8', '9.0.0.0/8']);
|
||||
$this->assertEquals('8.0.0.0/8', $cidrTool->contains('8.8.8.8'));
|
||||
$this->assertFalse($cidrTool->contains('::1'));
|
||||
$this->assertFalse($cidrTool->contains('7.1.2.3'));
|
||||
}
|
||||
|
||||
public function testIpv6(): void
|
||||
{
|
||||
$cidrTool = new CidrTool(['2001:0db8:1234::/48']);
|
||||
$this->assertEquals('2001:db8:1234::/48', $cidrTool->contains('2001:0db8:1234:0000:0000:0000:0000:0000'));
|
||||
$this->assertEquals('2001:db8:1234::/48', $cidrTool->contains('2001:0db8:1234:ffff:ffff:ffff:ffff:ffff'));
|
||||
$this->assertFalse($cidrTool->contains('2002:0db8:1234:ffff:ffff:ffff:ffff:ffff'));
|
||||
}
|
||||
}
|
|
@ -29,9 +29,10 @@
|
|||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
|
||||
echo $this->Paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
$paginator = $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
$paginator .= $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
|
||||
$paginator .= $this->Paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $paginator;
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -91,6 +92,7 @@
|
|||
if (!empty($attribute['Attribute']['RelatedAttribute'])) {
|
||||
$event['RelatedAttribute'] = array($attribute['Attribute']['id'] => $attribute['Attribute']['RelatedAttribute']);
|
||||
}
|
||||
$attribute['Attribute']['objectType'] = 'attribute';
|
||||
echo $this->element('/Events/View/row_attribute', array(
|
||||
'object' => $attribute['Attribute'],
|
||||
'k' => $k,
|
||||
|
@ -124,24 +126,18 @@
|
|||
</p>
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<?php
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 20, 'separator' => '', 'tag' => 'li', 'currentClass' => 'active', 'currentTag' => 'span'));
|
||||
echo $this->Paginator->next(__('next') . ' »', array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'next disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
?>
|
||||
<?= $paginator ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($isSearch == 1){
|
||||
if ($isSearch == 1) {
|
||||
$class = 'searchAttributes2';
|
||||
} else {
|
||||
$class = 'listAttributes';
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $class));
|
||||
?>
|
||||
<?= $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event-collection', 'menuItem' => $class)); ?>
|
||||
<script type="text/javascript">
|
||||
// tooltips
|
||||
$(function () {
|
||||
|
|
|
@ -10,6 +10,9 @@ if (isset($keyUsage)) {
|
|||
$dateAsString = date('Y-m-d', $date);
|
||||
$keyUsageCsv .= $dateAsString . ',' . (isset($keyUsage[$dateAsString]) ? $keyUsage[$dateAsString] : 0) . '\n';
|
||||
}
|
||||
} else {
|
||||
$lastUsed = null;
|
||||
$uniqueIps = null;
|
||||
}
|
||||
|
||||
echo $this->element(
|
||||
|
@ -63,7 +66,7 @@ echo $this->element(
|
|||
],
|
||||
[
|
||||
'key' => __('Last used'),
|
||||
'raw' => $lastUsed ? date('Y-m-d H:i:s', $lastUsed) : __('Not used yet'),
|
||||
'raw' => $lastUsed ? $this->Time->time($lastUsed) : __('Not used yet'),
|
||||
'requirement' => isset($keyUsage),
|
||||
],
|
||||
[
|
||||
|
|
|
@ -91,12 +91,3 @@
|
|||
));
|
||||
echo '</div>';
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'dashboard', 'menuItem' => 'dashboardTemplateIndex'));
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var passedArgsArray = <?php echo json_encode($passedArgs); ?>;
|
||||
$(document).ready(function() {
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(function() {
|
||||
if (<?= $config['autoRefreshDelay'] ? 'true' : 'false' ?>) {
|
||||
setTimeout( function(){
|
||||
updateDashboardWidget("#widget_<?= h($widget_id) ?>")},
|
||||
|
|
|
@ -94,7 +94,7 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
if (!empty($extended)):
|
||||
if ($object['event_id'] != $event['Event']['id']):
|
||||
$extensionOrg = $event['extensionEvents'][$object['event_id']]['Orgc'];
|
||||
echo $this->OrgImg->getOrgLogo($extensionOrg['name'], 24);
|
||||
echo $this->OrgImg->getOrgLogo($extensionOrg, 24);
|
||||
else:
|
||||
echo $this->OrgImg->getOrgLogo($event['Orgc'], 24);
|
||||
endif;
|
||||
|
@ -211,16 +211,16 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
if (isset($object['Feed'])) {
|
||||
foreach ($object['Feed'] as $feed) {
|
||||
$relatedData = array(
|
||||
__('Name') => $feed['name'],
|
||||
__('URL') => $feed['url'],
|
||||
__('Provider') => $feed['provider'],
|
||||
__('Name') => h($feed['name']),
|
||||
__('URL') => h($feed['url']),
|
||||
__('Provider') => h($feed['provider']),
|
||||
);
|
||||
if (isset($feed['event_uuids'])) {
|
||||
$relatedData[__('Event UUIDs')] = implode('<br>', $feed['event_uuids']);
|
||||
$relatedData[__('Event UUIDs')] = implode('<br>', array_map('h', $feed['event_uuids']));
|
||||
}
|
||||
$popover = '';
|
||||
foreach ($relatedData as $k => $v) {
|
||||
$popover .= '<span class="bold black">' . h($k) . '</span>: <span class="blue">' . h($v) . '</span><br>';
|
||||
$popover .= '<span class="bold black">' . $k . '</span>: <span class="blue">' . $v . '</span><br>';
|
||||
}
|
||||
if ($isSiteAdmin || $hostOrgUser) {
|
||||
if ($feed['source_format'] === 'misp') {
|
||||
|
@ -418,4 +418,3 @@ if (!empty($object['ShadowAttribute'])) {
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,23 +115,35 @@
|
|||
?>
|
||||
<td class="short action-links">
|
||||
<?php
|
||||
if ($mayModify && empty($object['deleted'])) {
|
||||
echo sprintf(
|
||||
'<a href="%s/objects/edit/%s" title="%s" aria-label="%s" class="fa fa-edit white useCursorPointer"></a> ',
|
||||
$baseurl,
|
||||
h($object['id']),
|
||||
__('Edit'),
|
||||
__('Edit')
|
||||
);
|
||||
echo sprintf(
|
||||
'<span class="fa fa-trash white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
|
||||
(empty($event['Event']['publish_timestamp']) ? __('Permanently delete object') : __('Soft delete object')),
|
||||
sprintf(
|
||||
'deleteObject(\'objects\', \'delete\', \'%s\', \'%s\');',
|
||||
empty($event['Event']['publish_timestamp']) ? h($object['id']) . '/true' : h($object['id']),
|
||||
h($event['Event']['id'])
|
||||
)
|
||||
);
|
||||
if ($mayModify) {
|
||||
if (empty($object['deleted'])) {
|
||||
echo sprintf(
|
||||
'<a href="%s/objects/edit/%s" title="%s" aria-label="%s" class="fa fa-edit white useCursorPointer"></a> ',
|
||||
$baseurl,
|
||||
h($object['id']),
|
||||
__('Edit'),
|
||||
__('Edit')
|
||||
);
|
||||
echo sprintf(
|
||||
'<span class="fa fa-trash white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
|
||||
(empty($event['Event']['publish_timestamp']) ? __('Permanently delete object') : __('Soft delete object')),
|
||||
sprintf(
|
||||
'deleteObject(\'objects\', \'delete\', \'%s\', \'%s\');',
|
||||
empty($event['Event']['publish_timestamp']) ? h($object['id']) . '/true' : h($object['id']),
|
||||
h($event['Event']['id'])
|
||||
)
|
||||
);
|
||||
} else {
|
||||
echo sprintf(
|
||||
'<span class="fa fa-trash white useCursorPointer" title="%1$s" role="button" tabindex="0" aria-label="%1$s" onClick="%2$s"></span>',
|
||||
__('Permanently delete object'),
|
||||
sprintf(
|
||||
'deleteObject(\'objects\', \'delete\', \'%s\', \'%s\');',
|
||||
h($object['id']) . '/true',
|
||||
h($event['Event']['id'])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
@ -151,4 +163,3 @@
|
|||
}
|
||||
echo '<tr class="objectAddFieldTr"><td><span class="fa fa-plus-circle objectAddField" title="' . __('Add an Object Attribute') .'" onclick="popoverPopup(this, ' . h($object['id']) . ', \'objects\', \'quickFetchTemplateWithValidObjectAttributes\')"></span></td></tr>';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
<?php if ($object['first_seen'] != null || $object['last_seen'] != null): ?>
|
||||
<?php
|
||||
$time = function ($value) {
|
||||
return $value != null ? $this->Time->time($value) : '<span style="display: block; text-align:center;">_</span>';
|
||||
};
|
||||
|
||||
if ($object['first_seen'] != null || $object['last_seen'] != null): ?>
|
||||
<div>
|
||||
<div><?php echo $object['first_seen'] != null ? h($object['first_seen']) : '<span style="display: block; text-align:center;">_</span>'; ?></div>
|
||||
<div><?= $time($object['first_seen']) ?></div>
|
||||
<i style="display: block; text-align: center;" class="fas fa-arrow-down"></i>
|
||||
<div><?php echo $object['last_seen'] != null ? h($object['last_seen']) : '<span style="display: block; text-align:center;">_</span>'; ?></div>
|
||||
<div><?= $time($object['last_seen']) ?></div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -9,9 +9,9 @@ if (isset($sightingsData['data'][$objectId])) {
|
|||
foreach ($typeData['orgs'] as $org => $orgData) {
|
||||
$extra = $org === $me['Organisation']['name'] ? ' class="bold"' : "";
|
||||
if ($type == 'expiration') {
|
||||
$html .= '<span' . $extra . '>' . h($org) . '</span>: <span class="orange bold">' . date('Y-m-d H:i:s', $orgData['date']) . '</span><br>';
|
||||
$html .= '<span' . $extra . '>' . h($org) . '</span>: <span class="orange bold">' . $this->Time->time($orgData['date']) . '</span><br>';
|
||||
} else {
|
||||
$html .= '<span' . $extra . '>' . h($org) . '</span>: <span class="' . ($type === 'sighting' ? 'green' : 'red') . ' bold">' . h($orgData['count']) . ' (' . date('Y-m-d H:i:s', $orgData['date']) . ')</span><br>';
|
||||
$html .= '<span' . $extra . '>' . h($org) . '</span>: <span class="' . ($type === 'sighting' ? 'green' : 'red') . ' bold">' . h($orgData['count']) . ' (' . $this->Time->time($orgData['date']) . ')</span><br>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ switch ($object['type']) {
|
|||
if ($object['type'] === 'attachment' && isset($object['image'])) {
|
||||
if ($object['image'] === true) {
|
||||
$img = '<it class="fa fa-spin fa-spinner" style="font-size: large; left: 50%; top: 50%;"></it>';
|
||||
$img .= '<img class="screenshot screenshot-collapsed useCursorPointer img-rounded hidden" src="' . $baseurl . '/attributes/viewPicture/' . h($object['id']) . '/1' . '" title="' . h($object['value']) . '" onload="$(this).show(200); $(this).parent().find(\'.fa-spinner\').remove();"/>';
|
||||
$img .= '<img class="screenshot screenshot-collapsed useCursorPointer img-rounded hidden" src="' . $baseurl . sprintf('/%s/viewPicture/', $object['objectType'] == 'proposal' ? 'shadowAttributes' : 'attributes') . h($object['id']) . '/1' . '" title="' . h($object['value']) . '" onload="$(this).show(200); $(this).parent().find(\'.fa-spinner\').remove();"/>';
|
||||
echo $img;
|
||||
} else {
|
||||
$extension = pathinfo($object['value'], PATHINFO_EXTENSION);
|
||||
|
@ -70,6 +70,9 @@ switch ($object['type']) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case 'datetime':
|
||||
echo $this->Time->time($object['value']);
|
||||
break;
|
||||
|
||||
case 'vulnerability':
|
||||
$cveUrl = Configure::read('MISP.cveurl') ?: 'https://cve.circl.lu/cve/';
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<td style="width:30px;">
|
||||
<a href="<?php echo $baseurl."/events/view/".$event['Event']['id'] ?>"><?php echo $event['Event']['id'];?></a>
|
||||
</td>
|
||||
<td class="shortish">
|
||||
<td class="short">
|
||||
<?php
|
||||
$galaxies = array();
|
||||
if (!empty($event['GalaxyCluster'])) {
|
||||
|
|
|
@ -22,6 +22,11 @@ echo $this->element('genericElements/assetLoader', array(
|
|||
return;
|
||||
}
|
||||
hasBeenBuilt = true;
|
||||
var $tree = $('#treeSVG');
|
||||
treeWidth = $tree.width() - margin.right - margin.left;
|
||||
treeHeight = $tree.height() - margin.top - margin.bottom;
|
||||
var leftShift;
|
||||
var childrenBothSides, side;
|
||||
if (treeData.left[0].children === undefined || treeData.left[0].children.length == 0) {
|
||||
leftShift = 0;
|
||||
childrenBothSides = false;
|
||||
|
@ -38,11 +43,6 @@ echo $this->element('genericElements/assetLoader', array(
|
|||
}
|
||||
}
|
||||
adaptContainerHeightIfNeeded(side);
|
||||
var $tree = $('#treeSVG');
|
||||
treeWidth = $tree.width() - margin.right - margin.left;
|
||||
treeHeight = $tree.height() - margin.top - margin.bottom;
|
||||
var leftShift;
|
||||
var childrenBothSides, side;
|
||||
|
||||
var data = genHierarchy(treeData, leftShift, childrenBothSides, side);
|
||||
drawTree(data, leftShift, childrenBothSides);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</td>
|
||||
<td class="short">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_category_placeholder" class = "inline-field-placeholder"></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_category_solid" class="inline-field-solid" ondblclick="activateField('Attribute', '<?php echo $object['id']; ?>', 'category', <?php echo $event['Event']['id'];?>);">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_category_solid" class="inline-field-solid">
|
||||
<?php echo h($object['category']); ?>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -41,31 +41,16 @@
|
|||
?>
|
||||
<div></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_type_placeholder" class = "inline-field-placeholder"></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_type_solid" class="inline-field-solid" ondblclick="activateField('Attribute', '<?php echo $object['id']; ?>', 'type', <?php echo $event['Event']['id'];?>);">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_type_solid" class="inline-field-solid">
|
||||
<?php echo h($object['type']); ?>
|
||||
</div>
|
||||
</td>
|
||||
<td id="Attribute_<?php echo h($object['id']); ?>_container" class="showspaces limitedWidth shortish">
|
||||
<div id="Attribute_<?php echo $object['id']; ?>_value_placeholder" class="inline-field-placeholder"></div>
|
||||
<?php
|
||||
if ('attachment' !== $object['type'] && 'malware-sample' !== $object['type']) $editable = ' ondblclick="activateField(\'Attribute\', \'' . $object['id'] . '\', \'value\', \'' . $event['Event']['id'] . '\');"';
|
||||
else $editable = '';
|
||||
?>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_value_solid" class="inline-field-solid" <?php echo $editable; ?>>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_value_solid" class="inline-field-solid">
|
||||
<span <?php if (Configure::read('Plugin.Enrichment_hover_enable') && isset($modules) && isset($modules['hover_type'][$object['type']])) echo 'class="eventViewAttributeHover" data-object-type="Attribute" data-object-id="' . h($object['id']) . '"'?>>
|
||||
<?php
|
||||
echo $this->element('/Events/View/value_field', array('object' => $object, 'linkClass' => $linkClass));
|
||||
?>
|
||||
<?= $this->element('/Events/View/value_field', array('object' => $object, 'linkClass' => $linkClass)); ?>
|
||||
</span>
|
||||
<?php
|
||||
if (isset($object['warnings'])) {
|
||||
$temp = '';
|
||||
foreach ($object['warnings'] as $warning) {
|
||||
$temp .= '<span class="bold">' . h($warning['match']) . ':</span> <span class="red">' . h($warning['warninglist_name']) . '</span><br>';
|
||||
}
|
||||
echo ' <span aria-label="' . __('warning') . '" role="img" tabindex="0" class="fa fa-exclamation-triangle" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover" data-placement="right"> </span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="shortish">
|
||||
|
@ -78,7 +63,7 @@
|
|||
</td>
|
||||
<td class="showspaces bitwider">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_comment_placeholder" class = "inline-field-placeholder"></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_comment_solid" class="inline-field-solid" ondblclick="activateField('Attribute', '<?php echo $object['id']; ?>', 'comment', <?php echo $event['Event']['id'];?>);">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_comment_solid" class="inline-field-solid">
|
||||
<?php echo nl2br(h($object['comment'])); ?>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -136,7 +121,7 @@
|
|||
</td>
|
||||
<td class="short">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_placeholder" class = "inline-field-placeholder"></div>
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_solid" class="inline-field-solid" ondblclick="activateField('Attribute', '<?php echo $object['id']; ?>', 'to_ids', <?php echo $event['Event']['id'];?>);">
|
||||
<div id = "Attribute_<?php echo $object['id']; ?>_to_ids_solid" class="inline-field-solid">
|
||||
<?php echo $object['to_ids'] ? __('Yes') : __('No'); ?>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -12,10 +12,7 @@
|
|||
<ul>
|
||||
<?php
|
||||
$this->Paginator->options(array(
|
||||
'url' => array($server['Server']['id'], $event['Event']['id']),
|
||||
'evalScripts' => true,
|
||||
'before' => '$(".progress").show()',
|
||||
'complete' => '$(".progress").hide()',
|
||||
'url' => array($server['Server']['id'], $event['Event']['id']),
|
||||
));
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 60, 'separator' => '', 'tag' => 'li', 'currentClass' => 'red', 'currentTag' => 'span'));
|
||||
|
@ -79,10 +76,7 @@
|
|||
<ul>
|
||||
<?php
|
||||
$this->Paginator->options(array(
|
||||
'url' => array($server['Server']['id'], $event['Event']['id']),
|
||||
'evalScripts' => true,
|
||||
'before' => '$(".progress").show()',
|
||||
'complete' => '$(".progress").hide()',
|
||||
'url' => array($server['Server']['id'], $event['Event']['id']),
|
||||
));
|
||||
echo $this->Paginator->prev('« ' . __('previous'), array('tag' => 'li', 'escape' => false), null, array('tag' => 'li', 'class' => 'prev disabled', 'escape' => false, 'disabledTag' => 'span'));
|
||||
echo $this->Paginator->numbers(array('modulus' => 60, 'separator' => '', 'tag' => 'li', 'currentClass' => 'red', 'currentTag' => 'span'));
|
||||
|
@ -105,7 +99,7 @@
|
|||
var currentUri = "<?php echo isset($currentUri) ? h($currentUri) : $baseurl . '/servers/previewEvent/' . h($server['Server']['id']) . '/' . h($event['Event']['id']); ?>";
|
||||
var lastSelected = false;
|
||||
var deleted = <?php echo (isset($deleted) && $deleted) ? 'true' : 'false';?>;
|
||||
$(document).ready(function() {
|
||||
$(function() {
|
||||
<?php
|
||||
if ($focusedRow !== false):
|
||||
?>
|
||||
|
@ -118,6 +112,3 @@
|
|||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->Js->writeBuffer();
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
echo $this->element('genericElements/IndexTable/index_table', [
|
||||
'data' => [
|
||||
'data' => $data['data'],
|
||||
'top_bar' => [],
|
||||
'fields' => $data['fields'],
|
||||
'title' => false,
|
||||
'description' => false,
|
||||
'pull' => 'right',
|
||||
'skip_pagination' => true,
|
||||
'actions' => []
|
||||
]
|
||||
]);
|
||||
?>
|
|
@ -78,7 +78,7 @@
|
|||
'fa-icon' => 'rebel',
|
||||
'fa-source' => 'fab',
|
||||
'onClick' => 'popoverPopup',
|
||||
'onClickParams' => array('this', 'selected/attribute', 'galaxies', 'selectGalaxyNamespace')
|
||||
'onClickParams' => array('this', 'selected/attribute/eventid:' . h($event['Event']['id']), 'galaxies', 'selectGalaxyNamespace')
|
||||
),
|
||||
array(
|
||||
'id' => 'group-into-object-button',
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
?>
|
||||
</div>
|
||||
<div class="footerText footerCenterText">
|
||||
<span><?php echo h(Configure::read('MISP.footermidleft')); ?> Powered by <a href="https://github.com/MISP/MISP">MISP <?php if (isset($me['id'])) echo h($mispVersionFull);?></a> <?php echo h(Configure::read('MISP.footermidright')); ?> - <?php echo date("Y-m-d H:i:s"); ?></span>
|
||||
<span><?= h(Configure::read('MISP.footermidleft')); ?> Powered by <a href="https://github.com/MISP/MISP" rel="noopener">MISP <?= isset($me['id']) ? h($mispVersionFull) : '' ?></a> <?= h(Configure::read('MISP.footermidright')); ?> - <?= $this->Time->time(time()) ?></span>
|
||||
</div>
|
||||
<div class="pull-right" style="position:relative;padding-top:9px;z-index:2;">
|
||||
<?php
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php echo $this->Html->script('moment-with-locales'); ?>
|
||||
|
||||
<?= $this->Html->script('moment.min'); ?>
|
||||
<script>
|
||||
<?php
|
||||
$temp = explode('_', $this->params->controller);
|
||||
|
@ -49,22 +48,22 @@ $(function() {
|
|||
var $sliders_container = $("#bothSeenSliderContainer");
|
||||
var inputs_container = $('<div class="input-group input-daterange"></div>');
|
||||
// create separate date and time input
|
||||
var date_div_fs = $('<div class="input clear" style="width: 257px"></div>').append(
|
||||
var date_div_fs = $('<div class="input clear" style="width: 257px; margin-right: 0"></div>').append(
|
||||
$('<label><?php echo __('First seen date') . '<span class="fas fa-calendar label-icon"></span>'; ?><input id="date_fs" type="text" style="width: 240px;"></input></label>')
|
||||
);
|
||||
$(inputs_container).append(date_div_fs);
|
||||
var date_div_ls = $('<div class="input text" style="width: 257px"></div>').append(
|
||||
var date_div_ls = $('<div class="input text" style="width: 257px; margin-right: 0"></div>').append(
|
||||
$('<label><?php echo __('Last seen date') . '<span class="fas fa-calendar label-icon"></span>'; ?><input id="date_ls" type="text" style="width: 240px;"></input></label>')
|
||||
);
|
||||
$(inputs_container).append(date_div_ls);
|
||||
$sliders_container.append(inputs_container);
|
||||
|
||||
var time_div_fs = $('<div class="input clear" style="width: 257px"></div>').append(
|
||||
var time_div_fs = $('<div class="input clear" style="width: 257px; margin-right: 0"></div>').append(
|
||||
$('<label><?php echo __('First seen time') . '<span class="fas fa-clock label-icon"></span>'; ?><input id="time_fs" type="text" style="width: 240px; text-align: center; margin-bottom: 0px" placeholder="HH:MM:SS.ssssss+TT:TT"></input></label>'),
|
||||
$('<span class="apply_css_arrow"></span>').text('<?php echo __('Expected format: HH:MM:SS.ssssss+TT:TT') ?>')
|
||||
);
|
||||
$sliders_container.append(time_div_fs);
|
||||
var time_div_ls = $('<div class="input" style="width: 257px"></div>').append(
|
||||
var time_div_ls = $('<div class="input" style="width: 257px; margin-right: 0"></div>').append(
|
||||
$('<label><?php echo __('Last seen time') . '<span class="fas fa-clock label-icon"></span>'; ?><input id="time_ls" type="text" style="width: 240px; text-align: center; margin-bottom: 0px" placeholder="HH:MM:SS.ssssss+TT:TT"></input></label>'),
|
||||
$('<span class="apply_css_arrow"></span>').text('<?php echo __('Expected format: HH:MM:SS.ssssss+TT:TT') ?>')
|
||||
);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<?php
|
||||
|
||||
echo h($arrayData[Hash::extract($row, $field['data_path'])[0]]);
|
||||
echo h($field['arrayData'][Hash::extract($row, $field['data_path'])[0]]);
|
||||
?>
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
if (empty($data) && !empty($field['empty'])) {
|
||||
$data = $field['empty'];
|
||||
}
|
||||
if (is_numeric($data)) {
|
||||
$data = date('Y-m-d H:i:s', $data);
|
||||
} else {
|
||||
$data = h($data);
|
||||
}
|
||||
$data = $this->Time->time($data);
|
||||
if (!empty($field['onClick'])) {
|
||||
$data = sprintf(
|
||||
'<span onClick="%s">%s</span>',
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
$diffInDays = floor(($data - time()) / (3600 * 24));
|
||||
$class = $diffInDays <= 14 ? 'text-warning bold' : 'text-success';
|
||||
$title = __n('Will expire in %s day', 'Will expire in %s days', $diffInDays, $diffInDays);
|
||||
$data = '<span class="' . $class . '" title="' . $title . '">' . date('Y-m-d H:i:s', $data) . '</span>';
|
||||
$data = '<span class="' . $class . '" title="' . $title . '">' . $this->Time->time($data) . '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
$value = Hash::get($row, $field['data_path']);
|
||||
$key = Hash::get($row, $field['elementParams']['data_path_key']);
|
||||
|
||||
if ($key === 'refs' &&
|
||||
(substr($value, 0, 8) === 'https://' || substr($value, 0, 7) === 'http://')
|
||||
) {
|
||||
echo '<a href="' . h($value) . '" rel="noreferrer noopener">' . h($value) . '</a>';
|
||||
} else if ($key === 'country') {
|
||||
echo $this->Icon->countryFlag($item['GalaxyElement']['value']) . ' ' . h($value);
|
||||
} else {
|
||||
echo h($value);
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
$value = Hash::extract($data, $field['path'])[0];
|
||||
echo date('Y-m-d H:i:s', $value);
|
||||
echo $this->Time->time($value);
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
'functionName' => '', // function to be called on submit
|
||||
'submitButtonText' => 'Submit',
|
||||
'disabledSubmitButton' => false, // wether to not draw the submit button
|
||||
'flag_redraw_chosen' => false // should chosen picker be redraw at drawing time
|
||||
'flag_redraw_chosen' => false, // should chosen picker be redraw at drawing time
|
||||
'redraw_debounce_time' => 200,
|
||||
);
|
||||
/**
|
||||
* Supported default option in <Option> fields:
|
||||
|
@ -98,11 +99,11 @@ function setupChosen(id, redrawChosen) {
|
|||
// hack to add template into the div
|
||||
var $chosenContainer = $elem.parent().find('.chosen-container');
|
||||
$elem.on('chosen:searchdone chosen:picked keyup change', function(e) {
|
||||
redrawChosenWithTemplate($elem, $chosenContainer, e.type)
|
||||
redrawChosenWithTemplateDebounced(true, $elem, $chosenContainer, e.type)
|
||||
});
|
||||
|
||||
if (redrawChosen) {
|
||||
redrawChosenWithTemplate($elem, $chosenContainer);
|
||||
redrawChosenWithTemplateDebounced(false, $elem, $chosenContainer);
|
||||
}
|
||||
|
||||
if ($elem.prop('multiple')) {
|
||||
|
@ -112,6 +113,23 @@ function setupChosen(id, redrawChosen) {
|
|||
}
|
||||
}
|
||||
|
||||
var debounceTimer;
|
||||
function redrawChosenWithTemplateDebounced(useDebounce, $select, $chosenContainer, eventType) {
|
||||
if (useDebounce) {
|
||||
clearTimeout(debounceTimer);
|
||||
var timerValue = <?= $defaults['redraw_debounce_time'] ?>;
|
||||
var resultCount = $select.data('chosen').search_results.children().length;
|
||||
if (resultCount <= 20) {
|
||||
timerValue = 0
|
||||
}
|
||||
debounceTimer = setTimeout(function() {
|
||||
redrawChosenWithTemplate($select, $chosenContainer, eventType);
|
||||
}, timerValue);
|
||||
} else {
|
||||
redrawChosenWithTemplate($select, $chosenContainer, eventType);
|
||||
}
|
||||
}
|
||||
|
||||
function redrawChosenWithTemplate($select, $chosenContainer, eventType) {
|
||||
var optionLength = $select.find('option').length;
|
||||
if (optionLength > 1000) {
|
||||
|
|
|
@ -160,11 +160,11 @@
|
|||
<p><?php echo __('The following settings might have a negative impact on certain functionalities of MISP with their current and recommended minimum settings. You can adjust these in your php.ini. Keep in mind that the recommendations are not requirements, just recommendations. Depending on usage you might want to go beyond the recommended values.');?></p>
|
||||
<?php
|
||||
foreach ($phpSettings as $settingName => &$phpSetting):
|
||||
echo $settingName . ' (<span class="bold">' . $phpSetting['value'] . ($phpSetting['unit'] ? $phpSetting['unit'] : '') . '</span>' .')' . '…';
|
||||
echo $settingName . ' (<b>' . $phpSetting['value'] . ($phpSetting['unit'] ? ' ' . $phpSetting['unit'] : '') . '</b>' .')' . '…';
|
||||
if ($phpSetting['value'] < $phpSetting['recommended']) $pass = false;
|
||||
else $pass = true;
|
||||
?>
|
||||
<span style="color:<?php echo $pass ? 'green': 'orange'; ?>"><?php echo $pass ? __('OK') : __('Low'); ?> (recommended: <?php echo strval($phpSetting['recommended']) . ($phpSetting['unit'] ? $phpSetting['unit'] : '') . ')'; ?></span><br />
|
||||
<span style="color:<?php echo $pass ? 'green': 'orange'; ?>"><?php echo $pass ? __('OK') : __('Low'); ?> (recommended: <?php echo strval($phpSetting['recommended']) . ($phpSetting['unit'] ? ' ' . $phpSetting['unit'] : '') . ')'; ?></span><br>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
|
|
|
@ -201,7 +201,7 @@
|
|||
if ($canEdit) {
|
||||
echo $this->element('genericElements/assetLoader', array(
|
||||
'js' => array(
|
||||
'moment-with-locales',
|
||||
'moment.min',
|
||||
'codemirror/codemirror',
|
||||
'codemirror/modes/markdown',
|
||||
'codemirror/addons/simplescrollbars',
|
||||
|
@ -221,4 +221,4 @@
|
|||
if (!empty($additionalMarkdownElements)) {
|
||||
echo $this->element($additionalMarkdownElements['path'], $additionalMarkdownElements['variables']);
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ foreach($tabs as $tabName => $column):
|
|||
|
||||
echo $this->Form->create('Galaxy', array('url' => $url, 'style' => 'margin:0px;'));
|
||||
echo $this->Form->input('target_ids', array('type' => 'text'));
|
||||
echo $this->Form->input('attribute_ids', array('style' => 'display:none;', 'label' => false));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
|
||||
<?php
|
||||
echo $this->Html->script('moment-with-locales');
|
||||
echo $this->Html->script('moment.min');
|
||||
echo $this->Html->script('event-timeline');
|
||||
echo $this->Html->css('event-timeline');
|
||||
?>
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
h($distributionLevels[$report['EventReport']['distribution']])
|
||||
);
|
||||
|
||||
$table_data[] = array('key' => __('Last update'), 'value' => date('Y-m-d H:i:s', $report['EventReport']['timestamp']));
|
||||
$table_data[] = array(
|
||||
'key' => __('Last update'),
|
||||
'html' => $this->Time->time($report['EventReport']['timestamp']),
|
||||
);
|
||||
if ($report['EventReport']['deleted']) {
|
||||
$table_data[] = array(
|
||||
'key' => __('Deleted'),
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
<?php
|
||||
echo json_encode($result);
|
|
@ -54,6 +54,7 @@
|
|||
}
|
||||
$attributes_count = isset($event['Attribute']) ? count($event['Attribute']) : 0;
|
||||
$objects_count = isset($event['Object']) ? count($event['Object']) : 0;
|
||||
$report_count = isset($event['EventReport']) ? count($event['EventReport']) : 0;
|
||||
if (!empty($event['Object'])) {
|
||||
foreach ($event['Object'] as $object) {
|
||||
if (!empty($object['Attribute'])) {
|
||||
|
@ -77,11 +78,60 @@
|
|||
);
|
||||
}
|
||||
$table_data[] = array('key' => __('#Resolved Attributes'), 'value' => $count);
|
||||
$table_data[] = array('key' => __('#Resolved Reports'), 'value' => $report_count);
|
||||
echo $this->element('genericElements/viewMetaTable', array('table_data' => $table_data));
|
||||
}
|
||||
$attributeFields = array('category', 'type', 'value', 'uuid');
|
||||
$header_present = false;
|
||||
$typesWithData = array('attachment', 'malware-sample');
|
||||
?>
|
||||
<?php if (!empty($event['EventReport'])): ?>
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= __('Import') ?></th>
|
||||
<th><?= __('Name') ?></th>
|
||||
<th class="hidden"><?php echo __('UUID');?></th>
|
||||
<th><?= __('Content') ?></th>
|
||||
<th><?= __('Distribution') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($event['EventReport'] as $report): ?>
|
||||
<tr class="MISPEventReport">
|
||||
<td class="short" style="width:40px;text-align:center;">
|
||||
<input type="checkbox" class="ImportMISPEventReport" checked />
|
||||
</td>
|
||||
<td class="EventReportName"><?= h($report['name']); ?></td>
|
||||
<td class="EventReportUUID hidden"><?= h($report['uuid']); ?></td>
|
||||
<td class="EventReportContent ellipsis-overflow" style="max-width:800px;">
|
||||
<?= h($report['content']); ?>
|
||||
</td>
|
||||
<td class="short" style="width:40px;text-align:center;">
|
||||
<select class='EventReportDistribution' style='padding:0px;height:20px;margin-bottom:0px;'>
|
||||
<?php
|
||||
foreach ($distributions as $distKey => $distValue) {
|
||||
echo '<option value="' . h($distKey) . '" ' . ($distKey == $report['distribution'] ? 'selected="selected"' : '') . '>' . h($distValue) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div style="display:none;">
|
||||
<select class='EventReportSharingGroup' style='padding:0px;height:20px;margin-top:3px;margin-bottom:0px;'>
|
||||
<?php
|
||||
foreach ($sgs as $sgKey => $sgValue) {
|
||||
echo '<option value="' . h($sgKey) . '" ' . ($sgKey == $report['sharing_group_id'] ? 'selected="selected"' : '') . '>' . h($sgValue) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<table>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
if (!empty($event['Object'])) {
|
||||
?>
|
||||
<table class="table table-striped table-condensed">
|
||||
|
@ -389,7 +439,7 @@
|
|||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$('.AttributeDistribution, .ObjectDistribution').change(function() {
|
||||
$('.AttributeDistribution, .ObjectDistribution, .EventReportDistribution').change(function() {
|
||||
if ($(this).val() == 4) {
|
||||
$(this).next().show();
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'viewEvent', 'mayModify' => $mayModify, 'mayPublish' => $mayPublish));
|
||||
echo $this->Html->script('doT');
|
||||
echo $this->Html->script('extendext');
|
||||
echo $this->Html->script('moment-with-locales');
|
||||
echo $this->Html->script('moment.min');
|
||||
echo $this->Html->css('query-builder.default');
|
||||
echo $this->Html->script('query-builder');
|
||||
echo $this->Html->css('attack_matrix');
|
||||
|
@ -172,11 +172,11 @@
|
|||
);
|
||||
$table_data[] = array(
|
||||
'key' => __('First recorded change'),
|
||||
'value' => (!$oldest_timestamp) ? '' : date('Y-m-d H:i:s', $oldest_timestamp)
|
||||
'html' => !$oldest_timestamp ? '' : $this->Time->time($oldest_timestamp),
|
||||
);
|
||||
$table_data[] = array(
|
||||
'key' => __('Last change'),
|
||||
'value' => date('Y-m-d H:i:s', $event['Event']['timestamp'])
|
||||
'html' => $this->Time->time($event['Event']['timestamp']),
|
||||
);
|
||||
$table_data[] = array(
|
||||
'key' => __('Modification map'),
|
||||
|
@ -477,33 +477,33 @@
|
|||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="toggleButtons">
|
||||
<button class="btn btn-inverse toggle-left btn.active qet galaxy-toggle-button" id="pivots_toggle" data-toggle-type="pivots">
|
||||
<span class="icon-minus icon-white" title="<?php echo __('Toggle pivot graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle pivot graph');?>" style="vertical-align:top;"></span><?php echo __('Pivots');?>
|
||||
<div id="eventToggleButtons">
|
||||
<button class="btn btn-inverse toggle-left qet" id="pivots_toggle" data-toggle-type="pivots">
|
||||
<span class="fas fa-minus" title="<?php echo __('Toggle pivot graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle pivot graph');?>"></span><?php echo __('Pivots');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="galaxies_toggle" data-toggle-type="galaxies">
|
||||
<span class="icon-minus icon-white" title="<?php echo __('Toggle galaxies');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle galaxies');?>" style="vertical-align:top;"></span><?php echo __('Galaxy');?>
|
||||
<button class="btn btn-inverse toggle qet" id="galaxies_toggle" data-toggle-type="galaxies">
|
||||
<span class="fas fa-minus" title="<?php echo __('Toggle galaxies');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle galaxies');?>"></span><?php echo __('Galaxy');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="eventgraph_toggle" data-toggle-type="eventgraph" onclick="enable_interactive_graph();">
|
||||
<span class="icon-plus icon-white" title="<?php echo __('Toggle Event graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Event graph');?>" style="vertical-align:top;"></span><?php echo __('Event graph');?>
|
||||
<button class="btn btn-inverse toggle qet" id="eventgraph_toggle" data-toggle-type="eventgraph" onclick="enable_interactive_graph();">
|
||||
<span class="fas fa-plus" title="<?php echo __('Toggle Event graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Event graph');?>"></span><?php echo __('Event graph');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="eventtimeline_toggle" data-toggle-type="eventtimeline" onclick="enable_timeline();">
|
||||
<span class="icon-plus icon-white" title="<?php echo __('Toggle Event timeline');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Event timeline');?>" style="vertical-align:top;"></span><?php echo __('Event timeline');?>
|
||||
<button class="btn btn-inverse toggle qet" id="eventtimeline_toggle" data-toggle-type="eventtimeline" onclick="enable_timeline();">
|
||||
<span class="fas fa-plus" title="<?php echo __('Toggle Event timeline');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Event timeline');?>"></span><?php echo __('Event timeline');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="correlationgraph_toggle" data-toggle-type="correlationgraph" data-load-url="<?= $baseurl ?>/events/viewGraph/<?= h($event['Event']['id']) ?>">
|
||||
<span class="icon-plus icon-white" title="<?php echo __('Toggle Correlation graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Correlation graph');?>" style="vertical-align:top;"></span><?php echo __('Correlation graph');?>
|
||||
<button class="btn btn-inverse toggle qet" id="correlationgraph_toggle" data-toggle-type="correlationgraph" data-load-url="<?= $baseurl ?>/events/viewGraph/<?= h($event['Event']['id']) ?>">
|
||||
<span class="fas fa-plus" title="<?php echo __('Toggle Correlation graph');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle Correlation graph');?>"></span><?php echo __('Correlation graph');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="attackmatrix_toggle" data-toggle-type="attackmatrix" data-load-url="<?= $baseurl; ?>/events/viewGalaxyMatrix/<?= h($event['Event']['id']) ?>/mitre-attack/event/1">
|
||||
<span class="icon-plus icon-white" title="<?php echo __('Toggle ATT&CK matrix');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle ATT&CK matrix');?>" style="vertical-align:top;"></span><?php echo __('ATT&CK matrix');?>
|
||||
<button class="btn btn-inverse toggle qet" id="attackmatrix_toggle" data-toggle-type="attackmatrix" data-load-url="<?= $baseurl; ?>/events/viewGalaxyMatrix/<?= h($event['Event']['id']) ?>/mitre-attack/event/1">
|
||||
<span class="fas fa-plus" title="<?php echo __('Toggle ATT&CK matrix');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle ATT&CK matrix');?>"></span><?php echo __('ATT&CK matrix');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="eventreport_toggle" data-toggle-type="eventreport">
|
||||
<span class="icon-plus icon-white" title="<?php echo __('Toggle reports');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle reports');?>" style="vertical-align:top;"></span><?php echo __('Event reports');?>
|
||||
<button class="btn btn-inverse toggle qet" id="eventreport_toggle" data-toggle-type="eventreport">
|
||||
<span class="fas fa-plus" title="<?php echo __('Toggle reports');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle reports');?>"></span><?php echo __('Event reports');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle qet galaxy-toggle-button" id="attributes_toggle" data-toggle-type="attributes">
|
||||
<span class="icon-minus icon-white" title="<?php echo __('Toggle attributes');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle attributes');?>" style="vertical-align:top;"></span><?php echo __('Attributes');?>
|
||||
<button class="btn btn-inverse toggle qet" id="attributes_toggle" data-toggle-type="attributes">
|
||||
<span class="fas fa-minus" title="<?php echo __('Toggle attributes');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle attributes');?>"></span><?php echo __('Attributes');?>
|
||||
</button>
|
||||
<button class="btn btn-inverse toggle-right qet galaxy-toggle-button" id="discussions_toggle" data-toggle-type="discussions">
|
||||
<span class="icon-minus icon-white" title="<?php echo __('Toggle discussions');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle discussions');?>" style="vertical-align:top;"></span><?php echo __('Discussion');?>
|
||||
<button class="btn btn-inverse toggle-right qet" id="discussions_toggle" data-toggle-type="discussions">
|
||||
<span class="fas fa-minus" title="<?php echo __('Toggle discussions');?>" role="button" tabindex="0" aria-label="<?php echo __('Toggle discussions');?>"></span><?php echo __('Discussion');?>
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
|
|
|
@ -191,7 +191,8 @@
|
|||
'name' => __('Tag'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'Tag',
|
||||
'element' => 'tags'
|
||||
'element' => 'tags',
|
||||
'scope' => 'feeds'
|
||||
),
|
||||
array(
|
||||
'name' => __('Visible'),
|
||||
|
|
|
@ -96,8 +96,8 @@
|
|||
<div class="row-fuild">
|
||||
<div id="relations_container"></div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div id="elements_div" class="span8"></div>
|
||||
<div class="">
|
||||
<div id="elements_div"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
'fields' => array(
|
||||
array(
|
||||
'name' => __('Id'),
|
||||
'sort' => 'id',
|
||||
'class' => 'short',
|
||||
'data_path' => 'GalaxyClusterRelation.id',
|
||||
'data_path' => 'id',
|
||||
),
|
||||
array(
|
||||
'name' => __('Default'),
|
||||
|
@ -18,23 +17,21 @@
|
|||
),
|
||||
array(
|
||||
'name' => __('Galaxy Cluster Target (galaxy :: cluster)'),
|
||||
'sort' => 'TargetCluster.tag_name',
|
||||
'element' => 'galaxy_cluster_link',
|
||||
'data_path' => 'TargetCluster',
|
||||
'data_path_relation' => 'GalaxyClusterRelation',
|
||||
'url_params_data_paths' => 'TargetCluster.id',
|
||||
'data_path' => 'GalaxyCluster',
|
||||
'data_path_relation' => '',
|
||||
'url_params_data_paths' => 'GalaxyCluster.id',
|
||||
'url' => $baseurl . '/galaxy_clusters/view'
|
||||
),
|
||||
array(
|
||||
'name' => __('Relationship Type'),
|
||||
'sort' => 'type',
|
||||
'class' => 'short',
|
||||
'data_path' => 'GalaxyClusterRelation.referenced_galaxy_cluster_type',
|
||||
'data_path' => 'referenced_galaxy_cluster_type',
|
||||
),
|
||||
array(
|
||||
'name' => __('Relationship Tag'),
|
||||
'class' => 'short',
|
||||
'data_path' => 'GalaxyClusterRelationTag.{n}.Tag',
|
||||
'data_path' => 'Tag',
|
||||
'element' => 'tags',
|
||||
'elementParams' => array(
|
||||
'searchScope' => 'taxonomy'
|
||||
|
@ -43,18 +40,16 @@
|
|||
),
|
||||
array(
|
||||
'name' => __('Distribution'),
|
||||
'sort' => 'distribution',
|
||||
'data_path' => 'GalaxyClusterRelation.distribution',
|
||||
'data_path' => 'distribution',
|
||||
'element' => 'distribution_levels',
|
||||
),
|
||||
),
|
||||
'title' => __('Galaxy Cluster Relationships'),
|
||||
'actions' => array(
|
||||
array(
|
||||
'title' => 'Edit',
|
||||
'url' => '/galaxy_cluster_relations/edit',
|
||||
'url_params_data_paths' => array(
|
||||
'GalaxyClusterRelation.id'
|
||||
'id'
|
||||
),
|
||||
'icon' => 'edit',
|
||||
'complex_requirement' => array(
|
||||
|
@ -71,7 +66,7 @@
|
|||
'title' => 'Delete',
|
||||
'url' => '/galaxy_cluster_relations/delete',
|
||||
'url_params_data_paths' => array(
|
||||
'GalaxyClusterRelation.id'
|
||||
'id'
|
||||
),
|
||||
'postLink' => true,
|
||||
'postLinkConfirm' => __('Are you sure you want to delete the Relationship?'),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue