Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion ui/opensnitch/dialogs/prompt/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from slugify import slugify
import os
import re
import ipaddress

from PyQt6.QtCore import QCoreApplication as QC
Expand All @@ -23,7 +24,20 @@ def get_rule_name(rule, is_list):
rule_temp_name = "%s-list" % rule_temp_name
else:
rule_temp_name = "%s-simple" % rule_temp_name
rule_temp_name = slugify("%s %s" % (rule_temp_name, rule.operator.data))

rule_data = rule.operator.data
if rule.operator.type == Config.RULE_TYPE_REGEXP:
# Alnum character classes (e.g. [0-9A-Za-z]) don't carry any
# identifying info for a rule name, and slugify() lowercases
# everything, so a mixed-case range like [0-9A-Za-z] turns into
# "0-9a-za-z", which looks like a duplicated a-z class. Strip them
# out instead of slugifying them (#1587).
# Only match classes made up of digits/letters/hyphens, so we don't
# touch escaped brackets or other regexp syntax a user may have
# typed by hand (e.g. r'\[test\]' or r'[a-z\]]').
rule_data = re.sub(r'\[[0-9A-Za-z\-]+\]', '', rule_data)

rule_temp_name = slugify("%s %s" % (rule_temp_name, rule_data))

return rule_temp_name[:128]

Expand Down
52 changes: 52 additions & 0 deletions ui/tests/dialogs/test_prompt_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#
# pytest -v tests/dialogs/test_prompt_utils.py
#

import opensnitch.proto as proto
ui_pb2, ui_pb2_grpc = proto.import_()

from opensnitch.config import Config
from opensnitch.dialogs.prompt import utils


def _make_rule(data, rule_type=Config.RULE_TYPE_REGEXP):
rule = ui_pb2.Rule(name="user.choice")
rule.action = Config.ACTION_ALLOW
rule.duration = Config.DURATION_ONCE
rule.operator.type = rule_type
rule.operator.operand = Config.OPERAND_PROCESS_PATH
rule.operator.data = data
return rule


class TestPromptUtils():

def test_get_rule_name_appimage_regexp_no_duplicated_class(self):
""" Regexps built for appimage/snap paths use a mixed-case character
class ([0-9A-Za-z]). slugify() lowercases everything, which used to
turn it into "0-9a-za-z" in the rule name, looking like a duplicated
a-z class (#1587).
"""
rule = _make_rule(r'^/tmp/\.mount_handy_[0-9A-Za-z]+\/.*handy$')
name = utils.get_rule_name(rule, False)

assert "0-9a-za-z" not in name
assert "handy" in name

def test_get_rule_name_simple_rule_unaffected(self):
""" Non-regexp rules aren't touched by the character-class stripping.
"""
rule = _make_rule("www.google.com", rule_type=Config.RULE_TYPE_SIMPLE)
name = utils.get_rule_name(rule, False)

assert name == "allow-once-simple-www-google-com"

def test_get_rule_name_escaped_brackets_not_mangled(self):
""" A hand-typed regexp matching a literal bracket must not be
treated as a character class and stripped.
"""
rule = _make_rule(r'^/opt/\[legacy\]/app$')
name = utils.get_rule_name(rule, False)

assert "legacy" in name
assert "app" in name