diff --git a/libraries/libapparmor/swig/python/test/test_python.py.in b/libraries/libapparmor/swig/python/test/test_python.py.in index 75c71415e..a7b96cc19 100644 --- a/libraries/libapparmor/swig/python/test/test_python.py.in +++ b/libraries/libapparmor/swig/python/test/test_python.py.in @@ -79,7 +79,7 @@ class AAPythonBindingsTests(unittest.TestCase): "expected = %s\nactual = %s" % (expected, record)) def parse_output_file(self, outfile): - '''parse testcase .out file and return dict''' + """parse testcase .out file and return dict""" output = dict() with open(os.path.join(TESTDIR, outfile), 'r') as f: @@ -105,7 +105,7 @@ class AAPythonBindingsTests(unittest.TestCase): return output def create_record_dict(self, record): - '''parse the swig created record and construct a dict from it''' + """parse the swig created record and construct a dict from it""" new_record = dict() for key in [x for x in dir(record) if not (x.startswith('_') or x == 'this')]: @@ -128,7 +128,7 @@ class AAPythonBindingsTests(unittest.TestCase): def find_testcases(testdir): - '''dig testcases out of passed directory''' + """dig testcases out of passed directory""" for f in os.listdir(testdir): if f.endswith(".in"): @@ -143,5 +143,6 @@ def main(): setattr(AAPythonBindingsTests, 'test_%s' % (f), stub_test) return unittest.main(verbosity=2) + if __name__ == "__main__": main() diff --git a/parser/tst/caching.py b/parser/tst/caching.py index fd8f49ce0..9d0fc1f8b 100755 --- a/parser/tst/caching.py +++ b/parser/tst/caching.py @@ -50,7 +50,7 @@ class AAParserCachingCommon(testlib.AATestTemplate): do_cleanup = True def setUp(self): - '''setup for each test''' + """setup for each test""" global config # REPORT ALL THE OUTPUT @@ -88,7 +88,7 @@ class AAParserCachingCommon(testlib.AATestTemplate): self.cache_file = os.path.join(self.cache_dir, PROFILE) def tearDown(self): - '''teardown for each test''' + """teardown for each test""" if not self.do_cleanup: print("\n===> Skipping cleanup, leaving testfiles behind in '%s'" % (self.tmp_dir)) @@ -149,7 +149,7 @@ class AAParserCachingCommon(testlib.AATestTemplate): class AAParserBasicCachingTests(AAParserCachingCommon): def test_no_cache_by_default(self): - '''test profiles are not cached by default''' + """test profiles are not cached by default""" cmd = list(self.cmd_prefix) cmd.extend(('-q', '-r', self.profile)) @@ -157,7 +157,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon): self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) def test_no_cache_w_skip_cache(self): - '''test profiles are not cached with --skip-cache''' + """test profiles are not cached with --skip-cache""" cmd = list(self.cmd_prefix) cmd.extend(('-q', '--write-cache', '--skip-cache', '-r', self.profile)) @@ -165,7 +165,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon): self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) def test_cache_when_requested(self): - '''test profiles are cached when requested''' + """test profiles are cached when requested""" cmd = list(self.cmd_prefix) cmd.extend(('-q', '--write-cache', '-r', self.profile)) @@ -173,7 +173,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon): self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) def test_write_features_when_caching(self): - '''test features file is written when caching''' + """test features file is written when caching""" cmd = list(self.cmd_prefix) cmd.extend(('-q', '--write-cache', '-r', self.profile)) @@ -182,7 +182,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon): self.assert_path_exists(os.path.join(self.cache_dir, '.features')) def test_features_match_when_caching(self): - '''test features file is written when caching''' + """test features file is written when caching""" self.require_apparmorfs() @@ -196,7 +196,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon): class AAParserAltCacheBasicTests(AAParserBasicCachingTests): - '''Same tests as above, but with an alternate cache location specified on the command line''' + """Same tests as above, but with an alternate cache location specified on the command line""" def setUp(self): super().setUp() @@ -215,7 +215,7 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests): class AAParserCreateCacheBasicTestsCacheExists(AAParserBasicCachingTests): - '''Same tests as above, but with create cache option on the command line and the cache already exists''' + """Same tests as above, but with create cache option on the command line and the cache already exists""" def setUp(self): super().setUp() @@ -223,7 +223,7 @@ class AAParserCreateCacheBasicTestsCacheExists(AAParserBasicCachingTests): class AAParserCreateCacheBasicTestsCacheNotExist(AAParserBasicCachingTests): - '''Same tests as above, but with create cache option on the command line and cache dir removed''' + """Same tests as above, but with create cache option on the command line and cache dir removed""" def setUp(self): super().setUp() @@ -232,8 +232,8 @@ class AAParserCreateCacheBasicTestsCacheNotExist(AAParserBasicCachingTests): class AAParserCreateCacheAltCacheTestsCacheNotExist(AAParserBasicCachingTests): - '''Same tests as above, but with create cache option on the command line, - alt cache specified, and cache dir removed''' + """Same tests as above, but with create cache option on the command line, + alt cache specified, and cache dir removed""" def setUp(self): super().setUp() @@ -262,7 +262,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(os.stat(path).st_mtime, mtime) def test_cache_loaded_when_exists(self): - '''test cache is loaded when it exists, is newer than profile, and features match''' + """test cache is loaded when it exists, is newer than profile, and features match""" self._generate_cache_file() @@ -271,7 +271,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.run_cmd_check(cmd, expected_string='Cached reload succeeded') def test_cache_not_loaded_when_skip_arg(self): - '''test cache is not loaded when --skip-cache is passed''' + """test cache is not loaded when --skip-cache is passed""" self._generate_cache_file() @@ -280,7 +280,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_not_loaded_when_skip_read_arg(self): - '''test cache is not loaded when --skip-read-cache is passed''' + """test cache is not loaded when --skip-read-cache is passed""" self._generate_cache_file() @@ -289,7 +289,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_not_loaded_when_features_differ(self): - '''test cache is not loaded when features file differs''' + """test cache is not loaded when features file differs""" self._generate_cache_file() @@ -300,7 +300,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_writing_does_not_overwrite_features_when_features_differ(self): - '''test cache writing does not overwrite the features files when it differs and --skip-bad-cache is given''' + """test cache writing does not overwrite the features files when it differs and --skip-bad-cache is given""" self.require_apparmorfs() @@ -314,7 +314,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.compare_features_file(features_file, expected=False) def test_cache_writing_skipped_when_features_differ(self): - '''test cache writing is skipped when features file differs''' + """test cache writing is skipped when features file differs""" testlib.write_file(self.cache_dir, '.features', 'monkey\n') @@ -324,7 +324,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assert_path_exists(self.cache_file, expected=False) def test_cache_writing_collision_of_features(self): - '''test cache writing collision of features''' + """test cache writing collision of features""" # cache dir with different features causes a collision resulting # in a new cache dir self.require_apparmorfs() @@ -341,7 +341,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.compare_features_file(new_features_file) def test_cache_writing_updates_cache_file(self): - '''test cache writing updates cache file''' + """test cache writing updates cache file""" cache_file = testlib.write_file(self.cache_dir, PROFILE, 'monkey\n') orig_stat = os.stat(cache_file) @@ -358,7 +358,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(os.stat(self.profile).st_mtime, stat.st_mtime) def test_cache_writing_clears_all_files(self): - '''test cache writing clears all cache files''' + """test cache writing clears all cache files""" check_file = testlib.write_file(self.cache_dir, 'monkey', 'monkey\n') @@ -368,7 +368,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assert_path_exists(check_file, expected=False) def test_profile_mtime_preserved(self): - '''test profile mtime is preserved when it is newest''' + """test profile mtime is preserved when it is newest""" expected = 1 self._set_mtime(self.abstraction, 0) self._set_mtime(self.profile, expected) @@ -376,7 +376,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(expected, os.stat(self.cache_file).st_mtime) def test_abstraction_mtime_preserved(self): - '''test abstraction mtime is preserved when it is newest''' + """test abstraction mtime is preserved when it is newest""" expected = 1000 self._set_mtime(self.profile, 0) self._set_mtime(self.abstraction, expected) @@ -384,7 +384,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(expected, os.stat(self.cache_file).st_mtime) def test_equal_mtimes_preserved(self): - '''test equal profile and abstraction mtimes are preserved''' + """test equal profile and abstraction mtimes are preserved""" expected = 10000 + self.mtime_res self._set_mtime(self.profile, expected) self._set_mtime(self.abstraction, expected) @@ -392,7 +392,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(expected, os.stat(self.cache_file).st_mtime) def test_profile_newer_skips_cache(self): - '''test cache is skipped if profile is newer''' + """test cache is skipped if profile is newer""" self._generate_cache_file() profile_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res @@ -410,7 +410,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(orig_stat.st_mtime, stat.st_mtime) def test_abstraction_newer_skips_cache(self): - '''test cache is skipped if abstraction is newer''' + """test cache is skipped if abstraction is newer""" self._generate_cache_file() abstraction_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res @@ -428,7 +428,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(orig_stat.st_mtime, stat.st_mtime) def test_profile_newer_rewrites_cache(self): - '''test cache is rewritten if profile is newer''' + """test cache is rewritten if profile is newer""" self._generate_cache_file() profile_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res @@ -445,7 +445,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(profile_mtime, stat.st_mtime) def test_abstraction_newer_rewrites_cache(self): - '''test cache is rewritten if abstraction is newer''' + """test cache is rewritten if abstraction is newer""" self._generate_cache_file() abstraction_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res @@ -462,7 +462,7 @@ class AAParserCachingTests(AAParserCachingCommon): self.assertEqual(abstraction_mtime, stat.st_mtime) def test_parser_newer_uses_cache(self): - '''test cache is not skipped if parser is newer''' + """test cache is not skipped if parser is newer""" self._generate_cache_file() @@ -488,20 +488,20 @@ class AAParserCachingTests(AAParserCachingCommon): self.assert_path_exists(cache_file, expected=False) def test_cache_purge_removes_features_file(self): - '''test cache --purge-cache removes .features file''' + """test cache --purge-cache removes .features file""" self._purge_cache_test('.features') def test_cache_purge_removes_cache_file(self): - '''test cache --purge-cache removes profile cache file''' + """test cache --purge-cache removes profile cache file""" self._purge_cache_test(PROFILE) def test_cache_purge_removes_other_cache_files(self): - '''test cache --purge-cache removes other cache files''' + """test cache --purge-cache removes other cache files""" self._purge_cache_test('monkey') class AAParserAltCacheTests(AAParserCachingTests): - '''Same tests as above, but with an alternate cache location specified on the command line''' + """Same tests as above, but with an alternate cache location specified on the command line""" check_orig_cache = True def setUp(self): @@ -521,7 +521,7 @@ class AAParserAltCacheTests(AAParserCachingTests): super().tearDown() def test_cache_purge_leaves_original_cache_alone(self): - '''test cache purging only touches alt cache''' + """test cache purging only touches alt cache""" # skip tearDown check to ensure non-alt cache is empty self.check_orig_cache = False diff --git a/parser/tst/gen-xtrans.py b/parser/tst/gen-xtrans.py index 70b725052..c526cc228 100755 --- a/parser/tst/gen-xtrans.py +++ b/parser/tst/gen-xtrans.py @@ -74,7 +74,7 @@ def gen_list(): def test_gen_list(): - ''' test if gen_list returns the expected output ''' + """test if gen_list returns the expected output""" expected = "pix pux px Pix Pux Px cix cux cx Cix Cux Cx ux ix".split() actual = gen_list() diff --git a/parser/tst/testlib.py b/parser/tst/testlib.py index eef5d6f52..eeba76478 100644 --- a/parser/tst/testlib.py +++ b/parser/tst/testlib.py @@ -41,9 +41,9 @@ class AANoCleanupMetaClass(type): @classmethod def keep_on_fail(cls, unittest_func): - '''wrapping function for unittest testcases to detect failure + """wrapping function for unittest testcases to detect failure and leave behind test files in tearDown(); to be used as - a decorator''' + a decorator""" def new_unittest_func(self): try: @@ -58,17 +58,17 @@ class AANoCleanupMetaClass(type): class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass): - '''Stub class for use by test scripts''' + """Stub class for use by test scripts""" debug = False do_cleanup = True def run_cmd_check(self, command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=120, expected_rc=0, expected_string=None): - '''Wrapper around run_cmd that checks the rc code against + """Wrapper around run_cmd that checks the rc code against expected_rc and for expected strings in the output if passed. The valgrind tests generally don't care what the rc is as long as it's not a specific set of return codes, - so can't push the check directly into run_cmd().''' + so can't push the check directly into run_cmd().""" rc, report = self.run_cmd(command, input, stderr, stdout, stdin, timeout) self.assertEqual(rc, expected_rc, "Got return code %d, expected %d\nCommand run: %s\nOutput: %s" % (rc, expected_rc, (' '.join(command)), report)) if expected_string: @@ -77,8 +77,8 @@ class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass): def run_cmd(self, command, input=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=None, timeout=120): - '''Try to execute given command (array) and return its stdout, or - return a textual error if it failed.''' + """Try to execute given command (array) and return its stdout, or + return a textual error if it failed.""" if self.debug: print('\n===> Running command: \'%s\'' % (' '.join(command))) @@ -90,7 +90,7 @@ class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass): def _run_cmd(self, command, input=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=None, timeout=120): - '''Try to execute given command (array) and return its rc, stdout, and stderr as a tuple''' + """Try to execute given command (array) and return its rc, stdout, and stderr as a tuple""" try: sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, @@ -143,7 +143,7 @@ class TimeoutFunction: def filesystem_time_resolution(): - '''detect whether the filesystem stores subsecond timestamps''' + """detect whether the filesystem stores subsecond timestamps""" default_diff = 0.1 result = (True, default_diff) @@ -198,7 +198,7 @@ def touch(path): def write_file(directory, file, contents): - '''construct path, write contents to it, and return the constructed path''' + """construct path, write contents to it, and return the constructed path""" path = os.path.join(directory, file) with open(path, 'w+') as f: f.write(contents) diff --git a/parser/tst/valgrind_simple.py b/parser/tst/valgrind_simple.py index a4c9bbf92..c30884a7e 100755 --- a/parser/tst/valgrind_simple.py +++ b/parser/tst/valgrind_simple.py @@ -57,7 +57,7 @@ class AAParserValgrindTests(testlib.AATestTemplate): def find_testcases(testdir): - '''dig testcases out of passed directory''' + """dig testcases out of passed directory""" for (fdir, direntries, files) in os.walk(testdir): for f in files: @@ -66,7 +66,7 @@ def find_testcases(testdir): def create_suppressions(): - '''generate valgrind suppressions file''' + """generate valgrind suppressions file""" with NamedTemporaryFile("w+", suffix='.suppressions', prefix='aa-parser-valgrind', delete=False) as temp_file: temp_file.write(VALGRIND_SUPPRESSIONS) return temp_file.name diff --git a/utils/aa-easyprof b/utils/aa-easyprof index 7eec8e950..20e6b43dd 100755 --- a/utils/aa-easyprof +++ b/utils/aa-easyprof @@ -20,7 +20,7 @@ enable_aa_exception_handler() if __name__ == "__main__": def usage(): - '''Return usage information''' + """Return usage information""" return 'USAGE: %s [options] ' % \ os.path.basename(sys.argv[0]) diff --git a/utils/aa-notify b/utils/aa-notify index 438cf241f..790dd5641 100755 --- a/utils/aa-notify +++ b/utils/aa-notify @@ -51,8 +51,8 @@ import LibAppArmor # C-library to parse one log line def get_user_login(): - '''Portable function to get username. Should not trigger any - "OSError: [Errno 25] Inappropriate ioctl for device" errors in Giltab-CI''' + """Portable function to get username. Should not trigger any + "OSError: [Errno 25] Inappropriate ioctl for device" errors in Giltab-CI""" if os.name == "posix": username = pwd.getpwuid(os.geteuid()).pw_name else: @@ -159,7 +159,7 @@ def show_entries_since_days(logfile, since_days): def follow_apparmor_events(logfile, wait=0): - '''Follow AppArmor events and yield relevant entries until process stops''' + """Follow AppArmor events and yield relevant entries until process stops""" # If wait was given as argument but was type None (from ArgumentParser) # ensure it's type int and zero @@ -239,7 +239,7 @@ def reopen_logfile_if_needed(logfile, logdata, log_inode, log_size): def get_apparmor_events(logfile, since=0): - '''Read audit events from log source and yield all relevant events''' + """Read audit events from log source and yield all relevant events""" # Get logdata from file # @TODO Implement more log sources in addition to just the logfile @@ -253,7 +253,7 @@ def get_apparmor_events(logfile, since=0): def parse_logdata(logsource): - '''Traverse any iterable log source and extract relevant AppArmor events''' + """Traverse any iterable log source and extract relevant AppArmor events""" RE_audit_time_id = '(msg=)?audit\([\d\.\:]+\):\s+' # 'audit(1282626827.320:411): ' RE_kernel_time = '\[[\d\.\s]+\]' # '[ 1612.746129]' @@ -287,7 +287,7 @@ def parse_logdata(logsource): def drop_privileges(): - '''If running as root, drop privileges to USER if known, or fall-back to nobody_user/group''' + """If running as root, drop privileges to USER if known, or fall-back to nobody_user/group""" if os.geteuid() == 0: @@ -315,7 +315,7 @@ def drop_privileges(): def raise_privileges(): - '''If was running as user with saved user ID 0, raise back to root privileges''' + """If was running as user with saved user ID 0, raise back to root privileges""" if os.geteuid() != 0 and original_effective_user == 0: @@ -336,10 +336,10 @@ def read_notify_conf(path, shell_config): def main(): - ''' + """ Main function of aa-notify that parses command line arguments and starts the requested operations. - ''' + """ global _, debug_logger, config, args global debug_docs_url, nobody_user, original_effective_user, timeformat diff --git a/utils/aa-unconfined b/utils/aa-unconfined index 43f0b7954..cf13c0abf 100755 --- a/utils/aa-unconfined +++ b/utils/aa-unconfined @@ -49,12 +49,12 @@ if not aa_mountpoint: def get_all_pids(): - '''Return a set of all pids via walking /proc''' + """Return a set of all pids via walking /proc""" return set(filter(lambda x: re.search(r"^\d+$", x), aa.get_subdirectories("/proc"))) def get_pids_ss(ss='ss'): - '''Get a set of pids listening on network sockets via ss(8)''' + """Get a set of pids listening on network sockets via ss(8)""" regex_lines = re.compile(r"^(tcp|udp|raw|p_dgr)\s.+\s+users:(?P\(\(.*\)\))$") regex_users_pids = re.compile(r'(\("[^"]+",(pid=)?(\d+),[^)]+\))') @@ -80,7 +80,7 @@ def get_pids_ss(ss='ss'): def get_pids_netstat(netstat='netstat'): - '''Get a set of pids listening on network sockets via netstat(8)''' + """Get a set of pids listening on network sockets via netstat(8)""" regex_tcp_udp = re.compile(r"^(tcp|udp|raw)6?\s+\d+\s+\d+\s+\S+\:(\d+)\s+\S+\:(\*|\d+)\s+(LISTEN|\d+|\s+)\s+(?P\d+)\/(\S+)") cmd = [netstat, '-nlp', '--protocol', 'inet,inet6'] diff --git a/utils/apparmor/aa.py b/utils/apparmor/aa.py index c9262f441..b28eb32dd 100644 --- a/utils/apparmor/aa.py +++ b/utils/apparmor/aa.py @@ -106,10 +106,10 @@ helpers = dict() # Preserve this between passes # was our def reset_aa(): - ''' Reset the most important global variables + """Reset the most important global variables - Used by aa-mergeprof and some tests. - ''' + Used by aa-mergeprof and some tests. + """ global aa, include, active_profiles, original_aa @@ -241,7 +241,7 @@ def get_profile_filename_from_attachment(profile, get_new=False): def get_new_profile_filename(profile): - '''Compose filename for a new profile''' + """Compose filename for a new profile""" if profile.startswith('/'): # Remove leading / filename = profile[1:] @@ -347,7 +347,7 @@ def head(file): def get_output(params): - '''Runs the program with the given args and returns the return code and stdout (as list of lines)''' + """Runs the program with the given args and returns the return code and stdout (as list of lines)""" try: # Get the output of the program output = subprocess.check_output(params) # nosec @@ -422,12 +422,12 @@ def handle_binfmt(profile, path): def get_interpreter_and_abstraction(exec_target): - '''Check if exec_target is a script. + """Check if exec_target is a script. If a hashbang is found, check if we have an abstraction for it. Returns (interpreter_path, abstraction) - interpreter_path is none if exec_target is not a script or doesn't have a hashbang line - - abstraction is None if no matching abstraction exists''' + - abstraction is None if no matching abstraction exists""" if not os.path.exists(exec_target): aaui.UI_Important(_('Execute target %s does not exist!') % exec_target) @@ -527,7 +527,7 @@ def confirm_and_abort(): def get_profile(prof_name): - '''search for inactive/extra profile, and ask if it should be used''' + """search for inactive/extra profile, and ask if it should be used""" if not extra_profiles.profiles.get(prof_name, False): return None # no inactive profile found @@ -759,7 +759,7 @@ def build_x_functions(default, options, exec_toggle): def ask_addhat(hashlog): - '''ask the user about change_hat events (requests to add a hat)''' + """ask the user about change_hat events (requests to add a hat)""" for aamode in hashlog: for profile in hashlog[aamode]: @@ -827,7 +827,7 @@ def ask_addhat(hashlog): def ask_exec(hashlog): - '''ask the user about exec events (requests to execute another program) and which exec mode to use''' + """ask the user about exec events (requests to execute another program) and which exec mode to use""" for aamode in hashlog: for full_profile in hashlog[aamode]: @@ -1183,18 +1183,18 @@ def ask_the_questions(log_dict): def ask_rule_questions(prof_events, profile_name, the_profile, r_types): - ''' ask questions about rules to add to a single profile/hat + """ask questions about rules to add to a single profile/hat - parameter typical value - prof_events log_dict[aamode][full_profile] - profile_name profile name (possible profile//hat) - the_profile aa[profile][hat] -- will be modified - r_types ruletypes + parameter typical value + prof_events log_dict[aamode][full_profile] + profile_name profile name (possible profile//hat) + the_profile aa[profile][hat] -- will be modified + r_types ruletypes - returns: - changed True if the profile was changed - end_profiling True if the user wants to end profiling - ''' + returns: + changed True if the profile was changed + end_profiling True if the user wants to end profiling + """ changed = False @@ -1358,21 +1358,21 @@ def selection_to_rule_obj(rule_obj, selection): def set_options_audit_mode(rule_obj, options): - '''change audit state in options (proposed rules) to audit state in rule_obj. + """change audit state in options (proposed rules) to audit state in rule_obj. #include options will be kept unchanged - ''' + """ return set_options_mode(rule_obj, options, 'audit') def set_options_owner_mode(rule_obj, options): - '''change owner state in options (proposed rules) to owner state in rule_obj. + """change owner state in options (proposed rules) to owner state in rule_obj. #include options will be kept unchanged - ''' + """ return set_options_mode(rule_obj, options, 'owner') def set_options_mode(rule_obj, options, what): - ''' helper function for set_options_audit_mode() and set_options_owner_mode''' + """helper function for set_options_audit_mode() and set_options_owner_mode""" new_options = [] for rule in options: @@ -1447,7 +1447,7 @@ def delete_all_duplicates(profile, incname, r_types): def ask_conflict_mode(old_profile, merge_profile): - '''ask user about conflicting exec rules''' + """ask user about conflicting exec rules""" for oldrule in old_profile['file'].rules: conflictingrules = merge_profile['file'].get_exec_conflict_rules(oldrule) @@ -1482,10 +1482,10 @@ def ask_conflict_mode(old_profile, merge_profile): def match_includes(profile, rule_type, rule_obj): - ''' propose abstractions that allow the given rule_obj + """propose abstractions that allow the given rule_obj - Note: This function will return relative paths for includes inside profile_dir - ''' + Note: This function will return relative paths for includes inside profile_dir + """ newincludes = [] for incname in include.keys(): @@ -1514,7 +1514,7 @@ def match_includes(profile, rule_type, rule_obj): def valid_include(incname): - ''' check if the given include file exists or is whitelisted in custom_includes ''' + """check if the given include file exists or is whitelisted in custom_includes""" if cfg['settings']['custom_includes']: for incm in cfg['settings']['custom_includes'].split(): if incm == incname: @@ -1529,7 +1529,7 @@ def valid_include(incname): def set_logfile(filename): - ''' set logfile to a) the specified filename or b) if not given, the first existing logfile from logprof.conf''' + """set logfile to a) the specified filename or b) if not given, the first existing logfile from logprof.conf""" global logfile @@ -2099,7 +2099,7 @@ def parse_profile_data(data, file, do_include, in_preamble): def match_line_against_rule_classes(line, profile, file, lineno, in_preamble): - ''' handle all lines handled by *Rule classes ''' + """handle all lines handled by *Rule classes""" for rule_name in ( 'abi', @@ -2140,7 +2140,7 @@ def match_line_against_rule_classes(line, profile, file, lineno, in_preamble): def merged_to_split(profile_data): - ''' (temporary) helper function to convert a list of profile['foo//bar'] profiles into compat['foo']['bar']''' + """(temporary) helper function to convert a list of profile['foo//bar'] profiles into compat['foo']['bar']""" compat = hasher() for prof in profile_data: profile, hat = split_name(prof) # XXX limited to two levels to avoid an Exception on nested child profiles or nested null-* @@ -2150,7 +2150,7 @@ def merged_to_split(profile_data): def split_to_merged(profile_data): - ''' (temporary) helper function to convert a traditional compat['foo']['bar'] to a profile['foo//bar'] list ''' + """(temporary) helper function to convert a traditional compat['foo']['bar'] to a profile['foo//bar'] list""" merged = {} @@ -2307,7 +2307,7 @@ def write_profile(profile, is_attachment=False): def include_list_recursive(profile, in_preamble=False): - ''' get a list of all includes in a profile and its included files ''' + """get a list of all includes in a profile and its included files""" includelist = profile['inc_ie'].get_all_full_paths(profile_dir) full_list = [] @@ -2348,7 +2348,7 @@ def is_known_rule(profile, rule_type, rule_obj): def get_file_perms(profile, path, audit, deny): - '''get the current permissions for the given path''' + """get the current permissions for the given path""" perms = profile['file'].get_perms_for_path(path, audit, deny) @@ -2372,10 +2372,10 @@ def get_file_perms(profile, path, audit, deny): def propose_file_rules(profile_obj, rule_obj): - '''Propose merged file rules based on the existing profile and the log events + """Propose merged file rules based on the existing profile and the log events - permissions get merged - matching paths from existing rules, common_glob() and user_globs get proposed - - IMPORTANT: modifies rule_obj.original_perms and rule_obj.perms''' + - IMPORTANT: modifies rule_obj.original_perms and rule_obj.perms""" options = [] original_path = rule_obj.path.regex @@ -2423,7 +2423,7 @@ def reload_base(bin_path): def reload_profile(prof_filename, raise_exc=False): - ''' run apparmor_parser to reload the given profile file ''' + """run apparmor_parser to reload the given profile file""" ret, out = cmd((parser, '-I%s' % profile_dir, '--base', profile_dir, '-r', prof_filename)) @@ -2455,9 +2455,9 @@ def get_include_data(filename): def include_dir_filelist(include_name): - '''returns a list of files in the given include_name directory, + """returns a list of files in the given include_name directory, except skippable files. - ''' + """ if not include_name.startswith('/'): raise AppArmorBug('incfile %s not starting with /' % include_name) diff --git a/utils/apparmor/aare.py b/utils/apparmor/aare.py index e31b378aa..b01e114e1 100644 --- a/utils/apparmor/aare.py +++ b/utils/apparmor/aare.py @@ -18,11 +18,11 @@ from apparmor.common import convert_regexp, AppArmorBug, AppArmorException class AARE: - '''AARE (AppArmor Regular Expression) wrapper class''' + """AARE (AppArmor Regular Expression) wrapper class""" def __init__(self, regex, is_path, log_event=None): - '''create an AARE instance for the given AppArmor regex - If is_path is true, the regex is expected to be a path and therefore must start with / or a variable.''' + """create an AARE instance for the given AppArmor regex + If is_path is true, the regex is expected to be a path and therefore must start with / or a variable.""" # using the specified variables when matching. if is_path: @@ -44,7 +44,7 @@ class AARE: # self.variables = variables # XXX def __repr__(self): - '''returns a "printable" representation of AARE''' + """returns a "printable" representation of AARE""" return "AARE('%s')" % self.regex def __deepcopy__(self, memo): @@ -59,7 +59,7 @@ class AARE: plain_path = re.compile('^[0-9a-zA-Z/._-]+$') def match(self, expression): - '''check if the given expression (string or AARE) matches the regex''' + """check if the given expression (string or AARE) matches the regex""" if type(expression) == AARE: if expression.orig_regex: @@ -78,7 +78,7 @@ class AARE: return bool(self._regex_compiled.match(expression)) def is_equal(self, expression): - '''check if the given expression is equal''' + """check if the given expression is equal""" if type(expression) == AARE: return self.regex == expression.regex @@ -88,7 +88,7 @@ class AARE: raise AppArmorBug('AARE.is_equal() called with unknown object: %s' % str(expression)) def glob_path(self): - '''Glob the given file or directory path''' + """Glob the given file or directory path""" if self.regex[-1] == '/': if self.regex[-4:] == '/**/' or self.regex[-3:] == '/*/': # /foo/**/ and /foo/*/ => /**/ @@ -116,8 +116,8 @@ class AARE: return AARE(newpath, False) def glob_path_withext(self): - '''Glob given file path with extension - Files without extensions and directories won't be changed''' + """Glob given file path with extension + Files without extensions and directories won't be changed""" # match /**.ext and /*.ext match = re.search('/\*{1,2}(\.[^/]+)$', self.regex) if match: @@ -140,7 +140,7 @@ class AARE: def convert_expression_to_aare(expression): - '''convert an expression (taken from audit.log) to an AARE string''' + """convert an expression (taken from audit.log) to an AARE string""" aare_escape_chars = ['\\', '?', '*', '[', ']', '{', '}', '"', '!'] for char in aare_escape_chars: diff --git a/utils/apparmor/common.py b/utils/apparmor/common.py index 71d1c737f..60363240e 100644 --- a/utils/apparmor/common.py +++ b/utils/apparmor/common.py @@ -29,7 +29,7 @@ DEBUGGING = False # Utility classes # class AppArmorException(Exception): - '''This class represents AppArmor exceptions''' + """This class represents AppArmor exceptions""" def __init__(self, value): self.value = value @@ -38,14 +38,14 @@ class AppArmorException(Exception): class AppArmorBug(Exception): - '''This class represents AppArmor exceptions "that should never happen"''' + """This class represents AppArmor exceptions "that should never happen".""" # # Utility functions # def error(out, exit_code=1, do_exit=True): - '''Print error message and exit''' + """Print error message and exit""" try: print("ERROR: %s" % (out), file=sys.stderr) except IOError: @@ -56,7 +56,7 @@ def error(out, exit_code=1, do_exit=True): def warn(out): - '''Print warning message''' + """Print warning message""" try: print("WARN: %s" % (out), file=sys.stderr) except IOError: @@ -64,7 +64,7 @@ def warn(out): def msg(out, output=sys.stdout): - '''Print message''' + """Print message""" try: print("%s" % (out), file=output) except IOError: @@ -72,7 +72,7 @@ def msg(out, output=sys.stdout): def debug(out): - '''Print debug message''' + """Print debug message""" global DEBUGGING if DEBUGGING: try: @@ -87,7 +87,7 @@ def recursive_print(src, dpth=0, key=''): # based on code "stolen" from Scott S-Allen / MIT License # http://code.activestate.com/recipes/578094-recursively-print-nested-dictionaries/ - """ Recursively prints nested elements.""" + """Recursively prints nested elements.""" tabs = ' ' * dpth * 4 # or 2 or 8 or... if isinstance(src, dict): @@ -116,7 +116,7 @@ def recursive_print(src, dpth=0, key=''): def cmd(command): - '''Try to execute the given command.''' + """Try to execute the given command.""" debug(command) try: sp = subprocess.Popen(command, stdout=subprocess.PIPE, @@ -130,7 +130,7 @@ def cmd(command): def cmd_pipe(command1, command2): - '''Try to pipe command1 into command2.''' + """Try to pipe command1 into command2.""" try: sp1 = subprocess.Popen(command1, stdout=subprocess.PIPE) sp2 = subprocess.Popen(command2, stdin=sp1.stdout) @@ -143,7 +143,7 @@ def cmd_pipe(command1, command2): def valid_path(path): - '''Valid path''' + """Valid path""" # No relative paths m = "Invalid path: %s" % (path) if not path.startswith('/'): @@ -163,7 +163,7 @@ def valid_path(path): def get_directory_contents(path): - '''Find contents of the given directory''' + """Find contents of the given directory""" if not valid_path(path): return None @@ -195,17 +195,17 @@ def is_skippable_file(path): def open_file_read(path, encoding='UTF-8'): - '''Open specified file read-only''' + """Open specified file read-only""" return open_file_anymode('r', path, encoding) def open_file_write(path): - '''Open specified file in write/overwrite mode''' + """Open specified file in write/overwrite mode""" return open_file_anymode('w', path, 'UTF-8') def open_file_anymode(mode, path, encoding='UTF-8'): - '''Crash-resistant wrapper to open a specified file in specified mode''' + """Crash-resistant wrapper to open a specified file in specified mode""" # This avoids a crash when reading a logfile with special characters that # are not utf8-encoded (for example a latin1 "รถ"), and also avoids crashes @@ -214,7 +214,7 @@ def open_file_anymode(mode, path, encoding='UTF-8'): def readkey(): - '''Returns the pressed key''' + """Returns the pressed key""" fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: @@ -227,7 +227,7 @@ def readkey(): def hasher(): - '''A neat alternative to perl's hash reference''' + """A neat alternative to perl's hash reference""" # Creates a dictionary for any depth and returns empty dictionary otherwise # WARNING: when reading non-existing sub-dicts, empty dicts will be added. # This might cause strange effects when using .keys() @@ -286,7 +286,7 @@ def split_name(full_profile): def combine_profname(name_parts): - ''' combine name_parts (main profile, child) into a joint main//child profile name ''' + """combine name_parts (main profile, child) into a joint main//child profile name""" if type(name_parts) is not list: raise AppArmorBug('combine_name() called with parameter of type %s, must be a list' % type(name_parts)) @@ -299,12 +299,12 @@ def combine_profname(name_parts): class DebugLogger: - '''Unified debug facility. Logs to file or stderr. + """Unified debug facility. Logs to file or stderr. Does not log anything by default. Will only log if environment variable LOGPROF_DEBUG is set to a number between 1 and 3 or if method activateStderr is run. - ''' + """ def __init__(self, module_name=__name__): self.debugging = False self.debug_level = logging.DEBUG diff --git a/utils/apparmor/easyprof.py b/utils/apparmor/easyprof.py index 5c6aa29dd..fd7e11932 100644 --- a/utils/apparmor/easyprof.py +++ b/utils/apparmor/easyprof.py @@ -29,7 +29,7 @@ DEBUGGING = False # TODO: move this out to a utilities library # def error(out, exit_code=1, do_exit=True): - '''Print error message and exit''' + """Print error message and exit""" try: sys.stderr.write("ERROR: %s\n" % (out)) except IOError: @@ -40,7 +40,7 @@ def error(out, exit_code=1, do_exit=True): def warn(out): - '''Print warning message''' + """Print warning message""" try: sys.stderr.write("WARN: %s\n" % (out)) except IOError: @@ -48,7 +48,7 @@ def warn(out): def msg(out, output=sys.stdout): - '''Print message''' + """Print message""" try: sys.stdout.write("%s\n" % (out)) except IOError: @@ -56,7 +56,7 @@ def msg(out, output=sys.stdout): def cmd(command): - '''Try to execute the given command.''' + """Try to execute the given command.""" debug(command) try: sp = subprocess.Popen(command, stdout=subprocess.PIPE, @@ -69,7 +69,7 @@ def cmd(command): def debug(out): - '''Print debug message''' + """Print debug message""" if DEBUGGING: try: sys.stderr.write("DEBUG: %s\n" % (out)) @@ -78,7 +78,7 @@ def debug(out): def valid_binary_path(path): - '''Validate name''' + """Validate name""" try: a_path = os.path.abspath(path) except Exception: @@ -101,7 +101,7 @@ def valid_binary_path(path): def valid_variable(v): - '''Validate variable name''' + """Validate variable name""" debug("Checking '%s'" % v) try: (key, value) = v.split('=') @@ -126,7 +126,7 @@ def valid_variable(v): def valid_path(path, relative_ok=False): - '''Valid path''' + """Valid path""" m = "Invalid path: %s" % (path) if not relative_ok and not path.startswith('/'): debug("%s (relative)" % (m)) @@ -155,19 +155,19 @@ def valid_path(path, relative_ok=False): def _is_safe(s): - '''Known safe regex''' + """Known safe regex""" if re.search(r'^[a-zA-Z_0-9\-\.]+$', s): return True return False def valid_policy_vendor(s): - '''Verify the policy vendor''' + """Verify the policy vendor""" return _is_safe(s) def valid_policy_version(v): - '''Verify the policy version''' + """Verify the policy version""" try: float(v) except ValueError: @@ -178,7 +178,7 @@ def valid_policy_version(v): def valid_template_name(s, strict=False): - '''Verify the template name''' + """Verify the template name""" if not strict and s.startswith('/'): if not valid_path(s): return False @@ -187,12 +187,12 @@ def valid_template_name(s, strict=False): def valid_abstraction_name(s): - '''Verify the template name''' + """Verify the template name""" return _is_safe(s) def valid_profile_name(s): - '''Verify the profile name''' + """Verify the profile name""" # profile name specifies path if s.startswith('/'): if not valid_path(s): @@ -207,12 +207,12 @@ def valid_profile_name(s): def valid_policy_group_name(s): - '''Verify policy group name''' + """Verify policy group name""" return _is_safe(s) def get_directory_contents(path): - '''Find contents of the given directory''' + """Find contents of the given directory""" if not valid_path(path): return None @@ -225,7 +225,7 @@ def get_directory_contents(path): def verify_policy(policy, exe, base=None, include=None): - '''Verify policy compiles''' + """Verify policy compiles""" if not exe: warn("Could not find apparmor_parser. Skipping verify") return True @@ -257,7 +257,7 @@ def verify_policy(policy, exe, base=None, include=None): class AppArmorEasyProfile: - '''Easy profile class''' + """Easy profile class""" def __init__(self, binary, opt): verify_options(opt) opt.ensure_value("conffile", "/etc/apparmor/easyprof.conf") @@ -363,7 +363,7 @@ class AppArmorEasyProfile: self.policy_groups.append(f) def _get_defaults(self): - '''Read in defaults from configuration''' + """Read in defaults from configuration""" if not os.path.exists(self.conffile): raise AppArmorException("Could not find '%s'" % self.conffile) @@ -391,16 +391,16 @@ class AppArmorEasyProfile: raise AppArmorException("Could not find '%s'" % self.dirs[k]) def set_name(self, name): - '''Set name of policy''' + """Set name of policy""" self.name = name def get_template(self): - '''Get contents of current template''' + """Get contents of current template""" with open(self.template) as f: return f.read() def set_template(self, template, allow_abs_path=True): - '''Set current template''' + """Set current template""" if "../" in template: raise AppArmorException('template "%s" contains "../" escape path' % (template)) elif template.startswith('/') and not allow_abs_path: @@ -427,11 +427,11 @@ class AppArmorEasyProfile: raise AppArmorException('%s does not exist' % (template)) def get_templates(self): - '''Get list of all available templates by filename''' + """Get list of all available templates by filename""" return self.templates def get_policygroup(self, policygroup): - '''Get contents of specific policygroup''' + """Get contents of specific policygroup""" p = policygroup if not p.startswith('/'): sys_p = os.path.join(self.dirs['policygroups'], p) @@ -450,7 +450,7 @@ class AppArmorEasyProfile: return f.read() def set_policygroup(self, policygroups): - '''Set policygroups''' + """Set policygroups""" self.policy_groups = [] if policygroups is not None: for p in policygroups.split(','): @@ -475,11 +475,11 @@ class AppArmorEasyProfile: raise AppArmorException('%s does not exist' % (p)) def get_policy_groups(self): - '''Get list of all policy groups by filename''' + """Get list of all policy groups by filename""" return self.policy_groups def gen_abstraction_rule(self, abstraction): - '''Generate an abstraction rule''' + """Generate an abstraction rule""" base = os.path.join(self.parser_base, "abstractions", abstraction) if not os.path.exists(base): if not self.parser_include: @@ -492,7 +492,7 @@ class AppArmorEasyProfile: return "#include " % abstraction def gen_variable_declaration(self, dec): - '''Generate a variable declaration''' + """Generate a variable declaration""" if not valid_variable(dec): raise AppArmorException("Invalid variable declaration '%s'" % dec) # Make sure we always quote @@ -534,7 +534,7 @@ class AppArmorEasyProfile: copyright=None, no_verify=False): def find_prefix(t, s): - '''Calculate whitespace prefix based on occurrence of s in t''' + """Calculate whitespace prefix based on occurrence of s in t""" pat = re.compile(r'^ *%s' % s) p = "" for line in t.splitlines(): @@ -648,7 +648,7 @@ class AppArmorEasyProfile: return policy def output_policy(self, params, count=0, dir=None): - '''Output policy''' + """Output policy""" policy = self.gen_policy(**params) if not dir: if count: @@ -681,7 +681,7 @@ class AppArmorEasyProfile: os.rename(f.name, out_fn) def gen_manifest(self, params): - '''Take params list and output a JSON file''' + """Take params list and output a JSON file""" d = dict() d['security'] = dict() d['security']['profiles'] = dict() @@ -749,7 +749,7 @@ def print_files(files): def check_manifest_conflict_args(option, opt_str, value, parser): - '''Check for -m/--manifest with conflicting args''' + """Check for -m/--manifest with conflicting args""" conflict_args = ['abstractions', 'read_path', 'write_path', @@ -772,7 +772,7 @@ def check_manifest_conflict_args(option, opt_str, value, parser): def check_for_manifest_arg(option, opt_str, value, parser): - '''Check for -m/--manifest with conflicting args''' + """Check for -m/--manifest with conflicting args""" if parser.values.manifest: raise optparse.OptionValueError( "can't use --%s with --manifest argument" % opt_str.lstrip('-')) @@ -780,7 +780,7 @@ def check_for_manifest_arg(option, opt_str, value, parser): def check_for_manifest_arg_append(option, opt_str, value, parser): - '''Check for -m/--manifest with conflicting args (with append)''' + """Check for -m/--manifest with conflicting args (with append)""" if parser.values.manifest: raise optparse.OptionValueError( "can't use --%s with --manifest argument" % opt_str.lstrip('-')) @@ -788,7 +788,7 @@ def check_for_manifest_arg_append(option, opt_str, value, parser): def add_parser_policy_args(parser): - '''Add parser arguments''' + """Add parser arguments""" parser.add_option("--parser", dest="parser_path", help="The path to the profile parser used for verification", @@ -873,7 +873,7 @@ def add_parser_policy_args(parser): def parse_args(args=None, parser=None): - '''Parse arguments''' + """Parse arguments""" global DEBUGGING if parser is None: @@ -979,7 +979,7 @@ def parse_args(args=None, parser=None): def gen_policy_params(binary, opt): - '''Generate parameters for gen_policy''' + """Generate parameters for gen_policy""" params = dict(binary=binary) if not binary and not opt.profile_name: @@ -1021,8 +1021,8 @@ def gen_policy_params(binary, opt): def parse_manifest(manifest, opt_orig): - '''Take a JSON manifest as a string and updates options, returning an - updated binary. Note that a JSON file may contain multiple profiles.''' + """Take a JSON manifest as a string and updates options, returning an + updated binary. Note that a JSON file may contain multiple profiles.""" try: m = json.loads(manifest) @@ -1108,7 +1108,7 @@ def parse_manifest(manifest, opt_orig): def verify_options(opt, strict=False): - '''Make sure our options are valid''' + """Make sure our options are valid""" if hasattr(opt, 'binary') and opt.binary and not valid_path(opt.binary): raise AppArmorException("Invalid binary '%s'" % opt.binary) if (hasattr(opt, 'profile_name') and opt.profile_name is not None @@ -1150,7 +1150,7 @@ def verify_options(opt, strict=False): def verify_manifest(params, args=None): - '''Verify manifest for safe and unsafe options''' + """Verify manifest for safe and unsafe options""" err_str = "" (opt, args) = parse_args(args) fake_easyp = AppArmorEasyProfile(None, opt) diff --git a/utils/apparmor/fail.py b/utils/apparmor/fail.py index ddd9cb42a..ece6efc43 100644 --- a/utils/apparmor/fail.py +++ b/utils/apparmor/fail.py @@ -20,12 +20,12 @@ from apparmor.common import error # Exception handling # def handle_exception(*exc_info): - '''Used as exception handler in the aa-* tools. + """Used as exception handler in the aa-* tools. For AppArmorException (used for profile syntax errors etc.), print only the exceptions value because a backtrace is superfluous and would confuse users. For other exceptions, print backtrace and save detailed information in a file in /tmp/ (including variable content etc.) to make debugging easier. - ''' + """ (ex_cls, ex, tb) = exc_info if ex_cls.__name__ == 'AppArmorException': # I didn't find a way to get this working with isinstance() :-/ @@ -49,5 +49,5 @@ def handle_exception(*exc_info): def enable_aa_exception_handler(): - '''Setup handle_exception() as exception handler''' + """Setup handle_exception() as exception handler""" sys.excepthook = handle_exception diff --git a/utils/apparmor/logparser.py b/utils/apparmor/logparser.py index ae475ec27..ee7e0c8ed 100644 --- a/utils/apparmor/logparser.py +++ b/utils/apparmor/logparser.py @@ -41,7 +41,7 @@ class ReadLog: self.next_log_entry = None def init_hashlog(self, aamode, profile): - ''' initialize self.hashlog[aamode][profile] for all rule types''' + """initialize self.hashlog[aamode][profile] for all rule types""" if profile in self.hashlog[aamode].keys(): return # already initialized, don't overwrite existing data diff --git a/utils/apparmor/notify.py b/utils/apparmor/notify.py index 5cce6959d..84aaaf3e1 100644 --- a/utils/apparmor/notify.py +++ b/utils/apparmor/notify.py @@ -22,7 +22,7 @@ debug_logger = DebugLogger('apparmor.notify') def sane_timestamp(timestamp): - ''' Check if the given timestamp is in a date range that makes sense for a wtmp file ''' + """Check if the given timestamp is in a date range that makes sense for a wtmp file""" if timestamp < 946681200: # 2000-01-01 return False @@ -33,7 +33,7 @@ def sane_timestamp(timestamp): def get_last_login_timestamp(username, filename='/var/log/wtmp'): - '''Directly read wtmp and get last login for user as epoch timestamp''' + """Directly read wtmp and get last login for user as epoch timestamp""" timestamp = 0 last_login = 0 diff --git a/utils/apparmor/profile_list.py b/utils/apparmor/profile_list.py index 0e6884e95..b6c473bfa 100644 --- a/utils/apparmor/profile_list.py +++ b/utils/apparmor/profile_list.py @@ -36,12 +36,12 @@ header_rule_write_order = ('abi', 'alias', 'inc_ie', 'variable', 'boolean') # T class ProfileList: - ''' Stores the preamble section and the list of profile(s) (both name and - attachment) that live in profile files. + """Stores the preamble section and the list of profile(s) (both name and + attachment) that live in profile files. - Also allows "reverse" lookups to find out in which file a profile - lives. - ''' + Also allows "reverse" lookups to find out in which file a profile + lives. + """ def __init__(self): self.profile_names = {} # profile name -> filename @@ -65,7 +65,7 @@ class ProfileList: self.files[filename][rule] = preamble_ruletypes[rule]['ruleset']() def add_profile(self, filename, profile_name, attachment, prof_storage=None): - ''' Add the given profile and attachment to the list ''' + """Add the given profile and attachment to the list""" if not filename: raise AppArmorBug('Empty filename given to ProfileList') @@ -103,14 +103,14 @@ class ProfileList: self.profiles[attachment] = prof_storage def add_rule(self, filename, ruletype, rule): - ''' Store the given rule for the given profile filename preamble ''' + """Store the given rule for the given profile filename preamble""" self.init_file(filename) self.files[filename][ruletype].add(rule) def add_abi(self, filename, abi_rule): - ''' Store the given abi rule for the given profile filename preamble ''' + """Store the given abi rule for the given profile filename preamble""" if type(abi_rule) is not AbiRule: raise AppArmorBug('Wrong type given to ProfileList: %s' % abi_rule) @@ -120,7 +120,7 @@ class ProfileList: self.files[filename]['abi'].add(abi_rule) def add_alias(self, filename, alias_rule): - ''' Store the given alias rule for the given profile filename preamble ''' + """Store the given alias rule for the given profile filename preamble""" if type(alias_rule) is not AliasRule: raise AppArmorBug('Wrong type given to ProfileList: %s' % alias_rule) @@ -130,7 +130,7 @@ class ProfileList: self.files[filename]['alias'].add(alias_rule) def add_inc_ie(self, filename, inc_rule): - ''' Store the given include / include if exists rule for the given profile filename preamble ''' + """Store the given include / include if exists rule for the given profile filename preamble""" if type(inc_rule) is not IncludeRule: raise AppArmorBug('Wrong type given to ProfileList: %s' % inc_rule) @@ -139,7 +139,7 @@ class ProfileList: self.files[filename]['inc_ie'].add(inc_rule) def add_variable(self, filename, var_rule): - ''' Store the given variable rule for the given profile filename preamble ''' + """Store the given variable rule for the given profile filename preamble""" if type(var_rule) is not VariableRule: raise AppArmorBug('Wrong type given to ProfileList: %s' % var_rule) @@ -148,7 +148,7 @@ class ProfileList: self.files[filename]['variable'].add(var_rule) def add_boolean(self, filename, bool_rule): - ''' Store the given boolean variable rule for the given profile filename preamble ''' + """Store the given boolean variable rule for the given profile filename preamble""" if type(bool_rule) is not BooleanRule: raise AppArmorBug('Wrong type given to ProfileList: %s' % bool_rule) @@ -157,7 +157,7 @@ class ProfileList: self.files[filename]['boolean'].add(bool_rule) def delete_preamble_duplicates(self, filename): - ''' Delete duplicates in the preamble of the given profile file ''' + """Delete duplicates in the preamble of the given profile file""" if not self.files.get(filename): raise AppArmorBug('%s not listed in ProfileList files' % filename) @@ -178,7 +178,7 @@ class ProfileList: return found def get_raw(self, filename, depth=0): - ''' Get the preamble for the given profile filename (in original formatting) ''' + """Get the preamble for the given profile filename (in original formatting)""" if not self.files.get(filename): raise AppArmorBug('%s not listed in ProfileList files' % filename) @@ -188,7 +188,7 @@ class ProfileList: return data def get_clean(self, filename, depth=0): - ''' Get the preamble for the given profile filename (in clean formatting) ''' + """Get the preamble for the given profile filename (in clean formatting)""" if not self.files.get(filename): raise AppArmorBug('%s not listed in ProfileList files' % filename) @@ -198,12 +198,12 @@ class ProfileList: return data def filename_from_profile_name(self, name): - ''' Return profile filename for the given profile name, or None ''' + """Return profile filename for the given profile name, or None""" return self.profile_names.get(name, None) def filename_from_attachment(self, attachment): - ''' Return profile filename for the given attachment/executable path, or None ''' + """Return profile filename for the given attachment/executable path, or None""" if not attachment.startswith(('/', '@', '{')): raise AppArmorBug('Called filename_from_attachment with non-path attachment: %s' % attachment) @@ -220,13 +220,13 @@ class ProfileList: return None # nothing found def get_all_merged_variables(self, filename, all_incfiles): - ''' Get merged variables of a file and its includes + """Get merged variables of a file and its includes - Note that this function is more forgiving than apparmor_parser. - It detects variable redefinitions and adding values to non-existing variables. - However, it doesn't honor the order - so adding to a variable first and defining - it later won't trigger an error. - ''' + Note that this function is more forgiving than apparmor_parser. + It detects variable redefinitions and adding values to non-existing variables. + However, it doesn't honor the order - so adding to a variable first and defining + it later won't trigger an error. + """ if not self.files.get(filename): raise AppArmorBug('%s not listed in ProfileList files' % filename) @@ -275,7 +275,7 @@ class ProfileList: return merged_variables def profiles_in_file(self, filename): - ''' Return list of profiles in the given file ''' + """Return list of profiles in the given file""" if not self.files.get(filename): raise AppArmorBug('%s not listed in ProfileList files' % filename) diff --git a/utils/apparmor/profile_storage.py b/utils/apparmor/profile_storage.py index 5b5001331..d831a2c9c 100644 --- a/utils/apparmor/profile_storage.py +++ b/utils/apparmor/profile_storage.py @@ -50,10 +50,10 @@ ruletypes = { class ProfileStorage: - '''class to store the content (header, rules, comments) of a profilename + """class to store the content (header, rules, comments) of a profilename Acts like a dict(), but has some additional checks. - ''' + """ def __init__(self, profilename, hat, calledby): data = dict() @@ -169,10 +169,10 @@ class ProfileStorage: return data def get_rules_clean(self, depth): - '''return all clean rules of a profile (with default formatting, and leading whitespace as specified in the depth parameter) + """return all clean rules of a profile (with default formatting, and leading whitespace as specified in the depth parameter) Note that the profile header and the closing "}" are _not_ included. - ''' + """ # "old" write functions for rule types not implemented as *Rule class yet write_functions = { @@ -209,7 +209,7 @@ class ProfileStorage: @classmethod def parse(cls, line, file, lineno, profile, hat): - ''' parse a profile start line (using parse_profile_startline()) and convert it to a ProfileStorage ''' + """parse a profile start line (using parse_profile_startline()) and convert it to a ProfileStorage""" matches = parse_profile_start_line(line, file) @@ -260,7 +260,7 @@ class ProfileStorage: def split_flags(flags): - '''split the flags given as string into a sorted, de-duplicated list''' + """split the flags given as string into a sorted, de-duplicated list""" if flags is None: flags = '' @@ -272,7 +272,7 @@ def split_flags(flags): def add_or_remove_flag(flags, flags_to_change, set_flag): - '''add (if set_flag is True) or remove the given flags_to_change to flags''' + """add (if set_flag is True) or remove the given flags_to_change to flags""" if type(flags) is str or flags is None: flags = split_flags(flags) diff --git a/utils/apparmor/regex.py b/utils/apparmor/regex.py index f1e544b46..580429a72 100644 --- a/utils/apparmor/regex.py +++ b/utils/apparmor/regex.py @@ -168,7 +168,7 @@ RE_INCLUDE = re.compile('^\s*#?include(?P\s+if\s+exists)?\s*' + RE_MAG def re_match_include_parse(line, rule_name): - '''Matches the path for include, include if exists and abi rules + """Matches the path for include, include if exists and abi rules rule_name can be 'include' or 'abi' @@ -176,7 +176,7 @@ def re_match_include_parse(line, rule_name): - if the "if exists" condition is given - the include/abi path - if the path is a magic path (enclosed in <...>) - ''' + """ if rule_name == 'include': matches = RE_INCLUDE.search(line) @@ -223,7 +223,7 @@ def re_match_include_parse(line, rule_name): def re_match_include(line): - ''' return path of a 'include' rule ''' + """return path of a 'include' rule""" (path, ifexists, ismagic) = re_match_include_parse(line, 'include') if not ifexists: @@ -233,10 +233,10 @@ def re_match_include(line): def strip_parenthesis(data): - '''strips parenthesis from the given string and returns the strip()ped result. + """strips parenthesis from the given string and returns the strip()ped result. The parenthesis must be the first and last char, otherwise they won't be removed. Even if no parenthesis get removed, the result will be strip()ped. - ''' + """ if data[0] + data[-1] == '()': return data[1:-1].strip() else: diff --git a/utils/apparmor/rule/__init__.py b/utils/apparmor/rule/__init__.py index daf35983a..ebe48442c 100644 --- a/utils/apparmor/rule/__init__.py +++ b/utils/apparmor/rule/__init__.py @@ -24,7 +24,7 @@ _ = init_translation() class BaseRule: - '''Base class to handle and store a single rule''' + """Base class to handle and store a single rule""" # type specific rules should inherit from this class. # Methods that subclasses need to implement: @@ -53,7 +53,7 @@ class BaseRule: def __init__(self, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): - '''initialize variables needed by all rule types''' + """initialize variables needed by all rule types""" self.audit = audit self.deny = deny self.allow_keyword = allow_keyword @@ -64,7 +64,7 @@ class BaseRule: self.raw_rule = None def _aare_or_all(self, rulepart, partname, is_path, log_event): - '''checks rulepart and returns + """checks rulepart and returns - (AARE, False) if rulepart is a (non-empty) string - (None, True) if rulepart is all_obj (typically *Rule.ALL) - raises AppArmorBug if rulepart is an empty string or has a wrong type @@ -74,7 +74,7 @@ class BaseRule: - partname: the name of the rulepart (for example 'peer', used for exception messages) - is_path (passed through to AARE) - log_event (passed through to AARE) - ''' + """ if rulepart == self.ALL: return None, True @@ -99,9 +99,9 @@ class BaseRule: @classmethod def match(cls, raw_rule): - '''return True if raw_rule matches the class (main) regex, False otherwise + """return True if raw_rule matches the class (main) regex, False otherwise Note: This function just provides an answer to "is this your job?". - It does not guarantee that the rule is completely valid.''' + It does not guarantee that the rule is completely valid.""" if cls._match(raw_rule): return True @@ -111,12 +111,12 @@ class BaseRule: @classmethod @abstractmethod def _match(cls, raw_rule): - '''parse raw_rule and return regex match object''' + """parse raw_rule and return regex match object""" raise NotImplementedError("'%s' needs to implement _match(), but didn't" % (str(cls))) @classmethod def parse(cls, raw_rule): - '''parse raw_rule and return a rule object''' + """parse raw_rule and return a rule object""" rule = cls._parse(raw_rule) rule.raw_rule = raw_rule.strip() return rule @@ -124,24 +124,24 @@ class BaseRule: @classmethod @abstractmethod def _parse(cls, raw_rule): - '''returns a Rule object created from parsing the raw rule. - required to be implemented by subclasses; raise exception if not''' + """returns a Rule object created from parsing the raw rule. + required to be implemented by subclasses; raise exception if not""" raise NotImplementedError("'%s' needs to implement _parse(), but didn't" % (str(cls))) @abstractmethod def get_clean(self, depth=0): - '''return clean rule (with default formatting, and leading whitespace as specified in the depth parameter)''' + """return clean rule (with default formatting, and leading whitespace as specified in the depth parameter)""" raise NotImplementedError("'%s' needs to implement get_clean(), but didn't" % (str(self.__class__))) def get_raw(self, depth=0): - '''return raw rule (with original formatting, and leading whitespace in the depth parameter)''' + """return raw rule (with original formatting, and leading whitespace in the depth parameter)""" if self.raw_rule: return '%s%s' % (' ' * depth, self.raw_rule) else: return self.get_clean(depth) def is_covered(self, other_rule, check_allow_deny=True, check_audit=False): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not type(other_rule) == type(self): raise AppArmorBug('Passes %s instead of %s' % (str(other_rule), self.__class__.__name__)) @@ -163,11 +163,11 @@ class BaseRule: @abstractmethod def is_covered_localvars(self, other_rule): - '''check if the rule-specific parts of other_rule is covered by this rule object''' + """check if the rule-specific parts of other_rule is covered by this rule object""" raise NotImplementedError("'%s' needs to implement is_covered_localvars(), but didn't" % (str(self))) def _is_covered_plain(self, self_value, self_all, other_value, other_all, cond_name): - '''check if other_* is covered by self_* - for plain str, int etc.''' + """check if other_* is covered by self_* - for plain str, int etc.""" if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) @@ -182,7 +182,7 @@ class BaseRule: return True def _is_covered_list(self, self_value, self_all, other_value, other_all, cond_name, sanity_check=True): - '''check if other_* is covered by self_* - for lists''' + """check if other_* is covered by self_* - for lists""" if sanity_check and not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) @@ -197,7 +197,7 @@ class BaseRule: return True def _is_covered_aare(self, self_value, self_all, other_value, other_all, cond_name): - '''check if other_* is covered by self_* - for AARE''' + """check if other_* is covered by self_* - for AARE""" if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) @@ -212,8 +212,8 @@ class BaseRule: return True def is_equal(self, rule_obj, strict=False): - '''compare if rule_obj == self - Calls is_equal_localvars() to compare rule-specific variables''' + """compare if rule_obj == self + Calls is_equal_localvars() to compare rule-specific variables""" if self.audit != rule_obj.audit or self.deny != rule_obj.deny: return False @@ -228,7 +228,7 @@ class BaseRule: return self.is_equal_localvars(rule_obj, strict) def _is_equal_aare(self, self_value, self_all, other_value, other_all, cond_name): - '''check if other_* is the same as self_* - for AARE''' + """check if other_* is the same as self_* - for AARE""" if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) @@ -244,20 +244,20 @@ class BaseRule: @abstractmethod def is_equal_localvars(self, other_rule, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" raise NotImplementedError("'%s' needs to implement is_equal_localvars(), but didn't" % (str(self))) def severity(self, sev_db): - '''return severity of this rule, which can be: + """return severity of this rule, which can be: - a number between 0 and 10, where 0 means harmless and 10 means critical, - "unknown" (to be exact: the value specified for "unknown" as set when loading the severity database), or - sev_db.NOT_IMPLEMENTED if no severity check is implemented for this rule type. - sev_db must be an apparmor.severity.Severity object.''' + sev_db must be an apparmor.severity.Severity object.""" return sev_db.NOT_IMPLEMENTED def logprof_header(self): - '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object - returns {'label1': 'value1', 'label2': 'value2'} ''' + """return the headers (human-readable version of the rule) to display in aa-logprof for this rule object + returns {'label1': 'value1', 'label2': 'value2'}""" headers = [] qualifier = [] @@ -279,29 +279,29 @@ class BaseRule: @abstractmethod def logprof_header_localvars(self): - '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object - returns {'label1': 'value1', 'label2': 'value2'} ''' + """return the headers (human-readable version of the rule) to display in aa-logprof for this rule object + returns {'label1': 'value1', 'label2': 'value2'}""" raise NotImplementedError("'%s' needs to implement logprof_header(), but didn't" % (str(self))) @abstractmethod def edit_header(self): - '''return the prompt for, and the path to edit when using '(N)ew' ''' + """return the prompt for, and the path to edit when using '(N)ew'""" raise NotImplementedError("'%s' needs to implement edit_header(), but didn't" % (str(self))) @abstractmethod def validate_edit(self, newpath): - '''validate the new path. - Returns True if it covers the previous path, False if it doesn't.''' + """validate the new path. + Returns True if it covers the previous path, False if it doesn't.""" raise NotImplementedError("'%s' needs to implement validate_edit(), but didn't" % (str(self))) @abstractmethod def store_edit(self, newpath): - '''store the changed path. - This is done even if the new path doesn't match the original one.''' + """store the changed path. + This is done even if the new path doesn't match the original one.""" raise NotImplementedError("'%s' needs to implement store_edit(), but didn't" % (str(self))) def modifiers_str(self): - '''return the allow/deny and audit keyword as string, including whitespace''' + """return the allow/deny and audit keyword as string, including whitespace""" if self.audit: auditstr = 'audit ' @@ -319,7 +319,7 @@ class BaseRule: class BaseRuleset: - '''Base class to handle and store a collection of rules''' + """Base class to handle and store a collection of rules""" # decides if the (G)lob and Glob w/ (E)xt options are displayed # XXX TODO: remove in all *Ruleset classes (moved to *Rule) @@ -327,13 +327,13 @@ class BaseRuleset: can_glob_ext = False def __init__(self): - '''initialize variables needed by all ruleset types - Do not override in child class unless really needed - override _init_vars() instead''' + """initialize variables needed by all ruleset types + Do not override in child class unless really needed - override _init_vars() instead""" self.rules = [] self._init_vars() def _init_vars(self): - '''called by __init__() and delete_all_rules() - override in child class to initialize more variables''' + """called by __init__() and delete_all_rules() - override in child class to initialize more variables""" def __repr__(self): classname = self.__class__.__name__ @@ -343,11 +343,11 @@ class BaseRuleset: return '<%s (empty) />' % classname def add(self, rule, cleanup=False): - '''add a rule object + """add a rule object if cleanup is specified, delete rules that are covered by the new rule (the difference to delete_duplicates() is: cleanup only deletes rules that are covered by the new rule, but keeps other, unrelated superfluous rules) - ''' + """ deleted = 0 if cleanup: @@ -365,8 +365,8 @@ class BaseRuleset: return deleted def get_raw(self, depth=0): - '''return all raw rules (if possible/not modified in their original formatting). - Returns an array of lines, with depth * leading whitespace''' + """return all raw rules (if possible/not modified in their original formatting). + Returns an array of lines, with depth * leading whitespace""" data = [] for rule in self.rules: @@ -378,8 +378,8 @@ class BaseRuleset: return data def get_clean(self, depth=0): - '''return all rules (in clean/default formatting) - Returns an array of lines, with depth * leading whitespace''' + """return all rules (in clean/default formatting) + Returns an array of lines, with depth * leading whitespace""" allow_rules = [] deny_rules = [] @@ -406,8 +406,8 @@ class BaseRuleset: return cleandata def get_clean_unsorted(self, depth=0): - '''return all rules (in clean/default formatting) in original order - Returns an array of lines, with depth * leading whitespace''' + """return all rules (in clean/default formatting) in original order + Returns an array of lines, with depth * leading whitespace""" all_rules = [] @@ -420,7 +420,7 @@ class BaseRuleset: return all_rules def is_covered(self, rule, check_allow_deny=True, check_audit=False): - '''return True if rule is covered by existing rules, otherwise False''' + """return True if rule is covered by existing rules, otherwise False""" for r in self.rules: if r.is_covered(rule, check_allow_deny, check_audit): @@ -429,7 +429,7 @@ class BaseRuleset: return False # def is_log_covered(self, parsed_log_event, check_allow_deny=True, check_audit=False): -# '''return True if parsed_log_event is covered by existing rules, otherwise False''' +# """return True if parsed_log_event is covered by existing rules, otherwise False""" # # rule_obj = self.new_rule() # rule_obj.set_log(parsed_log_event) @@ -437,7 +437,7 @@ class BaseRuleset: # return self.is_covered(rule_obj, check_allow_deny, check_audit) def delete(self, rule): - '''Delete rule from rules''' + """Delete rule from rules""" rule_to_delete = False i = 0 @@ -453,8 +453,8 @@ class BaseRuleset: raise AppArmorBug('Attempt to delete non-existing rule %s' % rule.get_raw(0)) def delete_duplicates(self, include_rules): - '''Delete duplicate rules. - include_rules must be a *_rules object or None''' + """Delete duplicate rules. + include_rules must be a *_rules object or None""" deleted = 0 @@ -477,7 +477,7 @@ class BaseRuleset: return deleted def delete_in_profile_duplicates(self): - '''Delete duplicate rules inside a profile''' + """Delete duplicate rules inside a profile""" deleted = 0 oldrules = self.rules @@ -492,13 +492,13 @@ class BaseRuleset: return deleted def get_glob_ext(self, path_or_rule): - '''returns the next possible glob with extension (for file rules only). - For all other rule types, raise an exception''' + """returns the next possible glob with extension (for file rules only). + For all other rule types, raise an exception""" raise NotImplementedError("get_glob_ext is not available for this rule type!") def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name, allow_empty_list=False): - '''check if lst is all_obj or contains only items listed in allowed_keywords''' + """check if lst is all_obj or contains only items listed in allowed_keywords""" if lst == all_obj: return None, True, None @@ -524,8 +524,8 @@ def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name def logprof_value_or_all(value, all_values): - '''helper for logprof_header() to return 'all' (if all_values is True) or the specified value. - For some types, the value is made more readable.''' + """helper for logprof_header() to return 'all' (if all_values is True) or the specified value. + For some types, the value is made more readable.""" if all_values: return _('ALL') @@ -539,7 +539,7 @@ def logprof_value_or_all(value, all_values): def parse_comment(matches): - '''returns the comment (with a leading space) from the matches object''' + """returns the comment (with a leading space) from the matches object""" comment = '' if matches.group('comment'): # include a space so that we don't need to add it everywhere when writing the rule @@ -548,9 +548,9 @@ def parse_comment(matches): def parse_modifiers(matches): - '''returns audit, deny, allow_keyword and comment from the matches object + """returns audit, deny, allow_keyword and comment from the matches object - audit, deny and allow_keyword are True/False - - comment is the comment with a leading space''' + - comment is the comment with a leading space""" audit = False if matches.group('audit'): audit = True @@ -573,7 +573,7 @@ def parse_modifiers(matches): def quote_if_needed(data): - '''quote data if it contains whitespace''' + """quote data if it contains whitespace""" if ' ' in data: data = '"' + data + '"' return data diff --git a/utils/apparmor/rule/abi.py b/utils/apparmor/rule/abi.py index 8ea7a4284..9a5926be0 100644 --- a/utils/apparmor/rule/abi.py +++ b/utils/apparmor/rule/abi.py @@ -24,7 +24,7 @@ _ = init_translation() # abi and include rules have a very similar syntax # base AbiRule on IncludeRule to inherit most of its behaviour class AbiRule(IncludeRule): - '''Class to handle and store a single abi rule''' + """Class to handle and store a single abi rule""" rule_name = 'abi' @@ -44,7 +44,7 @@ class AbiRule(IncludeRule): return RE_ABI.search(raw_rule) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -58,4 +58,4 @@ class AbiRule(IncludeRule): class AbiRuleset(IncludeRuleset): - '''Class to handle and store a collection of abi rules''' + """Class to handle and store a collection of abi rules""" diff --git a/utils/apparmor/rule/alias.py b/utils/apparmor/rule/alias.py index f1c407b25..da9e0bae1 100644 --- a/utils/apparmor/rule/alias.py +++ b/utils/apparmor/rule/alias.py @@ -22,7 +22,7 @@ _ = init_translation() class AliasRule(BaseRule): - '''Class to handle and store a single alias rule''' + """Class to handle and store a single alias rule""" rule_name = 'alias' @@ -61,7 +61,7 @@ class AliasRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return AliasRule''' + """parse raw_rule and return AliasRule""" matches = cls._match(raw_rule) if not matches: @@ -76,20 +76,20 @@ class AliasRule(BaseRule): audit=False, deny=False, allow_keyword=False, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth return '%salias %s -> %s,' % (space, quote_if_needed(self.orig_path), quote_if_needed(self.target)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" # the only way aliases can be covered are exact duplicates return self.is_equal_localvars(other_rule, False) def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific aliass are equal''' + """compare if rule-specific aliass are equal""" if not type(rule_obj) == AliasRule: raise AppArmorBug('Passed non-alias rule: %s' % str(rule_obj)) @@ -111,4 +111,4 @@ class AliasRule(BaseRule): class AliasRuleset(BaseRuleset): - '''Class to handle and store a collection of alias rules''' + """Class to handle and store a collection of alias rules""" diff --git a/utils/apparmor/rule/boolean.py b/utils/apparmor/rule/boolean.py index 1aee98454..e4b226557 100644 --- a/utils/apparmor/rule/boolean.py +++ b/utils/apparmor/rule/boolean.py @@ -23,7 +23,7 @@ _ = init_translation() class BooleanRule(BaseRule): - '''Class to handle and store a single variable rule''' + """Class to handle and store a single variable rule""" rule_name = 'boolean' @@ -62,7 +62,7 @@ class BooleanRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return BooleanRule''' + """parse raw_rule and return BooleanRule""" matches = cls._match(raw_rule) if not matches: @@ -77,14 +77,14 @@ class BooleanRule(BaseRule): audit=False, deny=False, allow_keyword=False, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth return '%s%s = %s' % (space, self.varname, self.value) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if self.varname != other_rule.varname: return False @@ -96,7 +96,7 @@ class BooleanRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == BooleanRule: raise AppArmorBug('Passed non-boolean rule: %s' % str(rule_obj)) @@ -118,13 +118,13 @@ class BooleanRule(BaseRule): class BooleanRuleset(BaseRuleset): - '''Class to handle and store a collection of variable rules''' + """Class to handle and store a collection of variable rules""" def add(self, rule, cleanup=False): - ''' Add boolean variable rule object + """Add boolean variable rule object - If the variable name is already known, raise an exception because re-defining a variable isn't allowed. - ''' + If the variable name is already known, raise an exception because re-defining a variable isn't allowed. + """ for knownrule in self.rules: if rule.varname == knownrule.varname: diff --git a/utils/apparmor/rule/capability.py b/utils/apparmor/rule/capability.py index 6280458a8..dc83b4767 100644 --- a/utils/apparmor/rule/capability.py +++ b/utils/apparmor/rule/capability.py @@ -25,7 +25,7 @@ _ = init_translation() class CapabilityRule(BaseRule): - '''Class to handle and store a single capability rule''' + """Class to handle and store a single capability rule""" # Nothing external should reference this class, all external users # should reference the class field CapabilityRule.ALL @@ -66,7 +66,7 @@ class CapabilityRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return CapabilityRule''' + """parse raw_rule and return CapabilityRule""" matches = cls._match(raw_rule) if not matches: @@ -87,7 +87,7 @@ class CapabilityRule(BaseRule): comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth if self.all_caps: @@ -100,7 +100,7 @@ class CapabilityRule(BaseRule): raise AppArmorBug("Empty capability rule") def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_list(self.capability, self.all_caps, other_rule.capability, other_rule.all_caps, 'capability'): return False @@ -109,7 +109,7 @@ class CapabilityRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == CapabilityRule: raise AppArmorBug('Passed non-capability rule: %s' % str(rule_obj)) @@ -144,8 +144,8 @@ class CapabilityRule(BaseRule): class CapabilityRuleset(BaseRuleset): - '''Class to handle and store a collection of capability rules''' + """Class to handle and store a collection of capability rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For capability rules, that's always "capability," (all capabilities)''' + """Return the next possible glob. For capability rules, that's always "capability," (all capabilities)""" return 'capability,' diff --git a/utils/apparmor/rule/change_profile.py b/utils/apparmor/rule/change_profile.py index 7501ba058..a87a2bb88 100644 --- a/utils/apparmor/rule/change_profile.py +++ b/utils/apparmor/rule/change_profile.py @@ -23,7 +23,7 @@ _ = init_translation() class ChangeProfileRule(BaseRule): - '''Class to handle and store a single change_profile rule''' + """Class to handle and store a single change_profile rule""" # Nothing external should reference this class, all external users # should reference the class field ChangeProfileRule.ALL @@ -38,10 +38,7 @@ class ChangeProfileRule(BaseRule): def __init__(self, execmode, execcond, targetprofile, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): - - ''' - CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ -> PROGRAMCHILD ] - ''' + """CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ -> PROGRAMCHILD ]""" super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) @@ -85,7 +82,7 @@ class ChangeProfileRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return ChangeProfileRule''' + """parse raw_rule and return ChangeProfileRule""" matches = cls._match(raw_rule) if not matches: @@ -109,7 +106,7 @@ class ChangeProfileRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -135,7 +132,7 @@ class ChangeProfileRule(BaseRule): return ('%s%schange_profile%s%s%s,%s' % (space, self.modifiers_str(), execmode, execcond, targetprofile, self.comment)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if (self.execmode != other_rule.execmode and (self.execmode not in ChangeProfileRule.equiv_execmodes @@ -153,7 +150,7 @@ class ChangeProfileRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == ChangeProfileRule: raise AppArmorBug('Passed non-change_profile rule: %s' % str(rule_obj)) @@ -190,11 +187,11 @@ class ChangeProfileRule(BaseRule): class ChangeProfileRuleset(BaseRuleset): - '''Class to handle and store a collection of change_profile rules''' + """Class to handle and store a collection of change_profile rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For change_profile rules, that can be "change_profile EXECCOND,", + """Return the next possible glob. For change_profile rules, that can be "change_profile EXECCOND,", "change_profile -> TARGET_PROFILE," or "change_profile," (all change_profile). - Also, EXECCOND filename can be globbed''' + Also, EXECCOND filename can be globbed""" # XXX implement all options mentioned above ;-) return 'change_profile,' diff --git a/utils/apparmor/rule/dbus.py b/utils/apparmor/rule/dbus.py index 4ff0dd81e..a1f2a8c02 100644 --- a/utils/apparmor/rule/dbus.py +++ b/utils/apparmor/rule/dbus.py @@ -65,7 +65,7 @@ RE_DBUS_DETAILS = re.compile( class DbusRule(BaseRule): - '''Class to handle and store a single dbus rule''' + """Class to handle and store a single dbus rule""" # Nothing external should reference this class, all external users # should reference the class field DbusRule.ALL @@ -111,7 +111,7 @@ class DbusRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return DbusRule''' + """parse raw_rule and return DbusRule""" matches = cls._match(raw_rule) if not matches: @@ -194,7 +194,7 @@ class DbusRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -223,8 +223,8 @@ class DbusRule(BaseRule): return ('%s%sdbus%s%s%s%s%s%s%s,%s' % (space, self.modifiers_str(), access, bus, path, name, interface, member, peer, self.comment)) def _get_aare_rule_part(self, prefix, value, all_values): - '''helper function to write a rule part - value is expected to be a AARE''' + """helper function to write a rule part + value is expected to be a AARE""" if all_values: return '' elif value: @@ -233,7 +233,7 @@ class DbusRule(BaseRule): raise AppArmorBug('Empty %(prefix_name)s in %(rule_name)s rule' % {'prefix_name': prefix, 'rule_name': self.rule_name}) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False @@ -263,7 +263,7 @@ class DbusRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == DbusRule: raise AppArmorBug('Passed non-dbus rule: %s' % str(rule_obj)) @@ -318,9 +318,9 @@ class DbusRule(BaseRule): class DbusRuleset(BaseRuleset): - '''Class to handle and store a collection of dbus rules''' + """Class to handle and store a collection of dbus rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For dbus rules, that means removing access or removing/globbing bus''' + """Return the next possible glob. For dbus rules, that means removing access or removing/globbing bus""" # XXX only remove one part, not all return 'dbus,' diff --git a/utils/apparmor/rule/file.py b/utils/apparmor/rule/file.py index e51cecb4a..dd90264ba 100644 --- a/utils/apparmor/rule/file.py +++ b/utils/apparmor/rule/file.py @@ -29,7 +29,7 @@ file_permissions = ('m', 'r', 'w', 'a', 'l', 'k', 'link', 'subset') # also defi class FileRule(BaseRule): - '''Class to handle and store a single file rule''' + """Class to handle and store a single file rule""" # Nothing external should reference this class, all external users # should reference the class field FileRule.ALL @@ -46,7 +46,7 @@ class FileRule(BaseRule): def __init__(self, path, perms, exec_perms, target, owner, file_keyword=False, leading_perms=False, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): - '''Initialize FileRule + """Initialize FileRule Parameters: - path: string, AARE or FileRule.ALL @@ -56,7 +56,7 @@ class FileRule(BaseRule): - owner: bool - file_keyword: bool - leading_perms: bool - ''' + """ super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) @@ -138,7 +138,7 @@ class FileRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return FileRule''' + """parse raw_rule and return FileRule""" matches = cls._match(raw_rule) if not matches: @@ -192,7 +192,7 @@ class FileRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -240,11 +240,11 @@ class FileRule(BaseRule): raise AppArmorBug('Invalid combination of path and perms in file rule - either specify path and perms, or none of them') def _joint_perms(self): - '''return the permissions as string (using self.perms and self.exec_perms)''' + """return the permissions as string (using self.perms and self.exec_perms)""" return self._join_given_perms(self.perms, self.exec_perms) def _join_given_perms(self, perms, exec_perms): - '''return the permissions as string (using the perms and exec_perms given as parameter)''' + """return the permissions as string (using the perms and exec_perms given as parameter)""" perm_string = '' for perm in file_permissions: if perm in perms: @@ -260,7 +260,7 @@ class FileRule(BaseRule): return perm_string def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_aare(self.path, self.all_paths, other_rule.path, other_rule.all_paths, 'path'): return False @@ -311,7 +311,7 @@ class FileRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == FileRule: raise AppArmorBug('Passed non-file rule: %s' % str(rule_obj)) @@ -400,7 +400,7 @@ class FileRule(BaseRule): return headers def glob(self): - '''Change path to next possible glob''' + """Change path to next possible glob""" if self.all_paths: return @@ -408,7 +408,7 @@ class FileRule(BaseRule): self.raw_rule = None def glob_ext(self): - '''Change path to next possible glob with extension''' + """Change path to next possible glob with extension""" if self.all_paths: return @@ -437,13 +437,13 @@ class FileRule(BaseRule): class FileRuleset(BaseRuleset): - '''Class to handle and store a collection of file rules''' + """Class to handle and store a collection of file rules""" def get_rules_for_path(self, path, audit=False, deny=False): - '''Get all rules matching the given path + """Get all rules matching the given path path can be str or AARE If audit is True, only return rules with the audit flag set. - If deny is True, only return matching deny rules''' + If deny is True, only return matching deny rules""" matching_rules = FileRuleset() for rule in self.rules: @@ -453,7 +453,7 @@ class FileRuleset(BaseRuleset): return matching_rules def get_perms_for_path(self, path, audit=False, deny=False): - '''Get the summarized permissions of all rules matching the given path, and the list of paths involved in the calculation + """Get the summarized permissions of all rules matching the given path, and the list of paths involved in the calculation path can be str or AARE If audit is True, only analyze rules with the audit flag set. If deny is True, only analyze matching deny rules @@ -461,7 +461,7 @@ class FileRuleset(BaseRuleset): 'deny': {'owner': set_of_perms, 'all': set_of_perms}, 'path': involved_paths} Note: exec rules and exec/link target are not honored! - ''' + """ # XXX do we need to honor the link target? perms = { @@ -507,8 +507,8 @@ class FileRuleset(BaseRuleset): return {'allow': allow, 'deny': deny, 'paths': paths} def get_exec_rules_for_path(self, path, only_exact_matches=True): - '''Get all rules matching the given path that contain exec permissions - path can be str or AARE''' + """Get all rules matching the given path that contain exec permissions + path can be str or AARE""" matches = FileRuleset() @@ -522,7 +522,7 @@ class FileRuleset(BaseRuleset): return matches def get_exec_conflict_rules(self, oldrule): - '''check if one of the exec rules conflict with oldrule. If yes, return the conflicting rules.''' + """check if one of the exec rules conflict with oldrule. If yes, return the conflicting rules.""" conflictingrules = FileRuleset() @@ -537,10 +537,10 @@ class FileRuleset(BaseRuleset): def split_perms(perm_string, deny): - '''parse permission string + """parse permission string - perm_string: the permission string to parse - deny: True if this is a deny rule - ''' + """ perms = set() exec_mode = None @@ -570,9 +570,9 @@ def split_perms(perm_string, deny): def perms_with_a(perms): - '''if perms includes 'w', add 'a' perms + """if perms includes 'w', add 'a' perms - perms: the original permissions - ''' + """ perms_with_a = set() if perms: perms_with_a = set(perms) diff --git a/utils/apparmor/rule/include.py b/utils/apparmor/rule/include.py index a3654d04b..6de851d4b 100644 --- a/utils/apparmor/rule/include.py +++ b/utils/apparmor/rule/include.py @@ -23,7 +23,7 @@ _ = init_translation() class IncludeRule(BaseRule): - '''Class to handle and store a single include rule''' + """Class to handle and store a single include rule""" rule_name = 'include' @@ -58,7 +58,7 @@ class IncludeRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return IncludeRule''' + """parse raw_rule and return IncludeRule""" matches = cls._match(raw_rule) if not matches: @@ -73,7 +73,7 @@ class IncludeRule(BaseRule): audit=False, deny=False, allow_keyword=False, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -87,7 +87,7 @@ class IncludeRule(BaseRule): return ('%s%s%s "%s"%s' % (space, self.rule_name, ifexists_txt, self.path, self.comment)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if (self.path != other_rule.path): return False @@ -102,7 +102,7 @@ class IncludeRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == type(self): raise AppArmorBug('Passed non-%s rule: %s' % (self.rule_name, str(rule_obj))) @@ -122,7 +122,7 @@ class IncludeRule(BaseRule): return [_('Include'), self.get_clean()] def get_full_paths(self, profile_dir): - ''' get list of full paths of an include (can contain multiple paths if self.path is a directory) ''' + """get list of full paths of an include (can contain multiple paths if self.path is a directory)""" # TODO: improve/fix logic to honor magic vs. quoted include paths if self.path.startswith('/'): @@ -151,10 +151,10 @@ class IncludeRule(BaseRule): class IncludeRuleset(BaseRuleset): - '''Class to handle and store a collection of include rules''' + """Class to handle and store a collection of include rules""" def get_all_full_paths(self, profile_dir): - ''' get full path of all includes ''' + """get full path of all includes""" paths = [] for rule_obj in self.rules: diff --git a/utils/apparmor/rule/network.py b/utils/apparmor/rule/network.py index eddfc31f3..f58d4916f 100644 --- a/utils/apparmor/rule/network.py +++ b/utils/apparmor/rule/network.py @@ -46,7 +46,7 @@ RE_NETWORK_DETAILS = re.compile( class NetworkRule(BaseRule): - '''Class to handle and store a single network rule''' + """Class to handle and store a single network rule""" # Nothing external should reference this class, all external users # should reference the class field NetworkRule.ALL @@ -95,7 +95,7 @@ class NetworkRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return NetworkRule''' + """parse raw_rule and return NetworkRule""" matches = cls._match(raw_rule) if not matches: @@ -129,7 +129,7 @@ class NetworkRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -150,7 +150,7 @@ class NetworkRule(BaseRule): return ('%s%snetwork%s%s,%s' % (space, self.modifiers_str(), domain, type_or_protocol, self.comment)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_plain(self.domain, self.all_domains, other_rule.domain, other_rule.all_domains, 'domain'): return False @@ -162,7 +162,7 @@ class NetworkRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == NetworkRule: raise AppArmorBug('Passed non-network rule: %s' % str(rule_obj)) @@ -188,9 +188,9 @@ class NetworkRule(BaseRule): class NetworkRuleset(BaseRuleset): - '''Class to handle and store a collection of network rules''' + """Class to handle and store a collection of network rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For network rules, that's "network DOMAIN," or "network," (all network)''' + """Return the next possible glob. For network rules, that's "network DOMAIN," or "network," (all network)""" # XXX return 'network DOMAIN,' if 'network DOMAIN TYPE_OR_PROTOCOL' was given return 'network,' diff --git a/utils/apparmor/rule/ptrace.py b/utils/apparmor/rule/ptrace.py index 779bf9888..e76f6b639 100644 --- a/utils/apparmor/rule/ptrace.py +++ b/utils/apparmor/rule/ptrace.py @@ -41,7 +41,7 @@ RE_PTRACE_DETAILS = re.compile( class PtraceRule(BaseRule): - '''Class to handle and store a single ptrace rule''' + """Class to handle and store a single ptrace rule""" # Nothing external should reference this class, all external users # should reference the class field PtraceRule.ALL @@ -71,7 +71,7 @@ class PtraceRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return PtraceRule''' + """parse raw_rule and return PtraceRule""" matches = cls._match(raw_rule) if not matches: @@ -109,7 +109,7 @@ class PtraceRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -132,7 +132,7 @@ class PtraceRule(BaseRule): return ('%s%sptrace%s%s,%s' % (space, self.modifiers_str(), access, peer, self.comment)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False @@ -144,7 +144,7 @@ class PtraceRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == PtraceRule: raise AppArmorBug('Passed non-ptrace rule: %s' % str(rule_obj)) @@ -169,9 +169,9 @@ class PtraceRule(BaseRule): class PtraceRuleset(BaseRuleset): - '''Class to handle and store a collection of ptrace rules''' + """Class to handle and store a collection of ptrace rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For ptrace rules, that means removing access or removing/globbing peer''' + """Return the next possible glob. For ptrace rules, that means removing access or removing/globbing peer""" # XXX only remove one part, not all return 'ptrace,' diff --git a/utils/apparmor/rule/rlimit.py b/utils/apparmor/rule/rlimit.py index fa5099793..a2ab64426 100644 --- a/utils/apparmor/rule/rlimit.py +++ b/utils/apparmor/rule/rlimit.py @@ -37,7 +37,7 @@ RE_NICE = re.compile('^(-20|-[01]?[0-9]|[01]?[0-9])$') class RlimitRule(BaseRule): - '''Class to handle and store a single rlimit rule''' + """Class to handle and store a single rlimit rule""" # Nothing external should reference this class, all external users # should reference the class field RlimitRule.ALL @@ -110,7 +110,7 @@ class RlimitRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return RlimitRule''' + """parse raw_rule and return RlimitRule""" matches = cls._match(raw_rule) if not matches: @@ -134,7 +134,7 @@ class RlimitRule(BaseRule): return RlimitRule(rlimit, value, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -198,7 +198,7 @@ class RlimitRule(BaseRule): return number def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_plain(self.rlimit, False, other_rule.rlimit, False, 'rlimit'): # rlimit can't be ALL, therefore using False return False @@ -216,7 +216,7 @@ class RlimitRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == RlimitRule: raise AppArmorBug('Passed non-rlimit rule: %s' % str(rule_obj)) @@ -245,10 +245,10 @@ class RlimitRule(BaseRule): class RlimitRuleset(BaseRuleset): - '''Class to handle and store a collection of rlimit rules''' + """Class to handle and store a collection of rlimit rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For rlimit rules, that can mean changing the value to 'infinity' ''' + """Return the next possible glob. For rlimit rules, that can mean changing the value to 'infinity'""" # XXX implement all options mentioned above ;-) raise AppArmorBug('get_glob() is not (yet) available for this rule type') diff --git a/utils/apparmor/rule/signal.py b/utils/apparmor/rule/signal.py index 11cf029c0..8e40abcd4 100644 --- a/utils/apparmor/rule/signal.py +++ b/utils/apparmor/rule/signal.py @@ -67,7 +67,7 @@ RE_FILTER_QUOTES = re.compile('"([a-z0-9]+)"') # used to strip quotes around si class SignalRule(BaseRule): - '''Class to handle and store a single signal rule''' + """Class to handle and store a single signal rule""" # Nothing external should reference this class, all external users # should reference the class field SignalRule.ALL @@ -106,7 +106,7 @@ class SignalRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return SignalRule''' + """parse raw_rule and return SignalRule""" matches = cls._match(raw_rule) if not matches: @@ -153,7 +153,7 @@ class SignalRule(BaseRule): audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -185,7 +185,7 @@ class SignalRule(BaseRule): return ('%s%ssignal%s%s%s,%s' % (space, self.modifiers_str(), access, signal, peer, self.comment)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False @@ -200,7 +200,7 @@ class SignalRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == SignalRule: raise AppArmorBug('Passed non-signal rule: %s' % str(rule_obj)) @@ -231,9 +231,9 @@ class SignalRule(BaseRule): class SignalRuleset(BaseRuleset): - '''Class to handle and store a collection of signal rules''' + """Class to handle and store a collection of signal rules""" def get_glob(self, path_or_rule): - '''Return the next possible glob. For signal rules, that means removing access, signal or peer''' + """Return the next possible glob. For signal rules, that means removing access, signal or peer""" # XXX only remove one part, not all return 'signal,' diff --git a/utils/apparmor/rule/variable.py b/utils/apparmor/rule/variable.py index b4f38115c..8dd9dbe42 100644 --- a/utils/apparmor/rule/variable.py +++ b/utils/apparmor/rule/variable.py @@ -25,7 +25,7 @@ _ = init_translation() class VariableRule(BaseRule): - '''Class to handle and store a single variable rule''' + """Class to handle and store a single variable rule""" rule_name = 'variable' @@ -68,7 +68,7 @@ class VariableRule(BaseRule): @classmethod def _parse(cls, raw_rule): - '''parse raw_rule and return VariableRule''' + """parse raw_rule and return VariableRule""" matches = cls._match(raw_rule) if not matches: @@ -84,7 +84,7 @@ class VariableRule(BaseRule): audit=False, deny=False, allow_keyword=False, comment=comment) def get_clean(self, depth=0): - '''return rule (in clean/default formatting)''' + """return rule (in clean/default formatting)""" space = ' ' * depth @@ -97,7 +97,7 @@ class VariableRule(BaseRule): return '%s%s %s %s' % (space, self.varname, self.mode, ' '.join(data)) def is_covered_localvars(self, other_rule): - '''check if other_rule is covered by this rule object''' + """check if other_rule is covered by this rule object""" if self.varname != other_rule.varname: return False @@ -112,7 +112,7 @@ class VariableRule(BaseRule): return True def is_equal_localvars(self, rule_obj, strict): - '''compare if rule-specific variables are equal''' + """compare if rule-specific variables are equal""" if not type(rule_obj) == VariableRule: raise AppArmorBug('Passed non-variable rule: %s' % str(rule_obj)) @@ -137,13 +137,13 @@ class VariableRule(BaseRule): class VariableRuleset(BaseRuleset): - '''Class to handle and store a collection of variable rules''' + """Class to handle and store a collection of variable rules""" def add(self, rule, cleanup=False): - ''' Add variable rule object + """Add variable rule object - If the variable name is already known, raise an exception because re-defining a variable isn't allowed. - ''' + If the variable name is already known, raise an exception because re-defining a variable isn't allowed. + """ if rule.mode == '=': for knownrule in self.rules: @@ -155,10 +155,10 @@ class VariableRuleset(BaseRuleset): super().add(rule, cleanup) def get_merged_variables(self): - ''' Get merged variables of this VariableRuleset. + """Get merged variables of this VariableRuleset. - Note that no error checking is done because variables can be defined in one file and extended in another. - ''' + Note that no error checking is done because variables can be defined in one file and extended in another. + """ var_set = {} var_add = {} diff --git a/utils/apparmor/sandbox.py b/utils/apparmor/sandbox.py index 47c511aad..e54fad8dd 100644 --- a/utils/apparmor/sandbox.py +++ b/utils/apparmor/sandbox.py @@ -23,7 +23,7 @@ from tempfile import NamedTemporaryFile def check_requirements(binary): - '''Verify necessary software is installed''' + """Verify necessary software is installed""" exes = [ 'xset', # for detecting free X display 'aa-easyprof', # for templates @@ -43,7 +43,7 @@ def check_requirements(binary): def parse_args(args=None, parser=None): - '''Parse arguments''' + """Parse arguments""" if parser is None: parser = optparse.OptionParser() @@ -104,7 +104,7 @@ def parse_args(args=None, parser=None): def gen_policy_name(binary): - '''Generate a temporary policy based on the binary name''' + """Generate a temporary policy based on the binary name""" return "sandbox-%s%s" % (pwd.getpwuid(os.geteuid())[0], re.sub(r'/', '_', binary)) @@ -117,7 +117,7 @@ def set_environ(env): def aa_exec(command, opt, environ={}, verify_rules=[]): - '''Execute binary under specified policy''' + """Execute binary under specified policy""" if opt.profile is not None: policy_name = opt.profile else: @@ -169,7 +169,7 @@ def aa_exec(command, opt, environ={}, verify_rules=[]): def run_sandbox(command, opt): - '''Run application''' + """Run application""" # aa-exec rc, report = aa_exec(command, opt) return rc, report @@ -209,7 +209,7 @@ class SandboxXserver(): self.new_environ["LIBOVERLAY_SCROLLBAR"] = "0" def cleanup(self): - '''Cleanup our forked pids, reset the environment, etc''' + """Cleanup our forked pids, reset the environment, etc""" self.pids.reverse() debug(self.pids) for pid in self.pids: @@ -233,7 +233,7 @@ class SandboxXserver(): set_environ(self.old_environ) def find_free_x_display(self): - '''Find a free X display''' + """Find a free X display""" old_lang = None if 'LANG' in os.environ: old_lang = os.environ['LANG'] @@ -266,7 +266,7 @@ class SandboxXserver(): return "(Sandbox%s) %s" % (self.display, self.title) def verify_host_setup(self): - '''Make sure we have everything we need''' + """Make sure we have everything we need""" old_lang = None if 'LANG' in os.environ: old_lang = os.environ['LANG'] @@ -286,7 +286,7 @@ class SandboxXserver(): raise AppArmorException("Access control allows '%s' full access. Please see 'man aa-sandbox' for details" % username) def start(self): - '''Start a nested X server (need to override)''' + """Start a nested X server (need to override)""" # clean up the old one if os.path.exists(self.xauth): os.unlink(self.xauth) @@ -312,10 +312,10 @@ class SandboxXephyr(SandboxXserver): if which(e) is None: raise AppArmorException("Could not find '%s'" % e) - '''Run any setup code''' + # Run any setup code SandboxXserver.start(self) - '''Start a Xephyr server''' + # Start a Xephyr server listener_x = os.fork() if listener_x == 0: # TODO: break into config file? Which are needed? @@ -390,7 +390,7 @@ class SandboxXpra(SandboxXserver): SandboxXserver.cleanup(self) def _get_xvfb_args(self): - '''Setup xvfb arguments''' + """Setup xvfb arguments""" # Debugging tip (can also use glxinfo): # $ xdpyinfo > /tmp/native # $ aa-sandbox -X -t sandbox-x /usr/bin/xdpyinfo > /tmp/nested @@ -577,7 +577,7 @@ EndSection if not os.path.exists(drv): raise AppArmorException("Could not find '%s'" % drv) - '''Run any setup code''' + # Run any setup code SandboxXserver.start(self) xvfb_args = self._get_xvfb_args() @@ -676,7 +676,7 @@ EndSection def run_xsandbox(command, opt): - '''Run X application in a sandbox''' + """Run X application in a sandbox""" old_cwd = os.getcwd() # first, start X diff --git a/utils/apparmor/severity.py b/utils/apparmor/severity.py index a6ecec294..dd09e98ed 100644 --- a/utils/apparmor/severity.py +++ b/utils/apparmor/severity.py @@ -181,5 +181,5 @@ class Severity: return resource.replace(variable, replacement) def set_variables(self, vars): - ''' Set the profile variables to use for rating the severity ''' + """Set the profile variables to use for rating the severity""" self.severity['VARIABLES'] = vars diff --git a/utils/apparmor/tools.py b/utils/apparmor/tools.py index 4033c87cf..0750b4e0e 100644 --- a/utils/apparmor/tools.py +++ b/utils/apparmor/tools.py @@ -46,7 +46,7 @@ class aa_tools: self.silent = args.silent def get_next_to_profile(self): - '''Iterator function to walk the list of arguments passed''' + """Iterator function to walk the list of arguments passed""" for p in self.profiling: if not p: diff --git a/utils/python-tools-setup.py b/utils/python-tools-setup.py index 61d65c081..341aca291 100644 --- a/utils/python-tools-setup.py +++ b/utils/python-tools-setup.py @@ -28,7 +28,7 @@ import sys class Install(_install): - '''Override setuptools to install the files where we want them.''' + """Override setuptools to install the files where we want them.""" def run(self): # Now byte-compile everything super().run() diff --git a/utils/test/common_test.py b/utils/test/common_test.py index 0ceee52ce..1979f5db4 100755 --- a/utils/test/common_test.py +++ b/utils/test/common_test.py @@ -31,7 +31,7 @@ class AATest(unittest.TestCase): self.AASetup() def AASetup(self): - '''override this function if a test needs additional setup steps (instead of overriding setUp())''' + """override this function if a test needs additional setup steps (instead of overriding setUp())""" def tearDown(self): if self.tmpdir and os.path.exists(self.tmpdir): @@ -40,7 +40,7 @@ class AATest(unittest.TestCase): self.AATeardown() def AATeardown(self): - '''override this function if a test needs additional teardown steps (instead of overriding tearDown())''' + """override this function if a test needs additional teardown steps (instead of overriding tearDown())""" def createTmpdir(self): self.tmpdir = tempfile.mkdtemp(prefix='aa-test-') @@ -67,7 +67,7 @@ class AAParseTest(unittest.TestCase): def setup_all_loops(module_name): - '''call setup_tests_loop() for each class in module_name''' + """call setup_tests_loop() for each class in module_name""" for name, obj in inspect.getmembers(sys.modules[module_name]): if inspect.isclass(obj): if issubclass(obj, unittest.TestCase): @@ -75,7 +75,7 @@ def setup_all_loops(module_name): def setup_tests_loop(test_class): - '''Create tests in test_class using test_class.tests and self._run_test() + """Create tests in test_class using test_class.tests and self._run_test() test_class.tests should be tuples of (test_data, expected_results) test_data and expected_results can be of any type as long as test_class._run_test() @@ -83,7 +83,7 @@ def setup_tests_loop(test_class): A typical definition for _run_test() is: def test_class._run_test(self, test_data, expected) - ''' + """ for (i, (test_data, expected)) in enumerate(test_class.tests): def stub_test(self, test_data=test_data, expected=expected): @@ -94,10 +94,10 @@ def setup_tests_loop(test_class): def setup_regex_tests(test_class): - '''Create tests in test_class using test_class.tests and AAParseTest._test_parse_rule() + """Create tests in test_class using test_class.tests and AAParseTest._test_parse_rule() test_class.tests should be tuples of (line, description) - ''' + """ for (i, (line, desc)) in enumerate(test_class.tests): def stub_test(self, line=line): self._test_parse_rule(line) @@ -119,7 +119,7 @@ def setup_aa(aa): def write_file(directory, file, contents): - '''construct path, write contents to it, and return the constructed path''' + """construct path, write contents to it, and return the constructed path""" path = os.path.join(directory, file) with open(path, 'w+') as f: f.write(contents) @@ -127,7 +127,7 @@ def write_file(directory, file, contents): def read_file(path): - '''read and return file contents''' + """read and return file contents""" with open(path, 'r') as f: return f.read() diff --git a/utils/test/test-aa-cli-bootstrap.py b/utils/test/test-aa-cli-bootstrap.py index 9a23b7dde..b789d16ba 100644 --- a/utils/test/test-aa-cli-bootstrap.py +++ b/utils/test/test-aa-cli-bootstrap.py @@ -27,10 +27,10 @@ from apparmor.translations import init_translation class AACliBootstrapTest(AATest): - ''' + """ Generic test of the core AppArmor Python libraries that all command line tools rely on. - ''' + """ def AASetup(self): # Redirect sys.stdout to a buffer sys.stdout = io.StringIO() diff --git a/utils/test/test-aa-decode.py b/utils/test/test-aa-decode.py index 11d378025..55974fc82 100755 --- a/utils/test/test-aa-decode.py +++ b/utils/test/test-aa-decode.py @@ -32,8 +32,8 @@ def subprocess_setup(): # Define only arguments that are actually ever used: command and stdin def cmd(command, stdin=None): - '''Try to execute given command (array) and return its stdout, or return - a textual error if it failed.''' + """Try to execute given command (array) and return its stdout, or return + a textual error if it failed.""" try: sp = subprocess.Popen( @@ -62,7 +62,7 @@ def cmd(command, stdin=None): class AADecodeTest(unittest.TestCase): def test_help(self): - '''Test --help argument''' + """Test --help argument""" expected = 0 rc, report = cmd((aadecode_bin, "--help")) @@ -70,8 +70,8 @@ class AADecodeTest(unittest.TestCase): self.assertEqual(expected, rc, result + report) def _run_file_test(self, content, expected): - '''test case helper function; takes log content and a list of - expected strings as arguments''' + """test case helper function; takes log content and a list of + expected strings as arguments""" expected_return_code = 0 @@ -89,7 +89,7 @@ class AADecodeTest(unittest.TestCase): self.assertIn(expected_string, report, result + report) def test_simple_decode(self): - '''Test simple decode on command line''' + """Test simple decode on command line""" expected = 0 expected_output = 'Decoded: /tmp/foo bar' @@ -102,7 +102,7 @@ class AADecodeTest(unittest.TestCase): self.assertIn(expected_output, report, result + report) def test_simple_filter(self): - '''test simple decoding of the name argument''' + """test simple decoding of the name argument""" expected_string = 'name="/tmp/foo bar"' content = \ @@ -112,7 +112,7 @@ class AADecodeTest(unittest.TestCase): self._run_file_test(content, (expected_string,)) def test_simple_multiline(self): - '''test simple multiline decoding of the name argument''' + """test simple multiline decoding of the name argument""" expected_strings = ( 'ses=4294967295 new ses=2762', @@ -128,9 +128,9 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_profile(self): - '''test simple decoding of the profile argument''' + """test simple decoding of the profile argument""" - '''Example take from LP: #897957''' + # Example take from LP: #897957 expected_strings = ( 'name="/lib/x86_64-linux-gnu/libdl-2.13.so"', 'profile="/test space"') content = \ @@ -140,9 +140,9 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_profile2(self): - '''test simple decoding of name and profile argument''' + """test simple decoding of name and profile argument""" - '''Example take from LP: #897957''' + # Example take from LP: #897957 expected_strings = ('name="/home/steve/tmp/my test file"', 'profile="/home/steve/tmp/my prog.sh"') content = \ @@ -152,7 +152,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_embedded_carat(self): - '''test simple decoding of embedded ^ in files''' + """test simple decoding of embedded ^ in files""" expected_strings = ('name="/home/steve/tmp/my test ^file"',) content = \ @@ -162,7 +162,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_embedded_backslash_carat(self): - '''test simple decoding of embedded \^ in files''' + """test simple decoding of embedded \^ in files""" expected_strings = ('name="/home/steve/tmp/my test \^file"',) content = \ @@ -172,7 +172,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_embedded_singlequote(self): - '''test simple decoding of embedded \' in files''' + """test simple decoding of embedded \' in files""" expected_strings = ('name="/home/steve/tmp/my test \'file"',) content = \ @@ -182,7 +182,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" self._run_file_test(content, expected_strings) def test_simple_encoded_nonpath_profiles(self): - '''test simple decoding of nonpath profiles''' + """test simple decoding of nonpath profiles""" expected_strings = ('name="/lib/x86_64-linux-gnu/libdl-2.13.so"', 'profile="test space"') content = \ diff --git a/utils/test/test-aa-easyprof.py b/utils/test/test-aa-easyprof.py index 2d8687940..693b4f592 100755 --- a/utils/test/test-aa-easyprof.py +++ b/utils/test/test-aa-easyprof.py @@ -26,7 +26,7 @@ debugging = False def recursive_rm(dirPath, contents_only=False): - '''recursively remove directory''' + """recursively remove directory""" names = os.listdir(dirPath) for name in names: path = os.path.join(dirPath, name) @@ -111,7 +111,7 @@ class T(unittest.TestCase): ls = os.path.realpath('/bin/ls') def setUp(self): - '''Setup for tests''' + """Setup for tests""" global topdir self.tmpdir = os.path.realpath(tempfile.mkdtemp(prefix='test-aa-easyprof')) @@ -206,7 +206,7 @@ TEMPLATES_DIR="%s/templates" "inc_%s" % os.path.basename(f))) def tearDown(self): - '''Teardown for tests''' + """Teardown for tests""" if os.path.exists(self.tmpdir): if debugging: sys.stdout.write("%s\n" % self.tmpdir) @@ -217,7 +217,7 @@ TEMPLATES_DIR="%s/templates" # config file tests # def test_configuration_file_p_invalid(self): - '''Test config parsing (invalid POLICYGROUPS_DIR)''' + """Test config parsing (invalid POLICYGROUPS_DIR)""" contents = ''' POLICYGROUPS_DIR= TEMPLATES_DIR="%s/templates" @@ -235,7 +235,7 @@ TEMPLATES_DIR="%s/templates" raise Exception("File should have been invalid") def test_configuration_file_p_empty(self): - '''Test config parsing (empty POLICYGROUPS_DIR)''' + """Test config parsing (empty POLICYGROUPS_DIR)""" contents = ''' POLICYGROUPS_DIR="%s" TEMPLATES_DIR="%s/templates" @@ -253,7 +253,7 @@ TEMPLATES_DIR="%s/templates" raise Exception("File should have been invalid") def test_configuration_file_p_nonexistent(self): - '''Test config parsing (nonexistent POLICYGROUPS_DIR)''' + """Test config parsing (nonexistent POLICYGROUPS_DIR)""" contents = ''' POLICYGROUPS_DIR="%s/policygroups" TEMPLATES_DIR="%s/templates" @@ -271,7 +271,7 @@ TEMPLATES_DIR="%s/templates" raise Exception("File should have been invalid") def test_policygroups_dir_relative(self): - '''Test --policy-groups-dir (relative DIR)''' + """Test --policy-groups-dir (relative DIR)""" os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'relative') os.mkdir(rel) @@ -289,7 +289,7 @@ TEMPLATES_DIR="%s/templates" self.assertFalse(easyp.get_policy_groups() is None, "Could not find policy-groups") def test_policygroups_dir_nonexistent(self): - '''Test --policy-groups-dir (nonexistent DIR)''' + """Test --policy-groups-dir (nonexistent DIR)""" os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'nonexistent') @@ -305,7 +305,7 @@ TEMPLATES_DIR="%s/templates" self.assertTrue(easyp.get_policy_groups() is not None, "Found policy-groups when shouldn't have") def test_policygroups_dir_valid(self): - '''Test --policy-groups-dir (valid DIR)''' + """Test --policy-groups-dir (valid DIR)""" os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) @@ -321,7 +321,7 @@ TEMPLATES_DIR="%s/templates" self.assertFalse(easyp.get_policy_groups() is None, "Could not find policy-groups") def test_policygroups_dir_valid_with_vendor(self): - '''Test --policy-groups-dir (valid DIR with vendor)''' + """Test --policy-groups-dir (valid DIR with vendor)""" os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) @@ -346,7 +346,7 @@ TEMPLATES_DIR="%s/templates" self.assertFalse(os.path.basename(f) == vendor, "Found '%s' in %s" % (vendor, f)) def test_configuration_file_t_invalid(self): - '''Test config parsing (invalid TEMPLATES_DIR)''' + """Test config parsing (invalid TEMPLATES_DIR)""" contents = ''' TEMPLATES_DIR= POLICYGROUPS_DIR="%s/templates" @@ -364,7 +364,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("File should have been invalid") def test_configuration_file_t_empty(self): - '''Test config parsing (empty TEMPLATES_DIR)''' + """Test config parsing (empty TEMPLATES_DIR)""" contents = ''' TEMPLATES_DIR="%s" POLICYGROUPS_DIR="%s/templates" @@ -382,7 +382,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("File should have been invalid") def test_configuration_file_t_nonexistent(self): - '''Test config parsing (nonexistent TEMPLATES_DIR)''' + """Test config parsing (nonexistent TEMPLATES_DIR)""" contents = ''' TEMPLATES_DIR="%s/policygroups" POLICYGROUPS_DIR="%s/templates" @@ -400,7 +400,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("File should have been invalid") def test_templates_dir_relative(self): - '''Test --templates-dir (relative DIR)''' + """Test --templates-dir (relative DIR)""" os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'relative') os.mkdir(rel) @@ -418,7 +418,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(easyp.get_templates() is None, "Could not find templates") def test_templates_dir_nonexistent(self): - '''Test --templates-dir (nonexistent DIR)''' + """Test --templates-dir (nonexistent DIR)""" os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'nonexistent') @@ -434,7 +434,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(easyp.get_templates() is not None, "Found templates when shouldn't have") def test_templates_dir_valid(self): - '''Test --templates-dir (valid DIR)''' + """Test --templates-dir (valid DIR)""" os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) @@ -450,7 +450,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(easyp.get_templates() is None, "Could not find templates") def test_templates_dir_valid_with_vendor(self): - '''Test --templates-dir (valid DIR with vendor)''' + """Test --templates-dir (valid DIR with vendor)""" os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) @@ -477,29 +477,29 @@ POLICYGROUPS_DIR="%s/templates" # Binary file tests # def test_binary_without_profile_name(self): - '''Test binary ( { })''' + """Test binary ( { })""" easyprof.AppArmorEasyProfile(self.ls, self.options) def test_binary_with_profile_name(self): - '''Test binary (profile { })''' + """Test binary (profile { })""" args = self.full_args args += ['--profile-name=some-profile-name'] (self.options, self.args) = easyprof.parse_args(args) easyprof.AppArmorEasyProfile(self.ls, self.options) def test_binary_omitted_with_profile_name(self): - '''Test binary (profile { })''' + """Test binary (profile { })""" args = self.full_args args += ['--profile-name=some-profile-name'] (self.options, self.args) = easyprof.parse_args(args) easyprof.AppArmorEasyProfile(None, self.options) def test_binary_nonexistent(self): - '''Test binary (nonexistent)''' + """Test binary (nonexistent)""" easyprof.AppArmorEasyProfile(os.path.join(self.tmpdir, 'nonexistent'), self.options) def test_binary_relative(self): - '''Test binary (relative)''' + """Test binary (relative)""" try: easyprof.AppArmorEasyProfile('./foo', self.options) except AppArmorException: @@ -509,7 +509,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Binary should have been invalid") def test_binary_symlink(self): - '''Test binary (symlink)''' + """Test binary (symlink)""" exe = os.path.join(self.tmpdir, 'exe') open(exe, 'a').close() symlink = exe + ".lnk" @@ -527,7 +527,7 @@ POLICYGROUPS_DIR="%s/templates" # Templates tests # def test_templates_list(self): - '''Test templates (list)''' + """Test templates (list)""" args = self.full_args args.append('--list-templates') (self.options, self.args) = easyprof.parse_args(args) @@ -537,7 +537,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_templates_show(self): - '''Test templates (show)''' + """Test templates (show)""" files = glob.glob("%s/templates/*" % self.tmpdir) for f in files: args = self.full_args @@ -551,7 +551,7 @@ POLICYGROUPS_DIR="%s/templates" fd.read() def test_templates_list_include(self): - '''Test templates (list with --include-templates-dir)''' + """Test templates (list with --include-templates-dir)""" args = self.full_args args.append('--list-templates') (self.options, self.args) = easyprof.parse_args(args) @@ -574,7 +574,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_templates_show_include(self): - '''Test templates (show with --include-templates-dir)''' + """Test templates (show with --include-templates-dir)""" files = glob.glob("%s/templates/*" % self.test_include_dir) for f in files: args = self.full_args @@ -599,7 +599,7 @@ POLICYGROUPS_DIR="%s/templates" # Policygroups tests # def test_policygroups_list(self): - '''Test policygroups (list)''' + """Test policygroups (list)""" args = self.full_args args.append('--list-policy-groups') (self.options, self.args) = easyprof.parse_args(args) @@ -609,7 +609,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_policygroups_show(self): - '''Test policygroups (show)''' + """Test policygroups (show)""" files = glob.glob("%s/policygroups/*" % self.tmpdir) for f in files: args = self.full_args @@ -624,7 +624,7 @@ POLICYGROUPS_DIR="%s/templates" fd.read() def test_policygroups_list_include(self): - '''Test policygroups (list with --include-policy-groups-dir)''' + """Test policygroups (list with --include-policy-groups-dir)""" args = self.full_args args.append('--list-policy-groups') (self.options, self.args) = easyprof.parse_args(args) @@ -647,7 +647,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_policygroups_show_include(self): - '''Test policygroups (show with --include-policy-groups-dir)''' + """Test policygroups (show with --include-policy-groups-dir)""" files = glob.glob("%s/policygroups/*" % self.test_include_dir) for f in files: args = self.full_args @@ -672,7 +672,7 @@ POLICYGROUPS_DIR="%s/templates" # Manifest file argument tests # def test_manifest_argument(self): - '''Test manifest argument''' + """Test manifest argument""" # setup our manifest self.manifest = os.path.join(self.tmpdir, 'manifest.json') @@ -687,7 +687,7 @@ POLICYGROUPS_DIR="%s/templates" easyprof.parse_args(args) def _manifest_conflicts(self, opt, value): - '''Helper for conflicts tests''' + """Helper for conflicts tests""" # setup our manifest self.manifest = os.path.join(self.tmpdir, 'manifest.json') contents = ''' @@ -721,58 +721,58 @@ POLICYGROUPS_DIR="%s/templates" "raise a parse error" % opt) def test_manifest_conflicts_profilename(self): - '''Test manifest arg conflicts with profile_name arg''' + """Test manifest arg conflicts with profile_name arg""" self._manifest_conflicts("--profile-name", "simple-app") def test_manifest_conflicts_copyright(self): - '''Test manifest arg conflicts with copyright arg''' + """Test manifest arg conflicts with copyright arg""" self._manifest_conflicts("--copyright", "2013-01-01") def test_manifest_conflicts_author(self): - '''Test manifest arg conflicts with author arg''' + """Test manifest arg conflicts with author arg""" self._manifest_conflicts("--author", "Foo Bar") def test_manifest_conflicts_comment(self): - '''Test manifest arg conflicts with comment arg''' + """Test manifest arg conflicts with comment arg""" self._manifest_conflicts("--comment", "some comment") def test_manifest_conflicts_abstractions(self): - '''Test manifest arg conflicts with abstractions arg''' + """Test manifest arg conflicts with abstractions arg""" self._manifest_conflicts("--abstractions", "base") def test_manifest_conflicts_read_path(self): - '''Test manifest arg conflicts with read-path arg''' + """Test manifest arg conflicts with read-path arg""" self._manifest_conflicts("--read-path", "/etc/passwd") def test_manifest_conflicts_write_path(self): - '''Test manifest arg conflicts with write-path arg''' + """Test manifest arg conflicts with write-path arg""" self._manifest_conflicts("--write-path", "/tmp/foo") def test_manifest_conflicts_policy_groups(self): - '''Test manifest arg conflicts with policy-groups arg''' + """Test manifest arg conflicts with policy-groups arg""" self._manifest_conflicts("--policy-groups", "opt-application") def test_manifest_conflicts_name(self): - '''Test manifest arg conflicts with name arg''' + """Test manifest arg conflicts with name arg""" self._manifest_conflicts("--name", "foo") def test_manifest_conflicts_template_var(self): - '''Test manifest arg conflicts with template-var arg''' + """Test manifest arg conflicts with template-var arg""" self._manifest_conflicts("--template-var", "foo") def test_manifest_conflicts_policy_version(self): - '''Test manifest arg conflicts with policy-version arg''' + """Test manifest arg conflicts with policy-version arg""" self._manifest_conflicts("--policy-version", "1.0") def test_manifest_conflicts_policy_vendor(self): - '''Test manifest arg conflicts with policy-vendor arg''' + """Test manifest arg conflicts with policy-vendor arg""" self._manifest_conflicts("--policy-vendor", "somevendor") # # Test genpolicy # def _gen_policy(self, name=None, template=None, extra_args=[]): - '''Generate a policy''' + """Generate a policy""" # Build up our args args = self.full_args @@ -836,7 +836,7 @@ POLICYGROUPS_DIR="%s/templates" return p def test__is_safe(self): - '''Test _is_safe()''' + """Test _is_safe()""" bad = ( "/../../../../etc/passwd", "abstraction with spaces", @@ -850,7 +850,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(easyprof._is_safe(s), "'%s' should be bad" % s) def test_genpolicy_templates_abspath(self): - '''Test genpolicy (abspath to template)''' + """Test genpolicy (abspath to template)""" # create a new template template = os.path.join(self.tmpdir, "test-abspath-template") shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), template) @@ -866,11 +866,11 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) def test_genpolicy_templates_system(self): - '''Test genpolicy (system template)''' + """Test genpolicy (system template)""" self._gen_policy() def test_genpolicy_templates_nonexistent(self): - '''Test genpolicy (nonexistent template)''' + """Test genpolicy (nonexistent template)""" try: self._gen_policy(template=os.path.join(self.tmpdir, "/nonexistent")) except AppArmorException: @@ -880,11 +880,11 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("template should be invalid") def test_genpolicy_name(self): - '''Test genpolicy (name)''' + """Test genpolicy (name)""" self._gen_policy(name='test-foo') def test_genpolicy_comment(self): - '''Test genpolicy (comment)''' + """Test genpolicy (comment)""" s = "test comment" p = self._gen_policy(extra_args=['--comment=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) @@ -892,7 +892,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_author(self): - '''Test genpolicy (author)''' + """Test genpolicy (author)""" s = "Archibald Poindexter" p = self._gen_policy(extra_args=['--author=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) @@ -900,7 +900,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_copyright(self): - '''Test genpolicy (copyright)''' + """Test genpolicy (copyright)""" s = "2112/01/01" p = self._gen_policy(extra_args=['--copyright=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) @@ -908,7 +908,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions(self): - '''Test genpolicy (single abstraction)''' + """Test genpolicy (single abstraction)""" s = "nameservice" p = self._gen_policy(extra_args=['--abstractions=%s' % s]) search = "#include " % s @@ -917,7 +917,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_multiple(self): - '''Test genpolicy (multiple abstractions)''' + """Test genpolicy (multiple abstractions)""" abstractions = "authentication,X,user-tmp" p = self._gen_policy(extra_args=['--abstractions=%s' % abstractions]) for s in abstractions.split(','): @@ -927,7 +927,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_bad(self): - '''Test genpolicy (abstractions - bad values)''' + """Test genpolicy (abstractions - bad values)""" bad = ( "nonexistent", "/../../../../etc/passwd", @@ -943,7 +943,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("abstraction '%s' should be invalid" % s) def _create_tmp_base_dir(self, prefix='', abstractions=[], tunables=[]): - '''Create a temporary base dir layout''' + """Create a temporary base dir layout""" base_name = 'apparmor.d' if prefix: base_name = '%s-%s' % (prefix, base_name) @@ -974,7 +974,7 @@ POLICYGROUPS_DIR="%s/templates" return base_dir def test_genpolicy_abstractions_custom_base(self): - '''Test genpolicy (custom base dir)''' + """Test genpolicy (custom base dir)""" abstraction = "custom-base-dir-test-abstraction" # The default template #includes the base abstraction and global # tunable so we need to create placeholders @@ -988,7 +988,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_custom_base_bad(self): - '''Test genpolicy (custom base dir - bad base dirs)''' + """Test genpolicy (custom base dir - bad base dirs)""" abstraction = "custom-base-dir-test-abstraction" bad = [None, '/etc/apparmor.d', '/'] for base in bad: @@ -1004,7 +1004,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("abstraction '%s' should be invalid" % abstraction) def test_genpolicy_abstractions_custom_include(self): - '''Test genpolicy (custom include dir)''' + """Test genpolicy (custom include dir)""" abstraction = "custom-include-dir-test-abstraction" # No need to create placeholders for the base abstraction or global # tunable since we're not adjusting the base directory @@ -1017,7 +1017,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_custom_include_bad(self): - '''Test genpolicy (custom include dir - bad include dirs)''' + """Test genpolicy (custom include dir - bad include dirs)""" abstraction = "custom-include-dir-test-abstraction" bad = [None, '/etc/apparmor.d', '/'] for include in bad: @@ -1033,7 +1033,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("abstraction '%s' should be invalid" % abstraction) def test_genpolicy_profile_name_bad(self): - '''Test genpolicy (profile name - bad values)''' + """Test genpolicy (profile name - bad values)""" bad = [ "/../../../../etc/passwd", "../../../../etc/passwd", @@ -1049,7 +1049,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("profile_name '%s' should be invalid" % s) def test_genpolicy_policy_group_bad(self): - '''Test genpolicy (policy group - bad values)''' + """Test genpolicy (policy group - bad values)""" bad = [ "/../../../../etc/passwd", "../../../../etc/passwd", @@ -1065,7 +1065,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("policy group '%s' should be invalid" % s) def test_genpolicy_policygroups(self): - '''Test genpolicy (single policygroup)''' + """Test genpolicy (single policygroup)""" groups = self.test_policygroup p = self._gen_policy(extra_args=['--policy-groups=%s' % groups]) @@ -1075,7 +1075,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_policygroups_multiple(self): - '''Test genpolicy (multiple policygroups)''' + """Test genpolicy (multiple policygroups)""" test_policygroup2 = "test-policygroup2" contents = ''' # %s @@ -1097,7 +1097,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_policygroups_nonexistent(self): - '''Test genpolicy (nonexistent policygroup)''' + """Test genpolicy (nonexistent policygroup)""" try: self._gen_policy(extra_args=['--policy-groups=nonexistent']) except AppArmorException: @@ -1107,7 +1107,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("policygroup should be invalid") def test_genpolicy_readpath_file(self): - '''Test genpolicy (read-path file)''' + """Test genpolicy (read-path file)""" s = "/opt/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "%s rk," % s @@ -1116,7 +1116,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_home_file(self): - '''Test genpolicy (read-path file in /home)''' + """Test genpolicy (read-path file in /home)""" s = "/home/*/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s @@ -1125,7 +1125,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_homevar_file(self): - '''Test genpolicy (read-path file in @{HOME})''' + """Test genpolicy (read-path file in @{HOME})""" s = "@{HOME}/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s @@ -1134,7 +1134,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_homedirs_file(self): - '''Test genpolicy (read-path file in @{HOMEDIRS})''' + """Test genpolicy (read-path file in @{HOMEDIRS})""" s = "@{HOMEDIRS}/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s @@ -1143,7 +1143,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir(self): - '''Test genpolicy (read-path directory/)''' + """Test genpolicy (read-path directory/)""" s = "/opt/test-foo-dir/" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % s, "%s** rk," % s] @@ -1153,7 +1153,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir_glob(self): - '''Test genpolicy (read-path directory/*)''' + """Test genpolicy (read-path directory/*)""" s = "/opt/test-foo-dir/*" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % os.path.dirname(s), "%s rk," % s] @@ -1163,7 +1163,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir_glob_all(self): - '''Test genpolicy (read-path directory/**)''' + """Test genpolicy (read-path directory/**)""" s = "/opt/test-foo-dir/**" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % os.path.dirname(s), "%s rk," % s] @@ -1173,7 +1173,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_multiple(self): - '''Test genpolicy (read-path multiple)''' + """Test genpolicy (read-path multiple)""" paths = [ "/opt/test-foo", "/home/*/test-foo", @@ -1207,7 +1207,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_bad(self): - '''Test genpolicy (read-path bad)''' + """Test genpolicy (read-path bad)""" s = "bar" try: self._gen_policy(extra_args=['--read-path=%s' % s]) @@ -1218,7 +1218,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("read-path should be invalid") def test_genpolicy_writepath_file(self): - '''Test genpolicy (write-path file)''' + """Test genpolicy (write-path file)""" s = "/opt/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "%s rwk," % s @@ -1227,7 +1227,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_home_file(self): - '''Test genpolicy (write-path file in /home)''' + """Test genpolicy (write-path file in /home)""" s = "/home/*/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s @@ -1236,7 +1236,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_homevar_file(self): - '''Test genpolicy (write-path file in @{HOME})''' + """Test genpolicy (write-path file in @{HOME})""" s = "@{HOME}/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s @@ -1245,7 +1245,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_homedirs_file(self): - '''Test genpolicy (write-path file in @{HOMEDIRS})''' + """Test genpolicy (write-path file in @{HOMEDIRS})""" s = "@{HOMEDIRS}/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s @@ -1254,7 +1254,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir(self): - '''Test genpolicy (write-path directory/)''' + """Test genpolicy (write-path directory/)""" s = "/opt/test-foo-dir/" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % s, "%s** rwk," % s] @@ -1264,7 +1264,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir_glob(self): - '''Test genpolicy (write-path directory/*)''' + """Test genpolicy (write-path directory/*)""" s = "/opt/test-foo-dir/*" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % os.path.dirname(s), "%s rwk," % s] @@ -1274,7 +1274,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir_glob_all(self): - '''Test genpolicy (write-path directory/**)''' + """Test genpolicy (write-path directory/**)""" s = "/opt/test-foo-dir/**" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % os.path.dirname(s), "%s rwk," % s] @@ -1284,7 +1284,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_multiple(self): - '''Test genpolicy (write-path multiple)''' + """Test genpolicy (write-path multiple)""" paths = [ "/opt/test-foo", "/home/*/test-foo", @@ -1318,7 +1318,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_bad(self): - '''Test genpolicy (write-path bad)''' + """Test genpolicy (write-path bad)""" s = "bar" try: self._gen_policy(extra_args=['--write-path=%s' % s]) @@ -1329,7 +1329,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("write-path should be invalid") def test_genpolicy_templatevar(self): - '''Test genpolicy (template-var single)''' + """Test genpolicy (template-var single)""" s = "@{FOO}=bar" p = self._gen_policy(extra_args=['--template-var=%s' % s]) k, v = s.split('=') @@ -1339,7 +1339,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_templatevar_multiple(self): - '''Test genpolicy (template-var multiple)''' + """Test genpolicy (template-var multiple)""" variables = ['@{FOO}=bar', '@{BAR}=baz'] args = [] for s in variables: @@ -1354,7 +1354,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_templatevar_bad(self): - '''Test genpolicy (template-var - bad values)''' + """Test genpolicy (template-var - bad values)""" bad = [ "{FOO}=bar", "@FOO}=bar", @@ -1376,7 +1376,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("template-var should be invalid") def test_genpolicy_invalid_template_policy(self): - '''Test genpolicy (invalid template policy)''' + """Test genpolicy (invalid template policy)""" # create a new template template = os.path.join(self.tmpdir, "test-invalid-template") shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), template) @@ -1401,7 +1401,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("policy should be invalid") def test_genpolicy_no_binary_without_profile_name(self): - '''Test genpolicy (no binary with no profile name)''' + """Test genpolicy (no binary with no profile name)""" try: easyprof.gen_policy_params(None, self.options) except AppArmorException: @@ -1411,7 +1411,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("No binary or profile name should have been invalid") def test_genpolicy_with_binary_with_profile_name(self): - '''Test genpolicy (binary with profile name)''' + """Test genpolicy (binary with profile name)""" profile_name = "some-profile-name" p = self._gen_policy(extra_args=['--profile-name=%s' % profile_name]) s = 'profile "%s" "%s" {' % (profile_name, self.binary) @@ -1420,7 +1420,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_with_binary_without_profile_name(self): - '''Test genpolicy (binary without profile name)''' + """Test genpolicy (binary without profile name)""" p = self._gen_policy() s = '"%s" {' % (self.binary) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) @@ -1428,7 +1428,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_without_binary_with_profile_name(self): - '''Test genpolicy (no binary with profile name)''' + """Test genpolicy (no binary with profile name)""" profile_name = "some-profile-name" args = self.full_args args.append('--profile-name=%s' % profile_name) @@ -1444,30 +1444,30 @@ POLICYGROUPS_DIR="%s/templates" # manifest tests def test_gen_manifest_policy_with_binary_with_profile_name(self): - '''Test gen_manifest_policy (binary with profile name)''' + """Test gen_manifest_policy (binary with profile name)""" m = Manifest("test_gen_manifest_policy") m.add_binary(self.ls) self._gen_manifest_policy(m) def test_gen_manifest_policy_without_binary_with_profile_name(self): - '''Test gen_manifest_policy (no binary with profile name)''' + """Test gen_manifest_policy (no binary with profile name)""" m = Manifest("test_gen_manifest_policy") self._gen_manifest_policy(m) def test_gen_manifest_policy_templates_system(self): - '''Test gen_manifest_policy (system template)''' + """Test gen_manifest_policy (system template)""" m = Manifest("test_gen_manifest_policy") m.add_template(self.test_template) self._gen_manifest_policy(m) def test_gen_manifest_policy_templates_system_noprefix(self): - '''Test gen_manifest_policy (system template, no security prefix)''' + """Test gen_manifest_policy (system template, no security prefix)""" m = Manifest("test_gen_manifest_policy") m.add_template(self.test_template) self._gen_manifest_policy(m, use_security_prefix=False) def test_gen_manifest_abs_path_template(self): - '''Test gen_manifest_policy (abs path template)''' + """Test gen_manifest_policy (abs path template)""" m = Manifest("test_gen_manifest_policy") m.add_template("/etc/shadow") try: @@ -1479,7 +1479,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("abs path template name should be invalid") def test_gen_manifest_escape_path_templates(self): - '''Test gen_manifest_policy (esc path template)''' + """Test gen_manifest_policy (esc path template)""" m = Manifest("test_gen_manifest_policy") m.add_template("../../../../../../../../etc/shadow") try: @@ -1491,7 +1491,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("../ template name should be invalid") def test_gen_manifest_policy_templates_nonexistent(self): - '''Test gen manifest policy (nonexistent template)''' + """Test gen manifest policy (nonexistent template)""" m = Manifest("test_gen_manifest_policy") m.add_template("nonexistent") try: @@ -1503,7 +1503,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("template should be invalid") def test_gen_manifest_policy_comment(self): - '''Test gen manifest policy (comment)''' + """Test gen manifest policy (comment)""" s = "test comment" m = Manifest("test_gen_manifest_policy") m.add_comment(s) @@ -1513,7 +1513,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_author(self): - '''Test gen manifest policy (author)''' + """Test gen manifest policy (author)""" s = "Archibald Poindexter" m = Manifest("test_gen_manifest_policy") m.add_author(s) @@ -1523,7 +1523,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_copyright(self): - '''Test genpolicy (copyright)''' + """Test genpolicy (copyright)""" s = "2112/01/01" m = Manifest("test_gen_manifest_policy") m.add_copyright(s) @@ -1533,7 +1533,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups(self): - '''Test gen manifest policy (single policygroup)''' + """Test gen manifest policy (single policygroup)""" groups = self.test_policygroup m = Manifest("test_gen_manifest_policy") m.add_policygroups(groups) @@ -1545,7 +1545,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups_multiple(self): - '''Test genpolicy (multiple policygroups)''' + """Test genpolicy (multiple policygroups)""" test_policygroup2 = "test-policygroup2" contents = ''' # %s @@ -1569,7 +1569,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups_nonexistent(self): - '''Test gen manifest policy (nonexistent policygroup)''' + """Test gen manifest policy (nonexistent policygroup)""" groups = "nonexistent" m = Manifest("test_gen_manifest_policy") m.add_policygroups(groups) @@ -1582,7 +1582,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("policygroup should be invalid") def test_gen_manifest_policy_templatevar(self): - '''Test gen manifest policy (template-var single)''' + """Test gen manifest policy (template-var single)""" m = Manifest("test_gen_manifest_policy") m.add_template_variable("FOO", "bar") p = self._gen_manifest_policy(m) @@ -1592,7 +1592,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_templatevar_multiple(self): - '''Test gen manifest policy (template-var multiple)''' + """Test gen manifest policy (template-var multiple)""" variables = [["FOO", "bar"], ["BAR", "baz"]] m = Manifest("test_gen_manifest_policy") for s in variables: @@ -1606,7 +1606,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_invalid_keys(self): - '''Test gen manifest policy (invalid keys)''' + """Test gen manifest policy (invalid keys)""" keys = [ 'config_file', 'debug', @@ -1642,7 +1642,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("'%s' should be invalid" % k) def test_gen_manifest(self): - '''Test gen_manifest''' + """Test gen_manifest""" # this should come from manpage m = '''{ "security": { @@ -1698,7 +1698,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertEqual(m, man_new) def test_gen_manifest_ubuntu(self): - '''Test gen_manifest (ubuntu)''' + """Test gen_manifest (ubuntu)""" # this should be based on the manpage (but use existing policy_groups # and template m = '''{ @@ -1738,7 +1738,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertEqual(m, man_new) def test_parse_manifest_no_version(self): - '''Test parse_manifest (vendor with no version)''' + """Test parse_manifest (vendor with no version)""" # this should come from manpage m = '''{ "security": { @@ -1770,7 +1770,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed on missing version") def test_parse_manifest_no_vendor(self): - '''Test parse_manifest (version with no vendor)''' + """Test parse_manifest (version with no vendor)""" # this should come from manpage m = '''{ "security": { @@ -1802,7 +1802,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed on missing vendor") def test_parse_manifest_multiple(self): - '''Test parse_manifest_multiple''' + """Test parse_manifest_multiple""" m = '''{ "security": { "profiles": { @@ -1883,7 +1883,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(easyprof.verify_manifest(params, args), "params=%s\nmanifest=%s" % (params, m)) def test_verify_manifest_full(self): - '''Test verify_manifest (full)''' + """Test verify_manifest (full)""" m = '''{ "security": { "profiles": { @@ -1912,7 +1912,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=True) def test_verify_manifest_full_bad(self): - '''Test verify_manifest (full bad)''' + """Test verify_manifest (full bad)""" m = '''{ "security": { "profiles": { @@ -1958,7 +1958,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False, invalid=True) def test_verify_manifest_binary(self): - '''Test verify_manifest (binary in /usr)''' + """Test verify_manifest (binary in /usr)""" m = '''{ "security": { "profiles": { @@ -1972,7 +1972,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=True) def test_verify_manifest_profile_profile_name_bad(self): - '''Test verify_manifest (bad profile_name)''' + """Test verify_manifest (bad profile_name)""" m = '''{ "security": { "profiles": { @@ -1998,7 +1998,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False) def test_verify_manifest_profile_profile_name(self): - '''Test verify_manifest (profile_name)''' + """Test verify_manifest (profile_name)""" m = '''{ "security": { "profiles": { @@ -2012,7 +2012,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=True) def test_verify_manifest_profile_abstractions(self): - '''Test verify_manifest (abstractions)''' + """Test verify_manifest (abstractions)""" m = '''{ "security": { "profiles": { @@ -2029,7 +2029,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=True) def test_verify_manifest_profile_abstractions_bad(self): - '''Test verify_manifest (bad abstractions)''' + """Test verify_manifest (bad abstractions)""" m = '''{ "security": { "profiles": { @@ -2046,7 +2046,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False) def test_verify_manifest_profile_template_var(self): - '''Test verify_manifest (good template_var)''' + """Test verify_manifest (good template_var)""" m = '''{ "security": { "profiles": { @@ -2065,7 +2065,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=True) def test_verify_manifest_profile_template_var_bad(self): - '''Test verify_manifest (bad template_var)''' + """Test verify_manifest (bad template_var)""" for v in ('"VAR1": "f*o"', '"VAR2": "*foo"', '"VAR3": "fo*"', @@ -2092,7 +2092,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False) def test_manifest_invalid(self): - '''Test invalid manifest (parse error)''' + """Test invalid manifest (parse error)""" m = '''{ "security": { "com.example.foo": { @@ -2105,7 +2105,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid2(self): - '''Test invalid manifest (profile_name is not key)''' + """Test invalid manifest (profile_name is not key)""" m = '''{ "security": { "binary": "/opt/com.example/foo/**", @@ -2118,7 +2118,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid3(self): - '''Test invalid manifest (profile_name in dict)''' + """Test invalid manifest (profile_name in dict)""" m = '''{ "security": { "binary": "/opt/com.example/foo/**", @@ -2132,7 +2132,7 @@ POLICYGROUPS_DIR="%s/templates" self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid4(self): - '''Test invalid manifest (bad path in template var)''' + """Test invalid manifest (bad path in template var)""" for v in ('"VAR1": "/tmp/../etc/passwd"', '"VAR2": "./"', '"VAR3": "foo\"bar"', @@ -2165,7 +2165,7 @@ POLICYGROUPS_DIR="%s/templates" # policy version tests def test_policy_vendor_manifest_nonexistent(self): - '''Test policy vendor via manifest (nonexistent)''' + """Test policy vendor via manifest (nonexistent)""" m = '''{ "security": { "profiles": { @@ -2192,7 +2192,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with non-existent directory") def test_policy_version_manifest(self): - '''Test policy version via manifest (good)''' + """Test policy version via manifest (good)""" policy_vendor = "somevendor" policy_version = "1.0" policy_subdir = "%s/%s" % (policy_vendor, policy_version) @@ -2232,7 +2232,7 @@ POLICYGROUPS_DIR="%s/templates" easyp.gen_policy(**params) def test_policy_vendor_version_args(self): - '''Test policy vendor and version via command line args (good)''' + """Test policy vendor and version via command line args (good)""" policy_version = "1.0" policy_vendor = "somevendor" policy_subdir = "%s/%s" % (policy_vendor, policy_version) @@ -2265,7 +2265,7 @@ POLICYGROUPS_DIR="%s/templates" easyp.gen_policy(**params) def test_policy_vendor_args_nonexistent(self): - '''Test policy vendor via command line args (nonexistent)''' + """Test policy vendor via command line args (nonexistent)""" policy_vendor = "nonexistent" policy_version = "1.0" args = self.full_args @@ -2282,7 +2282,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with non-existent directory") def test_policy_version_args_bad(self): - '''Test policy version via command line args (bad)''' + """Test policy version via command line args (bad)""" bad = [ "../../../../../../etc", "notanumber", @@ -2304,7 +2304,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with bad version") def test_policy_vendor_args_bad(self): - '''Test policy vendor via command line args (bad)''' + """Test policy vendor via command line args (bad)""" bad = [ "../../../../../../etc", "vendor with space", @@ -2326,7 +2326,7 @@ POLICYGROUPS_DIR="%s/templates" # output_directory tests def test_output_directory_multiple(self): - '''Test output_directory (multiple)''' + """Test output_directory (multiple)""" files = dict() files["com.example.foo"] = "com.example.foo" files["com.ubuntu.developer.myusername.MyCoolApp"] = "com.ubuntu.developer.myusername.MyCoolApp" @@ -2407,7 +2407,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(f), "Could not find '%s'" % f) def test_output_directory_single(self): - '''Test output_directory (single)''' + """Test output_directory (single)""" files = dict() files["com.example.foo"] = "com.example.foo" m = '''{ @@ -2462,7 +2462,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(f), "Could not find '%s'" % f) def test_output_directory_invalid(self): - '''Test output_directory (output directory exists as file)''' + """Test output_directory (output directory exists as file)""" files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ @@ -2499,7 +2499,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with 'is not a directory'") def test_output_directory_invalid_params(self): - '''Test output_directory (no binary or profile_name)''' + """Test output_directory (no binary or profile_name)""" files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ @@ -2536,7 +2536,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with 'Must specify binary and/or profile name'") def test_output_directory_invalid2(self): - '''Test output_directory (profile exists)''' + """Test output_directory (profile exists)""" files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ @@ -2574,7 +2574,7 @@ POLICYGROUPS_DIR="%s/templates" raise Exception("Should have failed with 'already exists'") def test_output_directory_args(self): - '''Test output_directory (args)''' + """Test output_directory (args)""" files = dict() files["usr.bin.baz"] = "/usr/bin/baz" @@ -2600,7 +2600,7 @@ POLICYGROUPS_DIR="%s/templates" # utility classes # def test_valid_profile_name(self): - '''Test valid_profile_name''' + """Test valid_profile_name""" names = [ 'foo', 'com.example.foo', @@ -2611,7 +2611,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(easyprof.valid_profile_name(n), "'%s' should be valid" % n) def test_valid_profile_name_invalid(self): - '''Test valid_profile_name (invalid)''' + """Test valid_profile_name (invalid)""" names = [ 'fo/o', '/../../etc/passwd', @@ -2653,7 +2653,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertFalse(easyprof.valid_profile_name(n), "'%s' should be invalid" % n) def test_valid_path(self): - '''Test valid_path''' + """Test valid_path""" names = [ '/bin/bar', '/etc/apparmor.d/com.example.app_myapp_1:2.3+ab12~foo', @@ -2669,7 +2669,7 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(easyprof.valid_path(n, relative_ok=True), "'%s' should be valid" % n) def test_zz_valid_path_invalid(self): - '''Test valid_path (invalid)''' + """Test valid_path (invalid)""" names = [ '/bin//bar', 'bin/bar', diff --git a/utils/test/test-aa-notify.py b/utils/test/test-aa-notify.py index 6facd05a6..22a23b51d 100644 --- a/utils/test/test-aa-notify.py +++ b/utils/test/test-aa-notify.py @@ -36,8 +36,8 @@ def subprocess_setup(): def cmd(command): - '''Try to execute given command (array) and return its stdout, or return - a textual error if it failed.''' + """Try to execute given command (array) and return its stdout, or return + a textual error if it failed.""" try: sp = subprocess.Popen( @@ -66,7 +66,7 @@ def cmd(command): class AANotifyTest(AATest): def AASetup(self): - '''Create temporary log file with 30 enties of different age''' + """Create temporary log file with 30 enties of different age""" test_logfile_contents_999_days_old = \ '''Feb 4 13:40:38 XPS-13-9370 kernel: [128552.834382] audit: type=1400 audit({epoch}:113): apparmor="ALLOWED" operation="exec" profile="libreoffice-soffice" name="/bin/uname" pid=4097 comm="sh" requested_mask="x" denied_mask="x" fsuid=1001 ouid=0 target="libreoffice-soffice//null-/bin/uname" @@ -123,7 +123,7 @@ Feb 4 13:40:38 XPS-13-9370 kernel: [128552.880347] audit: type=1400 audit({epoc ) def AATeardown(self): - '''Remove temporary log file after tests ended''' + """Remove temporary log file after tests ended""" if self.test_logfile and os.path.exists(self.test_logfile): os.remove(self.test_logfile) @@ -132,7 +132,7 @@ Feb 4 13:40:38 XPS-13-9370 kernel: [128552.880347] audit: type=1400 audit({epoc # before printing help when invoked without arguments (sic!). @unittest.skipUnless(os.path.isfile('/var/log/kern.log'), 'Requires kern.log on system') def test_no_arguments(self): - '''Test using no arguments at all''' + """Test using no arguments at all""" expected_return_code = 0 expected_output_has = 'usage: aa-notify' @@ -144,7 +144,7 @@ Feb 4 13:40:38 XPS-13-9370 kernel: [128552.880347] audit: type=1400 audit({epoc self.assertIn(expected_output_has, output, result + output) def test_help_contents(self): - '''Test output of help text''' + """Test output of help text""" expected_return_code = 0 expected_output_1 = \ @@ -180,7 +180,7 @@ Display AppArmor notifications or messages for DENIED entries. self.assertIn(expected_output_2, output) def test_entries_since_100_days(self): - '''Test showing log entries since 100 days''' + """Test showing log entries since 100 days""" expected_return_code = 0 expected_output_has = 'AppArmor denials: 20 (since' @@ -193,7 +193,7 @@ Display AppArmor notifications or messages for DENIED entries. @unittest.skipUnless(os.path.isfile('/var/log/wtmp'), 'Requires wtmp on system') def test_entries_since_login(self): - '''Test showing log entries since last login''' + """Test showing log entries since last login""" expected_return_code = 0 expected_output_has = 'AppArmor denials: 10 (since' @@ -208,7 +208,7 @@ Display AppArmor notifications or messages for DENIED entries. @unittest.skipUnless(os.path.isfile('/var/log/wtmp'), 'Requires wtmp on system') def test_entries_since_login_verbose(self): - '''Test showing log entries since last login in verbose mode''' + """Test showing log entries since last login in verbose mode""" expected_return_code = 0 expected_output_has = \ diff --git a/utils/test/test-libapparmor-test_multi.py b/utils/test/test-libapparmor-test_multi.py index 1161832e2..7aadee6ee 100644 --- a/utils/test/test-libapparmor-test_multi.py +++ b/utils/test/test-libapparmor-test_multi.py @@ -22,7 +22,7 @@ from apparmor.profile_list import ProfileList class TestLibapparmorTestMulti(AATest): - '''Parse all libraries/libapparmor/testsuite/test_multi tests and compare the result with the *.out files''' + """Parse all libraries/libapparmor/testsuite/test_multi tests and compare the result with the *.out files""" tests = 'invalid' # filled by parse_test_profiles() @@ -108,7 +108,7 @@ class TestLibapparmorTestMulti(AATest): } def _parse_libapparmor_test_multi(self, file_with_path): - '''parse the libapparmor test_multi *.in tests and their expected result in *.out''' + """parse the libapparmor test_multi *.in tests and their expected result in *.out""" with open_file_read('%s.out' % file_with_path) as f_in: expected = f_in.readlines() @@ -185,7 +185,7 @@ log_to_profile_known_empty_log = [ class TestLogToProfile(AATest): - '''Check if the libraries/libapparmor/testsuite/test_multi tests result in the expected profile''' + """Check if the libraries/libapparmor/testsuite/test_multi tests result in the expected profile""" tests = 'invalid' # filled by parse_test_profiles() @@ -284,7 +284,7 @@ def logfile_to_profile(logfile): def find_test_multi(log_dir): - '''find all log sniplets in the given log_dir''' + """find all log sniplets in the given log_dir""" log_dir = os.path.abspath(log_dir) diff --git a/utils/test/test-parser-simple-tests.py b/utils/test/test-parser-simple-tests.py index 1e9414d50..e0eb66eae 100644 --- a/utils/test/test-parser-simple-tests.py +++ b/utils/test/test-parser-simple-tests.py @@ -437,7 +437,7 @@ class TestParseParserTests(AATest): def parse_test_profiles(file_with_path): - '''parse the test-related headers of a profile (for example EXRESULT) and add the profile to the set of tests''' + """parse the test-related headers of a profile (for example EXRESULT) and add the profile to the set of tests""" exresult = None exresult_found = False description = None @@ -506,11 +506,11 @@ def parse_test_profiles(file_with_path): def find_and_setup_test_profiles(profile_dir): - '''find all profiles in the given profile_dir, excluding + """find all profiles in the given profile_dir, excluding - skippable files - include directories - files in the main directory (readme, todo etc.) - ''' + """ skipped = 0 profile_dir = os.path.abspath(profile_dir) diff --git a/utils/test/test-regex_matches.py b/utils/test/test-regex_matches.py index 828c210b3..287ee3b4a 100644 --- a/utils/test/test-regex_matches.py +++ b/utils/test/test-regex_matches.py @@ -27,13 +27,13 @@ class AARegexTest(AATest): class AANamedRegexTest(AATest): def _run_test(self, line, expected): - '''Run a line through self.regex.search() and verify the result + """Run a line through self.regex.search() and verify the result Keyword arguments: line -- the line to search expected -- False if the search isn't expected to match or, if the search is expected to match, a tuple of expected match groups. - ''' + """ matches = self.regex.search(line) if not expected: self.assertFalse(matches) @@ -49,7 +49,7 @@ class AANamedRegexTest(AATest): class AARegexHasComma(AATest): - '''Tests for apparmor.aa.RE_RULE_HAS_COMMA''' + """Tests for apparmor.aa.RE_RULE_HAS_COMMA""" def _check(self, line, expected=True): result = aa.RE_RULE_HAS_COMMA.search(line) @@ -135,7 +135,7 @@ def setup_has_comma_testcases(): class AARegexSplitComment(AATest): - '''Tests for RE_HAS_COMMENT_SPLIT''' + """Tests for RE_HAS_COMMENT_SPLIT""" def _check(self, line, expected, comment=None, not_comment=None): result = aa.RE_HAS_COMMENT_SPLIT.search(line) @@ -189,14 +189,14 @@ def setup_split_comment_testcases(): def _regex_test(self, line, expected): - '''Run a line through self.regex.search() and verify the result + """Run a line through self.regex.search() and verify the result Keyword arguments: line -- the line to search expected -- False if the search isn't expected to match or, if the search is expected to match, a tuple of expected match groups with all of the strings stripped - ''' + """ result = self.regex.search(line) if not expected: self.assertFalse(result) @@ -213,7 +213,7 @@ def _regex_test(self, line, expected): class AARegexCapability(AARegexTest): - '''Tests for RE_PROFILE_CAP''' + """Tests for RE_PROFILE_CAP""" def AASetup(self): self.regex = RE_PROFILE_CAP @@ -228,7 +228,7 @@ class AARegexCapability(AARegexTest): class AARegexDbus(AARegexTest): - '''Tests for RE_PROFILE_DBUS''' + """Tests for RE_PROFILE_DBUS""" def AASetup(self): self.regex = RE_PROFILE_DBUS @@ -245,7 +245,7 @@ class AARegexDbus(AARegexTest): class AARegexMount(AARegexTest): - '''Tests for RE_PROFILE_MOUNT''' + """Tests for RE_PROFILE_MOUNT""" def AASetup(self): self.regex = aa.RE_PROFILE_MOUNT @@ -268,7 +268,7 @@ class AARegexMount(AARegexTest): class AARegexSignal(AARegexTest): - '''Tests for RE_PROFILE_SIGNAL''' + """Tests for RE_PROFILE_SIGNAL""" def AASetup(self): self.regex = RE_PROFILE_SIGNAL @@ -289,7 +289,7 @@ class AARegexSignal(AARegexTest): class AARegexPtrace(AARegexTest): - '''Tests for RE_PROFILE_PTRACE''' + """Tests for RE_PROFILE_PTRACE""" def AASetup(self): self.regex = RE_PROFILE_PTRACE @@ -310,7 +310,7 @@ class AARegexPtrace(AARegexTest): class AARegexPivotRoot(AARegexTest): - '''Tests for RE_PROFILE_PIVOT_ROOT''' + """Tests for RE_PROFILE_PIVOT_ROOT""" def AASetup(self): self.regex = aa.RE_PROFILE_PIVOT_ROOT @@ -334,7 +334,7 @@ class AARegexPivotRoot(AARegexTest): class AARegexUnix(AARegexTest): - '''Tests for RE_PROFILE_UNIX''' + """Tests for RE_PROFILE_UNIX""" def AASetup(self): self.regex = aa.RE_PROFILE_UNIX @@ -356,7 +356,7 @@ class AARegexUnix(AARegexTest): class AANamedRegexProfileStart_2(AANamedRegexTest): - '''Tests for RE_PROFILE_START''' + """Tests for RE_PROFILE_START""" def AASetup(self): self.regex = RE_PROFILE_START diff --git a/utils/vim/create-apparmor.vim.py b/utils/vim/create-apparmor.vim.py index e0b363c8e..6afa2ca97 100644 --- a/utils/vim/create-apparmor.vim.py +++ b/utils/vim/create-apparmor.vim.py @@ -25,8 +25,8 @@ danger_caps = ("audit_control", def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=None): - '''Try to execute given command (array) and return its stdout, or - return a textual error if it failed.''' + """Try to execute given command (array) and return its stdout, or + return a textual error if it failed.""" try: sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, universal_newlines=True)