mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into stix2
commit
9c9e2960a9
|
@ -1415,6 +1415,10 @@ class ServersController extends AppController
|
|||
if ($result['status'] == 1) {
|
||||
$version = json_decode($result['message'], true);
|
||||
if (isset($version['version']) && preg_match('/^[0-9]+\.+[0-9]+\.[0-9]+$/', $version['version'])) {
|
||||
$perm_sync = false;
|
||||
if (isset($version['perm_sync'])) {
|
||||
$perm_sync = $version['perm_sync'];
|
||||
}
|
||||
App::uses('Folder', 'Utility');
|
||||
$file = new File(ROOT . DS . 'VERSION.json', true);
|
||||
$local_version = json_decode($file->read(), true);
|
||||
|
@ -1438,16 +1442,9 @@ class ServersController extends AppController
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!isset($version['perm_sync'])) {
|
||||
if (!$this->Server->checkLegacyServerSyncPrivilege($id)) {
|
||||
$result['status'] = 7;
|
||||
return new CakeResponse(array('body'=> json_encode($result), 'type' => 'json'));
|
||||
}
|
||||
} else {
|
||||
if (!$version['perm_sync']) {
|
||||
$result['status'] = 7;
|
||||
return new CakeResponse(array('body'=> json_encode($result), 'type' => 'json'));
|
||||
}
|
||||
if (!$perm_sync) {
|
||||
$result['status'] = 7;
|
||||
return new CakeResponse(array('body'=> json_encode($result), 'type' => 'json'));
|
||||
}
|
||||
return new CakeResponse(
|
||||
array(
|
||||
|
|
|
@ -1193,6 +1193,16 @@ class AppModel extends Model
|
|||
return $version_array;
|
||||
}
|
||||
|
||||
public function validateAuthkey($value) {
|
||||
if (empty($value['authkey'])) {
|
||||
return 'Empty authkey found. Make sure you set the 40 character long authkey.';
|
||||
}
|
||||
if (!preg_match('/[a-z0-9]{40}/i', $value['authkey'])) {
|
||||
return 'The authkey has to be exactly 40 characters long and consist of alphanumeric characters.';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// alternative to the build in notempty/notblank validation functions, compatible with cakephp <= 2.6 and cakephp and cakephp >= 2.7
|
||||
public function valueNotEmpty($value)
|
||||
{
|
||||
|
|
|
@ -1242,8 +1242,8 @@ class Event extends AppModel
|
|||
public function downloadProposalsFromServer($uuidList, $server, $HttpSocket = null)
|
||||
{
|
||||
$url = $server['Server']['url'];
|
||||
$HttpSocket = $this->__setupHttpSocket($server, $HttpSocket);
|
||||
$request = $this->__setupPushRequest($server);
|
||||
$HttpSocket = $this->setupHttpSocket($server, $HttpSocket);
|
||||
$request = $this->setupSyncRequest($server);
|
||||
$uri = $url . '/shadow_attributes/getProposalsByUuidList';
|
||||
$response = $HttpSocket->post($uri, json_encode($uuidList), $request);
|
||||
if ($response->isOk()) {
|
||||
|
|
|
@ -47,14 +47,7 @@ class Server extends AppModel
|
|||
)
|
||||
),
|
||||
'authkey' => array(
|
||||
'minlength' => array(
|
||||
'rule' => array('minlength', 40),
|
||||
'message' => 'A authkey of a minimum length of 40 is required.',
|
||||
'required' => true,
|
||||
),
|
||||
'valueNotEmpty' => array(
|
||||
'rule' => array('valueNotEmpty'),
|
||||
),
|
||||
'rule' => array('validateAuthkey')
|
||||
),
|
||||
'org_id' => array(
|
||||
'numeric' => array(
|
||||
|
@ -1741,6 +1734,42 @@ class Server extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
private function __getEventIdListBasedOnPullTechnique($technique, $server) {
|
||||
if ("full" === $technique) {
|
||||
// get a list of the event_ids on the server
|
||||
$eventIds = $this->getEventIdsFromServer($server);
|
||||
if ($eventIds === 403) {
|
||||
return array('error' => array(1, null));
|
||||
} elseif (is_string($eventIds)) {
|
||||
return array('error' => array(2, $eventIds));
|
||||
}
|
||||
|
||||
// reverse array of events, to first get the old ones, and then the new ones
|
||||
if (!empty($eventIds)) {
|
||||
$eventIds = array_reverse($eventIds);
|
||||
}
|
||||
} elseif ("update" === $technique) {
|
||||
$eventIds = $this->getEventIdsFromServer($server, false, null, true, true);
|
||||
if ($eventIds === 403) {
|
||||
return array('error' => array(1, null));
|
||||
} elseif (is_string($eventIds)) {
|
||||
return array('error' => array(2, $eventIds));
|
||||
}
|
||||
$local_event_ids = $eventModel->find('list', array(
|
||||
'fields' => array('uuid'),
|
||||
'recursive' => -1,
|
||||
));
|
||||
$eventIds = array_intersect($eventIds, $local_event_ids);
|
||||
} elseif (is_numeric($technique)) {
|
||||
$eventIds[] = intval($technique);
|
||||
// if we are downloading a single event, don't fetch all proposals
|
||||
$conditions = array('Event.id' => $technique);
|
||||
} else {
|
||||
return array('error' => array(4, null));
|
||||
}
|
||||
return $eventIds;
|
||||
}
|
||||
|
||||
public function pull($user, $id = null, $technique=false, $server, $jobId = false, $percent = 100, $current = 0)
|
||||
{
|
||||
if ($jobId) {
|
||||
|
@ -1754,39 +1783,7 @@ class Server extends AppModel
|
|||
App::uses('HttpSocket', 'Network/Http');
|
||||
$eventIds = array();
|
||||
$conditions = array();
|
||||
if ("full" === $technique) {
|
||||
// get a list of the event_ids on the server
|
||||
$eventIds = $this->getEventIdsFromServer($server);
|
||||
// FIXME this is not clean at all ! needs to be refactored with try catch error handling/communication
|
||||
if ($eventIds === 403) {
|
||||
return array(1, null);
|
||||
} elseif (is_string($eventIds)) {
|
||||
return array(2, $eventIds);
|
||||
}
|
||||
|
||||
// reverse array of events, to first get the old ones, and then the new ones
|
||||
if (!empty($eventIds)) {
|
||||
$eventIds = array_reverse($eventIds);
|
||||
}
|
||||
} elseif ("update" === $technique) {
|
||||
$eventIds = $this->getEventIdsFromServer($server, false, null, true, true);
|
||||
if ($eventIds === 403) {
|
||||
return array(1, null);
|
||||
} elseif (is_string($eventIds)) {
|
||||
return array(2, $eventIds);
|
||||
}
|
||||
$local_event_ids = $eventModel->find('list', array(
|
||||
'fields' => array('uuid'),
|
||||
'recursive' => -1,
|
||||
));
|
||||
$eventIds = array_intersect($eventIds, $local_event_ids);
|
||||
} elseif (is_numeric($technique)) {
|
||||
$eventIds[] = intval($technique);
|
||||
// if we are downloading a single event, don't fetch all proposals
|
||||
$conditions = array('Event.id' => $technique);
|
||||
} else {
|
||||
return array(4, null);
|
||||
}
|
||||
$eventIds = $this->__getEventIdListBasedOnPullTechnique($technique, $server);
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
$pulledProposals = array();
|
||||
|
@ -2374,15 +2371,8 @@ class Server extends AppModel
|
|||
return $serverSettings;
|
||||
}
|
||||
|
||||
public function serverSettingsRead($unsorted = false)
|
||||
private function __serverSettingsRead($serverSettings, $currentSettings)
|
||||
{
|
||||
$this->Module = ClassRegistry::init('Module');
|
||||
$serverSettings = $this->getCurrentServerSettings();
|
||||
$currentSettings = Configure::read();
|
||||
if (Configure::read('Plugin.Enrichment_services_enable')) {
|
||||
$this->readModuleSettings($serverSettings, array('Enrichment'));
|
||||
}
|
||||
$finalSettingsUnsorted = array();
|
||||
foreach ($serverSettings as $branchKey => &$branchValue) {
|
||||
if (isset($branchValue['branch'])) {
|
||||
foreach ($branchValue as $leafKey => &$leafValue) {
|
||||
|
@ -2417,14 +2407,11 @@ class Server extends AppModel
|
|||
$finalSettingsUnsorted[$branchKey] = $branchValue;
|
||||
}
|
||||
}
|
||||
foreach ($finalSettingsUnsorted as $key => $temp) {
|
||||
if (in_array($temp['tab'], array_keys($this->__settingTabMergeRules))) {
|
||||
$finalSettingsUnsorted[$key]['tab'] = $this->__settingTabMergeRules[$temp['tab']];
|
||||
}
|
||||
}
|
||||
if ($unsorted) {
|
||||
return $finalSettingsUnsorted;
|
||||
}
|
||||
return $finalSettingsUnsorted;
|
||||
}
|
||||
|
||||
private function __sortFinalSettings($finalSettingsUnsorted)
|
||||
{
|
||||
$finalSettings = array();
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
foreach ($finalSettingsUnsorted as $k => $s) {
|
||||
|
@ -2437,6 +2424,26 @@ class Server extends AppModel
|
|||
return $finalSettings;
|
||||
}
|
||||
|
||||
public function serverSettingsRead($unsorted = false)
|
||||
{
|
||||
$this->Module = ClassRegistry::init('Module');
|
||||
$serverSettings = $this->getCurrentServerSettings();
|
||||
$currentSettings = Configure::read();
|
||||
if (Configure::read('Plugin.Enrichment_services_enable')) {
|
||||
$this->readModuleSettings($serverSettings, array('Enrichment'));
|
||||
}
|
||||
$finalSettingsUnsorted = $this->__serverSettingsRead($serverSettings, $currentSettings);
|
||||
foreach ($finalSettingsUnsorted as $key => $temp) {
|
||||
if (in_array($temp['tab'], array_keys($this->__settingTabMergeRules))) {
|
||||
$finalSettingsUnsorted[$key]['tab'] = $this->__settingTabMergeRules[$temp['tab']];
|
||||
}
|
||||
}
|
||||
if ($unsorted) {
|
||||
return $finalSettingsUnsorted;
|
||||
}
|
||||
return $this->__sortFinalSettings($finalSettingsUnsorted);
|
||||
}
|
||||
|
||||
public function serverSettingReadSingle($settingObject, $settingName, $leafKey)
|
||||
{
|
||||
// invalidate config.php from php opcode cache
|
||||
|
@ -2910,8 +2917,6 @@ class Server extends AppModel
|
|||
$k = $this->Attribute->generateCorrelation();
|
||||
}
|
||||
} else {
|
||||
$job = ClassRegistry::init('Job');
|
||||
$job->create();
|
||||
if ($value == true) {
|
||||
$jobType = 'jobPurgeCorrelation';
|
||||
$jobTypeText = 'purge correlations';
|
||||
|
@ -2919,6 +2924,8 @@ class Server extends AppModel
|
|||
$jobType = 'jobGenerateCorrelation';
|
||||
$jobTypeText = 'generate correlation';
|
||||
}
|
||||
$job = ClassRegistry::init('Job');
|
||||
$job->create();
|
||||
$data = array(
|
||||
'worker' => 'default',
|
||||
'job_type' => $jobTypeText,
|
||||
|
@ -3727,156 +3734,6 @@ class Server extends AppModel
|
|||
));
|
||||
}
|
||||
|
||||
public function upgrade2324($user_id, $jobId = false)
|
||||
{
|
||||
$this->cleanCacheFiles();
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job = ClassRegistry::init('Job');
|
||||
$this->Job->id = $jobId;
|
||||
}
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Organisation = ClassRegistry::init('Organisation');
|
||||
$this->Attribute = ClassRegistry::init('Attribute');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'upgrade_24',
|
||||
'user_id' => 0,
|
||||
'title' => 'Upgrade initiated',
|
||||
'change' => 'Starting the migration of the database to 2.4',
|
||||
));
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 10);
|
||||
$this->Job->saveField('message', 'Starting the migration of the database to 2.4');
|
||||
}
|
||||
$this->query('UPDATE roles SET perm_template = 1 WHERE perm_site_admin = 1 OR perm_admin = 1');
|
||||
$this->query('UPDATE roles SET perm_sharing_group = 1 WHERE perm_site_admin = 1 OR perm_sync = 1');
|
||||
$orgs = array('local' => array(), 'external' => array());
|
||||
$captureRules = array(
|
||||
'events_org' => array('table' => 'events', 'old' => 'org', 'new' => 'org_id'),
|
||||
'events_orgc' => array('table' => 'events', 'old' => 'orgc', 'new' => 'orgc_id'),
|
||||
'jobs_org' => array('table' => 'jobs', 'old' => 'org', 'new' => 'org_id'),
|
||||
'servers_org' => array('table' => 'servers', 'old' => 'org', 'new' => 'org_id'),
|
||||
'servers_organization' => array('table' => 'servers', 'old' => 'organization', 'new' => 'remote_org_id'),
|
||||
'shadow_attributes_org' => array('table' => 'shadow_attributes', 'old' => 'org', 'new' => 'org_id'),
|
||||
'shadow_attributes_event_org' => array('table' => 'shadow_attributes', 'old' => 'event_org', 'new' => 'event_org_id'),
|
||||
'threads_org' => array('table' => 'threads', 'old' => 'org', 'new' => 'org_id'),
|
||||
'users_org' => array('table' => 'users', 'old' => 'org', 'new' => 'org_id'),
|
||||
);
|
||||
$rules = array(
|
||||
'local' => array(
|
||||
$captureRules['users_org'],
|
||||
),
|
||||
'external' => array(
|
||||
$captureRules['events_org'],
|
||||
$captureRules['events_orgc'],
|
||||
$captureRules['shadow_attributes_event_org'],
|
||||
$captureRules['shadow_attributes_org'],
|
||||
$captureRules['servers_organization'],
|
||||
$captureRules['threads_org'],
|
||||
$captureRules['jobs_org'],
|
||||
$captureRules['servers_org'],
|
||||
)
|
||||
);
|
||||
foreach ($rules as $k => $type) {
|
||||
foreach ($type as $rule) {
|
||||
$temp = ($this->query('SELECT DISTINCT(`' . $rule['old'] . '`) from `' . $rule['table'] . '` WHERE ' . $rule['new'] . '= "";'));
|
||||
foreach ($temp as $t) {
|
||||
// in case we have something in the db with a missing org, let's hop over that
|
||||
if ($t[$rule['table']][$rule['old']] !== '') {
|
||||
if ($k == 'local' && !in_array($t[$rule['table']][$rule['old']], $orgs[$k])) {
|
||||
$orgs[$k][] = $t[$rule['table']][$rule['old']];
|
||||
} elseif ($k == 'external' && !in_array($t[$rule['table']][$rule['old']], $orgs['local']) && !in_array($t[$rule['table']][$rule['old']], $orgs[$k])) {
|
||||
$orgs[$k][] = $t[$rule['table']][$rule['old']];
|
||||
}
|
||||
} else {
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'upgrade_24',
|
||||
'user_id' => 0,
|
||||
'title' => '[ERROR] - Detected empty string organisation identifier during the upgrade',
|
||||
'change' => 'Detected entries in table `' . $rule['table'] . '` where `' . $rule['old'] . '` was blank. This has to be resolved manually!',
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'upgrade_24',
|
||||
'user_id' => 0,
|
||||
'title' => 'Organisation creation',
|
||||
'change' => 'Detected ' . count($orgs['local']) . ' local organisations and ' . count($orgs['external']) . ' external organisations. Starting organisation creation.',
|
||||
));
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 20);
|
||||
$this->Job->saveField('message', 'Starting organisation creation');
|
||||
}
|
||||
$orgMapping = array();
|
||||
foreach ($orgs as $k => $orgArray) {
|
||||
foreach ($orgArray as $org) {
|
||||
$orgMapping[$org] = $this->Organisation->createOrgFromName($org, $user_id, $k == 'local' ? true : false);
|
||||
}
|
||||
}
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => 0,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'upgrade_24',
|
||||
'user_id' => 0,
|
||||
'title' => 'Organisations created and / or mapped',
|
||||
'change' => 'Captured all missing organisations and created a mapping between the old organisation tag and the organisation IDs. ',
|
||||
));
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 30);
|
||||
$this->Job->saveField('message', 'Updating all current entries');
|
||||
}
|
||||
foreach ($orgMapping as $old => $new) {
|
||||
foreach ($captureRules as $rule) {
|
||||
$this->query('UPDATE `' . $rule['table'] . '` SET `' . $rule['new'] . '`="' . $new . '" WHERE (`' . $rule['old'] . '`="' . $old . '" AND `' . $rule['new'] . '`="");');
|
||||
}
|
||||
}
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 40);
|
||||
$this->Job->saveField('message', 'Rebuilding all correlations.');
|
||||
}
|
||||
//$this->Attribute->generateCorrelation($jobId, 40);
|
||||
// upgrade correlations. No need to recorrelate, we can be a bit trickier here
|
||||
// Private = 0 attributes become distribution 1 for both the event and attribute.
|
||||
// For all intents and purposes, this oversimplification works fine when upgrading from 2.3
|
||||
// Even though the distribution values stored in the correlation won't be correct, they will provide the exact same realeasability
|
||||
// Event1 = distribution 0 and Attribute1 distribution 3 would lead to private = 1, so setting distribution = 0 and a_distribution = 0
|
||||
// will result in the same visibility, etc. Once events / attributes get put into a sharing group this will get recorrelated anyway
|
||||
// Also by unsetting the org field after the move the changes we ensure that these correlations won't get hit again by the script if we rerun it
|
||||
// and that we don't accidentally "upgrade" a 2.4 correlation
|
||||
$this->query('UPDATE correlations SET distribution = 1, a_distribution = 1 WHERE org != "" AND private = 0');
|
||||
foreach ($orgMapping as $old => $new) {
|
||||
$this->query('UPDATE correlations SET org_id = "' . $new . '", org = "" WHERE org = "' . $old . '";');
|
||||
}
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 60);
|
||||
$this->Job->saveField('message', 'Correlations rebuilt. Indexing all tables.');
|
||||
}
|
||||
$this->updateDatabase('indexTables');
|
||||
if (Configure::read('MISP.background_jobs') && $jobId) {
|
||||
$this->Job->saveField('progress', 100);
|
||||
$this->Job->saveField('message', 'Upgrade complete.');
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the version string of a connected instance
|
||||
* error codes:
|
||||
* 1: received non json response
|
||||
|
|
|
@ -7,7 +7,7 @@ class User extends AppModel
|
|||
{
|
||||
public $displayField = 'email';
|
||||
|
||||
public $orgField = array('Organisation', 'name'); // TODO Audit, LogableBehaviour + org
|
||||
public $orgField = array('Organisation', 'name');
|
||||
|
||||
public $validate = array(
|
||||
'role_id' => array(
|
||||
|
@ -206,7 +206,7 @@ class User extends AppModel
|
|||
);
|
||||
|
||||
public $actsAs = array(
|
||||
'SysLogLogable.SysLogLogable' => array( // TODO Audit, logable
|
||||
'SysLogLogable.SysLogLogable' => array(
|
||||
'userModel' => 'User',
|
||||
'userKey' => 'user_id',
|
||||
'change' => 'full',
|
||||
|
@ -303,20 +303,17 @@ class User extends AppModel
|
|||
}
|
||||
|
||||
// Checks if the GnuPG key is a valid key, but also import it in the keychain.
|
||||
// TODO: this will NOT fail on keys that can only be used for signing but not encryption!
|
||||
// this will NOT fail on keys that can only be used for signing but not encryption!
|
||||
// the method in verifyUsers will fail in that case.
|
||||
public function validateGpgkey($check)
|
||||
{
|
||||
// LATER first remove the old gpgkey from the keychain
|
||||
|
||||
// empty value
|
||||
if (empty($check['gpgkey'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// we have a clean, hopefully public, key here
|
||||
|
||||
// key is entered
|
||||
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')));
|
||||
|
@ -331,12 +328,12 @@ class User extends AppModel
|
|||
}
|
||||
} catch (Exception $e) {
|
||||
$this->log($e->getMessage());
|
||||
return true; // TODO was false
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the certificate is a valid x509 certificate, but also import it in the keychain.
|
||||
// TODO: this will NOT fail on keys that can only be used for signing but not encryption!
|
||||
// this will NOT fail on keys that can only be used for signing but not encryption!
|
||||
// the method in verifyUsers will fail in that case.
|
||||
public function validateCertificate($check)
|
||||
{
|
||||
|
@ -351,48 +348,7 @@ class User extends AppModel
|
|||
|
||||
// Check if $check is a x509 certificate
|
||||
if (openssl_x509_read($check['certif_public'])) {
|
||||
try {
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$fileAccessTool = new FileAccessTool();
|
||||
$dir = APP . 'tmp' . DS . 'SMIME';
|
||||
if (!file_exists($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) {
|
||||
throw new MethodNotAllowedException('The SMIME temp directory is not writeable (app/tmp/SMIME).');
|
||||
}
|
||||
}
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg_test = $fileAccessTool->writeToFile($tempFile, 'test');
|
||||
$msg_test_encrypted = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
// encrypt it
|
||||
if (openssl_pkcs7_encrypt($msg_test, $msg_test_encrypted, $check['certif_public'], null, 0, OPENSSL_CIPHER_AES_256_CBC)) {
|
||||
unlink($msg_test);
|
||||
unlink($msg_test_encrypted);
|
||||
$parse = openssl_x509_parse($check['certif_public']);
|
||||
// Valid certificate ?
|
||||
$now = new DateTime("now");
|
||||
$validTo_time_t_epoch = $parse['validTo_time_t'];
|
||||
$validTo_time_t = new DateTime("@$validTo_time_t_epoch");
|
||||
if ($validTo_time_t > $now) {
|
||||
// purposes smimeencrypt ?
|
||||
if (($parse['purposes'][5][0] == 1) and ($parse['purposes'][5][2] == 'smimeencrypt')) {
|
||||
return true;
|
||||
} else {
|
||||
return 'This certificate cannot be used to encrypt email';
|
||||
}
|
||||
} else {
|
||||
return 'This certificate is expired';
|
||||
}
|
||||
} else {
|
||||
unlink($msg_test);
|
||||
unlink($msg_test_encrypted);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
unlink($msg_test);
|
||||
unlink($msg_test_encrypted);
|
||||
$this->log($e->getMessage());
|
||||
}
|
||||
return $this->testSmimeCertificate($check['certif_public']);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -572,58 +528,65 @@ class User extends AppModel
|
|||
return $results;
|
||||
}
|
||||
|
||||
private function testSmimeCertificate($certif_public) {
|
||||
$result = array();
|
||||
try {
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$fileAccessTool = new FileAccessTool();
|
||||
$dir = APP . 'tmp' . DS . 'SMIME';
|
||||
if (!file_exists($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) {
|
||||
throw new MethodNotAllowedException('The SMIME temp directory is not writeable (app/tmp/SMIME).');
|
||||
}
|
||||
}
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg_test = $fileAccessTool->writeToFile($tempFile, 'test');
|
||||
$msg_test_encrypted = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
// encrypt it
|
||||
if (openssl_pkcs7_encrypt($msg_test, $msg_test_encrypted, $certif_public, null, 0, OPENSSL_CIPHER_AES_256_CBC)) {
|
||||
$parse = openssl_x509_parse($certif_public);
|
||||
// Valid certificate ?
|
||||
$now = new DateTime("now");
|
||||
$validTo_time_t_epoch = $parse['validTo_time_t'];
|
||||
$validTo_time_t = new DateTime("@$validTo_time_t_epoch");
|
||||
if ($validTo_time_t > $now) {
|
||||
// purposes smimeencrypt ?
|
||||
if (($parse['purposes'][5][0] == 1) && ($parse['purposes'][5][2] == 'smimeencrypt')) {
|
||||
$result = true;
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt good -- Model/User purposes is NOT GOOD'
|
||||
$result = 'This certificate cannot be used to encrypt email';
|
||||
}
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt good -- Model/User expired;
|
||||
$result = 'This certificate is expired';
|
||||
}
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt NOT good -- Model/User
|
||||
$result = 'This certificate cannot be used to encrypt email';
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->log($e->getMessage());
|
||||
}
|
||||
unlink($msg_test);
|
||||
unlink($msg_test_encrypted);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function verifyCertificate()
|
||||
{
|
||||
$this->Behaviors->detach('Trim');
|
||||
$results = array();
|
||||
$users = $this->find('all', array(
|
||||
'conditions' => array('not' => array('certif_public' => '')),
|
||||
//'fields' => array('id', 'email', 'gpgkey'),
|
||||
'recursive' => -1,
|
||||
));
|
||||
foreach ($users as $k => $user) {
|
||||
$certif_public = $user['User']['certif_public'];
|
||||
try {
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$fileAccessTool = new FileAccessTool();
|
||||
$dir = APP . 'tmp' . DS . 'SMIME';
|
||||
if (!file_exists($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) {
|
||||
throw new MethodNotAllowedException('The SMIME temp directory is not writeable (app/tmp/SMIME).');
|
||||
}
|
||||
}
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg_test = $fileAccessTool->writeToFile($tempFile, 'test');
|
||||
$msg_test_encrypted = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
// encrypt it
|
||||
if (openssl_pkcs7_encrypt($msg_test, $msg_test_encrypted, $certif_public, null, 0, OPENSSL_CIPHER_AES_256_CBC)) {
|
||||
$parse = openssl_x509_parse($certif_public);
|
||||
// Valid certificate ?
|
||||
$now = new DateTime("now");
|
||||
$validTo_time_t_epoch = $parse['validTo_time_t'];
|
||||
$validTo_time_t = new DateTime("@$validTo_time_t_epoch");
|
||||
if ($validTo_time_t > $now) {
|
||||
// purposes smimeencrypt ?
|
||||
if (($parse['purposes'][5][0] == 1) && ($parse['purposes'][5][2] == 'smimeencrypt')) {
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt good -- Model/User purposes is NOT GOOD'
|
||||
$results[$user['User']['id']][0] = true;
|
||||
}
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt good -- Model/User expired;
|
||||
$results[$user['User']['id']][0] = true;
|
||||
}
|
||||
} else {
|
||||
// openssl_pkcs7_encrypt NOT good -- Model/User
|
||||
$results[$user['User']['id']][0] = true;
|
||||
}
|
||||
$results[$user['User']['id']][1] = $user['User']['email'];
|
||||
} catch (Exception $e) {
|
||||
$this->log($e->getMessage());
|
||||
$result = $this->testSmimeCertificate($user['User']['certif_public']);
|
||||
if ($result !== true) {
|
||||
$results[$user['User']['id']] = array(0 => true, 1 => $user['User']['email']);
|
||||
}
|
||||
unlink($msg_test);
|
||||
unlink($msg_test_encrypted);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
@ -782,20 +745,14 @@ class User extends AppModel
|
|||
));
|
||||
return true;
|
||||
}
|
||||
if (isset($user['User']['disabled']) && $user['User']['disabled']) {
|
||||
if (!empty($user['User']['disabled'])) {
|
||||
return true;
|
||||
}
|
||||
$failed = false;
|
||||
$failureReason = "";
|
||||
// check if the e-mail can be encrypted
|
||||
$canEncryptGPG = false;
|
||||
if (isset($user['User']['gpgkey']) && !empty($user['User']['gpgkey'])) {
|
||||
$canEncryptGPG = true;
|
||||
}
|
||||
$canEncryptSMIME = false;
|
||||
if (isset($user['User']['certif_public']) && !empty($user['User']['certif_public']) && Configure::read('SMIME.enabled')) {
|
||||
$canEncryptSMIME = true;
|
||||
}
|
||||
$canEncryptGPG = isset($user['User']['gpgkey']) && !empty($user['User']['gpgkey']);
|
||||
$canEncryptSMIME = isset($user['User']['certif_public']) && !empty($user['User']['certif_public']) && Configure::read('SMIME.enabled');
|
||||
|
||||
// If bodyonlyencrypted is enabled and the user has no encryption key, use the alternate body (if it exists)
|
||||
if (Configure::read('GnuPG.bodyonlyencrypted') && !$canEncryptSMIME && !$canEncryptGPG && $bodyNoEnc) {
|
||||
|
@ -803,21 +760,6 @@ class User extends AppModel
|
|||
}
|
||||
$body = str_replace('\n', PHP_EOL, $body);
|
||||
|
||||
if ($canEncryptGPG) {
|
||||
// Sign the body
|
||||
require_once 'Crypt/GPG.php';
|
||||
try {
|
||||
$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'), 'debug')); // , 'debug' => true
|
||||
if (Configure::read('GnuPG.sign')) {
|
||||
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
|
||||
$body = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$failureReason = " the message could not be signed. The following error message was returned by gpg: " . $e->getMessage();
|
||||
$this->log($e->getMessage());
|
||||
$failed = true;
|
||||
}
|
||||
}
|
||||
$Email = new CakeEmail();
|
||||
// If we cannot encrypt the mail and the server settings restricts sending unencrypted messages, return false
|
||||
if (!$failed && Configure::read('GnuPG.onlyencrypted') && !$canEncryptGPG && !$canEncryptSMIME) {
|
||||
|
@ -826,6 +768,98 @@ class User extends AppModel
|
|||
}
|
||||
// Let's encrypt the message if we can
|
||||
if (!$failed && $canEncryptGPG) {
|
||||
$encryptionResult = $this->__encryptUsingGPG($Email, $body, $subject, $user);
|
||||
if (isset($encryptionResult['failed'])) {
|
||||
$failed = true;
|
||||
}
|
||||
if (isset($encryptionResult['failureReason'])) {
|
||||
$failureReason = $encryptionResult['failureReason'];
|
||||
}
|
||||
}
|
||||
// SMIME if not GPG key
|
||||
if (!$failed && !$canEncryptGPG && $canEncryptSMIME) {
|
||||
$encryptionResult = $this->__encryptUsingSmime($Email, $body, $subject);
|
||||
if (isset($encryptionResult['failed'])) {
|
||||
$failed = true;
|
||||
}
|
||||
if (isset($encryptionResult['failureReason'])) {
|
||||
$failureReason = $encryptionResult['failureReason'];
|
||||
}
|
||||
}
|
||||
$replyToLog = '';
|
||||
if (!$failed) {
|
||||
$result = $this->__finaliseAndSendEmail($replyToUser, $Email, $replyToLog, $user, $subject, $body);
|
||||
}
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
if (!$failed && $result) {
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['User']['id'],
|
||||
'email' => $user['User']['email'],
|
||||
'action' => 'email',
|
||||
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ' sent, titled "' . $subject . '".',
|
||||
'change' => null,
|
||||
));
|
||||
return true;
|
||||
} else {
|
||||
if (empty($failureReason)) {
|
||||
$failureReason = " there was an error sending the e-mail.";
|
||||
}
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['User']['id'],
|
||||
'email' => $user['User']['email'],
|
||||
'action' => 'email',
|
||||
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ', titled "' . $subject . '" failed. Reason: ' . $failureReason,
|
||||
'change' => null,
|
||||
));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function __finaliseAndSendEmail($replyToUser, &$Email, &$replyToLog, $user, $subject, $body)
|
||||
{
|
||||
// If the e-mail is sent on behalf of a user, then we want the target user to be able to respond to the sender
|
||||
// For this reason we should also attach the public key of the sender along with the message (if applicable)
|
||||
if ($replyToUser != false) {
|
||||
$Email->replyTo($replyToUser['User']['email']);
|
||||
if (!empty($replyToUser['User']['gpgkey'])) {
|
||||
$Email->attachments(array('gpgkey.asc' => array('data' => $replyToUser['User']['gpgkey'])));
|
||||
} elseif (!empty($replyToUser['User']['certif_public'])) {
|
||||
$Email->attachments(array($replyToUser['User']['email'] . '.pem' => array('data' => $replyToUser['User']['certif_public'])));
|
||||
}
|
||||
$replyToLog = 'from ' . $replyToUser['User']['email'];
|
||||
}
|
||||
$Email->from(Configure::read('MISP.email'));
|
||||
$Email->returnPath(Configure::read('MISP.email'));
|
||||
$Email->to($user['User']['email']);
|
||||
$Email->subject($subject);
|
||||
$Email->emailFormat('text');
|
||||
$result = $Email->send($body);
|
||||
$Email->reset();
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function __encryptUsingGPG(&$Email, &$body, $subject, $user)
|
||||
{
|
||||
$failed = false;
|
||||
// Sign the body
|
||||
require_once 'Crypt/GPG.php';
|
||||
try {
|
||||
$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'), 'debug')); // , 'debug' => true
|
||||
if (Configure::read('GnuPG.sign')) {
|
||||
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
|
||||
$body = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$failureReason = " the message could not be signed. The following error message was returned by gpg: " . $e->getMessage();
|
||||
$this->log($e->getMessage());
|
||||
$failed = true;
|
||||
}
|
||||
if (!$failed) {
|
||||
$keyImportOutput = $gpg->importKey($user['User']['gpgkey']);
|
||||
try {
|
||||
$key = $gpg->getKeys($keyImportOutput['fingerprint']);
|
||||
|
@ -852,119 +886,75 @@ class User extends AppModel
|
|||
$failed = true;
|
||||
}
|
||||
}
|
||||
// SMIME if not GPG key
|
||||
if (!$failed && !$canEncryptGPG && $canEncryptSMIME) {
|
||||
try {
|
||||
$prependedBody = 'Content-Transfer-Encoding: 7bit' . PHP_EOL . 'Content-Type: text/plain;' . PHP_EOL . ' charset=us-ascii' . PHP_EOL . PHP_EOL . $body;
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$fileAccessTool = new FileAccessTool();
|
||||
$dir = APP . 'tmp' . DS . 'SMIME';
|
||||
if (!file_exists($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) {
|
||||
throw new MethodNotAllowedException('The SMIME temp directory is not writeable (app/tmp/SMIME).');
|
||||
}
|
||||
if (!empty($failed)) {
|
||||
return array('failed' => $failed, 'failureReason' => $failureReason);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function __encryptUsingSmime(&$Email, &$body, $subject)
|
||||
{
|
||||
try {
|
||||
$prependedBody = 'Content-Transfer-Encoding: 7bit' . PHP_EOL . 'Content-Type: text/plain;' . PHP_EOL . ' charset=us-ascii' . PHP_EOL . PHP_EOL . $body;
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
$fileAccessTool = new FileAccessTool();
|
||||
$dir = APP . 'tmp' . DS . 'SMIME';
|
||||
if (!file_exists($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) {
|
||||
throw new MethodNotAllowedException('The SMIME temp directory is not writeable (app/tmp/SMIME).');
|
||||
}
|
||||
}
|
||||
// save message to file
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg = $fileAccessTool->writeToFile($tempFile, $prependedBody);
|
||||
$headers_smime = array("To" => $user['User']['email'], "From" => Configure::read('MISP.email'), "Subject" => $subject);
|
||||
$canSign = true;
|
||||
if (
|
||||
!empty(Configure::read('SMIME.cert_public_sign')) &&
|
||||
is_readable(Configure::read('SMIME.cert_public_sign')) &&
|
||||
!empty(Configure::read('SMIME.key_sign')) &&
|
||||
is_readable(Configure::read('SMIME.key_sign'))
|
||||
) {
|
||||
$signed = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
if (openssl_pkcs7_sign($msg, $signed, 'file://'.Configure::read('SMIME.cert_public_sign'), array('file://'.Configure::read('SMIME.key_sign'), Configure::read('SMIME.password')), array(), PKCS7_TEXT)) {
|
||||
$bodySigned = $fileAccessTool->readFromFile($signed);
|
||||
unlink($msg);
|
||||
unlink($signed);
|
||||
} else {
|
||||
unlink($msg);
|
||||
unlink($signed);
|
||||
throw new Exception('Failed while attempting to sign the SMIME message.');
|
||||
}
|
||||
// save message to file
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg = $fileAccessTool->writeToFile($tempFile, $prependedBody);
|
||||
$headers_smime = array("To" => $user['User']['email'], "From" => Configure::read('MISP.email'), "Subject" => $subject);
|
||||
$canSign = true;
|
||||
if (empty(Configure::read('SMIME.cert_public_sign')) || !is_readable(Configure::read('SMIME.cert_public_sign'))) {
|
||||
$canSign = false;
|
||||
}
|
||||
if (empty(Configure::read('SMIME.key_sign')) || !is_readable(Configure::read('SMIME.key_sign'))) {
|
||||
$canSign = false;
|
||||
}
|
||||
if ($canSign) {
|
||||
$signed = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
if (openssl_pkcs7_sign($msg, $signed, 'file://'.Configure::read('SMIME.cert_public_sign'), array('file://'.Configure::read('SMIME.key_sign'), Configure::read('SMIME.password')), array(), PKCS7_TEXT)) {
|
||||
$bodySigned = $fileAccessTool->readFromFile($signed);
|
||||
unlink($msg);
|
||||
unlink($signed);
|
||||
} else {
|
||||
unlink($msg);
|
||||
unlink($signed);
|
||||
throw new Exception('Failed while attempting to sign the SMIME message.');
|
||||
}
|
||||
// save message to file
|
||||
$tempFile = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
$msg_signed = $fileAccessTool->writeToFile($tempFile, $bodySigned);
|
||||
} else {
|
||||
$msg_signed = $msg;
|
||||
}
|
||||
$msg_signed_encrypted = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
// encrypt it
|
||||
if (openssl_pkcs7_encrypt($msg_signed, $msg_signed_encrypted, $user['User']['certif_public'], $headers_smime, 0, OPENSSL_CIPHER_AES_256_CBC)) {
|
||||
$bodyEncSig = $fileAccessTool->readFromFile($msg_signed_encrypted);
|
||||
unlink($msg_signed);
|
||||
unlink($msg_signed_encrypted);
|
||||
$parts = explode("\n\n", $bodyEncSig);
|
||||
$bodyEncSig = $parts[1];
|
||||
// SMIME transport (hardcoded headers
|
||||
$Email = $Email->transport('Smime');
|
||||
$body = $bodyEncSig;
|
||||
} else {
|
||||
unlink($msg_signed);
|
||||
unlink($msg_signed_encrypted);
|
||||
throw new Exception('Could not encrypt the SMIME message.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// despite the user having a certificate. This must mean that there is an issue with the user's certificate.
|
||||
$failureReason = " the message could not be encrypted because there was an issue with the user's public certificate. The following error message was returned by openssl: " . $e->getMessage();
|
||||
$this->log($e->getMessage());
|
||||
$failed = true;
|
||||
$msg_signed = $fileAccessTool->writeToFile($tempFile, $bodySigned);
|
||||
} else {
|
||||
$msg_signed = $msg;
|
||||
}
|
||||
}
|
||||
$replyToLog = '';
|
||||
if (!$failed) {
|
||||
// If the e-mail is sent on behalf of a user, then we want the target user to be able to respond to the sender
|
||||
// For this reason we should also attach the public key of the sender along with the message (if applicable)
|
||||
if ($replyToUser != false) {
|
||||
$Email->replyTo($replyToUser['User']['email']);
|
||||
if (!empty($replyToUser['User']['gpgkey'])) {
|
||||
$Email->attachments(array('gpgkey.asc' => array('data' => $replyToUser['User']['gpgkey'])));
|
||||
} elseif (!empty($replyToUser['User']['certif_public'])) {
|
||||
$Email->attachments(array($replyToUser['User']['email'] . '.pem' => array('data' => $replyToUser['User']['certif_public'])));
|
||||
}
|
||||
$replyToLog = 'from ' . $replyToUser['User']['email'];
|
||||
$msg_signed_encrypted = $fileAccessTool->createTempFile($dir, 'SMIME');
|
||||
// encrypt it
|
||||
if (openssl_pkcs7_encrypt($msg_signed, $msg_signed_encrypted, $user['User']['certif_public'], $headers_smime, 0, OPENSSL_CIPHER_AES_256_CBC)) {
|
||||
$bodyEncSig = $fileAccessTool->readFromFile($msg_signed_encrypted);
|
||||
unlink($msg_signed);
|
||||
unlink($msg_signed_encrypted);
|
||||
$parts = explode("\n\n", $bodyEncSig);
|
||||
$bodyEncSig = $parts[1];
|
||||
// SMIME transport (hardcoded headers
|
||||
$Email = $Email->transport('Smime');
|
||||
$body = $bodyEncSig;
|
||||
} else {
|
||||
unlink($msg_signed);
|
||||
unlink($msg_signed_encrypted);
|
||||
throw new Exception('Could not encrypt the SMIME message.');
|
||||
}
|
||||
$Email->from(Configure::read('MISP.email'));
|
||||
$Email->returnPath(Configure::read('MISP.email'));
|
||||
$Email->to($user['User']['email']);
|
||||
$Email->subject($subject);
|
||||
$Email->emailFormat('text');
|
||||
$result = $Email->send($body);
|
||||
$Email->reset();
|
||||
} catch (Exception $e) {
|
||||
// despite the user having a certificate. This must mean that there is an issue with the user's certificate.
|
||||
$result['failureReason'] = " the message could not be encrypted because there was an issue with the user's public certificate. The following error message was returned by openssl: " . $e->getMessage();
|
||||
$this->log($e->getMessage());
|
||||
$result['failed'] = true;
|
||||
}
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
if (!$failed && $result) {
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['User']['id'],
|
||||
'email' => $user['User']['email'],
|
||||
'action' => 'email',
|
||||
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ' sent, titled "' . $subject . '".',
|
||||
'change' => null,
|
||||
));
|
||||
return true;
|
||||
} else {
|
||||
if (isset($result) && !$result) {
|
||||
$failureReason = " there was an error sending the e-mail.";
|
||||
}
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['User']['id'],
|
||||
'email' => $user['User']['email'],
|
||||
'action' => 'email',
|
||||
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ', titled "' . $subject . '" failed. Reason: ' . $failureReason,
|
||||
'change' => null,
|
||||
));
|
||||
}
|
||||
return false;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function adminMessageResolve($message)
|
||||
|
@ -1033,12 +1023,12 @@ class User extends AppModel
|
|||
{
|
||||
$fields = array();
|
||||
$fields = array_merge($fields, array_keys($this->getColumnTypes()));
|
||||
if (($key = array_search('gpgkey', $fields)) !== false) {
|
||||
unset($fields[$key]);
|
||||
}
|
||||
if (($key = array_search('certif_public', $fields)) !== false) {
|
||||
unset($fields[$key]);
|
||||
foreach ($fields as $k => $field) {
|
||||
if (in_array($field, array('gpgkey', 'certif_public'))) {
|
||||
unset($fields[$k]);
|
||||
}
|
||||
}
|
||||
$fields = array_values($fields);
|
||||
$relatedModels = array_keys($this->belongsTo);
|
||||
foreach ($relatedModels as $relatedModel) {
|
||||
$fields[] = $relatedModel . '.*';
|
||||
|
|
|
@ -461,7 +461,7 @@ class StixBuilder():
|
|||
killchain = self.create_killchain(category)
|
||||
labels = self.create_labels(attribute)
|
||||
attribute_value = attribute.value if attribute_type != "AS" else self.define_attribute_value(attribute.value, attribute.comment)
|
||||
pattern = mispTypesMapping[attribute_type]['pattern'](attribute_type, attribute_value, b64encode(attribute.data.getbuffer()).decode()[1:-1]) if 'data' in attribute else self.define_pattern(attribute_type, attribute_value)
|
||||
pattern = mispTypesMapping[attribute_type]['pattern'](attribute_type, attribute_value, b64encode(attribute.data.getbuffer()).decode()[1:-1]) if ('data' in attribute and attribute.data) else self.define_pattern(attribute_type, attribute_value)
|
||||
indicator_args = {'id': indicator_id, 'type': 'indicator', 'labels': labels, 'kill_chain_phases': killchain,
|
||||
'valid_from': attribute.timestamp, 'created_by_ref': self.identity_id, 'pattern': pattern}
|
||||
if hasattr(attribute, 'comment') and attribute.comment:
|
||||
|
@ -644,9 +644,11 @@ class StixBuilder():
|
|||
|
||||
@staticmethod
|
||||
def create_labels(attribute):
|
||||
return ['misp:type="{}"'.format(attribute.type),
|
||||
'misp:category="{}"'.format(attribute.category),
|
||||
'misp:to_ids="{}"'.format(attribute.to_ids)]
|
||||
labels = ['misp:type="{}"'.format(attribute.type),
|
||||
'misp:category="{}"'.format(attribute.category),
|
||||
'misp:to_ids="{}"'.format(attribute.to_ids)]
|
||||
labels += [tag.name for tag in attribute.Tag]
|
||||
return labels
|
||||
|
||||
@staticmethod
|
||||
def create_object_labels(name, category, to_ids):
|
||||
|
|
|
@ -278,6 +278,9 @@ class StixParser():
|
|||
attribute_type = self.get_misp_type(labels)
|
||||
attribute_category = self.get_misp_category(labels)
|
||||
attribute = {'type': attribute_type, 'category': attribute_category}
|
||||
tags = [{'name': label} for label in labels[3:]]
|
||||
if tags:
|
||||
attribute['Tag'] = tags
|
||||
stix_type = o._type
|
||||
if stix_type == 'vulnerability':
|
||||
value = o.get('name')
|
||||
|
|
Loading…
Reference in New Issue