From cf3cfd16a9de05f30303b5952fbe609cde842d2e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 19 Apr 2021 09:59:58 -0700 Subject: [PATCH 01/55] rename tests --- tests/test_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 206d2fc7..23e5a6db 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -45,7 +45,7 @@ class MyTests(unittest.TestCase): for input_string, expected_output in datetime_map.items(): self.assertEqual(jc.utils.timestamp(input_string).__dict__, expected_output) - def test_convert_to_int(self): + def test_utils_convert_to_int(self): io_map = { None: None, True: 1, @@ -72,7 +72,7 @@ class MyTests(unittest.TestCase): for input_string, expected_output in io_map.items(): self.assertEqual(jc.utils.convert_to_int(input_string), expected_output) - def test_convert_to_float(self): + def test_utils_convert_to_float(self): io_map = { None: None, True: 1.0, @@ -99,7 +99,7 @@ class MyTests(unittest.TestCase): for input_string, expected_output in io_map.items(): self.assertEqual(jc.utils.convert_to_float(input_string), expected_output) - def test_convert_to_bool(self): + def test_utils_convert_to_bool(self): io_map = { None: False, True: True, From 7dcf87d24ad40eba6ba98de2b4b2bf177a76cd71 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 19 Apr 2021 13:12:55 -0700 Subject: [PATCH 02/55] formatting --- jc/parsers/ping.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jc/parsers/ping.py b/jc/parsers/ping.py index e8121062..60e5df27 100644 --- a/jc/parsers/ping.py +++ b/jc/parsers/ping.py @@ -94,7 +94,6 @@ Examples: ] } - $ ping -c 3 -p ff cnn.com | jc --ping -p -r { "destination_ip": "151.101.129.67", From 312d465b61a15592cc70d3734ad747b9a2be10ae Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 19 Apr 2021 14:18:12 -0700 Subject: [PATCH 03/55] update link --- templates/readme_template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/readme_template b/templates/readme_template index 0e655fdf..da61517a 100644 --- a/templates/readme_template +++ b/templates/readme_template @@ -102,7 +102,7 @@ pip3 install jc | FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` | | Ansible filter plugin | `ansible-galaxy collection install community.general` | -> For more packages and binaries, see https://kellyjonbrazil.github.io/jc-packaging/. +> For more packages and binaries, see the [jc packaging](https://kellyjonbrazil.github.io/jc-packaging/) site. ## Usage `jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`. From 9747ca414dfb8218389c7b2199a080edabc2a184 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 10:50:20 -0700 Subject: [PATCH 04/55] minor optimization to convert_to_int(). No longer runs through convert_to_float(), but uses standard float() function. --- jc/utils.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/jc/utils.py b/jc/utils.py index ea0e5d0e..c6ed4569 100644 --- a/jc/utils.py +++ b/jc/utils.py @@ -85,7 +85,7 @@ def has_data(data): def convert_to_int(value): """ - Converts string input to integer by stripping all non-numeric characters + Converts string and float input to int. Strips all non-numeric characters from strings. Parameters: @@ -96,11 +96,12 @@ def convert_to_int(value): integer/None Integer if successful conversion, otherwise None """ if isinstance(value, str): + str_val = re.sub(r'[^0-9\-\.]', '', value) try: - return int(re.sub(r'[^0-9\-\.]', '', value)) - except ValueError: + return int(str_val) + except (ValueError, TypeError): try: - return int(convert_to_float(value)) + return int(float(str_val)) except (ValueError, TypeError): return None @@ -113,7 +114,7 @@ def convert_to_int(value): def convert_to_float(value): """ - Converts string input to float by stripping all non-numeric characters + Converts string and int input to float. Strips all non-numeric characters from strings. Parameters: From b5145d6c14d7a51e7cfdebe126c9689dc90f7b27 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 13:39:12 -0700 Subject: [PATCH 05/55] version bump to v1.15.3 --- CHANGELOG | 3 +++ jc/__init__.py | 6 +++--- jc/cli.py | 1 + setup.py | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f5368223..c566cb50 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ jc changelog +20210420 v1.15.3 +- Add ufw status command parser tested on linux + 20210418 v1.15.2 - Add systeminfo parser tested on Windows - Update dig parser to fix an issue with IPv6 addresses in the server field diff --git a/jc/__init__.py b/jc/__init__.py index 3b6efae6..42fad9c8 100644 --- a/jc/__init__.py +++ b/jc/__init__.py @@ -62,12 +62,12 @@ Module Example: ... ;; Got answer: ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64612 ... ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 - ... + ... ... ;; OPT PSEUDOSECTION: ... ; EDNS: version: 0, flags:; udp: 4096 ... ;; QUESTION SECTION: ... ;example.com. IN A - ... + ... ... ;; ANSWER SECTION: ... example.com. 29658 IN A 93.184.216.34 ... @@ -86,4 +86,4 @@ Module Example: """ name = 'jc' -__version__ = '1.15.2' +__version__ = '1.15.3' diff --git a/jc/cli.py b/jc/cli.py index 08ad7d38..23c10b07 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -102,6 +102,7 @@ parsers = [ 'timedatectl', 'tracepath', 'traceroute', + 'ufw', 'uname', 'upower', 'uptime', diff --git a/setup.py b/setup.py index 96a983ba..4deef0b3 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open('README.md', 'r') as f: setuptools.setup( name='jc', - version='1.15.2', + version='1.15.3', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Converts the output of popular command-line tools and file-types to JSON.', From 9a0fb2a7c87e6fde0cc0d84fa8a1f131e28ea732 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 14:17:01 -0700 Subject: [PATCH 06/55] parse major sections --- jc/parsers/ufw.py | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 jc/parsers/ufw.py diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py new file mode 100644 index 00000000..ed1c1902 --- /dev/null +++ b/jc/parsers/ufw.py @@ -0,0 +1,157 @@ +"""jc - JSON CLI output utility `ufw` command output parser + +<> + +Usage (cli): + + $ ufw status | jc --ufw + + or + + $ jc ufw status + +Usage (module): + + import jc.parsers.ufw + result = jc.parsers.ufw.parse(ufw_command_output) + +Schema: + + [ + { + "ufw": string, + "bar": boolean, + "baz": integer + } + ] + +Examples: + + $ ufw status verbose | jc --ufw -p + [] + + $ ufw status verbose | jc --ufw -p -r + [] +""" +import jc.utils +import re + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`ufw status` command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + # details = 'enter any other details here' + + # compatible options: linux, darwin, cygwin, win32, aix, freebsd + compatible = ['linux'] + magic_commands = ['ufw status'] + + +__version__ = info.version + + +def _process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (List of Dictionaries) raw structured data to process + + Returns: + + List of Dictionaries. Structured to conform to the schema. + """ + + # rebuild output for added semantic information + # use helper functions in jc.utils for int, float, bool conversions and timestamps + + return proc_data + + +def _parse_to_from(linedata, direction): + return {} + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + List of Dictionaries. Raw or processed structured data. + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + raw_output = {} + rules_list = [] + + if jc.utils.has_data(data): + + rule_lines = False + + for line in filter(None, data.splitlines()): + + if line.startswith('Status: '): + raw_output['status'] = line.split(': ', maxsplit=1)[1] + continue + + if line.startswith('Logging: '): + raw_output['logging'] = line.split(': ', maxsplit=1)[1] + continue + + if line.startswith('Default: '): + raw_output['default'] = line.split(': ', maxsplit=1)[1] + continue + + if line.startswith('New profiles: '): + raw_output['new_profiles'] = line.split(': ', maxsplit=1)[1] + continue + + if 'To' in line and 'Action' in line and 'From' in line: + rule_lines = True + continue + + if rule_lines: + if '------' in line: + continue + + # Split on action. Left of Action is 'to', right of Action is 'from' + rule_obj = {} + + splitline = re.split(r'(ALLOW IN|ALLOW OUT|DENY IN|DENY OUT|ALLOW|DENY)', line) + to_line = splitline[0] + action_line = splitline[1] + action_list = action_line.split() + from_line = splitline[2] + action_direction = None + + if len(action_list) == 1: + action = action_list[0] + elif len(action_list) == 2: + action = action_list[0] + action_direction = action_list[1] + + rule_obj['action'] = action + rule_obj['action_direction'] = action_direction + rule_obj.update(_parse_to_from(to_line, 'to')) + rule_obj.update(_parse_to_from(from_line, 'from')) + + rules_list.append(rule_obj) + + raw_output['rules'] = rules_list + + if raw: + return raw_output + else: + return _process(raw_output) From eec673be9092e382694aa02682564510ce4e7f90 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 20:32:59 -0700 Subject: [PATCH 07/55] working raw parser --- jc/parsers/ufw.py | 91 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index ed1c1902..70da4703 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -35,6 +35,7 @@ Examples: """ import jc.utils import re +import ipaddress class info(): @@ -72,8 +73,92 @@ def _process(proc_data): return proc_data -def _parse_to_from(linedata, direction): - return {} +def _parse_to_from(linedata, direction, rule_obj=None): + + if rule_obj is None: + rule_obj = {} + + # pull out rule index, if they exist: [ 1] + if direction == 'to': + RE_LINE_NUM = re.compile(r'\[[ 0-9]+\]\s') + line_number_match = re.search(RE_LINE_NUM, linedata) + if line_number_match: + rule_obj['index'] = line_number_match.group(0).replace('[', '').replace(']', '').strip() + linedata = re.sub(RE_LINE_NUM, '', linedata) + else: + rule_obj['index'] = None + + # pull (v6) + RE_V6 = re.compile(r'\(v6\)') + v6_match = re.search(RE_V6, linedata) + if v6_match: + rule_obj['network_protocol'] = 'ipv6' + linedata = re.sub(RE_V6, '', linedata) + elif not rule_obj.get('network_protocol'): + rule_obj['network_protocol'] = 'ipv4' + + # pull 'Anywhere' if exists. Assign to 0.0.0.0/0 or ::/0 depending on if (v6) is found + if 'Anywhere' in linedata: + if rule_obj.get('network_protocol') == 'ipv6': + rule_obj[direction + '_ip'] = '::' + rule_obj[direction + '_subnet'] = '0' + elif rule_obj.get('network_protocol') == 'ipv4': + rule_obj[direction + '_ip'] = '0.0.0.0' + rule_obj[direction + '_subnet'] = '0' + linedata = linedata.replace('Anywhere', '') + + # pull out interface (after 'on') + linedata_list = linedata.split(' on ', maxsplit=1) + + if len(linedata_list) > 1: + rule_obj[direction + '_interface'] = linedata_list[1] + linedata = linedata_list[0] + else: + rule_obj[direction + '_interface'] = 'any' + + # pull out ipv4 or ipv6 addresses + linedata_list = linedata.split() + new_linedata_list = [] + + valid_ip = None + for item in linedata_list: + try: + valid_ip = ipaddress.IPv4Interface(item) + except Exception: + try: + valid_ip = ipaddress.IPv6Interface(item) + except Exception: + new_linedata_list.append(item) + + if valid_ip: + rule_obj[direction + '_ip'] = str(valid_ip.ip) + rule_obj[direction + '_subnet'] = str(valid_ip.with_prefixlen.split('/')[1]) + linedata = ' '.join(new_linedata_list) + + # pull out anything ending in 'udp', 'tcp'. strip on '/' for ports + linedata_list = linedata.split('/', maxsplit=1) + if len(linedata_list) > 1: + rule_obj[direction + '_transport'] = linedata_list[1].strip() + linedata = linedata_list[0] + else: + rule_obj[direction + '_transport'] = 'any' + + # find the numeric port(s) + linedata_list = linedata.split(':', maxsplit=1) + if len(linedata_list) == 2 and linedata_list[1].isnumeric(): + rule_obj[direction + '_start_port'] = linedata_list[0] + rule_obj[direction + '_end_port'] = linedata_list[1] + linedata = '' + elif len(linedata_list) == 1 and linedata_list[0].isnumeric(): + rule_obj[direction + '_start_port'] = linedata_list[0] + rule_obj[direction + '_end_port'] = linedata_list[0] + linedata = '' + + # only thing left should be the service name. + if linedata.strip(): + rule_obj[direction + '_service'] = linedata.strip() + + return rule_obj def parse(data, raw=False, quiet=False): @@ -145,7 +230,7 @@ def parse(data, raw=False, quiet=False): rule_obj['action'] = action rule_obj['action_direction'] = action_direction rule_obj.update(_parse_to_from(to_line, 'to')) - rule_obj.update(_parse_to_from(from_line, 'from')) + rule_obj.update(_parse_to_from(from_line, 'from', rule_obj)) rules_list.append(rule_obj) From 47e262cf7200b02ff0af97a70ffa6bec286c8f39 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 21:21:42 -0700 Subject: [PATCH 08/55] clean up fields --- jc/parsers/ufw.py | 73 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 70da4703..f7aec046 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -17,13 +17,35 @@ Usage (module): Schema: - [ - { - "ufw": string, - "bar": boolean, - "baz": integer - } - ] + { + "status": string, + "logging": string, + "logging_level": string, + "default": string, + "new_profiles": string, + "rules": [ + { + "action": string, + "action_direction": string, # null if blank + "index": string, # null if blank + "network_protocol": string, + "to_ip": string, + "to_subnet": integer, + "to_interface": string, + "to_transport": string, + "to_start_port": integer, # null if to_service is set + "to_end_port": integer, # null if to_service is set + "to_service": string, # null if start/end ports above set + "from_ip": string, + "from_subnet": integer, + "from_interface": string, + "from_transport": string, + "from_start_port": integer, # null if from_service is set + "from_end_port": integer, # null if from_service is set + "from_service": string, # null if start/end ports above set + } + ] + } Examples: @@ -145,18 +167,36 @@ def _parse_to_from(linedata, direction, rule_obj=None): # find the numeric port(s) linedata_list = linedata.split(':', maxsplit=1) - if len(linedata_list) == 2 and linedata_list[1].isnumeric(): - rule_obj[direction + '_start_port'] = linedata_list[0] - rule_obj[direction + '_end_port'] = linedata_list[1] + if len(linedata_list) == 2 and linedata_list[1].strip().isnumeric(): + rule_obj[direction + '_start_port'] = linedata_list[0].strip() + rule_obj[direction + '_end_port'] = linedata_list[1].strip() linedata = '' - elif len(linedata_list) == 1 and linedata_list[0].isnumeric(): - rule_obj[direction + '_start_port'] = linedata_list[0] - rule_obj[direction + '_end_port'] = linedata_list[0] + elif len(linedata_list) == 1 and linedata_list[0].strip().isnumeric(): + rule_obj[direction + '_start_port'] = linedata_list[0].strip() + rule_obj[direction + '_end_port'] = linedata_list[0].strip() linedata = '' # only thing left should be the service name. if linedata.strip(): rule_obj[direction + '_service'] = linedata.strip() + rule_obj[direction + '_start_port'] = None + rule_obj[direction + '_end_port'] = None + + # check if to/from IP addresses exist. If not, set to 0.0.0.0/0 or ::/0 + if direction + '_ip' not in rule_obj: + if rule_obj.get('network_protocol') == 'ipv6': + rule_obj[direction + '_ip'] = '::' + rule_obj[direction + '_subnet'] = '0' + elif rule_obj.get('network_protocol') == 'ipv4': + rule_obj[direction + '_ip'] = '0.0.0.0' + rule_obj[direction + '_subnet'] = '0' + + # finally ensure service or ports exist. If not, set default values + if not rule_obj.get(direction + '_service'): + if not rule_obj.get(direction + '_start_port'): + rule_obj[direction + '_start_port'] = '0' + rule_obj[direction + '_end_port'] = '65535' + rule_obj[direction + '_service'] = None return rule_obj @@ -192,7 +232,12 @@ def parse(data, raw=False, quiet=False): continue if line.startswith('Logging: '): - raw_output['logging'] = line.split(': ', maxsplit=1)[1] + log_line = line.split(': ', maxsplit=1) + log_line = log_line[1] + log_line = log_line.split() + raw_output['logging'] = log_line[0] + if len(log_line) == 2: + raw_output['logging_level'] = log_line[1].replace('(', '').replace(')', '').strip() continue if line.startswith('Default: '): From ea1d820f96321ddf4084b54ee2fdf397295beb21 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 21:29:49 -0700 Subject: [PATCH 09/55] convert integer fields --- jc/parsers/ufw.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index f7aec046..b854b5b9 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -27,7 +27,7 @@ Schema: { "action": string, "action_direction": string, # null if blank - "index": string, # null if blank + "index": integer, # null if blank "network_protocol": string, "to_ip": string, "to_subnet": integer, @@ -88,9 +88,12 @@ def _process(proc_data): List of Dictionaries. Structured to conform to the schema. """ - - # rebuild output for added semantic information - # use helper functions in jc.utils for int, float, bool conversions and timestamps + int_list = ['index', 'to_subnet', 'to_start_port', 'to_end_port', 'from_subnet', + 'from_start_port', 'from_end_port'] + for i, item in enumerate(proc_data['rules']): + for key in item: + if key in int_list: + proc_data['rules'][i][key] = jc.utils.convert_to_int(proc_data['rules'][i][key]) return proc_data From 5be615a97e7c145c8351764234ac591028560c34 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 21:45:13 -0700 Subject: [PATCH 10/55] add examples for docs --- jc/parsers/ufw.py | 228 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 219 insertions(+), 9 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index b854b5b9..96a1d0ad 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -1,6 +1,4 @@ -"""jc - JSON CLI output utility `ufw` command output parser - -<> +"""jc - JSON CLI output utility `ufw status` command output parser Usage (cli): @@ -49,11 +47,223 @@ Schema: Examples: - $ ufw status verbose | jc --ufw -p - [] + $ ufw status verbose numbered | jc --ufw -p + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": 1, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_ip": "0.0.0.0", + "to_subnet": 0, + "from_ip": "0.0.0.0", + "from_subnet": 0, + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 2, + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_ip": "::", + "to_subnet": 0, + "from_ip": "::", + "from_subnet": 0, + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 3, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "any", + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_subnet": 0, + "from_ip": "0.0.0.0", + "from_subnet": 0, + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 4, + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_subnet": 128, + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "::", + "from_subnet": 0, + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 5, + "network_protocol": "ipv4", + "to_interface": "en0 ", + "to_ip": "10.10.10.10", + "to_subnet": 32, + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "0.0.0.0", + "from_subnet": 0, + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + } + ] + } - $ ufw status verbose | jc --ufw -p -r - [] + $ ufw status verbose numbered | jc --ufw -p -r + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": "1", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_ip": "0.0.0.0", + "to_subnet": "0", + "from_ip": "0.0.0.0", + "from_subnet": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "2", + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_ip": "::", + "to_subnet": "0", + "from_ip": "::", + "from_subnet": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "3", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "any", + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_subnet": "0", + "from_ip": "0.0.0.0", + "from_subnet": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "4", + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_subnet": "128", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "::", + "from_subnet": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "5", + "network_protocol": "ipv4", + "to_interface": "en0 ", + "to_ip": "10.10.10.10", + "to_subnet": "32", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "0.0.0.0", + "from_subnet": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + } + ] + } """ import jc.utils import re @@ -86,7 +296,7 @@ def _process(proc_data): Returns: - List of Dictionaries. Structured to conform to the schema. + Dictionary. Structured to conform to the schema. """ int_list = ['index', 'to_subnet', 'to_start_port', 'to_end_port', 'from_subnet', 'from_start_port', 'from_end_port'] @@ -216,7 +426,7 @@ def parse(data, raw=False, quiet=False): Returns: - List of Dictionaries. Raw or processed structured data. + Dictionary. Raw or processed structured data. """ if not quiet: jc.utils.compatibility(__name__, info.compatible) From b133d1f90d49362594508d8c475663754f0e7675 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 21:52:39 -0700 Subject: [PATCH 11/55] strip interface value --- jc/parsers/ufw.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 96a1d0ad..e9f9ed41 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -138,7 +138,7 @@ Examples: "action_direction": "IN", "index": 5, "network_protocol": "ipv4", - "to_interface": "en0 ", + "to_interface": "en0", "to_ip": "10.10.10.10", "to_subnet": 32, "to_transport": "any", @@ -247,7 +247,7 @@ Examples: "action_direction": "IN", "index": "5", "network_protocol": "ipv4", - "to_interface": "en0 ", + "to_interface": "en0", "to_ip": "10.10.10.10", "to_subnet": "32", "to_transport": "any", @@ -346,7 +346,7 @@ def _parse_to_from(linedata, direction, rule_obj=None): linedata_list = linedata.split(' on ', maxsplit=1) if len(linedata_list) > 1: - rule_obj[direction + '_interface'] = linedata_list[1] + rule_obj[direction + '_interface'] = linedata_list[1].strip() linedata = linedata_list[0] else: rule_obj[direction + '_interface'] = 'any' From d46fc8bbfa15a80a1af6c64f70230f858c215223 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 21:58:52 -0700 Subject: [PATCH 12/55] set to/from_transport to None if to/from_service is set --- jc/parsers/ufw.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index e9f9ed41..71df9295 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -30,17 +30,17 @@ Schema: "to_ip": string, "to_subnet": integer, "to_interface": string, - "to_transport": string, + "to_transport": string, # null if to_service is set "to_start_port": integer, # null if to_service is set "to_end_port": integer, # null if to_service is set - "to_service": string, # null if start/end ports above set + "to_service": string, # null if any above are set "from_ip": string, "from_subnet": integer, "from_interface": string, - "from_transport": string, + "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set "from_end_port": integer, # null if from_service is set - "from_service": string, # null if start/end ports above set + "from_service": string, # null if any above are set } ] } @@ -394,6 +394,7 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_service'] = linedata.strip() rule_obj[direction + '_start_port'] = None rule_obj[direction + '_end_port'] = None + rule_obj[direction + '_transport'] = None # check if to/from IP addresses exist. If not, set to 0.0.0.0/0 or ::/0 if direction + '_ip' not in rule_obj: From c60549a9947d5684bbfa58223bfbcfc40a3ed479 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Tue, 20 Apr 2021 22:08:12 -0700 Subject: [PATCH 13/55] change field name from to/from_subnet to to/from_ip_prefix --- jc/parsers/ufw.py | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 71df9295..18305e5c 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -28,14 +28,14 @@ Schema: "index": integer, # null if blank "network_protocol": string, "to_ip": string, - "to_subnet": integer, + "to_ip_prefix": integer, "to_interface": string, "to_transport": string, # null if to_service is set "to_start_port": integer, # null if to_service is set "to_end_port": integer, # null if to_service is set "to_service": string, # null if any above are set "from_ip": string, - "from_subnet": integer, + "from_ip_prefix": integer, "from_interface": string, "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set @@ -65,9 +65,9 @@ Examples: "to_start_port": 22, "to_end_port": 22, "to_ip": "0.0.0.0", - "to_subnet": 0, + "to_ip_prefix": "0", "from_ip": "0.0.0.0", - "from_subnet": 0, + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -84,9 +84,9 @@ Examples: "to_start_port": 22, "to_end_port": 22, "to_ip": "::", - "to_subnet": 0, + "to_ip_prefix": "0", "from_ip": "::", - "from_subnet": 0, + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -99,14 +99,14 @@ Examples: "index": 3, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": "any", + "to_transport": null, "to_service": "Apache Full", "to_start_port": null, "to_end_port": null, "to_ip": "0.0.0.0", - "to_subnet": 0, + "to_ip_prefix": "0", "from_ip": "0.0.0.0", - "from_subnet": 0, + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -120,13 +120,13 @@ Examples: "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_subnet": 128, + "to_ip_prefix": "128", "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "from_ip": "::", - "from_subnet": 0, + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -140,13 +140,13 @@ Examples: "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", - "to_subnet": 32, + "to_ip_prefix": "32", "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "from_ip": "0.0.0.0", - "from_subnet": 0, + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -174,9 +174,9 @@ Examples: "to_start_port": "22", "to_end_port": "22", "to_ip": "0.0.0.0", - "to_subnet": "0", + "to_ip_prefix": "0", "from_ip": "0.0.0.0", - "from_subnet": "0", + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": "0", @@ -193,9 +193,9 @@ Examples: "to_start_port": "22", "to_end_port": "22", "to_ip": "::", - "to_subnet": "0", + "to_ip_prefix": "0", "from_ip": "::", - "from_subnet": "0", + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": "0", @@ -208,14 +208,14 @@ Examples: "index": "3", "network_protocol": "ipv4", "to_interface": "any", - "to_transport": "any", + "to_transport": null, "to_service": "Apache Full", "to_start_port": null, "to_end_port": null, "to_ip": "0.0.0.0", - "to_subnet": "0", + "to_ip_prefix": "0", "from_ip": "0.0.0.0", - "from_subnet": "0", + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": "0", @@ -229,13 +229,13 @@ Examples: "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_subnet": "128", + "to_ip_prefix": "128", "to_transport": "any", "to_start_port": "0", "to_end_port": "65535", "to_service": null, "from_ip": "::", - "from_subnet": "0", + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": "0", @@ -249,13 +249,13 @@ Examples: "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", - "to_subnet": "32", + "to_ip_prefix": "32", "to_transport": "any", "to_start_port": "0", "to_end_port": "65535", "to_service": null, "from_ip": "0.0.0.0", - "from_subnet": "0", + "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", "from_start_port": "0", @@ -336,10 +336,10 @@ def _parse_to_from(linedata, direction, rule_obj=None): if 'Anywhere' in linedata: if rule_obj.get('network_protocol') == 'ipv6': rule_obj[direction + '_ip'] = '::' - rule_obj[direction + '_subnet'] = '0' + rule_obj[direction + '_ip_prefix'] = '0' elif rule_obj.get('network_protocol') == 'ipv4': rule_obj[direction + '_ip'] = '0.0.0.0' - rule_obj[direction + '_subnet'] = '0' + rule_obj[direction + '_ip_prefix'] = '0' linedata = linedata.replace('Anywhere', '') # pull out interface (after 'on') @@ -367,7 +367,7 @@ def _parse_to_from(linedata, direction, rule_obj=None): if valid_ip: rule_obj[direction + '_ip'] = str(valid_ip.ip) - rule_obj[direction + '_subnet'] = str(valid_ip.with_prefixlen.split('/')[1]) + rule_obj[direction + '_ip_prefix'] = str(valid_ip.with_prefixlen.split('/')[1]) linedata = ' '.join(new_linedata_list) # pull out anything ending in 'udp', 'tcp'. strip on '/' for ports @@ -400,10 +400,10 @@ def _parse_to_from(linedata, direction, rule_obj=None): if direction + '_ip' not in rule_obj: if rule_obj.get('network_protocol') == 'ipv6': rule_obj[direction + '_ip'] = '::' - rule_obj[direction + '_subnet'] = '0' + rule_obj[direction + '_ip_prefix'] = '0' elif rule_obj.get('network_protocol') == 'ipv4': rule_obj[direction + '_ip'] = '0.0.0.0' - rule_obj[direction + '_subnet'] = '0' + rule_obj[direction + '_ip_prefix'] = '0' # finally ensure service or ports exist. If not, set default values if not rule_obj.get(direction + '_service'): From e4acb3d5b70a7d75741ef3e35cd6750d1362a80f Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 07:08:50 -0700 Subject: [PATCH 14/55] always make to/from_service None if ports are assigned --- jc/parsers/ufw.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 18305e5c..b43e3bbe 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -380,13 +380,15 @@ def _parse_to_from(linedata, direction, rule_obj=None): # find the numeric port(s) linedata_list = linedata.split(':', maxsplit=1) - if len(linedata_list) == 2 and linedata_list[1].strip().isnumeric(): + if len(linedata_list) == 2 and linedata_list[0].strip().isnumeric(): rule_obj[direction + '_start_port'] = linedata_list[0].strip() rule_obj[direction + '_end_port'] = linedata_list[1].strip() + rule_obj[direction + '_service'] = None linedata = '' elif len(linedata_list) == 1 and linedata_list[0].strip().isnumeric(): rule_obj[direction + '_start_port'] = linedata_list[0].strip() rule_obj[direction + '_end_port'] = linedata_list[0].strip() + rule_obj[direction + '_service'] = None linedata = '' # only thing left should be the service name. From 733196103897a1d84d242324ddcf96e783320329 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 07:41:32 -0700 Subject: [PATCH 15/55] update docs with new examples that have `to_service` always existing. --- jc/parsers/ufw.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index b43e3bbe..6762ccd2 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -64,6 +64,7 @@ Examples: "to_transport": "tcp", "to_start_port": 22, "to_end_port": 22, + "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", "from_ip": "0.0.0.0", @@ -83,6 +84,7 @@ Examples: "to_transport": "tcp", "to_start_port": 22, "to_end_port": 22, + "to_service": null, "to_ip": "::", "to_ip_prefix": "0", "from_ip": "::", @@ -173,6 +175,7 @@ Examples: "to_transport": "tcp", "to_start_port": "22", "to_end_port": "22", + "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", "from_ip": "0.0.0.0", @@ -192,6 +195,7 @@ Examples: "to_transport": "tcp", "to_start_port": "22", "to_end_port": "22", + "to_service": null, "to_ip": "::", "to_ip_prefix": "0", "from_ip": "::", From 4eeec087bde98f90ab8425473d1fbeee6834852e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 07:49:49 -0700 Subject: [PATCH 16/55] add ufw example --- EXAMPLES.md | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 9342d4fe..34dd6520 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3126,6 +3126,121 @@ traceroute -m 3 8.8.8.8 | jc --traceroute -p # or: jc -p traceroute -m ] } ``` +### ufw status +```bash +ufw status verbose numbered | jc --ufw -p +``` +```json +{ + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": 1, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 2, + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "::", + "to_ip_prefix": "0", + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 3, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": null, + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 4, + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_ip_prefix": "128", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 5, + "network_protocol": "ipv4", + "to_interface": "en0", + "to_ip": "10.10.10.10", + "to_ip_prefix": "32", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + } + ] +} +``` ### uname -a ```bash uname -a | jc --uname -p # or: jc -p uname -a From 23635def8b654097178f73ed1b57fc50965142d5 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 07:51:32 -0700 Subject: [PATCH 17/55] add ufw to docs --- README.md | 3 +- docs/parsers/ping.md | 1 - docs/parsers/ufw.md | 302 +++++++++++++++++++++++++++++++++++++++++++ docs/utils.md | 4 +- jc/man/jc.1.gz | Bin 2062 -> 2068 bytes man/jc.1.gz | Bin 2062 -> 2068 bytes 6 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 docs/parsers/ufw.md diff --git a/README.md b/README.md index d9c49018..584f2ed3 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ pip3 install jc | FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` | | Ansible filter plugin | `ansible-galaxy collection install community.general` | -> For more packages and binaries, see https://kellyjonbrazil.github.io/jc-packaging/. +> For more packages and binaries, see the [jc packaging](https://kellyjonbrazil.github.io/jc-packaging/) site. ## Usage `jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`. @@ -182,6 +182,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--timedatectl` enables the `timedatectl status` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/timedatectl)) - `--tracepath` enables the `tracepath` and `tracepath6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/tracepath)) - `--traceroute` enables the `traceroute` and `traceroute6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/traceroute)) +- `--ufw` enables the `ufw status` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw)) - `--uname` enables the `uname -a` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uname)) - `--upower` enables the `upower` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/upower)) - `--uptime` enables the `uptime` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime)) diff --git a/docs/parsers/ping.md b/docs/parsers/ping.md index 3e7db2b5..fe0c0bc6 100644 --- a/docs/parsers/ping.md +++ b/docs/parsers/ping.md @@ -97,7 +97,6 @@ Examples: ] } - $ ping -c 3 -p ff cnn.com | jc --ping -p -r { "destination_ip": "151.101.129.67", diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md new file mode 100644 index 00000000..750c7026 --- /dev/null +++ b/docs/parsers/ufw.md @@ -0,0 +1,302 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.ufw +jc - JSON CLI output utility `ufw status` command output parser + +Usage (cli): + + $ ufw status | jc --ufw + + or + + $ jc ufw status + +Usage (module): + + import jc.parsers.ufw + result = jc.parsers.ufw.parse(ufw_command_output) + +Schema: + + { + "status": string, + "logging": string, + "logging_level": string, + "default": string, + "new_profiles": string, + "rules": [ + { + "action": string, + "action_direction": string, # null if blank + "index": integer, # null if blank + "network_protocol": string, + "to_ip": string, + "to_ip_prefix": integer, + "to_interface": string, + "to_transport": string, # null if to_service is set + "to_start_port": integer, # null if to_service is set + "to_end_port": integer, # null if to_service is set + "to_service": string, # null if any above are set + "from_ip": string, + "from_ip_prefix": integer, + "from_interface": string, + "from_transport": string, # null if from_service is set + "from_start_port": integer, # null if from_service is set + "from_end_port": integer, # null if from_service is set + "from_service": string, # null if any above are set + } + ] + } + +Examples: + + $ ufw status verbose numbered | jc --ufw -p + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": 1, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 2, + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": 22, + "to_end_port": 22, + "to_service": null, + "to_ip": "::", + "to_ip_prefix": "0", + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 3, + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": null, + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 4, + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_ip_prefix": "128", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": 5, + "network_protocol": "ipv4", + "to_interface": "en0", + "to_ip": "10.10.10.10", + "to_ip_prefix": "32", + "to_transport": "any", + "to_start_port": 0, + "to_end_port": 65535, + "to_service": null, + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": 0, + "from_end_port": 65535, + "from_service": null + } + ] + } + + $ ufw status verbose numbered | jc --ufw -p -r + { + "status": "active", + "logging": "on", + "logging_level": "low", + "default": "deny (incoming), allow (outgoing), deny (routed)", + "new_profiles": "skip", + "rules": [ + { + "action": "ALLOW", + "action_direction": "IN", + "index": "1", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_service": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "2", + "network_protocol": "ipv6", + "to_interface": "any", + "to_transport": "tcp", + "to_start_port": "22", + "to_end_port": "22", + "to_service": null, + "to_ip": "::", + "to_ip_prefix": "0", + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "3", + "network_protocol": "ipv4", + "to_interface": "any", + "to_transport": null, + "to_service": "Apache Full", + "to_start_port": null, + "to_end_port": null, + "to_ip": "0.0.0.0", + "to_ip_prefix": "0", + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "4", + "network_protocol": "ipv6", + "to_interface": "any", + "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", + "to_ip_prefix": "128", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "::", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + }, + { + "action": "ALLOW", + "action_direction": "IN", + "index": "5", + "network_protocol": "ipv4", + "to_interface": "en0", + "to_ip": "10.10.10.10", + "to_ip_prefix": "32", + "to_transport": "any", + "to_start_port": "0", + "to_end_port": "65535", + "to_service": null, + "from_ip": "0.0.0.0", + "from_ip_prefix": "0", + "from_interface": "any", + "from_transport": "any", + "from_start_port": "0", + "from_end_port": "65535", + "from_service": null + } + ] + } + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + +Returns: + + Dictionary. Raw or processed structured data. + +## Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/utils.md b/docs/utils.md index e245fd8c..1cac00ed 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -74,7 +74,7 @@ Returns: convert_to_int(value) ``` -Converts string input to integer by stripping all non-numeric characters +Converts string and float input to int. Strips all non-numeric characters from strings. Parameters: @@ -90,7 +90,7 @@ Returns: convert_to_float(value) ``` -Converts string input to float by stripping all non-numeric characters +Converts string and int input to float. Strips all non-numeric characters from strings. Parameters: diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index d860a611e53e602cfe3e64ecfcb42ecaff3b921e..3ceb719e859e2b709804f30494fa9c446a522498 100644 GIT binary patch literal 2068 zcmV+v2#@$#2no#>O`jrYc)jmQ_|}($*)zAi8F=(ex?+$-9stPNq^AW;db% ztCZ!us7c-`l^Mp1grzbQp{+|{NJ;c{HeW=OC>YPD)6wjb{TH2CjBcZ=TlU9%v7F3j z(Vsz}G$>okn3=k;{P`k4%e(K)O9!O$@+unNPUsV&{x9cP3Kj)7QfO9kZDg@#vS23G zvb1J^PVzVwK(kVoB7u*nHq|O;cj?Dyc{!Qgr3=#POo9b+g=tZ0VFXOWN>!jI=ogGV zNmUsZs~kK_{$d(et@0Y@pO&CbL-RwM&9FVQd4C@Hx?H2?!yndc&r+=5~F1~C!`x};%i@TwTF z)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK7J-gF|8m2R!-2-dx0j!yClQvP_~6=z4m^X62pFQkkHNbmO|gV>n)0H z1+g8G@Rg^p?8vm`dc*XH6jYNZvq^{b5;7qZ&fkXVQM(Nd96?TE%M$U#{(%2vEdFHp zp!~QMm;b)#z;`K>n+_>`u315(rTy^WuoFkd(gTblbkwEo#PdaUXxrn#yLH%Fqn!G*A}!5!SwJp#7;?$AK6u;;kMi^n$EXSm}#QoMv>MsOtj z`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSE zw|pAswCQnrmj(SPU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR` zzNDopq@{EFO^RfZs+JaHyTz=`T_z1HqlYV53~{7i25)9f#9KVW#jSc=wVK1Dh+B8) z?l`|0cl^(9(6ZkNd$z5I26_}#smpfweUtlD!F|k#Vj=Irmul;8QjY9{@7BbT-Eil7 zPhHu@4i)#nHZFPKw;TAJ)5?FD-n?EGYVJT^N5?35vt0#)1ws8g(!b+c@*HLP3f2#w zl&AD4c5mHxZ5WmQM64>fOjChnwC*b&KeAH-Ac7w1@N``%Blds;MU;#ik(Ewt!|-fD zf4}+VCLR8gm#DbPo5%Tq8oCaC&Eg8~mw3I+ls4>1a(cvr&fmu0#`Bx`ZG=IACx?VrAO?dyaV_!AHeky)BAMln z)JCba%Qt3V>uabb32a4;y@)5gZW(N=p!rl~ncCvGo5@8G?2P>5?~kI!#rj4*|MLv_ zt3z;ERhv{-=G8wyGU*y^*FNyyy3%H9Jr{HEj9^H%uN8Fi z8VOA80`7wCCFl_F8=17W;%};zTY|yPVe*uOa8tuV!Xo2JLPe0rJ`;kvoZ2-U2@DTY z19vDWJr>pvd{QanS-Ig*2!xig>*qokv~_JO&N8UW-~?;?;BrVo71c7?XT1Li4!brc z7Cqit$HT<&rOWk~zg+&xK5_`~ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh z7M{-;EW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;P4O)JHr=(`Qq#C yWtEkgwDn04#n)^)oLmJUc^5Lo$(0m_*^Owx zYQ=J1)Ff|}$_(R0%2qNHp{+|{NJ;#4I-AGiI2g?)li~D|{TH2?4{zhETlU9nz8KG@ z@t;AUG$>okgqgaq{P`k4%e(K)O9!O$@+uzPj_DJk{x9d)3M>k4q|mJ7+Q?$fWWh|L zWob=>PVyuXK(kVoB888rcBNI$?p7b;#pQTKZABWfS&4p`MoGyHssR|t$~+gTn#Ec{Ei{V506R zlJ1G>6w?YKVCe)My%%Ugyh}2y4rN<-wv~2+L8Y7hJJMjDP<9l5e%(q6u|o!s=$=Zt za==v&Os*YHuKR%619cBDm#Iip>K$#k9-;Da9cE4fNET*2c(=}J)eRE`t?51db^~$6 z35i4>v{(!6!ASPNweXsO=z*Fh_6EWx17h!A4~Df?Rk?=~+XXipo~mt2zzuYWY`EDF z9*J(>5#f)VCy(Il^gd62#1nW12N5ttfgjPkBTb2fbh`3!x#N1wOJkL;ort4*1eCF6 zzZS%Htc1@zeQ8IoTCO)tk4Ql|c|09=ST7+GGU5Dfm>#v;(7+YsB(^LSPwWr)PbT6| zh9A16AJozrL!uk{NGI$!Q4c=ztP-zJBICy0CrJ2&jO4Ogf94#?Odkwx1&;)(51gyi zgMsP;tCh#9o@AP4T<%kK^i1PgnvOMG~2(|v?Hz9Ym-NM-~_ z!tW1~KlRv=Wtd67wZJfB`bEsfry>+Vrbom@LD>@pkOKV$NmLKG%){^QK?EcNx*LC- zKYP=saZZ~ar*~1%9|EQ}iFMbcBYWXiAELN(e1=(&fD{~h~gUaZ^QWgUo>6gKmS+n9Tp5f+JJ+4~Kp(x_k zUAjBYAI2U3(;KwxPr{yU>!E=jMODH58W6=o-h(gI*1wD#*$3aPu_L?T?&S64iEZLg zNe^t}f&qTJfzLVZ&Lw24)k?+jDi~MDv0I;^>v}I%UbdrW%&~J153nHDso-z z`mPP5RGx}u1&?D&n2h#u$&*KRN&rMq;SHteQW>!a94MmT+K8-lVjG5c1^WBVZ#U`i zkG51LRo)ca2Wsf4m#ac08>rfw&OjSMZ&N6qt;HHz7WM@UU1;AcDJ;$k$|9)k4cl^E zz|CXYNQx`Xx2&~5?eFvqftefZ3gGe9IXUeL|1btC}Sh zychAgnkjAAljKyCgU(+^-$t{W*=>xA0wsimsty-}J#j7Z4HmJ*8Y`#@@mcKA#M>NznXCWtrOIxSPpE5bTWn^B<3*#?AUhKL6_s`K{9FjxVZw z2^-q5&Vpxy;P;KtqM0w(;sU3z%pg#}{WD~=NE>nuWlPa8wLq^LZV3)Ibk5fpCJmd^ zyx42t^-e^~^~N69azibPZs5SK8#=P?RqcInBS)UN!L~o!jkHb%;vD!?taz2t6&(DG zeXD1lmzg-jri~G{>G*hYwRBq$?HndgNeB-$Y$R+l?j&RcdF(SGsB5WR1ChW`Xc~AELF%!v zf8di^F`kth4v9c$nYjKeEQ7YL4aHdoc^RBwZ690=DafK)ru&HZAHiYQmc*pTTl;tz zI6if`e({&fU)V+ikQ~Y7JQz z5~yo*w>nsCcjHhfOsLy^sKpB)=mm{V?&nvoz9Su*#$wYyql+G9GW@i-p4~z@oWUl1 z)cij(W2cYEJ*Z+y{J+;Zml>LT7X%w?OLH+8tYK5CB@PY_(Qq<+BACs;-j08{UIZgm s)|6-1Y4VPJcz^!)5dZkV+D0L^pwur6>=v7h7tC}21HsX8nywfC0P6|yoB#j- diff --git a/man/jc.1.gz b/man/jc.1.gz index d860a611e53e602cfe3e64ecfcb42ecaff3b921e..3ceb719e859e2b709804f30494fa9c446a522498 100644 GIT binary patch literal 2068 zcmV+v2#@$#2no#>O`jrYc)jmQ_|}($*)zAi8F=(ex?+$-9stPNq^AW;db% ztCZ!us7c-`l^Mp1grzbQp{+|{NJ;c{HeW=OC>YPD)6wjb{TH2CjBcZ=TlU9%v7F3j z(Vsz}G$>okn3=k;{P`k4%e(K)O9!O$@+unNPUsV&{x9cP3Kj)7QfO9kZDg@#vS23G zvb1J^PVzVwK(kVoB7u*nHq|O;cj?Dyc{!Qgr3=#POo9b+g=tZ0VFXOWN>!jI=ogGV zNmUsZs~kK_{$d(et@0Y@pO&CbL-RwM&9FVQd4C@Hx?H2?!yndc&r+=5~F1~C!`x};%i@TwTF z)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK7J-gF|8m2R!-2-dx0j!yClQvP_~6=z4m^X62pFQkkHNbmO|gV>n)0H z1+g8G@Rg^p?8vm`dc*XH6jYNZvq^{b5;7qZ&fkXVQM(Nd96?TE%M$U#{(%2vEdFHp zp!~QMm;b)#z;`K>n+_>`u315(rTy^WuoFkd(gTblbkwEo#PdaUXxrn#yLH%Fqn!G*A}!5!SwJp#7;?$AK6u;;kMi^n$EXSm}#QoMv>MsOtj z`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSE zw|pAswCQnrmj(SPU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR` zzNDopq@{EFO^RfZs+JaHyTz=`T_z1HqlYV53~{7i25)9f#9KVW#jSc=wVK1Dh+B8) z?l`|0cl^(9(6ZkNd$z5I26_}#smpfweUtlD!F|k#Vj=Irmul;8QjY9{@7BbT-Eil7 zPhHu@4i)#nHZFPKw;TAJ)5?FD-n?EGYVJT^N5?35vt0#)1ws8g(!b+c@*HLP3f2#w zl&AD4c5mHxZ5WmQM64>fOjChnwC*b&KeAH-Ac7w1@N``%Blds;MU;#ik(Ewt!|-fD zf4}+VCLR8gm#DbPo5%Tq8oCaC&Eg8~mw3I+ls4>1a(cvr&fmu0#`Bx`ZG=IACx?VrAO?dyaV_!AHeky)BAMln z)JCba%Qt3V>uabb32a4;y@)5gZW(N=p!rl~ncCvGo5@8G?2P>5?~kI!#rj4*|MLv_ zt3z;ERhv{-=G8wyGU*y^*FNyyy3%H9Jr{HEj9^H%uN8Fi z8VOA80`7wCCFl_F8=17W;%};zTY|yPVe*uOa8tuV!Xo2JLPe0rJ`;kvoZ2-U2@DTY z19vDWJr>pvd{QanS-Ig*2!xig>*qokv~_JO&N8UW-~?;?;BrVo71c7?XT1Li4!brc z7Cqit$HT<&rOWk~zg+&xK5_`~ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh z7M{-;EW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;P4O)JHr=(`Qq#C yWtEkgwDn04#n)^)oLmJUc^5Lo$(0m_*^Owx zYQ=J1)Ff|}$_(R0%2qNHp{+|{NJ;#4I-AGiI2g?)li~D|{TH2?4{zhETlU9nz8KG@ z@t;AUG$>okgqgaq{P`k4%e(K)O9!O$@+uzPj_DJk{x9d)3M>k4q|mJ7+Q?$fWWh|L zWob=>PVyuXK(kVoB888rcBNI$?p7b;#pQTKZABWfS&4p`MoGyHssR|t$~+gTn#Ec{Ei{V506R zlJ1G>6w?YKVCe)My%%Ugyh}2y4rN<-wv~2+L8Y7hJJMjDP<9l5e%(q6u|o!s=$=Zt za==v&Os*YHuKR%619cBDm#Iip>K$#k9-;Da9cE4fNET*2c(=}J)eRE`t?51db^~$6 z35i4>v{(!6!ASPNweXsO=z*Fh_6EWx17h!A4~Df?Rk?=~+XXipo~mt2zzuYWY`EDF z9*J(>5#f)VCy(Il^gd62#1nW12N5ttfgjPkBTb2fbh`3!x#N1wOJkL;ort4*1eCF6 zzZS%Htc1@zeQ8IoTCO)tk4Ql|c|09=ST7+GGU5Dfm>#v;(7+YsB(^LSPwWr)PbT6| zh9A16AJozrL!uk{NGI$!Q4c=ztP-zJBICy0CrJ2&jO4Ogf94#?Odkwx1&;)(51gyi zgMsP;tCh#9o@AP4T<%kK^i1PgnvOMG~2(|v?Hz9Ym-NM-~_ z!tW1~KlRv=Wtd67wZJfB`bEsfry>+Vrbom@LD>@pkOKV$NmLKG%){^QK?EcNx*LC- zKYP=saZZ~ar*~1%9|EQ}iFMbcBYWXiAELN(e1=(&fD{~h~gUaZ^QWgUo>6gKmS+n9Tp5f+JJ+4~Kp(x_k zUAjBYAI2U3(;KwxPr{yU>!E=jMODH58W6=o-h(gI*1wD#*$3aPu_L?T?&S64iEZLg zNe^t}f&qTJfzLVZ&Lw24)k?+jDi~MDv0I;^>v}I%UbdrW%&~J153nHDso-z z`mPP5RGx}u1&?D&n2h#u$&*KRN&rMq;SHteQW>!a94MmT+K8-lVjG5c1^WBVZ#U`i zkG51LRo)ca2Wsf4m#ac08>rfw&OjSMZ&N6qt;HHz7WM@UU1;AcDJ;$k$|9)k4cl^E zz|CXYNQx`Xx2&~5?eFvqftefZ3gGe9IXUeL|1btC}Sh zychAgnkjAAljKyCgU(+^-$t{W*=>xA0wsimsty-}J#j7Z4HmJ*8Y`#@@mcKA#M>NznXCWtrOIxSPpE5bTWn^B<3*#?AUhKL6_s`K{9FjxVZw z2^-q5&Vpxy;P;KtqM0w(;sU3z%pg#}{WD~=NE>nuWlPa8wLq^LZV3)Ibk5fpCJmd^ zyx42t^-e^~^~N69azibPZs5SK8#=P?RqcInBS)UN!L~o!jkHb%;vD!?taz2t6&(DG zeXD1lmzg-jri~G{>G*hYwRBq$?HndgNeB-$Y$R+l?j&RcdF(SGsB5WR1ChW`Xc~AELF%!v zf8di^F`kth4v9c$nYjKeEQ7YL4aHdoc^RBwZ690=DafK)ru&HZAHiYQmc*pTTl;tz zI6if`e({&fU)V+ikQ~Y7JQz z5~yo*w>nsCcjHhfOsLy^sKpB)=mm{V?&nvoz9Su*#$wYyql+G9GW@i-p4~z@oWUl1 z)cij(W2cYEJ*Z+y{J+;Zml>LT7X%w?OLH+8tYK5CB@PY_(Qq<+BACs;-j08{UIZgm s)|6-1Y4VPJcz^!)5dZkV+D0L^pwur6>=v7h7tC}21HsX8nywfC0P6|yoB#j- From 90076090f05a1f03e2fbff307418ee18d7d046ef Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 09:09:09 -0700 Subject: [PATCH 18/55] fix int conversions if 'rules' key does not exist --- jc/parsers/ufw.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 6762ccd2..d3cae5cf 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -40,7 +40,7 @@ Schema: "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set "from_end_port": integer, # null if from_service is set - "from_service": string, # null if any above are set + "from_service": string # null if any above are set } ] } @@ -304,10 +304,12 @@ def _process(proc_data): """ int_list = ['index', 'to_subnet', 'to_start_port', 'to_end_port', 'from_subnet', 'from_start_port', 'from_end_port'] - for i, item in enumerate(proc_data['rules']): - for key in item: - if key in int_list: - proc_data['rules'][i][key] = jc.utils.convert_to_int(proc_data['rules'][i][key]) + + if 'rules' in proc_data: + for i, item in enumerate(proc_data['rules']): + for key in item: + if key in int_list: + proc_data['rules'][i][key] = jc.utils.convert_to_int(proc_data['rules'][i][key]) return proc_data From ade0e8e8fc18ff9a0dd406206a85238f1f5a739d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 09:09:23 -0700 Subject: [PATCH 19/55] add ufw tests --- tests/fixtures/generic/ufw-inactive.json | 1 + tests/fixtures/generic/ufw-inactive.out | 1 + tests/fixtures/generic/ufw-numbered.json | 1 + tests/fixtures/generic/ufw-numbered.out | 23 ++++++++++ tests/fixtures/generic/ufw.json | 1 + tests/fixtures/generic/ufw.out | 22 +++++++++ tests/test_ufw.py | 58 ++++++++++++++++++++++++ 7 files changed, 107 insertions(+) create mode 100644 tests/fixtures/generic/ufw-inactive.json create mode 100644 tests/fixtures/generic/ufw-inactive.out create mode 100644 tests/fixtures/generic/ufw-numbered.json create mode 100644 tests/fixtures/generic/ufw-numbered.out create mode 100644 tests/fixtures/generic/ufw.json create mode 100644 tests/fixtures/generic/ufw.out create mode 100644 tests/test_ufw.py diff --git a/tests/fixtures/generic/ufw-inactive.json b/tests/fixtures/generic/ufw-inactive.json new file mode 100644 index 00000000..1dd1cc6c --- /dev/null +++ b/tests/fixtures/generic/ufw-inactive.json @@ -0,0 +1 @@ +{"status":"inactive","rules":[]} diff --git a/tests/fixtures/generic/ufw-inactive.out b/tests/fixtures/generic/ufw-inactive.out new file mode 100644 index 00000000..91fecc6b --- /dev/null +++ b/tests/fixtures/generic/ufw-inactive.out @@ -0,0 +1 @@ +Status: inactive diff --git a/tests/fixtures/generic/ufw-numbered.json b/tests/fixtures/generic/ufw-numbered.json new file mode 100644 index 00000000..f9f97a09 --- /dev/null +++ b/tests/fixtures/generic/ufw-numbered.json @@ -0,0 +1 @@ +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw-numbered.out b/tests/fixtures/generic/ufw-numbered.out new file mode 100644 index 00000000..bd42c6c3 --- /dev/null +++ b/tests/fixtures/generic/ufw-numbered.out @@ -0,0 +1,23 @@ +Status: active +Logging: on (low) +Default: deny (incoming), allow (outgoing), deny (routed) +New profiles: skip + +To Action From +-- ------ ---- +[ 1] 22/tcp ALLOW IN Anywhere +[ 2] 22/tcp (v6) ALLOW OUT Anywhere (v6) +[ 3] 443/tcp DENY 192.168.0.1 +[ 4] 443/udp DENY OUT 192.168.0.7 8080:8081 +[ 5] 22/tcp ALLOW 192.168.0.0/24 +[ 6] 22/udp ALLOW 192.168.0.0/24 8080:8081 on en0 +[ 7] 22/tcp (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955/64 on en1 +[ 8] 80 ALLOW IN Anywhere +[ 9] 8080 (v6) ALLOW IN Anywhere (v6) +[10] Apache Full ALLOW IN Anywhere +[11] Apache Full (v6) ALLOW IN Anywhere (v6) +[12] OpenSSH (v6) DENY IN Anywhere (v6) +[13] 10.10.10.10 8080 on enp34s0 ALLOW 127.0.0.1 8000 +[14] 50200:50300/tcp (v6) ALLOW Anywhere (v6) +[15] Anywhere (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955 + diff --git a/tests/fixtures/generic/ufw.json b/tests/fixtures/generic/ufw.json new file mode 100644 index 00000000..35157b64 --- /dev/null +++ b/tests/fixtures/generic/ufw.json @@ -0,0 +1 @@ +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.out b/tests/fixtures/generic/ufw.out new file mode 100644 index 00000000..99bca0f5 --- /dev/null +++ b/tests/fixtures/generic/ufw.out @@ -0,0 +1,22 @@ +Status: active +Logging: on (low) +Default: deny (incoming), allow (outgoing), deny (routed) +New profiles: skip + +To Action From +-- ------ ---- +22/tcp ALLOW IN Anywhere +22/tcp (v6) ALLOW OUT Anywhere (v6) +443/tcp DENY 192.168.0.1 +443/udp DENY OUT 192.168.0.7 8080:8081 +22/tcp ALLOW 192.168.0.0/24 +22/udp ALLOW 192.168.0.0/24 8080:8081 on en0 +22/tcp (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955/64 on en1 +80 ALLOW IN Anywhere +8080 (v6) ALLOW IN Anywhere (v6) +Apache Full ALLOW IN Anywhere +Apache Full (v6) ALLOW IN Anywhere (v6) +OpenSSH (v6) DENY IN Anywhere (v6) +10.10.10.10 8080 on enp34s0 ALLOW 127.0.0.1 8000 +50200:50300/tcp (v6) ALLOW Anywhere (v6) +Anywhere (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955 diff --git a/tests/test_ufw.py b/tests/test_ufw.py new file mode 100644 index 00000000..4b53eaeb --- /dev/null +++ b/tests/test_ufw.py @@ -0,0 +1,58 @@ +import os +import json +import unittest +import jc.parsers.ufw + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class MyTests(unittest.TestCase): + + def setUp(self): + # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw.out'), 'r', encoding='utf-8') as f: + self.generic_ufw = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_numbered = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-inactive.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_inactive = f.read() + + # output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_numbered_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-inactive.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_inactive_json = json.loads(f.read()) + + def test_ufw_nodata(self): + """ + Test 'ufw' with no data + """ + self.assertEqual(jc.parsers.ufw.parse('', quiet=True), {}) + + def test_ufw_verbose(self): + """ + Test 'ufw status verbose' sample + """ + self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw, quiet=True), self.generic_ufw_json) + + def test_ufw_verbose_numbered(self): + """ + Test 'ufw status verbose numbered' sample + """ + self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw_numbered, quiet=True), self.generic_ufw_numbered_json) + + def test_ufw_inactive(self): + """ + Test 'ufw status' when firewall is inactive + """ + self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw_inactive, quiet=True), self.generic_ufw_inactive_json) + + +if __name__ == '__main__': + unittest.main() From da35eaf80ad4f11e7482fc4734db4b2265e50548 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 09:10:10 -0700 Subject: [PATCH 20/55] formatting --- docs/parsers/ufw.md | 2 +- jc/man/jc.1.gz | Bin 2068 -> 2068 bytes man/jc.1.gz | Bin 2068 -> 2068 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index 750c7026..f1fc7045 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -43,7 +43,7 @@ Schema: "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set "from_end_port": integer, # null if from_service is set - "from_service": string, # null if any above are set + "from_service": string # null if any above are set } ] } diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 3ceb719e859e2b709804f30494fa9c446a522498..7e289191a7646112a7014d507c6172b27a7d02af 100644 GIT binary patch delta 15 WcmbOtFhzh(zMF%?-ftrt9|r&)tOH{J delta 15 WcmbOtFhzh(zMF$%p7lmHJ`MmNhXbzw diff --git a/man/jc.1.gz b/man/jc.1.gz index 3ceb719e859e2b709804f30494fa9c446a522498..7e289191a7646112a7014d507c6172b27a7d02af 100644 GIT binary patch delta 15 WcmbOtFhzh(zMF%?-ftrt9|r&)tOH{J delta 15 WcmbOtFhzh(zMF$%p7lmHJ`MmNhXbzw From f638aca092475bbae14fed765e90435c093fcb8b Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 10:10:36 -0700 Subject: [PATCH 21/55] add deb package name fix --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index c566cb50..e7f69b05 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ jc changelog 20210420 v1.15.3 - Add ufw status command parser tested on linux +- Fix deb package name to conform to standard 20210418 v1.15.2 - Add systeminfo parser tested on Windows From 74f623f8d607c050db8f62ea4996c4e6aae43268 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 16:55:14 -0700 Subject: [PATCH 22/55] add support for rule comments and LIMIT and REJECT actions --- docs/parsers/ufw.md | 13 +++++++++++- jc/parsers/ufw.py | 25 ++++++++++++++++++++++-- tests/fixtures/generic/ufw-numbered.json | 2 +- tests/fixtures/generic/ufw.json | 2 +- tests/fixtures/generic/ufw.out | 12 ++++++------ 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index f1fc7045..d9b117a5 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -43,7 +43,8 @@ Schema: "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set "from_end_port": integer, # null if from_service is set - "from_service": string # null if any above are set + "from_service": string, # null if any above are set + "comment": string # null if no comment } ] } @@ -70,6 +71,7 @@ Examples: "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -90,6 +92,7 @@ Examples: "to_service": null, "to_ip": "::", "to_ip_prefix": "0", + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -110,6 +113,7 @@ Examples: "to_end_port": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -130,6 +134,7 @@ Examples: "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -150,6 +155,7 @@ Examples: "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -181,6 +187,7 @@ Examples: "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -201,6 +208,7 @@ Examples: "to_service": null, "to_ip": "::", "to_ip_prefix": "0", + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -221,6 +229,7 @@ Examples: "to_end_port": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -241,6 +250,7 @@ Examples: "to_start_port": "0", "to_end_port": "65535", "to_service": null, + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -261,6 +271,7 @@ Examples: "to_start_port": "0", "to_end_port": "65535", "to_service": null, + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index d3cae5cf..ea98d15f 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -40,7 +40,8 @@ Schema: "from_transport": string, # null if from_service is set "from_start_port": integer, # null if from_service is set "from_end_port": integer, # null if from_service is set - "from_service": string # null if any above are set + "from_service": string, # null if any above are set + "comment": string # null if no comment } ] } @@ -67,6 +68,7 @@ Examples: "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -87,6 +89,7 @@ Examples: "to_service": null, "to_ip": "::", "to_ip_prefix": "0", + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -107,6 +110,7 @@ Examples: "to_end_port": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -127,6 +131,7 @@ Examples: "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -147,6 +152,7 @@ Examples: "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -178,6 +184,7 @@ Examples: "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -198,6 +205,7 @@ Examples: "to_service": null, "to_ip": "::", "to_ip_prefix": "0", + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -218,6 +226,7 @@ Examples: "to_end_port": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -238,6 +247,7 @@ Examples: "to_start_port": "0", "to_end_port": "65535", "to_service": null, + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -258,6 +268,7 @@ Examples: "to_start_port": "0", "to_end_port": "65535", "to_service": null, + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -329,6 +340,16 @@ def _parse_to_from(linedata, direction, rule_obj=None): else: rule_obj['index'] = None + # pull out comments, if they exist + if direction == 'from': + RE_COMMENT = re.compile(r'#.+$') + comment_match = re.search(RE_COMMENT, linedata) + if comment_match: + rule_obj['comment'] = comment_match.group(0).lstrip('#').strip() + linedata = re.sub(RE_COMMENT, '', linedata) + else: + rule_obj['comment'] = None + # pull (v6) RE_V6 = re.compile(r'\(v6\)') v6_match = re.search(RE_V6, linedata) @@ -481,7 +502,7 @@ def parse(data, raw=False, quiet=False): # Split on action. Left of Action is 'to', right of Action is 'from' rule_obj = {} - splitline = re.split(r'(ALLOW IN|ALLOW OUT|DENY IN|DENY OUT|ALLOW|DENY)', line) + splitline = re.split(r'(ALLOW IN|ALLOW OUT|ALLOW FWD|DENY IN|DENY OUT|DENY FWD|LIMIT IN|LIMIT OUT|LIMIT FWD|REJECT IN|REJECT OUT|REJECT FWD|ALLOW|DENY|LIMIT|REJECT)', line) to_line = splitline[0] action_line = splitline[1] action_list = action_line.split() diff --git a/tests/fixtures/generic/ufw-numbered.json b/tests/fixtures/generic/ufw-numbered.json index f9f97a09..cf8ab6cf 100644 --- a/tests/fixtures/generic/ufw-numbered.json +++ b/tests/fixtures/generic/ufw-numbered.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.json b/tests/fixtures/generic/ufw.json index 35157b64..44f6edc5 100644 --- a/tests/fixtures/generic/ufw.json +++ b/tests/fixtures/generic/ufw.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":"nice comment","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":"this is a comment","from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.out b/tests/fixtures/generic/ufw.out index 99bca0f5..96e0ce94 100644 --- a/tests/fixtures/generic/ufw.out +++ b/tests/fixtures/generic/ufw.out @@ -7,16 +7,16 @@ To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere 22/tcp (v6) ALLOW OUT Anywhere (v6) -443/tcp DENY 192.168.0.1 +443/tcp DENY 192.168.0.1 # nice comment 443/udp DENY OUT 192.168.0.7 8080:8081 22/tcp ALLOW 192.168.0.0/24 22/udp ALLOW 192.168.0.0/24 8080:8081 on en0 -22/tcp (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955/64 on en1 +22/tcp (v6) ALLOW FWD 2405:204:7449:49fc:f09a:6f4a:bc93:1955/64 on en1 #commenting this rule 80 ALLOW IN Anywhere -8080 (v6) ALLOW IN Anywhere (v6) -Apache Full ALLOW IN Anywhere +8080 (v6) REJECT IN Anywhere (v6) +Apache Full ALLOW IN Anywhere # a comment Apache Full (v6) ALLOW IN Anywhere (v6) OpenSSH (v6) DENY IN Anywhere (v6) 10.10.10.10 8080 on enp34s0 ALLOW 127.0.0.1 8000 -50200:50300/tcp (v6) ALLOW Anywhere (v6) -Anywhere (v6) ALLOW IN 2405:204:7449:49fc:f09a:6f4a:bc93:1955 +50200:50300/tcp (v6) DENY FWD Anywhere (v6) +Anywhere (v6) LIMIT 2405:204:7449:49fc:f09a:6f4a:bc93:1955 # this is a comment From 7eef5d94d591a3f70f6638b1b30f952a3bf35f9d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Wed, 21 Apr 2021 16:55:25 -0700 Subject: [PATCH 23/55] ufw doc update --- EXAMPLES.md | 5 +++++ jc/man/jc.1.gz | Bin 2068 -> 2068 bytes man/jc.1.gz | Bin 2068 -> 2068 bytes 3 files changed, 5 insertions(+) diff --git a/EXAMPLES.md b/EXAMPLES.md index 34dd6520..26fdfd74 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3150,6 +3150,7 @@ ufw status verbose numbered | jc --ufw -p "to_service": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -3170,6 +3171,7 @@ ufw status verbose numbered | jc --ufw -p "to_service": null, "to_ip": "::", "to_ip_prefix": "0", + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -3190,6 +3192,7 @@ ufw status verbose numbered | jc --ufw -p "to_end_port": null, "to_ip": "0.0.0.0", "to_ip_prefix": "0", + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", @@ -3210,6 +3213,7 @@ ufw status verbose numbered | jc --ufw -p "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "::", "from_ip_prefix": "0", "from_interface": "any", @@ -3230,6 +3234,7 @@ ufw status verbose numbered | jc --ufw -p "to_start_port": 0, "to_end_port": 65535, "to_service": null, + "comment": null, "from_ip": "0.0.0.0", "from_ip_prefix": "0", "from_interface": "any", diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 7e289191a7646112a7014d507c6172b27a7d02af..7ccc11cd2d940628c58910d6497c6bbe5cac4ca0 100644 GIT binary patch delta 15 WcmbOtFhzh(zMF&N&#sMZd>jBJHUx|S delta 15 WcmbOtFhzh(zMF%?-ftrt9|r&)tOH{J diff --git a/man/jc.1.gz b/man/jc.1.gz index 7e289191a7646112a7014d507c6172b27a7d02af..7ccc11cd2d940628c58910d6497c6bbe5cac4ca0 100644 GIT binary patch delta 15 WcmbOtFhzh(zMF&N&#sMZd>jBJHUx|S delta 15 WcmbOtFhzh(zMF%?-ftrt9|r&)tOH{J From bb50caad4dfaefa309e747fd05b650186c5a80f4 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 22 Apr 2021 08:16:42 -0700 Subject: [PATCH 24/55] fix prefix int conversions. don't reset _transport if service is really a list of ports --- jc/parsers/ufw.py | 10 ++++++---- tests/fixtures/ubuntu-18.04/ufw-numbered.out | 11 +++++++++++ tests/fixtures/ubuntu-18.04/ufw-verbose.out | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/ubuntu-18.04/ufw-numbered.out create mode 100644 tests/fixtures/ubuntu-18.04/ufw-verbose.out diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index ea98d15f..e04be244 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -313,7 +313,7 @@ def _process(proc_data): Dictionary. Structured to conform to the schema. """ - int_list = ['index', 'to_subnet', 'to_start_port', 'to_end_port', 'from_subnet', + int_list = ['index', 'to_ip_prefix', 'to_start_port', 'to_end_port', 'from_ip_prefix', 'from_start_port', 'from_end_port'] if 'rules' in proc_data: @@ -397,8 +397,8 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_ip_prefix'] = str(valid_ip.with_prefixlen.split('/')[1]) linedata = ' '.join(new_linedata_list) - # pull out anything ending in 'udp', 'tcp'. strip on '/' for ports - linedata_list = linedata.split('/', maxsplit=1) + # pull tcp/udp transport and strip on '/' for ports + linedata_list = linedata.rsplit('/', maxsplit=1) if len(linedata_list) > 1: rule_obj[direction + '_transport'] = linedata_list[1].strip() linedata = linedata_list[0] @@ -423,7 +423,9 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_service'] = linedata.strip() rule_obj[direction + '_start_port'] = None rule_obj[direction + '_end_port'] = None - rule_obj[direction + '_transport'] = None + # if service name is really a list of ports, don't reset the _transport field to null + if ',' not in rule_obj[direction + '_service']: + rule_obj[direction + '_transport'] = None # check if to/from IP addresses exist. If not, set to 0.0.0.0/0 or ::/0 if direction + '_ip' not in rule_obj: diff --git a/tests/fixtures/ubuntu-18.04/ufw-numbered.out b/tests/fixtures/ubuntu-18.04/ufw-numbered.out new file mode 100644 index 00000000..a9ba97ff --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-numbered.out @@ -0,0 +1,11 @@ +Status: active + + To Action From + -- ------ ---- +[ 1] 22 ALLOW IN Anywhere +[ 2] 80,443/tcp ALLOW IN Anywhere +[ 3] 80 on eth0 ALLOW IN Anywhere # test +[ 4] 22 (v6) ALLOW IN Anywhere (v6) +[ 5] 80,443/tcp (v6) ALLOW IN Anywhere (v6) +[ 6] 80 (v6) on eth0 ALLOW IN Anywhere (v6) # test + diff --git a/tests/fixtures/ubuntu-18.04/ufw-verbose.out b/tests/fixtures/ubuntu-18.04/ufw-verbose.out new file mode 100644 index 00000000..a653d609 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-verbose.out @@ -0,0 +1,14 @@ +Status: active +Logging: on (low) +Default: deny (incoming), allow (outgoing), disabled (routed) +New profiles: skip + +To Action From +-- ------ ---- +22 ALLOW IN Anywhere +80,443/tcp ALLOW IN Anywhere +80 on eth0 ALLOW IN Anywhere # test +22 (v6) ALLOW IN Anywhere (v6) +80,443/tcp (v6) ALLOW IN Anywhere (v6) +80 (v6) on eth0 ALLOW IN Anywhere (v6) # test + From 5500648aa0886ea5089856e5b33d7c8ebd78d5b0 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 22 Apr 2021 08:33:45 -0700 Subject: [PATCH 25/55] fix ufw docs for int conversions and service behavior --- EXAMPLES.md | 20 ++++++++++---------- docs/parsers/ufw.md | 36 ++++++++++++++++++------------------ jc/parsers/ufw.py | 36 ++++++++++++++++++------------------ 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 26fdfd74..282b8ba7 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3149,10 +3149,10 @@ ufw status verbose numbered | jc --ufw -p "to_end_port": 22, "to_service": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -3170,10 +3170,10 @@ ufw status verbose numbered | jc --ufw -p "to_end_port": 22, "to_service": null, "to_ip": "::", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -3191,10 +3191,10 @@ ufw status verbose numbered | jc --ufw -p "to_start_port": null, "to_end_port": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -3208,14 +3208,14 @@ ufw status verbose numbered | jc --ufw -p "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": "128", + "to_ip_prefix": 128, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -3229,14 +3229,14 @@ ufw status verbose numbered | jc --ufw -p "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", - "to_ip_prefix": "32", + "to_ip_prefix": 32, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index d9b117a5..ef9b34c0 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -33,17 +33,17 @@ Schema: "to_ip": string, "to_ip_prefix": integer, "to_interface": string, - "to_transport": string, # null if to_service is set - "to_start_port": integer, # null if to_service is set - "to_end_port": integer, # null if to_service is set - "to_service": string, # null if any above are set + "to_transport": string, # null if to_service is set and not a list of ports + "to_start_port": integer, # null if to_service is set and not a list of ports + "to_end_port": integer, # null if to_service is set and not a list of ports + "to_service": string, # null if any above are set (can also be a list of ports) "from_ip": string, "from_ip_prefix": integer, "from_interface": string, - "from_transport": string, # null if from_service is set - "from_start_port": integer, # null if from_service is set - "from_end_port": integer, # null if from_service is set - "from_service": string, # null if any above are set + "from_transport": string, # null if to_service is set and not a list of ports + "from_start_port": integer, # null if to_service is set and not a list of ports + "from_end_port": integer, # null if to_service is set and not a list of ports + "from_service": string, # null if any above are set (can also be a list of ports) "comment": string # null if no comment } ] @@ -70,10 +70,10 @@ Examples: "to_end_port": 22, "to_service": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -91,10 +91,10 @@ Examples: "to_end_port": 22, "to_service": null, "to_ip": "::", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -112,10 +112,10 @@ Examples: "to_start_port": null, "to_end_port": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -129,14 +129,14 @@ Examples: "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": "128", + "to_ip_prefix": 128, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -150,14 +150,14 @@ Examples: "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", - "to_ip_prefix": "32", + "to_ip_prefix": 32, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index e04be244..e2613e96 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -30,17 +30,17 @@ Schema: "to_ip": string, "to_ip_prefix": integer, "to_interface": string, - "to_transport": string, # null if to_service is set - "to_start_port": integer, # null if to_service is set - "to_end_port": integer, # null if to_service is set - "to_service": string, # null if any above are set + "to_transport": string, # null if to_service is set and not a list of ports + "to_start_port": integer, # null if to_service is set and not a list of ports + "to_end_port": integer, # null if to_service is set and not a list of ports + "to_service": string, # null if any above are set (can also be a list of ports) "from_ip": string, "from_ip_prefix": integer, "from_interface": string, - "from_transport": string, # null if from_service is set - "from_start_port": integer, # null if from_service is set - "from_end_port": integer, # null if from_service is set - "from_service": string, # null if any above are set + "from_transport": string, # null if to_service is set and not a list of ports + "from_start_port": integer, # null if to_service is set and not a list of ports + "from_end_port": integer, # null if to_service is set and not a list of ports + "from_service": string, # null if any above are set (can also be a list of ports) "comment": string # null if no comment } ] @@ -67,10 +67,10 @@ Examples: "to_end_port": 22, "to_service": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -88,10 +88,10 @@ Examples: "to_end_port": 22, "to_service": null, "to_ip": "::", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -109,10 +109,10 @@ Examples: "to_start_port": null, "to_end_port": null, "to_ip": "0.0.0.0", - "to_ip_prefix": "0", + "to_ip_prefix": 0, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -126,14 +126,14 @@ Examples: "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": "128", + "to_ip_prefix": 128, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "::", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, @@ -147,14 +147,14 @@ Examples: "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", - "to_ip_prefix": "32", + "to_ip_prefix": 32, "to_transport": "any", "to_start_port": 0, "to_end_port": 65535, "to_service": null, "comment": null, "from_ip": "0.0.0.0", - "from_ip_prefix": "0", + "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", "from_start_port": 0, From 0679bcbc560ea3575555d8546afdd4e2474d05d7 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 22 Apr 2021 08:33:57 -0700 Subject: [PATCH 26/55] fix ufw tests --- tests/fixtures/generic/ufw-numbered.json | 2 +- tests/fixtures/generic/ufw.json | 2 +- tests/fixtures/ubuntu-18.04/ufw-numbered.json | 1 + tests/fixtures/ubuntu-18.04/ufw-verbose.json | 1 + tests/test_ufw.py | 30 +++++++++++++++++-- 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/ubuntu-18.04/ufw-numbered.json create mode 100644 tests/fixtures/ubuntu-18.04/ufw-verbose.json diff --git a/tests/fixtures/generic/ufw-numbered.json b/tests/fixtures/generic/ufw-numbered.json index cf8ab6cf..76d14a27 100644 --- a/tests/fixtures/generic/ufw-numbered.json +++ b/tests/fixtures/generic/ufw-numbered.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":32,"to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.json b/tests/fixtures/generic/ufw.json index 44f6edc5..0238ff7b 100644 --- a/tests/fixtures/generic/ufw.json +++ b/tests/fixtures/generic/ufw.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":"nice comment","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":"32","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":"24","from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"64","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":"0","comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":"32","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":"32","from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":"0","comment":null,"from_ip":"::","from_ip_prefix":"0","from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":"0","to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":"this is a comment","from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":"128","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"nice comment","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":32,"to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":"this is a comment","from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/ubuntu-18.04/ufw-numbered.json b/tests/fixtures/ubuntu-18.04/ufw-numbered.json new file mode 100644 index 00000000..16383d39 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-numbered.json @@ -0,0 +1 @@ +{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/ubuntu-18.04/ufw-verbose.json b/tests/fixtures/ubuntu-18.04/ufw-verbose.json new file mode 100644 index 00000000..83384f3d --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-verbose.json @@ -0,0 +1 @@ +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), disabled (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/test_ufw.py b/tests/test_ufw.py index 4b53eaeb..3dbe8370 100644 --- a/tests/test_ufw.py +++ b/tests/test_ufw.py @@ -10,6 +10,12 @@ class MyTests(unittest.TestCase): def setUp(self): # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-verbose.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_verbose = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-numbered.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_numbered = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw.out'), 'r', encoding='utf-8') as f: self.generic_ufw = f.read() @@ -20,6 +26,12 @@ class MyTests(unittest.TestCase): self.generic_ufw_inactive = f.read() # output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-verbose.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_verbose_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-numbered.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_numbered_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw.json'), 'r', encoding='utf-8') as f: self.generic_ufw_json = json.loads(f.read()) @@ -35,19 +47,31 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.ufw.parse('', quiet=True), {}) - def test_ufw_verbose(self): + def test_ufw_ubuntu_18_04_verbose(self): + """ + Test 'ufw status verbose' on Ubuntu 18.04 + """ + self.assertEqual(jc.parsers.ufw.parse(self.ubuntu_18_04_ufw_verbose, quiet=True), self.ubuntu_18_04_ufw_verbose_json) + + def test_ufw_ubuntu_18_04_numbered(self): + """ + Test 'ufw status numbered' on Ubuntu 18.04 + """ + self.assertEqual(jc.parsers.ufw.parse(self.ubuntu_18_04_ufw_numbered, quiet=True), self.ubuntu_18_04_ufw_numbered_json) + + def test_ufw_generic_verbose(self): """ Test 'ufw status verbose' sample """ self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw, quiet=True), self.generic_ufw_json) - def test_ufw_verbose_numbered(self): + def test_ufw_generic_verbose_numbered(self): """ Test 'ufw status verbose numbered' sample """ self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw_numbered, quiet=True), self.generic_ufw_numbered_json) - def test_ufw_inactive(self): + def test_ufw_generic_inactive(self): """ Test 'ufw status' when firewall is inactive """ From 0152e0665f87833250561d743144af35416992f8 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Thu, 22 Apr 2021 16:52:01 -0700 Subject: [PATCH 27/55] initial working ufw-appinfo parser --- jc/cli.py | 1 + jc/parsers/ufw_appinfo.py | 214 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 jc/parsers/ufw_appinfo.py diff --git a/jc/cli.py b/jc/cli.py index 23c10b07..f8989e13 100644 --- a/jc/cli.py +++ b/jc/cli.py @@ -103,6 +103,7 @@ parsers = [ 'tracepath', 'traceroute', 'ufw', + 'ufw-appinfo', 'uname', 'upower', 'uptime', diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py new file mode 100644 index 00000000..9f3c4a93 --- /dev/null +++ b/jc/parsers/ufw_appinfo.py @@ -0,0 +1,214 @@ +"""jc - JSON CLI output utility `ufw app info [application]` command output parser + + +Usage (cli): + + $ ufw app info OpenSSH | jc --ufw-appinfo + + or + + $ jc ufw app info OpenSSH + +Usage (module): + + import jc.parsers.ufw_appinfo + result = jc.parsers.ufw_appinfo.parse(ufw_appinfo_command_output) + +Schema: + + { + "profile": string, + "title": string, + "description": string, + "ports": { + "tcp_list": [ + integer + ], + "tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "udp_list": [ + integer + ], + "upd_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ] + } + } + +Examples: + + $ ufw app info OpenSSH | jc --ufw-appinfo -p + [] + + $ ufw app info OpenSSH | jc --ufw-appinfo -p -r + [] +""" +import jc.utils + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`ufw app info [application]` command parser' + author = 'Kelly Brazil' + author_email = 'kellyjonbrazil@gmail.com' + compatible = ['linux'] + magic_commands = ['ufw-appinfo'] + + +__version__ = info.version + + +def _process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (List of Dictionaries) raw structured data to process + + Returns: + + Dictionary. Structured to conform to the schema. + """ + + # rebuild output for added semantic information + # use helper functions in jc.utils for int, float, bool conversions and timestamps + + return proc_data + + +def _parse_port_list(data, port_list=None): + """return a list of integers""" + # 1,2,3,4,5,6,7,8,9,10,9,30,80:90,8080:8090 + # overlapping and repeated port numbers are allowed, so use a set to correct + + if port_list is None: + port_list = [] + + data = data.split(',') + data_list = [int(p) for p in data if ':' not in p and 'any' not in p] + port_list.extend(data_list) + + return sorted(list(set(port_list))) + + +def _parse_port_range(data, range_list=None): + """return a list of dictionaries""" + # 1,2,3,4,5,6,7,8,9,10,9,30,80:90,8080:8090 + # overlapping ports are allowed + + if range_list is None: + range_list = [] + + data = data.strip().split(',') + ranges = [p.strip() for p in data if ':' in p] + range_obj = {} + + if 'any' in data: + range_list.append( + { + 'start': 0, + 'end': 65535 + } + ) + + for range_ in ranges: + range_obj = { + 'start': int(range_.split(':')[0]), + 'end': int(range_.split(':')[1]) + } + range_list.append(range_obj) + + return range_list + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + + Returns: + + Dictionary. Raw or processed structured data. + """ + if not quiet: + jc.utils.compatibility(__name__, info.compatible) + + raw_output = {} + + if jc.utils.has_data(data): + + ports = False + + for line in filter(None, data.splitlines()): + + if line.startswith('Profile:'): + raw_output['profile'] = line.split(': ')[1] + continue + + if line.startswith('Title:'): + raw_output['title'] = line.split(': ')[1] + continue + + if line.startswith('Description:'): + raw_output['description'] = line.split(': ')[1] + continue + + if line.startswith('Ports:'): + ports = True + ports_obj = {'ports': {}} + continue + + if ports: + line_list = line.rsplit('/', maxsplit=1) + if len(line_list) == 2: + if line_list[1] == 'tcp': + ports_obj['ports']['tcp_list'] = _parse_port_list(line_list[0]) + ports_obj['ports']['tcp_ranges'] = _parse_port_range(line_list[0]) + elif line_list[1] == 'udp': + ports_obj['ports']['udp_list'] = _parse_port_list(line_list[0]) + ports_obj['ports']['udp_ranges'] = _parse_port_range(line_list[0]) + + # 'any' case + else: + t_list = [] + t_range = [] + u_list = [] + u_range = [] + + if 'tcp_list' in ports_obj['ports']: + t_list = ports_obj['ports']['tcp_list'] + + if 'tcp_ranges' in ports_obj['ports']: + t_range = ports_obj['ports']['tcp_ranges'] + + if 'udp_list' in ports_obj['ports']: + u_list = ports_obj['ports']['udp_list'] + + if 'udp_ranges' in ports_obj['ports']: + u_range = ports_obj['ports']['udp_ranges'] + + ports_obj['ports']['tcp_list'] = _parse_port_list(line, t_list) + ports_obj['ports']['tcp_ranges'] = _parse_port_range(line, t_range) + ports_obj['ports']['udp_list'] = _parse_port_list(line, u_list) + ports_obj['ports']['udp_ranges'] = _parse_port_range(line, u_range) + + raw_output.update(ports_obj) + + if raw: + return raw_output + else: + return _process(raw_output) From 125e54213e8d4dcfe2e3271456af80b3f79c0544 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 08:13:53 -0700 Subject: [PATCH 28/55] update schema and add normalized fields --- jc/parsers/ufw_appinfo.py | 151 ++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 47 deletions(-) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index 9f3c4a93..52ab6cc5 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -1,5 +1,6 @@ """jc - JSON CLI output utility `ufw app info [application]` command output parser +Because `ufw` application definitions allow overlapping ports and port ranges, this parser preserves that behavior, but also provides `normalized` lists and ranges that remove duplicate ports and merge overlapping ranges. Usage (cli): @@ -17,29 +18,45 @@ Usage (module): Schema: { - "profile": string, - "title": string, - "description": string, - "ports": { - "tcp_list": [ - integer - ], - "tcp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ], - "udp_list": [ - integer - ], - "upd_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ] - } + "profile": string, + "title": string, + "description": string, + "tcp_list": [ + integer + ], + "tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "udp_list": [ + integer + ], + "udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "normalized_tcp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ], + "normalized_udp_list": [ + integer + ], + "normalized_udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ] } Examples: @@ -78,9 +95,50 @@ def _process(proc_data): Dictionary. Structured to conform to the schema. """ + # convert to ints + int_list = ['start', 'end'] - # rebuild output for added semantic information - # use helper functions in jc.utils for int, float, bool conversions and timestamps + if 'tcp_list' in proc_data: + proc_data['tcp_list'] = [int(p) for p in proc_data['tcp_list']] + + if 'udp_list' in proc_data: + proc_data['udp_list'] = [int(p) for p in proc_data['udp_list']] + + for protocol in ['tcp', 'udp']: + if protocol + '_ranges' in proc_data: + for i, item in enumerate(proc_data[protocol + '_ranges']): + for key in item: + if key in int_list: + proc_data[protocol + '_ranges'][i][key] = int(proc_data[protocol + '_ranges'][i][key]) + + # create normalized port lists and port ranges (remove duplicates and merge ranges) + # dump ranges into a set of 0 - 65535 + # if items in the port list are in the set, then remove them + # iterate through the set to find gaps and create new ranges based on them + for protocol in ['tcp', 'udp']: + port_set = set() + if protocol + '_ranges' in proc_data: + for item in proc_data[protocol + '_ranges']: + port_set.update(range(item['start'], item['end'] + 1)) + + proc_data['normalized_' + protocol + '_list'] = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) + + new_port_ranges = [] + state = 'findstart' # 'findstart' or 'findend' + for port in range(0, 65535 + 2): + if state == 'findstart': + port_range_obj = {} + if port in port_set: + port_range_obj['start'] = port + state = 'findend' + continue + if state == 'findend': + if port not in port_set: + port_range_obj['end'] = port - 1 + new_port_ranges.append(port_range_obj) + state = 'findstart' + + proc_data['normalized_' + protocol + '_ranges'] = new_port_ranges return proc_data @@ -94,10 +152,10 @@ def _parse_port_list(data, port_list=None): port_list = [] data = data.split(',') - data_list = [int(p) for p in data if ':' not in p and 'any' not in p] + data_list = [p.strip() for p in data if ':' not in p and 'any' not in p] port_list.extend(data_list) - return sorted(list(set(port_list))) + return port_list def _parse_port_range(data, range_list=None): @@ -122,8 +180,8 @@ def _parse_port_range(data, range_list=None): for range_ in ranges: range_obj = { - 'start': int(range_.split(':')[0]), - 'end': int(range_.split(':')[1]) + 'start': range_.split(':')[0], + 'end': range_.split(':')[1] } range_list.append(range_obj) @@ -169,18 +227,17 @@ def parse(data, raw=False, quiet=False): if line.startswith('Ports:'): ports = True - ports_obj = {'ports': {}} continue if ports: line_list = line.rsplit('/', maxsplit=1) if len(line_list) == 2: if line_list[1] == 'tcp': - ports_obj['ports']['tcp_list'] = _parse_port_list(line_list[0]) - ports_obj['ports']['tcp_ranges'] = _parse_port_range(line_list[0]) + raw_output['tcp_list'] = _parse_port_list(line_list[0]) + raw_output['tcp_ranges'] = _parse_port_range(line_list[0]) elif line_list[1] == 'udp': - ports_obj['ports']['udp_list'] = _parse_port_list(line_list[0]) - ports_obj['ports']['udp_ranges'] = _parse_port_range(line_list[0]) + raw_output['udp_list'] = _parse_port_list(line_list[0]) + raw_output['udp_ranges'] = _parse_port_range(line_list[0]) # 'any' case else: @@ -189,24 +246,24 @@ def parse(data, raw=False, quiet=False): u_list = [] u_range = [] - if 'tcp_list' in ports_obj['ports']: - t_list = ports_obj['ports']['tcp_list'] + if 'tcp_list' in raw_output: + t_list = raw_output['tcp_list'] - if 'tcp_ranges' in ports_obj['ports']: - t_range = ports_obj['ports']['tcp_ranges'] + if 'tcp_ranges' in raw_output: + t_range = raw_output['tcp_ranges'] - if 'udp_list' in ports_obj['ports']: - u_list = ports_obj['ports']['udp_list'] + if 'udp_list' in raw_output: + u_list = raw_output['udp_list'] - if 'udp_ranges' in ports_obj['ports']: - u_range = ports_obj['ports']['udp_ranges'] + if 'udp_ranges' in raw_output: + u_range = raw_output['udp_ranges'] - ports_obj['ports']['tcp_list'] = _parse_port_list(line, t_list) - ports_obj['ports']['tcp_ranges'] = _parse_port_range(line, t_range) - ports_obj['ports']['udp_list'] = _parse_port_list(line, u_list) - ports_obj['ports']['udp_ranges'] = _parse_port_range(line, u_range) + raw_output['tcp_list'] = _parse_port_list(line, t_list) + raw_output['tcp_ranges'] = _parse_port_range(line, t_range) + raw_output['udp_list'] = _parse_port_list(line, u_list) + raw_output['udp_ranges'] = _parse_port_range(line, u_range) - raw_output.update(ports_obj) + raw_output.update(raw_output) if raw: return raw_output From 4c98fd4b877c54e1cf7d285a29e178321be12f7e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 08:26:00 -0700 Subject: [PATCH 29/55] doc update --- docs/parsers/ufw_appinfo.md | 100 ++++++++++++++++++++++++++++++++++++ jc/parsers/ufw_appinfo.py | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 docs/parsers/ufw_appinfo.md diff --git a/docs/parsers/ufw_appinfo.md b/docs/parsers/ufw_appinfo.md new file mode 100644 index 00000000..99b00694 --- /dev/null +++ b/docs/parsers/ufw_appinfo.md @@ -0,0 +1,100 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + +# jc.parsers.ufw_appinfo +jc - JSON CLI output utility `ufw app info [application]` command output parser + +Because `ufw` application definitions allow overlapping ports and port ranges, this parser preserves that behavior, but also provides `normalized` lists and ranges that remove duplicate ports and merge overlapping ranges. + +Usage (cli): + + $ ufw app info OpenSSH | jc --ufw-appinfo + + or + + $ jc ufw app info OpenSSH + +Usage (module): + + import jc.parsers.ufw_appinfo + result = jc.parsers.ufw_appinfo.parse(ufw_appinfo_command_output) + +Schema: + + { + "profile": string, + "title": string, + "description": string, + "tcp_list": [ + integer + ], + "tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "udp_list": [ + integer + ], + "udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "normalized_tcp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ], + "normalized_udp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ] + } + +Examples: + + $ ufw app info OpenSSH | jc --ufw-appinfo -p + [] + + $ ufw app info OpenSSH | jc --ufw-appinfo -p -r + [] + + +## info +```python +info() +``` +Provides parser metadata (version, author, etc.) + +## parse +```python +parse(data, raw=False, quiet=False) +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) output preprocessed JSON if True + quiet: (boolean) suppress warning messages if True + +Returns: + + Dictionary. Raw or processed structured data. + +## Parser Information +Compatibility: linux + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index 52ab6cc5..161c67bc 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -49,7 +49,7 @@ Schema: } ], "normalized_udp_list": [ - integer + integers # duplicates and overlapping are removed ], "normalized_udp_ranges": [ { From 20e5c19de448c1b979497817c887d8d2d6487839 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 08:30:34 -0700 Subject: [PATCH 30/55] fix key error if tcp or udp don't exist --- jc/parsers/ufw_appinfo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index 161c67bc..e25e3c7d 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -121,7 +121,8 @@ def _process(proc_data): for item in proc_data[protocol + '_ranges']: port_set.update(range(item['start'], item['end'] + 1)) - proc_data['normalized_' + protocol + '_list'] = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) + if protocol + '_list' in proc_data: + proc_data['normalized_' + protocol + '_list'] = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) new_port_ranges = [] state = 'findstart' # 'findstart' or 'findend' From 145059fc8946b7026184139baea143c2869bc4e7 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 09:04:11 -0700 Subject: [PATCH 31/55] clean up output if sections are blank --- jc/parsers/ufw_appinfo.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index e25e3c7d..bd6a3063 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -139,7 +139,8 @@ def _process(proc_data): new_port_ranges.append(port_range_obj) state = 'findstart' - proc_data['normalized_' + protocol + '_ranges'] = new_port_ranges + if new_port_ranges: + proc_data['normalized_' + protocol + '_ranges'] = new_port_ranges return proc_data @@ -147,7 +148,7 @@ def _process(proc_data): def _parse_port_list(data, port_list=None): """return a list of integers""" # 1,2,3,4,5,6,7,8,9,10,9,30,80:90,8080:8090 - # overlapping and repeated port numbers are allowed, so use a set to correct + # overlapping and repeated port numbers are allowed if port_list is None: port_list = [] @@ -162,7 +163,7 @@ def _parse_port_list(data, port_list=None): def _parse_port_range(data, range_list=None): """return a list of dictionaries""" # 1,2,3,4,5,6,7,8,9,10,9,30,80:90,8080:8090 - # overlapping ports are allowed + # overlapping port ranges are allowed if range_list is None: range_list = [] @@ -226,7 +227,7 @@ def parse(data, raw=False, quiet=False): raw_output['description'] = line.split(': ')[1] continue - if line.startswith('Ports:'): + if line.startswith('Port'): ports = True continue @@ -234,11 +235,22 @@ def parse(data, raw=False, quiet=False): line_list = line.rsplit('/', maxsplit=1) if len(line_list) == 2: if line_list[1] == 'tcp': - raw_output['tcp_list'] = _parse_port_list(line_list[0]) - raw_output['tcp_ranges'] = _parse_port_range(line_list[0]) + prot_list = _parse_port_list(line_list[0]) + if prot_list: + raw_output['tcp_list'] = prot_list + + prot_range = _parse_port_range(line_list[0]) + if prot_range: + raw_output['tcp_ranges'] = prot_range + elif line_list[1] == 'udp': - raw_output['udp_list'] = _parse_port_list(line_list[0]) - raw_output['udp_ranges'] = _parse_port_range(line_list[0]) + prot_list = _parse_port_list(line_list[0]) + if prot_list: + raw_output['udp_list'] = prot_list + + prot_range = _parse_port_range(line_list[0]) + if prot_range: + raw_output['udp_ranges'] = prot_range # 'any' case else: From ff3c2d809ec3ea6e556c302909a228ee670578c9 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 09:57:41 -0700 Subject: [PATCH 32/55] add ufw-appinfo to docs --- EXAMPLES.md | 39 ++++++++++++++ README.md | 1 + docs/parsers/ufw_appinfo.md | 58 ++++++++++++++++++-- jc/man/jc.1.gz | Bin 2068 -> 2087 bytes jc/parsers/ufw_appinfo.py | 103 ++++++++++++++++++++++++++++-------- man/jc.1.gz | Bin 2068 -> 2087 bytes 6 files changed, 176 insertions(+), 25 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 282b8ba7..3b56c493 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3246,6 +3246,45 @@ ufw status verbose numbered | jc --ufw -p ] } ``` +### ufw app info [application] +```bash +ufw app info MSN | jc --ufw-appinfo -p # or: jc -p ufw app info MSN +``` +```json +{ + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] +} +``` ### uname -a ```bash uname -a | jc --uname -p # or: jc -p uname -a diff --git a/README.md b/README.md index 584f2ed3..774d5c4b 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio - `--tracepath` enables the `tracepath` and `tracepath6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/tracepath)) - `--traceroute` enables the `traceroute` and `traceroute6` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/traceroute)) - `--ufw` enables the `ufw status` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw)) +- `--ufw-appinfo` enables the `ufw app info [application]` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/ufw_appinfo)) - `--uname` enables the `uname -a` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uname)) - `--upower` enables the `upower` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/upower)) - `--uptime` enables the `uptime` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/uptime)) diff --git a/docs/parsers/ufw_appinfo.md b/docs/parsers/ufw_appinfo.md index 99b00694..826ff851 100644 --- a/docs/parsers/ufw_appinfo.md +++ b/docs/parsers/ufw_appinfo.md @@ -64,11 +64,61 @@ Schema: Examples: - $ ufw app info OpenSSH | jc --ufw-appinfo -p - [] + $ ufw app info MSN | jc --ufw-appinfo -p + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] + } - $ ufw app info OpenSSH | jc --ufw-appinfo -p -r - [] + $ ufw app info MSN | jc --ufw-appinfo -p -r + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + "1863", + "6901" + ], + "udp_list": [ + "1863", + "6901" + ], + "tcp_ranges": [ + { + "start": "6891", + "end": "6900" + } + ] + } ## info diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 7ccc11cd2d940628c58910d6497c6bbe5cac4ca0..547bcab0335d26de806de7f4bc691276736db7c4 100644 GIT binary patch delta 2084 zcmV+<2;29R5T_7-ABzYGQ~ZKp0{?1bE-?U|S#59II1>J@UqJ*5TmnRP)4g5bg1f`H zNp|DC_yv*MZP64BEm1ZTNmNNHjt=+ZZ)Ql@vXMx^eP}&HJ@dlha7a!Di);1}vorSo z-TSlf-Cx7^KeMyJ*)M~i+0h@-Y|1Wf#!OYVtSqan%%rV^Osr*pY0UtgMli*;2gkj(1#-44zf$+iYKA1NCs?HqF<(eQBrb)Y5)eZGS5XKxdp@U4Pqqr zbV$ut(jlRVDKTBL%4-D=fU7M3gGKv zj-wEQFywJ5Aq2ra68Br}B}p7WrA7-5?PwN`-y{>7eJRr;rAvp`WjAn{J<5cjM0JDX zM^ojK`~eMrmQK*oJAo#}yClPEU$%v38)?^=RJvKe0}bX0WiO&nuUknVcgO$|-BU?Y z2TXfla^-Mx)d$obsC$69Ohl{_?`XsI2$hekFmn<>vM}qxyErFRH%t^1(|h>s24chs zi9{c?SPAXHNcOftn`whQh`}V((v1hLu)HRk?!`+XXjko~TVrzzuYWthree z9*J(>5#hI-ClBE4_&!g5!5w%C8xb%>fggjD15L4na+>6fdEe5gZA>K1lxBV@H-@CjHU^ z!;tA0F>7CnPz0GC5tjvJPZmH4^amtSJ>W7Af4B<~kPPT<{9*mU+=0G~4pH#-y9x$#g8KKU ze-F0gIm+@SlS3A|KB>;QX; zD5=*XE1lSy;TeVge)r2wI{alZQE`Hk9KSE?SC!{ z`vQgz(jS!+7H0*|F)fT?8?FmD@k|>@d8PS=wF1=sPS+opxxsD(X1dPFY4 zxR!YL8?eP2k<9W(YR6RCd%*X9KppCp+6LjRXHN8{s z$0|-Z^Q_sUWmc_ZVOY*<>U4p1>f|ww zvwMh#53xfUx4E+fgy3_H$$#iH9gX04fD@9lL~1xD;n{ZNXBe^@SyazMIOd-zQGU9f zO|FIm62!Zg7Q+J@0SM(ho<%MEja+K3>)~j3`mo5gUtSXbQx|%5?n$Iss zi_zWPL)`ppiBP<5UWy9#>fq2U60V`d*LDqt;jK|+?uldu?4uFQj(>l^`#C8crb-P; z%-cpG$JQrYSs=bv&8Qxd{W4GRg2j4KHh zK_2={2PdrHp6gnnNKFTE?y~3}MjLwZAyape} zi&8CdaJY|#o#6|?Z2skT{QLDHxKL$Hb%q_sC+z*Zv%iJ-M-SFE3b`d?Q5aY)HW@FN O=l%!i*`!D&82|vrdk8N8 delta 2065 zcmV+s2=4c%5R?#qABzYG{JMZ(0{?1bE-?U|S#59II1>J@UqJ*5Tna>X)7xF(g1f`H zPIlwH_yv*MZLwK2v_#oVBvB=)I6B;qznLLr%SIvv_o4L+^~?*0!y!2tEU(!^%+A?| z_aDx~_dkXo&e{3k{HMWR*~xFwe8$E%6Q(L#R+d#(X42MwC&3`PX0y@sDgep5kReW{ zQW$18q5-Rv<-Dj#-YS(D#*2idG83V#OJPV!^mR60M3X2O&!^MT?2`Q#omq@-qpMr? z$9%Dz%xBS`L7+4!Tg#Z4y0HBDB0$T#@61aFr1SDB8sARn6Qcev=U56B1vgS?R&s4* zv1YPhCf2flv}S-#@;DYivr?8Kfsd#*)hcIq>Bne!Ihoz13)1RLf(3GgX;Ern1Wdz9 zRiG#67mPhgRT&nm96U?@Vj5Si@*3x#mY{OLMwu150O==@)n_DqLcuxl(P1$!*h;X< zfMcr~b(f+@a1P)%=tB{22iX;J#gouhBm*`t(J#|~C@Hx?H2?!yndc&r+=5~F1~C!` zx};%i@TwTF)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK< zfuj(DFywJ5Aq2ra68AgpB}p7XrA7-5?PwNG-Xs&6Ln+fErAvp`WjAn@J<5cjM0JDX zM^ojK`~eMrR!-2-dx0j!yClQvP_~6+0;08KGHr#9o zk3_fci11s^lSgoNdY>mh;SM~5jR+W`z>mSZBTcb{a+>MsOtj`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSEw|pAswCQnrmj(SP zU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR`zNDopq@{EFO^RfZ zs(+RiWV^+z%v~l8E2D=iSqyQcUj}bxO~hL~!^N$7T(z3RqljB~=fCEL8j2n@aPHe;QY(am&`Q;`Z{*srd zxXPQy`GFd`8s@4{@djS`O(&s^pt~$QwyniCw=C=n7&-vIS5jD<6+EM~FotcpE`Q*p zGHoQ~mF8R43Q+qyU0Y!02D=DY4s=dVy9f2v?DOPyKAT?6mcdt5(QDq6B9>{*;tKAU zc)iV(Htb1qdc=dy-^Sm@^PBl?gh7EPhlE!k27^6uE%DAaV9PfmndOhvMya&RH)de# zYp5j&Y(o5@8G?2P>5?~kI!#rj4*|MLv_tj24T_(Qp7Bg2B#V@|1*dQ^P{SBI8OzMUcln6N0*&+BF;r3=dNScPJ=5 z7S<1ZQYqtEx#3UFW! z!^H8W%k`JPT>i>Fa(@W$ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh7M{-; zEW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;5zUS4LidZg8Aa>?c~?% vWiVD{O?8Hy#_!mN_ve2L@sAa(Z4`1##-cE=T5LL5GSB@F^uK!k-WUJ?s0I}! diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index bd6a3063..ae4d83c5 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -61,11 +61,61 @@ Schema: Examples: - $ ufw app info OpenSSH | jc --ufw-appinfo -p - [] + $ ufw app info MSN | jc --ufw-appinfo -p + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] + } - $ ufw app info OpenSSH | jc --ufw-appinfo -p -r - [] + $ ufw app info MSN | jc --ufw-appinfo -p -r + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + "1863", + "6901" + ], + "udp_list": [ + "1863", + "6901" + ], + "tcp_ranges": [ + { + "start": "6891", + "end": "6900" + } + ] + } """ import jc.utils @@ -146,7 +196,7 @@ def _process(proc_data): def _parse_port_list(data, port_list=None): - """return a list of integers""" + """return a list of port strings""" # 1,2,3,4,5,6,7,8,9,10,9,30,80:90,8080:8090 # overlapping and repeated port numbers are allowed @@ -235,22 +285,22 @@ def parse(data, raw=False, quiet=False): line_list = line.rsplit('/', maxsplit=1) if len(line_list) == 2: if line_list[1] == 'tcp': - prot_list = _parse_port_list(line_list[0]) - if prot_list: - raw_output['tcp_list'] = prot_list + tcp_prot_list = _parse_port_list(line_list[0]) + if tcp_prot_list: + raw_output['tcp_list'] = tcp_prot_list - prot_range = _parse_port_range(line_list[0]) - if prot_range: - raw_output['tcp_ranges'] = prot_range + tcp_prot_range = _parse_port_range(line_list[0]) + if tcp_prot_range: + raw_output['tcp_ranges'] = tcp_prot_range elif line_list[1] == 'udp': - prot_list = _parse_port_list(line_list[0]) - if prot_list: - raw_output['udp_list'] = prot_list + udp_prot_list = _parse_port_list(line_list[0]) + if udp_prot_list: + raw_output['udp_list'] = udp_prot_list - prot_range = _parse_port_range(line_list[0]) - if prot_range: - raw_output['udp_ranges'] = prot_range + udp_prot_range = _parse_port_range(line_list[0]) + if udp_prot_range: + raw_output['udp_ranges'] = udp_prot_range # 'any' case else: @@ -271,10 +321,21 @@ def parse(data, raw=False, quiet=False): if 'udp_ranges' in raw_output: u_range = raw_output['udp_ranges'] - raw_output['tcp_list'] = _parse_port_list(line, t_list) - raw_output['tcp_ranges'] = _parse_port_range(line, t_range) - raw_output['udp_list'] = _parse_port_list(line, u_list) - raw_output['udp_ranges'] = _parse_port_range(line, u_range) + t_p_list = _parse_port_list(line, t_list) + if t_p_list: + raw_output['tcp_list'] = t_p_list + + t_r_list = _parse_port_range(line, t_range) + if t_r_list: + raw_output['tcp_ranges'] = t_r_list + + u_p_list = _parse_port_list(line, u_list) + if u_p_list: + raw_output['udp_list'] = u_p_list + + u_r_list = _parse_port_range(line, u_range) + if u_r_list: + raw_output['udp_ranges'] = u_r_list raw_output.update(raw_output) diff --git a/man/jc.1.gz b/man/jc.1.gz index 7ccc11cd2d940628c58910d6497c6bbe5cac4ca0..547bcab0335d26de806de7f4bc691276736db7c4 100644 GIT binary patch delta 2084 zcmV+<2;29R5T_7-ABzYGQ~ZKp0{?1bE-?U|S#59II1>J@UqJ*5TmnRP)4g5bg1f`H zNp|DC_yv*MZP64BEm1ZTNmNNHjt=+ZZ)Ql@vXMx^eP}&HJ@dlha7a!Di);1}vorSo z-TSlf-Cx7^KeMyJ*)M~i+0h@-Y|1Wf#!OYVtSqan%%rV^Osr*pY0UtgMli*;2gkj(1#-44zf$+iYKA1NCs?HqF<(eQBrb)Y5)eZGS5XKxdp@U4Pqqr zbV$ut(jlRVDKTBL%4-D=fU7M3gGKv zj-wEQFywJ5Aq2ra68Br}B}p7WrA7-5?PwN`-y{>7eJRr;rAvp`WjAn{J<5cjM0JDX zM^ojK`~eMrmQK*oJAo#}yClPEU$%v38)?^=RJvKe0}bX0WiO&nuUknVcgO$|-BU?Y z2TXfla^-Mx)d$obsC$69Ohl{_?`XsI2$hekFmn<>vM}qxyErFRH%t^1(|h>s24chs zi9{c?SPAXHNcOftn`whQh`}V((v1hLu)HRk?!`+XXjko~TVrzzuYWthree z9*J(>5#hI-ClBE4_&!g5!5w%C8xb%>fggjD15L4na+>6fdEe5gZA>K1lxBV@H-@CjHU^ z!;tA0F>7CnPz0GC5tjvJPZmH4^amtSJ>W7Af4B<~kPPT<{9*mU+=0G~4pH#-y9x$#g8KKU ze-F0gIm+@SlS3A|KB>;QX; zD5=*XE1lSy;TeVge)r2wI{alZQE`Hk9KSE?SC!{ z`vQgz(jS!+7H0*|F)fT?8?FmD@k|>@d8PS=wF1=sPS+opxxsD(X1dPFY4 zxR!YL8?eP2k<9W(YR6RCd%*X9KppCp+6LjRXHN8{s z$0|-Z^Q_sUWmc_ZVOY*<>U4p1>f|ww zvwMh#53xfUx4E+fgy3_H$$#iH9gX04fD@9lL~1xD;n{ZNXBe^@SyazMIOd-zQGU9f zO|FIm62!Zg7Q+J@0SM(ho<%MEja+K3>)~j3`mo5gUtSXbQx|%5?n$Iss zi_zWPL)`ppiBP<5UWy9#>fq2U60V`d*LDqt;jK|+?uldu?4uFQj(>l^`#C8crb-P; z%-cpG$JQrYSs=bv&8Qxd{W4GRg2j4KHh zK_2={2PdrHp6gnnNKFTE?y~3}MjLwZAyape} zi&8CdaJY|#o#6|?Z2skT{QLDHxKL$Hb%q_sC+z*Zv%iJ-M-SFE3b`d?Q5aY)HW@FN O=l%!i*`!D&82|vrdk8N8 delta 2065 zcmV+s2=4c%5R?#qABzYG{JMZ(0{?1bE-?U|S#59II1>J@UqJ*5Tna>X)7xF(g1f`H zPIlwH_yv*MZLwK2v_#oVBvB=)I6B;qznLLr%SIvv_o4L+^~?*0!y!2tEU(!^%+A?| z_aDx~_dkXo&e{3k{HMWR*~xFwe8$E%6Q(L#R+d#(X42MwC&3`PX0y@sDgep5kReW{ zQW$18q5-Rv<-Dj#-YS(D#*2idG83V#OJPV!^mR60M3X2O&!^MT?2`Q#omq@-qpMr? z$9%Dz%xBS`L7+4!Tg#Z4y0HBDB0$T#@61aFr1SDB8sARn6Qcev=U56B1vgS?R&s4* zv1YPhCf2flv}S-#@;DYivr?8Kfsd#*)hcIq>Bne!Ihoz13)1RLf(3GgX;Ern1Wdz9 zRiG#67mPhgRT&nm96U?@Vj5Si@*3x#mY{OLMwu150O==@)n_DqLcuxl(P1$!*h;X< zfMcr~b(f+@a1P)%=tB{22iX;J#gouhBm*`t(J#|~C@Hx?H2?!yndc&r+=5~F1~C!` zx};%i@TwTF)0wj3V)ub(k{gIB2Z2IaW~#DOXzty>t(jlRVDK?mK)8iA7s22*3gGK< zfuj(DFywJ5Aq2ra68AgpB}p7XrA7-5?PwNG-Xs&6Ln+fErAvp`WjAn@J<5cjM0JDX zM^ojK`~eMrR!-2-dx0j!yClQvP_~6+0;08KGHr#9o zk3_fci11s^lSgoNdY>mh;SM~5jR+W`z>mSZBTcb{a+>MsOtj`XKppj~!WtneJy`%H&>xUQ^?=Jf{O&G9Kr*1a@yGSEw|pAswCQnrmj(SP zU}_UvcT7667j8w~l5pG`g~IINP>z;1>@Nu|4dx{cM#Yc9zFkR`zNDopq@{EFO^RfZ zs(+RiWV^+z%v~l8E2D=iSqyQcUj}bxO~hL~!^N$7T(z3RqljB~=fCEL8j2n@aPHe;QY(am&`Q;`Z{*srd zxXPQy`GFd`8s@4{@djS`O(&s^pt~$QwyniCw=C=n7&-vIS5jD<6+EM~FotcpE`Q*p zGHoQ~mF8R43Q+qyU0Y!02D=DY4s=dVy9f2v?DOPyKAT?6mcdt5(QDq6B9>{*;tKAU zc)iV(Htb1qdc=dy-^Sm@^PBl?gh7EPhlE!k27^6uE%DAaV9PfmndOhvMya&RH)de# zYp5j&Y(o5@8G?2P>5?~kI!#rj4*|MLv_tj24T_(Qp7Bg2B#V@|1*dQ^P{SBI8OzMUcln6N0*&+BF;r3=dNScPJ=5 z7S<1ZQYqtEx#3UFW! z!^H8W%k`JPT>i>Fa(@W$ilIiUEEwnLDVc%DV+Dn|>P|^e~grr{(qh7M{-; zEW$_4|06SY`iR_vDpth*Yn^kMp~-hau(7r@7sKHi7NuI@;5zUS4LidZg8Aa>?c~?% vWiVD{O?8Hy#_!mN_ve2L@sAa(Z4`1##-cE=T5LL5GSB@F^uK!k-WUJ?s0I}! From 6aea066cf024f92adf4b94eebc7d51430c22332c Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 16:14:11 -0700 Subject: [PATCH 33/55] make normalized list appear only when data exists. set magic commands --- jc/parsers/ufw_appinfo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index ae4d83c5..57396f2c 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -127,7 +127,7 @@ class info(): author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' compatible = ['linux'] - magic_commands = ['ufw-appinfo'] + magic_commands = ['ufw app'] __version__ = info.version @@ -172,7 +172,9 @@ def _process(proc_data): port_set.update(range(item['start'], item['end'] + 1)) if protocol + '_list' in proc_data: - proc_data['normalized_' + protocol + '_list'] = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) + new_port_list = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) + if new_port_list: + proc_data['normalized_' + protocol + '_list'] = new_port_list new_port_ranges = [] state = 'findstart' # 'findstart' or 'findend' From 0a8495c68e427e39bbda957dd933fa2a461092e7 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 16:14:25 -0700 Subject: [PATCH 34/55] update docs --- jc/parsers/ufw.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index e2613e96..e251a0fb 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -48,7 +48,7 @@ Schema: Examples: - $ ufw status verbose numbered | jc --ufw -p + $ ufw status verbose | jc --ufw -p { "status": "active", "logging": "on", @@ -59,7 +59,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 1, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": "tcp", @@ -80,7 +80,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 2, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_transport": "tcp", @@ -101,7 +101,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 3, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": null, @@ -122,7 +122,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 4, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", @@ -143,7 +143,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 5, + "index": null, "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", @@ -164,7 +164,7 @@ Examples: ] } - $ ufw status verbose numbered | jc --ufw -p -r + $ ufw status verbose | jc --ufw -p -r { "status": "active", "logging": "on", @@ -175,7 +175,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "1", + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": "tcp", @@ -196,7 +196,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "2", + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_transport": "tcp", @@ -217,7 +217,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "3", + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": null, @@ -238,7 +238,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "4", + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", @@ -259,7 +259,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "5", + "index": null, "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", @@ -291,9 +291,6 @@ class info(): description = '`ufw status` command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' - # details = 'enter any other details here' - - # compatible options: linux, darwin, cygwin, win32, aix, freebsd compatible = ['linux'] magic_commands = ['ufw status'] From 9aa424f9f8c7e4e0dc29e2c58dac481098beba7d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 16:14:39 -0700 Subject: [PATCH 35/55] fix ufw example --- EXAMPLES.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 3b56c493..40074156 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3128,7 +3128,7 @@ traceroute -m 3 8.8.8.8 | jc --traceroute -p # or: jc -p traceroute -m ``` ### ufw status ```bash -ufw status verbose numbered | jc --ufw -p +ufw status verbose | jc --ufw -p # or jc -p ufw status verbose ``` ```json { @@ -3141,7 +3141,7 @@ ufw status verbose numbered | jc --ufw -p { "action": "ALLOW", "action_direction": "IN", - "index": 1, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": "tcp", @@ -3162,7 +3162,7 @@ ufw status verbose numbered | jc --ufw -p { "action": "ALLOW", "action_direction": "IN", - "index": 2, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_transport": "tcp", @@ -3183,7 +3183,7 @@ ufw status verbose numbered | jc --ufw -p { "action": "ALLOW", "action_direction": "IN", - "index": 3, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": null, @@ -3204,7 +3204,7 @@ ufw status verbose numbered | jc --ufw -p { "action": "ALLOW", "action_direction": "IN", - "index": 4, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", @@ -3225,7 +3225,7 @@ ufw status verbose numbered | jc --ufw -p { "action": "ALLOW", "action_direction": "IN", - "index": 5, + "index": null, "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", From ffac5bf9d381305daa86e546f8570be092e5ff34 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 16:14:53 -0700 Subject: [PATCH 36/55] doc update --- docs/parsers/ufw.md | 24 ++++++++++++------------ jc/man/jc.1.gz | Bin 2087 -> 2087 bytes man/jc.1.gz | Bin 2087 -> 2087 bytes 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index ef9b34c0..8fe94faf 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -51,7 +51,7 @@ Schema: Examples: - $ ufw status verbose numbered | jc --ufw -p + $ ufw status verbose | jc --ufw -p { "status": "active", "logging": "on", @@ -62,7 +62,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 1, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": "tcp", @@ -83,7 +83,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 2, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_transport": "tcp", @@ -104,7 +104,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 3, + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": null, @@ -125,7 +125,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 4, + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", @@ -146,7 +146,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": 5, + "index": null, "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", @@ -167,7 +167,7 @@ Examples: ] } - $ ufw status verbose numbered | jc --ufw -p -r + $ ufw status verbose | jc --ufw -p -r { "status": "active", "logging": "on", @@ -178,7 +178,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "1", + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": "tcp", @@ -199,7 +199,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "2", + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_transport": "tcp", @@ -220,7 +220,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "3", + "index": null, "network_protocol": "ipv4", "to_interface": "any", "to_transport": null, @@ -241,7 +241,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "4", + "index": null, "network_protocol": "ipv6", "to_interface": "any", "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", @@ -262,7 +262,7 @@ Examples: { "action": "ALLOW", "action_direction": "IN", - "index": "5", + "index": null, "network_protocol": "ipv4", "to_interface": "en0", "to_ip": "10.10.10.10", diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 547bcab0335d26de806de7f4bc691276736db7c4..d8d4e3b8c7d0b2bae70ee9f9bdb2efffbb028b58 100644 GIT binary patch delta 16 XcmZ23uv~y$zMF%iIHY+ay8;IQC(Z;~ delta 16 XcmZ23uv~y$zMF$1_)pVDb_EUqD%k|# diff --git a/man/jc.1.gz b/man/jc.1.gz index 547bcab0335d26de806de7f4bc691276736db7c4..d8d4e3b8c7d0b2bae70ee9f9bdb2efffbb028b58 100644 GIT binary patch delta 16 XcmZ23uv~y$zMF%iIHY+ay8;IQC(Z;~ delta 16 XcmZ23uv~y$zMF$1_)pVDb_EUqD%k|# From 4cbe84c3d6ac8a3b594feb525460f2a68f5d62b2 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Fri, 23 Apr 2021 16:15:04 -0700 Subject: [PATCH 37/55] add ufw-appinfo tests --- tests/fixtures/generic/ufw-appinfo-msn.json | 1 + tests/fixtures/generic/ufw-appinfo-msn.out | 9 +++ tests/fixtures/generic/ufw-appinfo-test.json | 1 + tests/fixtures/generic/ufw-appinfo-test.out | 9 +++ tests/fixtures/generic/ufw-appinfo-test2.json | 1 + tests/fixtures/generic/ufw-appinfo-test2.out | 9 +++ tests/fixtures/generic/ufw-appinfo-test3.json | 1 + tests/fixtures/generic/ufw-appinfo-test3.out | 9 +++ tests/test_ufw_appinfo.py | 70 +++++++++++++++++++ 9 files changed, 110 insertions(+) create mode 100644 tests/fixtures/generic/ufw-appinfo-msn.json create mode 100644 tests/fixtures/generic/ufw-appinfo-msn.out create mode 100644 tests/fixtures/generic/ufw-appinfo-test.json create mode 100644 tests/fixtures/generic/ufw-appinfo-test.out create mode 100644 tests/fixtures/generic/ufw-appinfo-test2.json create mode 100644 tests/fixtures/generic/ufw-appinfo-test2.out create mode 100644 tests/fixtures/generic/ufw-appinfo-test3.json create mode 100644 tests/fixtures/generic/ufw-appinfo-test3.out create mode 100644 tests/test_ufw_appinfo.py diff --git a/tests/fixtures/generic/ufw-appinfo-msn.json b/tests/fixtures/generic/ufw-appinfo-msn.json new file mode 100644 index 00000000..3532d142 --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-msn.json @@ -0,0 +1 @@ +{"profile":"MSN","title":"MSN Chat","description":"MSN chat protocol (with file transfer and voice)","tcp_list":[1863,6901],"udp_list":[1863,6901],"tcp_ranges":[{"start":6891,"end":6900}],"normalized_tcp_list":[1863,6901],"normalized_tcp_ranges":[{"start":6891,"end":6900}],"normalized_udp_list":[1863,6901]} diff --git a/tests/fixtures/generic/ufw-appinfo-msn.out b/tests/fixtures/generic/ufw-appinfo-msn.out new file mode 100644 index 00000000..a08c18c5 --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-msn.out @@ -0,0 +1,9 @@ +Profile: MSN +Title: MSN Chat +Description: MSN chat protocol (with file transfer and voice) + +Ports: + 1863 + 6891:6900/tcp + 6901 + diff --git a/tests/fixtures/generic/ufw-appinfo-test.json b/tests/fixtures/generic/ufw-appinfo-test.json new file mode 100644 index 00000000..64eb243e --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test.json @@ -0,0 +1 @@ +{"profile":"TEST","title":"My test app","description":"a longer description of the test app here.","tcp_list":[1,2,3,4,5,6,7,8,9,10,9,8,7,30,53],"tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"udp_ranges":[{"start":50,"end":51},{"start":40,"end":60}],"udp_list":[53],"normalized_tcp_list":[1,2,3,4,5,6,7,8,9,10,30,53],"normalized_tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"normalized_udp_ranges":[{"start":40,"end":60}]} diff --git a/tests/fixtures/generic/ufw-appinfo-test.out b/tests/fixtures/generic/ufw-appinfo-test.out new file mode 100644 index 00000000..f8e3d73a --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test.out @@ -0,0 +1,9 @@ +Profile: TEST +Title: My test app +Description: a longer description of the test app here. + +Ports: + 1,2,3,4,5,6,7,8,9,10,9,8,7,30,80:90,8080:8090/tcp + 50:51,40:60/udp + 53 + diff --git a/tests/fixtures/generic/ufw-appinfo-test2.json b/tests/fixtures/generic/ufw-appinfo-test2.json new file mode 100644 index 00000000..b48fb46a --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test2.json @@ -0,0 +1 @@ +{"profile":"TEST2","title":"My test app2","description":"a longer description of the test app here.","tcp_ranges":[{"start":0,"end":65535}],"udp_ranges":[{"start":50,"end":51}],"tcp_list":[53],"udp_list":[53],"normalized_tcp_ranges":[{"start":0,"end":65535}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]} diff --git a/tests/fixtures/generic/ufw-appinfo-test2.out b/tests/fixtures/generic/ufw-appinfo-test2.out new file mode 100644 index 00000000..6b3bf5d5 --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test2.out @@ -0,0 +1,9 @@ +Profile: TEST2 +Title: My test app2 +Description: a longer description of the test app here. + +Ports: + any/tcp + 50:51/udp + 53 + diff --git a/tests/fixtures/generic/ufw-appinfo-test3.json b/tests/fixtures/generic/ufw-appinfo-test3.json new file mode 100644 index 00000000..20eb606c --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test3.json @@ -0,0 +1 @@ +{"profile":"TEST3","title":"My test app3","description":"test overlapping ports","tcp_list":[80,83,80,53],"tcp_ranges":[{"start":70,"end":90}],"udp_ranges":[{"start":50,"end":51}],"udp_list":[53],"normalized_tcp_list":[53],"normalized_tcp_ranges":[{"start":70,"end":90}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]} diff --git a/tests/fixtures/generic/ufw-appinfo-test3.out b/tests/fixtures/generic/ufw-appinfo-test3.out new file mode 100644 index 00000000..45a8f1fb --- /dev/null +++ b/tests/fixtures/generic/ufw-appinfo-test3.out @@ -0,0 +1,9 @@ +Profile: TEST3 +Title: My test app3 +Description: test overlapping ports + +Ports: + 80,83,80,70:90/tcp + 50:51/udp + 53 + diff --git a/tests/test_ufw_appinfo.py b/tests/test_ufw_appinfo.py new file mode 100644 index 00000000..ae5acb88 --- /dev/null +++ b/tests/test_ufw_appinfo.py @@ -0,0 +1,70 @@ +import os +import json +import unittest +import jc.parsers.ufw_appinfo + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class MyTests(unittest.TestCase): + + def setUp(self): + # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test2.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test2 = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test3.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test3 = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-msn.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_msn = f.read() + + # output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test2.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test2_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test3.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_test3_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-msn.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_appinfo_msn_json = json.loads(f.read()) + + def test_ufw_appinfo_nodata(self): + """ + Test 'ufw_appinfo' with no data + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse('', quiet=True), {}) + + def test_ufw_appinfo_generic_test(self): + """ + Test 'ufw app info [application]' sample + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_test, quiet=True), self.generic_ufw_appinfo_test_json) + + def test_ufw_appinfo_generic_test2(self): + """ + Test 'ufw app info [application]' sample + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_test2, quiet=True), self.generic_ufw_appinfo_test2_json) + + def test_ufw_appinfo_generic_test3(self): + """ + Test 'ufw app info [application]' sample + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_test3, quiet=True), self.generic_ufw_appinfo_test3_json) + + def test_ufw_appinfo_generic_msn(self): + """ + Test 'ufw app info MSN' sample + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.generic_ufw_appinfo_msn, quiet=True), self.generic_ufw_appinfo_msn_json) + + +if __name__ == '__main__': + unittest.main() From f6ca32b3a31f314fa0b31d9e8b5494491b928f7e Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 10:22:19 -0700 Subject: [PATCH 38/55] update ufw docs with a note on lists of ports --- docs/parsers/ufw.md | 2 ++ jc/parsers/ufw.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index 8fe94faf..d89f4d88 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -3,6 +3,8 @@ # jc.parsers.ufw jc - JSON CLI output utility `ufw status` command output parser +Note: a list of ports will be parsed to the `to_service` or `from_service` field as a comma-separated string. + Usage (cli): $ ufw status | jc --ufw diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index e251a0fb..7d5a3d9f 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -1,5 +1,7 @@ """jc - JSON CLI output utility `ufw status` command output parser +Note: a list of ports will be parsed to the `to_service` or `from_service` field as a comma-separated string. + Usage (cli): $ ufw status | jc --ufw From 9f925d6ac989a4f21a8c00c84fcf97dfb141e8c2 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 10:22:37 -0700 Subject: [PATCH 39/55] doc update --- jc/man/jc.1.gz | Bin 2087 -> 2087 bytes man/jc.1.gz | Bin 2087 -> 2087 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index d8d4e3b8c7d0b2bae70ee9f9bdb2efffbb028b58..2d3ee4fd4a2ceb17b505fd814c342ed8017401d6 100644 GIT binary patch delta 67 zcmV-J0KEUF5T_6#ABzYGa#Mt00{?1bE-?U|S#59II1>J@UqJ*5TmnRP)7z0EKMT*{ Z`=8m_;Ov*dU$Jbn2M7!t;jJba004Ik8;Jk_ delta 67 zcmV-J0KEUF5T_6#ABzYGb5w(10{?1bE-?U|S#59II1>J@UqJ*5TmnRP)4h=*KMP;O Z_dm0J@UqJ*5TmnRP)7z0EKMT*{ Z`=8m_;Ov*dU$Jbn2M7!t;jJba004Ik8;Jk_ delta 67 zcmV-J0KEUF5T_6#ABzYGb5w(10{?1bE-?U|S#59II1>J@UqJ*5TmnRP)4h=*KMP;O Z_dm0 Date: Sat, 24 Apr 2021 10:58:31 -0700 Subject: [PATCH 40/55] add another ufw test sample --- runtests.sh | 1 + tests/fixtures/generic/ufw-numbered2.json | 1 + tests/fixtures/generic/ufw-numbered2.out | 18 ++++++++++++++++++ tests/test_ufw.py | 12 ++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 tests/fixtures/generic/ufw-numbered2.json create mode 100644 tests/fixtures/generic/ufw-numbered2.out diff --git a/runtests.sh b/runtests.sh index 2f592d3e..d0a7ab96 100755 --- a/runtests.sh +++ b/runtests.sh @@ -1,3 +1,4 @@ #!/bin/bash +# system should be in "America/Los_Angeles" timezone for all tests to pass python3 -m unittest -v diff --git a/tests/fixtures/generic/ufw-numbered2.json b/tests/fixtures/generic/ufw-numbered2.json new file mode 100644 index 00000000..bbcb1aa1 --- /dev/null +++ b/tests/fixtures/generic/ufw-numbered2.json @@ -0,0 +1 @@ +{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_ip":"224.0.0.251","to_ip_prefix":32,"to_transport":null,"to_service":"mDNS","to_start_port":null,"to_end_port":null,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_ip":"0.0.0.0","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"123.123.123.123","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":25,"to_end_port":25,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":465,"to_end_port":465,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":993,"to_end_port":993,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":995,"to_end_port":995,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_ip":"ff02::fb","to_ip_prefix":128,"to_transport":null,"to_service":"mDNS","to_start_port":null,"to_end_port":null,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":25,"to_end_port":25,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":13,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":465,"to_end_port":465,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":993,"to_end_port":993,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":995,"to_end_port":995,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} diff --git a/tests/fixtures/generic/ufw-numbered2.out b/tests/fixtures/generic/ufw-numbered2.out new file mode 100644 index 00000000..6cd82010 --- /dev/null +++ b/tests/fixtures/generic/ufw-numbered2.out @@ -0,0 +1,18 @@ +Status: active + To Action From + -- ------ ---- +[ 1] 224.0.0.251 mDNS ALLOW IN Anywhere +[ 2] Anywhere ALLOW IN 123.123.123.123 +[ 3] 25 ALLOW IN Anywhere +[ 4] 80 ALLOW IN Anywhere +[ 5] 443 ALLOW IN Anywhere +[ 6] 465 ALLOW IN Anywhere +[ 7] 993 ALLOW IN Anywhere +[ 8] 995 ALLOW IN Anywhere +[ 9] ff02::fb mDNS ALLOW IN Anywhere (v6) +[10] 25 (v6) ALLOW IN Anywhere (v6) +[11] 80 (v6) ALLOW IN Anywhere (v6) +[12] 443 (v6) ALLOW IN Anywhere (v6) +[13] 465 (v6) ALLOW IN Anywhere (v6) +[14] 993 (v6) ALLOW IN Anywhere (v6) +[15] 995 (v6) ALLOW IN Anywhere (v6) diff --git a/tests/test_ufw.py b/tests/test_ufw.py index 3dbe8370..28fdcc69 100644 --- a/tests/test_ufw.py +++ b/tests/test_ufw.py @@ -22,6 +22,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered.out'), 'r', encoding='utf-8') as f: self.generic_ufw_numbered = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered2.out'), 'r', encoding='utf-8') as f: + self.generic_ufw_numbered2 = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-inactive.out'), 'r', encoding='utf-8') as f: self.generic_ufw_inactive = f.read() @@ -38,6 +41,9 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered.json'), 'r', encoding='utf-8') as f: self.generic_ufw_numbered_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-numbered2.json'), 'r', encoding='utf-8') as f: + self.generic_ufw_numbered2_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-inactive.json'), 'r', encoding='utf-8') as f: self.generic_ufw_inactive_json = json.loads(f.read()) @@ -71,6 +77,12 @@ class MyTests(unittest.TestCase): """ self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw_numbered, quiet=True), self.generic_ufw_numbered_json) + def test_ufw_generic_verbose_numbered2(self): + """ + Test 'ufw status verbose numbered' sample + """ + self.assertEqual(jc.parsers.ufw.parse(self.generic_ufw_numbered2, quiet=True), self.generic_ufw_numbered2_json) + def test_ufw_generic_inactive(self): """ Test 'ufw status' when firewall is inactive From e23aa818eaa6d1a389ddef7dd2ad8f62b9f6ff25 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 12:47:12 -0700 Subject: [PATCH 41/55] add tests section and timezone info --- CONTRIBUTING.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5531efcb..cea57a16 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu 2. Fork the repo and create your branch from `dev`, if available, otherwise `master`. 3. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests. 4. Documentation is auto-generated from docstrings, so ensure they are clear and accurate. -5. Ensure the test suite passes. +5. Ensure the test suite passes. (Note: "America/Los_Angeles" timezone should be configured on the test system) 6. Make sure your code lints. 7. Issue that pull request! @@ -61,6 +61,9 @@ Good: ] ``` +## Tests +It is essential to have good command output sample coverage and tests to keep the `jc` parser quality high. Many parsers include calculated timestamp fields using the `jc.utils.timestamp()` class. Naive timestamps created with this class should be generated on a system configured with the "America/Los_Angeles" timezone on linux/macOS/unix and "Pacific Standard Time" timezone on Windows for tests to pass on the Github Actions CI tests. + ## Any contributions you make will be under the MIT Software License In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. From b833c44783eb32f2fad24ca205b5b7eab854750f Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 12:47:24 -0700 Subject: [PATCH 42/55] add ufw-appinfo parser --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e7f69b05..6b2d1df5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ jc changelog 20210420 v1.15.3 - Add ufw status command parser tested on linux +- Add ufw-appinfo command parser tested on linux - Fix deb package name to conform to standard 20210418 v1.15.2 From 14289ecd6c022ad204444dff5b5e48f6024a5d0d Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 12:50:40 -0700 Subject: [PATCH 43/55] more timezone info --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cea57a16..06d822f4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,7 +62,9 @@ Good: ``` ## Tests -It is essential to have good command output sample coverage and tests to keep the `jc` parser quality high. Many parsers include calculated timestamp fields using the `jc.utils.timestamp()` class. Naive timestamps created with this class should be generated on a system configured with the "America/Los_Angeles" timezone on linux/macOS/unix and "Pacific Standard Time" timezone on Windows for tests to pass on the Github Actions CI tests. +It is essential to have good command output sample coverage and tests to keep the `jc` parser quality high. Many parsers include calculated timestamp fields using the `jc.utils.timestamp()` class. + +Naive timestamps created with this class should be generated on a system configured with the "America/Los_Angeles" timezone on linux/macOS/unix and "Pacific Standard Time" timezone on Windows for tests to pass on the Github Actions CI tests. This timezone should be configured on your local system before running the tests locally, as well. ## Any contributions you make will be under the MIT Software License In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. From 8c91a7b7601a967cd9d8096433ffd4ad62b65ceb Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 12:52:26 -0700 Subject: [PATCH 44/55] formatting --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 06d822f4..00698b1f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -62,9 +62,9 @@ Good: ``` ## Tests -It is essential to have good command output sample coverage and tests to keep the `jc` parser quality high. Many parsers include calculated timestamp fields using the `jc.utils.timestamp()` class. +It is essential to have good command output sample coverage and tests to keep the `jc` parser quality high. -Naive timestamps created with this class should be generated on a system configured with the "America/Los_Angeles" timezone on linux/macOS/unix and "Pacific Standard Time" timezone on Windows for tests to pass on the Github Actions CI tests. This timezone should be configured on your local system before running the tests locally, as well. +Many parsers include calculated timestamp fields using the `jc.utils.timestamp` class. Naive timestamps created with this class should be generated on a system configured with the "**America/Los_Angeles**" timezone on linux/macOS/unix and "**Pacific Standard Time**" timezone on Windows for tests to pass on the Github Actions CI tests. This timezone should be configured on your local system before running the tests locally, as well. ## Any contributions you make will be under the MIT Software License In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. From 929c38715d87bf9dd689507d319c22b90871ae1c Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sat, 24 Apr 2021 12:53:29 -0700 Subject: [PATCH 45/55] formatting --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 00698b1f..1fba610f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu 2. Fork the repo and create your branch from `dev`, if available, otherwise `master`. 3. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests. 4. Documentation is auto-generated from docstrings, so ensure they are clear and accurate. -5. Ensure the test suite passes. (Note: "America/Los_Angeles" timezone should be configured on the test system) +5. Ensure the test suite passes. (Note: "**America/Los_Angeles**" timezone should be configured on the test system) 6. Make sure your code lints. 7. Issue that pull request! From 5eff65c326675a449afd05a2af0a6c9bcf7b5e23 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sun, 25 Apr 2021 20:10:52 -0700 Subject: [PATCH 46/55] update schema to support port lists and port range lists. Also support other transports than tcp and udp --- jc/parsers/ufw.py | 353 +++++++++++----------------------------------- 1 file changed, 85 insertions(+), 268 deletions(-) diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 7d5a3d9f..b4def323 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -1,7 +1,5 @@ """jc - JSON CLI output utility `ufw status` command output parser -Note: a list of ports will be parsed to the `to_service` or `from_service` field as a comma-separated string. - Usage (cli): $ ufw status | jc --ufw @@ -32,17 +30,31 @@ Schema: "to_ip": string, "to_ip_prefix": integer, "to_interface": string, - "to_transport": string, # null if to_service is set and not a list of ports - "to_start_port": integer, # null if to_service is set and not a list of ports - "to_end_port": integer, # null if to_service is set and not a list of ports - "to_service": string, # null if any above are set (can also be a list of ports) + "to_transport": string, + "to_ports": [ + integer + ], + "to_port_ranges": [ + { + "start": integer, + "end": integer + } + ], + "to_service": string, # null if any to ports or port_ranges are set "from_ip": string, "from_ip_prefix": integer, "from_interface": string, - "from_transport": string, # null if to_service is set and not a list of ports - "from_start_port": integer, # null if to_service is set and not a list of ports - "from_end_port": integer, # null if to_service is set and not a list of ports - "from_service": string, # null if any above are set (can also be a list of ports) + "from_transport": string, + "from_ports": [ + integer + ], + "from_port_ranges": [ + { + "start": integer, + "end": integer + } + ], + "from_service": string, # null if any from ports or port_ranges are set "comment": string # null if no comment } ] @@ -51,236 +63,10 @@ Schema: Examples: $ ufw status verbose | jc --ufw -p - { - "status": "active", - "logging": "on", - "logging_level": "low", - "default": "deny (incoming), allow (outgoing), deny (routed)", - "new_profiles": "skip", - "rules": [ - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, - "to_service": null, - "to_ip": "0.0.0.0", - "to_ip_prefix": 0, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, - "to_service": null, - "to_ip": "::", - "to_ip_prefix": 0, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "any", - "to_transport": null, - "to_service": "Apache Full", - "to_start_port": null, - "to_end_port": null, - "to_ip": "0.0.0.0", - "to_ip_prefix": 0, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": 128, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "en0", - "to_ip": "10.10.10.10", - "to_ip_prefix": 32, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - } - ] - } + $ ufw status verbose | jc --ufw -p -r - { - "status": "active", - "logging": "on", - "logging_level": "low", - "default": "deny (incoming), allow (outgoing), deny (routed)", - "new_profiles": "skip", - "rules": [ - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": "22", - "to_end_port": "22", - "to_service": null, - "to_ip": "0.0.0.0", - "to_ip_prefix": "0", - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": "22", - "to_end_port": "22", - "to_service": null, - "to_ip": "::", - "to_ip_prefix": "0", - "comment": null, - "from_ip": "::", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "any", - "to_transport": null, - "to_service": "Apache Full", - "to_start_port": null, - "to_end_port": null, - "to_ip": "0.0.0.0", - "to_ip_prefix": "0", - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": "128", - "to_transport": "any", - "to_start_port": "0", - "to_end_port": "65535", - "to_service": null, - "comment": null, - "from_ip": "::", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "en0", - "to_ip": "10.10.10.10", - "to_ip_prefix": "32", - "to_transport": "any", - "to_start_port": "0", - "to_end_port": "65535", - "to_service": null, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - } - ] - } + """ import jc.utils import re @@ -312,8 +98,7 @@ def _process(proc_data): Dictionary. Structured to conform to the schema. """ - int_list = ['index', 'to_ip_prefix', 'to_start_port', 'to_end_port', 'from_ip_prefix', - 'from_start_port', 'from_end_port'] + int_list = ['index', 'to_ip_prefix', 'from_ip_prefix'] if 'rules' in proc_data: for i, item in enumerate(proc_data['rules']): @@ -321,6 +106,15 @@ def _process(proc_data): if key in int_list: proc_data['rules'][i][key] = jc.utils.convert_to_int(proc_data['rules'][i][key]) + if key in ['to_ports', 'from_ports']: + for i2, item2 in enumerate(proc_data['rules'][i][key]): + proc_data['rules'][i][key][i2] = jc.utils.convert_to_int(item2) + + if key in ['to_port_ranges', 'from_port_ranges']: + for i2, item2 in enumerate(proc_data['rules'][i][key]): + proc_data['rules'][i][key][i2]['start'] = jc.utils.convert_to_int(proc_data['rules'][i][key][i2]['start']) + proc_data['rules'][i][key][i2]['end'] = jc.utils.convert_to_int(proc_data['rules'][i][key][i2]['end']) + return proc_data @@ -377,6 +171,15 @@ def _parse_to_from(linedata, direction, rule_obj=None): else: rule_obj[direction + '_interface'] = 'any' + # pull tcp/udp/etc. transport - strip on '/' + linedata_list = linedata.rsplit('/', maxsplit=1) + if len(linedata_list) > 1: + if linedata_list[1].strip() in ['tcp', 'udp', 'ah', 'esp', 'gre', 'ipv6', 'igmp']: + rule_obj[direction + '_transport'] = linedata_list[1].strip() + linedata = linedata_list[0] + else: + rule_obj[direction + '_transport'] = 'any' + # pull out ipv4 or ipv6 addresses linedata_list = linedata.split() new_linedata_list = [] @@ -396,35 +199,36 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_ip_prefix'] = str(valid_ip.with_prefixlen.split('/')[1]) linedata = ' '.join(new_linedata_list) - # pull tcp/udp transport and strip on '/' for ports - linedata_list = linedata.rsplit('/', maxsplit=1) - if len(linedata_list) > 1: - rule_obj[direction + '_transport'] = linedata_list[1].strip() - linedata = linedata_list[0] - else: - rule_obj[direction + '_transport'] = 'any' - # find the numeric port(s) - linedata_list = linedata.split(':', maxsplit=1) - if len(linedata_list) == 2 and linedata_list[0].strip().isnumeric(): - rule_obj[direction + '_start_port'] = linedata_list[0].strip() - rule_obj[direction + '_end_port'] = linedata_list[1].strip() - rule_obj[direction + '_service'] = None - linedata = '' - elif len(linedata_list) == 1 and linedata_list[0].strip().isnumeric(): - rule_obj[direction + '_start_port'] = linedata_list[0].strip() - rule_obj[direction + '_end_port'] = linedata_list[0].strip() + linedata_list = linedata.split(',') + port_list = [] + port_ranges = [] + for item in linedata_list: + if item.strip().isnumeric(): + port_list.append(item.strip()) + elif ':' in item: + p_range = item.strip().split(':', maxsplit=1) + port_ranges.append( + { + "start": p_range[0], + "end": p_range[1] + } + ) + + if port_list or port_ranges: rule_obj[direction + '_service'] = None linedata = '' + if port_list: + rule_obj[direction + '_ports'] = port_list + + if port_ranges: + rule_obj[direction + '_port_ranges'] = port_ranges + # only thing left should be the service name. if linedata.strip(): rule_obj[direction + '_service'] = linedata.strip() - rule_obj[direction + '_start_port'] = None - rule_obj[direction + '_end_port'] = None - # if service name is really a list of ports, don't reset the _transport field to null - if ',' not in rule_obj[direction + '_service']: - rule_obj[direction + '_transport'] = None + rule_obj[direction + '_transport'] = None # check if to/from IP addresses exist. If not, set to 0.0.0.0/0 or ::/0 if direction + '_ip' not in rule_obj: @@ -435,12 +239,25 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_ip'] = '0.0.0.0' rule_obj[direction + '_ip_prefix'] = '0' - # finally ensure service or ports exist. If not, set default values - if not rule_obj.get(direction + '_service'): - if not rule_obj.get(direction + '_start_port'): - rule_obj[direction + '_start_port'] = '0' - rule_obj[direction + '_end_port'] = '65535' - rule_obj[direction + '_service'] = None + # finally set default ports if no ports exist and there should be some + set_default = False + if direction + '_transport' in rule_obj: + if rule_obj[direction + '_transport'] in ['tcp', 'udp', 'any']: + if not port_list and not port_ranges: + set_default = True + + else: + rule_obj[direction + '_transport'] = 'any' + set_default = True + + if set_default: + rule_obj[direction + '_port_ranges'] = [ + { + 'start': '0', + 'end': '65535' + } + ] + rule_obj[direction + '_service'] = None return rule_obj From d1f33645caccdb3a55576081c4d355f997ac033c Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sun, 25 Apr 2021 20:40:38 -0700 Subject: [PATCH 47/55] update ufw tests --- tests/fixtures/generic/ufw-numbered.json | 2 +- tests/fixtures/generic/ufw-numbered2.json | 2 +- tests/fixtures/generic/ufw.json | 2 +- tests/fixtures/ubuntu-18.04/ufw-numbered.json | 2 +- tests/fixtures/ubuntu-18.04/ufw-numbered.out | 16 ++++++++++++---- tests/fixtures/ubuntu-18.04/ufw-verbose.json | 2 +- tests/fixtures/ubuntu-18.04/ufw-verbose.out | 10 +++++++++- 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tests/fixtures/generic/ufw-numbered.json b/tests/fixtures/generic/ufw-numbered.json index 76d14a27..27809d81 100644 --- a/tests/fixtures/generic/ufw-numbered.json +++ b/tests/fixtures/generic/ufw-numbered.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":32,"to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":0,"end":65535}],"from_transport":"any"},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/generic/ufw-numbered2.json b/tests/fixtures/generic/ufw-numbered2.json index bbcb1aa1..31622026 100644 --- a/tests/fixtures/generic/ufw-numbered2.json +++ b/tests/fixtures/generic/ufw-numbered2.json @@ -1 +1 @@ -{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_ip":"224.0.0.251","to_ip_prefix":32,"to_transport":null,"to_service":"mDNS","to_start_port":null,"to_end_port":null,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_ip":"0.0.0.0","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":null,"from_interface":"any","from_ip":"123.123.123.123","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":25,"to_end_port":25,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":465,"to_end_port":465,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":993,"to_end_port":993,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":995,"to_end_port":995,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_ip":"ff02::fb","to_ip_prefix":128,"to_transport":null,"to_service":"mDNS","to_start_port":null,"to_end_port":null,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":25,"to_end_port":25,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":13,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":465,"to_end_port":465,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":993,"to_end_port":993,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":995,"to_end_port":995,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_ip":"224.0.0.251","to_ip_prefix":32,"to_service":"mDNS","comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_ip":"0.0.0.0","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"123.123.123.123","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[25],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[465],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[993],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[995],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_ip":"ff02::fb","to_ip_prefix":128,"to_service":"mDNS","comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[25],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[443],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":13,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[465],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[993],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[995],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.json b/tests/fixtures/generic/ufw.json index 0238ff7b..9ea2b2a2 100644 --- a/tests/fixtures/generic/ufw.json +++ b/tests/fixtures/generic/ufw.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"nice comment","from_interface":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":443,"to_end_port":443,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_start_port":8080,"from_end_port":8081,"from_service":null},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_ip":"10.10.10.10","to_ip_prefix":32,"to_transport":"any","to_start_port":8080,"to_end_port":8080,"to_service":null,"comment":null,"from_interface":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_transport":"any","from_start_port":8000,"from_end_port":8000,"from_service":null},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_start_port":50200,"to_end_port":50300,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_start_port":0,"to_end_port":65535,"to_service":null,"comment":"this is a comment","from_interface":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"nice comment","from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":0,"end":65535}],"from_transport":"any"},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":"this is a comment","from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/ubuntu-18.04/ufw-numbered.json b/tests/fixtures/ubuntu-18.04/ufw-numbered.json index 16383d39..fbb008be 100644 --- a/tests/fixtures/ubuntu-18.04/ufw-numbered.json +++ b/tests/fixtures/ubuntu-18.04/ufw-numbered.json @@ -1 +1 @@ -{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":2,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[80,443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":3,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"ipv6","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"ipv6","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"esp","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"esp","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"esp","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv4","to_interface":"any","to_transport":"ah","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"ah","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"ah","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[1,2],"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[80,443],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":13,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[1,2],"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/ubuntu-18.04/ufw-numbered.out b/tests/fixtures/ubuntu-18.04/ufw-numbered.out index a9ba97ff..8138cff8 100644 --- a/tests/fixtures/ubuntu-18.04/ufw-numbered.out +++ b/tests/fixtures/ubuntu-18.04/ufw-numbered.out @@ -5,7 +5,15 @@ Status: active [ 1] 22 ALLOW IN Anywhere [ 2] 80,443/tcp ALLOW IN Anywhere [ 3] 80 on eth0 ALLOW IN Anywhere # test -[ 4] 22 (v6) ALLOW IN Anywhere (v6) -[ 5] 80,443/tcp (v6) ALLOW IN Anywhere (v6) -[ 6] 80 (v6) on eth0 ALLOW IN Anywhere (v6) # test - +[ 4] 10.0.0.1/ipv6 ALLOW IN 10.4.0.0/16/ipv6 +[ 5] 10.0.0.1/esp ALLOW IN Anywhere +[ 6] 10.0.0.1/esp ALLOW IN 10.4.0.0/16/esp +[ 7] 10.0.0.1/ah ALLOW IN Anywhere +[ 8] 10.0.0.1/ah ALLOW IN 10.4.0.0/16/ah +[ 9] 100:200,300:400/tcp ALLOW IN Anywhere +[10] 1,2,100:200,300:400/udp ALLOW IN Anywhere +[11] 22 (v6) ALLOW IN Anywhere (v6) +[12] 80,443/tcp (v6) ALLOW IN Anywhere (v6) +[13] 80 (v6) on eth0 ALLOW IN Anywhere (v6) # test +[14] 100:200,300:400/tcp (v6) ALLOW IN Anywhere (v6) +[15] 1,2,100:200,300:400/udp (v6) ALLOW IN Anywhere (v6) diff --git a/tests/fixtures/ubuntu-18.04/ufw-verbose.json b/tests/fixtures/ubuntu-18.04/ufw-verbose.json index 83384f3d..d833be45 100644 --- a/tests/fixtures/ubuntu-18.04/ufw-verbose.json +++ b/tests/fixtures/ubuntu-18.04/ufw-verbose.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), disabled (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_start_port":22,"to_end_port":22,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":"80,443","to_start_port":null,"to_end_port":null,"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_start_port":80,"to_end_port":80,"to_service":null,"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_start_port":0,"from_end_port":65535,"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), disabled (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[80,443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"eth0","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"test","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"ipv6","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"ipv6","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"esp","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"esp","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"esp","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"ah","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"ah","to_ip":"10.0.0.1","to_ip_prefix":32,"comment":null,"from_interface":"any","from_transport":"ah","from_ip":"10.4.0.0","from_ip_prefix":16},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[1,2],"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[80,443],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"eth0","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"::","to_ip_prefix":0,"comment":"test","from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[1,2],"to_port_ranges":[{"start":100,"end":200},{"start":300,"end":400}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/ubuntu-18.04/ufw-verbose.out b/tests/fixtures/ubuntu-18.04/ufw-verbose.out index a653d609..a826d052 100644 --- a/tests/fixtures/ubuntu-18.04/ufw-verbose.out +++ b/tests/fixtures/ubuntu-18.04/ufw-verbose.out @@ -8,7 +8,15 @@ To Action From 22 ALLOW IN Anywhere 80,443/tcp ALLOW IN Anywhere 80 on eth0 ALLOW IN Anywhere # test +10.0.0.1/ipv6 ALLOW IN 10.4.0.0/16/ipv6 +10.0.0.1/esp ALLOW IN Anywhere +10.0.0.1/esp ALLOW IN 10.4.0.0/16/esp +10.0.0.1/ah ALLOW IN Anywhere +10.0.0.1/ah ALLOW IN 10.4.0.0/16/ah +100:200,300:400/tcp ALLOW IN Anywhere +1,2,100:200,300:400/udp ALLOW IN Anywhere 22 (v6) ALLOW IN Anywhere (v6) 80,443/tcp (v6) ALLOW IN Anywhere (v6) 80 (v6) on eth0 ALLOW IN Anywhere (v6) # test - +100:200,300:400/tcp (v6) ALLOW IN Anywhere (v6) +1,2,100:200,300:400/udp (v6) ALLOW IN Anywhere (v6) From 66cb4e9bde81b9290c1addaf851de5d80a1b0702 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sun, 25 Apr 2021 20:49:35 -0700 Subject: [PATCH 48/55] update ufw parser docs --- EXAMPLES.md | 98 +++++-------------- docs/parsers/ufw.md | 230 ++++++++++++++------------------------------ jc/man/jc.1.gz | Bin 2087 -> 2087 bytes jc/parsers/ufw.py | 128 +++++++++++++++++++++++- man/jc.1.gz | Bin 2087 -> 2087 bytes 5 files changed, 219 insertions(+), 237 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 40074156..c221cbf9 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3135,7 +3135,7 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose "status": "active", "logging": "on", "logging_level": "low", - "default": "deny (incoming), allow (outgoing), deny (routed)", + "default": "deny (incoming), allow (outgoing), disabled (routed)", "new_profiles": "skip", "rules": [ { @@ -3144,10 +3144,11 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, + "to_transport": "any", "to_service": null, + "to_ports": [ + 22 + ], "to_ip": "0.0.0.0", "to_ip_prefix": 0, "comment": null, @@ -3155,29 +3156,12 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, - "to_service": null, - "to_ip": "::", - "to_ip_prefix": 0, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, + "from_port_ranges": [ + { + "start": 0, + "end": 65535 + } + ], "from_service": null }, { @@ -3186,10 +3170,12 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": null, - "to_service": "Apache Full", - "to_start_port": null, - "to_end_port": null, + "to_transport": "tcp", + "to_service": null, + "to_ports": [ + 80, + 443 + ], "to_ip": "0.0.0.0", "to_ip_prefix": 0, "comment": null, @@ -3197,50 +3183,12 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": 128, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "en0", - "to_ip": "10.10.10.10", - "to_ip_prefix": 32, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, + "from_port_ranges": [ + { + "start": 0, + "end": 65535 + } + ], "from_service": null } ] diff --git a/docs/parsers/ufw.md b/docs/parsers/ufw.md index d89f4d88..a82a4034 100644 --- a/docs/parsers/ufw.md +++ b/docs/parsers/ufw.md @@ -3,8 +3,6 @@ # jc.parsers.ufw jc - JSON CLI output utility `ufw status` command output parser -Note: a list of ports will be parsed to the `to_service` or `from_service` field as a comma-separated string. - Usage (cli): $ ufw status | jc --ufw @@ -35,17 +33,31 @@ Schema: "to_ip": string, "to_ip_prefix": integer, "to_interface": string, - "to_transport": string, # null if to_service is set and not a list of ports - "to_start_port": integer, # null if to_service is set and not a list of ports - "to_end_port": integer, # null if to_service is set and not a list of ports - "to_service": string, # null if any above are set (can also be a list of ports) + "to_transport": string, + "to_ports": [ + integer + ], + "to_port_ranges": [ + { + "start": integer, + "end": integer + } + ], + "to_service": string, # null if any to ports or port_ranges are set "from_ip": string, "from_ip_prefix": integer, "from_interface": string, - "from_transport": string, # null if to_service is set and not a list of ports - "from_start_port": integer, # null if to_service is set and not a list of ports - "from_end_port": integer, # null if to_service is set and not a list of ports - "from_service": string, # null if any above are set (can also be a list of ports) + "from_transport": string, + "from_ports": [ + integer + ], + "from_port_ranges": [ + { + "start": integer, + "end": integer + } + ], + "from_service": string, # null if any from ports or port_ranges are set "comment": string # null if no comment } ] @@ -58,7 +70,7 @@ Examples: "status": "active", "logging": "on", "logging_level": "low", - "default": "deny (incoming), allow (outgoing), deny (routed)", + "default": "deny (incoming), allow (outgoing), disabled (routed)", "new_profiles": "skip", "rules": [ { @@ -67,10 +79,11 @@ Examples: "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, + "to_transport": "any", "to_service": null, + "to_ports": [ + 22 + ], "to_ip": "0.0.0.0", "to_ip_prefix": 0, "comment": null, @@ -78,29 +91,12 @@ Examples: "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": 22, - "to_end_port": 22, - "to_service": null, - "to_ip": "::", - "to_ip_prefix": 0, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, + "from_port_ranges": [ + { + "start": 0, + "end": 65535 + } + ], "from_service": null }, { @@ -109,10 +105,12 @@ Examples: "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": null, - "to_service": "Apache Full", - "to_start_port": null, - "to_end_port": null, + "to_transport": "tcp", + "to_service": null, + "to_ports": [ + 80, + 443 + ], "to_ip": "0.0.0.0", "to_ip_prefix": 0, "comment": null, @@ -120,52 +118,15 @@ Examples: "from_ip_prefix": 0, "from_interface": "any", "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, + "from_port_ranges": [ + { + "start": 0, + "end": 65535 + } + ], "from_service": null }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": 128, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "::", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "en0", - "to_ip": "10.10.10.10", - "to_ip_prefix": 32, - "to_transport": "any", - "to_start_port": 0, - "to_end_port": 65535, - "to_service": null, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": 0, - "from_interface": "any", - "from_transport": "any", - "from_start_port": 0, - "from_end_port": 65535, - "from_service": null - } + ... ] } @@ -174,7 +135,7 @@ Examples: "status": "active", "logging": "on", "logging_level": "low", - "default": "deny (incoming), allow (outgoing), deny (routed)", + "default": "deny (incoming), allow (outgoing), disabled (routed)", "new_profiles": "skip", "rules": [ { @@ -183,10 +144,11 @@ Examples: "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": "tcp", - "to_start_port": "22", - "to_end_port": "22", + "to_transport": "any", "to_service": null, + "to_ports": [ + "22" + ], "to_ip": "0.0.0.0", "to_ip_prefix": "0", "comment": null, @@ -194,29 +156,12 @@ Examples: "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_transport": "tcp", - "to_start_port": "22", - "to_end_port": "22", - "to_service": null, - "to_ip": "::", - "to_ip_prefix": "0", - "comment": null, - "from_ip": "::", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", + "from_port_ranges": [ + { + "start": "0", + "end": "65535" + } + ], "from_service": null }, { @@ -225,10 +170,12 @@ Examples: "index": null, "network_protocol": "ipv4", "to_interface": "any", - "to_transport": null, - "to_service": "Apache Full", - "to_start_port": null, - "to_end_port": null, + "to_transport": "tcp", + "to_service": null, + "to_ports": [ + "80", + "443" + ], "to_ip": "0.0.0.0", "to_ip_prefix": "0", "comment": null, @@ -236,52 +183,15 @@ Examples: "from_ip_prefix": "0", "from_interface": "any", "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", + "from_port_ranges": [ + { + "start": "0", + "end": "65535" + } + ], "from_service": null }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv6", - "to_interface": "any", - "to_ip": "2405:204:7449:49fc:f09a:6f4a:bc93:1955", - "to_ip_prefix": "128", - "to_transport": "any", - "to_start_port": "0", - "to_end_port": "65535", - "to_service": null, - "comment": null, - "from_ip": "::", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - }, - { - "action": "ALLOW", - "action_direction": "IN", - "index": null, - "network_protocol": "ipv4", - "to_interface": "en0", - "to_ip": "10.10.10.10", - "to_ip_prefix": "32", - "to_transport": "any", - "to_start_port": "0", - "to_end_port": "65535", - "to_service": null, - "comment": null, - "from_ip": "0.0.0.0", - "from_ip_prefix": "0", - "from_interface": "any", - "from_transport": "any", - "from_start_port": "0", - "from_end_port": "65535", - "from_service": null - } + ... ] } diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 2d3ee4fd4a2ceb17b505fd814c342ed8017401d6..5dbd9eacc7efa2447e797cd52b559b38267b00eb 100644 GIT binary patch literal 2087 zcmV+?2-x=@iwFn^IEG*X|7v3{F#w%eZExE+68^4VK?Dn23Pg6(+b*!d-QnCMyYXK9 zg2?T*Xo`lGD4U5Ssw5RhhyC$4Go)WtEkgwDnOih_2XlG`S2w@-}3Mlc^Mj*|liE zDrGq@YLd4~Wrp!0VX4eSXzNlKQWAZc&gRiL3eIPf$!L1P{z7NwqnqgRhJBsQ7vtG9 z`W6IAgR+&3nW+oQpUwiby#3C+bU->UE~E3CF?~YR|K%J@!J^W_bWU2GNw7e!FfB?gjDTrasS5N2{erPa zsVc)_m4j!=-%R7GRbJ!l;{sF;*eJ6?7a;v8vigLik0>}tJ~}Ms1zQSM8E|Y_qwZ1^ z3C;oh27M^v?I62Eu6PvMie$iMCHiF=B_%hg24Em7^IRm7TQCgYAVy+Omo#hzUKIm& zJXKblZ9ni#asyH2AW$gFOjVW&&Al18HS;SO3_b*N2)EGYEEwEG0eoG|aTG!jhCD7M zgdn&>;%=+GB#8s4)M&w>9nHe=t7Jm6FJ*e9bm{QA>;^8g2bmC*sBUolV5*$JMBPy) z-4WF(rWIts(g`|xC(xvLmt8fhVvL0Yen{F?e&JDV9)9Q=gYxuE)GIR_WS_IJ!qb8Eba2 zAhshCzVh^y9htUVZ5L)K4Sk>;_8(CXKk=**FHa)l#+@ff_=1e&vRi-V9LY={3{C})1ga05tHgtW z>I19PV^vQv%~e&nITFW{(vN^2VCai4|gE~k^$X~Kdhg< z<;Q;#zR3>A3wSDW+Q*a-9 zqFBg#@TJ=L8<`{f;M=uzWH;Q!pr<}NFtUMT*|3XGs>SOk001E0T4kC zes}^el@U9@o+3)>wa7{*wq|%np}*h#a+3~!Sxi)1<;^31PYqo$b5*E#tySK1B-#kN z6T_q3T70|9!ajqcgY-uwg~eIHb4&|k*oNx@PCU~_QeJ7kVXXkQzti;xW^S+>ftjvz za@sx2FQ=czH?!&Fa=Hk{=Gp(-4mN zCrXr`u4a?V;eZ73?xn@>z(xQe35DDkyjgJF1URGE7snF0G~M6=`X@qSK9 zhpAG767#lE$g%YaR~Cq`6?B3d2~6z*?t<+l=n(K5nY6azZ>ptRg2C2d@|1*dQ^P{S zBI8OzMUaO+6N0*>+BGf-3=dobcQGhE7S<1ZQYqtEx#my^gqE@E3qu&Rb?qZH@=Xw|tu4*j zaJYg+sg^i6+(*OC@P%MD|8g__{b~`MtFop#!;a%O?A_bbUqk$(2WuOJ+>)^<46GKL Rj2Fyv{{wAa5JM&z005Ck`E&pP literal 2087 zcmV+?2-x=@iwFpEQ-ojw|7v3{F#w%eZExE+68^4VK?Dn20z`Jx+g;#-yTiFjcH_PH z1(Dlr(G(3WQ8p7vR7on14)^14W=Pqxkx0RPXgxzc^TOe9NKOWeYxWScGxq-7`?K)f z&*A%@+1cRim%(4z(I3%l$}VokOjWk5EUT={q^*yFL3GWgqsdhOl6N6PoJ^%K%&tWP zRw>JQQIot?Dl?212}@-rLR*)@kdo-jbT*I1QE)MvOh(g7_Fr^nKDv#rZrRt_d@-I) zqi;c=G$>oin3=k;{P{dU%iHhFO9!O$@+!Kx9n&X7{a?RMbOF*&BCAhH`iO#ax_=HR>)! zk>DJ_Z_tM#-VU-$$ut(jlRVDKTBL%4-D=fU7M3gGKvj-wEQFywJ5 zAq2ra68Br}B}p7WrA7-5?PwN`-y{>7eJRr;rAvp`WjAn{J<5cjM0JDXM^ohlChDFt z>7J-gF|8m2mQK*oJAo#}yClPEU$%v38)?^=RJvKe0}bX0WiO&nuUknVcgO$|-BU?Y z2TXfla^-Mx)d$obsC$69Ohl{_?`XsI2$hekFmn<>vM}qxyErFRH%t^1(|h>s24chs zi9{c?SPAXHNcOftn`whQh`}V((v1hLu)Txq}ni1vhJ+s7*`24RnaCxmgn) ziEiH!;kTS858&+hK2LtZ9e4^G5imr7AA^$vO|gV>n)0D z1+g8G@Rg^p?8vm`dc*XH6jYPP({YFO5;7qZ&fkXVQM(BZ96?TE!xHhtzQTVp7T*|t z=$3v^OJ@v;Zs;TJuz!ns_=#tgczqHXH|{(^!WU#Dm)-g^=SXJyU~npUBv5_eTqPb1 zR3BKS9;^Uy+;;~6~8SeOw6fdEe5gZA> zK1lxBV@H-@CjHU^!;tA0F>7CnPz0GC5tjvJPZmH4^amtSJ>W7Af4B<~kPPT<{9*m< zEuY3YZF-#EW*A3;?^Cy zTh4FBE&uBqwCr}mj&19qfgVLw>arbv-{d~vLSB~JP@^313 z6U9Q_gD=&_-^d)<2j8x(BfH@)20is@6FXGg16#Yuz;8G3Ij0QzJh^$jywu!*zKjl0 z@bR7UIodx|Kj*CH#O*qY%Ph5ml`%S}4`Wie54l{b(4JvDU2%vGV{wN`o4k!U06 zP7IHBYw_(a3;P0w4$>c$6c%R%&oM2GVH>UsIPpvyNqMFDhP49J{!Z5)n7P4j1ZKL< z$!Yg6znXp;-_E9!tLY;6qAKbNm{P^8!n zz|%#-YZ8OOp178H_ZzUq8;B$@1=rkRT;CO%&lCwl=I40rQcI0OmvKv`c&qFxo zpD9s(x}Ht0h657ByO$Qj0~-MdcaHlg)!OiSq zbTgXIFGq{f-Q7dn{A-C&yl!5K3ij&Y&@2+Jp~TmA4Tj;ZQDyFlWCrY`5zUT&!23BV z9i~bRO3d3vA;;DyTv;H#R?rDWtEkgwDnOih_2XlG`S2w@-}3Mlc^Mj*|liE zDrGq@YLd4~Wrp!0VX4eSXzNlKQWAZc&gRiL3eIPf$!L1P{z7NwqnqgRhJBsQ7vtG9 z`W6IAgR+&3nW+oQpUwiby#3C+bU->UE~E3CF?~YR|K%J@!J^W_bWU2GNw7e!FfB?gjDTrasS5N2{erPa zsVc)_m4j!=-%R7GRbJ!l;{sF;*eJ6?7a;v8vigLik0>}tJ~}Ms1zQSM8E|Y_qwZ1^ z3C;oh27M^v?I62Eu6PvMie$iMCHiF=B_%hg24Em7^IRm7TQCgYAVy+Omo#hzUKIm& zJXKblZ9ni#asyH2AW$gFOjVW&&Al18HS;SO3_b*N2)EGYEEwEG0eoG|aTG!jhCD7M zgdn&>;%=+GB#8s4)M&w>9nHe=t7Jm6FJ*e9bm{QA>;^8g2bmC*sBUolV5*$JMBPy) z-4WF(rWIts(g`|xC(xvLmt8fhVvL0Yen{F?e&JDV9)9Q=gYxuE)GIR_WS_IJ!qb8Eba2 zAhshCzVh^y9htUVZ5L)K4Sk>;_8(CXKk=**FHa)l#+@ff_=1e&vRi-V9LY={3{C})1ga05tHgtW z>I19PV^vQv%~e&nITFW{(vN^2VCai4|gE~k^$X~Kdhg< z<;Q;#zR3>A3wSDW+Q*a-9 zqFBg#@TJ=L8<`{f;M=uzWH;Q!pr<}NFtUMT*|3XGs>SOk001E0T4kC zes}^el@U9@o+3)>wa7{*wq|%np}*h#a+3~!Sxi)1<;^31PYqo$b5*E#tySK1B-#kN z6T_q3T70|9!ajqcgY-uwg~eIHb4&|k*oNx@PCU~_QeJ7kVXXkQzti;xW^S+>ftjvz za@sx2FQ=czH?!&Fa=Hk{=Gp(-4mN zCrXr`u4a?V;eZ73?xn@>z(xQe35DDkyjgJF1URGE7snF0G~M6=`X@qSK9 zhpAG767#lE$g%YaR~Cq`6?B3d2~6z*?t<+l=n(K5nY6azZ>ptRg2C2d@|1*dQ^P{S zBI8OzMUaO+6N0*>+BGf-3=dobcQGhE7S<1ZQYqtEx#my^gqE@E3qu&Rb?qZH@=Xw|tu4*j zaJYg+sg^i6+(*OC@P%MD|8g__{b~`MtFop#!;a%O?A_bbUqk$(2WuOJ+>)^<46GKL Rj2Fyv{{wAa5JM&z005Ck`E&pP literal 2087 zcmV+?2-x=@iwFpEQ-ojw|7v3{F#w%eZExE+68^4VK?Dn20z`Jx+g;#-yTiFjcH_PH z1(Dlr(G(3WQ8p7vR7on14)^14W=Pqxkx0RPXgxzc^TOe9NKOWeYxWScGxq-7`?K)f z&*A%@+1cRim%(4z(I3%l$}VokOjWk5EUT={q^*yFL3GWgqsdhOl6N6PoJ^%K%&tWP zRw>JQQIot?Dl?212}@-rLR*)@kdo-jbT*I1QE)MvOh(g7_Fr^nKDv#rZrRt_d@-I) zqi;c=G$>oin3=k;{P{dU%iHhFO9!O$@+!Kx9n&X7{a?RMbOF*&BCAhH`iO#ax_=HR>)! zk>DJ_Z_tM#-VU-$$ut(jlRVDKTBL%4-D=fU7M3gGKvj-wEQFywJ5 zAq2ra68Br}B}p7WrA7-5?PwN`-y{>7eJRr;rAvp`WjAn{J<5cjM0JDXM^ohlChDFt z>7J-gF|8m2mQK*oJAo#}yClPEU$%v38)?^=RJvKe0}bX0WiO&nuUknVcgO$|-BU?Y z2TXfla^-Mx)d$obsC$69Ohl{_?`XsI2$hekFmn<>vM}qxyErFRH%t^1(|h>s24chs zi9{c?SPAXHNcOftn`whQh`}V((v1hLu)Txq}ni1vhJ+s7*`24RnaCxmgn) ziEiH!;kTS858&+hK2LtZ9e4^G5imr7AA^$vO|gV>n)0D z1+g8G@Rg^p?8vm`dc*XH6jYPP({YFO5;7qZ&fkXVQM(BZ96?TE!xHhtzQTVp7T*|t z=$3v^OJ@v;Zs;TJuz!ns_=#tgczqHXH|{(^!WU#Dm)-g^=SXJyU~npUBv5_eTqPb1 zR3BKS9;^Uy+;;~6~8SeOw6fdEe5gZA> zK1lxBV@H-@CjHU^!;tA0F>7CnPz0GC5tjvJPZmH4^amtSJ>W7Af4B<~kPPT<{9*m< zEuY3YZF-#EW*A3;?^Cy zTh4FBE&uBqwCr}mj&19qfgVLw>arbv-{d~vLSB~JP@^313 z6U9Q_gD=&_-^d)<2j8x(BfH@)20is@6FXGg16#Yuz;8G3Ij0QzJh^$jywu!*zKjl0 z@bR7UIodx|Kj*CH#O*qY%Ph5ml`%S}4`Wie54l{b(4JvDU2%vGV{wN`o4k!U06 zP7IHBYw_(a3;P0w4$>c$6c%R%&oM2GVH>UsIPpvyNqMFDhP49J{!Z5)n7P4j1ZKL< z$!Yg6znXp;-_E9!tLY;6qAKbNm{P^8!n zz|%#-YZ8OOp178H_ZzUq8;B$@1=rkRT;CO%&lCwl=I40rQcI0OmvKv`c&qFxo zpD9s(x}Ht0h657ByO$Qj0~-MdcaHlg)!OiSq zbTgXIFGq{f-Q7dn{A-C&yl!5K3ij&Y&@2+Jp~TmA4Tj;ZQDyFlWCrY`5zUT&!23BV z9i~bRO3d3vA;;DyTv;H#R?rD Date: Sun, 25 Apr 2021 20:55:43 -0700 Subject: [PATCH 49/55] add caveats to man page --- jc/man/jc.1.gz | Bin 2087 -> 2413 bytes man/jc.1.gz | Bin 2087 -> 2413 bytes templates/manpage_template | 13 +++++++++++++ 3 files changed, 13 insertions(+) diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 5dbd9eacc7efa2447e797cd52b559b38267b00eb..e433338a73ba2862031a26b0d47f537f1f6054dd 100644 GIT binary patch literal 2413 zcmV-z36l07iwFpnIfh^Y|7v3{F#w%eQE%Hg5`NdOAc6%h0b;rBT^G3E_HeF~ZM>V< zM&x!|v_(Tpl+8pERg#LM#s2u68B(@vBvNn>iD#s5hQr}-h8%^9OLiBt*X+%!H?Ie; z{xx{>mc0&NzYYJ%j(&?~Q#QVuFjd*IvaGT)leRtz!swDsN7oktNPZnK#K}|&!|Yl# zV3o3*7d6RSr82{Kk+4)|Vqoi17*Y~_p3dgcBnrl}>+8|Hxqh=sQ=42mcodF8!0p^xi+#`FV||7$P}hUsf7_R4J%cFmY`km z>_Mu^uvq0_S@I9lm}-^RIQy^wl_48tR_FqxA4FE4lJpTd=g519#k^ok!72lWEo;gF~_Iig28~t zr34oQw@BP>wU;Du0F@d?aA-%f!Q@3U1G6t>dZcve@Ve{UC?W?-NMIf)HR!~^>R|70w_ zF?`W2eW#XgFeJL6_q4-)7xnNX&nof!Br`mw52lB)bTAd`F0vkjw~< zgkK*df9@GamV-?Cr3Ho|(=TGyJ{6$|GCd+L3d)`+fE4HpBvC!!G9UbK2O=OD(B1gM z{Mnm6jWgQx7`=^x{tz&=iLEP>j_ie7k+&oq_d=mTcDFA_OFQUK2`vrgDGf%&_rkth zNtHgOr7EPQy8R+WvPe}+3$oo}R^~2}hLzF7r7VW{q+bS4W{t;NJj2DUdQ7#N!=;E@ zS9G_W-;7)S=ND+%?SviM) zbe)sY?qYs1{W!UqO|LJei{P`Ws4HMf5zDk@aRuj8JSJyK8}=YMH3LBBZ{zRd+12bO zLZ`shMZ#?ooxvWsmU#9H+2VyrX8Ap}V=C?9jTuNG8gfzsTUujJ;{lIt2HP_@e5$fc zZSc99$ypF=2l?ec_oBwd`c5|g_Z0b!(#e)Ds(c9x+OTc}&j!ICYoSFmU#`U&PGOlr zpn&7~Ie~UtyRuY+UnVr-9d75iM71yEm45)Edz}*c;b9 zIvCxn+S%Zq99ZHWw(Z%hrFAk8=fEc-+4r$!x&JqxU*EI&C({wa~@&FZ*vqWkrlW=W2@-rN;D_K;J zLn!l)6evGk&aN+pAqnEyON-&b7y$_7Jf1}@{FPj4uIu4wSAAII+AmLu{~-%F(;27W zYBnBSjpp<7(PH%V>s{RZwM58YS5J8bdv#DWi-c=P@wHvUz;M^7GIvEXA^TuNv*YjZ zd`?P-sZwEyaoZ^5*!qMc3;5Rxs^CTfQ#*${XL|`M0)8Wt)|UTGwRB4mZVe_&NeDMJ zEF>&4t|Vjxd1x~ss9UOCC7mte4Khhoxeogxkb$EPmWr~Y*Qp1tGX;PdV4h|;c?^+7)R zcrjW;n8(Q+afY74y|@%GE2s%zhH;zGx%6r@eUBK5Lh($>rH=EMn$3IrT1a#swv<7m z#T@I5N52*APB2`k3IY27gOK5nzl?FR!nOBzZ9wengEsMq;f(rx%4nPA`^>s3u(UNJ zm`1yk^@EU3c)Wl^(VwaihWrs>ne~yx*8Bm?w51#8bH7o8CF?-2&doz&Bg`u_sYgDV$)PUGHJ0fPLT%DD-bOopadSv5dJSYw%5J; zTvD;#`sUk!JMr%}MQd+uU`+4~$YUpc0>R5ZEXF$xzKNd*Jj1)>hH9*Mw2k)W6z3-C zz9;PFw~<+f8nznw1``7ckSCv-u%8UnR&or?RD`P#f#htDK4DYE6a`eH+$Wvp;{ctf z+<04qjQ?P8@o98Dzq*Kms7XdT#-cEgr`Yvm!94djN9Ga2ARGVybDF0K literal 2087 zcmV+?2-x=@iwFn^IEG*X|7v3{F#w%eZExE+68^4VK?Dn23Pg6(+b*!d-QnCMyYXK9 zg2?T*Xo`lGD4U5Ssw5RhhyC$4Go)WtEkgwDnOih_2XlG`S2w@-}3Mlc^Mj*|liE zDrGq@YLd4~Wrp!0VX4eSXzNlKQWAZc&gRiL3eIPf$!L1P{z7NwqnqgRhJBsQ7vtG9 z`W6IAgR+&3nW+oQpUwiby#3C+bU->UE~E3CF?~YR|K%J@!J^W_bWU2GNw7e!FfB?gjDTrasS5N2{erPa zsVc)_m4j!=-%R7GRbJ!l;{sF;*eJ6?7a;v8vigLik0>}tJ~}Ms1zQSM8E|Y_qwZ1^ z3C;oh27M^v?I62Eu6PvMie$iMCHiF=B_%hg24Em7^IRm7TQCgYAVy+Omo#hzUKIm& zJXKblZ9ni#asyH2AW$gFOjVW&&Al18HS;SO3_b*N2)EGYEEwEG0eoG|aTG!jhCD7M zgdn&>;%=+GB#8s4)M&w>9nHe=t7Jm6FJ*e9bm{QA>;^8g2bmC*sBUolV5*$JMBPy) z-4WF(rWIts(g`|xC(xvLmt8fhVvL0Yen{F?e&JDV9)9Q=gYxuE)GIR_WS_IJ!qb8Eba2 zAhshCzVh^y9htUVZ5L)K4Sk>;_8(CXKk=**FHa)l#+@ff_=1e&vRi-V9LY={3{C})1ga05tHgtW z>I19PV^vQv%~e&nITFW{(vN^2VCai4|gE~k^$X~Kdhg< z<;Q;#zR3>A3wSDW+Q*a-9 zqFBg#@TJ=L8<`{f;M=uzWH;Q!pr<}NFtUMT*|3XGs>SOk001E0T4kC zes}^el@U9@o+3)>wa7{*wq|%np}*h#a+3~!Sxi)1<;^31PYqo$b5*E#tySK1B-#kN z6T_q3T70|9!ajqcgY-uwg~eIHb4&|k*oNx@PCU~_QeJ7kVXXkQzti;xW^S+>ftjvz za@sx2FQ=czH?!&Fa=Hk{=Gp(-4mN zCrXr`u4a?V;eZ73?xn@>z(xQe35DDkyjgJF1URGE7snF0G~M6=`X@qSK9 zhpAG767#lE$g%YaR~Cq`6?B3d2~6z*?t<+l=n(K5nY6azZ>ptRg2C2d@|1*dQ^P{S zBI8OzMUaO+6N0*>+BGf-3=dobcQGhE7S<1ZQYqtEx#my^gqE@E3qu&Rb?qZH@=Xw|tu4*j zaJYg+sg^i6+(*OC@P%MD|8g__{b~`MtFop#!;a%O?A_bbUqk$(2WuOJ+>)^<46GKL Rj2Fyv{{wAa5JM&z005Ck`E&pP diff --git a/man/jc.1.gz b/man/jc.1.gz index 5dbd9eacc7efa2447e797cd52b559b38267b00eb..e433338a73ba2862031a26b0d47f537f1f6054dd 100644 GIT binary patch literal 2413 zcmV-z36l07iwFpnIfh^Y|7v3{F#w%eQE%Hg5`NdOAc6%h0b;rBT^G3E_HeF~ZM>V< zM&x!|v_(Tpl+8pERg#LM#s2u68B(@vBvNn>iD#s5hQr}-h8%^9OLiBt*X+%!H?Ie; z{xx{>mc0&NzYYJ%j(&?~Q#QVuFjd*IvaGT)leRtz!swDsN7oktNPZnK#K}|&!|Yl# zV3o3*7d6RSr82{Kk+4)|Vqoi17*Y~_p3dgcBnrl}>+8|Hxqh=sQ=42mcodF8!0p^xi+#`FV||7$P}hUsf7_R4J%cFmY`km z>_Mu^uvq0_S@I9lm}-^RIQy^wl_48tR_FqxA4FE4lJpTd=g519#k^ok!72lWEo;gF~_Iig28~t zr34oQw@BP>wU;Du0F@d?aA-%f!Q@3U1G6t>dZcve@Ve{UC?W?-NMIf)HR!~^>R|70w_ zF?`W2eW#XgFeJL6_q4-)7xnNX&nof!Br`mw52lB)bTAd`F0vkjw~< zgkK*df9@GamV-?Cr3Ho|(=TGyJ{6$|GCd+L3d)`+fE4HpBvC!!G9UbK2O=OD(B1gM z{Mnm6jWgQx7`=^x{tz&=iLEP>j_ie7k+&oq_d=mTcDFA_OFQUK2`vrgDGf%&_rkth zNtHgOr7EPQy8R+WvPe}+3$oo}R^~2}hLzF7r7VW{q+bS4W{t;NJj2DUdQ7#N!=;E@ zS9G_W-;7)S=ND+%?SviM) zbe)sY?qYs1{W!UqO|LJei{P`Ws4HMf5zDk@aRuj8JSJyK8}=YMH3LBBZ{zRd+12bO zLZ`shMZ#?ooxvWsmU#9H+2VyrX8Ap}V=C?9jTuNG8gfzsTUujJ;{lIt2HP_@e5$fc zZSc99$ypF=2l?ec_oBwd`c5|g_Z0b!(#e)Ds(c9x+OTc}&j!ICYoSFmU#`U&PGOlr zpn&7~Ie~UtyRuY+UnVr-9d75iM71yEm45)Edz}*c;b9 zIvCxn+S%Zq99ZHWw(Z%hrFAk8=fEc-+4r$!x&JqxU*EI&C({wa~@&FZ*vqWkrlW=W2@-rN;D_K;J zLn!l)6evGk&aN+pAqnEyON-&b7y$_7Jf1}@{FPj4uIu4wSAAII+AmLu{~-%F(;27W zYBnBSjpp<7(PH%V>s{RZwM58YS5J8bdv#DWi-c=P@wHvUz;M^7GIvEXA^TuNv*YjZ zd`?P-sZwEyaoZ^5*!qMc3;5Rxs^CTfQ#*${XL|`M0)8Wt)|UTGwRB4mZVe_&NeDMJ zEF>&4t|Vjxd1x~ss9UOCC7mte4Khhoxeogxkb$EPmWr~Y*Qp1tGX;PdV4h|;c?^+7)R zcrjW;n8(Q+afY74y|@%GE2s%zhH;zGx%6r@eUBK5Lh($>rH=EMn$3IrT1a#swv<7m z#T@I5N52*APB2`k3IY27gOK5nzl?FR!nOBzZ9wengEsMq;f(rx%4nPA`^>s3u(UNJ zm`1yk^@EU3c)Wl^(VwaihWrs>ne~yx*8Bm?w51#8bH7o8CF?-2&doz&Bg`u_sYgDV$)PUGHJ0fPLT%DD-bOopadSv5dJSYw%5J; zTvD;#`sUk!JMr%}MQd+uU`+4~$YUpc0>R5ZEXF$xzKNd*Jj1)>hH9*Mw2k)W6z3-C zz9;PFw~<+f8nznw1``7ckSCv-u%8UnR&or?RD`P#f#htDK4DYE6a`eH+$Wvp;{ctf z+<04qjQ?P8@o98Dzq*Kms7XdT#-cEgr`Yvm!94djN9Ga2ARGVybDF0K literal 2087 zcmV+?2-x=@iwFn^IEG*X|7v3{F#w%eZExE+68^4VK?Dn23Pg6(+b*!d-QnCMyYXK9 zg2?T*Xo`lGD4U5Ssw5RhhyC$4Go)WtEkgwDnOih_2XlG`S2w@-}3Mlc^Mj*|liE zDrGq@YLd4~Wrp!0VX4eSXzNlKQWAZc&gRiL3eIPf$!L1P{z7NwqnqgRhJBsQ7vtG9 z`W6IAgR+&3nW+oQpUwiby#3C+bU->UE~E3CF?~YR|K%J@!J^W_bWU2GNw7e!FfB?gjDTrasS5N2{erPa zsVc)_m4j!=-%R7GRbJ!l;{sF;*eJ6?7a;v8vigLik0>}tJ~}Ms1zQSM8E|Y_qwZ1^ z3C;oh27M^v?I62Eu6PvMie$iMCHiF=B_%hg24Em7^IRm7TQCgYAVy+Omo#hzUKIm& zJXKblZ9ni#asyH2AW$gFOjVW&&Al18HS;SO3_b*N2)EGYEEwEG0eoG|aTG!jhCD7M zgdn&>;%=+GB#8s4)M&w>9nHe=t7Jm6FJ*e9bm{QA>;^8g2bmC*sBUolV5*$JMBPy) z-4WF(rWIts(g`|xC(xvLmt8fhVvL0Yen{F?e&JDV9)9Q=gYxuE)GIR_WS_IJ!qb8Eba2 zAhshCzVh^y9htUVZ5L)K4Sk>;_8(CXKk=**FHa)l#+@ff_=1e&vRi-V9LY={3{C})1ga05tHgtW z>I19PV^vQv%~e&nITFW{(vN^2VCai4|gE~k^$X~Kdhg< z<;Q;#zR3>A3wSDW+Q*a-9 zqFBg#@TJ=L8<`{f;M=uzWH;Q!pr<}NFtUMT*|3XGs>SOk001E0T4kC zes}^el@U9@o+3)>wa7{*wq|%np}*h#a+3~!Sxi)1<;^31PYqo$b5*E#tySK1B-#kN z6T_q3T70|9!ajqcgY-uwg~eIHb4&|k*oNx@PCU~_QeJ7kVXXkQzti;xW^S+>ftjvz za@sx2FQ=czH?!&Fa=Hk{=Gp(-4mN zCrXr`u4a?V;eZ73?xn@>z(xQe35DDkyjgJF1URGE7snF0G~M6=`X@qSK9 zhpAG767#lE$g%YaR~Cq`6?B3d2~6z*?t<+l=n(K5nY6azZ>ptRg2C2d@|1*dQ^P{S zBI8OzMUaO+6N0*>+BGf-3=dobcQGhE7S<1ZQYqtEx#my^gqE@E3qu&Rb?qZH@=Xw|tu4*j zaJYg+sg^i6+(*OC@P%MD|8g__{b~`MtFop#!;a%O?A_bbUqk$(2WuOJ+>)^<46GKL Rj2Fyv{{wAa5JM&z005Ck`E&pP diff --git a/templates/manpage_template b/templates/manpage_template index f7f99106..e8852f5c 100644 --- a/templates/manpage_template +++ b/templates/manpage_template @@ -96,6 +96,19 @@ Local plugin filenames must be valid python module names, therefore must consist Note: The application data directory follows the XDG Base Directory Specification +.SH CAVEATS +\fBLocale:\fP For best results set the \fBLANG\fP locale environment variable to \fBC\fP. For example, either by setting directly on the command-line: + +\fB$ LANG=C date | jc --date\fP + +or by exporting to the environment before running commands: + +\fB$ export LANG=C\fP + +\fBTimezones:\fP Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a \fB_utc\fP suffix it is considered naive. (i.e. based on the local timezone of the system the \fBjc\fP parser was run on). + +If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a \fB_utc\fP suffix on the key name. (e.g. \fBepoch_utc\fP) No other timezones are supported for aware timestamps. + .SH EXAMPLES Standard Syntax: .RS From eca785450d1c72687817d09259fa7cd33376fafc Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sun, 25 Apr 2021 21:06:47 -0700 Subject: [PATCH 50/55] add caveats to readme and manpage --- CHANGELOG | 3 ++- README.md | 22 ++++++++++++++++------ jc/man/jc.1.gz | Bin 2413 -> 2413 bytes man/jc.1.gz | Bin 2413 -> 2413 bytes templates/readme_template | 22 ++++++++++++++++------ 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6b2d1df5..09a34a70 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,10 @@ jc changelog -20210420 v1.15.3 +20210425 v1.15.3 - Add ufw status command parser tested on linux - Add ufw-appinfo command parser tested on linux - Fix deb package name to conform to standard +- Add Caveats section to readme and manpage 20210418 v1.15.2 - Add systeminfo parser tested on Windows diff --git a/README.md b/README.md index 774d5c4b..7971f582 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,6 @@ The `jc` parsers can also be used as python modules. In this case the output wil ``` Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of `None` are converted to JSON `null`, known boolean values are converted, and, in some cases, additional semantic context fields are added. -> Note: Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on). -> -> If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a `_utc` suffix on the key name. (e.g. `epoch_utc`) No other timezones are supported for aware timestamps. - To access the raw, pre-processed JSON, use the `-r` cli option or the `raw=True` function parameter in `parse()`. Schemas for each parser can be found at the documentation link beside each parser below. @@ -115,8 +111,6 @@ jc [OPTIONS] COMMAND ``` The JSON output can be compact (default) or pretty formatted with the `-p` option. -> Note: For best results set the `LANG` locale environment variable to `C`. For example, either by setting directly on the command-line: `$ LANG=C date | jc --date`, or by exporting to the environment before running commands: `$ export LANG=C`. - ### Parsers - `--acpi` enables the `acpi` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/acpi)) @@ -232,6 +226,22 @@ Local plugin filenames must be valid python module names, therefore must consist > Note: The application data directory follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) +### Caveats +**Locale:** +For best results set the `LANG` locale environment variable to `C`. For example, either by setting directly on the command-line: +``` +$ LANG=C date | jc --date +``` +or by exporting to the environment before running commands: +``` +$ export LANG=C +``` + +**Timezones:** +Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on). + +If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a `_utc`P suffix on the key name. (e.g. `epoch_utc`) No other timezones are supported for aware timestamps. + ## Compatibility Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`. diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index e433338a73ba2862031a26b0d47f537f1f6054dd..e7649408db411859f37259693ce70d782a3e3447 100644 GIT binary patch delta 15 WcmaDW^j3&XzMF$X)@CDHIwt@qDFiIAd^ diff --git a/man/jc.1.gz b/man/jc.1.gz index e433338a73ba2862031a26b0d47f537f1f6054dd..e7649408db411859f37259693ce70d782a3e3447 100644 GIT binary patch delta 15 WcmaDW^j3&XzMF$X)@CDHIwt@qDFiIAd^ diff --git a/templates/readme_template b/templates/readme_template index da61517a..8b94df63 100644 --- a/templates/readme_template +++ b/templates/readme_template @@ -62,10 +62,6 @@ The `jc` parsers can also be used as python modules. In this case the output wil ``` Two representations of the data are possible. The default representation uses a strict schema per parser and converts known numbers to int/float JSON values. Certain known values of `None` are converted to JSON `null`, known boolean values are converted, and, in some cases, additional semantic context fields are added. -> Note: Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on). -> -> If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a `_utc` suffix on the key name. (e.g. `epoch_utc`) No other timezones are supported for aware timestamps. - To access the raw, pre-processed JSON, use the `-r` cli option or the `raw=True` function parameter in `parse()`. Schemas for each parser can be found at the documentation link beside each parser below. @@ -115,8 +111,6 @@ jc [OPTIONS] COMMAND ``` The JSON output can be compact (default) or pretty formatted with the `-p` option. -> Note: For best results set the `LANG` locale environment variable to `C`. For example, either by setting directly on the command-line: `$ LANG=C date | jc --date`, or by exporting to the environment before running commands: `$ export LANG=C`. - ### Parsers {% for parser in jc.parsers %} - `{{ parser.argument }}` enables the {{ parser.description }} ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/{{ parser.name }})){% endfor %} @@ -160,6 +154,22 @@ Local plugin filenames must be valid python module names, therefore must consist > Note: The application data directory follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) +### Caveats +**Locale:** +For best results set the `LANG` locale environment variable to `C`. For example, either by setting directly on the command-line: +``` +$ LANG=C date | jc --date +``` +or by exporting to the environment before running commands: +``` +$ export LANG=C +``` + +**Timezones:** +Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on). + +If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a `_utc`P suffix on the key name. (e.g. `epoch_utc`) No other timezones are supported for aware timestamps. + ## Compatibility Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`. From 8d2d3db3fa969456342181a226bf54a3f1613542 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Sun, 25 Apr 2021 21:10:21 -0700 Subject: [PATCH 51/55] formatting --- README.md | 2 ++ jc/man/jc.1.gz | Bin 2413 -> 2413 bytes man/jc.1.gz | Bin 2413 -> 2413 bytes templates/readme_template | 2 ++ 4 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 7971f582..b6d29d9c 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,7 @@ Local plugin filenames must be valid python module names, therefore must consist ### Caveats **Locale:** + For best results set the `LANG` locale environment variable to `C`. For example, either by setting directly on the command-line: ``` $ LANG=C date | jc --date @@ -238,6 +239,7 @@ $ export LANG=C ``` **Timezones:** + Some parsers have calculated epoch timestamp fields added to the output. Unless a timestamp field name has a `_utc` suffix it is considered naive. (i.e. based on the local timezone of the system the `jc` parser was run on). If a UTC timezone can be detected in the text of the command output, the timestamp will be timezone aware and have a `_utc`P suffix on the key name. (e.g. `epoch_utc`) No other timezones are supported for aware timestamps. diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index e7649408db411859f37259693ce70d782a3e3447..8efe4136176e4f52c0aa3195d5fcb40f4f6f0399 100644 GIT binary patch delta 15 WcmaDW^j3&XzMF%C({>|UIwt@pwgfBy delta 15 WcmaDW^j3&XzMF$X)@CDHIwt@qDFi|UIwt@pwgfBy delta 15 WcmaDW^j3&XzMF$X)@CDHIwt@qDFi Date: Mon, 26 Apr 2021 10:00:44 -0700 Subject: [PATCH 52/55] change schema to a list of dictionaries to support `ufw app info all` use case --- EXAMPLES.md | 68 ++-- jc/parsers/ufw_appinfo.py | 331 +++++++++--------- tests/fixtures/generic/ufw-appinfo-msn.json | 2 +- tests/fixtures/generic/ufw-appinfo-test.json | 2 +- tests/fixtures/generic/ufw-appinfo-test2.json | 2 +- tests/fixtures/generic/ufw-appinfo-test3.json | 2 +- .../ubuntu-18.04/ufw-appinfo-all.json | 1 + .../fixtures/ubuntu-18.04/ufw-appinfo-all.out | 51 +++ tests/test_ufw_appinfo.py | 14 +- 9 files changed, 278 insertions(+), 195 deletions(-) create mode 100644 tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json create mode 100644 tests/fixtures/ubuntu-18.04/ufw-appinfo-all.out diff --git a/EXAMPLES.md b/EXAMPLES.md index c221cbf9..25279f31 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -3199,39 +3199,41 @@ ufw status verbose | jc --ufw -p # or jc -p ufw status verbose ufw app info MSN | jc --ufw-appinfo -p # or: jc -p ufw app info MSN ``` ```json -{ - "profile": "MSN", - "title": "MSN Chat", - "description": "MSN chat protocol (with file transfer and voice)", - "tcp_list": [ - 1863, - 6901 - ], - "udp_list": [ - 1863, - 6901 - ], - "tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_tcp_list": [ - 1863, - 6901 - ], - "normalized_tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_udp_list": [ - 1863, - 6901 - ] -} +[ + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] + } +] ``` ### uname -a ```bash diff --git a/jc/parsers/ufw_appinfo.py b/jc/parsers/ufw_appinfo.py index 57396f2c..ecde58c1 100644 --- a/jc/parsers/ufw_appinfo.py +++ b/jc/parsers/ufw_appinfo.py @@ -1,5 +1,7 @@ """jc - JSON CLI output utility `ufw app info [application]` command output parser +Supports individual apps via `ufw app info [application]` and all apps list via `ufw app info all`. + Because `ufw` application definitions allow overlapping ports and port ranges, this parser preserves that behavior, but also provides `normalized` lists and ranges that remove duplicate ports and merge overlapping ranges. Usage (cli): @@ -17,105 +19,111 @@ Usage (module): Schema: - { - "profile": string, - "title": string, - "description": string, - "tcp_list": [ - integer - ], - "tcp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ], - "udp_list": [ - integer - ], - "udp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ], - "normalized_tcp_list": [ - integers # duplicates and overlapping are removed - ], - "normalized_tcp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integers # overlapping are merged - } - ], - "normalized_udp_list": [ - integers # duplicates and overlapping are removed - ], - "normalized_udp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integers # overlapping are merged - } - ] - } + [ + { + "profile": string, + "title": string, + "description": string, + "tcp_list": [ + integer + ], + "tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "udp_list": [ + integer + ], + "udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "normalized_tcp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ], + "normalized_udp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ] + } + ] Examples: $ ufw app info MSN | jc --ufw-appinfo -p - { - "profile": "MSN", - "title": "MSN Chat", - "description": "MSN chat protocol (with file transfer and voice)", - "tcp_list": [ - 1863, - 6901 - ], - "udp_list": [ - 1863, - 6901 - ], - "tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_tcp_list": [ - 1863, - 6901 - ], - "normalized_tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_udp_list": [ - 1863, - 6901 - ] - } + [ + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] + } + ] $ ufw app info MSN | jc --ufw-appinfo -p -r - { - "profile": "MSN", - "title": "MSN Chat", - "description": "MSN chat protocol (with file transfer and voice)", - "tcp_list": [ - "1863", - "6901" - ], - "udp_list": [ - "1863", - "6901" - ], - "tcp_ranges": [ - { - "start": "6891", - "end": "6900" - } - ] - } + [ + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + "1863", + "6901" + ], + "udp_list": [ + "1863", + "6901" + ], + "tcp_ranges": [ + { + "start": "6891", + "end": "6900" + } + ] + } + ] """ import jc.utils @@ -143,56 +151,57 @@ def _process(proc_data): Returns: - Dictionary. Structured to conform to the schema. + List of Dictionaries. Structured to conform to the schema. """ - # convert to ints - int_list = ['start', 'end'] + for profile in proc_data: + # convert to ints + int_list = ['start', 'end'] - if 'tcp_list' in proc_data: - proc_data['tcp_list'] = [int(p) for p in proc_data['tcp_list']] + if 'tcp_list' in profile: + profile['tcp_list'] = [int(p) for p in profile['tcp_list']] - if 'udp_list' in proc_data: - proc_data['udp_list'] = [int(p) for p in proc_data['udp_list']] + if 'udp_list' in profile: + profile['udp_list'] = [int(p) for p in profile['udp_list']] - for protocol in ['tcp', 'udp']: - if protocol + '_ranges' in proc_data: - for i, item in enumerate(proc_data[protocol + '_ranges']): - for key in item: - if key in int_list: - proc_data[protocol + '_ranges'][i][key] = int(proc_data[protocol + '_ranges'][i][key]) + for protocol in ['tcp', 'udp']: + if protocol + '_ranges' in profile: + for i, item in enumerate(profile[protocol + '_ranges']): + for key in item: + if key in int_list: + profile[protocol + '_ranges'][i][key] = int(profile[protocol + '_ranges'][i][key]) - # create normalized port lists and port ranges (remove duplicates and merge ranges) - # dump ranges into a set of 0 - 65535 - # if items in the port list are in the set, then remove them - # iterate through the set to find gaps and create new ranges based on them - for protocol in ['tcp', 'udp']: - port_set = set() - if protocol + '_ranges' in proc_data: - for item in proc_data[protocol + '_ranges']: - port_set.update(range(item['start'], item['end'] + 1)) + # create normalized port lists and port ranges (remove duplicates and merge ranges) + # dump ranges into a set of 0 - 65535 + # if items in the port list are in the set, then remove them + # iterate through the set to find gaps and create new ranges based on them + for protocol in ['tcp', 'udp']: + port_set = set() + if protocol + '_ranges' in profile: + for item in profile[protocol + '_ranges']: + port_set.update(range(item['start'], item['end'] + 1)) - if protocol + '_list' in proc_data: - new_port_list = sorted(set([p for p in proc_data[protocol + '_list'] if p not in port_set])) - if new_port_list: - proc_data['normalized_' + protocol + '_list'] = new_port_list + if protocol + '_list' in profile: + new_port_list = sorted(set([p for p in profile[protocol + '_list'] if p not in port_set])) + if new_port_list: + profile['normalized_' + protocol + '_list'] = new_port_list - new_port_ranges = [] - state = 'findstart' # 'findstart' or 'findend' - for port in range(0, 65535 + 2): - if state == 'findstart': - port_range_obj = {} - if port in port_set: - port_range_obj['start'] = port - state = 'findend' - continue - if state == 'findend': - if port not in port_set: - port_range_obj['end'] = port - 1 - new_port_ranges.append(port_range_obj) - state = 'findstart' + new_port_ranges = [] + state = 'findstart' # 'findstart' or 'findend' + for port in range(0, 65535 + 2): + if state == 'findstart': + port_range_obj = {} + if port in port_set: + port_range_obj['start'] = port + state = 'findend' + continue + if state == 'findend': + if port not in port_set: + port_range_obj['end'] = port - 1 + new_port_ranges.append(port_range_obj) + state = 'findstart' - if new_port_ranges: - proc_data['normalized_' + protocol + '_ranges'] = new_port_ranges + if new_port_ranges: + profile['normalized_' + protocol + '_ranges'] = new_port_ranges return proc_data @@ -254,12 +263,13 @@ def parse(data, raw=False, quiet=False): Returns: - Dictionary. Raw or processed structured data. + List of Dictionaries. Raw or processed structured data. """ if not quiet: jc.utils.compatibility(__name__, info.compatible) - raw_output = {} + raw_output = [] + item_obj = {} if jc.utils.has_data(data): @@ -267,16 +277,22 @@ def parse(data, raw=False, quiet=False): for line in filter(None, data.splitlines()): + if line.startswith('--'): + if item_obj: + raw_output.append(item_obj) + item_obj = {} + continue + if line.startswith('Profile:'): - raw_output['profile'] = line.split(': ')[1] + item_obj['profile'] = line.split(': ')[1] continue if line.startswith('Title:'): - raw_output['title'] = line.split(': ')[1] + item_obj['title'] = line.split(': ')[1] continue if line.startswith('Description:'): - raw_output['description'] = line.split(': ')[1] + item_obj['description'] = line.split(': ')[1] continue if line.startswith('Port'): @@ -289,20 +305,20 @@ def parse(data, raw=False, quiet=False): if line_list[1] == 'tcp': tcp_prot_list = _parse_port_list(line_list[0]) if tcp_prot_list: - raw_output['tcp_list'] = tcp_prot_list + item_obj['tcp_list'] = tcp_prot_list tcp_prot_range = _parse_port_range(line_list[0]) if tcp_prot_range: - raw_output['tcp_ranges'] = tcp_prot_range + item_obj['tcp_ranges'] = tcp_prot_range elif line_list[1] == 'udp': udp_prot_list = _parse_port_list(line_list[0]) if udp_prot_list: - raw_output['udp_list'] = udp_prot_list + item_obj['udp_list'] = udp_prot_list udp_prot_range = _parse_port_range(line_list[0]) if udp_prot_range: - raw_output['udp_ranges'] = udp_prot_range + item_obj['udp_ranges'] = udp_prot_range # 'any' case else: @@ -311,35 +327,36 @@ def parse(data, raw=False, quiet=False): u_list = [] u_range = [] - if 'tcp_list' in raw_output: - t_list = raw_output['tcp_list'] + if 'tcp_list' in item_obj: + t_list = item_obj['tcp_list'] - if 'tcp_ranges' in raw_output: - t_range = raw_output['tcp_ranges'] + if 'tcp_ranges' in item_obj: + t_range = item_obj['tcp_ranges'] - if 'udp_list' in raw_output: - u_list = raw_output['udp_list'] + if 'udp_list' in item_obj: + u_list = item_obj['udp_list'] - if 'udp_ranges' in raw_output: - u_range = raw_output['udp_ranges'] + if 'udp_ranges' in item_obj: + u_range = item_obj['udp_ranges'] t_p_list = _parse_port_list(line, t_list) if t_p_list: - raw_output['tcp_list'] = t_p_list + item_obj['tcp_list'] = t_p_list t_r_list = _parse_port_range(line, t_range) if t_r_list: - raw_output['tcp_ranges'] = t_r_list + item_obj['tcp_ranges'] = t_r_list u_p_list = _parse_port_list(line, u_list) if u_p_list: - raw_output['udp_list'] = u_p_list + item_obj['udp_list'] = u_p_list u_r_list = _parse_port_range(line, u_range) if u_r_list: - raw_output['udp_ranges'] = u_r_list + item_obj['udp_ranges'] = u_r_list - raw_output.update(raw_output) + if item_obj: + raw_output.append(item_obj) if raw: return raw_output diff --git a/tests/fixtures/generic/ufw-appinfo-msn.json b/tests/fixtures/generic/ufw-appinfo-msn.json index 3532d142..36a1bb72 100644 --- a/tests/fixtures/generic/ufw-appinfo-msn.json +++ b/tests/fixtures/generic/ufw-appinfo-msn.json @@ -1 +1 @@ -{"profile":"MSN","title":"MSN Chat","description":"MSN chat protocol (with file transfer and voice)","tcp_list":[1863,6901],"udp_list":[1863,6901],"tcp_ranges":[{"start":6891,"end":6900}],"normalized_tcp_list":[1863,6901],"normalized_tcp_ranges":[{"start":6891,"end":6900}],"normalized_udp_list":[1863,6901]} +[{"profile":"MSN","title":"MSN Chat","description":"MSN chat protocol (with file transfer and voice)","tcp_list":[1863,6901],"udp_list":[1863,6901],"tcp_ranges":[{"start":6891,"end":6900}],"normalized_tcp_list":[1863,6901],"normalized_tcp_ranges":[{"start":6891,"end":6900}],"normalized_udp_list":[1863,6901]}] diff --git a/tests/fixtures/generic/ufw-appinfo-test.json b/tests/fixtures/generic/ufw-appinfo-test.json index 64eb243e..c3e6e6b5 100644 --- a/tests/fixtures/generic/ufw-appinfo-test.json +++ b/tests/fixtures/generic/ufw-appinfo-test.json @@ -1 +1 @@ -{"profile":"TEST","title":"My test app","description":"a longer description of the test app here.","tcp_list":[1,2,3,4,5,6,7,8,9,10,9,8,7,30,53],"tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"udp_ranges":[{"start":50,"end":51},{"start":40,"end":60}],"udp_list":[53],"normalized_tcp_list":[1,2,3,4,5,6,7,8,9,10,30,53],"normalized_tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"normalized_udp_ranges":[{"start":40,"end":60}]} +[{"profile":"TEST","title":"My test app","description":"a longer description of the test app here.","tcp_list":[1,2,3,4,5,6,7,8,9,10,9,8,7,30,53],"tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"udp_ranges":[{"start":50,"end":51},{"start":40,"end":60}],"udp_list":[53],"normalized_tcp_list":[1,2,3,4,5,6,7,8,9,10,30,53],"normalized_tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"normalized_udp_ranges":[{"start":40,"end":60}]}] diff --git a/tests/fixtures/generic/ufw-appinfo-test2.json b/tests/fixtures/generic/ufw-appinfo-test2.json index b48fb46a..25d964d7 100644 --- a/tests/fixtures/generic/ufw-appinfo-test2.json +++ b/tests/fixtures/generic/ufw-appinfo-test2.json @@ -1 +1 @@ -{"profile":"TEST2","title":"My test app2","description":"a longer description of the test app here.","tcp_ranges":[{"start":0,"end":65535}],"udp_ranges":[{"start":50,"end":51}],"tcp_list":[53],"udp_list":[53],"normalized_tcp_ranges":[{"start":0,"end":65535}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]} +[{"profile":"TEST2","title":"My test app2","description":"a longer description of the test app here.","tcp_ranges":[{"start":0,"end":65535}],"udp_ranges":[{"start":50,"end":51}],"tcp_list":[53],"udp_list":[53],"normalized_tcp_ranges":[{"start":0,"end":65535}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]}] diff --git a/tests/fixtures/generic/ufw-appinfo-test3.json b/tests/fixtures/generic/ufw-appinfo-test3.json index 20eb606c..54a91e4c 100644 --- a/tests/fixtures/generic/ufw-appinfo-test3.json +++ b/tests/fixtures/generic/ufw-appinfo-test3.json @@ -1 +1 @@ -{"profile":"TEST3","title":"My test app3","description":"test overlapping ports","tcp_list":[80,83,80,53],"tcp_ranges":[{"start":70,"end":90}],"udp_ranges":[{"start":50,"end":51}],"udp_list":[53],"normalized_tcp_list":[53],"normalized_tcp_ranges":[{"start":70,"end":90}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]} +[{"profile":"TEST3","title":"My test app3","description":"test overlapping ports","tcp_list":[80,83,80,53],"tcp_ranges":[{"start":70,"end":90}],"udp_ranges":[{"start":50,"end":51}],"udp_list":[53],"normalized_tcp_list":[53],"normalized_tcp_ranges":[{"start":70,"end":90}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]}] diff --git a/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json b/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json new file mode 100644 index 00000000..cbdcec44 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json @@ -0,0 +1 @@ +[{"profile":"MSN","title":"MSN Chat","description":"MSN chat protocol (with file transfer and voice)","tcp_list":[1863,6901],"udp_list":[1863,6901],"tcp_ranges":[{"start":6891,"end":6900}],"normalized_tcp_list":[1863,6901],"normalized_tcp_ranges":[{"start":6891,"end":6900}],"normalized_udp_list":[1863,6901]},{"profile":"OpenSSH","title":"Secure shell server, an rshd replacement","description":"OpenSSH is a free implementation of the Secure Shell protocol.","tcp_list":[22],"normalized_tcp_list":[22]},{"profile":"TEST","title":"My test app","description":"a longer description of the test app here.","tcp_list":[1,2,3,4,5,6,7,8,9,10,30,53],"tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"udp_ranges":[{"start":50,"end":51}],"udp_list":[53],"normalized_tcp_list":[1,2,3,4,5,6,7,8,9,10,30,53],"normalized_tcp_ranges":[{"start":80,"end":90},{"start":8080,"end":8090}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]},{"profile":"TEST2","title":"My test app2","description":"a longer description of the test app here.","tcp_ranges":[{"start":0,"end":65535}],"udp_ranges":[{"start":50,"end":51}],"tcp_list":[53],"udp_list":[53],"normalized_tcp_ranges":[{"start":0,"end":65535}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]},{"profile":"TEST3","title":"My test app3","description":"test overlapping ports","tcp_list":[80,83,80,53],"tcp_ranges":[{"start":70,"end":90}],"udp_ranges":[{"start":50,"end":51}],"udp_list":[53],"normalized_tcp_list":[53],"normalized_tcp_ranges":[{"start":70,"end":90}],"normalized_udp_list":[53],"normalized_udp_ranges":[{"start":50,"end":51}]}] diff --git a/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.out b/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.out new file mode 100644 index 00000000..55e71c72 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/ufw-appinfo-all.out @@ -0,0 +1,51 @@ +Profile: MSN +Title: MSN Chat +Description: MSN chat protocol (with file transfer and voice) + +Ports: + 1863 + 6891:6900/tcp + 6901 + +-- + +Profile: OpenSSH +Title: Secure shell server, an rshd replacement +Description: OpenSSH is a free implementation of the Secure Shell protocol. + +Port: + 22/tcp + +-- + +Profile: TEST +Title: My test app +Description: a longer description of the test app here. + +Ports: + 1,2,3,4,5,6,7,8,9,10,30,80:90,8080:8090/tcp + 50:51/udp + 53 + +-- + +Profile: TEST2 +Title: My test app2 +Description: a longer description of the test app here. + +Ports: + any/tcp + 50:51/udp + 53 + +-- + +Profile: TEST3 +Title: My test app3 +Description: test overlapping ports + +Ports: + 80,83,80,70:90/tcp + 50:51/udp + 53 + diff --git a/tests/test_ufw_appinfo.py b/tests/test_ufw_appinfo.py index ae5acb88..0e408042 100644 --- a/tests/test_ufw_appinfo.py +++ b/tests/test_ufw_appinfo.py @@ -10,6 +10,9 @@ class MyTests(unittest.TestCase): def setUp(self): # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-appinfo-all.out'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_appinfo_all = f.read() + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test.out'), 'r', encoding='utf-8') as f: self.generic_ufw_appinfo_test = f.read() @@ -23,6 +26,9 @@ class MyTests(unittest.TestCase): self.generic_ufw_appinfo_msn = f.read() # output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/ufw-appinfo-all.json'), 'r', encoding='utf-8') as f: + self.ubuntu_18_04_ufw_appinfo_all_json = json.loads(f.read()) + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/ufw-appinfo-test.json'), 'r', encoding='utf-8') as f: self.generic_ufw_appinfo_test_json = json.loads(f.read()) @@ -39,7 +45,13 @@ class MyTests(unittest.TestCase): """ Test 'ufw_appinfo' with no data """ - self.assertEqual(jc.parsers.ufw_appinfo.parse('', quiet=True), {}) + self.assertEqual(jc.parsers.ufw_appinfo.parse('', quiet=True), []) + + def test_ufw_appinfo_ubuntu_18_04_all(self): + """ + Test 'ufw app info all' on Ubuntu 18.04 + """ + self.assertEqual(jc.parsers.ufw_appinfo.parse(self.ubuntu_18_04_ufw_appinfo_all, quiet=True), self.ubuntu_18_04_ufw_appinfo_all_json) def test_ufw_appinfo_generic_test(self): """ From 72207c54ee5734e3d2d3d1a063c8daf1edaa8815 Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 26 Apr 2021 10:02:02 -0700 Subject: [PATCH 53/55] update ufw app info docs to support multiple apps (ufw app info all) --- docs/parsers/ufw_appinfo.md | 196 +++++++++++++++++++----------------- jc/man/jc.1.gz | Bin 2413 -> 2413 bytes man/jc.1.gz | Bin 2413 -> 2413 bytes 3 files changed, 102 insertions(+), 94 deletions(-) diff --git a/docs/parsers/ufw_appinfo.md b/docs/parsers/ufw_appinfo.md index 826ff851..35a5d75f 100644 --- a/docs/parsers/ufw_appinfo.md +++ b/docs/parsers/ufw_appinfo.md @@ -3,6 +3,8 @@ # jc.parsers.ufw_appinfo jc - JSON CLI output utility `ufw app info [application]` command output parser +Supports individual apps via `ufw app info [application]` and all apps list via `ufw app info all`. + Because `ufw` application definitions allow overlapping ports and port ranges, this parser preserves that behavior, but also provides `normalized` lists and ranges that remove duplicate ports and merge overlapping ranges. Usage (cli): @@ -20,105 +22,111 @@ Usage (module): Schema: - { - "profile": string, - "title": string, - "description": string, - "tcp_list": [ - integer - ], - "tcp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ], - "udp_list": [ - integer - ], - "udp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integer - } - ], - "normalized_tcp_list": [ - integers # duplicates and overlapping are removed - ], - "normalized_tcp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integers # overlapping are merged - } - ], - "normalized_udp_list": [ - integers # duplicates and overlapping are removed - ], - "normalized_udp_ranges": [ - { - "start": integer, # 'any' is converted to start/end: 0/65535 - "end": integers # overlapping are merged - } - ] - } + [ + { + "profile": string, + "title": string, + "description": string, + "tcp_list": [ + integer + ], + "tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "udp_list": [ + integer + ], + "udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integer + } + ], + "normalized_tcp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_tcp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ], + "normalized_udp_list": [ + integers # duplicates and overlapping are removed + ], + "normalized_udp_ranges": [ + { + "start": integer, # 'any' is converted to start/end: 0/65535 + "end": integers # overlapping are merged + } + ] + } + ] Examples: $ ufw app info MSN | jc --ufw-appinfo -p - { - "profile": "MSN", - "title": "MSN Chat", - "description": "MSN chat protocol (with file transfer and voice)", - "tcp_list": [ - 1863, - 6901 - ], - "udp_list": [ - 1863, - 6901 - ], - "tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_tcp_list": [ - 1863, - 6901 - ], - "normalized_tcp_ranges": [ - { - "start": 6891, - "end": 6900 - } - ], - "normalized_udp_list": [ - 1863, - 6901 - ] - } + [ + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + 1863, + 6901 + ], + "udp_list": [ + 1863, + 6901 + ], + "tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_tcp_list": [ + 1863, + 6901 + ], + "normalized_tcp_ranges": [ + { + "start": 6891, + "end": 6900 + } + ], + "normalized_udp_list": [ + 1863, + 6901 + ] + } + ] $ ufw app info MSN | jc --ufw-appinfo -p -r - { - "profile": "MSN", - "title": "MSN Chat", - "description": "MSN chat protocol (with file transfer and voice)", - "tcp_list": [ - "1863", - "6901" - ], - "udp_list": [ - "1863", - "6901" - ], - "tcp_ranges": [ - { - "start": "6891", - "end": "6900" - } - ] - } + [ + { + "profile": "MSN", + "title": "MSN Chat", + "description": "MSN chat protocol (with file transfer and voice)", + "tcp_list": [ + "1863", + "6901" + ], + "udp_list": [ + "1863", + "6901" + ], + "tcp_ranges": [ + { + "start": "6891", + "end": "6900" + } + ] + } + ] ## info @@ -142,7 +150,7 @@ Parameters: Returns: - Dictionary. Raw or processed structured data. + List of Dictionaries. Raw or processed structured data. ## Parser Information Compatibility: linux diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index 8efe4136176e4f52c0aa3195d5fcb40f4f6f0399..e2074643f268276802c67745acb7bb1cc6800564 100644 GIT binary patch delta 1002 zcmVI1+x>uONa2E&*b>?cElUBSwG! z9R8CX{T9upY@9tVzOW+*0QuFL?d|| z3!qskOOe1!RGVs*v#;s9XmLK7eog13)eQ+FkSR=yQVSzs8djj0#Th^$%6h(i6a{#+R zABy;KkX<5IJP2(?60%u|c9}*=$qlLj7|6;z7m4H+28MUwBeADT8nyzfijW;ol@({( z7d(^PfLA#P6v{GFm8HVrPC~b4ekFtOT`&iC3vJGV@Foi2?P88k!3Bc>k4p(I2yT(M z-D)pM;s7c&j^NOaW`oI#WCnj`U&{1I>C)kK*$rG~_c9?UQQhG9-c&h(iMpjox+SVp zOe=_hr4w}YPM`_#F3CZ)FWbVijkIeFD&4H#fd=z{vg7FE^P?mXJ2U_i-BU?Y2TXfl za^-Mx)d$obsC$69Ohl{_Z)n5y2$lD%LFOcYWP_{+@BExp-7ry*Pj7$Ww;PBaCnOSm z&|)RD2P4@7*TQQCq6cc4*c%EP4~e~fJ{VS7Rpky&Y!}?Dd7?Hg0r#LoWX;W*@JMvq zjtIZyJb3_T$G3U%Gw#4s*oc533hW3^4m8CQ(rN1Ba?AA$FO5~Yb|Q}M5m3gOoiB*( z@PyAieQ8IgEz=vON2GtCoIIIMIz}%c5;EcJZI~Xln}LB6N-qQ~IUDU&mJgda>lgPMn^#lo@kda(=>(87andyT;Rq#ll`oOtLJQ%1x zuu45v^(50=RfU@)QQhD|SlHkW?&%%@TmEopAlRU%T;joFlk9&Y-0>YDUP3Y>I1+w+ zkbK)Sjw}b6^h*m2L#AKEtbHm%5oCHqTojZ&Q2;5>7f7Odz-2!8;SNMVGN8NhhxxNN zeHv%9=`ng61^pplY7<*mCLP%ew<2#zIPQf)gY0f!j+S=NpAuRc%u^bSitmMexsob< zN=sEpOLhB2iexa6s+JaHyTz=`T_g=FqlZgb4Dm_744%vykGFV+i(B=WYBh&T5x1`B YZaKdhxBT0)5(HBP2!3vHS0Ee!0D%zD1^@s6 delta 1002 zcmVI1+x>uONa2E&*b>?Ohj{>Knm9m@{HOX70 zGQ)V0uvBJZVCzyCQWAZh&gRi13dXbR>(TU_{e{NNM>o;M4f`^iFDA2T^eqUK24yQ5 zGgB9qKb{3R^7cLR(gEo_zlg>+6MBDzsQ=42mcodF8!0p^xi+#`FV||7$P}hUsf7_R4J%cFmY`km>_Mu^uvq0_ zS@I9lm}-^RIQy^wl_48tR_FqxA4FE4lJpTd=g519#k^ok!72lWEo;;^8gdzlcFsBUn4Z>pTYMBP#(-4fL) zrWHiM(g`|xC(wj=m*k+@mu=zMM%pz7m2TGWK!bTe*>Uvo`B4&x9U1_M?x`fH1ExJN zxpFwU>H}&I)IGplCL&geH?-k;gv$HXAafExvO(5^cYaQ)ZkQ;@r?-Fb+YLmI6B3C& zXt5I7gOTikYvDBm(E~M2>whM07JW-pLfP2s(vgT$@cqF=Q zM}*&Uo;-lFk%0z1N!15L4nbej6O+;Tm`OJkL;ort4*1eCF6=L=#x zJmE7>U)qsr%k+ln5h;HtCr_r6j?qhqgiJVl8>UC?W?-NMIf)HR!~^>R|70w_F?`W2 zeW#XgFeJL6_q4-)7xnNX&nof!Br`mw52lB)fkIcYH^PmypZ|j)Y$y zB!BK1N0x(3`lSViA=58n);<-X2r@k)E(*$?D1a2`3nWoJ;4&Zla0enF8PMJM!~EHs zK8-Wl^ccO3g8mRNwTZ1OlaB0#TamXU9QQ(@L3Xz5(HBP2uJ1-!XO*~0Hep#9{>OV diff --git a/man/jc.1.gz b/man/jc.1.gz index 8efe4136176e4f52c0aa3195d5fcb40f4f6f0399..e2074643f268276802c67745acb7bb1cc6800564 100644 GIT binary patch delta 1002 zcmVI1+x>uONa2E&*b>?cElUBSwG! z9R8CX{T9upY@9tVzOW+*0QuFL?d|| z3!qskOOe1!RGVs*v#;s9XmLK7eog13)eQ+FkSR=yQVSzs8djj0#Th^$%6h(i6a{#+R zABy;KkX<5IJP2(?60%u|c9}*=$qlLj7|6;z7m4H+28MUwBeADT8nyzfijW;ol@({( z7d(^PfLA#P6v{GFm8HVrPC~b4ekFtOT`&iC3vJGV@Foi2?P88k!3Bc>k4p(I2yT(M z-D)pM;s7c&j^NOaW`oI#WCnj`U&{1I>C)kK*$rG~_c9?UQQhG9-c&h(iMpjox+SVp zOe=_hr4w}YPM`_#F3CZ)FWbVijkIeFD&4H#fd=z{vg7FE^P?mXJ2U_i-BU?Y2TXfl za^-Mx)d$obsC$69Ohl{_Z)n5y2$lD%LFOcYWP_{+@BExp-7ry*Pj7$Ww;PBaCnOSm z&|)RD2P4@7*TQQCq6cc4*c%EP4~e~fJ{VS7Rpky&Y!}?Dd7?Hg0r#LoWX;W*@JMvq zjtIZyJb3_T$G3U%Gw#4s*oc533hW3^4m8CQ(rN1Ba?AA$FO5~Yb|Q}M5m3gOoiB*( z@PyAieQ8IgEz=vON2GtCoIIIMIz}%c5;EcJZI~Xln}LB6N-qQ~IUDU&mJgda>lgPMn^#lo@kda(=>(87andyT;Rq#ll`oOtLJQ%1x zuu45v^(50=RfU@)QQhD|SlHkW?&%%@TmEopAlRU%T;joFlk9&Y-0>YDUP3Y>I1+w+ zkbK)Sjw}b6^h*m2L#AKEtbHm%5oCHqTojZ&Q2;5>7f7Odz-2!8;SNMVGN8NhhxxNN zeHv%9=`ng61^pplY7<*mCLP%ew<2#zIPQf)gY0f!j+S=NpAuRc%u^bSitmMexsob< zN=sEpOLhB2iexa6s+JaHyTz=`T_g=FqlZgb4Dm_744%vykGFV+i(B=WYBh&T5x1`B YZaKdhxBT0)5(HBP2!3vHS0Ee!0D%zD1^@s6 delta 1002 zcmVI1+x>uONa2E&*b>?Ohj{>Knm9m@{HOX70 zGQ)V0uvBJZVCzyCQWAZh&gRi13dXbR>(TU_{e{NNM>o;M4f`^iFDA2T^eqUK24yQ5 zGgB9qKb{3R^7cLR(gEo_zlg>+6MBDzsQ=42mcodF8!0p^xi+#`FV||7$P}hUsf7_R4J%cFmY`km>_Mu^uvq0_ zS@I9lm}-^RIQy^wl_48tR_FqxA4FE4lJpTd=g519#k^ok!72lWEo;;^8gdzlcFsBUn4Z>pTYMBP#(-4fL) zrWHiM(g`|xC(wj=m*k+@mu=zMM%pz7m2TGWK!bTe*>Uvo`B4&x9U1_M?x`fH1ExJN zxpFwU>H}&I)IGplCL&geH?-k;gv$HXAafExvO(5^cYaQ)ZkQ;@r?-Fb+YLmI6B3C& zXt5I7gOTikYvDBm(E~M2>whM07JW-pLfP2s(vgT$@cqF=Q zM}*&Uo;-lFk%0z1N!15L4nbej6O+;Tm`OJkL;ort4*1eCF6=L=#x zJmE7>U)qsr%k+ln5h;HtCr_r6j?qhqgiJVl8>UC?W?-NMIf)HR!~^>R|70w_F?`W2 zeW#XgFeJL6_q4-)7xnNX&nof!Br`mw52lB)fkIcYH^PmypZ|j)Y$y zB!BK1N0x(3`lSViA=58n);<-X2r@k)E(*$?D1a2`3nWoJ;4&Zla0enF8PMJM!~EHs zK8-Wl^ccO3g8mRNwTZ1OlaB0#TamXU9QQ(@L3Xz5(HBP2uJ1-!XO*~0Hep#9{>OV From db8ddd7f0e0c2a8bd3e545619e81d3d3972a4d7c Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 26 Apr 2021 12:04:03 -0700 Subject: [PATCH 54/55] fix for scenarios where the default port range didn't always display, or overrode existing port ranges. --- jc/man/jc.1.gz | Bin 2413 -> 2413 bytes jc/parsers/ufw.py | 24 +++++++++-------------- man/jc.1.gz | Bin 2413 -> 2413 bytes tests/fixtures/generic/ufw-numbered.json | 2 +- tests/fixtures/generic/ufw.json | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/jc/man/jc.1.gz b/jc/man/jc.1.gz index e2074643f268276802c67745acb7bb1cc6800564..51d228409630ffe51437fb0ed7fe450650a1a676 100644 GIT binary patch delta 16 XcmaDW^j3&nzMF$1oUeT&dm1MIE^`Fa delta 16 XcmaDW^j3&nzMF&N@W-}|>}i|;HnavI diff --git a/jc/parsers/ufw.py b/jc/parsers/ufw.py index 58072aa4..c4ae15c2 100644 --- a/jc/parsers/ufw.py +++ b/jc/parsers/ufw.py @@ -301,6 +301,8 @@ def _parse_to_from(linedata, direction, rule_obj=None): if linedata_list[1].strip() in ['tcp', 'udp', 'ah', 'esp', 'gre', 'ipv6', 'igmp']: rule_obj[direction + '_transport'] = linedata_list[1].strip() linedata = linedata_list[0] + else: + rule_obj[direction + '_transport'] = 'any' else: rule_obj[direction + '_transport'] = 'any' @@ -364,24 +366,16 @@ def _parse_to_from(linedata, direction, rule_obj=None): rule_obj[direction + '_ip_prefix'] = '0' # finally set default ports if no ports exist and there should be some - set_default = False if direction + '_transport' in rule_obj: if rule_obj[direction + '_transport'] in ['tcp', 'udp', 'any']: if not port_list and not port_ranges: - set_default = True - - else: - rule_obj[direction + '_transport'] = 'any' - set_default = True - - if set_default: - rule_obj[direction + '_port_ranges'] = [ - { - 'start': '0', - 'end': '65535' - } - ] - rule_obj[direction + '_service'] = None + rule_obj[direction + '_port_ranges'] = [ + { + 'start': '0', + 'end': '65535' + } + ] + rule_obj[direction + '_service'] = None return rule_obj diff --git a/man/jc.1.gz b/man/jc.1.gz index e2074643f268276802c67745acb7bb1cc6800564..51d228409630ffe51437fb0ed7fe450650a1a676 100644 GIT binary patch delta 16 XcmaDW^j3&nzMF$1oUeT&dm1MIE^`Fa delta 16 XcmaDW^j3&nzMF&N@W-}|>}i|;HnavI diff --git a/tests/fixtures/generic/ufw-numbered.json b/tests/fixtures/generic/ufw-numbered.json index 27809d81..a9d9170d 100644 --- a/tests/fixtures/generic/ufw-numbered.json +++ b/tests/fixtures/generic/ufw-numbered.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":0,"end":65535}],"from_transport":"any"},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":1,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":2,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":3,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":4,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":5,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":6,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_transport":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":"IN","index":7,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_interface":"en1","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":8,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":9,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":10,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":11,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":12,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":13,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"ALLOW","action_direction":null,"index":14,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":15,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} diff --git a/tests/fixtures/generic/ufw.json b/tests/fixtures/generic/ufw.json index 9ea2b2a2..0fc517a7 100644 --- a/tests/fixtures/generic/ufw.json +++ b/tests/fixtures/generic/ufw.json @@ -1 +1 @@ -{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"nice comment","from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":0,"end":65535}],"from_transport":"any"},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":"commenting this rule","from_interface":"en1","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":"this is a comment","from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} +{"status":"active","logging":"on","logging_level":"low","default":"deny (incoming), allow (outgoing), deny (routed)","new_profiles":"skip","rules":[{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"OUT","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"nice comment","from_interface":"any","from_transport":"any","from_ip":"192.168.0.1","from_ip_prefix":32,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"OUT","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[443],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.7","from_ip_prefix":32,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"any","from_transport":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"udp","to_service":null,"to_ports":[22],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_interface":"en0","from_transport":"any","from_ip":"192.168.0.0","from_ip_prefix":24,"from_service":null,"from_port_ranges":[{"start":8080,"end":8081}]},{"action":"ALLOW","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_ports":[22],"to_ip":"::","to_ip_prefix":0,"comment":"commenting this rule","from_interface":"en1","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":64,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[80],"to_ip":"0.0.0.0","to_ip_prefix":0,"comment":null,"from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"REJECT","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"any","to_service":null,"to_ports":[8080],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv4","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"0.0.0.0","to_ip_prefix":0,"comment":"a comment","from_ip":"0.0.0.0","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"Apache Full","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"DENY","action_direction":"IN","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":null,"to_service":"OpenSSH","to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"ALLOW","action_direction":null,"index":null,"network_protocol":"ipv4","to_interface":"enp34s0","to_transport":"any","to_ip":"10.10.10.10","to_ip_prefix":32,"to_service":null,"to_ports":[8080],"comment":null,"from_interface":"any","from_transport":"any","from_ip":"127.0.0.1","from_ip_prefix":32,"from_service":null,"from_ports":[8000]},{"action":"DENY","action_direction":"FWD","index":null,"network_protocol":"ipv6","to_interface":"any","to_transport":"tcp","to_service":null,"to_port_ranges":[{"start":50200,"end":50300}],"to_ip":"::","to_ip_prefix":0,"comment":null,"from_ip":"::","from_ip_prefix":0,"from_interface":"any","from_transport":"any","from_port_ranges":[{"start":0,"end":65535}],"from_service":null},{"action":"LIMIT","action_direction":null,"index":null,"network_protocol":"ipv6","to_ip":"::","to_ip_prefix":0,"to_interface":"any","to_transport":"any","to_port_ranges":[{"start":0,"end":65535}],"to_service":null,"comment":"this is a comment","from_interface":"any","from_transport":"any","from_ip":"2405:204:7449:49fc:f09a:6f4a:bc93:1955","from_ip_prefix":128,"from_port_ranges":[{"start":0,"end":65535}],"from_service":null}]} From 35464bbbfb6b424ef3ee1c855557ada1bf3769fa Mon Sep 17 00:00:00 2001 From: Kelly Brazil Date: Mon, 26 Apr 2021 12:08:10 -0700 Subject: [PATCH 55/55] date update --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 09a34a70..f25f1bb0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ jc changelog -20210425 v1.15.3 +20210426 v1.15.3 - Add ufw status command parser tested on linux - Add ufw-appinfo command parser tested on linux - Fix deb package name to conform to standard