diff --git a/libraries/libapparmor/swig/python/test/test_python.py.in b/libraries/libapparmor/swig/python/test/test_python.py.in index a7b96cc19..01877b90a 100644 --- a/libraries/libapparmor/swig/python/test/test_python.py.in +++ b/libraries/libapparmor/swig/python/test/test_python.py.in @@ -75,8 +75,8 @@ class AAPythonBindingsTests(unittest.TestCase): expected = self.parse_output_file(outfile) self.assertEqual(expected, record, - "expected records did not match\n" + - "expected = %s\nactual = %s" % (expected, record)) + "expected records did not match\n" + "expected = %s\nactual = %s" % (expected, record)) def parse_output_file(self, outfile): """parse testcase .out file and return dict""" diff --git a/tests/bin/shellcheck-tree b/tests/bin/shellcheck-tree index c9864d266..46828cdce 100755 --- a/tests/bin/shellcheck-tree +++ b/tests/bin/shellcheck-tree @@ -10,10 +10,10 @@ from pathlib import Path def is_excluded(f): return (re.match( # skip test scripts and the rc.apparmor.slackware initscript - r"^([.]git/|parser/tst/|tests/|utils/test/|parser/rc[.]apparmor[.]slackware)" + - "|" + + r"^([.]git/|parser/tst/|tests/|utils/test/|parser/rc[.]apparmor[.]slackware)" + + "|" # skip several files generated during libapparmor build - r"^libraries/libapparmor/(compile|config[.]guess|config[.]status|config[.]sub|configure|depcomp|install-sh|libtool|ltmain[.]sh|missing|test-driver|ylwrap|testsuite/test_multi[.]multi)", + + r"^libraries/libapparmor/(compile|config[.]guess|config[.]status|config[.]sub|configure|depcomp|install-sh|libtool|ltmain[.]sh|missing|test-driver|ylwrap|testsuite/test_multi[.]multi)", f, ) or Path(f).is_dir()) diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index b28eb32dd..7c2a93531 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -1922,8 +1922,8 @@ def parse_profile_data(data, file, do_include, in_preamble): if profile_data.get(profname, False): raise AppArmorException( - 'Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' % - {'file': file, 'line': lineno + 1, 'profile': combine_name(profile, hat)}) + 'Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' + % {'file': file, 'line': lineno + 1, 'profile': combine_name(profile, hat)}) profile_data[profname] = prof_storage diff --git a/utils/apparmor/common.py b/utils/apparmor/common.py index 60363240e..fa4b55d05 100644 --- a/utils/apparmor/common.py +++ b/utils/apparmor/common.py @@ -268,7 +268,7 @@ def convert_regexp(regexp): def user_perm(prof_dir): if not os.access(prof_dir, os.W_OK): - sys.stdout.write("Cannot write to profile directory.\n" + + sys.stdout.write("Cannot write to profile directory.\n" "Please run as a user with appropriate permissions.\n") return False return True diff --git a/utils/apparmor/logparser.py b/utils/apparmor/logparser.py index ee7e0c8ed..053a7f12b 100644 --- a/utils/apparmor/logparser.py +++ b/utils/apparmor/logparser.py @@ -285,8 +285,8 @@ class ReadLog: self.parse_event_for_tree(event) except AppArmorException as e: - ex_msg = ('%(msg)s\n\nThis error was caused by the log line:\n%(logline)s' % - {'msg': e.value, 'logline': line}) + ex_msg = ('%(msg)s\n\nThis error was caused by the log line:\n%(logline)s' + % {'msg': e.value, 'logline': line}) raise AppArmorBug(ex_msg) from None self.logmark = '' diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index 580429a72..dafdd0470 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -56,33 +56,33 @@ RE_PROFILE_UNIX = re.compile(RE_AUDIT_DENY + '(unix\s*,|unix\s+[^#]*\s*,)' + RE_ __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' RE_RULE_HAS_COMMA = re.compile( - '^' + __re_no_or_quoted_hash + - ',\s*(#.*)?$') # match comma plus any trailing comment + '^' + __re_no_or_quoted_hash + + ',\s*(#.*)?$') # match comma plus any trailing comment RE_HAS_COMMENT_SPLIT = re.compile( - '^(?P' + __re_no_or_quoted_hash + ')' + # store in 'not_comment' group - '(?P#.*)$') # match trailing comment and store in 'comment' group + '^(?P' + __re_no_or_quoted_hash + ')' # store in 'not_comment' group + + '(?P#.*)$') # match trailing comment and store in 'comment' group RE_PROFILE_START = re.compile( - '^(?P\s*)' + - '(' + - RE_PROFILE_PATH_OR_VAR % 'plainprofile' + # just a path - '|' + # or - '(' + 'profile' + '\s+' + RE_PROFILE_NAME % 'namedprofile' + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'attachment' + ')?' + ')' + # 'profile', profile name, optionally attachment - ')' + - RE_XATTRS + - RE_FLAGS + - '\s*\{' + - RE_EOL) + '^(?P\s*)' + + '(' + + RE_PROFILE_PATH_OR_VAR % 'plainprofile' # just a path + + '|' # or + + '(' + 'profile' + '\s+' + RE_PROFILE_NAME % 'namedprofile' + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'attachment' + ')?' + ')' # 'profile', profile name, optionally attachment + + ')' + + RE_XATTRS + + RE_FLAGS + + '\s*\{' + + RE_EOL) RE_PROFILE_CHANGE_PROFILE = re.compile( - RE_AUDIT_DENY + - 'change_profile' + - '(\s+' + RE_SAFE_OR_UNSAFE + ')?' + # optionally exec mode - '(\s+' + RE_PROFILE_PATH_OR_VAR % 'execcond' + ')?' + # optionally exec condition - '(\s+->\s*' + RE_PROFILE_NAME % 'targetprofile' + ')?' + # optionally '->' target profile - RE_COMMA_EOL) + RE_AUDIT_DENY + + 'change_profile' + + '(\s+' + RE_SAFE_OR_UNSAFE + ')?' # optionally exec mode + + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'execcond' + ')?' # optionally exec condition + + '(\s+->\s*' + RE_PROFILE_NAME % 'targetprofile' + ')?' # optionally '->' target profile + + RE_COMMA_EOL) # RE_PATH_PERMS is as restrictive as possible, but might still cause mismatches when adding different rule types. @@ -90,26 +90,26 @@ RE_PROFILE_CHANGE_PROFILE = re.compile( RE_PATH_PERMS = '(?P<%s>[mrwalkPUCpucix]+)' RE_PROFILE_FILE_ENTRY = re.compile( - RE_AUDIT_DENY + - '(?Powner\s+)?' + # optionally: - '(' + - '(?Pfile)' + # bare 'file,' - '|' + # or - '(?Pfile\s+)?' + # optional 'file' keyword - '(' + - RE_PROFILE_PATH_OR_VAR % 'path' + '\s+' + RE_PATH_PERMS % 'perms' + # path and perms - '|' + # or - RE_PATH_PERMS % 'perms2' + '\s+' + RE_PROFILE_PATH_OR_VAR % 'path2' + # perms and path - ')' + - '(\s+->\s*' + RE_PROFILE_NAME % 'target' + ')?' + - '|' + # or - '(?Plink\s+)' + # 'link' keyword - '(?Psubset\s+)?' + # optional 'subset' keyword - RE_PROFILE_PATH_OR_VAR % 'link_path' + # path - '\s+' + '->' + '\s+' + # ' -> ' - RE_PROFILE_PATH_OR_VAR % 'link_target' + # path - ')' + - RE_COMMA_EOL) + RE_AUDIT_DENY + + '(?Powner\s+)?' # optionally: + + '(' + + '(?Pfile)' # bare 'file,' + + '|' # or + + '(?Pfile\s+)?' # optional 'file' keyword + + '(' + + RE_PROFILE_PATH_OR_VAR % 'path' + '\s+' + RE_PATH_PERMS % 'perms' # path and perms + + '|' # or + + RE_PATH_PERMS % 'perms2' + '\s+' + RE_PROFILE_PATH_OR_VAR % 'path2' # perms and path + + ')' + + '(\s+->\s*' + RE_PROFILE_NAME % 'target' + ')?' + + '|' # or + + '(?Plink\s+)' # 'link' keyword + + '(?Psubset\s+)?' # optional 'subset' keyword + + RE_PROFILE_PATH_OR_VAR % 'link_path' # path + + '\s+' + '->' + '\s+' # ' -> ' + + RE_PROFILE_PATH_OR_VAR % 'link_target' # path + + ')' + + RE_COMMA_EOL) def parse_profile_start_line(line, filename): diff --git a/utils/apparmor/rule/__init__.py b/utils/apparmor/rule/__init__.py index ebe48442c..db68cfce0 100644 --- a/utils/apparmor/rule/__init__.py +++ b/utils/apparmor/rule/__init__.py @@ -508,15 +508,15 @@ def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name result_list = set(lst) else: raise AppArmorBug( - 'Passed unknown %(type)s object to %(classname)s: %(unknown_object)s' % - {'type': type(lst), 'classname': classname, 'unknown_object': str(lst)}) + 'Passed unknown %(type)s object to %(classname)s: %(unknown_object)s' + % {'type': type(lst), 'classname': classname, 'unknown_object': str(lst)}) unknown_items = set() for item in result_list: if not item.strip(): raise AppArmorBug( - 'Passed empty %(keyword_name)s to %(classname)s' % - {'keyword_name': keyword_name, 'classname': classname}) + 'Passed empty %(keyword_name)s to %(classname)s' + % {'keyword_name': keyword_name, 'classname': classname}) if item not in allowed_keywords: unknown_items.add(item) diff --git a/utils/apparmor/rule/dbus.py b/utils/apparmor/rule/dbus.py index a1f2a8c02..5e49f110b 100644 --- a/utils/apparmor/rule/dbus.py +++ b/utils/apparmor/rule/dbus.py @@ -41,27 +41,27 @@ RE_FLAG = '(?P<%s>(\S+|"[^"]+"|\(\s*\S+\s*\)|\(\s*"[^"]+"\)\s*))' # string with # XXX this regex will allow repeated parameters, last one wins # XXX (the parser will reject such rules) RE_DBUS_DETAILS = re.compile( - '^' + - '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) - '((\s+(bus\s*=\s*' + RE_FLAG % 'bus' + '))?|' + # optional bus= system | session | AARE, (...) optional - '(\s+(path\s*=\s*' + RE_FLAG % 'path' + '))?|' + # optional path=AARE, (...) optional - '(\s+(name\s*=\s*' + RE_FLAG % 'name' + '))?|' + # optional name=AARE, (...) optional - '(\s+(interface\s*=\s*' + RE_FLAG % 'interface' + '))?|' + # optional interface=AARE, (...) optional - '(\s+(member\s*=\s*' + RE_FLAG % 'member' + '))?|' + # optional member=AARE, (...) optional - '(\s+(peer\s*=\s*\((,|\s)*' + # optional peer=(name=AARE and/or label=AARE), (...) required - '(' + - '(' + '(,|\s)*' + ')' + # empty peer=() - '|' # or - '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername1' + ')' + # only peer name (match group peername1) - '|' # or - '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel1' + ')' + # only peer label (match group peerlabel1) - '|' # or - '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername2' + '(,|\s)+' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel2' + ')' + # peer name + label (match name peername2/peerlabel2) - '|' # or - '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel3' + '(,|\s)+' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername3' + ')' + # peer label + name (match name peername3/peerlabel3) - ')' - '(,|\s)*\)))?){0,6}' - '\s*$') + '^' + + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' # optional access keyword(s) + + '((\s+(bus\s*=\s*' + RE_FLAG % 'bus' + '))?|' # optional bus= system | session | AARE, (...) optional + + '(\s+(path\s*=\s*' + RE_FLAG % 'path' + '))?|' # optional path=AARE, (...) optional + + '(\s+(name\s*=\s*' + RE_FLAG % 'name' + '))?|' # optional name=AARE, (...) optional + + '(\s+(interface\s*=\s*' + RE_FLAG % 'interface' + '))?|' # optional interface=AARE, (...) optional + + '(\s+(member\s*=\s*' + RE_FLAG % 'member' + '))?|' # optional member=AARE, (...) optional + + '(\s+(peer\s*=\s*\((,|\s)*' # optional peer=(name=AARE and/or label=AARE), (...) required + + '(' + + '(' + '(,|\s)*' + ')' # empty peer=() + + '|' # or + + '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername1' + ')' # only peer name (match group peername1) + + '|' # or + + '(' 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel1' + ')' # only peer label (match group peerlabel1) + + '|' # or + + '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername2' + '(,|\s)+' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel2' + ')' # peer name + label (match name peername2/peerlabel2) + + '|' # or + + '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel3' + '(,|\s)+' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername3' + ')' # peer label + name (match name peername3/peerlabel3) + + ')' + + '(,|\s)*\)))?){0,6}' + + '\s*$') class DbusRule(BaseRule): diff --git a/utils/apparmor/rule/network.py b/utils/apparmor/rule/network.py index f58d4916f..63c472a4a 100644 --- a/utils/apparmor/rule/network.py +++ b/utils/apparmor/rule/network.py @@ -39,10 +39,10 @@ RE_NETWORK_TYPE = '(' + '|'.join(network_type_keywords) + ')' RE_NETWORK_PROTOCOL = '(' + '|'.join(network_protocol_keywords) + ')' RE_NETWORK_DETAILS = re.compile( - '^\s*' + - '(?P' + RE_NETWORK_DOMAIN + ')?' + # optional domain - '(\s+(?P' + RE_NETWORK_TYPE + '|' + RE_NETWORK_PROTOCOL + '))?' + # optional type or protocol - '\s*$') + '^\s*' + + '(?P' + RE_NETWORK_DOMAIN + ')?' # optional domain + + '(\s+(?P' + RE_NETWORK_TYPE + '|' + RE_NETWORK_PROTOCOL + '))?' # optional type or protocol + + '\s*$') class NetworkRule(BaseRule): diff --git a/utils/apparmor/rule/ptrace.py b/utils/apparmor/rule/ptrace.py index e76f6b639..e02854cef 100644 --- a/utils/apparmor/rule/ptrace.py +++ b/utils/apparmor/rule/ptrace.py @@ -27,17 +27,16 @@ access_keywords = ['r', 'w', 'rw', 'wr', 'read', 'write', 'readby', 'trace', 'tr # XXX joint_access_keyword and RE_ACCESS_KEYWORDS exactly as in PtraceRule - move to function! joint_access_keyword = '\s*(' + '|'.join(access_keywords) + ')\s*' -RE_ACCESS_KEYWORDS = (joint_access_keyword + # one of the access_keyword or - '|' + # or - '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) - ) +RE_ACCESS_KEYWORDS = (joint_access_keyword # one of the access_keyword or + + '|' # or + + '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)') # one or more access_keyword in (...) RE_PTRACE_DETAILS = re.compile( - '^' + - '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) - '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' + # optional peer - '\s*$') + '^' + + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' # optional access keyword(s) + + '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' # optional peer + + '\s*$') class PtraceRule(BaseRule): diff --git a/utils/apparmor/rule/signal.py b/utils/apparmor/rule/signal.py index 8e40abcd4..348868920 100644 --- a/utils/apparmor/rule/signal.py +++ b/utils/apparmor/rule/signal.py @@ -39,25 +39,25 @@ RE_SIGNAL_REALTIME = re.compile('^rtmin\+0*([0-9]|[12][0-9]|3[0-2])$') # rtmin+ joint_access_keyword = '\s*(' + '|'.join(access_keywords) + ')\s*' RE_ACCESS_KEYWORDS = ( - joint_access_keyword + # one of the access_keyword or - '|' + # or - '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) + joint_access_keyword # one of the access_keyword or + + '|' # or + + '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) ) signal_keyword = '\s*([a-z0-9+]+|"[a-z0-9+]+")\s*' # don't check against the signal keyword list in the regex to allow a more helpful error message RE_SIGNAL_KEYWORDS = ( - 'set\s*=\s*' + signal_keyword + # one of the signal_keyword or - '|' + # or - 'set\s*=\s*\(' + signal_keyword + '(' + '(\s|,)+' + signal_keyword + ')*' + '\)' # one or more signal_keyword in (...) + 'set\s*=\s*' + signal_keyword # one of the signal_keyword or + + '|' # or + + 'set\s*=\s*\(' + signal_keyword + '(' + '(\s|,)+' + signal_keyword + ')*' + '\)' # one or more signal_keyword in (...) ) RE_SIGNAL_DETAILS = re.compile( - '^' + - '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) - '(?P' + '(\s+(' + RE_SIGNAL_KEYWORDS + '))+' + ')?' + # optional signal set(s) - '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' + # optional peer - '\s*$') + '^' + + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' # optional access keyword(s) + + '(?P' + '(\s+(' + RE_SIGNAL_KEYWORDS + '))+' + ')?' # optional signal set(s) + + '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' # optional peer + + '\s*$') RE_FILTER_SET_1 = re.compile('set\s*=\s*\(([^)]*)\)') diff --git a/utils/apparmor/sandbox.py b/utils/apparmor/sandbox.py index e54fad8dd..32623d7fe 100644 --- a/utils/apparmor/sandbox.py +++ b/utils/apparmor/sandbox.py @@ -607,8 +607,8 @@ EndSection started = False # We need to wait for the xpra socket to exist before attaching - fn = os.path.join(os.environ['HOME'], '.xpra', '%s-%s' % - (socket.gethostname(), self.display.split(':')[1])) + fn = os.path.join(os.environ['HOME'], '.xpra', '%s-%s' + % (socket.gethostname(), self.display.split(':')[1])) for i in range(self.timeout * 2): # up to self.timeout seconds to start if os.path.exists(fn): debug("Found '%s'! Proceeding to attach" % fn) diff --git a/utils/test/test-aa-easyprof.py b/utils/test/test-aa-easyprof.py index 693b4f592..6e1ca8c44 100755 --- a/utils/test/test-aa-easyprof.py +++ b/utils/test/test-aa-easyprof.py @@ -561,8 +561,8 @@ POLICYGROUPS_DIR="%s/templates" args = self.full_args args.append('--list-templates') - args.append('--include-templates-dir=%s' % - os.path.join(self.test_include_dir, 'templates')) + args.append('--include-templates-dir=%s' + % os.path.join(self.test_include_dir, 'templates')) (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) @@ -580,8 +580,8 @@ POLICYGROUPS_DIR="%s/templates" args = self.full_args args += ['--show-template', '--template', f, - '--include-templates-dir=%s' % - os.path.join(self.test_include_dir, 'templates')] + '--include-templates-dir=%s' + % os.path.join(self.test_include_dir, 'templates')] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) @@ -634,8 +634,8 @@ POLICYGROUPS_DIR="%s/templates" args = self.full_args args.append('--list-policy-groups') - args.append('--include-policy-groups-dir=%s' % - os.path.join(self.test_include_dir, 'policygroups')) + args.append('--include-policy-groups-dir=%s' + % os.path.join(self.test_include_dir, 'policygroups')) (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) @@ -653,8 +653,8 @@ POLICYGROUPS_DIR="%s/templates" args = self.full_args args += ['--show-policy-group', '--policy-groups', os.path.basename(f), - '--include-policy-groups-dir=%s' % - os.path.join(self.test_include_dir, 'policygroups')] + '--include-policy-groups-dir=%s' + % os.path.join(self.test_include_dir, 'policygroups')] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) diff --git a/utils/test/test-aa-notify.py b/utils/test/test-aa-notify.py index 22a23b51d..d6fb59400 100644 --- a/utils/test/test-aa-notify.py +++ b/utils/test/test-aa-notify.py @@ -116,10 +116,10 @@ Feb 4 13:40:38 XPS-13-9370 kernel: [128552.880347] audit: type=1400 audit({epoc with NamedTemporaryFile("w+", prefix='test-aa-notify-', delete=False) as temp_file: self.test_logfile = temp_file.name temp_file.write( - test_logfile_contents_999_days_old + - test_logfile_contents_30_days_old + - test_logfile_contents_unrelevant_entries + - test_logfile_contents_0_seconds_old + test_logfile_contents_999_days_old + + test_logfile_contents_30_days_old + + test_logfile_contents_unrelevant_entries + + test_logfile_contents_0_seconds_old ) def AATeardown(self):