mirror of https://github.com/MISP/MISP
chg: [workflow:module_splunk_hec_export] Small refactoring
parent
1994f35e95
commit
f179b2db7a
|
@ -4,20 +4,17 @@ include_once APP . 'Model/WorkflowModules/WorkflowBaseModule.php';
|
|||
App::uses('SyncTool', 'Tools');
|
||||
App::uses('JsonTool', 'Tools');
|
||||
|
||||
class Module_splunk_hec_export extends WorkflowBaseActionModule
|
||||
class Module_splunk_hec_export extends Module_webhook
|
||||
{
|
||||
public $id = 'splunk-hec-export';
|
||||
public $name = 'Splunk HEC export';
|
||||
public $version = '0.1';
|
||||
public $description = 'Export Event Data to Splunk HTTP Event Collector';
|
||||
public $version = '0.2';
|
||||
public $description = 'Export Event Data to Splunk HTTP Event Collector. Due to the potential high amount of requests, it\'s recommanded to put this module after a `concurrent_task` logic module.';
|
||||
public $icon_path = 'Splunk.png';
|
||||
public $inputs = 1;
|
||||
public $outputs = 0;
|
||||
public $support_filters = false;
|
||||
public $expect_misp_core_format = true;
|
||||
public $params = [];
|
||||
|
||||
private $timeout = false;
|
||||
private $Event;
|
||||
public $outputs = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -34,10 +31,10 @@ class Module_splunk_hec_export extends WorkflowBaseActionModule
|
|||
'label' => __('Verify HTTPS Certificate'),
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'true' => __('True'),
|
||||
'false' => __('False'),
|
||||
'1' => __('True'),
|
||||
'0' => __('False'),
|
||||
],
|
||||
'default' => 'true',
|
||||
'default' => 1,
|
||||
],
|
||||
[
|
||||
'id' => 'hec_token',
|
||||
|
@ -51,10 +48,10 @@ class Module_splunk_hec_export extends WorkflowBaseActionModule
|
|||
'label' => __('Create one Splunk Event per Attribute'),
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'true' => __('True'),
|
||||
'false' => __('False'),
|
||||
'1' => __('True'),
|
||||
'0' => __('False'),
|
||||
],
|
||||
'default' => 'false',
|
||||
'default' => 0,
|
||||
],
|
||||
[
|
||||
'id' => 'data_extraction_model',
|
||||
|
@ -66,28 +63,8 @@ class Module_splunk_hec_export extends WorkflowBaseActionModule
|
|||
];
|
||||
}
|
||||
|
||||
public function diagnostic(): array
|
||||
{
|
||||
$errors = array_merge(parent::diagnostic(), []);
|
||||
if (empty(Configure::read('Security.rest_client_enable_arbitrary_urls'))) {
|
||||
$errors = $this->addNotification(
|
||||
$errors,
|
||||
'error',
|
||||
__('`rest_client_enable_arbitrary_urls` is turned off.'),
|
||||
__('The module will not send any request as long as `Security.rest_client_enable_arbitrary_urls` is turned off.'),
|
||||
[
|
||||
__('This is a security measure to ensure a site-admin do not send arbitrary request to internal services')
|
||||
],
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function exec(array $node, WorkflowRoamingData $roamingData, array &$errors = []): bool
|
||||
{
|
||||
parent::exec($node, $roamingData, $errors);
|
||||
if (empty(Configure::read('Security.rest_client_enable_arbitrary_urls'))) {
|
||||
$errors[] = __('`Security.rest_client_enable_arbitrary_urls` is turned off');
|
||||
return false;
|
||||
|
@ -97,45 +74,62 @@ class Module_splunk_hec_export extends WorkflowBaseActionModule
|
|||
$errors[] = __('URL not provided.');
|
||||
return false;
|
||||
}
|
||||
if (empty($params['hec_token']['value'])) {
|
||||
$errors[] = __('Authorization token not provided.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$rData = $roamingData->getData();
|
||||
|
||||
//$path = $params['data_extraction_path']['value'];
|
||||
//$extracted = !empty($params['data_extraction_path']['value']) ? $this->extractData($rData, $path) : $rData;
|
||||
|
||||
$event_without_attributes = $rData['Event'];
|
||||
unset($event_without_attributes['Attribute']);
|
||||
unset($event_without_attributes['_AttributeFlattened']);
|
||||
|
||||
$splunk_events = [];
|
||||
if ($params['event_per_attribute']['value'] == 'true') {
|
||||
if (!empty($params['event_per_attribute']['value'])) {
|
||||
foreach ($rData['Event']['Attribute'] as $attribute) {
|
||||
array_push($splunk_events, [
|
||||
'Attribute' => $attribute,
|
||||
'Event' => $event_without_attributes
|
||||
]);
|
||||
$splunk_events[] = [
|
||||
'Attribute' => $attribute,
|
||||
'Event' => $event_without_attributes
|
||||
];
|
||||
}
|
||||
} else {
|
||||
array_push($splunk_events, $rData);
|
||||
$splunk_events[] = $rData;
|
||||
}
|
||||
|
||||
if (!empty($params['data_extraction_model']['value'])) {
|
||||
$data_extraction_model = JsonTool::decode($params['data_extraction_model']['value']);
|
||||
$extracted_events = [];
|
||||
foreach ($splunk_events as $splunk_event) {
|
||||
$event = array();
|
||||
foreach ($data_extraction_model as $field => $path) {
|
||||
$field_data = $this->extractData($splunk_event, $path);
|
||||
$event[$field] = count($field_data) == 1 ? $field_data[0] : $field_data; // unpack if only one element
|
||||
}
|
||||
array_push($extracted_events, $event);
|
||||
}
|
||||
$splunk_events = $extracted_events;
|
||||
}
|
||||
if (!empty($params['data_extraction_model']['value'])) {
|
||||
$data_extraction_model = JsonTool::decode($params['data_extraction_model']['value']);
|
||||
$extracted_events = [];
|
||||
foreach ($splunk_events as $splunk_event) {
|
||||
$event = [];
|
||||
foreach ($data_extraction_model as $field => $path) {
|
||||
$field_data = $this->extractData($splunk_event, $path);
|
||||
$event[$field] = count($field_data) == 1 ? $field_data[0] : $field_data; // unpack if only one element
|
||||
}
|
||||
$extracted_events[] = $event;
|
||||
}
|
||||
$splunk_events = $extracted_events;
|
||||
}
|
||||
|
||||
return $this->sendToSplunk($splunk_events, $params['hec_token']['value'], $params['url']['value']);
|
||||
}
|
||||
|
||||
protected function sendToSplunk(array $splunk_events, $token, $url): bool
|
||||
{
|
||||
foreach ($splunk_events as $splunk_event) {
|
||||
try {
|
||||
$response = $this->doRequest($params['url']['value'], $params['hec_token']['value'], $params['verify_tls']['value'], $splunk_event);
|
||||
$headers = [
|
||||
'Authorization' => "Splunk {$token}",
|
||||
];
|
||||
$serverConfig = [
|
||||
'Server' => ['self_signed' => empty($params['verify_tls']['value'])]
|
||||
];
|
||||
$response = $this->doRequest(
|
||||
$url,
|
||||
'json',
|
||||
$splunk_event,
|
||||
$headers,
|
||||
$serverConfig,
|
||||
);
|
||||
if (!$response->isOk()) {
|
||||
if ($response->code === 403 || $response->code === 401) {
|
||||
$errors[] = __('Authentication failed.');
|
||||
|
@ -154,33 +148,4 @@ class Module_splunk_hec_export extends WorkflowBaseActionModule
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doRequest($url, $hec_token, $verify_tls, $data)
|
||||
{
|
||||
$this->Event = ClassRegistry::init('Event'); // We just need a model to use AppModel functions
|
||||
$version = implode('.', $this->Event->checkMISPVersion());
|
||||
$commit = $this->Event->checkMIPSCommit();
|
||||
|
||||
$request = [
|
||||
'header' => [
|
||||
'Authorization' => 'Splunk ' . $hec_token,
|
||||
]
|
||||
];
|
||||
$syncTool = new SyncTool();
|
||||
|
||||
$server = [];
|
||||
if ($verify_tls == 'false') {
|
||||
$server['Server'] = ['self_signed' => true];
|
||||
}
|
||||
|
||||
$HttpSocket = $syncTool->setupHttpSocket($server, $this->timeout, 'Server');
|
||||
|
||||
|
||||
$HEC_Event = [
|
||||
'event' => $data,
|
||||
];
|
||||
|
||||
$response = $HttpSocket->post($url, JsonTool::encode($HEC_Event), $request);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue