Skip to content

Commit

Permalink
Merge pull request #283 from oasis-open/fix-enable-disable-messages
Browse files Browse the repository at this point in the history
fix enable messages
  • Loading branch information
rpiazza authored Jun 10, 2022
2 parents 6161cf2 + a1e3b8e commit 931b1fd
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 62 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
CHANGELOG
=========

4.1.6 - 2022-06-10

- fix functionality for --enable and --disable options

4.1.5 - 2022-02-04

- Additional fix for Hostname in SocketAddress in pattern
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ STIX 1.x content to STIX 2.x content:
file
stix2-elevator v4.1.5
stix2-elevator v4.1.6

positional arguments:

Expand Down
12 changes: 8 additions & 4 deletions docs/command-line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ STIX 1.x content to STIX 2.x content:
file
stix2-elevator v4.1.5
stix2-elevator v4.1.6

positional arguments:

Expand Down Expand Up @@ -84,14 +84,13 @@ optional arguments:
-e ENABLED, --enable ENABLED
A comma-separated list of the stix2-elevator messages
to enable. If the --disable option is not used, no
other messages will be shown.
to enable. Not to be used with --disable.
Example: --enable 250
-d DISABLED, --disable DISABLED
A comma-separated list of the stix2-elevator messages
to disable.
to disable. Not to be used with --enable.
Example: --disable 212,220
Expand Down Expand Up @@ -136,4 +135,9 @@ Refer to the :ref:`warning_messages` section for all stix2-elevator messages. Us
associated code number to ``--enable`` or ``--disable`` a message. By default, the
stix2-elevator displays all messages.

The --enable and --disable arguments cannot be used at the same time. When a message code is not specified in the --enable
option it will not be displayed. When a message code is not specified in the --disable
option it will be displayed. If the number of messages codes to be both enabled and disabled are both large, it is sufficient
to just specify the shorter one.

Note: disabling the message does not disable any functionality.
1 change: 1 addition & 0 deletions docs/warnings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ custom_property_prefix is provided, but the missing policy is not 'use-custom-pr
Custom properties/objects/extensions are deprecated in version 2.1. Suggest using 'use-extensions' instead 215 info
The missing policy option of 'use-extensions' cannot be used with version 2.0. 'use-custom-properies' is suggested 216 error
ACS data markings cannot be supported in version 2.0. --acs option is ignored. 217 warn
Only one of the options --enable and --disable can be used 218 error
================================================================================================================== ==== =====


Expand Down
15 changes: 8 additions & 7 deletions stix2elevator/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ def _get_arg_parser(is_script=True):
"-e",
"--enable",
help="A comma-separated list of the stix2-elevator messages to enable. "
"If the --disable option is not used, no other messages will be "
"shown. \n\nExample: stix2_elevator.py <file> --enable 250",
"Not to be used with --disable. \n\nExample: stix2_elevator.py <file> --enable 250",
dest="enabled",
default=None
)
Expand All @@ -125,7 +124,7 @@ def _get_arg_parser(is_script=True):
"-d",
"--disable",
help="A comma-separated list of the stix2-elevator messages to disable. \n\n"
"Example: stix2_elevator.py <file> --disable 212,220",
"Not to be used with --enable. \n\nExample: stix2_elevator.py <file> --disable 212,220",
dest="disabled",
default=None
)
Expand Down Expand Up @@ -208,10 +207,12 @@ def main():
elevator_parser = _get_arg_parser()
elevator_args = elevator_parser.parse_args()
sys.setrecursionlimit(3000)
initialize_options(options=elevator_args)
result = elevate(elevator_args.file_)
if result:
sys.stdout.write(result + "\n")
if initialize_options(options=elevator_args):
result = elevate(elevator_args.file_)
if result:
sys.stdout.write(result + "\n")
else:
sys.exit(1)
else:
sys.exit(1)

Expand Down
12 changes: 6 additions & 6 deletions stix2elevator/convert_pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@
from stix2elevator.convert_cybox import split_into_requests_and_responses
from stix2elevator.ids import (
add_id_value, exists_id_of_obs_in_characterizations,
exists_id_of_obs_in_sightings, exists_object_id_key,
get_id_value
exists_id_of_obs_in_sightings, exists_object_id_key, get_id_value
)
from stix2elevator.missing_policy import (
check_for_missing_policy, convert_to_custom_name,
get_extension_definition_id
)
from stix2elevator.options import error, get_option_value, info, warn
from stix2elevator.utils import (
encode_in_base64, find_key_in_dict_case_insensitive, identifying_info, map_vocabs_to_label
encode_in_base64, find_key_in_dict_case_insensitive, identifying_info,
map_vocabs_to_label
)
from stix2elevator.vocab_mappings import WINDOWS_PEBINARY

Expand Down Expand Up @@ -2772,9 +2772,9 @@ def remove_pattern_objects(bundle_instance):
if obj["type"] == "sighting" and "observed_data_refs" in obj:
for ref in obj["observed_data_refs"]:
if exists_id_of_obs_in_sightings(ref) and ref in all_new_ids_with_patterns:
warn("Observable object from pattern cannot be an observed_data_ref of a sighting. See %s",
644,
obj["id"])
warn("Observable object from pattern cannot be an observed_data_ref of a sighting. See %s",
644,
obj["id"])
new_remaining_objects = []
for obj in remaining_objects:
if obj["type"] == "relationship" and "source_ref" in obj and "target_ref" in obj:
Expand Down
25 changes: 12 additions & 13 deletions stix2elevator/convert_stix.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Standard Library
from datetime import datetime
from operator import attrgetter

# external
from cybox.core import Observable
from lxml import etree
from operator import attrgetter
import pycountry
import stix
from stix.campaign import Campaign
Expand Down Expand Up @@ -67,9 +67,10 @@
)
from stix2elevator.convert_to_acs import convert_edh_marking_to_acs_marking
from stix2elevator.ids import (
add_id_of_obs_in_characterizations, add_id_of_obs_in_sightings, add_id_value, add_object_id_value,
exists_id_key, exists_ids_with_no_1x_object, generate_stix2x_id,
get_id_value, get_id_values, get_type_from_id, is_stix1x_id, record_ids
add_id_of_obs_in_characterizations, add_id_of_obs_in_sightings,
add_id_value, add_object_id_value, exists_id_key,
exists_ids_with_no_1x_object, generate_stix2x_id, get_id_value,
get_id_values, get_type_from_id, is_stix1x_id, record_ids
)
from stix2elevator.missing_policy import (
check_for_missing_policy, convert_to_custom_name,
Expand All @@ -83,10 +84,10 @@
add_label, add_marking_map_entry, apply_ais_markings,
check_map_1x_markings_to_2x, convert_controlled_vocabs_to_open_vocabs,
convert_timestamp_of_stix_object, convert_timestamp_to_string,
convert_to_stix_literal, find_key_in_dict_case_insensitive, identifying_info, iterpath,
lookup_marking_reference, map_1x_markings_to_2x, map_vocabs_to_label,
operation_on_path, set_tlp_reference,
strftime_with_appropriate_fractional_seconds
convert_to_stix_literal, find_key_in_dict_case_insensitive,
identifying_info, iterpath, lookup_marking_reference,
map_1x_markings_to_2x, map_vocabs_to_label, operation_on_path,
set_tlp_reference, strftime_with_appropriate_fractional_seconds
)
from stix2elevator.vocab_mappings import (
ATTACK_MOTIVATION_MAP, COA_LABEL_MAP, INCIDENT_LABEL_MAP,
Expand Down Expand Up @@ -359,10 +360,8 @@ def create_basic_object(stix2x_type, stix1x_obj, env, parent_id=None, id_used=Fa
instance = {"type": stix2x_type}
if get_option_value("spec_version") == "2.1":
instance["spec_version"] = "2.1"
instance["id"] = generate_stix2x_id(stix2x_type, stix1x_obj.id_ if (stix1x_obj and
hasattr(stix1x_obj, "id_") and
stix1x_obj.id_) \
else parent_id,
instance["id"] = generate_stix2x_id(stix2x_type,
stix1x_obj.id_ if (stix1x_obj and hasattr(stix1x_obj, "id_") and stix1x_obj.id_) else parent_id,
id_used)
if stix1x_obj:
timestamp = convert_timestamp_of_stix_object(stix1x_obj, env.timestamp, True)
Expand Down Expand Up @@ -2268,7 +2267,7 @@ def process_ttp_properties(sdo_instance, ttp, env, kill_chains_in_sdo=True, mark
if ttp.exploit_targets is not None:
warn("Exploit targets are part of STIX 1x %s. Assuming they are related.",
646,
"TTP" + (" " + ttp.id_ if hasattr(ttp,"id_") else ""))
"TTP" + (" " + ttp.id_ if hasattr(ttp, "id_") else ""))
handle_relationship_to_refs(ttp.exploit_targets, sdo_instance["id"], env,
"targets", marking_refs=marking_refs)
if ttp.related_ttps:
Expand Down
8 changes: 5 additions & 3 deletions stix2elevator/ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

# internal
from stix2elevator.options import error, info, warn
from stix2elevator.utils import (find_key_in_dict_case_insensitive,
find_string_in_list_case_insensitive,
map_1x_type_to_20)
from stix2elevator.utils import (
find_key_in_dict_case_insensitive, find_string_in_list_case_insensitive,
map_1x_type_to_20
)


def record_ids(stix_id, new_id):
Expand Down Expand Up @@ -213,6 +214,7 @@ def add_object_id_value(key, value):
if not value:
warn("Can not associate %s with None", 611, key)


_ID_OF_OBSERVABLES_IN_SIGHTINGS = []


Expand Down
34 changes: 10 additions & 24 deletions stix2elevator/options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Standard Library
import copy
import logging
import os
import shlex
Expand Down Expand Up @@ -210,19 +209,9 @@ def disabled(self):

@disabled.setter
def disabled(self, disabled):
def remove_silent(item, elements):
try:
elements.remove(item)
except ValueError:
pass # suppress exception if value is not present
# Convert string of comma-separated checks to a list,
# and convert check code numbers to names. By default no messages are
# disabled.
if disabled:
self._disabled = _convert_to_int_list(disabled)
self._disabled = [x for x in self._disabled if x in CHECK_CODES]
for x in self._disabled:
remove_silent(x, self._enabled)
else:
self._disabled = []

Expand All @@ -232,21 +221,11 @@ def enabled(self):

@enabled.setter
def enabled(self, enabled):
def remove_silent(item, elements):
try:
elements.remove(item)
except ValueError:
pass # suppress exception if value is not present
# Convert string of comma-separated checks to a list,
# and convert check code numbers to names. By default all messages are
# enabled.
if enabled:
self._enabled = _convert_to_int_list(enabled)
self._enabled = [x for x in self._enabled if x in CHECK_CODES]
for x in self._enabled:
remove_silent(x, self._disabled)
else:
self._enabled = copy.deepcopy(CHECK_CODES)
self._enabled = []


def initialize_options(options=None):
Expand All @@ -259,6 +238,10 @@ def initialize_options(options=None):
else:
ALL_OPTIONS = ElevatorOptions(options)

if ALL_OPTIONS.disabled and ALL_OPTIONS.enabled:
error("Only one of the options --enable and --disable can be used", 218)
return False

if ALL_OPTIONS.silent and ALL_OPTIONS.message_log_directory:
info("Both console and output log have disabled messages.", 209)

Expand All @@ -284,6 +267,7 @@ def initialize_options(options=None):
if ALL_OPTIONS.acs and ALL_OPTIONS.spec_version == "2.0":
warn("ACS data markings cannot be supported in version 2.0. --acs option is ignored.", 217)
ALL_OPTIONS.acs = False
return True


def get_validator_options():
Expand Down Expand Up @@ -311,10 +295,12 @@ def msg_id_enabled(msg_id):
if get_option_value("silent"):
return False

if not get_option_value("disabled"):
if get_option_value("disabled"):
return not (msg_id in get_option_value("disabled"))
elif get_option_value("enabled"):
return msg_id in get_option_value("enabled")
else:
return not (msg_id in get_option_value("disabled"))
return True


# These codes are aligned with elevator_log_messages spreadsheet.
Expand Down
1 change: 1 addition & 0 deletions stix2elevator/test/test_idioms.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def id_2x(id):
except AttributeError:
return False


def name_property(path):
return "name" == path[0][-1]

Expand Down
34 changes: 33 additions & 1 deletion stix2elevator/test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def setup_options():
message_log_directory=None, output_directory=None, markings_allowed="", acs=False,
ignore_required_properties=False),
])
def test_setup_options(opts):
def test_setup_options_with_disabled(opts):
options.ALL_OPTIONS = None # To make sure we can set it again
initialize_options(opts)
assert get_option_value("policy") == "no_policy"
Expand All @@ -50,6 +50,38 @@ def test_setup_options(opts):
assert get_option_value("disabled") == [212, 901]


