{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
   or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
   https://securityonion.net/license; you may not use this file except in compliance with the
   Elastic License 2.0. #}

{% from 'vars/globals.map.jinja' import GLOBALS %}
{% from 'soc/defaults.map.jinja' import SOCDEFAULTS with context %}
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_NODES %}
{% from 'manager/map.jinja' import MANAGERMERGED %}
{% set DOCKER_EXTRA_HOSTS = ELASTICSEARCH_NODES %}
{% do DOCKER_EXTRA_HOSTS.append({GLOBALS.influxdb_host:pillar.node_data[GLOBALS.influxdb_host].ip}) %}

{% set SOCMERGED = salt['pillar.get']('soc', SOCDEFAULTS, merge=true) %}

{% do SOCMERGED.config.server.update({'proxy': MANAGERMERGED.proxy}) %}
{% do SOCMERGED.config.server.update({'additionalCA': MANAGERMERGED.additionalCA}) %}
{% do SOCMERGED.config.server.update({'insecureSkipVerify': MANAGERMERGED.insecureSkipVerify}) %}

{# if SOCMERGED.config.server.modules.cases == httpcase details come from the soc pillar #}
{% if SOCMERGED.config.server.modules.cases != 'soc' %}
{%   do SOCMERGED.config.server.modules.elastic.update({'casesEnabled': false}) %}
{%   do SOCMERGED.config.server.client.update({'casesEnabled': false}) %}
{%   do SOCMERGED.config.server.client.hunt.update({'escalateRelatedEventsEnabled': false}) %}
{%   do SOCMERGED.config.server.client.alerts.update({'escalateRelatedEventsEnabled': false}) %}
{%   if SOCMERGED.config.server.modules.cases == 'elasticcases' %}
{%     do SOCMERGED.config.server.modules.update({
         'elasticcases': {
           'hostUrl': 'https://' ~ GLOBALS.manager_ip ~ ':5601',
           'username': GLOBALS.elasticsearch.auth.users.so_elastic_user.user,
           'password': GLOBALS.elasticsearch.auth.users.so_elastic_user.pass,
         }
       }) %}
{%   endif %}
{% endif %}
{# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #}
{% do SOCMERGED.config.server.modules.pop('cases') %}

{# set enabled Sigma rules based on role if defined and default if not #}
{# this particular config is deprecated as of 2.4.120 - use enabledSigmaRules instead #}
{% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules[GLOBALS.role]}) %}
{% else %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules.default}) %}
{% endif %}

{# set enabled Sigma rules based on role if defined and default if not #}
{% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules[GLOBALS.role]}) %}
{% else %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules.default}) %}
{% endif %}

