mirror of https://github.com/MISP/MISP
Merge remote-tracking branch 'upstream/2.4' into guides
commit
7781ce35ed
|
@ -583,7 +583,7 @@ class AdminShell extends AppShell
|
|||
'db_version' => $dbVersion
|
||||
);
|
||||
$file = new File(ROOT . DS . 'db_schema.json', true);
|
||||
$file->write(json_encode($data, JSON_PRETTY_PRINT));
|
||||
$file->write(json_encode($data, JSON_PRETTY_PRINT) . "\n");
|
||||
$file->close();
|
||||
echo __("> Database schema dumped on disk") . PHP_EOL;
|
||||
} else {
|
||||
|
@ -640,4 +640,19 @@ class AdminShell extends AppShell
|
|||
PHP_EOL, PHP_EOL, $ip, PHP_EOL, PHP_EOL, $user['User']['id'], $user['User']['email'], PHP_EOL, PHP_EOL
|
||||
);
|
||||
}
|
||||
|
||||
public function scanAttachment()
|
||||
{
|
||||
$input = $this->args[0];
|
||||
$attributeId = isset($this->args[1]) ? $this->args[1] : null;
|
||||
$jobId = isset($this->args[2]) ? $this->args[2] : null;
|
||||
|
||||
$this->loadModel('AttachmentScan');
|
||||
$result = $this->AttachmentScan->scan($input, $attributeId, $jobId);
|
||||
if ($result === false) {
|
||||
echo 'Job failed' . PHP_EOL;
|
||||
} else {
|
||||
echo $result . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,10 +36,15 @@ class ServerShell extends AppShell
|
|||
}
|
||||
|
||||
$serverId = intval($this->args[0]);
|
||||
$res = @$this->Server->runConnectionTest($serverId);
|
||||
if (!empty($res['message']))
|
||||
$res['message'] = json_decode($res['message']);
|
||||
$server = $this->Server->find('first', [
|
||||
'conditions' => ['Server.id' => $serverId],
|
||||
'recursive' => -1,
|
||||
]);
|
||||
if (!$server) {
|
||||
die("Server with ID $serverId doesn't exists.");
|
||||
}
|
||||
|
||||
$res = @$this->Server->runConnectionTest($server);
|
||||
echo json_encode($res) . PHP_EOL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
class StatisticsShell extends AppShell {
|
||||
|
||||
public $uses = array('Event', 'User', 'Organisation', 'Log');
|
||||
|
||||
public function contributors()
|
||||
{
|
||||
$from = empty($this->args[0]) ? null : $this->args[0];
|
||||
|
@ -133,4 +135,120 @@ class StatisticsShell extends AppShell {
|
|||
}
|
||||
echo "==================================\n\n";
|
||||
}
|
||||
|
||||
public function orgEngagement()
|
||||
{
|
||||
$orgs = $this->Organisation->find('list', [
|
||||
'recursive' => -1,
|
||||
'fields' => ['Organisation.id', 'Organisation.id'],
|
||||
'conditions' => ['Organisation.local' => 1]
|
||||
]);
|
||||
$orgs = array_values($orgs);
|
||||
$total_orgs = count($orgs);
|
||||
$data = [];
|
||||
$orgCreations = $this->Log->find('list', [
|
||||
'conditions' => [
|
||||
'model' => 'Organisation',
|
||||
'action' => 'add'
|
||||
],
|
||||
'fields' => ['Log.model_id', 'Log.created']
|
||||
]);
|
||||
$localOrgs = $this->Organisation->find('count', [
|
||||
'conditions' => [
|
||||
'Organisation.local' => 1
|
||||
]
|
||||
]);
|
||||
foreach ($orgs as $k => $org) {
|
||||
echo sprintf(__('Processing organisation %s / %s.%s', $k+1, $total_orgs, PHP_EOL));
|
||||
$temp = [
|
||||
'org_id' => $org
|
||||
];
|
||||
if (empty($orgCreations[$org])) {
|
||||
continue;
|
||||
} else {
|
||||
$temp['org_creation_timestamp'] = strtotime($orgCreations[$org]);
|
||||
}
|
||||
$first_event = $this->Event->find('first', [
|
||||
'recursive' => -1,
|
||||
'conditions' => [
|
||||
'orgc_id' => $org
|
||||
],
|
||||
'order' => ['Event.id ASC'],
|
||||
'fields' => ['Event.id']
|
||||
]);
|
||||
if (empty($first_event)) {
|
||||
continue;
|
||||
}
|
||||
$first_event_creation = $this->Log->find('first', [
|
||||
'recursive' => -1,
|
||||
'conditions' => [
|
||||
'model_id' => $first_event['Event']['id'],
|
||||
'model' => 'Event',
|
||||
'action' => 'add'
|
||||
]
|
||||
]);
|
||||
if (empty($first_event_creation)) {
|
||||
continue;
|
||||
}
|
||||
$temp['first_event_creation'] = strtotime($first_event_creation['Log']['created']);
|
||||
$temp['time_until_first_event'] = $temp['first_event_creation'] - $temp['org_creation_timestamp'];
|
||||
$data[] = $temp;
|
||||
}
|
||||
$average_time_to_first_event = 0;
|
||||
foreach ($data as $org_data) {
|
||||
$average_time_to_first_event += (int)$org_data['time_until_first_event'] / 60 / 60 / 24;
|
||||
}
|
||||
echo PHP_EOL . str_repeat('-', 63) . PHP_EOL;
|
||||
echo __('Total local orgs: %s%s', $localOrgs, PHP_EOL);
|
||||
echo __('Local orgs with event creations: %s%s', count($data), PHP_EOL);
|
||||
echo __('Average days until first event: %s', (int)($average_time_to_first_event / count($data)));
|
||||
echo PHP_EOL . str_repeat('-', 63) . PHP_EOL;
|
||||
}
|
||||
|
||||
public function yearlyOrgGrowth()
|
||||
{
|
||||
$orgCreations = $this->Log->find('list', [
|
||||
'conditions' => [
|
||||
'model' => 'Organisation',
|
||||
'action' => 'add'
|
||||
],
|
||||
'fields' => ['Log.model_id', 'Log.created']
|
||||
]);
|
||||
$localOnly = empty($this->args[0]) ? false : true;
|
||||
if ($localOnly) {
|
||||
$orgs = $this->Organisation->find('list', [
|
||||
'recursive' => -1,
|
||||
'fields' => ['Organisation.id', 'Organisation.local']
|
||||
]);
|
||||
foreach ($orgs as $org_id => $local) {
|
||||
if (!$local && isset($orgCreations[$org_id])) {
|
||||
unset($orgCreations[$org_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$years = [];
|
||||
foreach ($orgCreations as $orgCreation) {
|
||||
$year = substr($orgCreation, 0, 4);
|
||||
if (empty($years[$year])) {
|
||||
$years[$year] = 0;
|
||||
}
|
||||
$years[$year] += 1;
|
||||
}
|
||||
ksort($years);
|
||||
$yearOverYear = [];
|
||||
$previous = 0;
|
||||
echo PHP_EOL . str_repeat('-', 63) . PHP_EOL;
|
||||
echo __('Year over year growth of organisation count.');
|
||||
echo PHP_EOL . str_repeat('-', 63) . PHP_EOL;
|
||||
$currentYear = date("Y");
|
||||
foreach ($years as $year => $count) {
|
||||
$prognosis = '';
|
||||
if ($year == $currentYear) {
|
||||
$percentage_passed = (strtotime(($year +1) . '-01-01') - strtotime(($year) . '-01-01')) / (time() - (strtotime($year . '-01-01')));
|
||||
$prognosis = sprintf(' (%s by the end of the year at current rate)', round($percentage_passed * $count));
|
||||
}
|
||||
echo __('%s: %s %s%s', $year, $count - $previous, $prognosis, PHP_EOL);
|
||||
}
|
||||
echo str_repeat('-', 63) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -467,12 +467,6 @@ class AppController extends Controller
|
|||
$this->userRole = $role;
|
||||
|
||||
$this->set('loggedInUserName', $this->__convertEmailToName($this->Auth->user('email')));
|
||||
if ($this->request->params['controller'] === 'users' && $this->request->params['action'] === 'dashboard') {
|
||||
$notifications = $this->{$this->modelClass}->populateNotifications($this->Auth->user());
|
||||
} else {
|
||||
$notifications = $this->{$this->modelClass}->populateNotifications($this->Auth->user(), 'fast');
|
||||
}
|
||||
$this->set('notifications', $notifications);
|
||||
|
||||
if (
|
||||
Configure::read('MISP.log_paranoid') ||
|
||||
|
@ -543,6 +537,16 @@ class AppController extends Controller
|
|||
}
|
||||
}
|
||||
$this->components['RestResponse']['sql_dump'] = $this->sql_dump;
|
||||
|
||||
// Notifications and homepage is not necessary for AJAX or REST requests
|
||||
if ($this->Auth->user() && !$this->_isRest() && !$this->request->is('ajax')) {
|
||||
if ($this->request->params['controller'] === 'users' && $this->request->params['action'] === 'dashboard') {
|
||||
$notifications = $this->{$this->modelClass}->populateNotifications($this->Auth->user());
|
||||
} else {
|
||||
$notifications = $this->{$this->modelClass}->populateNotifications($this->Auth->user(), 'fast');
|
||||
}
|
||||
$this->set('notifications', $notifications);
|
||||
|
||||
$this->loadModel('UserSetting');
|
||||
$homepage = $this->UserSetting->find('first', array(
|
||||
'recursive' => -1,
|
||||
|
@ -556,6 +560,7 @@ class AppController extends Controller
|
|||
$this->set('homepage', $homepage['UserSetting']['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function __rateLimitCheck()
|
||||
{
|
||||
|
|
|
@ -1623,6 +1623,7 @@ class AttributesController extends AppController
|
|||
$this->Feed = ClassRegistry::init('Feed');
|
||||
|
||||
$this->loadModel('Sighting');
|
||||
$this->loadModel('AttachmentScan');
|
||||
$user = $this->Auth->user();
|
||||
foreach ($attributes as $k => $attribute) {
|
||||
$attributeId = $attribute['Attribute']['id'];
|
||||
|
@ -1635,6 +1636,10 @@ class AttributesController extends AppController
|
|||
}
|
||||
$attributes[$k] = $attribute;
|
||||
}
|
||||
if ($attribute['Attribute']['type'] === 'attachment' && $this->AttachmentScan->isEnabled()) {
|
||||
$infected = $this->AttachmentScan->isInfected(AttachmentScan::TYPE_ATTRIBUTE, $attribute['Attribute']['id']);
|
||||
$attributes[$k]['Attribute']['infected'] = $infected;
|
||||
}
|
||||
|
||||
if ($attribute['Attribute']['distribution'] == 4) {
|
||||
$attributes[$k]['Attribute']['SharingGroup'] = $attribute['SharingGroup'];
|
||||
|
@ -1948,9 +1953,17 @@ class AttributesController extends AppController
|
|||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This function can only be accessed via AJAX.'));
|
||||
}
|
||||
|
||||
$fieldsToFetch = ['id', $field];
|
||||
if ($field === 'value') {
|
||||
$fieldsToFetch[] = 'to_ids'; // for warninglist
|
||||
$fieldsToFetch[] = 'type'; // for view
|
||||
$fieldsToFetch[] = 'category'; // for view
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'conditions' => array('Attribute.id' => $id),
|
||||
'fields' => array('id', 'category', 'type', $field),
|
||||
'fields' => $fieldsToFetch,
|
||||
'contain' => ['Event'],
|
||||
'flatten' => 1,
|
||||
);
|
||||
|
@ -1970,7 +1983,11 @@ class AttributesController extends AppController
|
|||
} else {
|
||||
echo ' ';
|
||||
}
|
||||
} elseif ($field === 'value') {
|
||||
$this->loadModel('Warninglist');
|
||||
$attribute['Attribute'] = $this->Warninglist->checkForWarning($attribute['Attribute']);
|
||||
}
|
||||
|
||||
$this->set('value', $result);
|
||||
$this->set('object', $attribute);
|
||||
$this->set('field', $field);
|
||||
|
@ -2439,8 +2456,7 @@ class AttributesController extends AppController
|
|||
} else {
|
||||
$data[$attribute[0]['Attribute']['type']] = $attribute[0]['Attribute']['value'];
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$result = $this->Module->queryModuleServer('/query', $data, true);
|
||||
$result = $this->Module->queryModuleServer($data, true);
|
||||
if ($result) {
|
||||
if (!is_array($result)) {
|
||||
$resultArray[$type] = ['error' => $result];
|
||||
|
|
|
@ -1505,8 +1505,6 @@ class EventsController extends AppController
|
|||
$this->set('advancedFilteringActive', $advancedFiltering['active'] ? 1 : 0);
|
||||
$this->set('advancedFilteringActiveRules', $advancedFiltering['activeRules']);
|
||||
$this->set('defaultFilteringRules', $this->defaultFilteringRules);
|
||||
$this->loadModel('Galaxy');
|
||||
$this->set('mitreAttackGalaxyId', $this->Galaxy->getMitreAttackGalaxyId());
|
||||
$this->set('modificationMapCSV', $modificationMapCSV);
|
||||
$this->set('title_for_layout', __('Event #%s', $event['Event']['id']));
|
||||
}
|
||||
|
@ -4518,11 +4516,16 @@ class EventsController extends AppController
|
|||
|
||||
public function viewGalaxyMatrix($scope_id, $galaxy_id, $scope='event', $disable_picking=false)
|
||||
{
|
||||
$local = !empty($this->params['named']['local']);
|
||||
$this->set('local', $local);
|
||||
$this->loadModel('Galaxy');
|
||||
$mitreAttackGalaxyId = $this->Galaxy->getMitreAttackGalaxyId();
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
|
||||
if ($galaxy_id === 'mitre-attack') { // specific case for MITRE ATTACK matrix
|
||||
$galaxy_id = $mitreAttackGalaxyId;
|
||||
}
|
||||
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id); // throws exception if matrix not found
|
||||
|
||||
$local = !empty($this->params['named']['local']);
|
||||
$this->set('local', $local);
|
||||
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
|
@ -4759,8 +4762,7 @@ class EventsController extends AppController
|
|||
if (!empty($options)) {
|
||||
$data['config'] = $options;
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$result = $this->Module->queryModuleServer('/query', $data, false, $type);
|
||||
$result = $this->Module->queryModuleServer($data, false, $type);
|
||||
if (!$result) {
|
||||
throw new MethodNotAllowedException(__('%s service not reachable.', $type));
|
||||
}
|
||||
|
@ -4805,8 +4807,7 @@ class EventsController extends AppController
|
|||
if (!empty($options)) {
|
||||
$data['config'] = $options;
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$result = $this->Module->queryModuleServer('/query', $data, false, $type);
|
||||
$result = $this->Module->queryModuleServer($data, false, $type);
|
||||
if (!$result) {
|
||||
throw new MethodNotAllowedException(__('%s service not reachable.', $type));
|
||||
}
|
||||
|
@ -4996,7 +4997,7 @@ class EventsController extends AppController
|
|||
if (!empty($filename)) {
|
||||
$modulePayload['filename'] = $filename;
|
||||
}
|
||||
$result = $this->Module->queryModuleServer('/query', json_encode($modulePayload), false, $moduleFamily = 'Import');
|
||||
$result = $this->Module->queryModuleServer($modulePayload, false, $moduleFamily = 'Import');
|
||||
if (!$result) {
|
||||
throw new Exception(__('Import service not reachable.'));
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ class LogsController extends AppController
|
|||
{
|
||||
parent::beforeFilter();
|
||||
|
||||
// permit reuse of CSRF tokens on the search page.
|
||||
// No need for CSRF tokens for a search
|
||||
if ('admin_search' == $this->request->params['action']) {
|
||||
$this->Security->csrfUseOnce = false;
|
||||
$this->Security->csrfCheck = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class ModulesController extends AppController
|
|||
}
|
||||
|
||||
// Query
|
||||
$result = $this->Module->queryModuleServer('/query', json_encode($data), true);
|
||||
$result = $this->Module->queryModuleServer($data, true);
|
||||
if (!$result) {
|
||||
$result = array('error' => 'Something went wrong, no response from module.');
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class ObjectsController extends AppController
|
|||
|
||||
if (isset($this->request->data['Attribute'])) {
|
||||
foreach ($this->request->data['Attribute'] as &$attribute) {
|
||||
$validation = $this->MispObject->Attribute->validateAttribute($attribute);
|
||||
$validation = $this->MispObject->Attribute->validateAttribute($attribute, false);
|
||||
if ($validation !== true) {
|
||||
$attribute['validation'] = $validation;
|
||||
}
|
||||
|
|
|
@ -1121,7 +1121,14 @@ class ServersController extends AppController
|
|||
$sessionStatus = $this->Server->sessionDiagnostics($diagnostic_errors, $sessionCount);
|
||||
$this->set('sessionCount', $sessionCount);
|
||||
|
||||
$additionalViewVars = array('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'stixVersion', 'cyboxVersion', 'mixboxVersion', 'maecVersion', 'stix2Version', 'pymispVersion', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stixOperational', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'redisInfo');
|
||||
$this->loadModel('AttachmentScan');
|
||||
try {
|
||||
$attachmentScan = ['status' => true, 'software' => $this->AttachmentScan->diagnostic()];
|
||||
} catch (Exception $e) {
|
||||
$attachmentScan = ['status' => false, 'error' => $e->getMessage()];
|
||||
}
|
||||
|
||||
$additionalViewVars = array('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'stixVersion', 'cyboxVersion', 'mixboxVersion', 'maecVersion', 'stix2Version', 'pymispVersion', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stixOperational', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'redisInfo', 'attachmentScan');
|
||||
}
|
||||
// check whether the files are writeable
|
||||
$writeableDirs = $this->Server->writeableDirsDiagnostics($diagnostic_errors);
|
||||
|
@ -1659,34 +1666,33 @@ class ServersController extends AppController
|
|||
if (!$this->Auth->user('Role')['perm_sync'] && !$this->Auth->user('Role')['perm_site_admin']) {
|
||||
throw new MethodNotAllowedException('You don\'t have permission to do that.');
|
||||
}
|
||||
$this->Server->id = $id;
|
||||
if (!$this->Server->exists()) {
|
||||
|
||||
$server = $this->Server->find('first', ['Server.id' => $id]);
|
||||
if (!$server) {
|
||||
throw new NotFoundException(__('Invalid server'));
|
||||
}
|
||||
$result = $this->Server->runConnectionTest($id);
|
||||
$result = $this->Server->runConnectionTest($server);
|
||||
if ($result['status'] == 1) {
|
||||
$version = json_decode($result['message'], true);
|
||||
if (isset($version['version']) && preg_match('/^[0-9]+\.+[0-9]+\.[0-9]+$/', $version['version'])) {
|
||||
if (isset($result['info']['version']) && preg_match('/^[0-9]+\.+[0-9]+\.[0-9]+$/', $result['info']['version'])) {
|
||||
$perm_sync = false;
|
||||
if (isset($version['perm_sync'])) {
|
||||
$perm_sync = $version['perm_sync'];
|
||||
if (isset($result['info']['perm_sync'])) {
|
||||
$perm_sync = $result['info']['perm_sync'];
|
||||
}
|
||||
$perm_sighting = false;
|
||||
if (isset($version['perm_sighting'])) {
|
||||
$perm_sighting = $version['perm_sighting'];
|
||||
if (isset($result['info']['perm_sighting'])) {
|
||||
$perm_sighting = $result['info']['perm_sighting'];
|
||||
}
|
||||
App::uses('Folder', 'Utility');
|
||||
$file = new File(ROOT . DS . 'VERSION.json', true);
|
||||
$local_version = json_decode($file->read(), true);
|
||||
$file->close();
|
||||
$version = explode('.', $version['version']);
|
||||
$version = explode('.', $result['info']['version']);
|
||||
$mismatch = false;
|
||||
$newer = false;
|
||||
$parts = array('major', 'minor', 'hotfix');
|
||||
if ($version[0] == 2 && $version[1] == 4 && $version[2] > 68) {
|
||||
$post = $this->Server->runPOSTTest($id);
|
||||
$post = $this->Server->runPOSTTest($server);
|
||||
}
|
||||
$testPost = false;
|
||||
foreach ($parts as $k => $v) {
|
||||
if (!$mismatch) {
|
||||
if ($version[$k] > $local_version[$v]) {
|
||||
|
@ -1718,7 +1724,8 @@ class ServersController extends AppController
|
|||
'version' => implode('.', $version),
|
||||
'mismatch' => $mismatch,
|
||||
'newer' => $newer,
|
||||
'post' => isset($post) ? $post : 'too old'
|
||||
'post' => isset($post) ? $post : 'too old',
|
||||
'client_certificate' => $result['client_certificate'],
|
||||
)
|
||||
),
|
||||
'type' => 'json'
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
class ButtonWidget
|
||||
{
|
||||
public $title = 'Button Widget';
|
||||
public $render = 'Button';
|
||||
public $width = 3;
|
||||
public $height = 2;
|
||||
public $cacheLifetime = false;
|
||||
public $autoRefreshDelay = false;
|
||||
public $params = array(
|
||||
'url' => 'URL (after base url) to redirect to',
|
||||
'text' => 'Text to display on the button'
|
||||
);
|
||||
public $description = 'Simple button to allow shortcuts';
|
||||
public $placeholder =
|
||||
'{
|
||||
"url": "/events/index",
|
||||
"text": "Go to events"
|
||||
}';
|
||||
|
||||
public function handler($user, $options = array())
|
||||
{
|
||||
$data = array();
|
||||
if(isset($options['url'])) {
|
||||
$data['url'] = $options['url'];
|
||||
}
|
||||
if(isset($options['text'])) {
|
||||
$data['text'] = $options['text'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -16,14 +16,15 @@ class MispAdminResourceWidget
|
|||
{
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$data = array();
|
||||
$redis = $this->Server->setupRedis();
|
||||
if ($redis) {
|
||||
$memory_stats = round($redis->rawCommand('memory', 'stats')[3] / 1024 / 1024) . 'M';
|
||||
|
||||
$redisInfo = $this->Server->redisInfo();
|
||||
if ($redisInfo['connection']) {
|
||||
$memory_stats = round($redisInfo['used_memory'] / 1024 / 1024) . 'M';
|
||||
$data[] = array(
|
||||
'title' => __('Current Redis memory usage'),
|
||||
'value' => h($memory_stats)
|
||||
);
|
||||
$memory_stats = round($redis->rawCommand('memory', 'stats')[1] / 1024 / 1024) . 'M';
|
||||
$memory_stats = round($redisInfo['used_memory_peak'] / 1024 / 1024) . 'M';
|
||||
$data[] = array(
|
||||
'title' => __('Peak Redis memory usage'),
|
||||
'value' => h($memory_stats)
|
||||
|
|
|
@ -15,7 +15,7 @@ class MispAdminSyncTestWidget
|
|||
{
|
||||
$this->Server = ClassRegistry::init('Server');
|
||||
$servers = $this->Server->find('all', array(
|
||||
'fields' => array('id', 'url', 'name', 'pull', 'push', 'caching_enabled'),
|
||||
'fields' => array('id', 'url', 'name', 'pull', 'push', 'caching_enabled', 'authkey', 'cert_file', 'client_cert_file', 'self_signed'),
|
||||
'conditions' => array('OR' => array('pull' => 1, 'push' => 1, 'caching_enabled' => 1)),
|
||||
'recursive' => -1
|
||||
));
|
||||
|
@ -25,16 +25,15 @@ class MispAdminSyncTestWidget
|
|||
}
|
||||
$syncTestErrorCodes = $this->Server->syncTestErrorCodes;
|
||||
foreach ($servers as $server) {
|
||||
$result = $this->Server->runConnectionTest($server['Server']['id']);
|
||||
$result = $this->Server->runConnectionTest($server);
|
||||
if ($result['status'] === 1) {
|
||||
$message = __('Connected.');
|
||||
$colour = 'green';
|
||||
$flags = json_decode($result['message'], true);
|
||||
if (empty($flags['perm_sync'])) {
|
||||
if (empty($result['info']['perm_sync'])) {
|
||||
$colour = 'orange';
|
||||
$message .= ' ' . __('No sync access.');
|
||||
}
|
||||
if (empty($flags['perm_sighting'])) {
|
||||
if (empty($result['info']['perm_sighting'])) {
|
||||
$colour = 'orange';
|
||||
$message .= ' ' . __('No sighting access.');
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ class AttachmentTool
|
|||
return $this->_exists(true, $eventId, $attributeId, $path_suffix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $shadow
|
||||
* @param int $eventId
|
||||
|
@ -297,6 +296,9 @@ class AttachmentTool
|
|||
}
|
||||
|
||||
/**
|
||||
* It is not possible to use PHP extensions for compressing. The reason is, that extensions support just AES encrypted
|
||||
* files, but these files are not supported in Windows and in Python. So the only solution is to use 'zip' command.
|
||||
*
|
||||
* @param string $originalFilename
|
||||
* @param string $content
|
||||
* @param string $md5
|
||||
|
@ -304,23 +306,6 @@ class AttachmentTool
|
|||
* @throws Exception
|
||||
*/
|
||||
public function encrypt($originalFilename, $content, $md5)
|
||||
{
|
||||
if (method_exists("ZipArchive", "setEncryptionName")) {
|
||||
// When PHP zip extension is installed and supports creating encrypted archives.
|
||||
return $this->encryptByExtension($originalFilename, $content, $md5);
|
||||
} else {
|
||||
return $this->encryptByCommand($originalFilename, $content, $md5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $originalFilename
|
||||
* @param string $content
|
||||
* @param string $md5
|
||||
* @return string Content of zipped file
|
||||
* @throws Exception
|
||||
*/
|
||||
private function encryptByCommand($originalFilename, $content, $md5)
|
||||
{
|
||||
$tempDir = $this->tempDir();
|
||||
|
||||
|
@ -367,43 +352,6 @@ class AttachmentTool
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $originalFilename
|
||||
* @param string $content
|
||||
* @param string $md5
|
||||
* @return string Content of zipped file
|
||||
* @throws Exception
|
||||
*/
|
||||
private function encryptByExtension($originalFilename, $content, $md5)
|
||||
{
|
||||
$zipFilePath = $this->tempFileName();
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$result = $zip->open($zipFilePath, ZipArchive::CREATE);
|
||||
if ($result === true) {
|
||||
$zip->setPassword(self::ZIP_PASSWORD);
|
||||
|
||||
$zip->addFromString($md5, $content);
|
||||
$zip->setEncryptionName($md5, ZipArchive::EM_AES_128);
|
||||
|
||||
$zip->addFromString("$md5.filename.txt", $originalFilename);
|
||||
$zip->setEncryptionName("$md5.filename.txt", ZipArchive::EM_AES_128);
|
||||
|
||||
$zip->close();
|
||||
} else {
|
||||
throw new Exception("Could not create encrypted ZIP file '$zipFilePath'. Error code: $result");
|
||||
}
|
||||
|
||||
$zipFile = new File($zipFilePath);
|
||||
$zipContent = $zipFile->read();
|
||||
if ($zipContent === false) {
|
||||
throw new Exception("Could not read content of newly created ZIP file.");
|
||||
}
|
||||
$zipFile->delete();
|
||||
|
||||
return $zipContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @param array $hashTypes
|
||||
|
@ -475,7 +423,7 @@ class AttachmentTool
|
|||
* Naive way to detect if we're working in S3
|
||||
* @return bool
|
||||
*/
|
||||
private function attachmentDirIsS3()
|
||||
public function attachmentDirIsS3()
|
||||
{
|
||||
return substr(Configure::read('MISP.attachments_dir'), 0, 2) === "s3";
|
||||
}
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
<?php
|
||||
class CryptGpgExtended extends Crypt_GPG
|
||||
{
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
if (!method_exists($this, '_prepareInput')) {
|
||||
$reflector = new \ReflectionClass('Crypt_GPG');
|
||||
$classPath = $reflector->getFileName();
|
||||
throw new Exception("Crypt_GPG class from '$classPath' is too old, at least version 1.6.1 is required.");
|
||||
}
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the smallest public key possible from the keyring.
|
||||
*
|
||||
|
|
|
@ -60,4 +60,115 @@ class SyncTool
|
|||
}
|
||||
return $HttpSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $server
|
||||
* @return array|void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getServerClientCertificateInfo(array $server)
|
||||
{
|
||||
if (!$server['Server']['client_cert_file']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clientCertificate = new File(APP . "files" . DS . "certs" . DS . $server['Server']['id'] . '_client.pem');
|
||||
if (!$clientCertificate->exists()) {
|
||||
throw new Exception("Certificate file '{$clientCertificate->pwd()}' doesn't exists.");
|
||||
}
|
||||
|
||||
$certificateContent = $clientCertificate->read();
|
||||
if ($certificateContent === false) {
|
||||
throw new Exception("Could not read '{$clientCertificate->pwd()}' file with client certificate.");
|
||||
}
|
||||
|
||||
return self::getClientCertificateInfo($certificateContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certificateContent PEM encoded certificate and private key.
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function getClientCertificateInfo($certificateContent)
|
||||
{
|
||||
$certificate = openssl_x509_read($certificateContent);
|
||||
if (!$certificate) {
|
||||
throw new Exception("Could't parse certificate: " . openssl_error_string());
|
||||
}
|
||||
$privateKey = openssl_pkey_get_private($certificateContent);
|
||||
if (!$privateKey) {
|
||||
throw new Exception("Could't get private key from certificate: " . openssl_error_string());
|
||||
}
|
||||
$verify = openssl_x509_check_private_key($certificate, $privateKey);
|
||||
if (!$verify) {
|
||||
throw new Exception('Public and private key do not match.');
|
||||
}
|
||||
return self::parseCertificate($certificate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $certificate
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function parseCertificate($certificate)
|
||||
{
|
||||
$parsed = openssl_x509_parse($certificate);
|
||||
if (!$parsed) {
|
||||
throw new Exception("Could't get parse X.509 certificate: " . openssl_error_string());
|
||||
}
|
||||
$currentTime = new DateTime();
|
||||
$output = [
|
||||
'serial_number' => $parsed['serialNumberHex'],
|
||||
'signature_type' => $parsed['signatureTypeSN'],
|
||||
'valid_from' => isset($parsed['validFrom_time_t']) ? new DateTime("@{$parsed['validFrom_time_t']}") : null,
|
||||
'valid_to' => isset($parsed['validTo_time_t']) ? new DateTime("@{$parsed['validTo_time_t']}") : null,
|
||||
'public_key_size' => null,
|
||||
'public_key_type' => null,
|
||||
'public_key_size_ok' => null,
|
||||
];
|
||||
|
||||
$output['valid_from_ok'] = $output['valid_from'] ? ($output['valid_from'] <= $currentTime) : null;
|
||||
$output['valid_to_ok'] = $output['valid_to'] ? ($output['valid_to'] >= $currentTime) : null;
|
||||
|
||||
$subject = [];
|
||||
foreach ($parsed['subject'] as $type => $value) {
|
||||
$subject[] = "$type=$value";
|
||||
}
|
||||
$output['subject'] = implode(', ', $subject);
|
||||
|
||||
$issuer = [];
|
||||
foreach ($parsed['issuer'] as $type => $value) {
|
||||
$issuer[] = "$type=$value";
|
||||
}
|
||||
$output['issuer'] = implode(', ', $issuer);
|
||||
|
||||
$publicKey = openssl_pkey_get_public($certificate);
|
||||
if ($publicKey) {
|
||||
$publicKeyDetails = openssl_pkey_get_details($publicKey);
|
||||
if ($publicKeyDetails) {
|
||||
$output['public_key_size'] = $publicKeyDetails['bits'];
|
||||
switch ($publicKeyDetails['type']) {
|
||||
case OPENSSL_KEYTYPE_RSA:
|
||||
$output['public_key_type'] = 'RSA';
|
||||
$output['public_key_size_ok'] = $output['public_key_size'] >= 2048;
|
||||
break;
|
||||
case OPENSSL_KEYTYPE_DSA:
|
||||
$output['public_key_type'] = 'DSA';
|
||||
$output['public_key_size_ok'] = $output['public_key_size'] >= 2048;
|
||||
break;
|
||||
case OPENSSL_KEYTYPE_DH:
|
||||
$output['public_key_type'] = 'DH';
|
||||
break;
|
||||
case OPENSSL_KEYTYPE_EC:
|
||||
$output['public_key_type'] = "EC ({$publicKeyDetails['ec']['curve_name']})";
|
||||
$output['public_key_size_ok'] = $output['public_key_size'] >= 224;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class AppModel extends Model
|
|||
39 => false, 40 => false, 41 => false, 42 => false, 43 => false, 44 => false,
|
||||
45 => false, 46 => false, 47 => false, 48 => false, 49 => false, 50 => false,
|
||||
51 => false, 52 => false, 53 => false, 54 => false, 55 => false, 56 => false,
|
||||
57 => false, 58 => false, 59 => false
|
||||
57 => false, 58 => false, 59 => false, 60 => false,
|
||||
);
|
||||
|
||||
public $advanced_updates_description = array(
|
||||
|
@ -1436,6 +1436,18 @@ class AppModel extends Model
|
|||
INDEX `name` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||||
break;
|
||||
case 60:
|
||||
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `attachment_scans` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`type` varchar(40) COLLATE utf8_bin NOT NULL,
|
||||
`attribute_id` int(11) NOT NULL,
|
||||
`infected` tinyint(1) NOT NULL,
|
||||
`malware_name` varchar(191) NULL,
|
||||
`timestamp` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `index` (`type`, `attribute_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||||
break;
|
||||
case 'fixNonEmptySharingGroupID':
|
||||
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
|
@ -2425,6 +2437,19 @@ class AppModel extends Model
|
|||
$this->elasticSearchClient = $client;
|
||||
}
|
||||
|
||||
public function checkVersionRequirements($versionString, $minVersion)
|
||||
{
|
||||
$version = explode('.', $versionString);
|
||||
$minVersion = explode('.', $minVersion);
|
||||
if (count($version) > $minVersion) {
|
||||
return true;
|
||||
}
|
||||
if (count($version) == 1) {
|
||||
return $minVersion <= $version;
|
||||
}
|
||||
return ($version[0] >= $minVersion[0] && $version[1] >= $minVersion[1] && $version[2] >= $minVersion[2]);
|
||||
}
|
||||
|
||||
// generate a generic subquery - options needs to include conditions
|
||||
public function subQueryGenerator($model, $options, $lookupKey, $negation = false)
|
||||
{
|
||||
|
@ -2966,4 +2991,27 @@ class AppModel extends Model
|
|||
|
||||
return $this->attachmentTool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AttachmentScan
|
||||
*/
|
||||
protected function loadAttachmentScan()
|
||||
{
|
||||
if ($this->AttachmentScan === null) {
|
||||
$this->AttachmentScan = ClassRegistry::init('AttachmentScan');
|
||||
}
|
||||
|
||||
return $this->AttachmentScan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Log
|
||||
*/
|
||||
protected function loadLog()
|
||||
{
|
||||
if (!isset($this->Log)) {
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
}
|
||||
return $this->Log;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,528 @@
|
|||
<?php
|
||||
App::uses('AppModel', 'Model');
|
||||
|
||||
class AttachmentScan extends AppModel
|
||||
{
|
||||
const TYPE_ATTRIBUTE = 'Attribute',
|
||||
TYPE_SHADOW_ATTRIBUTE = 'ShadowAttribute';
|
||||
|
||||
// base64 encoded eicar.exe
|
||||
const EICAR = 'WDVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCo=';
|
||||
|
||||
/** @var AttachmentTool */
|
||||
private $attachmentTool;
|
||||
|
||||
/** @var Module */
|
||||
private $moduleModel;
|
||||
|
||||
/** @var mixed|null */
|
||||
private $attachmentScanModuleName;
|
||||
|
||||
/**
|
||||
* List of supported object templates
|
||||
* @var string[]
|
||||
*/
|
||||
private $signatureTemplates = [
|
||||
'4dbb56ef-4763-4c97-8696-a2bfc305cf8e', // av-signature
|
||||
'984c5c39-be7f-4e1e-b034-d3213bac51cb', // sb-signature
|
||||
];
|
||||
|
||||
/**
|
||||
* List of supported ways how to send data to module. From the most reliable to worst.
|
||||
* @var string[]
|
||||
*/
|
||||
private $possibleTypes = [
|
||||
'attachment',
|
||||
'sha3-512',
|
||||
'sha3-384',
|
||||
'sha3-256',
|
||||
'sha3-224',
|
||||
'sha512',
|
||||
'sha512/224',
|
||||
'sha512/256',
|
||||
'sha384',
|
||||
'sha256',
|
||||
'sha224',
|
||||
'sha1',
|
||||
'md5',
|
||||
];
|
||||
|
||||
public function __construct($id = false, $table = null, $ds = null)
|
||||
{
|
||||
parent::__construct($id, $table, $ds);
|
||||
$this->attachmentScanModuleName = Configure::read('MISP.attachment_scan_module');
|
||||
|
||||
// This can be useful, if you use third party service (like VirusTotal) and you don't want leak uploaded
|
||||
// files payload. Then just file hash will be send.
|
||||
if (Configure::read('MISP.attachment_scan_hash_only')) {
|
||||
array_shift($this->possibleTypes); // remove 'attachment' type
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks configuration and connection to module wth AV engine and returns an array of scanning software.
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function diagnostic()
|
||||
{
|
||||
if (!$this->isEnabled()) {
|
||||
throw new Exception("Malware scanning module is not configured.");
|
||||
}
|
||||
|
||||
if ($this->attachmentTool()->attachmentDirIsS3()) {
|
||||
throw new Exception("S3 attachment storage is not supported now for malware scanning.");
|
||||
}
|
||||
|
||||
$moduleInfo = $this->loadModuleInfo($this->attachmentScanModuleName);
|
||||
|
||||
if (in_array('attachment', $moduleInfo['types'])) {
|
||||
$fakeAttribute = [
|
||||
'uuid' => CakeText::uuid(),
|
||||
'event_id' => 1,
|
||||
'type' => 'attachment',
|
||||
'value' => 'eicar.com',
|
||||
'data' => self::EICAR,
|
||||
];
|
||||
} else {
|
||||
$hashAlgo = $moduleInfo['types'][0];
|
||||
$hash = hash($hashAlgo, base64_decode(self::EICAR));
|
||||
$fakeAttribute = [
|
||||
'uuid' => CakeText::uuid(),
|
||||
'event_id' => 1,
|
||||
'type' => $hashAlgo,
|
||||
'value' => $hash,
|
||||
];
|
||||
}
|
||||
$results = $this->sendToModule($fakeAttribute, $moduleInfo['config']);
|
||||
if (empty($results)) {
|
||||
throw new Exception("Eicar test file was not detected.");
|
||||
}
|
||||
|
||||
return array_column($results, 'software');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
return !empty($this->attachmentScanModuleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $attributeId Attribute or Shadow Attribute ID
|
||||
* @param bool $infected
|
||||
* @param string|null $malwareName
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function insertScan($type, $attributeId, $infected, $malwareName = null)
|
||||
{
|
||||
$this->checkType($type);
|
||||
$this->create();
|
||||
$result = $this->save(array(
|
||||
'type' => $type,
|
||||
'attribute_id' => $attributeId,
|
||||
'infected' => $infected,
|
||||
'malware_name' => $malwareName,
|
||||
'timestamp' => time(),
|
||||
));
|
||||
if (!$result) {
|
||||
throw new Exception("Could not save scan result for attribute $attributeId: " . json_encode($this->validationErrors));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $attributeId Attribute or Shadow Attribute ID
|
||||
* @return array|null
|
||||
*/
|
||||
public function getLatestScan($type, $attributeId)
|
||||
{
|
||||
$this->checkType($type);
|
||||
return $this->find('first', array(
|
||||
'conditions' => array(
|
||||
'type' => $type,
|
||||
'attribute_id' => $attributeId,
|
||||
),
|
||||
'fields' => ['infected', 'malware_name'],
|
||||
'order' => 'timestamp DESC', // newest first
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if file is infected according to latest scan. Return values:
|
||||
* - null - file was never checked
|
||||
* - false - file is not infected according to latest scan
|
||||
* - string - file is infected, string contains malware name
|
||||
*
|
||||
* @param string $type
|
||||
* @param int $attributeId Attribute or Shadow Attribute ID
|
||||
* @return bool|null|string
|
||||
*/
|
||||
public function isInfected($type, $attributeId)
|
||||
{
|
||||
$latest = $this->getLatestScan($type, $attributeId);
|
||||
if (empty($latest)) {
|
||||
return null;
|
||||
}
|
||||
if ($latest['AttachmentScan']['infected']) {
|
||||
return $latest['AttachmentScan']['malware_name'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $attributeId Attribute or ShadowAttribute ID
|
||||
* @param int|null $jobId
|
||||
* @return bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function scan($type, $attributeId = null, $jobId = null)
|
||||
{
|
||||
/** @var Job $job */
|
||||
$job = ClassRegistry::init('Job');
|
||||
if ($jobId && !$job->exists($jobId)) {
|
||||
$jobId = null;
|
||||
}
|
||||
|
||||
if (!$this->isEnabled()) {
|
||||
throw new Exception("Malware scanning module is not configured.");
|
||||
}
|
||||
|
||||
if ($this->attachmentTool()->attachmentDirIsS3()) {
|
||||
throw new Exception("S3 attachment storage is not supported now for malware scanning.");
|
||||
}
|
||||
|
||||
$fields = ['id', 'uuid', 'type', 'value', 'event_id'];
|
||||
if ($type === 'all') {
|
||||
$attributes = ClassRegistry::init('Attribute')->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => ['type' => 'attachment'],
|
||||
'fields' => $fields,
|
||||
));
|
||||
$shadowAttributes = ClassRegistry::init('ShadowAttribute')->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => ['type' => 'attachment'],
|
||||
'fields' => $fields,
|
||||
));
|
||||
$attributes = array_merge($attributes, $shadowAttributes);
|
||||
} else if ($type === self::TYPE_ATTRIBUTE) {
|
||||
$attributes = ClassRegistry::init('Attribute')->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => ['type' => 'attachment', 'id' => $attributeId],
|
||||
'fields' => $fields,
|
||||
));
|
||||
} else if ($type === self::TYPE_SHADOW_ATTRIBUTE) {
|
||||
$attributes = ClassRegistry::init('ShadowAttribute')->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => ['type' => 'attachment', 'id' => $attributeId],
|
||||
'fields' => $fields,
|
||||
));
|
||||
} else {
|
||||
throw new InvalidArgumentException("Input must be 'all', 'Attribute' or 'ShadowAttribute', '$type' provided.");
|
||||
}
|
||||
|
||||
if (empty($attributes) && $type !== 'all') {
|
||||
$message = "$type not found";
|
||||
$job->saveStatus($jobId, false, $message);
|
||||
return $message;
|
||||
}
|
||||
|
||||
try {
|
||||
$moduleInfo = $this->loadModuleInfo($this->attachmentScanModuleName);
|
||||
} catch (Exception $e) {
|
||||
$job->saveStatus($jobId, false, 'Could not connect to attachment scan module.');
|
||||
$this->logException('Could not connect to attachment scan module.', $e);
|
||||
return false;
|
||||
}
|
||||
|
||||
$scanned = 0;
|
||||
$fails = 0;
|
||||
$virusFound = 0;
|
||||
foreach ($attributes as $attribute) {
|
||||
$type = isset($attribute['Attribute']) ? self::TYPE_ATTRIBUTE : self::TYPE_SHADOW_ATTRIBUTE;
|
||||
try {
|
||||
$infected = $this->scanAttachment($type, $attribute[$type], $moduleInfo);
|
||||
if ($infected === true) {
|
||||
$virusFound++;
|
||||
}
|
||||
$scanned++;
|
||||
} catch (NotFoundException $e) {
|
||||
// skip
|
||||
} catch (Exception $e) {
|
||||
$this->logException("Could not scan attachment for $type {$attribute['Attribute']['id']}", $e);
|
||||
$fails++;
|
||||
}
|
||||
|
||||
$message = "$scanned files scanned, $virusFound malware files found.";
|
||||
$job->saveProgress($jobId, $message, ($scanned + $fails) / count($attributes) * 100);
|
||||
}
|
||||
|
||||
if ($scanned === 0 && $fails > 0) {
|
||||
$job->saveStatus($jobId, false);
|
||||
return false;
|
||||
} else {
|
||||
$message = "$scanned files scanned, $virusFound malware files found.";
|
||||
if ($fails) {
|
||||
$message .= " $fails files failed to scan (see error log for more details).";
|
||||
}
|
||||
|
||||
$job->saveStatus($jobId, true, "Job done, $message");
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $attribute Attribute or Shadow Attribute
|
||||
* @throws Exception
|
||||
*/
|
||||
public function backgroundScan($type, array $attribute)
|
||||
{
|
||||
$this->checkType($type);
|
||||
|
||||
$canScan = $attribute['type'] === 'attachment' &&
|
||||
$this->isEnabled() &&
|
||||
Configure::read('MISP.background_jobs') &&
|
||||
!$this->attachmentTool()->attachmentDirIsS3();
|
||||
|
||||
if ($canScan) {
|
||||
$job = ClassRegistry::init('Job');
|
||||
$job->create();
|
||||
$job->save(array(
|
||||
'worker' => 'default',
|
||||
'job_type' => 'virus_scan',
|
||||
'job_input' => ($type === self::TYPE_ATTRIBUTE ? 'Attribute: ' : 'Shadow attribute: ') . $attribute['id'],
|
||||
'status' => 0,
|
||||
'retries' => 0,
|
||||
'org' => 'SYSTEM',
|
||||
'message' => 'Scanning...',
|
||||
));
|
||||
|
||||
$processId = CakeResque::enqueue(
|
||||
'default',
|
||||
'AdminShell',
|
||||
array('scanAttachment', $type, $attribute['id'], $job->id),
|
||||
true
|
||||
);
|
||||
$job->saveField('process_id', $processId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $attribute
|
||||
* @param array $moduleInfo
|
||||
* @return bool|null Return true if attachment is infected.
|
||||
* @throws Exception
|
||||
*/
|
||||
private function scanAttachment($type, array $attribute, array $moduleInfo)
|
||||
{
|
||||
if (!isset($attribute['type'])) {
|
||||
throw new InvalidArgumentException("Invalid attribute provided.");
|
||||
}
|
||||
|
||||
if ($attribute['type'] !== 'attachment') {
|
||||
throw new InvalidArgumentException("Just attachment attributes can be scanned, attribute with type '{$attribute['type']}' provided.");
|
||||
}
|
||||
|
||||
if ($type === self::TYPE_ATTRIBUTE) {
|
||||
$file = $this->attachmentTool()->getFile($attribute['event_id'], $attribute['id']);
|
||||
} else {
|
||||
$file = $this->attachmentTool()->getShadowFile($attribute['event_id'], $attribute['id']);
|
||||
}
|
||||
|
||||
if (in_array('attachment', $moduleInfo['types'])) {
|
||||
/* if ($file->size() > 50 * 1024 * 1024) {
|
||||
$this->log("File '$file->path' is bigger than 50 MB, will be not scanned.", LOG_NOTICE);
|
||||
return false;
|
||||
}*/
|
||||
|
||||
$fileContent = $file->read();
|
||||
if ($fileContent === false) {
|
||||
throw new Exception("Could not read content of file '$file->path'.");
|
||||
}
|
||||
$attribute['data'] = base64_encode($fileContent);
|
||||
} else {
|
||||
// Instead of sending whole file to module, just generate file hash and send that hash as fake attribute.
|
||||
$hashAlgo = $moduleInfo['types'][0];
|
||||
$hash = hash_file($hashAlgo, $file->pwd());
|
||||
if (!$hash) {
|
||||
throw new Exception("Could not generate $hashAlgo hash for file '$file->path'.");
|
||||
}
|
||||
|
||||
$attribute = [
|
||||
'uuid' => CakeText::uuid(),
|
||||
'event_id' => $attribute['event_id'],
|
||||
'type' => $hashAlgo,
|
||||
'value' => $hash,
|
||||
];
|
||||
}
|
||||
|
||||
$results = $this->sendToModule($attribute, $moduleInfo['config']);
|
||||
|
||||
if (!empty($results)) {
|
||||
$signatures = [];
|
||||
foreach ($results as $result) {
|
||||
$signatures = array_merge($signatures, $result['signatures']);
|
||||
}
|
||||
$this->insertScan($type, $attribute['id'], true, implode(', ', $signatures));
|
||||
return true;
|
||||
|
||||
} else {
|
||||
$this->insertScan($type, $attribute['id'], false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attribute
|
||||
* @param array $moduleConfig
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function sendToModule(array $attribute, array $moduleConfig)
|
||||
{
|
||||
// How long we will wait for scan result
|
||||
$timeout = Configure::read('MISP.attachment_scan_timeout') ?: 30;
|
||||
$data = [
|
||||
'module' => $this->attachmentScanModuleName,
|
||||
'attribute' => $attribute,
|
||||
'event_id' => $attribute['event_id'],
|
||||
'config' => $moduleConfig,
|
||||
'timeout' => $timeout, // module internal timeout
|
||||
];
|
||||
|
||||
$results = $this->moduleModel()->sendRequest('/query', $timeout + 1, $data, 'Enrichment');
|
||||
if (isset($results['error'])) {
|
||||
throw new Exception("{$this->attachmentScanModuleName} module returns error: " . $results['error']);
|
||||
}
|
||||
if (!isset($results['results'])) {
|
||||
throw new Exception("Invalid data received from {$this->attachmentScanModuleName} module.");
|
||||
}
|
||||
return $this->extractInfoFromModuleResult($results['results']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts data from scan results.
|
||||
* @param array $results
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function extractInfoFromModuleResult(array $results)
|
||||
{
|
||||
if (!isset($results['Object']) || !is_array($results['Object'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$output = [];
|
||||
foreach ($results['Object'] as $object) {
|
||||
if (!isset($object['template_uuid'])) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($object['template_uuid'], $this->signatureTemplates)) {
|
||||
$software = null;
|
||||
$signatures = array();
|
||||
foreach ($object['Attribute'] as $attribute) {
|
||||
if (!isset($attribute['object_relation']) || !isset($attribute['value'])) {
|
||||
continue;
|
||||
}
|
||||
if ($attribute['object_relation'] === 'signature') {
|
||||
$signatures[] = $attribute['value'];
|
||||
} else if ($attribute['object_relation'] === 'software') {
|
||||
$software = $attribute['value'];
|
||||
}
|
||||
}
|
||||
if (!empty($signatures) && $software) {
|
||||
$output[] = ['signatures' => $signatures, 'software' => $software];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $moduleName
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function loadModuleInfo($moduleName)
|
||||
{
|
||||
$modules = $this->moduleModel()->getModules('Enrichment', true);
|
||||
|
||||
$module = null;
|
||||
foreach ($modules as $temp) {
|
||||
if (strtolower($temp['name']) === strtolower($moduleName)) {
|
||||
$module = $temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$module) {
|
||||
throw new Exception("Module $moduleName not found.");
|
||||
}
|
||||
|
||||
if (!in_array('expansion', $module['meta']['module-type'])) {
|
||||
throw new Exception("Module $moduleName must be expansion type.");
|
||||
}
|
||||
|
||||
$types = array_intersect($this->possibleTypes, $module['mispattributes']['input']);
|
||||
if (empty($types)) {
|
||||
throw new Exception("Module $moduleName doesn't support at least one required type: " . implode(", ", $this->possibleTypes) . ".");
|
||||
}
|
||||
|
||||
if (!isset($module['mispattributes']['format']) || $module['mispattributes']['format'] !== 'misp_standard') {
|
||||
throw new Exception("Module $moduleName doesn't support misp_standard output format.");
|
||||
}
|
||||
|
||||
$config = [];
|
||||
if (isset($module['meta']['config'])) {
|
||||
foreach ($module['meta']['config'] as $conf) {
|
||||
$config[$conf] = Configure::read("Plugin.Enrichment_{$moduleName}_$conf");
|
||||
}
|
||||
}
|
||||
return ['config' => $config, 'types' => $types];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AttachmentTool
|
||||
*/
|
||||
private function attachmentTool()
|
||||
{
|
||||
if (!$this->attachmentTool) {
|
||||
$this->attachmentTool = new AttachmentTool();
|
||||
}
|
||||
|
||||
return $this->attachmentTool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Module
|
||||
*/
|
||||
private function moduleModel()
|
||||
{
|
||||
if (!$this->moduleModel) {
|
||||
$this->moduleModel = ClassRegistry::init('Module');
|
||||
}
|
||||
|
||||
return $this->moduleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @raise InvalidArgumentException
|
||||
*/
|
||||
private function checkType($type)
|
||||
{
|
||||
if (!in_array($type, [self::TYPE_ATTRIBUTE, self::TYPE_SHADOW_ATTRIBUTE])) {
|
||||
throw new InvalidArgumentException("Type must be 'Attribute' or 'ShadowAttribute', '$type' provided.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1194,7 +1194,7 @@ class Attribute extends AppModel
|
|||
}
|
||||
break;
|
||||
case 'filename|vhash':
|
||||
if (preg_match('#^.+\|[a-zA-Z0-9&!="]+$#', $value)) {
|
||||
if (preg_match('#^.+\|[a-zA-Z0-9&!=\"]+$#', $value)) {
|
||||
$returnValue = true;
|
||||
} else {
|
||||
$returnValue = __('Checksum has an invalid length or format (expected: filename|string characters). Please double check the value or select type "other".');
|
||||
|
@ -1820,7 +1820,11 @@ class Attribute extends AppModel
|
|||
|
||||
public function saveAttachment($attribute, $path_suffix='')
|
||||
{
|
||||
return $this->loadAttachmentTool()->save($attribute['event_id'], $attribute['id'], $attribute['data'], $path_suffix);
|
||||
$result = $this->loadAttachmentTool()->save($attribute['event_id'], $attribute['id'], $attribute['data'], $path_suffix);
|
||||
if ($result) {
|
||||
$this->loadAttachmentScan()->backgroundScan(AttachmentScan::TYPE_ATTRIBUTE, $attribute);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3703,7 +3707,7 @@ class Attribute extends AppModel
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param array $attribute
|
||||
* @param bool $context
|
||||
* @return array|true
|
||||
*/
|
||||
|
@ -3713,6 +3717,7 @@ class Attribute extends AppModel
|
|||
if (!$context) {
|
||||
unset($this->validate['event_id']);
|
||||
unset($this->validate['value']['uniqueValue']);
|
||||
unset($this->validate['uuid']['unique']);
|
||||
}
|
||||
if ($this->validates()) {
|
||||
return true;
|
||||
|
|
|
@ -5371,6 +5371,10 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
if ($object['type'] === 'attachment' && $this->loadAttachmentScan()->isEnabled()) {
|
||||
$type = $object['objectType'] === 'attribute' ? AttachmentScan::TYPE_ATTRIBUTE : AttachmentScan::TYPE_SHADOW_ATTRIBUTE;
|
||||
$object['infected'] = $this->loadAttachmentScan()->isInfected($type, $object['id']);;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
|
@ -5751,7 +5755,7 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
$modulePayload['data'] = $events;
|
||||
$result = $this->Module->queryModuleServer('/query', json_encode($modulePayload, true), false, 'Export');
|
||||
$result = $this->Module->queryModuleServer($modulePayload, false, 'Export');
|
||||
return array(
|
||||
'data' => $result['data'],
|
||||
'extension' => $module['mispattributes']['outputFileExtension'],
|
||||
|
@ -6135,8 +6139,7 @@ class Event extends AppModel
|
|||
} else {
|
||||
$data[$attribute['type']] = $attribute['value'];
|
||||
}
|
||||
$data = json_encode($data);
|
||||
$result = $this->Module->queryModuleServer('/query', $data, false, 'Enrichment');
|
||||
$result = $this->Module->queryModuleServer($data, false, 'Enrichment');
|
||||
if (!$result) {
|
||||
throw new MethodNotAllowedException(h($module['name']) . ' service not reachable.');
|
||||
}
|
||||
|
|
|
@ -82,28 +82,32 @@ class Module extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function getModules($type = false, $moduleFamily = 'Enrichment', &$exception = false)
|
||||
/**
|
||||
* @param string $moduleFamily
|
||||
* @param bool $throwException
|
||||
* @return array[]|string
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function getModules($moduleFamily = 'Enrichment', $throwException = false)
|
||||
{
|
||||
$modules = $this->queryModuleServer('/modules', false, false, $moduleFamily, $exception);
|
||||
if (!$modules) {
|
||||
return 'Module service not reachable.';
|
||||
try {
|
||||
// Wait just one second to not block loading pages when modules are not reachable
|
||||
return $this->sendRequest('/modules', 1, null, $moduleFamily);
|
||||
} catch (Exception $e) {
|
||||
if ($throwException) {
|
||||
throw $e;
|
||||
}
|
||||
if (!empty($modules)) {
|
||||
$result = array('modules' => $modules);
|
||||
return $result;
|
||||
} else {
|
||||
return 'The module service reports that it found no modules.';
|
||||
return 'Module service not reachable.';
|
||||
}
|
||||
}
|
||||
|
||||
public function getEnabledModules($user, $type = false, $moduleFamily = 'Enrichment')
|
||||
{
|
||||
$modules = $this->getModules($type, $moduleFamily);
|
||||
$modules = $this->getModules($moduleFamily);
|
||||
if (is_array($modules)) {
|
||||
foreach ($modules['modules'] as $k => $module) {
|
||||
foreach ($modules as $k => $module) {
|
||||
if (!Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_enabled') || ($type && !in_array(strtolower($type), $module['meta']['module-type']))) {
|
||||
unset($modules['modules'][$k]);
|
||||
unset($modules[$k]);
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
|
@ -111,38 +115,33 @@ class Module extends AppModel
|
|||
Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_restrict') &&
|
||||
Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_restrict') != $user['org_id']
|
||||
) {
|
||||
unset($modules['modules'][$k]);
|
||||
unset($modules[$k]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 'The modules system reports that it found no suitable modules.';
|
||||
}
|
||||
if (!isset($modules) || empty($modules)) {
|
||||
$modules = array();
|
||||
if (empty($modules)) {
|
||||
return [];
|
||||
}
|
||||
if (isset($modules['modules']) && !empty($modules['modules'])) {
|
||||
$modules['modules'] = array_values($modules['modules']);
|
||||
}
|
||||
if (!is_array($modules)) {
|
||||
return array();
|
||||
}
|
||||
foreach ($modules['modules'] as $temp) {
|
||||
$output = ['modules' => array_values($modules)];
|
||||
foreach ($modules as $temp) {
|
||||
if (isset($temp['meta']['module-type']) && in_array('import', $temp['meta']['module-type'])) {
|
||||
$modules['Import'] = $temp['name'];
|
||||
$output['Import'] = $temp['name'];
|
||||
} elseif (isset($temp['meta']['module-type']) && in_array('export', $temp['meta']['module-type'])) {
|
||||
$modules['Export'] = $temp['name'];
|
||||
$output['Export'] = $temp['name'];
|
||||
} else {
|
||||
foreach ($temp['mispattributes']['input'] as $input) {
|
||||
if (!isset($temp['meta']['module-type']) || (in_array('expansion', $temp['meta']['module-type']) || in_array('cortex', $temp['meta']['module-type']))) {
|
||||
$modules['types'][$input][] = $temp['name'];
|
||||
$output['types'][$input][] = $temp['name'];
|
||||
}
|
||||
if (isset($temp['meta']['module-type']) && in_array('hover', $temp['meta']['module-type'])) {
|
||||
$modules['hover_type'][$input][] = $temp['name'];
|
||||
$output['hover_type'][$input][] = $temp['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $modules;
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -156,7 +155,7 @@ class Module extends AppModel
|
|||
throw new InvalidArgumentException("Invalid type '$type'.");
|
||||
}
|
||||
$moduleFamily = $this->__typeToFamily[$type];
|
||||
$modules = $this->getModules($type, $moduleFamily);
|
||||
$modules = $this->getModules($moduleFamily);
|
||||
if (!Configure::read('Plugin.' . $moduleFamily . '_' . $name . '_enabled')) {
|
||||
return 'The requested module is not enabled.';
|
||||
}
|
||||
|
@ -199,33 +198,58 @@ class Module extends AppModel
|
|||
return "$url:$port";
|
||||
}
|
||||
|
||||
public function queryModuleServer($uri, $post = false, $hover = false, $moduleFamily = 'Enrichment', &$exception = false)
|
||||
/**
|
||||
* Send request to `/query` module endpoint.
|
||||
*
|
||||
* @param array $postData
|
||||
* @param bool $hover
|
||||
* @param string $moduleFamily
|
||||
* @param bool $throwException
|
||||
* @return array|false
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function queryModuleServer(array $postData, $hover = false, $moduleFamily = 'Enrichment', $throwException = false)
|
||||
{
|
||||
if ($hover) {
|
||||
$timeout = Configure::read('Plugin.' . $moduleFamily . '_hover_timeout') ?: 5;
|
||||
} else {
|
||||
$timeout = Configure::read('Plugin.' . $moduleFamily . '_timeout') ?: 10;
|
||||
}
|
||||
try {
|
||||
return $this->sendRequest('/query', $timeout, $postData, $moduleFamily);
|
||||
} catch (Exception $e) {
|
||||
if ($throwException) {
|
||||
throw $e;
|
||||
}
|
||||
$this->logException('Failed to query module ' . $moduleFamily, $e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level way how to send request to module.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param int $timeout
|
||||
* @param array|null $postData
|
||||
* @param string $moduleFamily
|
||||
* @return array
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function sendRequest($uri, $timeout, $postData = null, $moduleFamily = 'Enrichment')
|
||||
{
|
||||
$url = $this->__getModuleServer($moduleFamily);
|
||||
if (!$url) {
|
||||
return false;
|
||||
throw new Exception("Module type $moduleFamily is not enabled.");
|
||||
}
|
||||
App::uses('HttpSocket', 'Network/Http');
|
||||
if ($hover) {
|
||||
$settings = array(
|
||||
'timeout' => Configure::read('Plugin.' . $moduleFamily . '_hover_timeout') ?: 5
|
||||
);
|
||||
} else {
|
||||
$settings = array(
|
||||
'timeout' => Configure::read('Plugin.' . $moduleFamily . '_timeout') ?: 10
|
||||
);
|
||||
}
|
||||
$sslSettings = array('ssl_verify_peer', 'ssl_verify_host', 'ssl_allow_self_signed', 'ssl_verify_peer', 'ssl_cafile');
|
||||
foreach ($sslSettings as $sslSetting) {
|
||||
if (Configure::check('Plugin.' . $moduleFamily . '_' . $sslSetting) && Configure::read('Plugin.' . $moduleFamily . '_' . $sslSetting) !== '') {
|
||||
$settings[$sslSetting] = Configure::read('Plugin.' . $moduleFamily . '_' . $sslSetting);
|
||||
}
|
||||
}
|
||||
// let's set a low timeout for the introspection so that we don't block the loading of pages due to a misconfigured modules
|
||||
if ($uri == '/modules') {
|
||||
$settings['timeout'] = 1;
|
||||
}
|
||||
$httpSocket = new HttpSocket($settings);
|
||||
$httpSocket = new HttpSocket(['timeout' => $timeout]);
|
||||
$request = array(
|
||||
'header' => array(
|
||||
'Content-Type' => 'application/json',
|
||||
|
@ -236,8 +260,11 @@ class Module extends AppModel
|
|||
$request['header']['Authorization'] = 'Bearer ' . Configure::read('Plugin.' . $moduleFamily . '_authkey');
|
||||
}
|
||||
}
|
||||
try {
|
||||
if ($post) {
|
||||
if ($postData) {
|
||||
if (!is_array($postData)) {
|
||||
throw new InvalidArgumentException("Post data must be array, " . gettype($postData) . " given.");
|
||||
}
|
||||
$post = json_encode($postData);
|
||||
$response = $httpSocket->post($url . $uri, $post, $request);
|
||||
} else {
|
||||
if ($moduleFamily == 'Cortex') {
|
||||
|
@ -245,29 +272,41 @@ class Module extends AppModel
|
|||
}
|
||||
$response = $httpSocket->get($url . $uri, false, $request);
|
||||
}
|
||||
return json_decode($response->body, true);
|
||||
} catch (Exception $e) {
|
||||
$this->logException('Failed to query module ' . $moduleFamily, $e);
|
||||
$exception = $e->getMessage();
|
||||
return false;
|
||||
if (!$response->isOk()) {
|
||||
if ($httpSocket->lastError()) {
|
||||
throw new Exception("Failed to get response from $moduleFamily module: " . $httpSocket->lastError['str']);
|
||||
}
|
||||
throw new Exception("Failed to get response from $moduleFamily module: HTTP $response->reasonPhrase", (int)$response->code);
|
||||
}
|
||||
return $this->jsonDecode($response->body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $moduleFamily
|
||||
* @return array
|
||||
*/
|
||||
public function getModuleSettings($moduleFamily = 'Enrichment')
|
||||
{
|
||||
$modules = $this->getModules(false, $moduleFamily);
|
||||
$modules = $this->getModules($moduleFamily);
|
||||
$result = array();
|
||||
if (!empty($modules['modules'])) {
|
||||
foreach ($modules['modules'] as $module) {
|
||||
if (!empty($modules)) {
|
||||
foreach ($modules as $module) {
|
||||
if (array_intersect($this->__validTypes[$moduleFamily], $module['meta']['module-type'])) {
|
||||
$result[$module['name']][0] = array('name' => 'enabled', 'type' => 'boolean');
|
||||
$result[$module['name']][1] = array('name' => 'restrict', 'type' => 'orgs');
|
||||
$moduleSettings = [
|
||||
array('name' => 'enabled', 'type' => 'boolean'),
|
||||
array('name' => 'restrict', 'type' => 'orgs')
|
||||
];
|
||||
if (isset($module['meta']['config'])) {
|
||||
foreach ($module['meta']['config'] as $conf) {
|
||||
$result[$module['name']][] = array('name' => $conf, 'type' => 'string');
|
||||
foreach ($module['meta']['config'] as $key => $value) {
|
||||
if (is_string($key)) {
|
||||
$moduleSettings[] = array('name' => $key, 'type' => 'string', 'description' => $value);
|
||||
} else {
|
||||
$moduleSettings[] = array('name' => $value, 'type' => 'string');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result[$module['name']] = $moduleSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
|
|
|
@ -4,6 +4,10 @@ App::uses('GpgTool', 'Tools');
|
|||
|
||||
class Server extends AppModel
|
||||
{
|
||||
const SETTING_CRITICAL = 0,
|
||||
SETTING_RECOMMENDED = 1,
|
||||
SETTING_OPTIONAL = 2;
|
||||
|
||||
public $name = 'Server';
|
||||
|
||||
public $actsAs = array('SysLogLogable.SysLogLogable' => array(
|
||||
|
@ -1100,7 +1104,33 @@ class Server extends AppModel
|
|||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => true
|
||||
)
|
||||
),
|
||||
'attachment_scan_module' => [
|
||||
'level' => self::SETTING_OPTIONAL,
|
||||
'description' => __('Name of enrichment module that will be used for attachment malware scanning. This module must return av-signature or sb-signature object.'),
|
||||
'value' => '',
|
||||
'errorMessage' => '',
|
||||
'type' => 'string',
|
||||
'null' => true,
|
||||
],
|
||||
'attachment_scan_hash_only' => [
|
||||
'level' => self::SETTING_OPTIONAL,
|
||||
'description' => __('Send to attachment scan module just file hash. This can be useful if module sends attachment to remote service and you don\'t want to leak real data.'),
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => true,
|
||||
],
|
||||
'attachment_scan_timeout' => [
|
||||
'level' => self::SETTING_OPTIONAL,
|
||||
'description' => __('How long to wait for scan results in seconds.'),
|
||||
'value' => 30,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testForPositiveInteger',
|
||||
'type' => 'numeric',
|
||||
'null' => true,
|
||||
]
|
||||
),
|
||||
'GnuPG' => array(
|
||||
'branch' => 1,
|
||||
|
@ -2251,6 +2281,14 @@ class Server extends AppModel
|
|||
'test' => 'testBool',
|
||||
'type' => 'boolean'
|
||||
),
|
||||
'Enrichment_hover_popover_only' => array(
|
||||
'level' => 0,
|
||||
'description' => __('When enabled, user have to click on magnifier icon to show enrichment'),
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean'
|
||||
),
|
||||
'Enrichment_hover_timeout' => array(
|
||||
'level' => 1,
|
||||
'description' => __('Set a timeout for the hover services'),
|
||||
|
@ -3248,7 +3286,7 @@ class Server extends AppModel
|
|||
} else {
|
||||
$setting['test'] = 'testForEmpty';
|
||||
$setting['type'] = 'string';
|
||||
$setting['description'] = __('Set this required module specific setting.');
|
||||
$setting['description'] = isset($result['description']) ? $result['description'] : __('Set this required module specific setting.');
|
||||
$setting['value'] = '';
|
||||
}
|
||||
$serverSettings['Plugin'][$moduleType . '_' . $module . '_' . $result['name']] = $setting;
|
||||
|
@ -3418,6 +3456,14 @@ class Server extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function testForPositiveInteger($value)
|
||||
{
|
||||
if ((is_int($value) && $value >= 0) || ctype_digit($value)) {
|
||||
return true;
|
||||
}
|
||||
return __('The value has to be a whole number greater or equal 0.');
|
||||
}
|
||||
|
||||
public function testForCookieTimeout($value)
|
||||
{
|
||||
$numeric = $this->testForNumeric($value);
|
||||
|
@ -4277,96 +4323,99 @@ class Server extends AppModel
|
|||
return $validItems;
|
||||
}
|
||||
|
||||
public function runConnectionTest($id)
|
||||
/**
|
||||
* @param array $server
|
||||
* @return array
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function runConnectionTest(array $server)
|
||||
{
|
||||
$server = $this->find('first', array('conditions' => array('Server.id' => $id)));
|
||||
App::uses('SyncTool', 'Tools');
|
||||
try {
|
||||
$clientCertificate = SyncTool::getServerClientCertificateInfo($server);
|
||||
if ($clientCertificate) {
|
||||
$clientCertificate['valid_from'] = $clientCertificate['valid_from'] ? $clientCertificate['valid_from']->format('c') : __('Not defined');
|
||||
$clientCertificate['valid_to'] = $clientCertificate['valid_to'] ? $clientCertificate['valid_to']->format('c') : __('Not defined');
|
||||
$clientCertificate['public_key_size'] = $clientCertificate['public_key_size'] ?: __('Unknwon');
|
||||
$clientCertificate['public_key_type'] = $clientCertificate['public_key_type'] ?: __('Unknwon');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$clientCertificate = ['error' => $e->getMessage()];
|
||||
}
|
||||
|
||||
$HttpSocket = $this->setupHttpSocket($server, null, 5);
|
||||
$request = $this->setupSyncRequest($server);
|
||||
$uri = $server['Server']['url'] . '/servers/getVersion';
|
||||
|
||||
try {
|
||||
$response = $HttpSocket->get($uri, false, $request);
|
||||
if ($response === false) {
|
||||
throw new Exception("Connection failed for unknown reason.");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: Connection test failed. Reason: ' . json_encode($e->getMessage()),
|
||||
));
|
||||
return array('status' => 2);
|
||||
$logTitle = 'Error: Connection test failed. Reason: ' . $e->getMessage();
|
||||
$this->loadLog()->createLogEntry('SYSTEM', 'error', 'Server', $server['Server']['id'], $logTitle);
|
||||
return array('status' => 2, 'client_certificate' => $clientCertificate);
|
||||
}
|
||||
if ($response->isOk()) {
|
||||
return array('status' => 1, 'message' => $response->body());
|
||||
} else {
|
||||
|
||||
if ($response->code == '403') {
|
||||
return array('status' => 4);
|
||||
}
|
||||
if ($response->code == '405') {
|
||||
return array('status' => 4, 'client_certificate' => $clientCertificate);
|
||||
} else if ($response->code == '405') {
|
||||
try {
|
||||
$responseText = $this->jsonDecode($response->body)['message'];
|
||||
} catch (Exception $e) {
|
||||
return array('status' => 3);
|
||||
}
|
||||
if ($responseText === 'Your user account is expecting a password change, please log in via the web interface and change it before proceeding.') {
|
||||
return array('status' => 5);
|
||||
return array('status' => 5, 'client_certificate' => $clientCertificate);
|
||||
} elseif ($responseText === 'You have not accepted the terms of use yet, please log in via the web interface and accept them.') {
|
||||
return array('status' => 6);
|
||||
return array('status' => 6, 'client_certificate' => $clientCertificate);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// pass
|
||||
}
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: Connection test failed. Returned data is in the change field.',
|
||||
'change' => sprintf(
|
||||
'response () => (%s), response-code () => (%s)',
|
||||
$response->body,
|
||||
$response->code
|
||||
)
|
||||
));
|
||||
return array('status' => 3);
|
||||
} else if ($response->isOk()) {
|
||||
try {
|
||||
$info = $this->jsonDecode($response->body());
|
||||
if (!isset($info['version'])) {
|
||||
throw new Exception("Server returns JSON response, but doesn't contain required 'version' field.");
|
||||
}
|
||||
return array('status' => 1, 'info' => $info, 'client_certificate' => $clientCertificate);
|
||||
} catch (Exception $e) {
|
||||
// Even if server returns OK status, that doesn't mean that connection to another MISP instance works
|
||||
}
|
||||
}
|
||||
|
||||
public function runPOSTtest($id)
|
||||
$logTitle = 'Error: Connection test failed. Returned data is in the change field.';
|
||||
$this->loadLog()->createLogEntry('SYSTEM', 'error', 'Server', $server['Server']['id'], $logTitle, [
|
||||
'response' => ['', $response->body],
|
||||
'response-code' => ['', $response->code],
|
||||
]);
|
||||
return array('status' => 3, 'client_certificate' => $clientCertificate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $server
|
||||
* @return int
|
||||
* @throws JsonException
|
||||
*/
|
||||
public function runPOSTtest(array $server)
|
||||
{
|
||||
$server = $this->find('first', array('conditions' => array('Server.id' => $id)));
|
||||
if (empty($server)) {
|
||||
throw new InvalidArgumentException(__('Invalid server.'));
|
||||
$testFile = file_get_contents(APP . 'files/scripts/test_payload.txt');
|
||||
if (!$testFile) {
|
||||
throw new Exception("Could not load payload for POST test.");
|
||||
}
|
||||
$HttpSocket = $this->setupHttpSocket($server);
|
||||
$request = $this->setupSyncRequest($server);
|
||||
$testFile = file_get_contents(APP . 'files/scripts/test_payload.txt');
|
||||
$uri = $server['Server']['url'] . '/servers/postTest';
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
|
||||
try {
|
||||
$response = $HttpSocket->post($uri, json_encode(array('testString' => $testFile)), $request);
|
||||
$rawBody = $response->body;
|
||||
$response = json_decode($response, true);
|
||||
$response = $this->jsonDecode($rawBody);
|
||||
} catch (Exception $e) {
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: POST connection test failed. Reason: ' . json_encode($e->getMessage()),
|
||||
));
|
||||
$title = 'Error: POST connection test failed. Reason: ' . $e->getMessage();
|
||||
$this->loadLog()->createLogEntry('SYSTEM', 'error', 'Server', $server['Server']['id'], $title);
|
||||
return 8;
|
||||
}
|
||||
if (!isset($response['body']['testString']) || $response['body']['testString'] !== $testFile) {
|
||||
$responseString = '';
|
||||
if (!empty($repsonse['body']['testString'])) {
|
||||
$responseString = $response['body']['testString'];
|
||||
} else if (!empty($rawBody)){
|
||||
|
@ -4374,32 +4423,17 @@ class Server extends AppModel
|
|||
} else {
|
||||
$responseString = __('Response was empty.');
|
||||
}
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: POST connection test failed due to the message body not containing the expected data. Response: ' . PHP_EOL . PHP_EOL . $responseString,
|
||||
));
|
||||
|
||||
$title = 'Error: POST connection test failed due to the message body not containing the expected data. Response: ' . PHP_EOL . PHP_EOL . $responseString;
|
||||
$this->loadLog()->createLogEntry('SYSTEM', 'error', 'Server', $server['Server']['id'], $title);
|
||||
return 9;
|
||||
}
|
||||
$headers = array('Accept', 'Content-type');
|
||||
foreach ($headers as $header) {
|
||||
if (!isset($response['headers'][$header]) || $response['headers'][$header] != 'application/json') {
|
||||
$responseHeader = isset($response['headers'][$header]) ? $response['headers'][$header] : 'Header was not set.';
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: POST connection test failed due to a header not matching the expected value. Expected: "application/json", received "' . $responseHeader,
|
||||
));
|
||||
$title = 'Error: POST connection test failed due to a header not matching the expected value. Expected: "application/json", received "' . $responseHeader . '"';
|
||||
$this->loadLog()->createLogEntry('SYSTEM', 'error', 'Server', $server['Server']['id'], $title);
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
@ -5232,13 +5266,12 @@ class Server extends AppModel
|
|||
public function moduleDiagnostics(&$diagnostic_errors, $type = 'Enrichment')
|
||||
{
|
||||
$this->Module = ClassRegistry::init('Module');
|
||||
$types = array('Enrichment', 'Import', 'Export', 'Cortex');
|
||||
$diagnostic_errors++;
|
||||
if (Configure::read('Plugin.' . $type . '_services_enable')) {
|
||||
$exception = false;
|
||||
$result = $this->Module->getModules(false, $type, $exception);
|
||||
if ($exception) {
|
||||
return $exception;
|
||||
try {
|
||||
$result = $this->Module->getModules($type, true);
|
||||
} catch (Exception $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
if (empty($result)) {
|
||||
return 2;
|
||||
|
|
|
@ -403,7 +403,11 @@ class ShadowAttribute extends AppModel
|
|||
public function saveBase64EncodedAttachment($attribute)
|
||||
{
|
||||
$data = base64_decode($attribute['data']);
|
||||
return $this->loadAttachmentTool()->saveShadow($attribute['event_id'], $attribute['id'], $data);
|
||||
$result = $this->loadAttachmentTool()->saveShadow($attribute['event_id'], $attribute['id'], $data);
|
||||
if ($result) {
|
||||
$this->loadAttachmentScan()->backgroundScan(AttachmentScan::TYPE_SHADOW_ATTRIBUTE, $attribute);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,72 @@ This plugin enables CakePHP applications to use Single Sign-On to authenticate i
|
|||
|
||||
## Usage
|
||||
|
||||
### Prerequisites - Shibboleth Service Provider
|
||||
The MISP plugin takes care of the mapping of your shibboleth session attributes to MISP, but you will still need to install the service provider (SP) and configure it yourself. The documentation for Shibboleth Service Provider 3 can be found at https://wiki.shibboleth.net/confluence/display/SP3/Home.
|
||||
|
||||
To install Shibboleth SP3 on Ubuntu, you can use the instructions provided by SWITCH at https://www.switch.ch/aai/guides/sp/installation/ and then follow the below steps. If you already installed and configured Shibboleth you can skip this section.
|
||||
|
||||
Create signing and encryption certificate. The value following -e should be your entity ID, for example https://<host>/shibboleth.
|
||||
```bash
|
||||
sudo shib-keygen -f -u _shibd -h <host> -y 5 -e https://<host>/shibboleth -o /etc/shibboleth
|
||||
```
|
||||
|
||||
Edit /etc/shibboleth/shibboleth2.xml to use the created certificate for both signing and encryption (change the values for key and certificate).
|
||||
```xml
|
||||
<CredentialResolver type="File" use="signing"
|
||||
key="sp-key.pem" certificate="sp-cert.pem"/>
|
||||
<CredentialResolver type="File" use="encryption"
|
||||
key="sp-key.pem" certificate="sp-cert.pem"/>
|
||||
```
|
||||
|
||||
Edit /etc/shibboleth/shibboleth2.xml to set secure cookie properties (cookieProps) if you want to.
|
||||
```xml
|
||||
<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
|
||||
checkAddress="false" handlerSSL="false" cookieProps="https"
|
||||
redirectLimit="exact">
|
||||
```
|
||||
|
||||
At this point, you should already be able to test your configuration. The last line of the output should be "overall configuration is loadable, check console for non-fatal problems".
|
||||
```bash
|
||||
sudo shibd -t
|
||||
```
|
||||
|
||||
Set entityID in /etc/shibboleth/shibboleth2.xml.
|
||||
```xml
|
||||
<ApplicationDefaults entityID="https://<host>/shibboleth"
|
||||
REMOTE_USER="eppn subject-id pairwise-id persistent-id"
|
||||
cipherSuites="DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1">
|
||||
```
|
||||
|
||||
Copy your identity provider metadata to /etc/shibboleth, for example to /etc/shibboleth/idp-metadata.xml and refer to it in /etc/shibboleth/shibboleth2.xml. Uncomment and edit the relevant line.
|
||||
```xml
|
||||
<MetadataProvider type="XML" validate="true" path="idp-metadata.xml"/>
|
||||
```
|
||||
|
||||
Optionally, you can make sure the service provider does not create a session if some attributes, like OrgTag and GroupTag are missing. If users attempt to login an this happens, they will receive a pre-configured reply (default at /etc/shibboleth/attrChecker.html).
|
||||
In /etc/shibboleth/shibboleth2.xml, edit ApplicationDefaults by adding the sessionHook:
|
||||
```xml
|
||||
<ApplicationDefaults entityID="https://<HOST>/shibboleth"
|
||||
REMOTE_USER="eppn persistent-id targeted-id"
|
||||
signing="front" encryption="false"
|
||||
sessionHook="/Shibboleth.sso/AttrChecker"
|
||||
```
|
||||
Optional for attribute checking: add your checks (note that the incoming attribute names can be different for you, for more info on possible checks refer to https://wiki.shibboleth.net/confluence/display/SP3/Attribute+Checker+Handler):
|
||||
```xml
|
||||
<Handler type="AttributeChecker" Location="/AttrChecker" template="attrChecker.html" attributes="OrgTag GroupTag" flushSession="true"/>
|
||||
```
|
||||
|
||||
At this point you will have to send your metadata to your identity provider. You can get template metadata based on your configuration from https://<host>/Shibboleth.sso/Metadata.
|
||||
|
||||
### MISP plugin configuration
|
||||
|
||||
Edit your MISP apache configuration by adding the below (location depends on your handler path, /Shibboleth.sso by default).
|
||||
```Apache
|
||||
<Location /Shibboleth.sso>
|
||||
SetHandler shib
|
||||
</Locations>
|
||||
```
|
||||
|
||||
Enable the plugin at bootstrap.php:
|
||||
|
||||
```php
|
||||
|
@ -18,32 +84,49 @@ Uncomment the following line to enable SSO authorization
|
|||
'auth'=>array('ShibbAuth.ApacheShibb'),
|
||||
```
|
||||
|
||||
And configure it. MailTag, OrgTag and GroupTag are the string that represent the key for the values needed by the plugin.
|
||||
For example if you are using ADFS OrgTag will be ADFS_FEDERATION, GroupTag will be ADFS_GROUP, etc. meaning the key for the values needed.
|
||||
DefaultOrg are values that come by default just in case they are not defined or obtained from the environment variables.
|
||||
The GroupRoleMatching is an array that allows the definition and correlation between groups and roles in MISP, being them updated
|
||||
If the line does not exist, add it to 'Security' array, for example like below. Note that you should just add the line to your own existing config.
|
||||
```php
|
||||
'Security' =>
|
||||
array (
|
||||
'level' => 'medium',
|
||||
'salt' => '',
|
||||
'cipherSeed' => '',
|
||||
'password_policy_length' => 12,
|
||||
'password_policy_complexity' => '/^((?=.*\\d)|(?=.*\\W+))(?![\\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/',
|
||||
'self_registration_message' => 'If you would like to send us a registration request, please fill out the form below. Make sure you fill out as much information as possible in order to ease the task of the administrators.',
|
||||
'auth'=>array('ShibbAuth.ApacheShibb'),
|
||||
)
|
||||
```
|
||||
|
||||
And configure it. MailTag, OrgTag and GroupTag are the keys for the values needed by the plugin.
|
||||
For example if you are using ADFS you should replace IDP_FEDERATION_TAG by ADFS_FEDERATION, IDP_GROUP_TAG by ADFS_GROUP, etc.
|
||||
Replace MISP_DEFAULT_ORG by the organization you want users to be assigned to in case no organization value is given by the identity provider.
|
||||
The GroupRoleMatching is an array that allows the definition and correlation between groups and roles in MISP. These get updated
|
||||
if the groups are updated (i.e. a user that was admin and their groups changed inside the organization will have his role changed in MISP
|
||||
upon the next login being now user or org admin respectively). The GroupSeparator is the character used to separate the different groups
|
||||
in the list given by apache.
|
||||
in the list given by apache. By default, you can leave it at ';'.
|
||||
|
||||
```php
|
||||
'ApacheShibbAuth' => // Configuration for shibboleth authentication
|
||||
array(
|
||||
'MailTag' => 'EMAIL_TAG',
|
||||
'OrgTag' => 'FEDERATION_TAG',
|
||||
'GroupTag' => 'GROUP_TAG',
|
||||
'MailTag' => 'IDP_EMAIL_TAG',
|
||||
'OrgTag' => 'IDP_FEDERATION_TAG',
|
||||
'GroupTag' => 'IDP_GROUP_TAG',
|
||||
'GroupSeparator' => ';',
|
||||
'GroupRoleMatching' => array( // 3:User, 1:admin. May be good to set "1" for the first user
|
||||
'group_three' => '3',
|
||||
'group_two' => 2,
|
||||
'group_one' => 1,
|
||||
'possible_group_attribute_value_3' => '3',
|
||||
'possible_group_attribute_value_2' => 2,
|
||||
'possible_group_attribute_value_1' => 1,
|
||||
),
|
||||
'DefaultOrg' => 'DEFAULT_ORG',
|
||||
'DefaultOrg' => 'MISP_DEFAULT_ORG',
|
||||
),
|
||||
```
|
||||
If used with Apache as webserver it might be useful to make a distinction to filter out API/Syncs from SSO login. It can be added to the vhost as follows:
|
||||
If used with Apache as webserver it might be useful to make a distinction to filter out API/Syncs from SSO login. It can be added to the vhost as follows (Added lines are the If/Else clauses):
|
||||
|
||||
```Apache
|
||||
<Directory /var/www/MISP/app/webroot>
|
||||
Options -Indexes
|
||||
AllowOverride all
|
||||
<If "-T req('Authorization')">
|
||||
Require all granted
|
||||
AuthType None
|
||||
|
@ -55,6 +138,14 @@ If used with Apache as webserver it might be useful to make a distinction to fil
|
|||
ShibRequestSetting shibexportassertion Off
|
||||
ShibUseHeaders On
|
||||
</Else>
|
||||
</Directory>
|
||||
```
|
||||
|
||||
If you want the logout button to work for killing your session, you can use the CustomAuth plugin to configure a custom logout url, by default the url should be https://<host>/Shibboleth.sso/Logout. This leads to a local logout. If you want to also trigger a logout at the identity provider, you can use the return mechanism. In this case you will need to change the allowed redirects. Your logout url will look like https://<host>/Shibboleth.sso/Logout?return=https://<idp_host>/Logout. Edit your shibboleth configuration (often at /etc/shibboleth/shibboleth2.xml) as necessary. Relevant shibboleth documentation can be found at https://wiki.shibboleth.net/confluence/display/SP3/Logout and https://wiki.shibboleth.net/confluence/display/SP3/Sessions.
|
||||
```xml
|
||||
<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
|
||||
checkAddress="false" handlerSSL="false" cookieProps="https"
|
||||
redirectLimit="exact+whitelist" redirectWhitelist="https://<idp_host>">
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ $event['Related' . $scope][$object['id']] = array_values($event['Related' . $sco
|
|||
$count = count($event['Related' . $scope][$object['id']]);
|
||||
foreach ($event['Related' . $scope][$object['id']] as $relatedAttribute) {
|
||||
if ($i == 4 && $count > 5) {
|
||||
$expandButton = __('Show ') . ($count - 4) . __(' more...');
|
||||
$expandButton = __('Show %s more...', $count - 4);
|
||||
echo sprintf(
|
||||
'<li class="no-side-padding correlation-expand-button useCursorPointer linkButton %s">%s</li>',
|
||||
$linkColour,
|
||||
|
@ -24,12 +24,12 @@ foreach ($event['Related' . $scope][$object['id']] as $relatedAttribute) {
|
|||
$relatedData = array(
|
||||
'Orgc' => !empty($orgTable[$relatedAttribute['org_id']]) ? $orgTable[$relatedAttribute['org_id']] : 'N/A',
|
||||
'Date' => isset($relatedAttribute['date']) ? $relatedAttribute['date'] : 'N/A',
|
||||
'Info' => $relatedAttribute['info'],
|
||||
'Event' => $relatedAttribute['info'],
|
||||
'Correlating Value' => $relatedAttribute['value']
|
||||
);
|
||||
$popover = '';
|
||||
foreach ($relatedData as $k => $v) {
|
||||
$popover .= '<span class=\'bold black\'>' . h($k) . '</span>: <span class="blue">' . h($v) . '</span><br />';
|
||||
$popover .= '<span class="bold black">' . h($k) . '</span>: <span class="blue">' . h($v) . '</span><br>';
|
||||
}
|
||||
$link = $this->Html->link(
|
||||
$relatedAttribute['id'],
|
||||
|
@ -53,4 +53,3 @@ if ($i > 5) {
|
|||
__('Collapse…')
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -124,34 +124,19 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
<td id="Attribute_<?= $objectId ?>_container" class="showspaces limitedWidth shortish"<?= $quickEdit('value') ?>>
|
||||
<div id="Attribute_<?= $objectId ?>_value_placeholder" class="inline-field-placeholder"></div>
|
||||
<div id="Attribute_<?= $objectId ?>_value_solid" class="inline-field-solid">
|
||||
<span>
|
||||
<?php
|
||||
$spanExtra = '';
|
||||
$popupButton = '';
|
||||
if (Configure::read('Plugin.Enrichment_hover_enable') && isset($modules) && isset($modules['hover_type'][$object['type']])) {
|
||||
$commonDataFields = sprintf(
|
||||
'data-object-type="Attribute" data-object-id="%s"',
|
||||
$objectId
|
||||
);
|
||||
|
||||
$spanExtra = sprintf(' class="eventViewAttributeHover" %s', $commonDataFields);
|
||||
$commonDataFields = sprintf('data-object-type="Attribute" data-object-id="%s"', $objectId);
|
||||
$spanExtra = Configure::read('Plugin.Enrichment_hover_popover_only') ? '' : sprintf(' class="eventViewAttributeHover" %s', $commonDataFields);
|
||||
$popupButton = sprintf('<i class="fa fa-search-plus useCursorPointer eventViewAttributePopup noPrint" title="%s" %s></i>', __('Show hover enrichment'), $commonDataFields);
|
||||
}
|
||||
echo sprintf(
|
||||
'<span%s style="white-space: pre-wrap;">%s</span> %s',
|
||||
'<span%s>%s</span> %s',
|
||||
$spanExtra,
|
||||
$this->element('/Events/View/value_field', array('object' => $object, 'linkClass' => $linkClass)),
|
||||
$popupButton
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php
|
||||
if (isset($object['warnings'])) {
|
||||
$temp = '';
|
||||
foreach ($object['warnings'] as $warning) {
|
||||
$temp .= '<span class="bold">' . h($warning['match']) . ':</span> <span class="red">' . h($warning['warninglist_name']) . '</span><br>';
|
||||
}
|
||||
echo ' <span aria-label="' . __('warning') . '" role="img" tabindex="0" class="fa fa-exclamation-triangle" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover" data-placement="right"> </span>';
|
||||
} else {
|
||||
echo $this->element('/Events/View/value_field', array('object' => $object, 'linkClass' => $linkClass));
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
@ -206,17 +191,17 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
>
|
||||
</td>
|
||||
<td class="shortish">
|
||||
<ul class="inline" style="margin:0">
|
||||
<?php
|
||||
if (!empty($event['RelatedAttribute'][$object['id']])) {
|
||||
echo '<ul class="inline" style="margin:0">';
|
||||
echo $this->element('Events/View/attribute_correlations', array(
|
||||
'scope' => 'Attribute',
|
||||
'object' => $object,
|
||||
'event' => $event,
|
||||
));
|
||||
echo '</ul>';
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</td>
|
||||
<td class="shortish">
|
||||
<ul class="inline" style="margin:0">
|
||||
|
@ -230,15 +215,15 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
foreach ($v as $k2 => $v2) {
|
||||
$v[$k2] = h($v2);
|
||||
}
|
||||
$v = implode('<br />', $v);
|
||||
$v = implode('<br>', $v);
|
||||
} else {
|
||||
$v = h($v);
|
||||
}
|
||||
$popover .= '<span class=\'bold black\'>' . Inflector::humanize(h($k)) . '</span>: <span class="blue">' . $v . '</span><br />';
|
||||
$popover .= '<span class="bold black">' . Inflector::humanize(h($k)) . '</span>: <span class="blue">' . $v . '</span><br>';
|
||||
}
|
||||
$liContents = '';
|
||||
if ($isSiteAdmin || $hostOrgUser) {
|
||||
if ($feed['source_format'] == 'misp') {
|
||||
if ($feed['source_format'] === 'misp') {
|
||||
$liContents .= sprintf(
|
||||
'<form action="%s/feeds/previewIndex/%s" method="post" style="margin:0;line-height:auto;">%s%s</form>',
|
||||
$baseurl,
|
||||
|
@ -255,14 +240,11 @@ $quickEdit = function($fieldName) use ($editScope, $object, $event) {
|
|||
);
|
||||
} else {
|
||||
$liContents .= sprintf(
|
||||
'<form>%s</form>',
|
||||
sprintf(
|
||||
'<a href="%s/feeds/previewIndex/%s" style="margin-right:3px;" data-toggle="popover" data-content="%s" data-trigger="hover">%s</a>',
|
||||
$baseurl,
|
||||
h($feed['id']),
|
||||
h($popover),
|
||||
h($feed['id'])
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -91,15 +91,6 @@
|
|||
<?php
|
||||
echo $this->element('/Events/View/value_field', array('object' => $object, 'linkClass' => $linkClass));
|
||||
?>
|
||||
<?php
|
||||
if (isset($object['warnings'])) {
|
||||
$temp = '';
|
||||
foreach ($object['warnings'] as $warning) {
|
||||
$temp .= '<span class="bold" style="color: black">' . h($warning['match']) . ':</span> <span class="red">' . h($warning['warninglist_name']) . '</span><br>';
|
||||
}
|
||||
echo ' <span aria-label="' . __('warning') . '" role="img" tabindex="0" class="fa fa-exclamation-triangle white" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover"> </span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="shortish"> </td>
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
<i style="display: block; text-align: center;" class="fas fa-arrow-down"></i>
|
||||
<div><?php echo $object['last_seen'] != null ? h($object['last_seen']) : '<span style="display: block; text-align:center;">_</span>'; ?></div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div></div>
|
||||
<?php endif; ?>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -46,15 +46,28 @@ switch ($object['type']) {
|
|||
}
|
||||
|
||||
if (isset($object['objectType'])) {
|
||||
if (array_key_exists('infected', $object) && $object['infected'] !== false) { // it is not possible to use isset
|
||||
if ($object['infected'] === null) {
|
||||
$confirm = __('This file was not checked by AV scan. Do you really want to download it?');
|
||||
} else {
|
||||
$confirm = __('According to AV scan, this file contains %s malware. Do you really want to download it?', $object['infected']);
|
||||
}
|
||||
} else {
|
||||
$confirm = null;
|
||||
}
|
||||
|
||||
$controller = $object['objectType'] === 'proposal' ? 'shadow_attributes' : 'attributes';
|
||||
$url = array('controller' => $controller, 'action' => 'download', $object['id']);
|
||||
echo $this->Html->link($filename, $url, array('class' => $linkClass));
|
||||
echo $this->Html->link($filename, $url, array('class' => $linkClass), $confirm);
|
||||
} else {
|
||||
echo $filename;
|
||||
}
|
||||
if (isset($filenameHash[1])) {
|
||||
echo '<br>' . $filenameHash[1];
|
||||
}
|
||||
if (isset($object['infected']) && $object['infected'] !== false) {
|
||||
echo ' <i class="fas fa-virus" title="' . __('This file contains malware %s', $object['infected']) . '"></i>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -95,11 +108,11 @@ switch ($object['type']) {
|
|||
$value = str_replace("\r", '', $object['value']);
|
||||
$truncated = $truncateLongText($value);
|
||||
if ($truncated) {
|
||||
echo '<span data-full="' . h($object['value']) .'" data-full-type="text">' .
|
||||
echo '<span style="white-space: pre-wrap;" data-full="' . h($object['value']) .'" data-full-type="text">' .
|
||||
str_replace(" ", ' ', h(rtrim($truncated)));
|
||||
echo ' <b>…</b><br><a href="#">' . __('Show all') . '</a></span>';
|
||||
} else {
|
||||
echo str_replace(" ", ' ', h($value));
|
||||
echo '<span style="white-space: pre-wrap;">' . str_replace(" ", ' ', h($value)) . '</span>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -140,14 +153,22 @@ switch ($object['type']) {
|
|||
if ($truncated) {
|
||||
$rawTypes = ['email-header', 'yara', 'pgp-private-key', 'pgp-public-key', 'url'];
|
||||
$dataFullType = in_array($object['type'], $rawTypes) ? 'raw' : 'text';
|
||||
echo '<span data-full="' . h($value) .'" data-full-type="' . $dataFullType .'">' . h(rtrim($truncated)) .
|
||||
echo '<span style="white-space: pre-wrap;" data-full="' . h($value) .'" data-full-type="' . $dataFullType .'">' . h($truncated) .
|
||||
' <b>…</b><br><a href="#">' . __('Show all') . '</a></span>';
|
||||
} else {
|
||||
echo h($value);
|
||||
echo '<span style="white-space: pre-wrap;">' . h($value) . '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($object['validationIssue'])) {
|
||||
echo ' <span class="fa fa-exclamation-triangle" title="' . __('Warning, this doesn\'t seem to be a legitimate ') . strtoupper(h($object['type'])) . __(' value') . '"> </span>';
|
||||
echo ' <span class="fa fa-exclamation-triangle" title="' . __('Warning, this doesn\'t seem to be a legitimate %s value', strtoupper(h($object['type']))) . '"> </span>';
|
||||
}
|
||||
|
||||
if (isset($object['warnings'])) {
|
||||
$temp = '';
|
||||
foreach ($object['warnings'] as $warning) {
|
||||
$temp .= '<span class="bold">' . h($warning['match']) . ':</span> <span class="red">' . h($warning['warninglist_name']) . '</span><br>';
|
||||
}
|
||||
echo ' <span aria-label="' . __('warning') . '" role="img" tabindex="0" class="fa fa-exclamation-triangle" data-placement="right" data-toggle="popover" data-content="' . h($temp) . '" data-trigger="hover"> </span>';
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
echo $this->Form->input('Attribute.' . $k . '.type', $formSettings);
|
||||
echo '<span class="bold">' . Inflector::humanize(h($element['object_relation'])) . '</span>';
|
||||
if (!empty($template['ObjectTemplate']['requirements']['required']) && in_array($element['object_relation'], $template['ObjectTemplate']['requirements']['required'])) {
|
||||
echo '<span class="bold red">' . '(*)' . '</span>';
|
||||
echo '<span class="red" style="vertical-align: super;font-size: 8px;margin-left: 2px;" title="' . __('Required') . '"><i class="fas fa-asterisk"></i></span>';
|
||||
}
|
||||
echo ' :: ' . h($element['type']) . '';
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<div>
|
||||
<?php
|
||||
/*
|
||||
* A simple button to add a link to a specific section
|
||||
*
|
||||
* Expected input:
|
||||
* { url: <relative url>, text: <text to be displayed on the button>}
|
||||
*
|
||||
* Example:
|
||||
* {url: "/events/index", text: "To the list of events"}
|
||||
*
|
||||
*/
|
||||
echo '<a href="'.$baseurl.h($data['url']).'">';
|
||||
echo '<button class="btn btn-primary widget-button">';
|
||||
echo h($data['text']);
|
||||
echo '</button></a>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<style widget-scoped>
|
||||
.widget-button {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
}
|
||||
</style>
|
|
@ -28,7 +28,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if ($data['url'] === '#' && empty($child_data)) {
|
||||
if ($data['url'] === '#' && !empty($data['children']) && empty($child_data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -472,11 +472,11 @@
|
|||
h($me['email']),
|
||||
$this->UserName->prepend($me['email']),
|
||||
h($loggedInUserName),
|
||||
sprintf(
|
||||
isset($notifications) ? sprintf(
|
||||
'<i class="fa fa-envelope %s" role="img" aria-label="%s"></i>',
|
||||
(($notifications['total'] == 0) ? 'white' : 'red'),
|
||||
__('Notifications') . ': ' . $notifications['total']
|
||||
)
|
||||
) : ''
|
||||
)
|
||||
),
|
||||
array(
|
||||
|
|
|
@ -274,6 +274,16 @@
|
|||
endif;
|
||||
?>
|
||||
</div>
|
||||
<h3><?= __('Attachment scan module') ?></h3>
|
||||
<div style="background-color:#f7f7f9;width:400px;">
|
||||
<?php if ($attachmentScan['status']): ?>
|
||||
<b>Status:</b> <span class="green bold"><?= __('OK') ?></span><br>
|
||||
<b>Software</b>: <?= implode(", ", $attachmentScan['software']) ?>
|
||||
<?php else: ?>
|
||||
<b>Status:</b> <span class="red bold"><?= __('Not available.') ?></span><br>
|
||||
<b>Reason:</b> <?= $attachmentScan['error'] ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<h3><?php echo __('STIX and Cybox libraries');?></h3>
|
||||
<p><?php echo __('Mitre\'s STIX and Cybox python libraries have to be installed in order for MISP\'s STIX export to work. Make sure that you install them (as described in the MISP installation instructions) if you receive an error below.');?><br />
|
||||
<?php echo __('If you run into any issues here, make sure that both STIX and CyBox are installed as described in the INSTALL.txt file. The required versions are');?>:<br />
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
echo $this->Form->create('Event', array('class' => 'inline-form inline-field-form', 'url' => $baseurl . '/events/quickEdit/' . $event['Event']['id'] . '/' . $field));
|
||||
?>
|
||||
<div class='inline-input inline-input-container'>
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" title="<?php echo __('Accept');?>" role="button" tabindex="0" aria-label="<?php echo __('Accept');?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" title="<?php echo __('Cancel');?>" role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>"></span></div>
|
||||
<?php
|
||||
echo $this->Form->input('category', array(
|
||||
'options' => array(array_combine($typeCategory[$object['type']], $typeCategory[$object['type']])),
|
||||
'label' => false,
|
||||
'selected' => $object['category'],
|
||||
'error' => array('escape' => false),
|
||||
'class' => 'inline-input',
|
||||
'id' => 'Attribute_' . $object['id'] . '_category_field',
|
||||
'div' => false
|
||||
));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
|
@ -144,7 +144,7 @@
|
|||
?></pre>
|
||||
<code><request><type>ip</type><eventid>!51</eventid><eventid>!62</eventid><withAttachment>false</withAttachment><tags>APT1</tags><tags>!OSINT</tags><from>false</from><to>2015-02-15</to></request></code><br /><br />
|
||||
<p><?php echo __('Alternatively, it is also possible to pass the filters via the parameters in the URL, though it is highly advised to use POST requests with JSON objects instead. The format is as described below');?>:</p>
|
||||
<pre><?php echo $baseurl.'/attributes/bro/download/[type]/[tags]/[event_id]/[allowNonIDS]/[from]/[to]/[last]'; ?></pre>
|
||||
<pre><?php echo $baseurl.'/attributes/bro/download/[type]/[tags]/[event_id]/[from]/[to]/[last]'; ?></pre>
|
||||
<b>type</b>: <?php echo __('The Bro type, any valid Bro type is accepted. The mapping between Bro and MISP types is as follows');?>:<br />
|
||||
<pre><?php
|
||||
foreach ($broTypes as $key => $value) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
if ($fieldData === 'Tag') {
|
||||
echo '<div><span class="blue bold">Tags</span>: ';
|
||||
if (!empty($event['EventTag'])) {
|
||||
echo '<span>' . $this->element('ajaxTags', array('event' => $event, 'tags' => $event['EventTag'], 'tagAccess' => false)) . '</span>';
|
||||
echo '<span>' . $this->element('ajaxTags', array('event' => $event, 'tags' => $event['EventTag'], 'static_tags_only' => true)) . '</span>';
|
||||
}
|
||||
echo '</div>';
|
||||
} else {
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
?></pre>
|
||||
<code><request><type>ip</type><eventid>!51</eventid><eventid>!62</eventid><withAttachment>false</withAttachment><tags>APT1</tags><tags>!OSINT</tags><from>false</from><to>2015-02-15</to></request></code><br /><br />
|
||||
<p><?php echo __('Alternatively, it is also possible to pass the filters via the parameters in the URL, though it is highly advised to use POST requests with JSON objects instead. The format is as described below');?>:</p>
|
||||
<pre><?php echo $baseurl.'/attributes/bro/download/[type]/[tags]/[event_id]/[allowNonIDS]/[from]/[to]/[last]'; ?></pre>
|
||||
<pre><?php echo $baseurl.'/attributes/bro/download/[type]/[tags]/[event_id]/[from]/[to]/[last]'; ?></pre>
|
||||
<b>type</b>: <?php echo __('The Bro type, any valid Bro type is accepted. The mapping between Bro and MISP types is as follows');?>:<br />
|
||||
<pre><?php
|
||||
foreach ($broTypes as $key => $value) {
|
||||
|
|
|
@ -517,7 +517,7 @@
|
|||
</div>
|
||||
<div id="correlationgraph_div" class="info_container_eventgraph_network" style="display: none;" data-fullscreen="false">
|
||||
</div>
|
||||
<div id="attackmatrix_div" class="info_container_eventgraph_network" style="display: none;" data-fullscreen="false" data-mitre-attack-galaxy-id="<?php echo h($mitreAttackGalaxyId)?>">
|
||||
<div id="attackmatrix_div" class="info_container_eventgraph_network" style="display: none;" data-fullscreen="false">
|
||||
</div>
|
||||
<div id="eventreport_div" style="display: none;">
|
||||
<span class="report-title-section"><?php echo __('Event Reports');?></span>
|
||||
|
@ -560,7 +560,7 @@ function enable_correlation_graph() {
|
|||
}
|
||||
|
||||
function enable_attack_matrix() {
|
||||
$.get("<?php echo $baseurl; ?>/events/viewGalaxyMatrix/<?php echo h($event['Event']['id']); ?>/<?php echo h($mitreAttackGalaxyId); ?>/event/1", function(data) {
|
||||
$.get("<?php echo $baseurl; ?>/events/viewGalaxyMatrix/<?php echo h($event['Event']['id']); ?>/mitre-attack/event/1", function(data) {
|
||||
$("#attackmatrix_div").html(data);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?= Configure::read('Config.language') === 'eng' ? 'en' : Configure::read('Config.language') ?>">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<?php echo $this->Html->charset(); ?>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>
|
||||
<?php echo $title_for_layout, ' - '. h(Configure::read('MISP.title_text') ? Configure::read('MISP.title_text') : 'MISP'); ?>
|
||||
</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title><?= $title_for_layout, ' - ', h(Configure::read('MISP.title_text') ?: 'MISP') ?></title>
|
||||
<?php
|
||||
$css_collection = array(
|
||||
'bootstrap',
|
||||
|
@ -35,7 +33,6 @@
|
|||
'meta' => 'icon'
|
||||
));
|
||||
?>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="popover_form" class="ajax_popover_form"></div>
|
||||
|
@ -96,7 +93,7 @@
|
|||
<?php
|
||||
if (!isset($debugMode)):
|
||||
?>
|
||||
$(window).scroll(function(e) {
|
||||
$(window).scroll(function() {
|
||||
$('.actions').css('left',-$(window).scrollLeft());
|
||||
});
|
||||
<?php
|
||||
|
@ -111,11 +108,10 @@
|
|||
echo $baseurl . '/' . h($this->params['controller']) . '/' . h($this->params['action']);
|
||||
}
|
||||
?>';
|
||||
$(document).ready(function(){
|
||||
$(function(){
|
||||
$(window).blur(function() {
|
||||
tabIsActive = false;
|
||||
});
|
||||
$(window).focus(function() {
|
||||
}).focus(function() {
|
||||
tabIsActive = true;
|
||||
});
|
||||
<?php
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
echo $this->Form->create('Object', array('class' => 'inline-form inline-field-form', 'id' => 'Object_' . $object['id'] . '_comment_form', 'url' => $baseurl . '/objects/editField/' . $object['id']));
|
||||
?>
|
||||
<div class='inline-input inline-input-container'>
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="<?php echo __('Accept change'); ?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="<?php echo __('Discard change'); ?>"></span></div>
|
||||
<div class="inline-input inline-input-container">
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class="fas fa-check" role="button" tabindex="0" aria-label="<?php echo __('Accept change'); ?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class="fas fa-times" role="button" tabindex="0" aria-label="<?php echo __('Discard change'); ?>"></span></div>
|
||||
<?php
|
||||
echo $this->Form->input('comment', array(
|
||||
'type' => 'textarea',
|
||||
|
@ -17,6 +17,3 @@
|
|||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
echo $this->Form->create('Object', array('class' => 'inline-form inline-field-form', 'id' => 'Object_' . $object['id'] . '_distribution_form', 'url' => '/objects/editField/' . $object['id']));
|
||||
?>
|
||||
<div class='inline-input inline-input-container'>
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" role="button" tabindex="0" aria-label="<?php echo __('Accept change'); ?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" role="button" tabindex="0" aria-label="<?php echo __('Discard change'); ?>"></span></div>
|
||||
<div class="inline-input inline-input-container">
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class="fas fa-check" role="button" tabindex="0" aria-label="<?php echo __('Accept change'); ?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class="fas fa-times" role="button" tabindex="0" aria-label="<?php echo __('Discard change'); ?>"></span></div>
|
||||
<?php
|
||||
echo $this->Form->input('distribution', array(
|
||||
'options' => array($distributionLevels),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
echo $this->Form->create('Server', array('class' => 'inline-form inline-field-form', 'url' => $baseurl . '/servers/serverSettingsEdit/' . $setting['setting'] . '/' . $id . '/' . '1', 'id' => 'setting_' . $subGroup . '_' . $id . '_form'));
|
||||
?>
|
||||
<div class='inline-input inline-input-container'>
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class = "icon-ok" title="<?php echo __('Accept');?>" role="button" tabindex="0" aria-label="<?php echo __('Accept');?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class = "icon-remove" title="<?php echo __('Cancel');?>" role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>"></span></div>
|
||||
<div class="inline-input inline-input-container">
|
||||
<div class="inline-input-accept inline-input-button inline-input-passive"><span class="fas fa-check" title="<?php echo __('Accept');?>" role="button" tabindex="0" aria-label="<?php echo __('Accept');?>"></span></div>
|
||||
<div class="inline-input-decline inline-input-button inline-input-passive"><span class="fas fa-times" title="<?php echo __('Cancel');?>" role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>"></span></div>
|
||||
<?php
|
||||
if (!empty($setting['redacted'])) {
|
||||
$setting['value'] = '*****';
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
top: 20,
|
||||
right: 60,
|
||||
bottom: 30,
|
||||
left: 25
|
||||
left: 40
|
||||
},
|
||||
width = 980 - margin.left - margin.right,
|
||||
height = 300 - margin.top - margin.bottom;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
"php-parallel-lint/php-parallel-lint": "^1.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Enabling the openssl extension allows you to access https URLs",
|
||||
"ext-redis": "For working background jobs and feed and warninglist chaches",
|
||||
"ext-zip": "Enabling processing feeds that are ZIP compressed",
|
||||
"ext-zlib": "Allow gzip compression of HTTP requests",
|
||||
"ext-intl": "For handling IDN domain names",
|
||||
"elasticsearch/elasticsearch": "For logging to elasticsearch",
|
||||
"aws/aws-sdk-php": "To upload samples to S3"
|
||||
},
|
||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
Subproject commit dce9d27ed612f2316866ebf1d2be113d67d17227
|
||||
Subproject commit b41e3d4f5037d0d325d38b2d5cf4f4bc94274cbc
|
|
@ -1,11 +1,12 @@
|
|||
/*!
|
||||
* Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com
|
||||
* Font Awesome Free 5.15.1 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
*/
|
||||
.fa,
|
||||
.fas,
|
||||
.far,
|
||||
.fal,
|
||||
.fad,
|
||||
.fab {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
@ -215,9 +216,6 @@ readers do not read off random characters that represent icons */
|
|||
.fa-adn:before {
|
||||
content: "\f170"; }
|
||||
|
||||
.fa-adobe:before {
|
||||
content: "\f778"; }
|
||||
|
||||
.fa-adversal:before {
|
||||
content: "\f36a"; }
|
||||
|
||||
|
@ -440,9 +438,24 @@ readers do not read off random characters that represent icons */
|
|||
.fa-bacon:before {
|
||||
content: "\f7e5"; }
|
||||
|
||||
.fa-bacteria:before {
|
||||
content: "\e059"; }
|
||||
|
||||
.fa-bacterium:before {
|
||||
content: "\e05a"; }
|
||||
|
||||
.fa-bahai:before {
|
||||
content: "\f666"; }
|
||||
|
||||
.fa-balance-scale:before {
|
||||
content: "\f24e"; }
|
||||
|
||||
.fa-balance-scale-left:before {
|
||||
content: "\f515"; }
|
||||
|
||||
.fa-balance-scale-right:before {
|
||||
content: "\f516"; }
|
||||
|
||||
.fa-ban:before {
|
||||
content: "\f05e"; }
|
||||
|
||||
|
@ -512,6 +525,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-bicycle:before {
|
||||
content: "\f206"; }
|
||||
|
||||
.fa-biking:before {
|
||||
content: "\f84a"; }
|
||||
|
||||
.fa-bimobject:before {
|
||||
content: "\f378"; }
|
||||
|
||||
|
@ -599,6 +615,15 @@ readers do not read off random characters that represent icons */
|
|||
.fa-bootstrap:before {
|
||||
content: "\f836"; }
|
||||
|
||||
.fa-border-all:before {
|
||||
content: "\f84c"; }
|
||||
|
||||
.fa-border-none:before {
|
||||
content: "\f850"; }
|
||||
|
||||
.fa-border-style:before {
|
||||
content: "\f853"; }
|
||||
|
||||
.fa-bowling-ball:before {
|
||||
content: "\f436"; }
|
||||
|
||||
|
@ -608,6 +633,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-box-open:before {
|
||||
content: "\f49e"; }
|
||||
|
||||
.fa-box-tissue:before {
|
||||
content: "\e05b"; }
|
||||
|
||||
.fa-boxes:before {
|
||||
content: "\f468"; }
|
||||
|
||||
|
@ -668,6 +696,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-business-time:before {
|
||||
content: "\f64a"; }
|
||||
|
||||
.fa-buy-n-large:before {
|
||||
content: "\f8a6"; }
|
||||
|
||||
.fa-buysellads:before {
|
||||
content: "\f20d"; }
|
||||
|
||||
|
@ -734,6 +765,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-car-side:before {
|
||||
content: "\f5e4"; }
|
||||
|
||||
.fa-caravan:before {
|
||||
content: "\f8ff"; }
|
||||
|
||||
.fa-caret-down:before {
|
||||
content: "\f0d7"; }
|
||||
|
||||
|
@ -971,6 +1005,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-cloud-upload-alt:before {
|
||||
content: "\f382"; }
|
||||
|
||||
.fa-cloudflare:before {
|
||||
content: "\e07d"; }
|
||||
|
||||
.fa-cloudscale:before {
|
||||
content: "\f383"; }
|
||||
|
||||
|
@ -1043,6 +1080,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-compress:before {
|
||||
content: "\f066"; }
|
||||
|
||||
.fa-compress-alt:before {
|
||||
content: "\f422"; }
|
||||
|
||||
.fa-compress-arrows-alt:before {
|
||||
content: "\f78c"; }
|
||||
|
||||
|
@ -1070,6 +1110,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-copyright:before {
|
||||
content: "\f1f9"; }
|
||||
|
||||
.fa-cotton-bureau:before {
|
||||
content: "\f89e"; }
|
||||
|
||||
.fa-couch:before {
|
||||
content: "\f4b8"; }
|
||||
|
||||
|
@ -1169,6 +1212,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-d-and-d-beyond:before {
|
||||
content: "\f6ca"; }
|
||||
|
||||
.fa-dailymotion:before {
|
||||
content: "\e052"; }
|
||||
|
||||
.fa-dashcube:before {
|
||||
content: "\f210"; }
|
||||
|
||||
|
@ -1178,6 +1224,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-deaf:before {
|
||||
content: "\f2a4"; }
|
||||
|
||||
.fa-deezer:before {
|
||||
content: "\e077"; }
|
||||
|
||||
.fa-delicious:before {
|
||||
content: "\f1a5"; }
|
||||
|
||||
|
@ -1256,6 +1305,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-discourse:before {
|
||||
content: "\f393"; }
|
||||
|
||||
.fa-disease:before {
|
||||
content: "\f7fa"; }
|
||||
|
||||
.fa-divide:before {
|
||||
content: "\f529"; }
|
||||
|
||||
|
@ -1358,6 +1410,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-edge:before {
|
||||
content: "\f282"; }
|
||||
|
||||
.fa-edge-legacy:before {
|
||||
content: "\e078"; }
|
||||
|
||||
.fa-edit:before {
|
||||
content: "\f044"; }
|
||||
|
||||
|
@ -1439,6 +1494,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-expand:before {
|
||||
content: "\f065"; }
|
||||
|
||||
.fa-expand-alt:before {
|
||||
content: "\f424"; }
|
||||
|
||||
.fa-expand-arrows-alt:before {
|
||||
content: "\f31e"; }
|
||||
|
||||
|
@ -1472,6 +1530,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-facebook-square:before {
|
||||
content: "\f082"; }
|
||||
|
||||
.fa-fan:before {
|
||||
content: "\f863"; }
|
||||
|
||||
.fa-fantasy-flight-games:before {
|
||||
content: "\f6dc"; }
|
||||
|
||||
|
@ -1481,6 +1542,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-fast-forward:before {
|
||||
content: "\f050"; }
|
||||
|
||||
.fa-faucet:before {
|
||||
content: "\e005"; }
|
||||
|
||||
.fa-fax:before {
|
||||
content: "\f1ac"; }
|
||||
|
||||
|
@ -1601,6 +1665,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-firefox:before {
|
||||
content: "\f269"; }
|
||||
|
||||
.fa-firefox-browser:before {
|
||||
content: "\e007"; }
|
||||
|
||||
.fa-first-aid:before {
|
||||
content: "\f479"; }
|
||||
|
||||
|
@ -1838,6 +1905,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-google-drive:before {
|
||||
content: "\f3aa"; }
|
||||
|
||||
.fa-google-pay:before {
|
||||
content: "\e079"; }
|
||||
|
||||
.fa-google-play:before {
|
||||
content: "\f3ab"; }
|
||||
|
||||
|
@ -1931,6 +2001,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-grunt:before {
|
||||
content: "\f3ad"; }
|
||||
|
||||
.fa-guilded:before {
|
||||
content: "\e07e"; }
|
||||
|
||||
.fa-guitar:before {
|
||||
content: "\f7a6"; }
|
||||
|
||||
|
@ -1964,9 +2037,15 @@ readers do not read off random characters that represent icons */
|
|||
.fa-hand-holding-heart:before {
|
||||
content: "\f4be"; }
|
||||
|
||||
.fa-hand-holding-medical:before {
|
||||
content: "\e05c"; }
|
||||
|
||||
.fa-hand-holding-usd:before {
|
||||
content: "\f4c0"; }
|
||||
|
||||
.fa-hand-holding-water:before {
|
||||
content: "\f4c1"; }
|
||||
|
||||
.fa-hand-lizard:before {
|
||||
content: "\f258"; }
|
||||
|
||||
|
@ -2000,6 +2079,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-hand-scissors:before {
|
||||
content: "\f257"; }
|
||||
|
||||
.fa-hand-sparkles:before {
|
||||
content: "\e05d"; }
|
||||
|
||||
.fa-hand-spock:before {
|
||||
content: "\f259"; }
|
||||
|
||||
|
@ -2009,9 +2091,18 @@ readers do not read off random characters that represent icons */
|
|||
.fa-hands-helping:before {
|
||||
content: "\f4c4"; }
|
||||
|
||||
.fa-hands-wash:before {
|
||||
content: "\e05e"; }
|
||||
|
||||
.fa-handshake:before {
|
||||
content: "\f2b5"; }
|
||||
|
||||
.fa-handshake-alt-slash:before {
|
||||
content: "\e05f"; }
|
||||
|
||||
.fa-handshake-slash:before {
|
||||
content: "\e060"; }
|
||||
|
||||
.fa-hanukiah:before {
|
||||
content: "\f6e6"; }
|
||||
|
||||
|
@ -2021,15 +2112,30 @@ readers do not read off random characters that represent icons */
|
|||
.fa-hashtag:before {
|
||||
content: "\f292"; }
|
||||
|
||||
.fa-hat-cowboy:before {
|
||||
content: "\f8c0"; }
|
||||
|
||||
.fa-hat-cowboy-side:before {
|
||||
content: "\f8c1"; }
|
||||
|
||||
.fa-hat-wizard:before {
|
||||
content: "\f6e8"; }
|
||||
|
||||
.fa-haykal:before {
|
||||
content: "\f666"; }
|
||||
|
||||
.fa-hdd:before {
|
||||
content: "\f0a0"; }
|
||||
|
||||
.fa-head-side-cough:before {
|
||||
content: "\e061"; }
|
||||
|
||||
.fa-head-side-cough-slash:before {
|
||||
content: "\e062"; }
|
||||
|
||||
.fa-head-side-mask:before {
|
||||
content: "\e063"; }
|
||||
|
||||
.fa-head-side-virus:before {
|
||||
content: "\e064"; }
|
||||
|
||||
.fa-heading:before {
|
||||
content: "\f1dc"; }
|
||||
|
||||
|
@ -2072,6 +2178,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-history:before {
|
||||
content: "\f1da"; }
|
||||
|
||||
.fa-hive:before {
|
||||
content: "\e07f"; }
|
||||
|
||||
.fa-hockey-puck:before {
|
||||
content: "\f453"; }
|
||||
|
||||
|
@ -2102,6 +2211,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-hospital-symbol:before {
|
||||
content: "\f47e"; }
|
||||
|
||||
.fa-hospital-user:before {
|
||||
content: "\f80d"; }
|
||||
|
||||
.fa-hot-tub:before {
|
||||
content: "\f593"; }
|
||||
|
||||
|
@ -2129,6 +2241,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-house-damage:before {
|
||||
content: "\f6f1"; }
|
||||
|
||||
.fa-house-user:before {
|
||||
content: "\e065"; }
|
||||
|
||||
.fa-houzz:before {
|
||||
content: "\f27c"; }
|
||||
|
||||
|
@ -2150,6 +2265,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-icicles:before {
|
||||
content: "\f7ad"; }
|
||||
|
||||
.fa-icons:before {
|
||||
content: "\f86d"; }
|
||||
|
||||
.fa-id-badge:before {
|
||||
content: "\f2c1"; }
|
||||
|
||||
|
@ -2159,6 +2277,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-id-card-alt:before {
|
||||
content: "\f47f"; }
|
||||
|
||||
.fa-ideal:before {
|
||||
content: "\e013"; }
|
||||
|
||||
.fa-igloo:before {
|
||||
content: "\f7ae"; }
|
||||
|
||||
|
@ -2189,9 +2310,18 @@ readers do not read off random characters that represent icons */
|
|||
.fa-info-circle:before {
|
||||
content: "\f05a"; }
|
||||
|
||||
.fa-innosoft:before {
|
||||
content: "\e080"; }
|
||||
|
||||
.fa-instagram:before {
|
||||
content: "\f16d"; }
|
||||
|
||||
.fa-instagram-square:before {
|
||||
content: "\e055"; }
|
||||
|
||||
.fa-instalod:before {
|
||||
content: "\e081"; }
|
||||
|
||||
.fa-intercom:before {
|
||||
content: "\f7af"; }
|
||||
|
||||
|
@ -2306,6 +2436,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-laptop-code:before {
|
||||
content: "\f5fc"; }
|
||||
|
||||
.fa-laptop-house:before {
|
||||
content: "\e066"; }
|
||||
|
||||
.fa-laptop-medical:before {
|
||||
content: "\f812"; }
|
||||
|
||||
|
@ -2423,6 +2556,12 @@ readers do not read off random characters that represent icons */
|
|||
.fa-luggage-cart:before {
|
||||
content: "\f59d"; }
|
||||
|
||||
.fa-lungs:before {
|
||||
content: "\f604"; }
|
||||
|
||||
.fa-lungs-virus:before {
|
||||
content: "\e067"; }
|
||||
|
||||
.fa-lyft:before {
|
||||
content: "\f3c3"; }
|
||||
|
||||
|
@ -2498,6 +2637,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-maxcdn:before {
|
||||
content: "\f136"; }
|
||||
|
||||
.fa-mdb:before {
|
||||
content: "\f8ca"; }
|
||||
|
||||
.fa-medal:before {
|
||||
content: "\f5a2"; }
|
||||
|
||||
|
@ -2546,6 +2688,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-meteor:before {
|
||||
content: "\f753"; }
|
||||
|
||||
.fa-microblog:before {
|
||||
content: "\e01a"; }
|
||||
|
||||
.fa-microchip:before {
|
||||
content: "\f2db"; }
|
||||
|
||||
|
@ -2585,6 +2730,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-mixcloud:before {
|
||||
content: "\f289"; }
|
||||
|
||||
.fa-mixer:before {
|
||||
content: "\e056"; }
|
||||
|
||||
.fa-mizuni:before {
|
||||
content: "\f3cc"; }
|
||||
|
||||
|
@ -2636,6 +2784,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-mountain:before {
|
||||
content: "\f6fc"; }
|
||||
|
||||
.fa-mouse:before {
|
||||
content: "\f8cc"; }
|
||||
|
||||
.fa-mouse-pointer:before {
|
||||
content: "\f245"; }
|
||||
|
||||
|
@ -2663,9 +2814,6 @@ readers do not read off random characters that represent icons */
|
|||
.fa-nimblr:before {
|
||||
content: "\f5a8"; }
|
||||
|
||||
.fa-nintendo-switch:before {
|
||||
content: "\f418"; }
|
||||
|
||||
.fa-node:before {
|
||||
content: "\f419"; }
|
||||
|
||||
|
@ -2693,6 +2841,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-object-ungroup:before {
|
||||
content: "\f248"; }
|
||||
|
||||
.fa-octopus-deploy:before {
|
||||
content: "\e082"; }
|
||||
|
||||
.fa-odnoklassniki:before {
|
||||
content: "\f263"; }
|
||||
|
||||
|
@ -2720,6 +2871,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-optin-monster:before {
|
||||
content: "\f23c"; }
|
||||
|
||||
.fa-orcid:before {
|
||||
content: "\f8d2"; }
|
||||
|
||||
.fa-osi:before {
|
||||
content: "\f41a"; }
|
||||
|
||||
|
@ -2819,12 +2973,18 @@ readers do not read off random characters that represent icons */
|
|||
.fa-penny-arcade:before {
|
||||
content: "\f704"; }
|
||||
|
||||
.fa-people-arrows:before {
|
||||
content: "\e068"; }
|
||||
|
||||
.fa-people-carry:before {
|
||||
content: "\f4ce"; }
|
||||
|
||||
.fa-pepper-hot:before {
|
||||
content: "\f816"; }
|
||||
|
||||
.fa-perbyte:before {
|
||||
content: "\e083"; }
|
||||
|
||||
.fa-percent:before {
|
||||
content: "\f295"; }
|
||||
|
||||
|
@ -2849,15 +3009,24 @@ readers do not read off random characters that represent icons */
|
|||
.fa-phone:before {
|
||||
content: "\f095"; }
|
||||
|
||||
.fa-phone-alt:before {
|
||||
content: "\f879"; }
|
||||
|
||||
.fa-phone-slash:before {
|
||||
content: "\f3dd"; }
|
||||
|
||||
.fa-phone-square:before {
|
||||
content: "\f098"; }
|
||||
|
||||
.fa-phone-square-alt:before {
|
||||
content: "\f87b"; }
|
||||
|
||||
.fa-phone-volume:before {
|
||||
content: "\f2a0"; }
|
||||
|
||||
.fa-photo-video:before {
|
||||
content: "\f87c"; }
|
||||
|
||||
.fa-php:before {
|
||||
content: "\f457"; }
|
||||
|
||||
|
@ -2873,6 +3042,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-pied-piper-pp:before {
|
||||
content: "\f1a7"; }
|
||||
|
||||
.fa-pied-piper-square:before {
|
||||
content: "\e01e"; }
|
||||
|
||||
.fa-piggy-bank:before {
|
||||
content: "\f4d3"; }
|
||||
|
||||
|
@ -2903,6 +3075,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-plane-departure:before {
|
||||
content: "\f5b0"; }
|
||||
|
||||
.fa-plane-slash:before {
|
||||
content: "\e069"; }
|
||||
|
||||
.fa-play:before {
|
||||
content: "\f04b"; }
|
||||
|
||||
|
@ -2978,6 +3153,12 @@ readers do not read off random characters that represent icons */
|
|||
.fa-project-diagram:before {
|
||||
content: "\f542"; }
|
||||
|
||||
.fa-pump-medical:before {
|
||||
content: "\e06a"; }
|
||||
|
||||
.fa-pump-soap:before {
|
||||
content: "\e06b"; }
|
||||
|
||||
.fa-pushed:before {
|
||||
content: "\f3e1"; }
|
||||
|
||||
|
@ -3053,6 +3234,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-receipt:before {
|
||||
content: "\f543"; }
|
||||
|
||||
.fa-record-vinyl:before {
|
||||
content: "\f8d9"; }
|
||||
|
||||
.fa-recycle:before {
|
||||
content: "\f1b8"; }
|
||||
|
||||
|
@ -3080,6 +3264,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-registered:before {
|
||||
content: "\f25d"; }
|
||||
|
||||
.fa-remove-format:before {
|
||||
content: "\f87d"; }
|
||||
|
||||
.fa-renren:before {
|
||||
content: "\f18b"; }
|
||||
|
||||
|
@ -3161,6 +3348,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-rupee-sign:before {
|
||||
content: "\f156"; }
|
||||
|
||||
.fa-rust:before {
|
||||
content: "\e07a"; }
|
||||
|
||||
.fa-sad-cry:before {
|
||||
content: "\f5b3"; }
|
||||
|
||||
|
@ -3257,6 +3447,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-shield-alt:before {
|
||||
content: "\f3ed"; }
|
||||
|
||||
.fa-shield-virus:before {
|
||||
content: "\e06c"; }
|
||||
|
||||
.fa-ship:before {
|
||||
content: "\f21a"; }
|
||||
|
||||
|
@ -3269,6 +3462,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-shoe-prints:before {
|
||||
content: "\f54b"; }
|
||||
|
||||
.fa-shopify:before {
|
||||
content: "\e057"; }
|
||||
|
||||
.fa-shopping-bag:before {
|
||||
content: "\f290"; }
|
||||
|
||||
|
@ -3311,6 +3507,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-simplybuilt:before {
|
||||
content: "\f215"; }
|
||||
|
||||
.fa-sink:before {
|
||||
content: "\e06d"; }
|
||||
|
||||
.fa-sistrix:before {
|
||||
content: "\f3ee"; }
|
||||
|
||||
|
@ -3404,6 +3603,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-snowplow:before {
|
||||
content: "\f7d2"; }
|
||||
|
||||
.fa-soap:before {
|
||||
content: "\e06e"; }
|
||||
|
||||
.fa-socks:before {
|
||||
content: "\f696"; }
|
||||
|
||||
|
@ -3416,24 +3618,42 @@ readers do not read off random characters that represent icons */
|
|||
.fa-sort-alpha-down:before {
|
||||
content: "\f15d"; }
|
||||
|
||||
.fa-sort-alpha-down-alt:before {
|
||||
content: "\f881"; }
|
||||
|
||||
.fa-sort-alpha-up:before {
|
||||
content: "\f15e"; }
|
||||
|
||||
.fa-sort-alpha-up-alt:before {
|
||||
content: "\f882"; }
|
||||
|
||||
.fa-sort-amount-down:before {
|
||||
content: "\f160"; }
|
||||
|
||||
.fa-sort-amount-down-alt:before {
|
||||
content: "\f884"; }
|
||||
|
||||
.fa-sort-amount-up:before {
|
||||
content: "\f161"; }
|
||||
|
||||
.fa-sort-amount-up-alt:before {
|
||||
content: "\f885"; }
|
||||
|
||||
.fa-sort-down:before {
|
||||
content: "\f0dd"; }
|
||||
|
||||
.fa-sort-numeric-down:before {
|
||||
content: "\f162"; }
|
||||
|
||||
.fa-sort-numeric-down-alt:before {
|
||||
content: "\f886"; }
|
||||
|
||||
.fa-sort-numeric-up:before {
|
||||
content: "\f163"; }
|
||||
|
||||
.fa-sort-numeric-up-alt:before {
|
||||
content: "\f887"; }
|
||||
|
||||
.fa-sort-up:before {
|
||||
content: "\f0de"; }
|
||||
|
||||
|
@ -3455,6 +3675,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-speaker-deck:before {
|
||||
content: "\f83c"; }
|
||||
|
||||
.fa-spell-check:before {
|
||||
content: "\f891"; }
|
||||
|
||||
.fa-spider:before {
|
||||
content: "\f717"; }
|
||||
|
||||
|
@ -3548,12 +3771,21 @@ readers do not read off random characters that represent icons */
|
|||
.fa-stopwatch:before {
|
||||
content: "\f2f2"; }
|
||||
|
||||
.fa-stopwatch-20:before {
|
||||
content: "\e06f"; }
|
||||
|
||||
.fa-store:before {
|
||||
content: "\f54e"; }
|
||||
|
||||
.fa-store-alt:before {
|
||||
content: "\f54f"; }
|
||||
|
||||
.fa-store-alt-slash:before {
|
||||
content: "\e070"; }
|
||||
|
||||
.fa-store-slash:before {
|
||||
content: "\e071"; }
|
||||
|
||||
.fa-strava:before {
|
||||
content: "\f428"; }
|
||||
|
||||
|
@ -3617,6 +3849,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-swatchbook:before {
|
||||
content: "\f5c3"; }
|
||||
|
||||
.fa-swift:before {
|
||||
content: "\f8e1"; }
|
||||
|
||||
.fa-swimmer:before {
|
||||
content: "\f5c4"; }
|
||||
|
||||
|
@ -3761,6 +3996,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-ticket-alt:before {
|
||||
content: "\f3ff"; }
|
||||
|
||||
.fa-tiktok:before {
|
||||
content: "\e07b"; }
|
||||
|
||||
.fa-times:before {
|
||||
content: "\f00d"; }
|
||||
|
||||
|
@ -3788,6 +4026,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-toilet-paper:before {
|
||||
content: "\f71e"; }
|
||||
|
||||
.fa-toilet-paper-slash:before {
|
||||
content: "\e072"; }
|
||||
|
||||
.fa-toolbox:before {
|
||||
content: "\f552"; }
|
||||
|
||||
|
@ -3815,6 +4056,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-traffic-light:before {
|
||||
content: "\f637"; }
|
||||
|
||||
.fa-trailer:before {
|
||||
content: "\e041"; }
|
||||
|
||||
.fa-train:before {
|
||||
content: "\f238"; }
|
||||
|
||||
|
@ -3902,12 +4146,18 @@ readers do not read off random characters that represent icons */
|
|||
.fa-uikit:before {
|
||||
content: "\f403"; }
|
||||
|
||||
.fa-umbraco:before {
|
||||
content: "\f8e8"; }
|
||||
|
||||
.fa-umbrella:before {
|
||||
content: "\f0e9"; }
|
||||
|
||||
.fa-umbrella-beach:before {
|
||||
content: "\f5ca"; }
|
||||
|
||||
.fa-uncharted:before {
|
||||
content: "\e084"; }
|
||||
|
||||
.fa-underline:before {
|
||||
content: "\f0cd"; }
|
||||
|
||||
|
@ -3920,6 +4170,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-uniregistry:before {
|
||||
content: "\f404"; }
|
||||
|
||||
.fa-unity:before {
|
||||
content: "\e049"; }
|
||||
|
||||
.fa-universal-access:before {
|
||||
content: "\f29a"; }
|
||||
|
||||
|
@ -3935,6 +4188,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-unlock-alt:before {
|
||||
content: "\f13e"; }
|
||||
|
||||
.fa-unsplash:before {
|
||||
content: "\e07c"; }
|
||||
|
||||
.fa-untappd:before {
|
||||
content: "\f405"; }
|
||||
|
||||
|
@ -4025,6 +4281,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-users-cog:before {
|
||||
content: "\f509"; }
|
||||
|
||||
.fa-users-slash:before {
|
||||
content: "\e073"; }
|
||||
|
||||
.fa-usps:before {
|
||||
content: "\f7e1"; }
|
||||
|
||||
|
@ -4052,6 +4311,12 @@ readers do not read off random characters that represent icons */
|
|||
.fa-venus-mars:before {
|
||||
content: "\f228"; }
|
||||
|
||||
.fa-vest:before {
|
||||
content: "\e085"; }
|
||||
|
||||
.fa-vest-patches:before {
|
||||
content: "\e086"; }
|
||||
|
||||
.fa-viacoin:before {
|
||||
content: "\f237"; }
|
||||
|
||||
|
@ -4091,12 +4356,24 @@ readers do not read off random characters that represent icons */
|
|||
.fa-vine:before {
|
||||
content: "\f1ca"; }
|
||||
|
||||
.fa-virus:before {
|
||||
content: "\e074"; }
|
||||
|
||||
.fa-virus-slash:before {
|
||||
content: "\e075"; }
|
||||
|
||||
.fa-viruses:before {
|
||||
content: "\e076"; }
|
||||
|
||||
.fa-vk:before {
|
||||
content: "\f189"; }
|
||||
|
||||
.fa-vnv:before {
|
||||
content: "\f40b"; }
|
||||
|
||||
.fa-voicemail:before {
|
||||
content: "\f897"; }
|
||||
|
||||
.fa-volleyball-ball:before {
|
||||
content: "\f45f"; }
|
||||
|
||||
|
@ -4130,6 +4407,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-warehouse:before {
|
||||
content: "\f494"; }
|
||||
|
||||
.fa-watchman-monitoring:before {
|
||||
content: "\e087"; }
|
||||
|
||||
.fa-water:before {
|
||||
content: "\f773"; }
|
||||
|
||||
|
@ -4205,6 +4485,9 @@ readers do not read off random characters that represent icons */
|
|||
.fa-wizards-of-the-coast:before {
|
||||
content: "\f730"; }
|
||||
|
||||
.fa-wodu:before {
|
||||
content: "\e088"; }
|
||||
|
||||
.fa-wolf-pack-battalion:before {
|
||||
content: "\f514"; }
|
||||
|
||||
|
|
|
@ -1297,7 +1297,8 @@ span.success {
|
|||
bottom:-17px;
|
||||
background-color: #fff;
|
||||
position:absolute;
|
||||
z-index:100;
|
||||
z-index:10;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.inline-input-active {
|
||||
|
@ -2379,7 +2380,7 @@ table tr:hover .down-expand-button {
|
|||
}
|
||||
|
||||
.strikethrough {
|
||||
text-decoration: line-through;
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
|
||||
.highlighted_node {
|
||||
|
@ -2601,7 +2602,7 @@ table tr:hover .down-expand-button {
|
|||
}
|
||||
|
||||
/* Threat levels */
|
||||
.threat-level-high::before, .threat-level-medium::before, .threat-level-low::before {
|
||||
.threat-level-high::before, .threat-level-medium::before, .threat-level-low::before, .threat-level-undefined::before {
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-weight: 900;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
@ -2629,6 +2630,11 @@ table tr:hover .down-expand-button {
|
|||
color: rgb(35,120,40);
|
||||
}
|
||||
|
||||
.threat-level-undefined::before {
|
||||
content: "\f128";
|
||||
color: gray;
|
||||
}
|
||||
|
||||
#UserGpgkey, #UserCertifPublic {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
font-size: 100%;
|
||||
|
|
|
@ -427,7 +427,7 @@ function updateIndex(id, context, newPage) {
|
|||
div = "#templateElements";
|
||||
}
|
||||
$.ajax({
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
beforeSend: function () {
|
||||
$(".loading").show();
|
||||
},
|
||||
dataType:"html",
|
||||
|
@ -452,15 +452,15 @@ function updateIndex(id, context, newPage) {
|
|||
|
||||
function updateAttributeFieldOnSuccess(name, type, id, field, event) {
|
||||
$.ajax({
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
if (field != 'timestamp') {
|
||||
beforeSend: function () {
|
||||
if (field !== 'timestamp') {
|
||||
$(".loading").show();
|
||||
}
|
||||
},
|
||||
dataType:"html",
|
||||
cache: false,
|
||||
success:function (data, textStatus) {
|
||||
if (field != 'timestamp') {
|
||||
if (field !== 'timestamp') {
|
||||
$(".loading").hide();
|
||||
$(name + '_solid').html(data);
|
||||
$(name + '_placeholder').empty();
|
||||
|
@ -468,6 +468,7 @@ function updateAttributeFieldOnSuccess(name, type, id, field, event) {
|
|||
} else {
|
||||
$('#' + type + '_' + id + '_' + 'timestamp_solid').html(data);
|
||||
}
|
||||
popoverStartup(); // reactive popovers
|
||||
},
|
||||
url: baseurl + "/attributes/fetchViewValue/" + id + "/" + field,
|
||||
});
|
||||
|
@ -793,7 +794,7 @@ function refreshTagCollectionRow(tag_collection_id) {
|
|||
|
||||
function handleAjaxEditResponse(data, name, type, id, field, event) {
|
||||
responseArray = data;
|
||||
if (type == 'Attribute') {
|
||||
if (type === 'Attribute') {
|
||||
if (responseArray.saved) {
|
||||
var msg = responseArray.success !== undefined ? responseArray.success : responseArray.message;
|
||||
showMessage('success', msg);
|
||||
|
@ -804,13 +805,11 @@ function handleAjaxEditResponse(data, name, type, id, field, event) {
|
|||
showMessage('fail', 'Validation failed: ' + responseArray.errors.value);
|
||||
updateAttributeFieldOnSuccess(name, type, id, field, event);
|
||||
}
|
||||
}
|
||||
if (type == 'ShadowAttribute') {
|
||||
} else if (type === 'ShadowAttribute') {
|
||||
updateIndex(event, 'event');
|
||||
} else if (type == 'Object') {
|
||||
} else if (type === 'Object') {
|
||||
if (responseArray.saved) {
|
||||
var msg = responseArray.success !== undefined ? responseArray.success : responseArray.message;
|
||||
showMessage('success', msg);
|
||||
showMessage('success', responseArray.message);
|
||||
updateObjectFieldOnSuccess(name, type, id, field, event);
|
||||
updateObjectFieldOnSuccess(name, type, id, 'timestamp', event);
|
||||
eventUnpublish();
|
||||
|
@ -982,7 +981,6 @@ function multiSelectAction(event, context) {
|
|||
var formData = $('#' + settings[context]["action"] + '_selected').serialize();
|
||||
if (context == 'deleteAttributes') {
|
||||
var url = $('#delete_selected').attr('action');
|
||||
console.log(url);
|
||||
} else {
|
||||
var url = baseurl + "/" + settings[context]["controller"] + "/" + settings[context]["action"] + "Selected/" + event;
|
||||
}
|
||||
|
@ -991,11 +989,20 @@ function multiSelectAction(event, context) {
|
|||
cache: false,
|
||||
type:"POST",
|
||||
url: url,
|
||||
success:function (data, textStatus) {
|
||||
beforeSend: function () {
|
||||
$(".loading").show();
|
||||
},
|
||||
success: function (data) {
|
||||
updateIndex(event, 'event');
|
||||
var result = handleGenericAjaxResponse(data);
|
||||
if (settings[context]["action"] != "discard" && result == true) eventUnpublish();
|
||||
if (settings[context]["action"] != "discard" && result == true) {
|
||||
eventUnpublish();
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
$(".loading").hide();
|
||||
},
|
||||
error: xhrFailCallback,
|
||||
});
|
||||
}
|
||||
return false;
|
||||
|
@ -2516,19 +2523,27 @@ function serverSettingsPostActivationScripts(name, setting, id) {
|
|||
}
|
||||
|
||||
function serverSettingSubmitForm(name, setting, id) {
|
||||
subGroup = getSubGroupFromSetting(setting);
|
||||
var subGroup = getSubGroupFromSetting(setting);
|
||||
var formData = $(name + '_field').closest("form").serialize();
|
||||
$.ajax({
|
||||
data: formData,
|
||||
cache: false,
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
beforeSend: function () {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
success: function (data) {
|
||||
if (!data.saved) {
|
||||
$(".loading").hide();
|
||||
showMessage('fail', data.errors);
|
||||
resetForms();
|
||||
$('.inline-field-placeholder').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "get",
|
||||
url: baseurl + "/servers/serverSettingsReloadSetting/" + setting + "/" + id,
|
||||
success:function (data2, textStatus2) {
|
||||
success: function (data2) {
|
||||
$('#' + subGroup + "_" + id + '_row').replaceWith(data2);
|
||||
$(".loading").hide();
|
||||
},
|
||||
|
@ -2538,6 +2553,7 @@ function serverSettingSubmitForm(name, setting, id) {
|
|||
});
|
||||
},
|
||||
error: function() {
|
||||
$(".loading").hide();
|
||||
showMessage('fail', 'Request failed for an unknown reason.');
|
||||
resetForms();
|
||||
$('.inline-field-placeholder').hide();
|
||||
|
@ -3298,21 +3314,50 @@ function testConnection(id) {
|
|||
$.ajax({
|
||||
url: baseurl + '/servers/testConnection/' + id,
|
||||
type: 'GET',
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
beforeSend: function () {
|
||||
$("#connection_test_" + id).html('Running test...');
|
||||
},
|
||||
error: function(){
|
||||
$("#connection_test_" + id).html('Internal error.');
|
||||
$("#connection_test_" + id).html('<span class="red bold">Internal error</span>');
|
||||
},
|
||||
success: function(response){
|
||||
var result = response;
|
||||
success: function(result) {
|
||||
function line(name, value, valid) {
|
||||
var $value = $('<span></span>').text(value);
|
||||
if (valid === true) {
|
||||
$value.addClass('green');
|
||||
} else if (valid === false) {
|
||||
$value.addClass('red');
|
||||
} else if (valid) {
|
||||
$value.addClass(valid);
|
||||
}
|
||||
return $('<div></div>').text(name + ': ').append($value).html() + '<br>';
|
||||
}
|
||||
|
||||
var html = '';
|
||||
|
||||
if (result.client_certificate) {
|
||||
var cert = result.client_certificate;
|
||||
html += '<span class="bold">Client certificate:</span><br>';
|
||||
if (cert.error) {
|
||||
html += '<span class="red bold">Error: ' + cert.error + '</span><br>';
|
||||
} else {
|
||||
html += line("Subject", cert.subject);
|
||||
html += line("Issuer", cert.issuer);
|
||||
html += line("Serial number", cert.serial_number);
|
||||
html += line("Valid from", cert.valid_from, cert.valid_from_ok);
|
||||
html += line("Valid to", cert.valid_to, cert.valid_to_ok);
|
||||
html += line("Public key", cert.public_key_type + ' (' + cert.public_key_size + ' bits)', cert.public_key_size_ok);
|
||||
}
|
||||
html += "<br>";
|
||||
}
|
||||
|
||||
switch (result.status) {
|
||||
case 1:
|
||||
status_message = "OK";
|
||||
compatibility = "Compatible";
|
||||
compatibility_colour = "green";
|
||||
colours = {'local': 'class="green"', 'remote': 'class="green"', 'status': 'class="green"'};
|
||||
issue_colour = "red";
|
||||
var status_message = "OK";
|
||||
var compatibility = "Compatible";
|
||||
var compatibility_colour = "green";
|
||||
var colours = {'local': 'class="green"', 'remote': 'class="green"', 'status': 'class="green"'};
|
||||
var issue_colour = "red";
|
||||
if (result.mismatch == "hotfix") issue_colour = "orange";
|
||||
if (result.newer == "local") {
|
||||
colours.remote = 'class="' + issue_colour + '"';
|
||||
|
@ -3338,6 +3383,7 @@ function testConnection(id) {
|
|||
else status_message = "Remote outdated, notify admin!"
|
||||
colours.status = 'class="' + issue_colour + '"';
|
||||
}
|
||||
var post_result;
|
||||
if (result.post != false) {
|
||||
var post_colour = "red";
|
||||
if (result.post == 1) {
|
||||
|
@ -3354,36 +3400,36 @@ function testConnection(id) {
|
|||
post_result = "Remote too old for this test";
|
||||
}
|
||||
}
|
||||
resultDiv = '<div>Local version: <span ' + colours.local + '>' + result.local_version + '</span><br />';
|
||||
resultDiv += '<div>Remote version: <span ' + colours.remote + '>' + result.version + '</span><br />';
|
||||
resultDiv += '<div>Status: <span ' + colours.status + '>' + status_message + '</span><br />';
|
||||
resultDiv += '<div>Compatiblity: <span class="' + compatibility_colour + '">' + compatibility + '</span><br />';
|
||||
resultDiv += '<div>POST test: <span class="' + post_colour + '">' + post_result + '</span><br />';
|
||||
$("#connection_test_" + id).html(resultDiv);
|
||||
//$("#connection_test_" + id).html('<span class="green bold" title="Connection established, correct response received.">OK</span>');
|
||||
html += line('Local version', result.local_version, colours.local);
|
||||
html += line('Remote version', result.version, colours.remote);
|
||||
html += line('Status', status_message, colours.status);
|
||||
html += line('Compatibility', compatibility, compatibility_colour);
|
||||
html += line('POST test', post_result, post_colour);
|
||||
break;
|
||||
case 2:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="There seems to be a connection issue. Make sure that the entered URL is correct and that the certificates are in order.">Server unreachable</span>');
|
||||
html += '<span class="red bold" title="There seems to be a connection issue. Make sure that the entered URL is correct and that the certificates are in order.">Server unreachable</span>';
|
||||
break;
|
||||
case 3:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="The server returned an unexpected result. Make sure that the provided URL (or certificate if it applies) are correct.">Unexpected error</span>');
|
||||
html += '<span class="red bold" title="The server returned an unexpected result. Make sure that the provided URL (or certificate if it applies) are correct.">Unexpected error</span>';
|
||||
break;
|
||||
case 4:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="Authentication failed due to incorrect authentication key or insufficient privileges on the remote instance.">Authentication failed</span>');
|
||||
html += '<span class="red bold" title="Authentication failed due to incorrect authentication key or insufficient privileges on the remote instance.">Authentication failed</span>';
|
||||
break;
|
||||
case 5:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="Authentication failed because the sync user is expected to change passwords. Log into the remote MISP to rectify this.">Password change required</span>');
|
||||
html += '<span class="red bold" title="Authentication failed because the sync user is expected to change passwords. Log into the remote MISP to rectify this.">Password change required</span>';
|
||||
break;
|
||||
case 6:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="Authentication failed because the sync user on the remote has not accepted the terms of use. Log into the remote MISP to rectify this.">Terms not accepted</span>');
|
||||
html += '<span class="red bold" title="Authentication failed because the sync user on the remote has not accepted the terms of use. Log into the remote MISP to rectify this.">Terms not accepted</span>';
|
||||
break;
|
||||
case 7:
|
||||
$("#connection_test_" + id).html('<span class="red bold" title="The user account on the remote instance is not a sync user.">Remote user not a sync user</span>');
|
||||
html += '<span class="red bold" title="The user account on the remote instance is not a sync user.">Remote user not a sync user</span>';
|
||||
break;
|
||||
case 8:
|
||||
$("#connection_test_" + id).html('<span class="orange bold" title="The user account on the remote instance is only a sightings user.">Remote user not a sync user, syncing sightings only</span>');
|
||||
html += '<span class="orange bold" title="The user account on the remote instance is only a sightings user.">Remote user not a sync user, syncing sightings only</span>';
|
||||
break;
|
||||
}
|
||||
|
||||
$("#connection_test_" + id).html(html);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 676 KiB After Width: | Height: | Size: 730 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,16 +1,12 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!--
|
||||
Font Awesome Free 5.8.2 by @fontawesome - https://fontawesome.com
|
||||
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
-->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<metadata>
|
||||
Created by FontForge 20190112 at Tue May 7 11:33:43 2019
|
||||
Created by FontForge 20200314 at Mon Oct 5 09:50:45 2020
|
||||
By Robert Madole
|
||||
Copyright (c) Font Awesome
|
||||
</metadata>
|
||||
<defs>
|
||||
<!-- Font Awesome Free 5.15.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
|
||||
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
|
||||
<font-face
|
||||
font-family="Font Awesome 5 Free Regular"
|
||||
|
@ -20,9 +16,9 @@ Copyright (c) Font Awesome
|
|||
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||
ascent="448"
|
||||
descent="-64"
|
||||
bbox="-0.0663408 -64.0662 640.01 448.1"
|
||||
bbox="-0.0663408 -64.0662 640.004 448.1"
|
||||
underline-thickness="25"
|
||||
underline-position="-51"
|
||||
underline-position="-50"
|
||||
unicode-range="U+0020-F5C8"
|
||||
/>
|
||||
<missing-glyph />
|
||||
|
@ -50,7 +46,7 @@ s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.
|
|||
<glyph glyph-name="flag" unicode=""
|
||||
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
|
||||
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.177734 -1.52441 0.321289 -4.00781 0.321289 -5.54199c0 -4.30176 -1.10352 -11.1035 -2.46289 -15.1846c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.213867 -1.83398 0.308594 -3.65918 0.308594 -5.5498c0 -5.30273 -0.860352 -10.4053 -2.4502 -15.1768c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
|
||||
<glyph glyph-name="bookmark" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
|
||||
|
@ -77,17 +73,17 @@ c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72
|
|||
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
|
||||
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
|
||||
<glyph glyph-name="eye" unicode="" horiz-adv-x="576"
|
||||
d="M288 304c0.0927734 0 0.244141 0.000976562 0.336914 0.000976562c61.6641 0 111.71 -50.0469 111.71 -111.711c0 -61.6631 -50.0459 -111.71 -111.71 -111.71s-111.71 50.0469 -111.71 111.71c0 8.71289 1.95898 22.5781 4.37305 30.9502
|
||||
c6.93066 -3.94141 19.0273 -7.18457 27 -7.24023c30.9121 0 56 25.0879 56 56c-0.0556641 7.97266 -3.29883 20.0693 -7.24023 27c8.42383 2.62207 22.4189 4.8623 31.2402 5zM572.52 206.6c1.9209 -3.79883 3.47949 -10.3379 3.47949 -14.5947
|
||||
s-1.55859 -10.7959 -3.47949 -14.5947c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c54.1992 105.771 161.59 177.41 284.52 177.41
|
||||
s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
d="M288 304c0.114258 0 0.240234 -0.0175781 0.354492 -0.0175781c61.6543 0 111.71 -50.0557 111.71 -111.71s-50.0557 -111.71 -111.71 -111.71s-111.71 50.0557 -111.71 111.71c0 10.7422 1.51953 21.1328 4.35547 30.9678
|
||||
c7.95898 -4.52637 17.2129 -7.17188 27 -7.24023c30.9072 0 56 25.0928 56 56c-0.0683594 9.78711 -2.71387 19.041 -7.24023 27c9.88379 3.07617 20.3896 4.83008 31.2402 5zM572.52 206.6c2.21387 -4.37793 3.46094 -9.38965 3.46094 -14.626
|
||||
c0 -5.2373 -1.24707 -10.1855 -3.46094 -14.5635c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635
|
||||
c54.1992 105.771 161.59 177.41 284.52 177.41s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="eye-slash" unicode="" horiz-adv-x="640"
|
||||
d="M634 -23c3.31738 -2.65137 6.00977 -8.25098 6.00977 -12.498c0 -3.10449 -1.57715 -7.58984 -3.51953 -10.0117l-10 -12.4902c-2.65234 -3.31152 -8.24707 -6 -12.4902 -6c-3.09961 0 -7.58008 1.57227 -10 3.50977l-598 467.49
|
||||
c-3.31738 2.65137 -6.00977 8.25098 -6.00977 12.498c0 3.10449 1.57715 7.58984 3.51953 10.0117l10 12.4902c2.65234 3.31152 8.24707 6 12.4902 6c3.09961 0 7.58008 -1.57227 10 -3.50977zM296.79 301.53c6.33496 1.35059 16.7324 2.45801 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-6.33496 -1.34375 -16.7334 -2.44629 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c1.91992 -3.79883 3.47949 -10.3379 3.47949 -14.5947s-1.55957 -10.7959 -3.47949 -14.5947c-11.7197 -22.7598 -35.4189 -56.4092 -52.9004 -75.1104l-37.7402 29.5
|
||||
c14.333 15.0156 34.0449 41.9854 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-1.9209 3.79883 -3.47949 10.3379 -3.47949 14.5947s1.55859 10.7959 3.47949 14.5947c11.7168 22.7568 35.4111 56.4014 52.8896 75.1006l37.7402 -29.5c-14.3467 -15.0107 -34.0811 -41.9756 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
d="M634 -23c3.66895 -2.93262 6.00391 -7.45117 6.00391 -12.5088c0 -3.7832 -1.31543 -7.26074 -3.51367 -10.001l-10 -12.4902c-2.93359 -3.66309 -7.44824 -5.99414 -12.502 -5.99414c-3.77637 0 -7.25 1.31152 -9.98828 3.50391l-598 467.49
|
||||
c-3.66895 2.93262 -6.00391 7.45117 -6.00391 12.5088c0 3.7832 1.31543 7.26074 3.51367 10.001l10 12.4902c2.93359 3.66309 7.44824 5.99414 12.502 5.99414c3.77637 0 7.25 -1.31152 9.98828 -3.50391zM296.79 301.53c7.51172 1.60254 15.2266 2.45508 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-7.51367 -1.59375 -15.2285 -2.44336 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c2.21289 -4.37793 3.45996 -9.38965 3.45996 -14.626c0 -5.2373 -1.24707 -10.1855 -3.45996 -14.5635c-14.1924 -27.5625 -31.9229 -52.6689 -52.9004 -75.1104l-37.7402 29.5
|
||||
c17.2305 18.0527 31.9385 38.1318 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635c14.1885 27.5586 31.916 52.6621 52.8896 75.1006l37.7402 -29.5c-17.249 -18.0469 -31.9727 -38.1221 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="calendar-alt" unicode="" horiz-adv-x="448"
|
||||
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
|
||||
|
@ -131,47 +127,47 @@ d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.099
|
|||
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="hdd" unicode="" horiz-adv-x="576"
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 8.30957 3.85156 20.5898 8.59668 27.4121l105.08 151.053
|
||||
c7.90625 11.3652 25.5596 20.5889 39.4033 20.5889h0.000976562h269.838h0.000976562c13.8438 0 31.4971 -9.22363 39.4033 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32
|
||||
s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 10.167 3.19531 19.6465 8.59668 27.4121l105.08 151.053
|
||||
c8.67383 12.4678 23.0791 20.5889 39.4043 20.5889h269.838c16.3252 0 30.7305 -8.12109 39.4043 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32
|
||||
s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
<glyph glyph-name="hand-point-right" unicode=""
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.41602 -6.36719 -4.96875 -16.252 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.71387 -7.70605 -4.43555 -15.2051 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
|
||||
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
|
||||
v-0.0839844c0 -6.21777 -0.974609 -16.2148 -2.17578 -22.3154h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994c0 26.4004 -20.625 35.2002 -44 35.2002
|
||||
c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c0 -0.0283203 0 0.0361328 0 0.0078125c0 -7.66602 -0.748047 -15.1582 -2.17578 -22.4072h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994
|
||||
c0 26.4004 -20.625 35.2002 -44 35.2002c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="hand-point-left" unicode=""
|
||||
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
|
||||
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-2.96094 5.8125 -6.51367 15.6973 -7.92969 22.0645h-35.6465
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-3.49414 6.85938 -6.21582 14.3584 -7.92969 22.0645h-35.6465
|
||||
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
|
||||
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
|
||||
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
|
||||
s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-up" unicode="" horiz-adv-x="448"
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c6.36719 -1.41602 16.252 -4.96875 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c7.70605 -1.71387 15.2051 -4.43555 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
|
||||
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
|
||||
c0 56.9277 35.2861 92 83.2002 92h0.0839844c6.21777 0 16.2148 -0.974609 22.3154 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994
|
||||
c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988
|
||||
c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
c0 56.9277 35.2861 92 83.2002 92c0.0283203 0 -0.0361328 0 -0.0078125 0c7.66602 0 15.1582 -0.748047 22.4072 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399
|
||||
c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753
|
||||
c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24
|
||||
s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-down" unicode="" horiz-adv-x="448"
|
||||
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
|
||||
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-5.8125 -2.96094 -15.6973 -6.51367 -22.0645 -7.92969v-35.6465
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-6.85938 -3.49414 -14.3584 -6.21582 -22.0645 -7.92969v-35.6465
|
||||
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
|
||||
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
|
||||
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
|
||||
<glyph glyph-name="copy" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 382.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184
|
||||
v-64h64z" />
|
||||
d="M433.941 382.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184v-64h64z" />
|
||||
<glyph glyph-name="save" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 318.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM272 368h-128v-80h128v80
|
||||
zM394 16c3.31152 0 6 2.68848 6 6v259.632v0.000976562c0 1.37207 -0.787109 3.27246 -1.75684 4.24219l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340
|
||||
c0 -3.31152 2.68848 -6 6 -6h340zM224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
d="M433.941 318.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM272 368h-128v-80h128v80z
|
||||
M394 16c3.31152 0 6 2.68848 6 6v259.632c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340z
|
||||
M224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
<glyph glyph-name="square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="envelope" unicode=""
|
||||
|
@ -181,7 +177,7 @@ c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.205
|
|||
<glyph glyph-name="lightbulb" unicode="" horiz-adv-x="352"
|
||||
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
|
||||
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00390625 4.04199 0.999023 10.4482 2.21973 14.3008
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00488281 4.98145 0.790039 9.78809 2.21973 14.3008
|
||||
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
|
||||
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
|
||||
c0 93.0303 73.7197 176 176 176z" />
|
||||
|
@ -241,13 +237,13 @@ c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.
|
|||
<glyph glyph-name="share-square" unicode="" horiz-adv-x="576"
|
||||
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
|
||||
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c6.14844 1.75684 15.5449 5.92383 20.9736 9.30273
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c7.4375 2.125 14.5508 5.30566 20.9736 9.30273
|
||||
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.59668 -0.974609 -4.41016 -1.77051 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541
|
||||
z" />
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.82715 -1.11523 -3.98633 -1.76953 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541z
|
||||
" />
|
||||
<glyph glyph-name="compass" unicode="" horiz-adv-x="496"
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-2.73047 -5.97363 -9.7959 -13.0391 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c2.73047 5.97363 9.7959 13.0391 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-3.19238 -6.9834 -8.78613 -12.5771 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c3.19238 6.9834 8.78613 12.5771 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="caret-square-down" unicode="" horiz-adv-x="448"
|
||||
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
|
@ -287,7 +283,7 @@ l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9
|
|||
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
|
||||
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
|
||||
<glyph glyph-name="moon" unicode=""
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c13.0068 -0.00195312 33.9443 -1.91797 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c16.0342 -0.00292969 31.5078 -1.46875 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
|
||||
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
|
||||
<glyph glyph-name="caret-square-left" unicode="" horiz-adv-x="448"
|
||||
|
@ -334,12 +330,12 @@ c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -1
|
|||
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
|
||||
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
|
||||
<glyph glyph-name="file-audio" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
|
||||
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
|
||||
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
|
||||
<glyph glyph-name="file-video" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c7.75977 -7.75977 14.0586 -22.9658 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c10.9746 0 26.1807 -6.29883 33.9404 -14.0586zM332.118 320
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
|
||||
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
|
||||
<glyph glyph-name="file-code" unicode="" horiz-adv-x="384"
|
||||
|
@ -376,9 +372,9 @@ c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.33
|
|||
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="copyright" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.13379 -1.96289 3.86523 -5.9082 3.86523 -8.80762
|
||||
c0 -1.95508 -0.864258 -4.87402 -1.92969 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.28613 -1.74512 2.33008 -4.91992 2.33008 -7.08789c0 -2.72363 -1.56055 -6.5 -3.48242 -8.42969z" />
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.37793 -2.1875 3.86914 -5.3252 3.86914 -8.80762
|
||||
c0 -2.39746 -0.717773 -4.64258 -1.93359 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.45996 -1.98145 2.32422 -4.42969 2.32422 -7.07715c0 -3.28809 -1.32422 -6.2793 -3.47656 -8.44043z" />
|
||||
<glyph glyph-name="closed-captioning" unicode=""
|
||||
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
|
||||
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
|
||||
|
@ -398,7 +394,7 @@ c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c
|
|||
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
|
||||
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
|
||||
<glyph glyph-name="sticky-note" unicode="" horiz-adv-x="448"
|
||||
d="M448 99.8936c0 -10.9746 -6.29883 -26.1797 -14.0586 -33.9404l-83.8828 -83.8818c-7.75977 -7.76074 -22.9658 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
d="M448 99.8936c0 -13.2451 -5.37012 -25.252 -14.0586 -33.9404l-83.8828 -83.8818c-8.68848 -8.68848 -20.6943 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
|
||||
<glyph glyph-name="clone" unicode=""
|
||||
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
|
||||
|
@ -412,11 +408,11 @@ d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0
|
|||
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
|
||||
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83203 -7.16797 -16 -16 -16c-3.30664 0 -8.01367 1.7627 -10.5068 3.93359l-7 6.09473c-3.03223 2.64062 -5.49316 8.04688 -5.49316 12.0674v0v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c2.91602 6.75391 5.28223 18.207 5.28223 25.5635v0.0488281z" />
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83105 -7.17773 -15.9961 -16.0078 -15.9961c-4.0166 0 -7.68848 1.48242 -10.499 3.92969l-7 6.09473c-3.37012 2.93457 -5.49316 7.25293 -5.49316 12.0674v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c3.37891 7.82715 5.28223 16.501 5.28223 25.5625v0.0498047z" />
|
||||
<glyph glyph-name="hand-paper" unicode="" horiz-adv-x="448"
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00195312 -12.7666 -2.33008 -33.2246 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-9.10352 0 -20.7793 6.01758 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00292969 -15.7393 -1.80566 -30.9482 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-10.7539 0 -20.2588 5.28613 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
|
||||
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
|
||||
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
|
||||
|
@ -424,45 +420,46 @@ c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
|
|||
<glyph glyph-name="hand-scissors" unicode=""
|
||||
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
|
||||
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.23633 0 3.21777 0.225586 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.65039 -3.24512 -8.20215 -5.87891 -12.3926 -5.87891
|
||||
c-1.64062 0 -4.21484 0.477539 -5.74609 1.06738l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c5.66016 -2.17773 10.2539 -8.86816 10.2539 -14.9326v0v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.52441 0 2.99707 0.174805 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.93457 -3.59375 -7.40332 -5.87305 -12.4004 -5.87305
|
||||
c-2.02246 0 -3.95703 0.375977 -5.73828 1.06152l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c6 -2.30859 10.2539 -8.12402 10.2539 -14.9326v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
|
||||
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
|
||||
<glyph glyph-name="hand-lizard" unicode="" horiz-adv-x="576"
|
||||
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709v0.0478516c0 11.7461 -5.19141 29.2734 -11.5879 39.124l-146.358 225.715c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917
|
||||
c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8
|
||||
h131.552h0.0517578c7.44141 0 19.1074 -2.19238 26.041 -4.89355l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709c0 0.0166016 -0.0439453 0.106445 -0.0439453 0.12207c0 14.3945 -4.24219 27.8057 -11.5439 39.0498l-146.358 225.715
|
||||
c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709
|
||||
c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8h131.552c0.0175781 0 0.0712891 -0.0273438 0.0888672 -0.0273438c9.16992 0 17.9404 -1.72461 26.0039 -4.86621l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
<glyph glyph-name="hand-spock" unicode=""
|
||||
d="M21.0957 66.21c-26.9688 25.3818 -28.2471 67.7461 -2.87109 94.707c24.1982 25.7139 64.2881 28.2373 91.4824 5.72168l-31.04 136.509c-9.38379 41.2803 21.4336 81.0127 64.0713 81.8438c1.74414 28.9062 22.2656 54.4912 51.8818 61.2949
|
||||
c36.001 8.27539 72.0176 -14.2266 80.3037 -50.2959l21.6748 -131.99l16.9014 105.25c9.02344 36.0947 45.4473 57.7021 81.25 48.75c27.3066 -6.82715 45.7061 -29.1357 49.8496 -53.9922c43.2285 0.212891 75.6436 -40.1133 65.5439 -82.5244l-31.7295 -133.41
|
||||
c-0.938477 -3.94141 -1.41406 -7.99414 -1.41406 -12.0449v-36.8389v-0.00683594c0 -9.29102 -2.14355 -24.0596 -4.78516 -32.9668l-31.8145 -107.312c-4.02734 -13.585 -16.5107 -22.9043 -30.6807 -22.9043h-237.6c-7.00586 0 -16.8311 3.89648 -21.9316 8.69824z
|
||||
M53.1641 128.021c-7.17969 -7.62891 -6.81543 -19.6777 0.813477 -26.8574l124.487 -117.164h219.311l28.4199 95.8613c1.86133 6.27637 2.80469 12.7793 2.80469 19.3281v36.8389c0.000976562 6.48047 1.21973 16.8574 2.71973 23.1621l31.7549 133.407
|
||||
c5.83105 24.4893 -31.1445 33.25 -36.9658 8.80273l-26.9229 -113.105c-1.61523 -6.78711 -8.58887 -12.2949 -15.5645 -12.2949h-9.69434c-10.4072 0 -18.043 9.79199 -15.5225 19.8799l38.127 152.512c6.09766 24.376 -30.7607 33.6396 -36.8643 9.21777l-42.3721 -169.49
|
||||
c-1.67285 -6.68945 -8.62695 -12.1191 -15.5225 -12.1191h-13.2168v0c-7.0332 0 -14.0195 5.5625 -15.5938 12.417l-45.2207 196.828c-5.64453 24.5684 -42.6572 15.9609 -37.0342 -8.50781l41.6191 -181.153c2.30078 -10.0156 -5.31738 -19.583 -15.5938 -19.583h-8.60352
|
||||
h-0.000976562c-7.0498 0 -14.04 5.5791 -15.6025 12.4541l-30.3984 133.757c-5.55273 24.4395 -42.6504 16.1963 -37.0547 -8.4209l34.1299 -150.172c0.263672 -1.16309 0.397461 -2.35352 0.397461 -3.5459v-69.4795c0 -13.9941 -16.7754 -21.2432 -26.9658 -11.6523
|
||||
l-53.0117 49.8936c-7.61523 7.16699 -19.6377 6.85938 -26.8564 -0.8125z" />
|
||||
d="M501.03 331.824c6.92773 -11.1826 10.9697 -24.4053 10.9697 -38.5146c0 -5.92676 -0.706055 -11.6885 -2.03809 -17.208l-57.623 -241.963c-13.2236 -56.1904 -63.707 -98.1387 -123.908 -98.1387h-0.352539h-107.455
|
||||
c-0.0761719 0 -0.193359 0.00195312 -0.270508 0.00195312c-40.9248 0 -78.1475 15.9814 -105.761 42.0391l-91.3652 85.9766c-14.3076 13.4434 -23.2246 32.5547 -23.2246 53.7168c0 19.5254 7.61035 37.2861 20.0254 50.4766
|
||||
c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973c-1.97363 6.64844 -2.97656 13.6836 -2.97656 20.9688c0 38.6953 29.8926 70.4639 67.8262 73.4531c-0.246094 2.45117 -0.34082 4.85547 -0.34082 7.37207c0 34.4199 23.585 63.376 55.4619 71.5752
|
||||
c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207l4.64648 22.6602c6.99023 33.5186 36.6826 58.8037 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219
|
||||
c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971
|
||||
c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779
|
||||
c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539c6.59375 -22.2441 10.1777 -45.7803 10.1777 -70.1523c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805
|
||||
c19.0469 -17.9736 44.75 -28.998 72.9795 -28.998h0.157227h107.455c0.0732422 0 0.138672 0.0429688 0.212891 0.0429688c37.5791 0 69.1016 26.1416 77.3564 61.2168z" />
|
||||
<glyph glyph-name="hand-pointer" unicode="" horiz-adv-x="448"
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -4.25 -0.775391 -11.0615 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286c-21.2588 0 -41.3682 10.4102 -53.791 27.8457
|
||||
l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289
|
||||
c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001
|
||||
c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938
|
||||
c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832z
|
||||
M176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -5.24023 -0.600586 -10.3037 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286
|
||||
c-21.2588 0 -41.3682 10.4102 -53.791 27.8457l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338
|
||||
c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285
|
||||
c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832zM176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96
|
||||
c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
<glyph glyph-name="hand-peace" unicode="" horiz-adv-x="448"
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -4.25 -0.775391 -11.0615 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -5.24023 -0.600586 -10.3027 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
|
||||
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328v0
|
||||
c-6.06445 0 -12.7549 4.59375 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.589844 -1.53125 1.06738 -4.10547 1.06738 -5.74609c0 -4.19043 -2.63379 -9.74219 -5.87891 -12.3926l-26.6475 -21.7646
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328
|
||||
c-6.80859 0 -12.624 4.25391 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.685547 -1.78125 1.07812 -3.71875 1.07812 -5.74121c0 -4.99707 -2.2959 -9.46289 -5.88965 -12.3975l-26.6475 -21.7646
|
||||
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
|
||||
<glyph glyph-name="registered" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096h-0.0126953c-3.97559 0 -8.71582 2.84961 -10.5801 6.36035l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304
|
||||
c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094c20.9131 0 32.4307 11.5186 32.4316 32.4316
|
||||
c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096c-0.00488281 0 -0.000976562 -0.0126953 -0.00585938 -0.0126953c-4.58594 0 -8.57422 2.58301 -10.5869 6.37305l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12
|
||||
h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094
|
||||
c20.9131 0 32.4307 11.5186 32.4316 32.4316c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
<glyph glyph-name="calendar-plus" unicode="" horiz-adv-x="448"
|
||||
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
|
||||
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
|
||||
|
@ -481,9 +478,9 @@ c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-
|
|||
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
|
||||
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
|
||||
<glyph glyph-name="map" unicode="" horiz-adv-x="576"
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -11.9609 -9.01367 -25.2705 -20.1201 -29.71l-151.83 -52.8105c-5.32617 -1.7334 -14.1953 -3.13965 -19.7969 -3.13965c-5.7373 0 -14.8105 1.47363 -20.2529 3.29004l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 11.959 9.0166 25.2686 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c5.73242 -0.00195312 14.8008 -1.47168 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -13.4707 -8.32422 -24.9951 -20.1201 -29.71l-151.83 -52.8105c-6.23242 -2.02832 -12.9023 -3.12305 -19.8076 -3.12305c-7.07324 0 -13.8799 1.15039 -20.2422 3.27344l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 13.4697 8.32617 24.9932 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c7.06641 -0.00292969 13.8789 -1.16602 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
|
||||
<glyph glyph-name="comment-alt" unicode=""
|
||||
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
|
||||
|
@ -497,16 +494,16 @@ c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.200
|
|||
<glyph glyph-name="handshake" unicode="" horiz-adv-x="640"
|
||||
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
|
||||
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
|
||||
h226.8v0c12.7812 0 30.5225 -7.30273 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
h226.8c15.4326 0 29.4326 -6.22168 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
|
||||
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
|
||||
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
|
||||
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
|
||||
" />
|
||||
<glyph glyph-name="envelope-open" unicode=""
|
||||
d="M494.586 283.484c9.6123 -7.94824 17.4141 -24.5205 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 12.5166 7.84668 29.1279 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632v0.00488281c0 1.5791 -0.996094 3.66602 -2.22363 4.6582
|
||||
c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
d="M494.586 283.484c10.6523 -8.80762 17.4141 -22.1064 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 14.9355 6.80469 28.2705 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632c0 0.00195312 0.00390625 0.000976562 0.00390625 0.00292969
|
||||
c0 1.88184 -0.869141 3.56152 -2.22754 4.66016c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
|
||||
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
|
||||
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
|
||||
|
@ -555,10 +552,11 @@ c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.
|
|||
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
|
||||
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
|
||||
<glyph glyph-name="trash-alt" unicode="" horiz-adv-x="448"
|
||||
d="M268 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24zM432 368c8.83203 0 16 -7.16797 16 -16v-16c0 -8.83203 -7.16797 -16 -16 -16h-16v-336
|
||||
c0 -26.4961 -21.5039 -48 -48 -48h-288c-26.4961 0 -48 21.5039 -48 48v336h-16c-8.83203 0 -16 7.16797 -16 16v16c0 8.83203 7.16797 16 16 16h82.4102l34.0195 56.7002c7.71875 12.8613 26.1572 23.2998 41.1572 23.2998h0.00292969h100.82h0.0224609
|
||||
c15 0 33.4385 -10.4385 41.1572 -23.2998l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-0.96582 1.60645 -3.26953 2.91016 -5.14355 2.91016h-0.00683594h-94h-0.0166016c-1.87402 0 -4.17871 -1.30371 -5.14355 -2.91016zM368 -16v336
|
||||
h-288v-336h288zM156 32c-6.62402 0 -12 5.37598 -12 12v216c0 6.62402 5.37598 12 12 12h24c6.62402 0 12 -5.37598 12 -12v-216c0 -6.62402 -5.37598 -12 -12 -12h-24z" />
|
||||
d="M268 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216c0 -6.62305 -5.37695 -12 -12 -12h-24zM432 368c8.83105 0 16 -7.16895 16 -16v-16c0 -8.83105 -7.16895 -16 -16 -16h-16v-336
|
||||
c0 -26.4922 -21.5078 -48 -48 -48h-288c-26.4922 0 -48 21.5078 -48 48v336h-16c-8.83105 0 -16 7.16895 -16 16v16c0 8.83105 7.16895 16 16 16h82.4102l34.0195 56.7002c8.39258 13.9844 23.6777 23.2998 41.1602 23.2998h100.82
|
||||
c0.0078125 0 -0.015625 0.0517578 -0.0078125 0.0517578c17.4824 0 32.7949 -9.36719 41.1875 -23.3516l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-1.0498 1.74707 -2.95898 2.91016 -5.14355 2.91016h-0.00683594h-94
|
||||
c-0.00585938 0 -0.00683594 0.00683594 -0.0126953 0.00683594c-2.18457 0 -4.09766 -1.16992 -5.14746 -2.91699zM368 -16v336h-288v-336h288zM156 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216
|
||||
c0 -6.62305 -5.37695 -12 -12 -12h-24z" />
|
||||
<glyph glyph-name="images" unicode="" horiz-adv-x="576"
|
||||
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
|
||||
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
|
||||
|
@ -584,9 +582,9 @@ d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.400
|
|||
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
|
||||
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
|
||||
<glyph glyph-name="money-bill-alt" unicode="" horiz-adv-x="640"
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801h-0.000976562
|
||||
c-4.01074 0 -9.97266 -1.80566 -13.3086 -4.03027l-15.3301 -10.2197c-1.96777 -1.30957 -3.56445 -4.29004 -3.56445 -6.65332c0 -1.33691 0.601562 -3.32422 1.34375 -4.43652l8.88086 -13.3105c1.30859 -1.9668 4.29004 -3.56445 6.65332 -3.56445
|
||||
c1.33691 0 3.32422 0.602539 4.43652 1.34473l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801
|
||||
c-4.91113 0 -9.50586 -1.49316 -13.3096 -4.03027l-15.3301 -10.2197c-2.15332 -1.43262 -3.55957 -3.88379 -3.55957 -6.66113c0 -1.6377 0.493164 -3.16113 1.33887 -4.42871l8.88086 -13.3105c1.43164 -2.15234 3.88379 -3.55957 6.66113 -3.55957
|
||||
c1.6377 0 3.16016 0.494141 4.42871 1.33984l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
|
||||
<glyph glyph-name="window-close" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
|
||||
|
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 798 KiB After Width: | Height: | Size: 896 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
Subproject commit 0d6db44c80afd81976f54f58c8cb02e4d33acc16
|
||||
Subproject commit 52d806b349333d40c5dd75b62e8e64d6a18fcdf4
|
|
@ -59,6 +59,74 @@
|
|||
"extra": ""
|
||||
}
|
||||
],
|
||||
"attachment_scans": [
|
||||
{
|
||||
"column_name": "id",
|
||||
"is_nullable": "NO",
|
||||
"data_type": "int",
|
||||
"character_maximum_length": null,
|
||||
"numeric_precision": "10",
|
||||
"collation_name": null,
|
||||
"column_type": "int(11)",
|
||||
"column_default": null,
|
||||
"extra": "auto_increment"
|
||||
},
|
||||
{
|
||||
"column_name": "type",
|
||||
"is_nullable": "NO",
|
||||
"data_type": "varchar",
|
||||
"character_maximum_length": "40",
|
||||
"numeric_precision": null,
|
||||
"collation_name": "utf8_bin",
|
||||
"column_type": "varchar(40)",
|
||||
"column_default": null,
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"column_name": "attribute_id",
|
||||
"is_nullable": "NO",
|
||||
"data_type": "int",
|
||||
"character_maximum_length": null,
|
||||
"numeric_precision": "10",
|
||||
"collation_name": null,
|
||||
"column_type": "int(11)",
|
||||
"column_default": null,
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"column_name": "infected",
|
||||
"is_nullable": "NO",
|
||||
"data_type": "tinyint",
|
||||
"character_maximum_length": null,
|
||||
"numeric_precision": "3",
|
||||
"collation_name": null,
|
||||
"column_type": "tinyint(1)",
|
||||
"column_default": null,
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"column_name": "malware_name",
|
||||
"is_nullable": "YES",
|
||||
"data_type": "varchar",
|
||||
"character_maximum_length": "191",
|
||||
"numeric_precision": null,
|
||||
"collation_name": "utf8mb4_general_ci",
|
||||
"column_type": "varchar(191)",
|
||||
"column_default": "NULL",
|
||||
"extra": ""
|
||||
},
|
||||
{
|
||||
"column_name": "timestamp",
|
||||
"is_nullable": "NO",
|
||||
"data_type": "int",
|
||||
"character_maximum_length": null,
|
||||
"numeric_precision": "10",
|
||||
"collation_name": null,
|
||||
"column_type": "int(11)",
|
||||
"column_default": null,
|
||||
"extra": ""
|
||||
}
|
||||
],
|
||||
"attributes": [
|
||||
{
|
||||
"column_name": "id",
|
||||
|
@ -6882,6 +6950,11 @@
|
|||
"allowedlist": {
|
||||
"id": true
|
||||
},
|
||||
"attachment_scans": {
|
||||
"id": true,
|
||||
"type": false,
|
||||
"attribute_id": false
|
||||
},
|
||||
"attributes": {
|
||||
"id": true,
|
||||
"uuid": false,
|
||||
|
@ -7275,5 +7348,5 @@
|
|||
"id": true
|
||||
}
|
||||
},
|
||||
"db_version": "59"
|
||||
"db_version": "60"
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
# Ingest STIX
|
||||
|
||||
Python script to ingest STIX files on MISP.
|
||||
|
||||
## Requirements
|
||||
|
||||
There are a few requirements for this little python script to run, which are included in the MISP requirements:
|
||||
- PyMISP
|
||||
- Python 3.6+ (because PyMISP is Python 3.6+)
|
||||
- Your API key
|
||||
|
||||
The recommended python setup for MISP is described within [the following documentation](https://www.circl.lu/doc/misp/updating-python/).
|
||||
|
||||
## Description
|
||||
|
||||
The aim of this small piece of code is to ingest STIX files.
|
||||
|
||||
In order to ingest STIX data into MISP, there are 2 end points to query, `/events/upload_stix` for STIX 1, and `/events/upload_stix/2` for STIX 2.
|
||||
The content of the STIX file to ingest has then to be passed in the body of the query.
|
||||
|
||||
The equivalent is available in PyMISP with the `upload_stix` method. The only difference is instead of passing the STIX content, the filename(s) of the file(s) to import are passed.
|
||||
|
||||
MISP creates then an event for each file ingested, using the [stix import](https://github.com/MISP/MISP/blob/2.4/app/files/scripts/stix2misp.py) or [stix2 import](https://github.com/MISP/MISP/blob/2.4/app/files/scripts/stix2/stix2misp.py) scripts.
|
||||
|
||||
## Usage
|
||||
|
||||
Depending of the python environment set in your MISP server, you will have to use the correct python command in order to be sure to reach the correct environment containing all the required libraries and dependencies:
|
||||
- The recommended environment installed by default in most of our installation scripts, and virtual machine is a virtualenv available using `/var/www/MISP/venv/bin/python`
|
||||
- If any other python environment is set instead, use the corresponding command. As an example, the built-in python3 provided with most of the linux distribution is available with a simple `python3`
|
||||
**Please replace the python command in the next examples with your own settings if needed**
|
||||
|
||||
In order to connect to MISP, we need an URL and an API key.
|
||||
You can either pass those parameters when you call the `ingest_python.py` script, or put them within the `setup.json` file that is passed by default to the script, or event use another setup file as long as it contains the same required fields:
|
||||
- `misp_url`: the URL of your MISP server
|
||||
- `misp_key`: your MISP API key
|
||||
- `misp_verifycert`: (`true` or `false`) to check or not the validity of the certificate
|
||||
|
||||
We also require here a STIX version and the path to the files to ingest (**Please use file names instead of directory names**)
|
||||
|
||||
As just mentioned, the setup file is used by default, and it avoids empty value issues for the required parameters. It is thus possible to simply run the following:
|
||||
```
|
||||
# STIX 1
|
||||
python3 ingest_stix.py --version 1 --path _PATH_TO_YOUR_FILES_/stix_files*.xml
|
||||
|
||||
# STIX 2
|
||||
python3 ingest_stix.py --version 2 --path _PATH_TO_YOUR_FILES_/stix_files*.json
|
||||
```
|
||||
|
||||
But you can also overwrite the required MISP setups:
|
||||
```
|
||||
# Overwrite the SSL verification
|
||||
python3 ingest_stix.py --version 1 --path _PATH_TO_YOUR_FILES_/stix_files*.xml --misp_verifycert
|
||||
|
||||
# Simply define all the parameters without using the setup file
|
||||
python3 ingest_stix.py --version 1 --path _PATH_TO_YOUR_FILES_/stix_files*.xml --misp_url _MISP_URL_ --misp_key _YOUR_API_KEY_ --misp_verifycert
|
||||
```
|
||||
|
||||
## Important information to be aware of
|
||||
|
||||
There are a few reasons why the data you want to ingest may be truncated or there may be missing information:
|
||||
- The most obvious reason is the impossibility to map 100\% of the STIX objects and fields into MISP format.
|
||||
- The import of STIX data into MISP is made to keep the uuids when possible. If you import an indicator with an uuid already existing in MISP, it will be skipped.
|
||||
- If one file raises an error and is not imported at all, there might be an issue in the import script.
|
||||
|
||||
Once the ingestion is completed, each ingested file is also saved within the corresponding MISP event, so the initial data is available if needed.
|
|
@ -0,0 +1,40 @@
|
|||
import json
|
||||
from argparse import ArgumentParser
|
||||
from pymisp import ExpandedPyMISP
|
||||
from pymisp.exceptions import PyMISPError
|
||||
|
||||
def ingest_to_misp(path, version, url, key, verifycert):
|
||||
try:
|
||||
misp = ExpandedPyMISP(url, key, verifycert)
|
||||
except PyMISPError:
|
||||
return f'Unable to connect to MISP ({url}). Please make sure the API key and the URL are correct.'
|
||||
|
||||
errors = []
|
||||
for filename in path:
|
||||
response = misp.upload_stix(filename, version=version)
|
||||
if response.status_code != 200:
|
||||
errors.append(filename)
|
||||
|
||||
if errors:
|
||||
file = "file: " if len(errors) == 1 else "files:\n- "
|
||||
print_errors = '\n- '.join(errors)
|
||||
return f'Error with the ingestion of the following {file}{print_errors}'
|
||||
return f'Successfully ingested {len(path)} STIX {version} files.'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='')
|
||||
parser.add_argument('--misp_url', help='URL of the MISP instance you want to connect to.')
|
||||
parser.add_argument('--misp_key', help='API key of the user you want to use.')
|
||||
parser.add_argument('--misp_verifycert', action='store_true', help='To check the validity of the certificate.')
|
||||
parser.add_argument('--version', required=True, help='STIX version (1 or 2).')
|
||||
parser.add_argument('--path', nargs='+', required=True, help='Path to the STIX files to ingest.')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.version not in ('1', '2'):
|
||||
sys.exit('Please specify the STIX version: 1 or 2.')
|
||||
with open('setup.json', 'rt', encoding='utf-8') as f:
|
||||
default_setup = json.loads(f.read())
|
||||
features = ('misp_url', 'misp_key', 'misp_verifycert')
|
||||
setup = [getattr(args, feature) if getattr(args, feature) else default_setup[feature] for feature in features]
|
||||
print(ingest_to_misp(args.path, args.version, *setup))
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"misp_url": "_YOUR_MISP_URL_",
|
||||
"misp_key": "_YOUR_API_KEY_",
|
||||
"misp_verifycert": false
|
||||
}
|
Loading…
Reference in New Issue