@pytest.mark.parametrize("opts", [
ElevatorOptions(policy="no_policy", spec_version=get_environment_variable_value('VERSION'), log_level="DEBUG", enabled=[212, 901]),
{"policy": "no_policy", "spec_version": get_environment_variable_value('VERSION'), "log_level": "DEBUG", "enabled": [212, 901]},
Namespace(policy="no_policy", spec_version=get_environment_variable_value('VERSION'), log_level="DEBUG", enabled="212,901",
file_=None, incidents=False, missing_policy=get_environment_variable_value("MISSING_POLICY"),
custom_property_prefix="elevator", infrastructure=False, package_created_by_id=None,
default_timestamp=None, validator_args="--strict-types", disabled=None, silent=False,
message_log_directory=None, output_directory=None, markings_allowed="", acs=False,
ignore_required_properties=False),
])
def test_setup_options_with_enabled(opts):
options.ALL_OPTIONS = None # To make sure we can set it again
initialize_options(opts)
assert get_option_value("policy") == "no_policy"
assert get_option_value("spec_version") == get_environment_variable_value('VERSION')
assert get_option_value("log_level") == "DEBUG"
assert get_option_value("enabled") == [212, 901]


@pytest.mark.parametrize("opts", [
Namespace(policy="no_policy", spec_version=get_environment_variable_value('VERSION'), log_level="DEBUG", enabled="212,901",
file_=None, incidents=False, missing_policy=get_environment_variable_value("MISSING_POLICY"),
custom_property_prefix="elevator", infrastructure=False, package_created_by_id=None,
default_timestamp=None, validator_args="--strict-types", disabled="902", silent=False,
message_log_directory=None, output_directory=None, markings_allowed="", acs=False,
ignore_required_properties=False),
])
def test_setup_options_with_enabled_and_disabled(opts):
options.ALL_OPTIONS = None # To make sure we can set it again
assert not initialize_options(opts)


def test_elevate_with_marking_container():
setup_options()

Expand Down
5 changes: 3 additions & 2 deletions stix2elevator/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
# internal
from stix2elevator.options import info, warn

def find_string_in_list_case_insensitive(item, l):

def find_string_in_list_case_insensitive(item, ls):
if item:
item_as_lower = item.lower()
for s in l:
for s in ls:
if item_as_lower == s.lower():
return True
return False
Expand Down
2 changes: 1 addition & 1 deletion stix2elevator/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "4.1.5"
__version__ = "4.1.6"

0 comments on commit 931b1fd

Please sign in to comment.