{# set elastalertengine.rulesRepos, strelkaengine.rulesRepos, and suricataengine.rulesetSources based on airgap or not #}
{% if GLOBALS.airgap %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'rulesRepos': SOCMERGED.config.server.modules.elastalertengine.rulesRepos.airgap}) %}
{%   do SOCMERGED.config.server.modules.strelkaengine.update({'rulesRepos': SOCMERGED.config.server.modules.strelkaengine.rulesRepos.airgap}) %}
{#%   if SOCMERGED.config.server.modules.suricataengine.rulesetSources is mapping %#}
{%     do SOCMERGED.config.server.modules.suricataengine.update({'rulesetSources': SOCMERGED.config.server.modules.suricataengine.rulesetSources.airgap}) %}
{#%   endif %#}
{%   do SOCMERGED.config.server.update({'airgapEnabled': true}) %}
{% else %}
{%   do SOCMERGED.config.server.modules.elastalertengine.update({'rulesRepos': SOCMERGED.config.server.modules.elastalertengine.rulesRepos.default}) %}
{%   do SOCMERGED.config.server.modules.strelkaengine.update({'rulesRepos': SOCMERGED.config.server.modules.strelkaengine.rulesRepos.default}) %}
{#%   if SOCMERGED.config.server.modules.suricataengine.rulesetSources is mapping %#}
{%     do SOCMERGED.config.server.modules.suricataengine.update({'rulesetSources': SOCMERGED.config.server.modules.suricataengine.rulesetSources.default}) %}
{#%   endif %#}
{%   do SOCMERGED.config.server.update({'airgapEnabled': false}) %}
{% endif %}


{# Define the Detections custom ruleset that should always be present #}
{% set CUSTOM_RULESET = {
  'name': '__custom__',
  'description': 'User-created custom rules created via the Detections module in the SOC UI',
  'sourceType': 'elasticsearch',
  'sourcePath': 'so_detection.ruleset:__custom__',
  'readOnly': false,
  'deleteUnreferenced': false,
  'license': 'Custom',
  'enabled': true
} %}

{# Always append the custom ruleset to suricataengine.rulesetSources if not already present #}
{% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %}
{%   if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %}
{%     set custom_names = SOCMERGED.config.server.modules.suricataengine.rulesetSources | selectattr('name', 'equalto', '__custom__') | list %}
{%     if custom_names | length == 0 %}
{%       do SOCMERGED.config.server.modules.suricataengine.rulesetSources.append(CUSTOM_RULESET) %}
{%     endif %}
{%   endif %}
{% endif %}

{# Enable SO_FILTERS and SO_EXTRACTIONS when Suricata is the metadata engine #}
{% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %}
{%   if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %}
{%     for ruleset in SOCMERGED.config.server.modules.suricataengine.rulesetSources %}
{%       if ruleset.name in ['SO_FILTERS', 'SO_EXTRACTIONS'] and GLOBALS.md_engine == 'SURICATA' %}
{%         do ruleset.update({'enabled': true}) %}
{%       endif %}
{%     endfor %}
{%   endif %}
{% endif %}

{# Transform Emerging-Threats ruleset based on license key #}
{% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %}
{%   if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %}
{%     for ruleset in SOCMERGED.config.server.modules.suricataengine.rulesetSources %}
{%     if ruleset.name == 'Emerging-Threats' %}
{%       if ruleset.licenseKey and ruleset.licenseKey != '' %}
{#         License key is defined - transform to ETPRO #}
{%         if ruleset.sourceType == 'directory' %}
{#           Airgap mode - update directory path #}
{%           do ruleset.update({
               'name': 'ETPRO',
               'sourcePath': '/nsm/rules/custom-local-repos/local-etpro-suricata/etpro.rules.tar.gz',
               'license': 'Commercial'
             }) %}
{%         else %}
{#           Engine Version is hardcoded in the URL - this does not change often: https://community.emergingthreats.net/t/supported-engines/71 #}
{%           do ruleset.update({
               'name': 'ETPRO',
               'sourcePath': 'https://rules.emergingthreatspro.com/' ~ ruleset.licenseKey ~ '/suricata-7.0.3/etpro.rules.tar.gz',
               'urlHash': 'https://rules.emergingthreatspro.com/' ~ ruleset.licenseKey ~ '/suricata-7.0.3/etpro.rules.tar.gz.md5',
               'license': 'Commercial'
             }) %}
{%         endif %}
{%       else %}
{#         No license key - explicitly set to ETOPEN #}
{%         if ruleset.sourceType == 'directory' %}
{#           Airgap mode - update directory path #}
{%           do ruleset.update({
               'name': 'ETOPEN',
               'sourcePath': '/nsm/rules/suricata/etopen/',
               'license': 'BSD'
             }) %}
{%         else %}
{%           do ruleset.update({
               'name': 'ETOPEN',
               'sourcePath': 'https://rules.emergingthreats.net/open/suricata-7.0.3/emerging.rules.tar.gz',
               'urlHash': 'https://rules.emergingthreats.net/open/suricata-7.0.3/emerging.rules.tar.gz.md5',
               'license': 'BSD'
             }) %}
{%         endif %}
{%       endif %}
{%     endif %}
{%     endfor %}
{%   endif %}
{% endif %}


{# set playbookRepos based on airgap or not #}
{% if GLOBALS.airgap %}
{%   do SOCMERGED.config.server.modules.playbook.update({'playbookRepos': SOCMERGED.config.server.modules.playbook.playbookRepos.airgap}) %}
{% else %}
{%   do SOCMERGED.config.server.modules.playbook.update({'playbookRepos': SOCMERGED.config.server.modules.playbook.playbookRepos.default}) %}
{% endif %}

{# remove these modules if detections is disabled #}
{% if not SOCMERGED.config.server.client.detectionsEnabled %}
{%   do SOCMERGED.config.server.modules.pop('elastalertengine') %}
{%   do SOCMERGED.config.server.modules.pop('strelkaengine') %}
{%   do SOCMERGED.config.server.modules.pop('suricataengine') %}
{% elif pillar.global.airgap %}
  {# if system is Airgap, don't autoupdate Yara & Sigma rules #}
  {%   do SOCMERGED.config.server.modules.elastalertengine.update({'autoUpdateEnabled': false}) %}
  {%   do SOCMERGED.config.server.modules.strelkaengine.update({'autoUpdateEnabled': false}) %}
{% endif %}

{% set standard_actions = SOCMERGED.config.pop('actions') %}

{% if pillar.global.endgamehost != '' %}
{# this is added to prevent endgame_dict from being added to standard_actions for each time this file is rendered #}
{# since this map file is rendered 3 times, it causes endgame_dict to appened 3 times if custom actions are defined in the pillar #}
{%   set endgame = namespace(add=true) %}
{%   for d in standard_actions %}
{%     if d.name is defined %}
{%       if d.name == 'Endgame' %}
{%         set endgame.add = false %}
{%       endif %}
{%     endif %}
{%   endfor %}
{%   set endgame_dict = {
       "name": "Endgame",
       "description": "Endgame Endpoint Investigation and Response",
       "icon": "fa-external-link-alt",
       "target": "_blank",
       "links": ["https://" ~ pillar.global.endgamehost ~ "/endpoints/{:agent.id}"]
     }
%}
{%   if endgame.add %}
{%     do standard_actions.append(endgame_dict) %}
{%   endif %}
{% endif %}

{%   do SOCMERGED.config.server.client.hunt.update({'actions': standard_actions}) %}
{%   do SOCMERGED.config.server.client.dashboards.update({'actions': standard_actions}) %}
{%   do SOCMERGED.config.server.client.update({'job': {'actions': standard_actions}}) %}
{%   do SOCMERGED.config.server.client.alerts.update({'actions': standard_actions}) %}
{%   do SOCMERGED.config.server.client.cases.update({'actions': standard_actions}) %}
{%   do SOCMERGED.config.server.client.detections.update({'actions': standard_actions}) %}

{# replace the _x_ with . for soc ui to config conversion #}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.api': SOCMERGED.config.eventFields.pop(':endpoint:events_x_api') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.file': SOCMERGED.config.eventFields.pop(':endpoint:events_x_file') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.library': SOCMERGED.config.eventFields.pop(':endpoint:events_x_library') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.network': SOCMERGED.config.eventFields.pop(':endpoint:events_x_network') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.process': SOCMERGED.config.eventFields.pop(':endpoint:events_x_process') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.registry': SOCMERGED.config.eventFields.pop(':endpoint:events_x_registry') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.security': SOCMERGED.config.eventFields.pop(':endpoint:events_x_security') }) %}
{% set standard_eventFields = SOCMERGED.config.pop('eventFields') %}
{%   do SOCMERGED.config.server.client.hunt.update({'eventFields': standard_eventFields}) %}
{%   do SOCMERGED.config.server.client.dashboards.update({'eventFields': standard_eventFields}) %}
