From 2ea4b37368a1166341535af934874b6e27dc9601 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Wed, 4 Sep 2019 18:09:49 +0200 Subject: [PATCH 01/22] fix: [UI] GPG keys are fetched from CIRCL keyserver --- app/Locale/ara/LC_MESSAGES/default.po | 2 +- app/Locale/cze/LC_MESSAGES/default.po | 2 +- app/Locale/dan/LC_MESSAGES/default.po | 2 +- app/Locale/default.pot | 2 +- app/Locale/deu/LC_MESSAGES/default.po | 2 +- app/Locale/fra/LC_MESSAGES/default.po | 4 ++-- app/Locale/hun/LC_MESSAGES/default.po | 2 +- app/Locale/ita/LC_MESSAGES/default.po | 2 +- app/Locale/jpn/LC_MESSAGES/default.po | 4 ++-- app/Locale/kor/LC_MESSAGES/default.po | 2 +- app/Locale/no/LC_MESSAGES/default.po | 4 ++-- app/Locale/pol/LC_MESSAGES/default.po | 2 +- app/Locale/pt/LC_MESSAGES/default.po | 2 +- app/Locale/pt_BR/LC_MESSAGES/default.po | 2 +- app/Locale/rus/LC_MESSAGES/default.po | 4 ++-- app/Locale/spa/LC_MESSAGES/default.po | 2 +- app/Locale/swe/LC_MESSAGES/default.po | 2 +- app/Locale/ukr/LC_MESSAGES/default.po | 2 +- app/Locale/zh-s/LC_MESSAGES/default.po | 2 +- app/View/Users/admin_add.ctp | 2 +- app/View/Users/admin_edit.ctp | 2 +- app/View/Users/edit.ctp | 2 +- 22 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/Locale/ara/LC_MESSAGES/default.po b/app/Locale/ara/LC_MESSAGES/default.po index 2b5848b5f..23faf772b 100644 --- a/app/Locale/ara/LC_MESSAGES/default.po +++ b/app/Locale/ara/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/cze/LC_MESSAGES/default.po b/app/Locale/cze/LC_MESSAGES/default.po index 2847e371a..aaf3b4408 100644 --- a/app/Locale/cze/LC_MESSAGES/default.po +++ b/app/Locale/cze/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/dan/LC_MESSAGES/default.po b/app/Locale/dan/LC_MESSAGES/default.po index 98332b8c9..daa553558 100644 --- a/app/Locale/dan/LC_MESSAGES/default.po +++ b/app/Locale/dan/LC_MESSAGES/default.po @@ -15325,7 +15325,7 @@ msgstr "Synkroniser bruger for" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/default.pot b/app/Locale/default.pot index d9fa17a8c..6ddbeb117 100755 --- a/app/Locale/default.pot +++ b/app/Locale/default.pot @@ -15821,7 +15821,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 #: View/Users/edit.ctp:23 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/deu/LC_MESSAGES/default.po b/app/Locale/deu/LC_MESSAGES/default.po index 64146b78f..fcacebfab 100644 --- a/app/Locale/deu/LC_MESSAGES/default.po +++ b/app/Locale/deu/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/fra/LC_MESSAGES/default.po b/app/Locale/fra/LC_MESSAGES/default.po index c23e6647b..2c2e91dc0 100644 --- a/app/Locale/fra/LC_MESSAGES/default.po +++ b/app/Locale/fra/LC_MESSAGES/default.po @@ -15355,8 +15355,8 @@ msgstr "Synchroniser l'utilisateur pour" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." -msgstr "Coller ici la clé GnuPG de l’utilisateur, ou essayer de le récupérer depuis le serveur de clés du MIT en cliquant sur « Fetch GnuPG key » ci-dessous." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." +msgstr "Coller ici la clé GnuPG de l’utilisateur, ou essayer de le récupérer depuis le serveur de clés du CIRCL en cliquant sur « Fetch GnuPG key » ci-dessous." #: View/Users/admin_add.ctp:72 #: View/Users/admin_edit.ctp:66 diff --git a/app/Locale/hun/LC_MESSAGES/default.po b/app/Locale/hun/LC_MESSAGES/default.po index 615beaaa8..f7a5a0c22 100644 --- a/app/Locale/hun/LC_MESSAGES/default.po +++ b/app/Locale/hun/LC_MESSAGES/default.po @@ -12464,7 +12464,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/ita/LC_MESSAGES/default.po b/app/Locale/ita/LC_MESSAGES/default.po index 1a8b013d5..c27878e0f 100644 --- a/app/Locale/ita/LC_MESSAGES/default.po +++ b/app/Locale/ita/LC_MESSAGES/default.po @@ -13164,7 +13164,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/jpn/LC_MESSAGES/default.po b/app/Locale/jpn/LC_MESSAGES/default.po index 9b975751f..bdb9dc720 100644 --- a/app/Locale/jpn/LC_MESSAGES/default.po +++ b/app/Locale/jpn/LC_MESSAGES/default.po @@ -15347,8 +15347,8 @@ msgstr "同期ユーザー用" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." -msgstr "ユーザーの GnuPG キーをここに貼り付けるか、下の \"GnuPG キーを取得\"をクリックして MIT キーサーバーから取得します。" +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." +msgstr "ユーザーの GnuPG キーをここに貼り付けるか、下の \"GnuPG キーを取得\"をクリックして CIRCL キーサーバーから取得します。" #: View/Users/admin_add.ctp:72 #: View/Users/admin_edit.ctp:66 diff --git a/app/Locale/kor/LC_MESSAGES/default.po b/app/Locale/kor/LC_MESSAGES/default.po index 95979ce45..55eb598d2 100644 --- a/app/Locale/kor/LC_MESSAGES/default.po +++ b/app/Locale/kor/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/no/LC_MESSAGES/default.po b/app/Locale/no/LC_MESSAGES/default.po index 7141c5b59..4754289b3 100644 --- a/app/Locale/no/LC_MESSAGES/default.po +++ b/app/Locale/no/LC_MESSAGES/default.po @@ -15945,8 +15945,8 @@ msgstr "Synkroniser brukeren for" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 #: View/Users/edit.ctp:23 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." -msgstr "Lim inn brukerens GnuPG-nøkkel her, eller prøv å hente den fra MIT-nøkkelserveren ved å klikke på \"Hent GnuPG-nøkkel\" nedenfor." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." +msgstr "Lim inn brukerens GnuPG-nøkkel her, eller prøv å hente den fra CIRCL-nøkkelserveren ved å klikke på \"Hent GnuPG-nøkkel\" nedenfor." #: View/Users/admin_add.ctp:72 #: View/Users/admin_edit.ctp:66 diff --git a/app/Locale/pol/LC_MESSAGES/default.po b/app/Locale/pol/LC_MESSAGES/default.po index 34139e42c..f6df25cfb 100644 --- a/app/Locale/pol/LC_MESSAGES/default.po +++ b/app/Locale/pol/LC_MESSAGES/default.po @@ -13159,7 +13159,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/pt/LC_MESSAGES/default.po b/app/Locale/pt/LC_MESSAGES/default.po index 1a4881c2c..6b33117ef 100644 --- a/app/Locale/pt/LC_MESSAGES/default.po +++ b/app/Locale/pt/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/pt_BR/LC_MESSAGES/default.po b/app/Locale/pt_BR/LC_MESSAGES/default.po index 59f1d17aa..c2f54ea88 100644 --- a/app/Locale/pt_BR/LC_MESSAGES/default.po +++ b/app/Locale/pt_BR/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/rus/LC_MESSAGES/default.po b/app/Locale/rus/LC_MESSAGES/default.po index d4504f587..30c1ead93 100644 --- a/app/Locale/rus/LC_MESSAGES/default.po +++ b/app/Locale/rus/LC_MESSAGES/default.po @@ -15332,8 +15332,8 @@ msgstr "Синхронизировать пользователя" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." -msgstr "Вставьте GnuPG ключ пользователя сюда или нажмите кнопку \"Получить GnuPG ключ\" для получения ключа с сервера MIT." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." +msgstr "Вставьте GnuPG ключ пользователя сюда или нажмите кнопку \"Получить GnuPG ключ\" для получения ключа с сервера CIRCL." #: View/Users/admin_add.ctp:72 #: View/Users/admin_edit.ctp:66 diff --git a/app/Locale/spa/LC_MESSAGES/default.po b/app/Locale/spa/LC_MESSAGES/default.po index de627d3a7..6c5dddc49 100644 --- a/app/Locale/spa/LC_MESSAGES/default.po +++ b/app/Locale/spa/LC_MESSAGES/default.po @@ -15316,7 +15316,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/swe/LC_MESSAGES/default.po b/app/Locale/swe/LC_MESSAGES/default.po index 50ca88dfa..a78148119 100644 --- a/app/Locale/swe/LC_MESSAGES/default.po +++ b/app/Locale/swe/LC_MESSAGES/default.po @@ -13159,7 +13159,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/ukr/LC_MESSAGES/default.po b/app/Locale/ukr/LC_MESSAGES/default.po index d824a089a..5ad653747 100644 --- a/app/Locale/ukr/LC_MESSAGES/default.po +++ b/app/Locale/ukr/LC_MESSAGES/default.po @@ -12464,7 +12464,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/Locale/zh-s/LC_MESSAGES/default.po b/app/Locale/zh-s/LC_MESSAGES/default.po index a61ed4168..5b0973883 100644 --- a/app/Locale/zh-s/LC_MESSAGES/default.po +++ b/app/Locale/zh-s/LC_MESSAGES/default.po @@ -13159,7 +13159,7 @@ msgstr "" #: View/Users/admin_add.ctp:70 #: View/Users/admin_edit.ctp:64 -msgid "Paste the user's GnuPG key here or try to retrieve it from the MIT key server by clicking on \"Fetch GnuPG key\" below." +msgid "Paste the user's GnuPG key here or try to retrieve it from the CIRCL key server by clicking on \"Fetch GnuPG key\" below." msgstr "" #: View/Users/admin_add.ctp:72 diff --git a/app/View/Users/admin_add.ctp b/app/View/Users/admin_add.ctp index 9f79adefc..a8c517369 100644 --- a/app/View/Users/admin_add.ctp +++ b/app/View/Users/admin_add.ctp @@ -67,7 +67,7 @@ ?> Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.'))); + echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the CIRCL key server by clicking on "Fetch GnuPG key" below.'))); ?>
Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.'))); + echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the CIRCL key server by clicking on "Fetch GnuPG key" below.'))); ?>
Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.'))); + echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the CIRCL key server by clicking on "Fetch GnuPG key" below.'))); ?>
Date: Thu, 5 Sep 2019 10:42:08 +0200 Subject: [PATCH 02/22] Loose a find when adding existing event --- app/Model/Event.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Model/Event.php b/app/Model/Event.php index 58f62cd54..9985b1319 100755 --- a/app/Model/Event.php +++ b/app/Model/Event.php @@ -3453,13 +3453,12 @@ class Event extends AppModel } if (isset($data['Event']['uuid'])) { // check if the uuid already exists - $existingEventCount = $this->find('count', array('conditions' => array('Event.uuid' => $data['Event']['uuid']))); - if ($existingEventCount > 0) { + $existingEvent = $this->find('first', array('conditions' => array('Event.uuid' => $data['Event']['uuid']))); + if ($existingEvent) { // RESTful, set response location header so client can find right URL to edit if ($fromPull) { return false; } - $existingEvent = $this->find('first', array('conditions' => array('Event.uuid' => $data['Event']['uuid']))); if ($fromXml) { $created_id = $existingEvent['Event']['id']; } From 9ebd5f21be9713bed158d09da3efc77925269997 Mon Sep 17 00:00:00 2001 From: Richard van den Berg Date: Thu, 5 Sep 2019 15:22:38 +0200 Subject: [PATCH 03/22] Log all errors from server pull --- app/Locale/ara/LC_MESSAGES/default.po | 2 +- app/Locale/cze/LC_MESSAGES/default.po | 2 +- app/Locale/dan/LC_MESSAGES/default.po | 2 +- app/Locale/default.pot | 2 +- app/Locale/deu/LC_MESSAGES/default.po | 2 +- app/Locale/fra/LC_MESSAGES/default.po | 2 +- app/Locale/jpn/LC_MESSAGES/default.po | 2 +- app/Locale/kor/LC_MESSAGES/default.po | 2 +- app/Locale/no/LC_MESSAGES/default.po | 4 ++-- app/Locale/pt/LC_MESSAGES/default.po | 2 +- app/Locale/pt_BR/LC_MESSAGES/default.po | 2 +- app/Locale/rus/LC_MESSAGES/default.po | 2 +- app/Locale/spa/LC_MESSAGES/default.po | 2 +- app/Model/Server.php | 5 ++--- 14 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/Locale/ara/LC_MESSAGES/default.po b/app/Locale/ara/LC_MESSAGES/default.po index 2b5848b5f..a75a59afe 100644 --- a/app/Locale/ara/LC_MESSAGES/default.po +++ b/app/Locale/ara/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/cze/LC_MESSAGES/default.po b/app/Locale/cze/LC_MESSAGES/default.po index 2847e371a..783e6209b 100644 --- a/app/Locale/cze/LC_MESSAGES/default.po +++ b/app/Locale/cze/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/dan/LC_MESSAGES/default.po b/app/Locale/dan/LC_MESSAGES/default.po index 98332b8c9..8670f28ef 100644 --- a/app/Locale/dan/LC_MESSAGES/default.po +++ b/app/Locale/dan/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "Instansens debug-niveauet for webstedsadmins. Denne funktion lader webstedsadmins eksekvere debug-tilstand på en idriftsat instans uden at afsløre dette overfor andre brugere. Den mest detaljerigholdige Indstilling for debug og site_admin_debug benyttes for admins." #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/default.pot b/app/Locale/default.pot index d9fa17a8c..780f7d895 100755 --- a/app/Locale/default.pot +++ b/app/Locale/default.pot @@ -3890,7 +3890,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2254 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2258 diff --git a/app/Locale/deu/LC_MESSAGES/default.po b/app/Locale/deu/LC_MESSAGES/default.po index 64146b78f..a64ba0cbb 100644 --- a/app/Locale/deu/LC_MESSAGES/default.po +++ b/app/Locale/deu/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/fra/LC_MESSAGES/default.po b/app/Locale/fra/LC_MESSAGES/default.po index c23e6647b..fa52563d4 100644 --- a/app/Locale/fra/LC_MESSAGES/default.po +++ b/app/Locale/fra/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "Le niveau de debuggage de l'instance pour les adminstrateurs. Cette option permet aux administrateurs de l'instance de lancer le mode debug sur une instance active sans exposer les autres utilisateurs. L'option la plus verbeuse de debug et site_admin_debug sont utilisés pour les administrateurs d'instance." #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/jpn/LC_MESSAGES/default.po b/app/Locale/jpn/LC_MESSAGES/default.po index 9b975751f..4df330392 100644 --- a/app/Locale/jpn/LC_MESSAGES/default.po +++ b/app/Locale/jpn/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "サイト管理者用のインスタンスのデバッグレベル。 この機能により、サイト管理者は、他のユーザーに公開することなく、動作中のインスタンスでデバッグモードを実行できます。 debug と site_admin_debug の最も冗長なオプションは、サイト管理者に使用されます。" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/kor/LC_MESSAGES/default.po b/app/Locale/kor/LC_MESSAGES/default.po index 95979ce45..43a013331 100644 --- a/app/Locale/kor/LC_MESSAGES/default.po +++ b/app/Locale/kor/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/no/LC_MESSAGES/default.po b/app/Locale/no/LC_MESSAGES/default.po index 7141c5b59..fc9ecb668 100644 --- a/app/Locale/no/LC_MESSAGES/default.po +++ b/app/Locale/no/LC_MESSAGES/default.po @@ -3891,8 +3891,8 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "Feilsøkingsnivået for forekomsten for nettstedadministratorer. Denne funksjonen tillater at webansvarlige kan kjøre feilsøkingsmodus på en levende forekomst uten å utsette den for andre brukere. Det mest fordelaktige alternativet for feilsøking og site_admin_debug brukes til administratorer på nettstedet." #: Model/Server.php:2254 -msgid "Failed (partially?) because of validation errors: " -msgstr "Mislyktes (delvis?) På grunn av valideringsfeil: " +msgid "Failed (partially?) because of errors: " +msgstr "Mislyktes (delvis?) På grunn av feil: " #: Model/Server.php:2258 msgid "Blocked an edit to an event that was created locally. This can happen if a synchronised event that was created on this instance was modified by an administrator on the remote side." diff --git a/app/Locale/pt/LC_MESSAGES/default.po b/app/Locale/pt/LC_MESSAGES/default.po index 1a4881c2c..71bf5f4a2 100644 --- a/app/Locale/pt/LC_MESSAGES/default.po +++ b/app/Locale/pt/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/pt_BR/LC_MESSAGES/default.po b/app/Locale/pt_BR/LC_MESSAGES/default.po index 59f1d17aa..484390865 100644 --- a/app/Locale/pt_BR/LC_MESSAGES/default.po +++ b/app/Locale/pt_BR/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/rus/LC_MESSAGES/default.po b/app/Locale/rus/LC_MESSAGES/default.po index d4504f587..3661175c8 100644 --- a/app/Locale/rus/LC_MESSAGES/default.po +++ b/app/Locale/rus/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "Уровень отладки приложения для администраторов сайта. Данный функционал позволяет администраторам сайта включать режим отладки на рабтающих инстансах без воздействия на других пользователей." #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Locale/spa/LC_MESSAGES/default.po b/app/Locale/spa/LC_MESSAGES/default.po index de627d3a7..a1e94e116 100644 --- a/app/Locale/spa/LC_MESSAGES/default.po +++ b/app/Locale/spa/LC_MESSAGES/default.po @@ -3705,7 +3705,7 @@ msgid "The debug level of the instance for site admins. This feature allows site msgstr "" #: Model/Server.php:2172 -msgid "Failed (partially?) because of validation errors: " +msgid "Failed (partially?) because of errors: " msgstr "" #: Model/Server.php:2176 diff --git a/app/Model/Server.php b/app/Model/Server.php index f1c6c028b..88dbc0c06 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -2289,10 +2289,10 @@ class Server extends AppModel if (!$existingEvent) { // add data for newly imported events $result = $eventModel->_add($event, true, $user, $server['Server']['org_id'], $passAlong, true, $jobId); - if ($result) { + if ($result === true) { $successes[] = $eventId; } else { - $fails[$eventId] = __('Failed (partially?) because of validation errors: ') . json_encode($eventModel->validationErrors, true); + $fails[$eventId] = __('Failed (partially?) because of errors: ') . $result; } } else { if (!$existingEvent['Event']['locked'] && !$server['Server']['internal']) { @@ -2316,7 +2316,6 @@ class Server extends AppModel $eventId, $server ); - ; if (!empty($event)) { if ($this->__checkIfEventIsBlockedBeforePull($event)) { return false; From e53ec5b0c8e5bc1b6a4159e4dccd236327c4722e Mon Sep 17 00:00:00 2001 From: Richard van den Berg Date: Thu, 5 Sep 2019 15:29:23 +0200 Subject: [PATCH 04/22] Log reason for event download failure --- app/Model/Server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Model/Server.php b/app/Model/Server.php index 88dbc0c06..71baf3af7 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -2328,7 +2328,7 @@ class Server extends AppModel } } else { // error - $fails[$eventId] = __('failed downloading the event'); + $fails[$eventId] = __('failed downloading the event') . ': ' . json_encode($event); } return true; } From 7904509fde0a1ec78a0e3d11bc6ebf6060dc0ace Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Thu, 5 Sep 2019 19:16:26 +0200 Subject: [PATCH 05/22] fix: [feed] Fetching event manifest --- app/Model/Feed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Model/Feed.php b/app/Model/Feed.php index 413230460..661a1fe0a 100644 --- a/app/Model/Feed.php +++ b/app/Model/Feed.php @@ -521,7 +521,7 @@ class Feed extends AppModel return true; } - private function __filterEventsIndex($events, $feed, $filterRules) + private function __filterEventsIndex($events, $feed) { $filterRules = $this->__prepareFilterRules($feed); if (!$filterRules) { From 41f5c88c74fa9cf048c725248f625bc12960d0e5 Mon Sep 17 00:00:00 2001 From: iglocska Date: Fri, 6 Sep 2019 10:59:48 +0200 Subject: [PATCH 06/22] fix: [sync] Fixed major performance blocker - fix based on the insights of @RichieB2B, the hero we need, not the one we deserve - added orgc_uuid to the minimal event index - added handlers for it on the pull side - when pulling from old instances the new functionality is skipped, resulting in the behaviour we had pre-patch - both sides of the sync are encouraged to update, especially if the slow pulls are causing issues --- app/Controller/EventsController.php | 2 ++ app/Model/Server.php | 46 +++++++++++++++++++---------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 691ea59cf..8734715e0 100644 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -730,6 +730,7 @@ class EventsController extends AppController unset($rules['contain']); $rules['recursive'] = -1; $rules['fields'] = array('id', 'timestamp', 'published', 'uuid'); + $rules['contain'] = array('Orgc.uuid'); } $paginationRules = array('page', 'limit', 'sort', 'direction', 'order'); foreach ($paginationRules as $paginationRule) { @@ -835,6 +836,7 @@ class EventsController extends AppController return $this->RestResponse->viewData($events, $this->response->type(), false, false, false, array('X-Result-Count' => $absolute_total)); } else { foreach ($events as $key => $event) { + $event['Event']['orgc_uuid'] = $event['Orgc']['uuid']; $events[$key] = $event['Event']; } return $this->RestResponse->viewData($events, $this->response->type(), false, false, false, array('X-Result-Count' => $absolute_total)); diff --git a/app/Model/Server.php b/app/Model/Server.php index f1c6c028b..4ed7d8135 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -2528,6 +2528,7 @@ class Server extends AppModel $request = $this->setupSyncRequest($server); $uri = $url . '/events/index'; $filter_rules['minimal'] = 1; + $filter_rules['published'] = 1; try { $response = $HttpSocket->post($uri, json_encode($filter_rules), $request); if ($response->isOk()) { @@ -2549,9 +2550,38 @@ class Server extends AppModel } else { // multiple events, iterate over the array $this->Event = ClassRegistry::init('Event'); + $blacklisting = array(); + if (Configure::read('MISP.enableEventBlacklisting') !== false) { + $this->EventBlacklist = ClassRegistry::init('EventBlacklist'); + $blacklisting['EventBlacklist'] = array( + 'index_field' => 'uuid', + 'blacklist_field' => 'event_uuid' + ); + } + if (Configure::read('MISP.enableOrgBlacklisting') !== false) { + $this->OrgBlacklist = ClassRegistry::init('OrgBlacklist'); + $blacklisting['OrgBlacklist'] = array( + 'index_field' => 'orgc_uuid', + 'blacklist_field' => 'org_uuid' + ); + } foreach ($eventArray as $k => $event) { if (1 != $event['published']) { unset($eventArray[$k]); // do not keep non-published events + continue; + } + foreach ($blacklisting as $type => $blacklist) { + if (!empty($eventArray[$k][$blacklist['index_field']])) { + $blacklist_hit = $this->{$type}->find('first', array( + 'conditions' => array($blacklist['blacklist_field'] => $eventArray[$k][$blacklist['index_field']]), + 'recursive' => -1, + 'fields' => array($type . '.id') + )); + if (!empty($blacklist_hit)) { + unset($eventArray[$k]); + continue 2; + } + } } } $this->Event->removeOlder($eventArray); @@ -2565,20 +2595,6 @@ class Server extends AppModel } } } - if (!empty($eventIds) && Configure::read('MISP.enableEventBlacklisting') !== false) { - $this->EventBlacklist = ClassRegistry::init('EventBlacklist'); - foreach ($eventIds as $k => $eventUuid) { - $blacklistEntry = $this->EventBlacklist->find('first', array( - 'conditions' => array('event_uuid' => $eventUuid), - 'recursive' => -1, - 'fields' => array('EventBlacklist.id') - )); - if (!empty($blacklistEntry)) { - unset($eventIds[$k]); - } - } - } - $eventIds = array_values($eventIds); return $eventIds; } if ($response->code == '403') { @@ -4193,7 +4209,7 @@ class Server extends AppModel } return $result; } - + } public function writeableDirsDiagnostics(&$diagnostic_errors) From 6f4b99026e05ba4886a4cde7f6c00f21d9bde841 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 6 Sep 2019 13:59:47 +0200 Subject: [PATCH 07/22] chg: [user] Remove unused private method --- app/Model/User.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/app/Model/User.php b/app/Model/User.php index 26168efc6..d6e6cd6df 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -216,26 +216,6 @@ class User extends AppModel 'Containable' ); - private function __generatePassword() - { - $groups = array( - '0123456789', - 'abcdefghijklmnopqrstuvwxyz', - 'ABCDEFGHIJKLOMNOPQRSTUVWXYZ', - '!@#$%^&*()_-' - ); - $passwordLength = (Configure::read('Security.password_policy_length') && Configure::read('Security.password_policy_length') >= 12) ? Configure::read('Security.password_policy_length') : 12; - $pw = ''; - for ($i = 0; $i < $passwordLength; $i++) { - $chars = implode('', $groups); - $pw .= $chars[mt_rand(0, strlen($chars)-1)]; - } - foreach ($groups as $group) { - $pw .= $group[mt_rand(0, strlen($group)-1)]; - } - return $pw; - } - public function beforeValidate($options = array()) { if (!isset($this->data['User']['id'])) { From 5e1a26afa0e08ac3d753754a6c8e23479c98cfa6 Mon Sep 17 00:00:00 2001 From: iglocska Date: Fri, 6 Sep 2019 15:54:58 +0200 Subject: [PATCH 08/22] fix: [internal] orgs restricted to a domain displayed incorrectly - afterfind messes up the keys by reusing the same var for an inner loop --- app/Model/Organisation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Model/Organisation.php b/app/Model/Organisation.php index 7de15e33a..5aa68c2cc 100644 --- a/app/Model/Organisation.php +++ b/app/Model/Organisation.php @@ -138,8 +138,8 @@ class Organisation extends AppModel foreach ($results as $k => $organisation) { if (!empty($organisation['Organisation']['restricted_to_domain'])) { $results[$k]['Organisation']['restricted_to_domain'] = json_decode($organisation['Organisation']['restricted_to_domain'], true); - foreach ($results[$k]['Organisation']['restricted_to_domain'] as $k => $v) { - $results[$k]['Organisation']['restricted_to_domain'][$k] = trim($v); + foreach ($results[$k]['Organisation']['restricted_to_domain'] as $k2 => $v) { + $results[$k]['Organisation']['restricted_to_domain'][$k2] = trim($v); } } else if (isset($organisation['Organisation']['restricted_to_domain'])){ $results[$k]['Organisation']['restricted_to_domain'] = array(); From f63cfc9c5a4e237ba37c532570d46058021c26d6 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 6 Sep 2019 15:56:01 +0200 Subject: [PATCH 09/22] fix: [UI] Fetching GPG keys This error was introduced in 600e54051694ca4d479a9e2c82db45fe19a46a6c --- app/Model/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Model/User.php b/app/Model/User.php index d6e6cd6df..94512f979 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -1057,7 +1057,7 @@ class User extends AppModel 'fingerprint' => chunk_split($parts[1], 4, ' '), 'key_id' => substr($parts[1], -8), 'date' => date('Y-m-d', $parts[4]), - 'uri' => 'pks/lookup?op=get&search=0x' . $parts[1], + 'uri' => '/pks/lookup?op=get&search=0x' . $parts[1], ); } else if ($parts[0] === 'uid' && !empty($temp)) { From 9d3e340b52e65e3b1b3c4e5e728cb8ae11087dc4 Mon Sep 17 00:00:00 2001 From: chrisr3d Date: Fri, 6 Sep 2019 17:06:38 +0200 Subject: [PATCH 10/22] fix: [stix2 import] Fixed hash patterns import for external STIX files --- app/files/scripts/stix2/stix2misp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/files/scripts/stix2/stix2misp.py b/app/files/scripts/stix2/stix2misp.py index ba246d8f1..a48a1a915 100644 --- a/app/files/scripts/stix2/stix2misp.py +++ b/app/files/scripts/stix2/stix2misp.py @@ -216,7 +216,7 @@ class StixParser(): attributes = [] for type_, value in zip(types, values): if 'hashes' in type_: - hash_type = type_.split('.')[1] + hash_type = type_.split('.')[1].strip("'").replace('-', '').lower() attributes.append({'type': hash_type, 'value': value, 'object_relation': hash_type, 'to_ids': True}) else: From a0733e6429f92cffef487a871dc6e0597cca4abe Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 6 Sep 2019 18:48:33 +0200 Subject: [PATCH 11/22] fix: [UI] Removed duplicate button title in userIndexTable.ctp --- app/View/Elements/Users/userIndexTable.ctp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/View/Elements/Users/userIndexTable.ctp b/app/View/Elements/Users/userIndexTable.ctp index 5e2bd1df7..2e171d6ec 100644 --- a/app/View/Elements/Users/userIndexTable.ctp +++ b/app/View/Elements/Users/userIndexTable.ctp @@ -85,7 +85,7 @@ - + Html->link('', array('admin' => true, 'action' => 'edit', $user['User']['id']), array('class' => 'fa fa-edit', 'title' => __('Edit'), 'aria-label' => __('Edit'))); echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $user['User']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to delete # %s? It is highly recommended to never delete users but to disable them instead.', $user['User']['id'])); From 863e38807d77384cc64646a76706d25a6121ea83 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 6 Sep 2019 21:31:16 +0200 Subject: [PATCH 12/22] chg: Allow to load Crypt_GPG from composer --- app/Model/Server.php | 13 +++++++++++-- app/Model/User.php | 41 ++++++++++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/app/Model/Server.php b/app/Model/Server.php index 2d1cd1e74..eaabb73c7 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -4330,8 +4330,17 @@ class Server extends AppModel if (Configure::read('GnuPG.email') && Configure::read('GnuPG.homedir')) { $continue = true; try { - require_once 'Crypt/GPG.php'; - $gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'), 'gpgconf' => Configure::read('GnuPG.gpgconf'), 'binary' => (Configure::read('GnuPG.binary') ? Configure::read('GnuPG.binary') : '/usr/bin/gpg'))); + if (!class_exists('Crypt_GPG')) { + if (!stream_resolve_include_path('Crypt/GPG.php')) { + throw new Exception("Crypt_GPG is not installed"); + } + require_once 'Crypt/GPG.php'; + } + $gpg = new Crypt_GPG(array( + 'homedir' => Configure::read('GnuPG.homedir'), + 'gpgconf' => Configure::read('GnuPG.gpgconf'), + 'binary' => Configure::read('GnuPG.binary') ?: '/usr/bin/gpg' + )); } catch (Exception $e) { $gpgStatus = 2; $continue = false; diff --git a/app/Model/User.php b/app/Model/User.php index 94512f979..379ea04ab 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -306,8 +306,7 @@ class User extends AppModel // we have a clean, hopefully public, key here try { - require_once 'Crypt/GPG.php'; - $gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'), 'gpgconf' => Configure::read('GnuPG.gpgconf'), 'binary' => (Configure::read('GnuPG.binary') ? Configure::read('GnuPG.binary') : '/usr/bin/gpg'))); + $gpg = $this->initializeGpg(); try { $keyImportOutput = $gpg->importKey($check['gpgkey']); if (!empty($keyImportOutput['fingerprint'])) { @@ -379,7 +378,7 @@ class User extends AppModel return preg_match($regex, $value); } - public function identicalFieldValues($field=array(), $compareField=null) + public function identicalFieldValues($field = array(), $compareField = null) { foreach ($field as $key => $value) { $v1 = $value; @@ -450,10 +449,9 @@ class User extends AppModel { if (!$gpg) { try { - require_once 'Crypt/GPG.php'; - $gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'), 'gpgconf' => Configure::read('GnuPG.gpgconf'), 'binary' => (Configure::read('GnuPG.binary') ? Configure::read('GnuPG.binary') : '/usr/bin/gpg'))); + $gpg = $this->initializeGpg(); } catch (Exception $e) { - $result[2] ='GnuPG is not configured on this system.'; + $result[2] = 'GnuPG is not configured on this system.'; $result[0] = true; return $result; } @@ -499,7 +497,6 @@ class User extends AppModel public function verifyGPG($id = false) { - require_once 'Crypt/GPG.php'; $this->Behaviors->detach('Trim'); $results = array(); $conditions = array('not' => array('gpgkey' => '')); @@ -513,7 +510,7 @@ class User extends AppModel if (empty($users)) { return $results; } - $gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'), 'gpgconf' => Configure::read('GnuPG.gpgconf'), 'binary' => (Configure::read('GnuPG.binary') ? Configure::read('GnuPG.binary') : '/usr/bin/gpg'))); + $gpg = $this->initializeGpg(); foreach ($users as $k => $user) { $results[$user['User']['id']] = $this->verifySingleGPG($user, $gpg); } @@ -1217,9 +1214,9 @@ class User extends AppModel public function verifyPassword($user_id, $password) { $currentUser = $this->find('first', array( - 'conditions' => array('User.id' => $user_id), - 'recursive' => -1, - 'fields' => array('User.password') + 'conditions' => array('User.id' => $user_id), + 'recursive' => -1, + 'fields' => array('User.password') )); if (empty($currentUser)) { return false; @@ -1253,4 +1250,26 @@ class User extends AppModel $this->save($admin); return $authKey; } + + /** + * @return Crypt_GPG + * @throws Exception + */ + private function initializeGpg() + { + if (!class_exists('Crypt_GPG')) { + if (!stream_resolve_include_path('Crypt/GPG.php')) { + throw new Exception("Crypt_GPG is not installed."); + } + require_once 'Crypt/GPG.php'; + } + + $options = array( + 'homedir' => Configure::read('GnuPG.homedir'), + 'gpgconf' => Configure::read('GnuPG.gpgconf'), + 'binary' => Configure::read('GnuPG.binary') ?: '/usr/bin/gpg', + ); + + return new Crypt_GPG($options); + } } From becee3b772027e8fe8bf92869f39de5e16aeb012 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Fri, 6 Sep 2019 21:32:49 +0200 Subject: [PATCH 13/22] chg: Install crypt_gpg by composer --- .gitmodules | 6 ------ .travis.yml | 2 +- INSTALL/INSTALL.sh | 9 --------- INSTALL/INSTALL.sh.sha1 | 2 +- INSTALL/INSTALL.sh.sha256 | 2 +- INSTALL/INSTALL.sh.sha384 | 2 +- INSTALL/INSTALL.sh.sha512 | 2 +- INSTALL/ansible/roles/misp/tasks/main.yml | 20 -------------------- INSTALL/dependencies/Console_CommandLine | 1 - INSTALL/dependencies/Crypt_GPG | 1 - app/composer.json | 3 ++- docs/INSTALL.rhel7.md | 5 ----- docs/INSTALL.rhel8.md | 7 +------ docs/INSTALL.ubuntu1804.md | 5 ----- docs/generic/supportFunctions.md | 2 -- docs/xINSTALL.centos6.md | 5 ----- docs/xINSTALL.centos7.md | 5 ----- docs/xINSTALL.debian10.md | 4 ---- docs/xINSTALL.debian9.md | 4 ---- docs/xINSTALL.tsurugi.md | 2 -- 20 files changed, 8 insertions(+), 81 deletions(-) delete mode 160000 INSTALL/dependencies/Console_CommandLine delete mode 160000 INSTALL/dependencies/Crypt_GPG diff --git a/.gitmodules b/.gitmodules index fcfb3688b..4033ceb5e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,12 +37,6 @@ path = Plugin/DebugKit url = https://github.com/cakephp/debug_kit.git branch = 2.2 -[submodule "INSTALL/Crypt_GPG"] - path = INSTALL/dependencies/Crypt_GPG - url = https://github.com/pear/Crypt_GPG -[submodule "INSTALL/Console_CommandLine"] - path = INSTALL/dependencies/Console_CommandLine - url = https://github.com/pear/Console_CommandLine [submodule "INSTALL/dependencies/Net_GeoIP"] path = INSTALL/dependencies/Net_GeoIP url = https://github.com/pear/Net_GeoIP diff --git a/.travis.yml b/.travis.yml index 28bae8234..dcbcb9f4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ install: - sudo apt-get -y update # Travis lacks entropy. - sudo apt-get -y install haveged - - sudo apt-get -y install python3 python3-pip python3-dev python3-nose libxml2-dev libzmq3-dev zlib1g-dev apache2 curl php-mysql php-dev php-cli libapache2-mod-php libfuzzy-dev php-mbstring libonig4 php-json php-xml php-opcache php-readline php-pear php-redis php-gnupg php-gd + - sudo apt-get -y install python3 python3-pip python3-dev python3-nose libxml2-dev libzmq3-dev zlib1g-dev apache2 curl php-mysql php-dev php-cli libapache2-mod-php libfuzzy-dev php-mbstring libonig4 php-json php-xml php-opcache php-readline php-redis php-gnupg php-gd - sudo apt-get -y dist-upgrade - sudo pip3 install --upgrade pip setuptools requests pyzmq - sudo pip3 install --upgrade -r requirements.txt diff --git a/INSTALL/INSTALL.sh b/INSTALL/INSTALL.sh index 8e334e508..d9ddafc4f 100644 --- a/INSTALL/INSTALL.sh +++ b/INSTALL/INSTALL.sh @@ -763,7 +763,6 @@ installDepsPhp70 () { php php-cli \ php-dev \ php-json php-xml php-mysql php-opcache php-readline php-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd @@ -785,7 +784,6 @@ installDepsPhp73 () { php7.3 php7.3-cli \ php7.3-dev \ php7.3-json php7.3-xml php7.3-mysql php7.3-opcache php7.3-readline php7.3-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd } @@ -1137,7 +1135,6 @@ installDepsPhp73 () { php7.3 php7.3-cli \ php7.3-dev \ php7.3-json php7.3-xml php7.3-mysql php7.3-opcache php7.3-readline php7.3-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd } @@ -1153,7 +1150,6 @@ installDepsPhp72 () { php php-cli \ php-dev \ php-json php-xml php-mysql php7.2-opcache php-readline php-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd @@ -1174,7 +1170,6 @@ installDepsPhp70 () { php php-cli \ php-dev \ php-json php-xml php-mysql php-opcache php-readline php-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd @@ -1324,10 +1319,6 @@ installCore () { # install plyara $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara - - # Install Crypt_GPG and Console_CommandLine - sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml - sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml } installCake () { diff --git a/INSTALL/INSTALL.sh.sha1 b/INSTALL/INSTALL.sh.sha1 index 8e3690848..b5e4192e3 100644 --- a/INSTALL/INSTALL.sh.sha1 +++ b/INSTALL/INSTALL.sh.sha1 @@ -1 +1 @@ -75d9de9742ccb2383d044f6a19fed73ea2909f9d INSTALL.sh +6f5260ea0b7af730f4b94007e5046f661e3c2585 INSTALL.sh diff --git a/INSTALL/INSTALL.sh.sha256 b/INSTALL/INSTALL.sh.sha256 index 383df84c6..b146d4980 100644 --- a/INSTALL/INSTALL.sh.sha256 +++ b/INSTALL/INSTALL.sh.sha256 @@ -1 +1 @@ -c5f790fc1c13af0b95490cc2136324b9dd9930af1b4c0afb6da4687b47c58e23 INSTALL.sh +babd4491825edd02153d7d09624f1668c452ee14279872f367c5729dd51171bc INSTALL.sh diff --git a/INSTALL/INSTALL.sh.sha384 b/INSTALL/INSTALL.sh.sha384 index 8d959efb6..875836e37 100644 --- a/INSTALL/INSTALL.sh.sha384 +++ b/INSTALL/INSTALL.sh.sha384 @@ -1 +1 @@ -5c2aaba9cafc88f5f81dafa7717e95daaec671ddd9aa32ed2ce0daf7654c2a11eab59271802590566f1cdd285a485673 INSTALL.sh +0cf66499a027baaf5b52aba19270a7f6e5fbc7d99df225a9049bf9c35c35f9c4316a59ef92ec544ef2f23eea416897b0 INSTALL.sh diff --git a/INSTALL/INSTALL.sh.sha512 b/INSTALL/INSTALL.sh.sha512 index 4b032f6dc..36612fe4b 100644 --- a/INSTALL/INSTALL.sh.sha512 +++ b/INSTALL/INSTALL.sh.sha512 @@ -1 +1 @@ -dcb06c97ca3d4528b41c81f9d6933de235260e5fcfcc28c5fdd2fb19a287b421e492c3ae5ab3896ee3119309f7539be4b1a03422510721dae3f20d07ec2cc415 INSTALL.sh +cfc7e4b1749ad8ed2d75fd3e7d984bb48ab253559c4a37318568dfc175fad40612a05bb59d3672dc3de88b651bd18e8b959457c4ae9c72eff2c0a7418e51fce8 INSTALL.sh diff --git a/INSTALL/ansible/roles/misp/tasks/main.yml b/INSTALL/ansible/roles/misp/tasks/main.yml index b6114e62e..c8540b7e2 100644 --- a/INSTALL/ansible/roles/misp/tasks/main.yml +++ b/INSTALL/ansible/roles/misp/tasks/main.yml @@ -74,26 +74,6 @@ - "/opt/misp-server/tmp" - "/opt/misp-server/backup" -######### PEAR: CRYPTPGP ######### -- name: Configure PEAR proxy - shell: "{{ item }}" - args: - creates: /home/misp/ansible/ansible_shell_pear_configure_proxy.log - with_items: - - "pear config-set http_proxy http://{{proxy_host}}:{{proxy_port}} > /home/misp/ansible/ansible_shell_pear_configure_proxy.log" - -- name: Configure PEAR tmp - shell: "{{ item }}" - args: - creates: /home/misp/ansible/ansible_shell_pear_configure_tmp.log - with_items: - - pear config-set temp_dir /opt/misp-server/tmp/ > /home/misp/ansible/ansible_shell_pear_configure_tmp.log - -- name: Install CryptGPG - pear: - name: Crypt_GPG - state: present - ######### MISP REPOSITORY ######### - name: Clone MISP repository diff --git a/INSTALL/dependencies/Console_CommandLine b/INSTALL/dependencies/Console_CommandLine deleted file mode 160000 index 40fca1d3d..000000000 --- a/INSTALL/dependencies/Console_CommandLine +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 40fca1d3dabbbb23e13b333bd5c615ca19d7d73f diff --git a/INSTALL/dependencies/Crypt_GPG b/INSTALL/dependencies/Crypt_GPG deleted file mode 160000 index bf07ab512..000000000 --- a/INSTALL/dependencies/Crypt_GPG +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bf07ab51207446ed33ea0075083df9bbc2358617 diff --git a/app/composer.json b/app/composer.json index 281858edc..4f88ca3cf 100644 --- a/app/composer.json +++ b/app/composer.json @@ -2,7 +2,8 @@ "prefer-stable": true, "minimum-stability": "dev", "require": { - "kamisama/cake-resque": "4.1.2" + "kamisama/cake-resque": "4.1.2", + "pear/crypt_gpg": "1.6.3" }, "suggest": { "elasticsearch/elasticsearch": "For logging to elasticsearch", diff --git a/docs/INSTALL.rhel7.md b/docs/INSTALL.rhel7.md index 2d6748c85..cddb771ed 100644 --- a/docs/INSTALL.rhel7.md +++ b/docs/INSTALL.rhel7.md @@ -216,11 +216,6 @@ installCoreRHEL () { # Make git ignore filesystem permission differences $SUDO_WWW git config core.filemode false - # Install packaged pears - sudo $RUN_PHP -- pear channel-update pear.php.net - sudo $RUN_PHP -- pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml - sudo $RUN_PHP -- pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml - # Create a python3 virtualenv $SUDO_WWW $RUN_PYTHON -- virtualenv -p python3 $PATH_TO_MISP/venv sudo mkdir /usr/share/httpd/.cache diff --git a/docs/INSTALL.rhel8.md b/docs/INSTALL.rhel8.md index d8b9300f7..4c5688954 100644 --- a/docs/INSTALL.rhel8.md +++ b/docs/INSTALL.rhel8.md @@ -142,7 +142,7 @@ yumInstallCoreDeps () { sudo systemctl enable --now redis.service PHP_INI=/etc/php.ini - sudo yum install php php-fpm php-devel php-pear \ + sudo yum install php php-fpm php-devel \ php-mysqlnd \ php-mbstring \ php-xml \ @@ -200,11 +200,6 @@ installCoreRHEL () { # Make git ignore filesystem permission differences $SUDO_WWW git config core.filemode false - # Install packaged pears - sudo $RUN_PHP -- pear channel-update pear.php.net - sudo $RUN_PHP -- pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml - sudo $RUN_PHP -- pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml - # Create a python3 virtualenv $SUDO_WWW virtualenv-3 -p python3 $PATH_TO_MISP/venv sudo mkdir /usr/share/httpd/.cache diff --git a/docs/INSTALL.ubuntu1804.md b/docs/INSTALL.ubuntu1804.md index 0ce54a6e2..3a7d74e2e 100644 --- a/docs/INSTALL.ubuntu1804.md +++ b/docs/INSTALL.ubuntu1804.md @@ -116,7 +116,6 @@ installDepsPhp72 () { php php-cli \ php-dev \ php-json php-xml php-mysql php7.2-opcache php-readline php-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd @@ -190,10 +189,6 @@ installCore () { # install plyara $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara - - # Install Crypt_GPG and Console_CommandLine - sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml - sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml } # ``` diff --git a/docs/generic/supportFunctions.md b/docs/generic/supportFunctions.md index e357ff502..58ec305c7 100644 --- a/docs/generic/supportFunctions.md +++ b/docs/generic/supportFunctions.md @@ -605,7 +605,6 @@ installDepsPhp70 () { php php-cli \ php-dev \ php-json php-xml php-mysql php-opcache php-readline php-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd @@ -629,7 +628,6 @@ installDepsPhp73 () { php7.3 php7.3-cli \ php7.3-dev \ php7.3-json php7.3-xml php7.3-mysql php7.3-opcache php7.3-readline php7.3-mbstring \ - php-pear \ php-redis php-gnupg \ php-gd } diff --git a/docs/xINSTALL.centos6.md b/docs/xINSTALL.centos6.md index 7a983ecb8..d8343647e 100644 --- a/docs/xINSTALL.centos6.md +++ b/docs/xINSTALL.centos6.md @@ -145,11 +145,6 @@ $SUDO_WWW git submodule update --init --recursive # Make git ignore filesystem permission differences for submodules $SUDO_WWW git submodule foreach --recursive git config core.filemode false -# Install packaged pears -sudo $RUN_PHP "pear channel-update pear.php.net" -sudo $RUN_PHP "pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml" -sudo $RUN_PHP "pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml" - # Create a python3 virtualenv $SUDO_WWW $RUN_PYTHON "virtualenv -p python3 $PATH_TO_MISP/venv" sudo mkdir /var/www/.cache diff --git a/docs/xINSTALL.centos7.md b/docs/xINSTALL.centos7.md index 4a131d549..eea9600b0 100644 --- a/docs/xINSTALL.centos7.md +++ b/docs/xINSTALL.centos7.md @@ -137,11 +137,6 @@ $SUDO_WWW git submodule foreach --recursive git config core.filemode false # Make git ignore filesystem permission differences $SUDO_WWW git config core.filemode false -# Install packaged pears -sudo $RUN_PHP "pear channel-update pear.php.net" -sudo $RUN_PHP "pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml" -sudo $RUN_PHP "pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml" - # Create a python3 virtualenv $SUDO_WWW $RUN_PYTHON "virtualenv -p python3 $PATH_TO_MISP/venv" sudo mkdir /usr/share/httpd/.cache diff --git a/docs/xINSTALL.debian10.md b/docs/xINSTALL.debian10.md index 6f0f5f7d3..2f3f99531 100644 --- a/docs/xINSTALL.debian10.md +++ b/docs/xINSTALL.debian10.md @@ -180,10 +180,6 @@ $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic # install plyara $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara - -# Install Crypt_GPG and Console_CommandLine -sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml -sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml ``` ### 4/ CakePHP diff --git a/docs/xINSTALL.debian9.md b/docs/xINSTALL.debian9.md index 18f938aa0..c1f4743d0 100644 --- a/docs/xINSTALL.debian9.md +++ b/docs/xINSTALL.debian9.md @@ -205,10 +205,6 @@ $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic # install plyara $SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara - -# Install Crypt_GPG and Console_CommandLine -sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml -sudo pear install ${PATH_TO_MISP}/INSTALL/dependencies/Crypt_GPG/package.xml ``` ### 4/ CakePHP diff --git a/docs/xINSTALL.tsurugi.md b/docs/xINSTALL.tsurugi.md index a91618ed5..bb87dc6ec 100644 --- a/docs/xINSTALL.tsurugi.md +++ b/docs/xINSTALL.tsurugi.md @@ -172,8 +172,6 @@ function installMISPonTsurugi() { a2dissite 000-default a2ensite default-ssl - pear channel-update pear.php.net - pear install Crypt_GPG pecl channel-update pecl.php.net yes '' |pecl install redis From 4b1645a54e1858f1f886e046b9189347a1869637 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Sat, 7 Sep 2019 00:01:55 +0200 Subject: [PATCH 14/22] fix: Throw exception when GnuGP homedir is not set --- app/Model/User.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Model/User.php b/app/Model/User.php index 379ea04ab..91ee813b8 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -1264,8 +1264,13 @@ class User extends AppModel require_once 'Crypt/GPG.php'; } + $homedir = Configure::read('GnuPG.homedir'); + if ($homedir === null) { + throw new Exception("Configuration option 'GnuPG.homedir' is not set, Crypt_GPG cannot be initialized."); + } + $options = array( - 'homedir' => Configure::read('GnuPG.homedir'), + 'homedir' => $homedir, 'gpgconf' => Configure::read('GnuPG.gpgconf'), 'binary' => Configure::read('GnuPG.binary') ?: '/usr/bin/gpg', ); From 75acd63c46506ad404764c3a3de7d4ca11d0560f Mon Sep 17 00:00:00 2001 From: iglocska Date: Mon, 9 Sep 2019 13:00:21 +0200 Subject: [PATCH 15/22] fix: [security] Fix to a vulnerability related to the server index - along with various support tools - more information coming soon --- app/Console/Command/AdminShell.php | 26 ++++ app/Controller/Component/ACLComponent.php | 88 ++++++++++- app/Controller/ServersController.php | 30 +++- app/Controller/UsersController.php | 93 +++++------- app/Model/Log.php | 1 + app/Model/Server.php | 68 ++++++++- app/Model/User.php | 170 ++++++++++++++++++++++ app/View/Servers/index.ctp | 15 ++ app/View/Users/admin_index.ctp | 20 +++ 9 files changed, 435 insertions(+), 76 deletions(-) diff --git a/app/Console/Command/AdminShell.php b/app/Console/Command/AdminShell.php index 07817f058..0ee3544fa 100644 --- a/app/Console/Command/AdminShell.php +++ b/app/Console/Command/AdminShell.php @@ -506,4 +506,30 @@ class AdminShell extends AppShell $this->Server->cleanCacheFiles(); echo '...caches lost in time, like tears in rain.' . PHP_EOL; } + + public function resetSyncAuthkeys() + { + if (empty($this->args[0])) { + echo sprintf( + __("MISP mass sync authkey reset command line tool.\n\nUsage: %sConsole/cake resetSyncAuthkeys [user_id]") . "\n\n", + APP + ); + die(); + } else { + $userId = $this->args[0]; + $user = $this->User->getAuthUser($userId); + if (empty($user)) { + echo __('Invalid user.') . "\n\n"; + } + if (!$user['Role']['perm_site_admin']) { + echo __('User has to be a site admin.') . "\n\n"; + } + if (!empty($this->args[1])) { + $jobId = $this->args[1]; + } else { + $jobId = false; + } + $this->User->resetAllSyncAuthKeys($user, $jobId); + } + } } diff --git a/app/Controller/Component/ACLComponent.php b/app/Controller/Component/ACLComponent.php index f796c3ced..1c019daa9 100644 --- a/app/Controller/Component/ACLComponent.php +++ b/app/Controller/Component/ACLComponent.php @@ -335,7 +335,7 @@ class ACLComponent extends Component ), 'servers' => array( 'add' => array(), - 'cache' => array('perm_site_admin'), + 'cache' => array(), 'checkout' => array(), 'createSync' => array('perm_sync'), 'delete' => array(), @@ -348,14 +348,14 @@ class ACLComponent extends Component 'getInstanceUUID' => array('perm_sync'), 'getPyMISPVersion' => array('*'), 'getSetting' => array(), - 'getSubmodulesStatus' => array('perm_site_admin'), - 'getSubmoduleQuickUpdateForm' => array('perm_site_admin'), + 'getSubmodulesStatus' => array(), + 'getSubmoduleQuickUpdateForm' => array(), 'getWorkers' => array(), 'getVersion' => array('*'), - 'import' => ('perm_site_admin'), - 'index' => array('OR' => array('perm_sync', 'perm_admin')), + 'import' => array(), + 'index' => array(), 'ondemandAction' => array(), - 'postTest' => array('perm_sync'), + 'postTest' => array(), 'previewEvent' => array(), 'previewIndex' => array(), 'pull' => array(), @@ -371,7 +371,7 @@ class ACLComponent extends Component 'statusZeroMQServer' => array(), 'stopWorker' => array(), 'stopZeroMQServer' => array(), - 'testConnection' => array('perm_sync'), + 'testConnection' => array(), 'update' => array(), 'updateJSON' => array(), 'updateProgress' => array(), @@ -518,6 +518,7 @@ class ACLComponent extends Component 'initiatePasswordReset' => array('perm_admin'), 'login' => array('*'), 'logout' => array('*'), + 'resetAllSyncAuthKeys' => array(), 'resetauthkey' => array('*'), 'request_API' => array('*'), 'routeafterlogin' => array('*'), @@ -553,6 +554,78 @@ class ACLComponent extends Component ) ); + private function __checkLoggedActions($user, $controller, $action) + { + $loggedActions = array( + 'servers' => array( + 'index' => array( + 'role' => array( + 'NOT' => array( + 'perm_site_admin' + ) + ), + 'message' => __('This could be an indication of an attempted privilege escalation on older vulnerable versions of MISP (<2.4.115)') + ) + ) + ); + foreach ($loggedActions as $k => $v) { + $loggedActions[$k] = array_change_key_case($v); + } + $message = ''; + if (!empty($loggedActions[$controller])) { + if (!empty($loggedActions[$controller][$action])) { + $message = $loggedActions[$controller][$action]['message']; + $hit = false; + if (empty($loggedActions[$controller][$action]['role'])) { + $hit = true; + } else { + $role_req = $loggedActions[$controller][$action]['role']; + if (empty($role_req['OR']) && empty($role_req['AND']) && empty($role_req['NOT'])) { + $role_req = array('OR' => $role_req); + } + if (!empty($role_req['NOT'])) { + foreach ($role_req['NOT'] as $k => $v) { + if (!$user['Role'][$v]) { + $hit = true; + continue; + } + } + } + if (!$hit && !empty($role_req['AND'])) { + $subhit = true; + foreach ($role_req['AND'] as $k => $v) { + $subhit = $subhit && $user['Role'][$v]; + } + if ($subhit) { + $hit = true; + } + } + if (!$hit && !empty($role_req['OR'])) { + foreach ($role_req['OR'] as $k => $v) { + if ($user['Role'][$v]) { + $hit = true; + continue; + } + } + } + if ($hit) { + $this->Log = ClassRegistry::init('Log'); + $this->Log->create(); + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'User', + 'model_id' => $user['id'], + 'email' => $user['email'], + 'action' => 'security', + 'user_id' => $user['id'], + 'title' => __('User triggered security alert by attempting to access /%s/%s. Reason why this endpoint is of interest: %s', $controller, $action, $message), + )); + } + } + } + } + } + // The check works like this: // If the user is a site admin, return true // If the requested action has an OR-d list, iterate through the list. If any of the permissions are set for the user, return true @@ -567,6 +640,7 @@ class ACLComponent extends Component foreach ($aclList as $k => $v) { $aclList[$k] = array_change_key_case($v); } + $this->__checkLoggedActions($user, $controller, $action); if ($user['Role']['perm_site_admin']) { return true; } diff --git a/app/Controller/ServersController.php b/app/Controller/ServersController.php index b3190420e..c59b17c00 100644 --- a/app/Controller/ServersController.php +++ b/app/Controller/ServersController.php @@ -44,12 +44,6 @@ class ServersController extends AppController public function index() { - if (!$this->_isSiteAdmin()) { - if (!$this->userRole['perm_sync'] && !$this->userRole['perm_admin']) { - $this->redirect(array('controller' => 'events', 'action' => 'index')); - } - $this->paginate['conditions'] = array('Server.org_id LIKE' => $this->Auth->user('org_id')); - } if ($this->_isRest()) { $params = array( 'recursive' => -1, @@ -2089,4 +2083,28 @@ misp.direct_call(relative_path, body) } } } + + public function resetRemoteAuthKey($id) + { + if (!$this->request->is('post')) { + throw new MethodNotAllowedException(__('This endpoint expects POST requests.')); + } + $result = $this->Server->resetRemoteAuthkey($id); + if ($result !== true) { + if (!$this->_isRest()) { + $this->Flash->error($result); + $this->redirect(array('action' => 'index')); + } else { + return $this->RestResponse->saveFailResponse('Servers', 'resetRemoteAuthKey', $id, $message, $this->response->type()); + } + } else { + $message = __('API key updated.'); + if (!$this->_isRest()) { + $this->Flash->success($message); + $this->redirect(array('action' => 'index')); + } else { + return $this->RestResponse->saveSuccessResponse('Servers', 'resetRemoteAuthKey', $message, $this->response->type()); + } + } + } } diff --git a/app/Controller/UsersController.php b/app/Controller/UsersController.php index 6495a081b..151374726 100644 --- a/app/Controller/UsersController.php +++ b/app/Controller/UsersController.php @@ -211,7 +211,7 @@ class UsersController extends AppController // Save the data if ($this->User->save($user)) { $message = __('Password Changed.'); - $this->__extralog("change_pw"); + $this->User->extralog($this->Auth->user(), "change_pw", null, null, $user); if ($this->_isRest()) { return $this->RestResponse->saveSuccessResponse('User', 'change_pw', false, $this->response->type(), $message); } @@ -869,7 +869,11 @@ class UsersController extends AppController $c++; } $fieldsResultStr = substr($fieldsResultStr, 2); - $this->__extralog("edit", "user", $fieldsResultStr); + $user = $this->User->find('first', array( + 'recursive' => -1, + 'conditions' => array('User.id' => $this->id) + )); + $this->User->extralog($this->Auth->user(), "edit", "user", $fieldsResultStr, $user); if ($this->_isRest()) { $user = $this->User->find('first', array( 'conditions' => array('User.id' => $this->User->id), @@ -954,7 +958,7 @@ class UsersController extends AppController } $fieldsDescrStr = 'User (' . $id . '): ' . $user['User']['email']; if ($this->User->delete($id)) { - $this->__extralog("delete", $fieldsDescrStr, ''); + $this->User->extralog($this->Auth->user(), "delete", $fieldsDescrStr, ''); if ($this->_isRest()) { return $this->RestResponse->saveSuccessResponse('User', 'admin_delete', $id, $this->response->type(), 'User deleted.'); } else { @@ -1010,7 +1014,7 @@ class UsersController extends AppController } } if ($this->Auth->login()) { - $this->__extralog("login"); + $this->User->extralog($this->Auth->user(), "login"); $this->User->Behaviors->disable('SysLogLogable.SysLogLogable'); $this->User->id = $this->Auth->user('id'); $user = $this->User->find('first', array( @@ -1125,7 +1129,7 @@ class UsersController extends AppController public function logout() { if ($this->Session->check('Auth.User')) { - $this->__extralog("logout"); + $this->User->extralog($this->Auth->user(), "logout"); } $this->Flash->info(__('Good-Bye')); $user = $this->User->find('first', array( @@ -1140,7 +1144,7 @@ class UsersController extends AppController $this->redirect($this->Auth->logout()); } - public function resetauthkey($id = null) + public function resetauthkey($id = null, $alert = false) { if (!$this->_isAdmin() && Configure::read('MISP.disableUserSelfManagement')) { throw new MethodNotAllowedException('User self-management has been disabled on this instance.'); @@ -1149,24 +1153,12 @@ class UsersController extends AppController $id = $this->Auth->user('id'); } if (!$this->userRole['perm_auth']) { - throw new MethodNotAllowedException('Invalid action.'); + throw new MethodNotAllowedException(__('Invalid action.')); } - $this->User->id = $id; - if (!$id || !$this->User->exists($id)) { - throw new MethodNotAllowedException('Invalid user.'); + $newkey = $this->User->resetauthkey($this->Auth->user(), $id, $alert); + if ($newkey === false) { + throw new MethodNotAllowedException(__('Invalid user.')); } - $user = $this->User->read(); - $oldKey = $this->User->data['User']['authkey']; - if (!$this->_isSiteAdmin() && !($this->_isAdmin() && $this->Auth->user('org_id') == $this->User->data['User']['org_id']) && ($this->Auth->user('id') != $id)) { - throw new MethodNotAllowedException('Invalid user.'); - } - $newkey = $this->User->generateAuthKey(); - $this->User->saveField('authkey', $newkey); - $this->__extralog( - 'reset_auth_key', - 'Authentication key for user ' . $user['User']['id'] . ' (' . $user['User']['email'] . ')', - $fieldsResult = 'authkey(' . $oldKey . ') => (' . $newkey . ')' - ); if (!$this->_isRest()) { $this->Flash->success(__('New authkey generated.', true)); $this->_refreshAuth(); @@ -1176,6 +1168,25 @@ class UsersController extends AppController } } + public function resetAllSyncAuthKeys() + { + if (!$this->request->is('post')) { + throw new MethodNotAllowedException(__('This functionality is only accessible via POST requests.')); + } + $results = $this->User->resetAllSyncAuthKeysRouter($this->Auth->user()); + if ($results === true) { + $message = __('Job initiated.'); + } else { + $message = __('%s authkeys reset, %s could not be reset.', $results['success'], $results['fails']); + } + if (!$this->_isRest()) { + $this->Flash->info($message); + $this->redirect($this->referer()); + } else { + return $this->RestResponse->saveSuccessResponse('User', 'resetAllSyncAuthKeys', false, $this->response->type(), $message); + } + } + public function histogram($selected = null) { //if (!$this->request->is('ajax') && !$this->_isRest()) throw new MethodNotAllowedException('This function can only be accessed via AJAX or the API.'); @@ -1297,44 +1308,6 @@ class UsersController extends AppController return $this->response; } - private function __extralog($action = null, $description = null, $fieldsResult = null) - { - // new data - $model = 'User'; - $modelId = $this->Auth->user('id'); - if ($action == 'login') { - $description = "User (" . $this->Auth->user('id') . "): " . $this->data['User']['email']; - } elseif ($action == 'logout') { - $description = "User (" . $this->Auth->user('id') . "): " . $this->Auth->user('email'); - } elseif ($action == 'edit') { - $description = "User (" . $this->User->id . "): " . $this->data['User']['email']; - } elseif ($action == 'change_pw') { - $description = "User (" . $this->User->id . "): " . $this->Auth->user('email'); - $fieldsResult = "Password changed."; - } - - // query - $this->Log = ClassRegistry::init('Log'); - $this->Log->create(); - $this->Log->save(array( - 'org' => $this->Auth->user('Organisation')['name'], - 'model' => $model, - 'model_id' => $modelId, - 'email' => $this->Auth->user('email'), - 'action' => $action, - 'title' => $description, - 'change' => isset($fieldsResult) ? $fieldsResult : '')); - - // write to syslogd as well - App::import('Lib', 'SysLog.SysLog'); - $syslog = new SysLog(); - if (isset($fieldsResult) && $fieldsResult) { - $syslog->write('notice', $description . ' -- ' . $action . ' -- ' . $fieldsResult); - } else { - $syslog->write('notice', $description . ' -- ' . $action); - } - } - // Used for fields_before and fields for audit public function arrayCopy(array $array) { diff --git a/app/Model/Log.php b/app/Model/Log.php index a7c0e8b38..4748fcba8 100644 --- a/app/Model/Log.php +++ b/app/Model/Log.php @@ -48,6 +48,7 @@ class Log extends AppModel 'request', 'request_delegation', 'reset_auth_key', + 'security', 'serverSettingsEdit', 'tag', 'undelete', diff --git a/app/Model/Server.php b/app/Model/Server.php index 2d1cd1e74..7fdc93be8 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -2289,10 +2289,10 @@ class Server extends AppModel if (!$existingEvent) { // add data for newly imported events $result = $eventModel->_add($event, true, $user, $server['Server']['org_id'], $passAlong, true, $jobId); - if ($result === true) { + if ($result) { $successes[] = $eventId; } else { - $fails[$eventId] = __('Failed (partially?) because of errors: ') . $result; + $fails[$eventId] = __('Failed (partially?) because of validation errors: ') . json_encode($eventModel->validationErrors, true); } } else { if (!$existingEvent['Event']['locked'] && !$server['Server']['internal']) { @@ -2316,6 +2316,7 @@ class Server extends AppModel $eventId, $server ); + ; if (!empty($event)) { if ($this->__checkIfEventIsBlockedBeforePull($event)) { return false; @@ -2328,7 +2329,7 @@ class Server extends AppModel } } else { // error - $fails[$eventId] = __('failed downloading the event') . ': ' . json_encode($event); + $fails[$eventId] = __('failed downloading the event'); } return true; } @@ -5187,4 +5188,65 @@ class Server extends AppModel } return $results; } + + public function resetRemoteAuthKey($id) + { + $server = $this->find('first', array( + 'recursive' => -1, + 'conditions' => array('Server.id' => $id) + )); + if (empty($server)) { + return __('Invalid server'); + } + $HttpSocket = $this->setupHttpSocket($server); + $request = $this->setupSyncRequest($server); + $uri = $server['Server']['url'] . '/users/resetauthkey/me'; + try { + $response = $HttpSocket->post($uri, '{}', $request); + } catch (Exception $e) { + $this->Log = ClassRegistry::init('Log'); + $this->Log->create(); + $message = 'Could not reset the remote authentication key.'; + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'Server', + 'model_id' => $id, + 'email' => 'SYSTEM', + 'action' => 'error', + 'user_id' => 0, + 'title' => 'Error: ' . $message, + )); + return $message; + } + if ($response->isOk()) { + try { + $response = json_decode($response->body, true); + } catch (Exception $e) { + $this->Log = ClassRegistry::init('Log'); + $this->Log->create(); + $message = 'Invalid response received from the remote instance.'; + $this->Log->save(array( + 'org' => 'SYSTEM', + 'model' => 'Server', + 'model_id' => $id, + 'email' => 'SYSTEM', + 'action' => 'error', + 'user_id' => 0, + 'title' => 'Error: ' . $message, + )); + return $message; + } + if (!empty($response['message'])) { + $authkey = $response['message']; + } + if (substr($authkey, 0, 17) === 'Authkey updated: ') { + $authkey = substr($authkey, 17, 57); + } + $server['Server']['authkey'] = $authkey; + $this->save($server); + return true; + } else { + return __('Could not reset the remote authentication key.'); + } + } } diff --git a/app/Model/User.php b/app/Model/User.php index d6e6cd6df..9b1e3aa0e 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -1253,4 +1253,174 @@ class User extends AppModel $this->save($admin); return $authKey; } + + public function resetAllSyncAuthKeysRouter($user, $jobId = false) + { + if (Configure::read('MISP.background_jobs')) { + $job = ClassRegistry::init('Job'); + $job->create(); + $eventModel = ClassRegistry::init('Event'); + $data = array( + 'worker' => $eventModel->__getPrioWorkerIfPossible(), + 'job_type' => __('reset_all_sync_api_keys'), + 'job_input' => __('Reseting all API keys'), + 'status' => 0, + 'retries' => 0, + 'org_id' => $user['org_id'], + 'org' => $user['Organisation']['name'], + 'message' => 'Issuing new API keys to all sync users.', + ); + $job->save($data); + $jobId = $job->id; + $process_id = CakeResque::enqueue( + 'prio', + 'AdminShell', + array('resetSyncAuthkeys', $user['id'], $jobId), + true + ); + $job->saveField('process_id', $process_id); + return true; + } else { + return $this->resetAllSyncAuthKeys($user); + } + } + + public function resetAllSyncAuthKeys($user, $jobId = false) + { + $affected_users = $this->find('all', array( + 'recursive' => -1, + 'contain' => array('Role'), + 'conditions' => array( + 'OR' => array( + 'Role.perm_sync' => 1, + 'Role.perm_admin' => 1 + ), + 'Role.perm_site_admin' => 0 + ) + )); + $results = array('success' => 0, 'fails' => 0); + $user_count = count($affected_users); + if ($jobId) { + $job = ClassRegistry::init('Job'); + $existingJob = $job->find('first', array( + 'conditions' => array('Job.id' => $jobId), + 'recursive' => -1 + )); + if (empty($existingJob)) { + $jobId = false; + } + } + foreach ($affected_users as $k => $affected_user) { + try { + $reset_result = $this->resetauthkey($user, $affected_user['User']['id'], true); + if ($reset_result) { + $results['success'] += 1; + } else { + $results['fails'] += 1; + } + } catch (Exception $e) { + $results['fails'] += 1; + } + if ($jobId) { + if ($k % 100 == 0) { + $job->id = $jobId; + $job->saveField('progress', 100 * (($k + 1) / count($user_count))); + $job->saveField('message', __('Reset in progress - %s/%s.', $k, $user_count)); + } + } + } + if ($jobId) { + $message = __('%s authkeys reset, %s could not be reset', $results['success'], $results['fails']); + $job->saveField('progress', 100); + $job->saveField('message', $message); + $job->saveField('status', 4); + } + return $results; + } + + public function resetauthkey($user, $id, $alert = false) + { + $this->id = $id; + if (!$id || !$this->exists($id)) { + return false; + } + $updatedUser = $this->read(); + $oldKey = $this->data['User']['authkey']; + if (empty($user['Role']['perm_site_admin']) && !($user['Role']['perm_admin'] && $user['org_id'] == $updatedUser['User']['org_id']) && ($user['id'] != $id)) { + return false; + } + $newkey = $this->generateAuthKey(); + $this->saveField('authkey', $newkey); + $this->extralog( + $user, + 'reset_auth_key', + sprintf( + __('Authentication key for user %s (%s) updated.'), + $updatedUser['User']['id'], + $updatedUser['User']['email'] + ), + $fieldsResult = 'authkey(' . $oldKey . ') => (' . $newkey . ')', + $updatedUser + ); + if ($alert) { + $baseurl = Configure::read('MISP.external_baseurl'); + if (empty($baseurl)) { + $baseurl = Configure::read('MISP.baseurl'); + } + $body = __( + "Dear user,\n\nan API key reset has been triggered by an administrator for your user account on %s.\n\nYour new API key is: %s\n\nPlease update your server's sync setup to reflect this change.\n\nWe apologise for the inconvenience.", + $baseurl, + $newkey + ); + $bodyNoEnc = __( + "Dear user,\n\nan API key reset has been triggered by an administrator for your user account on %s.\n\nYour new API key can be retrieved by logging in using this sync user's account.\n\nPlease update your server's sync setup to reflect this change.\n\nWe apologise for the inconvenience.", + $baseurl, + $newkey + ); + $this->sendEmail( + $updatedUser, + $body, + $bodyNoEnc, + __('API key reset by administrator') + ); + } + return $newkey; + } + + public function extralog($user, $action = null, $description = null, $fieldsResult = null, $modifiedUser = null) + { + // new data + $model = 'User'; + $modelId = $user['id']; + if (!empty($modifiedUser)) { + $modelId = $modifiedUser['User']['id']; + } + if ($action == 'login') { + $description = "User (" . $user['id'] . "): " . $user['email']; + } elseif ($action == 'logout') { + $description = "User (" . $user['id'] . "): " . $user['email']; + } elseif ($action == 'edit') { + $description = "User (" . $modifiedUser['User']['id'] . "): " . $modifiedUser['User']['email']; + } elseif ($action == 'change_pw') { + $description = "User (" . $modifiedUser['User']['id'] . "): " . $modifiedUser['User']['email']; + $fieldsResult = "Password changed."; + } + + // query + $this->Log = ClassRegistry::init('Log'); + $this->Log->create(); + $this->Log->save(array( + 'org' => $user['Organisation']['name'], + 'model' => $model, + 'model_id' => $modelId, + 'email' => $user['email'], + 'action' => $action, + 'title' => $description, + 'change' => isset($fieldsResult) ? $fieldsResult : '')); + + // write to syslogd as well + App::import('Lib', 'SysLog.SysLog'); + $syslog = new SysLog(); + $syslog->write('notice', $description . ' -- ' . $action . (empty($fieldResult) ? '' : '-- ' . $fieldResult)); + } } diff --git a/app/View/Servers/index.ctp b/app/View/Servers/index.ctp index 1d2c31da2..0dba82bd9 100644 --- a/app/View/Servers/index.ctp +++ b/app/View/Servers/index.ctp @@ -21,6 +21,7 @@ Paginator->sort('id');?> Paginator->sort('name');?> + Paginator->sort('internal');?> Paginator->sort('push');?> Paginator->sort('pull');?> @@ -70,6 +71,20 @@ foreach ($servers as $server): ?> + + Form->postLink( + __('Reset'), + $baseurl . '/servers/resetRemoteAuthKey/' . $server['Server']['id'], + array( + 'style' => 'line-height:10px; padding: 4px 4px;', + 'title' => __('Remotely reset API key'), + 'aria-label' => __('Remotely reset API key'), + 'class' => 'btn btn-primary' + ) + ); + ?> + " data-toggle="popover" title="Distribution List" data-content=""> () diff --git a/app/View/Users/admin_index.ctp b/app/View/Users/admin_index.ctp index c889161dc..7732ea2b0 100755 --- a/app/View/Users/admin_index.ctp +++ b/app/View/Users/admin_index.ctp @@ -1,5 +1,25 @@

+ %s', + __( + 'Click %s to reset the API keys of all sync and org admin users in one shot. This will also automatically inform them of their new API keys.', + $this->Form->postLink( + __('here'), + $baseurl . '/users/resetAllSyncAuthKeys', + array( + 'title' => __('Reset all sync user API keys'), + 'aria-label' => __('Reset all sync user API keys'), + 'class' => 'bold' + ), + __('Are you sure you wish to reset the API keys of all users with sync privileges?') + ) + ) + ); + } + ?>