Speed up list creations, and change lists to tuples where appropriate..

This commit is contained in:
Mark Grassi 2022-06-18 14:30:49 -04:00
parent 36c704ce04
commit 7581c9e113
55 changed files with 1756 additions and 1770 deletions

View file

@ -98,7 +98,8 @@ class AAParserCachingCommon(testlib.AATestTemplate):
shutil.rmtree(self.tmp_dir) shutil.rmtree(self.tmp_dir)
def get_cache_dir(self, create=False): def get_cache_dir(self, create=False):
cmd = [config.parser, '--print-cache-dir'] + self.cmd_prefix cmd = [config.parser, '--print-cache-dir']
cmd.extend(self.cmd_prefix)
rc, report = self.run_cmd(cmd) rc, report = self.run_cmd(cmd)
if rc != 0: if rc != 0:
if "unrecognized option '--print-cache-dir'" not in report: if "unrecognized option '--print-cache-dir'" not in report:
@ -153,7 +154,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon):
'''test profiles are not cached by default''' '''test profiles are not cached by default'''
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '-r', self.profile]) cmd.extend(('-q', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False)
@ -161,7 +162,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon):
'''test profiles are not cached with --skip-cache''' '''test profiles are not cached with --skip-cache'''
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '--write-cache', '--skip-cache', '-r', self.profile]) cmd.extend(('-q', '--write-cache', '--skip-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False)
@ -169,7 +170,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon):
'''test profiles are cached when requested''' '''test profiles are cached when requested'''
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '--write-cache', '-r', self.profile]) cmd.extend(('-q', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE))
@ -177,7 +178,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon):
'''test features file is written when caching''' '''test features file is written when caching'''
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '--write-cache', '-r', self.profile]) cmd.extend(('-q', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE))
self.assert_path_exists(os.path.join(self.cache_dir, '.features')) self.assert_path_exists(os.path.join(self.cache_dir, '.features'))
@ -188,7 +189,7 @@ class AAParserBasicCachingTests(AAParserCachingCommon):
self.require_apparmorfs() self.require_apparmorfs()
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '--write-cache', '-r', self.profile]) cmd.extend(('-q', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE))
self.assert_path_exists(os.path.join(self.cache_dir, '.features')) self.assert_path_exists(os.path.join(self.cache_dir, '.features'))
@ -206,7 +207,7 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
os.chmod(alt_cache_loc, 0o755) os.chmod(alt_cache_loc, 0o755)
self.unused_cache_loc = self.cache_dir self.unused_cache_loc = self.cache_dir
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc]) self.cmd_prefix.extend(('--cache-loc', alt_cache_loc))
self.cache_dir = self.get_cache_dir() self.cache_dir = self.get_cache_dir()
def tearDown(self): def tearDown(self):
@ -253,7 +254,7 @@ class AAParserCachingTests(AAParserCachingCommon):
def _generate_cache_file(self): def _generate_cache_file(self):
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-q', '--write-cache', '-r', self.profile]) cmd.extend(('-q', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
self.assert_path_exists(self.cache_file) self.assert_path_exists(self.cache_file)
@ -282,7 +283,7 @@ class AAParserCachingTests(AAParserCachingCommon):
self._generate_cache_file() self._generate_cache_file()
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', self.profile]) cmd.extend(('-v', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Cached reload succeeded') self.run_cmd_check(cmd, expected_string='Cached reload succeeded')
def test_cache_not_loaded_when_skip_arg(self): def test_cache_not_loaded_when_skip_arg(self):
@ -291,7 +292,7 @@ class AAParserCachingTests(AAParserCachingCommon):
self._generate_cache_file() self._generate_cache_file()
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--skip-cache', '-r', self.profile]) cmd.extend(('-v', '--skip-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
def test_cache_not_loaded_when_skip_read_arg(self): def test_cache_not_loaded_when_skip_read_arg(self):
@ -300,7 +301,7 @@ class AAParserCachingTests(AAParserCachingCommon):
self._generate_cache_file() self._generate_cache_file()
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--skip-read-cache', '-r', self.profile]) cmd.extend(('-v', '--skip-read-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
def test_cache_not_loaded_when_features_differ(self): def test_cache_not_loaded_when_features_differ(self):
@ -311,7 +312,7 @@ class AAParserCachingTests(AAParserCachingCommon):
testlib.write_file(self.cache_dir, '.features', 'monkey\n') testlib.write_file(self.cache_dir, '.features', 'monkey\n')
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', self.profile]) cmd.extend(('-v', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
def test_cache_writing_does_not_overwrite_features_when_features_differ(self): def test_cache_writing_does_not_overwrite_features_when_features_differ(self):
@ -322,7 +323,7 @@ class AAParserCachingTests(AAParserCachingCommon):
features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n') features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n')
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '--skip-bad-cache', '-r', self.profile]) cmd.extend(('-v', '--write-cache', '--skip-bad-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(features_file) self.assert_path_exists(features_file)
# ensure that the features does *not* match the current features set # ensure that the features does *not* match the current features set
@ -334,7 +335,7 @@ class AAParserCachingTests(AAParserCachingCommon):
testlib.write_file(self.cache_dir, '.features', 'monkey\n') testlib.write_file(self.cache_dir, '.features', 'monkey\n')
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '--skip-bad-cache', '-r', self.profile]) cmd.extend(('-v', '--write-cache', '--skip-bad-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(self.cache_file, expected=False) self.assert_path_exists(self.cache_file, expected=False)
@ -349,7 +350,7 @@ class AAParserCachingTests(AAParserCachingCommon):
new_features_file = new_file + '/.features'; new_features_file = new_file + '/.features';
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '-r', self.profile]) cmd.extend(('-v', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(features_file) self.assert_path_exists(features_file)
self.assert_path_exists(new_features_file) self.assert_path_exists(new_features_file)
@ -362,7 +363,7 @@ class AAParserCachingTests(AAParserCachingCommon):
orig_stat = os.stat(cache_file) orig_stat = os.stat(cache_file)
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '-r', self.profile]) cmd.extend(('-v', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(cache_file) self.assert_path_exists(cache_file)
stat = os.stat(cache_file) stat = os.stat(cache_file)
@ -378,7 +379,7 @@ class AAParserCachingTests(AAParserCachingCommon):
check_file = testlib.write_file(self.cache_dir, 'monkey', 'monkey\n') check_file = testlib.write_file(self.cache_dir, 'monkey', 'monkey\n')
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--write-cache', '-r', self.profile]) cmd.extend(('-v', '--write-cache', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
self.assert_path_exists(check_file, expected=False) self.assert_path_exists(check_file, expected=False)
@ -416,7 +417,7 @@ class AAParserCachingTests(AAParserCachingCommon):
orig_stat = os.stat(self.cache_file) orig_stat = os.stat(self.cache_file)
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', self.profile]) cmd.extend(('-v', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
stat = os.stat(self.cache_file) stat = os.stat(self.cache_file)
@ -434,7 +435,7 @@ class AAParserCachingTests(AAParserCachingCommon):
orig_stat = os.stat(self.cache_file) orig_stat = os.stat(self.cache_file)
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', self.profile]) cmd.extend(('-v', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
stat = os.stat(self.cache_file) stat = os.stat(self.cache_file)
@ -452,7 +453,7 @@ class AAParserCachingTests(AAParserCachingCommon):
orig_stat = os.stat(self.cache_file) orig_stat = os.stat(self.cache_file)
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', '-W', self.profile]) cmd.extend(('-v', '-r', '-W', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
stat = os.stat(self.cache_file) stat = os.stat(self.cache_file)
@ -469,7 +470,7 @@ class AAParserCachingTests(AAParserCachingCommon):
orig_stat = os.stat(self.cache_file) orig_stat = os.stat(self.cache_file)
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '-r', '-W', self.profile]) cmd.extend(('-v', '-r', '-W', self.profile))
self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.run_cmd_check(cmd, expected_string='Replacement succeeded for')
stat = os.stat(self.cache_file) stat = os.stat(self.cache_file)
@ -489,7 +490,7 @@ class AAParserCachingTests(AAParserCachingCommon):
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd[0] = new_parser cmd[0] = new_parser
cmd.extend(['-v', '-r', self.profile]) cmd.extend(('-v', '-r', self.profile))
self.run_cmd_check(cmd, expected_string='Cached reload succeeded for') self.run_cmd_check(cmd, expected_string='Cached reload succeeded for')
def _purge_cache_test(self, location): def _purge_cache_test(self, location):
@ -497,7 +498,7 @@ class AAParserCachingTests(AAParserCachingCommon):
cache_file = testlib.write_file(self.cache_dir, location, 'monkey\n') cache_file = testlib.write_file(self.cache_dir, location, 'monkey\n')
cmd = list(self.cmd_prefix) cmd = list(self.cmd_prefix)
cmd.extend(['-v', '--purge-cache', '-r', self.profile]) cmd.extend(('-v', '--purge-cache', '-r', self.profile))
self.run_cmd_check(cmd) self.run_cmd_check(cmd)
# no message is output # no message is output
self.assert_path_exists(cache_file, expected=False) self.assert_path_exists(cache_file, expected=False)
@ -526,7 +527,7 @@ class AAParserAltCacheTests(AAParserCachingTests):
os.chmod(alt_cache_loc, 0o755) os.chmod(alt_cache_loc, 0o755)
self.orig_cache_dir = self.cache_dir self.orig_cache_dir = self.cache_dir
self.cmd_prefix.extend(['--cache-loc', alt_cache_loc]) self.cmd_prefix.extend(('--cache-loc', alt_cache_loc))
self.cache_dir = self.get_cache_dir(create=True) self.cache_dir = self.get_cache_dir(create=True)
self.cache_file = os.path.join(self.cache_dir, PROFILE) self.cache_file = os.path.join(self.cache_dir, PROFILE)
@ -540,7 +541,7 @@ class AAParserAltCacheTests(AAParserCachingTests):
# skip tearDown check to ensure non-alt cache is empty # skip tearDown check to ensure non-alt cache is empty
self.check_orig_cache = False self.check_orig_cache = False
filelist = [PROFILE, '.features', 'monkey'] filelist = (PROFILE, '.features', 'monkey')
for f in filelist: for f in filelist:
testlib.write_file(self.orig_cache_dir, f, 'monkey\n') testlib.write_file(self.orig_cache_dir, f, 'monkey\n')

View file

@ -36,9 +36,9 @@ class AAErrorTests(testlib.AATestTemplate):
else: else:
self.assertEqual(rc, 0, report) self.assertEqual(rc, 0, report)
ignore_messages = [ ignore_messages = (
'Cache read/write disabled: interface file missing. (Kernel needs AppArmor 2.4 compatibility patch.)\n', 'Cache read/write disabled: interface file missing. (Kernel needs AppArmor 2.4 compatibility patch.)\n',
] )
for ign in ignore_messages: for ign in ignore_messages:
if ign in outerr: if ign in outerr:
outerr = outerr.replace(ign, '') outerr = outerr.replace(ign, '')

View file

@ -22,7 +22,7 @@ def get_rule (quantifier, perms, session, name, path, interface, member, peer):
result = ' ' result = ' '
for part in [quantifier, 'dbus', perms, session, name, path, interface, member, peer]: for part in (quantifier, 'dbus', perms, session, name, path, interface, member, peer):
if part: if part:
result += ' %s' % part result += ' %s' % part
@ -59,8 +59,8 @@ def gen_files (test, xres, quantifiers, perms, sessions, names, paths, interface
count=0 count=0
quantifier = ['', 'deny', 'audit'] quantifier = ('', 'deny', 'audit')
session = ['', 'bus=session', 'bus=system', 'bus=accessibility'] session = ('', 'bus=session', 'bus=system', 'bus=accessibility')
path = ['', 'path=/foo/bar', 'path="/foo/bar"'] path = ['', 'path=/foo/bar', 'path="/foo/bar"']
interface = ['', 'interface=com.baz', 'interface="com.baz"'] interface = ['', 'interface=com.baz', 'interface="com.baz"']
member = ['', 'member=bar', 'member="bar"'] member = ['', 'member=bar', 'member="bar"']
@ -100,12 +100,14 @@ msg_perms = [
'(receive write)', '(receive write)',
] ]
empty_tup = ('',)
gen_files('message-rules', 'PASS', quantifier, msg_perms, session, gen_files('message-rules', 'PASS', quantifier, msg_perms, session,
[''], path, interface, member, peer) empty_tup, path, interface, member, peer)
gen_files('service-rules', 'PASS', quantifier, ['bind'], session, gen_files('service-rules', 'PASS', quantifier, ['bind'], session,
name, [''], [''], [''], ['']) name, empty_tup, empty_tup, empty_tup, empty_tup)
gen_files('eavesdrop-rules', 'PASS', quantifier, ['eavesdrop'], session, gen_files('eavesdrop-rules', 'PASS', quantifier, ['eavesdrop'], session,
[''], [''], [''], [''], ['']) empty_tup, empty_tup, empty_tup, empty_tup, empty_tup)
gen_file('sloppy-formatting', 'PASS', '', '(send , receive )', 'bus=session', gen_file('sloppy-formatting', 'PASS', '', '(send , receive )', 'bus=session',
'', 'path ="/foo/bar"', 'interface = com.foo', ' member=bar', '', 'path ="/foo/bar"', 'interface = com.foo', ' member=bar',
'peer =( label= /usr/bin/app name ="com.foo")') 'peer =( label= /usr/bin/app name ="com.foo")')
@ -122,26 +124,26 @@ interface.remove('')
member.remove('') member.remove('')
peer.remove('peer=()') peer.remove('peer=()')
gen_files('message-incompat', 'FAIL', quantifier, msg_perms, session, name, [''], [''], [''], ['']) gen_files('message-incompat', 'FAIL', quantifier, msg_perms, session, name, empty_tup, empty_tup, empty_tup, empty_tup)
gen_files('service-incompat', 'FAIL', quantifier, ['bind'], session, name, path, [''], [''], ['']) gen_files('service-incompat', 'FAIL', quantifier, ('bind',), session, name, path, empty_tup, empty_tup, empty_tup)
gen_files('service-incompat', 'FAIL', quantifier, ['bind'], session, name, [''], interface, [''], ['']) gen_files('service-incompat', 'FAIL', quantifier, ('bind',), session, name, empty_tup, interface, empty_tup, empty_tup)
gen_files('service-incompat', 'FAIL', quantifier, ['bind'], session, name, [''], [''], member, ['']) gen_files('service-incompat', 'FAIL', quantifier, ('bind',), session, name, empty_tup, empty_tup, member, empty_tup)
gen_files('service-incompat', 'FAIL', quantifier, ['bind'], session, name, [''], [''], [''], peer) gen_files('service-incompat', 'FAIL', quantifier, ('bind',), session, name, empty_tup, empty_tup, empty_tup, peer)
gen_files('eavesdrop-incompat', 'FAIL', quantifier, ['eavesdrop'], session, name, path, interface, member, peer) gen_files('eavesdrop-incompat', 'FAIL', quantifier, ('eavesdrop',), session, name, path, interface, member, peer)
gen_files('pairing-unsupported', 'FAIL', quantifier, ['send', 'bind'], gen_files('pairing-unsupported', 'FAIL', quantifier, ('send', 'bind'),
session, ['name=sn', 'label=sl'], [''], [''], [''], session, ('name=sn', 'label=sl'), empty_tup, empty_tup, empty_tup,
['peer=(name=pn)', 'peer=(label=pl)']) ('peer=(name=pn)', 'peer=(label=pl)'))
# missing bus= prefix # missing bus= prefix
gen_file('bad-formatting', 'FAIL', '', 'send', 'session', '', '', '', '', '') gen_file('bad-formatting', 'FAIL', '', 'send', 'session', '', '', '', '', '')
# incorrectly formatted permissions # incorrectly formatted permissions
gen_files('bad-perms', 'FAIL', [''], ['send receive', '(send', 'send)'], gen_files('bad-perms', 'FAIL', empty_tup, ('send receive', '(send', 'send)'),
['bus=session'], [''], [''], [''], [''], ['']) ('bus=session',), empty_tup, empty_tup, empty_tup, empty_tup, empty_tup)
# invalid permissions # invalid permissions
gen_files('bad-perms', 'FAIL', [''], gen_files('bad-perms', 'FAIL', empty_tup,
['a', 'x', 'Ux', 'ix', 'm', 'k', 'l', '(a)', '(x)'], [''], [''], ('a', 'x', 'Ux', 'ix', 'm', 'k', 'l', '(a)', '(x)'), empty_tup, empty_tup,
[''], [''], [''], ['']) empty_tup, empty_tup, empty_tup, empty_tup)
gen_file('duplicated-conditionals', 'FAIL', '', 'bus=1 bus=2', '', '', '', '', '', '') gen_file('duplicated-conditionals', 'FAIL', '', 'bus=1 bus=2', '', '', '', '', '', '')
gen_file('duplicated-conditionals', 'FAIL', '', 'name=1 name=2', '', '', '', '', '', '') gen_file('duplicated-conditionals', 'FAIL', '', 'name=1 name=2', '', '', '', '', '', '')

View file

@ -86,7 +86,7 @@ class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass):
(rc, out, outerr) = self._run_cmd(command, input, stderr, stdout, stdin, timeout) (rc, out, outerr) = self._run_cmd(command, input, stderr, stdout, stdin, timeout)
report = out + outerr report = out + outerr
return [rc, report] return rc, report
def _run_cmd(self, command, input=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE, def _run_cmd(self, command, input=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
stdin=None, timeout=120): stdin=None, timeout=120):
@ -96,7 +96,7 @@ class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass):
sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr,
close_fds=True, preexec_fn=subprocess_setup, universal_newlines=True) close_fds=True, preexec_fn=subprocess_setup, universal_newlines=True)
except OSError as e: except OSError as e:
return [127, str(e)] return 127, str(e)
timeout_communicate = TimeoutFunction(sp.communicate, timeout) timeout_communicate = TimeoutFunction(sp.communicate, timeout)
out, outerr = (None, None) out, outerr = (None, None)
@ -115,7 +115,7 @@ class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass):
if outerr is None: if outerr is None:
outerr = '' outerr = ''
return (rc, out, outerr) return rc, out, outerr
# Timeout handler using alarm() from John P. Speno's Pythonic Avocado # Timeout handler using alarm() from John P. Speno's Pythonic Avocado

View file

@ -42,8 +42,8 @@ class AAParserValgrindTests(testlib.AATestTemplate):
self.maxDiff = None self.maxDiff = None
def _runtest(self, testname, config): def _runtest(self, testname, config):
parser_args = ['-Q', '-I', config.testdir, '-M', './features_files/features.all'] parser_args = ('-Q', '-I', config.testdir, '-M', './features_files/features.all')
failure_rc = [VALGRIND_ERROR_CODE, testlib.TIMEOUT_ERROR_CODE] failure_rc = (VALGRIND_ERROR_CODE, testlib.TIMEOUT_ERROR_CODE)
command = [config.valgrind] command = [config.valgrind]
command.extend(VALGRIND_ARGS) command.extend(VALGRIND_ARGS)
command.append(config.parser) command.append(config.parser)

View file

@ -367,7 +367,7 @@ def get_reqs(file):
if not os.path.isfile(ldd) or not os.access(ldd, os.EX_OK): if not os.path.isfile(ldd) or not os.access(ldd, os.EX_OK):
raise AppArmorException('Can\'t find ldd') raise AppArmorException('Can\'t find ldd')
ret, ldd_out = get_output([ldd, file]) ret, ldd_out = get_output((ldd, file))
if ret == 0 or ret == 1: if ret == 0 or ret == 1:
for line in ldd_out: for line in ldd_out:
if 'not a dynamic executable' in line: # comes with ret == 1 if 'not a dynamic executable' in line: # comes with ret == 1
@ -432,7 +432,7 @@ def get_interpreter_and_abstraction(exec_target):
interpreter_path = get_full_path(interpreter) interpreter_path = get_full_path(interpreter)
interpreter = re.sub('^(/usr)?/bin/', '', interpreter_path) interpreter = re.sub('^(/usr)?/bin/', '', interpreter_path)
if interpreter in ['bash', 'dash', 'sh']: if interpreter in ('bash', 'dash', 'sh'):
abstraction = 'abstractions/bash' abstraction = 'abstractions/bash'
elif interpreter == 'perl': elif interpreter == 'perl':
abstraction = 'abstractions/perl' abstraction = 'abstractions/perl'
@ -755,7 +755,7 @@ def ask_addhat(hashlog):
context = profile + ' -> ^%s' % hat context = profile + ' -> ^%s' % hat
ans = transitions.get(context, 'XXXINVALIDXXX') ans = transitions.get(context, 'XXXINVALIDXXX')
while ans not in ['CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY']: while ans not in ('CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY'):
q = aaui.PromptQuestion() q = aaui.PromptQuestion()
q.headers.extend((_('Profile'), profile)) q.headers.extend((_('Profile'), profile))
@ -883,7 +883,7 @@ def ask_exec(hashlog):
# ask user about the exec mode to use # ask user about the exec mode to use
ans = '' ans = ''
while ans not in ['CMD_ix', 'CMD_px', 'CMD_cx', 'CMD_nx', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_ux', 'CMD_DENY']: # add '(I)gnore'? (hotkey conflict with '(i)x'!) while ans not in ('CMD_ix', 'CMD_px', 'CMD_cx', 'CMD_nx', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_ux', 'CMD_DENY'): # add '(I)gnore'? (hotkey conflict with '(i)x'!)
ans = q.promptUser()[0] ans = q.promptUser()[0]
if ans.startswith('CMD_EXEC_IX_'): if ans.startswith('CMD_EXEC_IX_'):
@ -916,7 +916,7 @@ def ask_exec(hashlog):
if ans == 'CMD_ix': if ans == 'CMD_ix':
exec_mode = 'ix' exec_mode = 'ix'
elif ans in ['CMD_px', 'CMD_cx', 'CMD_pix', 'CMD_cix']: elif ans in ('CMD_px', 'CMD_cx', 'CMD_pix', 'CMD_cix'):
exec_mode = ans.replace('CMD_', '') exec_mode = ans.replace('CMD_', '')
px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut some applications depend on the presence\nof LD_PRELOAD or LD_LIBRARY_PATH.") px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut some applications depend on the presence\nof LD_PRELOAD or LD_LIBRARY_PATH.")
if parent_uses_ld_xxx: if parent_uses_ld_xxx:
@ -1082,7 +1082,7 @@ def ask_the_questions(log_dict):
continue continue
ans = '' ans = ''
while ans not in ['CMD_ADDHAT', 'CMD_ADDSUBPROFILE', 'CMD_DENY']: while ans not in ('CMD_ADDHAT', 'CMD_ADDSUBPROFILE', 'CMD_DENY'):
q = aaui.PromptQuestion() q = aaui.PromptQuestion()
q.headers.extend((_('Profile'), profile)) q.headers.extend((_('Profile'), profile))
@ -1625,7 +1625,7 @@ def collapse_log(hashlog, ignore_null_profiles=True):
# Depending on the access type, not all parameters are allowed. # Depending on the access type, not all parameters are allowed.
# Ignore them, even if some of them appear in the log. # Ignore them, even if some of them appear in the log.
# Also, the log doesn't provide a peer name, therefore always use ALL. # Also, the log doesn't provide a peer name, therefore always use ALL.
if access in ['send', 'receive']: if access in ('send', 'receive'):
dbus_event = DbusRule(access, bus, path, DbusRule.ALL, interface, member, DbusRule.ALL, peer_profile, log_event=True) dbus_event = DbusRule(access, bus, path, DbusRule.ALL, interface, member, DbusRule.ALL, peer_profile, log_event=True)
elif access == 'bind': elif access == 'bind':
dbus_event = DbusRule(access, bus, DbusRule.ALL, name, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, log_event=True) dbus_event = DbusRule(access, bus, DbusRule.ALL, name, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, log_event=True)
@ -1893,7 +1893,7 @@ def parse_profile_data(data, file, do_include, in_preamble):
mount_rule.audit = audit mount_rule.audit = audit
mount_rule.deny = (allow == 'deny') mount_rule.deny = (allow == 'deny')
mount_rules = profile_data[profname][allow].get('mount', list()) mount_rules = profile_data[profname][allow].get('mount', [])
mount_rules.append(mount_rule) mount_rules.append(mount_rule)
profile_data[profname][allow]['mount'] = mount_rules profile_data[profname][allow]['mount'] = mount_rules
@ -1915,7 +1915,7 @@ def parse_profile_data(data, file, do_include, in_preamble):
pivot_root_rule.audit = audit pivot_root_rule.audit = audit
pivot_root_rule.deny = (allow == 'deny') pivot_root_rule.deny = (allow == 'deny')
pivot_root_rules = profile_data[profname][allow].get('pivot_root', list()) pivot_root_rules = profile_data[profname][allow].get('pivot_root', [])
pivot_root_rules.append(pivot_root_rule) pivot_root_rules.append(pivot_root_rule)
profile_data[profname][allow]['pivot_root'] = pivot_root_rules profile_data[profname][allow]['pivot_root'] = pivot_root_rules
@ -1937,7 +1937,7 @@ def parse_profile_data(data, file, do_include, in_preamble):
unix_rule.audit = audit unix_rule.audit = audit
unix_rule.deny = (allow == 'deny') unix_rule.deny = (allow == 'deny')
unix_rules = profile_data[profname][allow].get('unix', list()) unix_rules = profile_data[profname][allow].get('unix', [])
unix_rules.append(unix_rule) unix_rules.append(unix_rule)
profile_data[profname][allow]['unix'] = unix_rules profile_data[profname][allow]['unix'] = unix_rules
@ -2001,7 +2001,7 @@ def parse_profile_data(data, file, do_include, in_preamble):
def match_line_against_rule_classes(line, profile, file, lineno, 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 [ for rule_name in (
'abi', 'abi',
'alias', 'alias',
'boolean', 'boolean',
@ -2015,7 +2015,7 @@ def match_line_against_rule_classes(line, profile, file, lineno, in_preamble):
'ptrace', 'ptrace',
'rlimit', 'rlimit',
'signal', 'signal',
]: ):
if rule_name in ruletypes: if rule_name in ruletypes:
rule_class = ruletypes[rule_name]['rule'] rule_class = ruletypes[rule_name]['rule']
@ -2246,8 +2246,8 @@ def get_file_perms(profile, path, audit, deny):
for incname in includelist: for incname in includelist:
incperms = include[incname][incname]['file'].get_perms_for_path(path, audit, deny) incperms = include[incname][incname]['file'].get_perms_for_path(path, audit, deny)
for allow_or_deny in ['allow', 'deny']: for allow_or_deny in ('allow', 'deny'):
for owner_or_all in ['all', 'owner']: for owner_or_all in ('all', 'owner'):
for perm in incperms[allow_or_deny][owner_or_all]: for perm in incperms[allow_or_deny][owner_or_all]:
perms[allow_or_deny][owner_or_all].add(perm) perms[allow_or_deny][owner_or_all].add(perm)
@ -2311,7 +2311,7 @@ def reload_base(bin_path):
def reload_profile(prof_filename, raise_exc=False): 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]) ret, out = cmd((parser, '-I%s' % profile_dir, '--base', profile_dir, '-r', prof_filename))
if ret != 0: if ret != 0:
if raise_exc: if raise_exc:

View file

@ -273,7 +273,7 @@ if sys.version_info[0] > 2:
def type_is_str(var): def type_is_str(var):
''' returns True if the given variable is a str (or unicode string when using python 2)''' ''' returns True if the given variable is a str (or unicode string when using python 2)'''
if type(var) in [str, unicode]: # python 2 sometimes uses the 'unicode' type if type(var) in (str, unicode): # python 2 sometimes uses the 'unicode' type
return True return True
else: else:
return False return False

View file

@ -255,9 +255,9 @@ def verify_policy(policy, exe, base=None, include=None):
command = [exe, '-QTK'] command = [exe, '-QTK']
if base: if base:
command.extend(['-b', base]) command.extend(('-b', base))
if include: if include:
command.extend(['-I', include]) command.extend(('-I', include))
command.append(fn) command.append(fn)
rc, out = cmd(command) rc, out = cmd(command)
@ -329,9 +329,9 @@ class AppArmorEasyProfile:
self.policy_vendor = opt.policy_vendor self.policy_vendor = opt.policy_vendor
self.policy_version = str(opt.policy_version) self.policy_version = str(opt.policy_version)
for i in ['templates', 'policygroups']: for i in ('templates', 'policygroups'):
d = os.path.join(self.dirs[i], \ d = os.path.join(self.dirs[i],
self.policy_vendor, \ self.policy_vendor,
self.policy_version) self.policy_version)
if not os.path.isdir(d): if not os.path.isdir(d):
raise AppArmorException( raise AppArmorException(

View file

@ -157,7 +157,7 @@ class ReadLog:
if aamode == 'UNKNOWN': if aamode == 'UNKNOWN':
raise AppArmorBug('aamode is UNKNOWN - %s' % e['type']) # should never happen raise AppArmorBug('aamode is UNKNOWN - %s' % e['type']) # should never happen
if aamode in ['AUDIT', 'STATUS', 'ERROR']: if aamode in ('AUDIT', 'STATUS', 'ERROR'):
return None return None
# Skip if AUDIT event was issued due to a change_hat in unconfined mode # Skip if AUDIT event was issued due to a change_hat in unconfined mode

View file

@ -80,12 +80,12 @@ class ProfileStorage:
data['deny'] = dict() data['deny'] = dict()
# mount, pivot_root, unix have a .get() fallback to list() - initialize them nevertheless # mount, pivot_root, unix have a .get() fallback to list() - initialize them nevertheless
data['allow']['mount'] = list() data['allow']['mount'] = []
data['deny']['mount'] = list() data['deny']['mount'] = []
data['allow']['pivot_root'] = list() data['allow']['pivot_root'] = []
data['deny']['pivot_root'] = list() data['deny']['pivot_root'] = []
data['allow']['unix'] = list() data['allow']['unix'] = []
data['deny']['unix'] = list() data['deny']['unix'] = []
self.data = data self.data = data

View file

@ -131,7 +131,7 @@ def parse_profile_start_line(line, filename):
result[section] = matches.group(section) result[section] = matches.group(section)
# sections with optional quotes # sections with optional quotes
if section in ['plainprofile', 'namedprofile', 'attachment', 'hat']: if section in ('plainprofile', 'namedprofile', 'attachment', 'hat'):
result[section] = strip_quotes(result[section]) result[section] = strip_quotes(result[section])
else: else:
result[section] = None result[section] = None

View file

@ -501,7 +501,7 @@ def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name
return None, True, None return None, True, None
elif type_is_str(lst): elif type_is_str(lst):
result_list = {lst} result_list = {lst}
elif type(lst) in [list, tuple, set] and (len(lst) > 0 or allow_empty_list): elif type(lst) in (list, tuple, set) and (len(lst) > 0 or allow_empty_list):
result_list = set(lst) result_list = set(lst)
else: else:
raise AppArmorBug('Passed unknown %(type)s object to %(classname)s: %(unknown_object)s' % raise AppArmorBug('Passed unknown %(type)s object to %(classname)s: %(unknown_object)s' %

View file

@ -52,7 +52,7 @@ class BooleanRule(BaseRule):
raise AppArmorException('Passed empty value to %s: %s' % (self.__class__.__name__, value)) raise AppArmorException('Passed empty value to %s: %s' % (self.__class__.__name__, value))
value = value.lower() value = value.lower()
if value not in ['true', 'false']: if value not in ('true', 'false'):
raise AppArmorException('Passed invalid value to %s: %s' % (self.__class__.__name__, value)) raise AppArmorException('Passed invalid value to %s: %s' % (self.__class__.__name__, value))
self.varname = varname self.varname = varname

View file

@ -78,7 +78,7 @@ class FileRule(BaseRule):
if perms == {'subset'}: if perms == {'subset'}:
raise AppArmorBug('subset without link permissions given') raise AppArmorBug('subset without link permissions given')
elif perms in [{'link'}, {'link', 'subset'}]: elif perms in ({'link'}, {'link', 'subset'}):
self.perms = perms self.perms = perms
self.all_perms = False self.all_perms = False
else: else:
@ -492,7 +492,7 @@ class FileRuleset(BaseRuleset):
allow = {} allow = {}
deny = {} deny = {}
for who in ['all', 'owner']: for who in ('all', 'owner'):
if all_perms['allow'][who]: if all_perms['allow'][who]:
allow[who] = FileRule.ALL allow[who] = FileRule.ALL
else: else:

View file

@ -177,23 +177,23 @@ class RlimitRule(BaseRule):
if unit == '': if unit == '':
unit = default_unit unit = default_unit
if unit in ['us', 'microsecond', 'microseconds']: if unit in ('us', 'microsecond', 'microseconds'):
number = number / 1000000.0 number = number / 1000000.0
if default_unit == 'seconds': if default_unit == 'seconds':
raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value) raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
elif unit in ['ms', 'millisecond', 'milliseconds']: elif unit in ('ms', 'millisecond', 'milliseconds'):
number = number / 1000.0 number = number / 1000.0
if default_unit == 'seconds': if default_unit == 'seconds':
raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value) raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
elif unit in ['s', 'sec', 'second', 'seconds']: # manpage doesn't list sec elif unit in ('s', 'sec', 'second', 'seconds'): # manpage doesn't list sec
pass pass
elif unit in ['min', 'minute', 'minutes']: elif unit in ('min', 'minute', 'minutes'):
number = number * 60 number = number * 60
elif unit in ['h', 'hour', 'hours']: elif unit in ('h', 'hour', 'hours'):
number = number * 60 * 60 number = number * 60 * 60
elif unit in ['d', 'day', 'days']: # manpage doesn't list 'd' elif unit in ('d', 'day', 'days'): # manpage doesn't list 'd'
number = number * 60 * 60 * 24 number = number * 60 * 60 * 24
elif unit in ['week', 'weeks']: elif unit in ('week', 'weeks'):
number = number * 60 * 60 * 24 * 7 number = number * 60 * 60 * 24 * 7
else: else:
raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value)) raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value))

View file

@ -52,7 +52,7 @@ class VariableRule(BaseRule):
if not type_is_str(mode): if not type_is_str(mode):
raise AppArmorBug('Passed unknown type for variable assignment mode to %s: %s' % (self.__class__.__name__, mode)) raise AppArmorBug('Passed unknown type for variable assignment mode to %s: %s' % (self.__class__.__name__, mode))
if mode not in ['=', '+=']: if mode not in ('=', '+='):
raise AppArmorBug('Passed unknown variable assignment mode to %s: %s' % (self.__class__.__name__, mode)) raise AppArmorBug('Passed unknown variable assignment mode to %s: %s' % (self.__class__.__name__, mode))
if type(values) is not set: if type(values) is not set:

View file

@ -137,13 +137,13 @@ def aa_exec(command, opt, environ={}, verify_rules=[]):
debug("using '%s' template" % opt.template) debug("using '%s' template" % opt.template)
# TODO: get rid of this # TODO: get rid of this
if opt.withx: if opt.withx:
rc, report = cmd(['pkexec', 'apparmor_parser', '-r', '%s' % tmp.name]) rc, report = cmd(('pkexec', 'apparmor_parser', '-r', '%s' % tmp.name))
else: else:
rc, report = cmd(['sudo', 'apparmor_parser', '-r', tmp.name]) rc, report = cmd(('sudo', 'apparmor_parser', '-r', tmp.name))
if rc != 0: if rc != 0:
raise AppArmorException("Could not load policy") raise AppArmorException("Could not load policy")
rc, report = cmd(['sudo', 'apparmor_parser', '-p', tmp.name]) rc, report = cmd(('sudo', 'apparmor_parser', '-p', tmp.name))
if rc != 0: if rc != 0:
raise AppArmorException("Could not dump policy") raise AppArmorException("Could not dump policy")
@ -185,8 +185,8 @@ class SandboxXserver():
# preserve our environment # preserve our environment
self.old_environ = dict() self.old_environ = dict()
for env in ['DISPLAY', 'XAUTHORITY', 'UBUNTU_MENUPROXY', for env in ('DISPLAY', 'XAUTHORITY', 'UBUNTU_MENUPROXY',
'QT_X11_NO_NATIVE_MENUBAR', 'LIBOVERLAY_SCROLLBAR']: 'QT_X11_NO_NATIVE_MENUBAR', 'LIBOVERLAY_SCROLLBAR'):
if env in os.environ: if env in os.environ:
self.old_environ[env] = os.environ[env] self.old_environ[env] = os.environ[env]
@ -243,7 +243,7 @@ class SandboxXserver():
# sandboxed applications # sandboxed applications
tmp = ":%d" % i tmp = ":%d" % i
os.environ["DISPLAY"] = tmp os.environ["DISPLAY"] = tmp
rc, report = cmd(['xset', '-q']) rc, report = cmd(('xset', '-q'))
if rc != 0 and 'Invalid MIT-MAGIC-COOKIE-1' not in report: if rc != 0 and 'Invalid MIT-MAGIC-COOKIE-1' not in report:
display = tmp display = tmp
break break
@ -271,7 +271,7 @@ class SandboxXserver():
old_lang = os.environ['LANG'] old_lang = os.environ['LANG']
os.environ['LANG'] = 'C' os.environ['LANG'] = 'C'
rc, report = cmd(['xhost']) rc, report = cmd(('xhost',))
if old_lang: if old_lang:
os.environ['LANG'] = old_lang os.environ['LANG'] = old_lang
@ -289,22 +289,22 @@ class SandboxXserver():
# clean up the old one # clean up the old one
if os.path.exists(self.xauth): if os.path.exists(self.xauth):
os.unlink(self.xauth) os.unlink(self.xauth)
rc, cookie = cmd(['mcookie']) rc, cookie = cmd(('mcookie',))
if rc != 0: if rc != 0:
raise AppArmorException("Could not generate magic cookie") raise AppArmorException("Could not generate magic cookie")
rc, out = cmd(['xauth', '-f', self.xauth, \ rc, out = cmd(('xauth', '-f', self.xauth, \
'add', \ 'add', \
self.display, \ self.display, \
'MIT-MAGIC-COOKIE-1', \ 'MIT-MAGIC-COOKIE-1', \
cookie.strip()]) cookie.strip()))
if rc != 0: if rc != 0:
raise AppArmorException("Could not generate '%s'" % self.display) raise AppArmorException("Could not generate '%s'" % self.display)
class SandboxXephyr(SandboxXserver): class SandboxXephyr(SandboxXserver):
def start(self): def start(self):
for e in ['Xephyr', 'matchbox-window-manager']: for e in ('Xephyr', 'matchbox-window-manager'):
debug("Searching for '%s'" % e) debug("Searching for '%s'" % e)
if which(e) is None: if which(e) is None:
raise AppArmorException("Could not find '%s'" % e) raise AppArmorException("Could not find '%s'" % e)
@ -376,7 +376,7 @@ class SandboxXpra(SandboxXserver):
# Annoyingly, xpra doesn't clean up itself well if the application # Annoyingly, xpra doesn't clean up itself well if the application
# failed for some reason. Try to account for that. # failed for some reason. Try to account for that.
rc, report = cmd(['ps', 'auxww']) rc, report = cmd(('ps', 'auxww'))
for line in report.splitlines(): for line in report.splitlines():
if '-for-Xpra-%s' % self.display in line: if '-for-Xpra-%s' % self.display in line:
self.pids.append(int(line.split()[1])) self.pids.append(int(line.split()[1]))
@ -585,7 +585,7 @@ EndSection
os.environ['XAUTHORITY'] = self.xauth os.environ['XAUTHORITY'] = self.xauth
# This will clean out any dead sessions # This will clean out any dead sessions
cmd(['xpra', 'list']) cmd(('xpra', 'list'))
x_args = ['--no-daemon', x_args = ['--no-daemon',
#'--no-mmap', # for security? #'--no-mmap', # for security?
@ -621,7 +621,7 @@ EndSection
raise AppArmorException("Could not start xpra (try again with -d)") raise AppArmorException("Could not start xpra (try again with -d)")
for i in range(self.timeout): # Up to self.timeout seconds to start for i in range(self.timeout): # Up to self.timeout seconds to start
rc, out = cmd(['xpra', 'list']) rc, out = cmd(('xpra', 'list'))
if 'DEAD session at %s' % self.display in out: if 'DEAD session at %s' % self.display in out:
error("xpra session at '%s' died" % self.display, do_exit=False) error("xpra session at '%s' died" % self.display, do_exit=False)
@ -663,7 +663,7 @@ EndSection
# Make sure that a client has attached # Make sure that a client has attached
for i in range(self.timeout): # up to self.timeout seconds to attach for i in range(self.timeout): # up to self.timeout seconds to attach
time.sleep(1) time.sleep(1)
rc, out = cmd (['xpra', 'info', self.display]) rc, out = cmd (('xpra', 'info', self.display))
search = 'clients=1' search = 'clients=1'
if search in out: if search in out:
debug("Client successfully attached!") debug("Client successfully attached!")

View file

@ -35,7 +35,7 @@ class aa_tools:
self.silent = None self.silent = None
self.do_reload = args.do_reload self.do_reload = args.do_reload
if tool_name in ['audit']: if tool_name == 'audit':
self.remove = args.remove self.remove = args.remove
elif tool_name == 'autodep': elif tool_name == 'autodep':
self.force = args.force self.force = args.force

View file

@ -129,7 +129,7 @@ def UI_YesNo(text, default):
yeskey = get_translated_hotkey(yes).lower() yeskey = get_translated_hotkey(yes).lower()
nokey = get_translated_hotkey(no).lower() nokey = get_translated_hotkey(no).lower()
ans = 'XXXINVALIDXXX' ans = 'XXXINVALIDXXX'
while ans not in ['y', 'n']: while ans not in ('y', 'n'):
if UI_mode == 'json': if UI_mode == 'json':
jsonout = {'dialog': 'yesno', 'text': text, 'default': default} jsonout = {'dialog': 'yesno', 'text': text, 'default': default}
write_json(jsonout) write_json(jsonout)
@ -173,7 +173,7 @@ def UI_YesNoCancel(text, default):
cancelkey = get_translated_hotkey(cancel).lower() cancelkey = get_translated_hotkey(cancel).lower()
ans = 'XXXINVALIDXXX' ans = 'XXXINVALIDXXX'
while ans not in ['c', 'n', 'y']: while ans not in ('c', 'n', 'y'):
if UI_mode == 'json': if UI_mode == 'json':
jsonout = {'dialog': 'yesnocancel', 'text': text, 'default': default} jsonout = {'dialog': 'yesnocancel', 'text': text, 'default': default}
write_json(jsonout) write_json(jsonout)
@ -373,8 +373,8 @@ class PromptQuestion(object):
helptext = None helptext = None
def __init__(self): def __init__(self):
self.headers = list() self.headers = []
self.functions = list() self.functions = []
self.selected = 0 self.selected = 0
def promptUser(self, params=''): def promptUser(self, params=''):
@ -400,7 +400,7 @@ class PromptQuestion(object):
if helptext: if helptext:
functions.append('CMD_HELP') functions.append('CMD_HELP')
menu_items = list() menu_items = []
keys = dict() keys = dict()
for cmd in functions: for cmd in functions:

View file

@ -37,18 +37,18 @@ class Install(_install, object):
prefix = self.root prefix = self.root
# Install scripts, configuration files and data # Install scripts, configuration files and data
scripts = ['/usr/bin/aa-easyprof'] scripts = ('/usr/bin/aa-easyprof',)
self.mkpath(prefix + os.path.dirname(scripts[0])) self.mkpath(prefix + os.path.dirname(scripts[0]))
for s in scripts: for s in scripts:
f = prefix + s f = prefix + s
self.copy_file(os.path.basename(s), f) self.copy_file(os.path.basename(s), f)
configs = ['easyprof/easyprof.conf'] configs = ('easyprof/easyprof.conf',)
self.mkpath(prefix + "/etc/apparmor") self.mkpath(prefix + "/etc/apparmor")
for c in configs: for c in configs:
self.copy_file(c, os.path.join(prefix + "/etc/apparmor", os.path.basename(c))) self.copy_file(c, os.path.join(prefix + "/etc/apparmor", os.path.basename(c)))
data = ['easyprof/templates', 'easyprof/policygroups'] data = ('easyprof/templates', 'easyprof/policygroups')
self.mkpath(prefix + "/usr/share/apparmor/easyprof") self.mkpath(prefix + "/usr/share/apparmor/easyprof")
for d in data: for d in data:
self.copy_tree(d, os.path.join(prefix + "/usr/share/apparmor/easyprof", os.path.basename(d))) self.copy_tree(d, os.path.join(prefix + "/usr/share/apparmor/easyprof", os.path.basename(d)))

View file

@ -52,7 +52,7 @@ class AATest(unittest.TestCase):
self.createTmpdir() self.createTmpdir()
return write_file(self.tmpdir, file, contents) return write_file(self.tmpdir, file, contents)
tests = [] tests = ()
tmpdir = None tmpdir = None
class AAParseTest(unittest.TestCase): class AAParseTest(unittest.TestCase):

View file

@ -43,7 +43,7 @@ def cmd(command, stdin=None):
preexec_fn=subprocess_setup preexec_fn=subprocess_setup
) )
except OSError as e: except OSError as e:
return [127, str(e)] return 127, str(e)
stdout, stderr = sp.communicate(input) stdout, stderr = sp.communicate(input)
@ -54,7 +54,7 @@ def cmd(command, stdin=None):
else: else:
out = stdout out = stdout
return [sp.returncode, out.decode('utf-8')] return sp.returncode, out.decode('utf-8')
def mkstemp_fill(contents, suffix='', prefix='tst-aadecode-', dir=None): def mkstemp_fill(contents, suffix='', prefix='tst-aadecode-', dir=None):
@ -82,22 +82,22 @@ class AADecodeTest(unittest.TestCase):
'''Test --help argument''' '''Test --help argument'''
expected = 0 expected = 0
rc, report = cmd([aadecode_bin, "--help"]) rc, report = cmd((aadecode_bin, "--help"))
result = 'Got exit code %d, expected %d\n' % (rc, expected) result = 'Got exit code %d, expected %d\n' % (rc, expected)
self.assertEqual(expected, rc, result + report) self.assertEqual(expected, rc, result + report)
def _run_file_test(self, content, expected_list): def _run_file_test(self, content, expected):
'''test case helper function; takes log content and a list of '''test case helper function; takes log content and a list of
expected strings as arguments''' expected strings as arguments'''
expected = 0 expected_return_code = 0
(f, self.tmpfile) = mkstemp_fill(content) (f, self.tmpfile) = mkstemp_fill(content)
rc, report = cmd([aadecode_bin], stdin=f) rc, report = cmd((aadecode_bin,), stdin=f)
result = 'Got exit code %d, expected %d\n' % (rc, expected) result = 'Got exit code %d, expected %d\n' % (rc, expected_return_code)
self.assertEqual(expected, rc, result + report) self.assertEqual(expected_return_code, rc, result + report)
for expected_string in expected_list: for expected_string in expected:
result = 'could not find expected %s in output:\n' % (expected_string) result = 'could not find expected %s in output:\n' % (expected_string)
self.assertIn(expected_string, report, result + report) self.assertIn(expected_string, report, result + report)
f.close() f.close()
@ -109,7 +109,7 @@ class AADecodeTest(unittest.TestCase):
expected_output = 'Decoded: /tmp/foo bar' expected_output = 'Decoded: /tmp/foo bar'
test_code = '2F746D702F666F6F20626172' test_code = '2F746D702F666F6F20626172'
rc, report = cmd([aadecode_bin, test_code]) rc, report = cmd((aadecode_bin, test_code))
result = 'Got exit code %d, expected %d\n' % (rc, expected) result = 'Got exit code %d, expected %d\n' % (rc, expected)
self.assertEqual(expected, rc, result + report) self.assertEqual(expected, rc, result + report)
result = 'Got output "%s", expected "%s"\n' % (report, expected_output) result = 'Got output "%s", expected "%s"\n' % (report, expected_output)
@ -123,14 +123,14 @@ class AADecodeTest(unittest.TestCase):
'''type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 '''type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
''' '''
self._run_file_test(content, [expected_string]) self._run_file_test(content, (expected_string,))
def test_simple_multiline(self): 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', expected_strings = ('ses=4294967295 new ses=2762',
'name="/tmp/foo bar"', 'name="/tmp/foo bar"',
'name="/home/steve/tmp/my test file"'] 'name="/home/steve/tmp/my test file"')
content = \ content = \
''' type=LOGIN msg=audit(1348980001.155:2925): login pid=17875 uid=0 old auid=4294967295 new auid=0 old ses=4294967295 new ses=2762 ''' type=LOGIN msg=audit(1348980001.155:2925): login pid=17875 uid=0 old auid=4294967295 new auid=0 old ses=4294967295 new ses=2762
type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
@ -143,8 +143,8 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
'''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"', expected_strings = ('name="/lib/x86_64-linux-gnu/libdl-2.13.so"',
'profile="/test space"'] 'profile="/test space"')
content = \ content = \
'''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=2F74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 '''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=2F74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
''' '''
@ -155,8 +155,8 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
'''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"', expected_strings = ('name="/home/steve/tmp/my test file"',
'profile="/home/steve/tmp/my prog.sh"'] 'profile="/home/steve/tmp/my prog.sh"')
content = \ content = \
'''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile=2F686F6D652F73746576652F746D702F6D792070726F672E7368 name=2F686F6D652F73746576652F746D702F6D7920746573742066696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile=2F686F6D652F73746576652F746D702F6D792070726F672E7368 name=2F686F6D652F73746576652F746D702F6D7920746573742066696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
''' '''
@ -166,7 +166,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
def test_simple_embedded_carat(self): 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"'] expected_strings = ('name="/home/steve/tmp/my test ^file"',)
content = \ content = \
'''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
''' '''
@ -176,7 +176,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
def test_simple_embedded_backslash_carat(self): 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"'] expected_strings = ('name="/home/steve/tmp/my test \^file"',)
content = \ content = \
'''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205C5E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205C5E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
''' '''
@ -186,7 +186,7 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
def test_simple_embedded_singlequote(self): 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"'] expected_strings = ('name="/home/steve/tmp/my test \'file"',)
content = \ content = \
'''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374202766696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374202766696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
''' '''
@ -196,8 +196,8 @@ type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock"
def test_simple_encoded_nonpath_profiles(self): 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"', expected_strings = ('name="/lib/x86_64-linux-gnu/libdl-2.13.so"',
'profile="test space"'] 'profile="test space"')
content = \ content = \
'''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 '''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
''' '''

View file

@ -114,7 +114,7 @@ class T(unittest.TestCase):
self.tmpdir = os.path.realpath(tempfile.mkdtemp(prefix='test-aa-easyprof')) self.tmpdir = os.path.realpath(tempfile.mkdtemp(prefix='test-aa-easyprof'))
# Copy everything into place # Copy everything into place
for d in ['easyprof/policygroups', 'easyprof/templates']: for d in ('easyprof/policygroups', 'easyprof/templates'):
shutil.copytree(os.path.join(topdir, d), shutil.copytree(os.path.join(topdir, d),
os.path.join(self.tmpdir, os.path.basename(d))) os.path.join(self.tmpdir, os.path.basename(d)))
@ -196,7 +196,7 @@ TEMPLATES_DIR="%s/templates"
os.mkdir(self.test_include_dir) os.mkdir(self.test_include_dir)
os.mkdir(os.path.join(self.test_include_dir, "templates")) os.mkdir(os.path.join(self.test_include_dir, "templates"))
os.mkdir(os.path.join(self.test_include_dir, "policygroups")) os.mkdir(os.path.join(self.test_include_dir, "policygroups"))
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
for f in easyprof.get_directory_contents(os.path.join( for f in easyprof.get_directory_contents(os.path.join(
self.tmpdir, d)): self.tmpdir, d)):
shutil.copy(f, os.path.join(self.test_include_dir, d, shutil.copy(f, os.path.join(self.test_include_dir, d,
@ -532,10 +532,7 @@ POLICYGROUPS_DIR="%s/templates"
def test_templates_show(self): def test_templates_show(self):
'''Test templates (show)''' '''Test templates (show)'''
files = [] files = glob.glob("%s/templates/*" % self.tmpdir)
for f in glob.glob("%s/templates/*" % self.tmpdir):
files.append(f)
for f in files: for f in files:
args = self.full_args args = self.full_args
args += ['--show-template', '--template', f] args += ['--show-template', '--template', f]
@ -572,10 +569,7 @@ POLICYGROUPS_DIR="%s/templates"
def test_templates_show_include(self): def test_templates_show_include(self):
'''Test templates (show with --include-templates-dir)''' '''Test templates (show with --include-templates-dir)'''
files = [] files = glob.glob("%s/templates/*" % self.test_include_dir)
for f in glob.glob("%s/templates/*" % self.test_include_dir):
files.append(f)
for f in files: for f in files:
args = self.full_args args = self.full_args
args += ['--show-template', args += ['--show-template',
@ -610,10 +604,7 @@ POLICYGROUPS_DIR="%s/templates"
def test_policygroups_show(self): def test_policygroups_show(self):
'''Test policygroups (show)''' '''Test policygroups (show)'''
files = [] files = glob.glob("%s/policygroups/*" % self.tmpdir)
for f in glob.glob("%s/policygroups/*" % self.tmpdir):
files.append(f)
for f in files: for f in files:
args = self.full_args args = self.full_args
args += ['--show-policy-group', args += ['--show-policy-group',
@ -651,10 +642,7 @@ POLICYGROUPS_DIR="%s/templates"
def test_policygroups_show_include(self): def test_policygroups_show_include(self):
'''Test policygroups (show with --include-policy-groups-dir)''' '''Test policygroups (show with --include-policy-groups-dir)'''
files = [] files = glob.glob("%s/policygroups/*" % self.test_include_dir)
for f in glob.glob("%s/policygroups/*" % self.test_include_dir):
files.append(f)
for f in files: for f in files:
args = self.full_args args = self.full_args
args += ['--show-policy-group', args += ['--show-policy-group',
@ -689,7 +677,7 @@ POLICYGROUPS_DIR="%s/templates"
f.write(contents) f.write(contents)
args = self.full_args args = self.full_args
args.extend(['--manifest', self.manifest]) args.extend(('--manifest', self.manifest))
easyprof.parse_args(args) easyprof.parse_args(args)
def _manifest_conflicts(self, opt, value): def _manifest_conflicts(self, opt, value):
@ -704,7 +692,7 @@ POLICYGROUPS_DIR="%s/templates"
# opt first # opt first
args = self.full_args args = self.full_args
args.extend([opt, value, '--manifest', self.manifest]) args.extend((opt, value, '--manifest', self.manifest))
raised = False raised = False
try: try:
easyprof.parse_args(args, InterceptingOptionParser()) easyprof.parse_args(args, InterceptingOptionParser())
@ -716,7 +704,7 @@ POLICYGROUPS_DIR="%s/templates"
# manifest first # manifest first
args = self.full_args args = self.full_args
args.extend(['--manifest', self.manifest, opt, value]) args.extend(('--manifest', self.manifest, opt, value))
raised = False raised = False
try: try:
easyprof.parse_args(args, InterceptingOptionParser()) easyprof.parse_args(args, InterceptingOptionParser())
@ -845,7 +833,7 @@ POLICYGROUPS_DIR="%s/templates"
def test__is_safe(self): def test__is_safe(self):
'''Test _is_safe()''' '''Test _is_safe()'''
bad = [ bad = (
"/../../../../etc/passwd", "/../../../../etc/passwd",
"abstraction with spaces", "abstraction with spaces",
"semicolon;bad", "semicolon;bad",
@ -853,7 +841,7 @@ POLICYGROUPS_DIR="%s/templates"
"foo/bar", "foo/bar",
"foo'bar", "foo'bar",
'foo"bar', 'foo"bar',
] )
for s in bad: for s in bad:
self.assertFalse(easyprof._is_safe(s), "'%s' should be bad" %s) self.assertFalse(easyprof._is_safe(s), "'%s' should be bad" %s)
@ -870,7 +858,7 @@ POLICYGROUPS_DIR="%s/templates"
p = self._gen_policy(template=template) p = self._gen_policy(template=template)
for s in [self.test_template, test_string]: for s in (self.test_template, test_string):
self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p))
def test_genpolicy_templates_system(self): def test_genpolicy_templates_system(self):
@ -936,11 +924,11 @@ POLICYGROUPS_DIR="%s/templates"
def test_genpolicy_abstractions_bad(self): def test_genpolicy_abstractions_bad(self):
'''Test genpolicy (abstractions - bad values)''' '''Test genpolicy (abstractions - bad values)'''
bad = [ bad = (
"nonexistent", "nonexistent",
"/../../../../etc/passwd", "/../../../../etc/passwd",
"abstraction with spaces", "abstraction with spaces",
] )
for s in bad: for s in bad:
try: try:
self._gen_policy(extra_args=['--abstractions=%s' % s]) self._gen_policy(extra_args=['--abstractions=%s' % s])
@ -1077,7 +1065,7 @@ POLICYGROUPS_DIR="%s/templates"
groups = self.test_policygroup groups = self.test_policygroup
p = self._gen_policy(extra_args=['--policy-groups=%s' % groups]) p = self._gen_policy(extra_args=['--policy-groups=%s' % groups])
for s in ['#include <abstractions/nameservice>', '#include <abstractions/gnome>']: for s in ('#include <abstractions/nameservice>', '#include <abstractions/gnome>'):
self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p))
inv_s = '###POLICYGROUPS###' inv_s = '###POLICYGROUPS###'
self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p))
@ -1096,10 +1084,10 @@ POLICYGROUPS_DIR="%s/templates"
groups = "%s,%s" % (self.test_policygroup, test_policygroup2) groups = "%s,%s" % (self.test_policygroup, test_policygroup2)
p = self._gen_policy(extra_args=['--policy-groups=%s' % groups]) p = self._gen_policy(extra_args=['--policy-groups=%s' % groups])
for s in ['#include <abstractions/nameservice>', for s in ('#include <abstractions/nameservice>',
'#include <abstractions/gnome>', '#include <abstractions/gnome>',
'#include <abstractions/kde>', '#include <abstractions/kde>',
'#include <abstractions/openssl>']: '#include <abstractions/openssl>'):
self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p))
inv_s = '###POLICYGROUPS###' inv_s = '###POLICYGROUPS###'
self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p))
@ -1543,7 +1531,7 @@ POLICYGROUPS_DIR="%s/templates"
m.add_policygroups(groups) m.add_policygroups(groups)
p = self._gen_manifest_policy(m) p = self._gen_manifest_policy(m)
for s in ['#include <abstractions/nameservice>', '#include <abstractions/gnome>']: for s in ('#include <abstractions/nameservice>', '#include <abstractions/gnome>'):
self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p))
inv_s = '###POLICYGROUPS###' inv_s = '###POLICYGROUPS###'
self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p))
@ -1564,10 +1552,10 @@ POLICYGROUPS_DIR="%s/templates"
m.add_policygroups(groups) m.add_policygroups(groups)
p = self._gen_manifest_policy(m) p = self._gen_manifest_policy(m)
for s in ['#include <abstractions/nameservice>', for s in ('#include <abstractions/nameservice>',
'#include <abstractions/gnome>', '#include <abstractions/gnome>',
'#include <abstractions/kde>', '#include <abstractions/kde>',
'#include <abstractions/openssl>']: '#include <abstractions/openssl>'):
self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p))
inv_s = '###POLICYGROUPS###' inv_s = '###POLICYGROUPS###'
self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p))
@ -1685,7 +1673,7 @@ POLICYGROUPS_DIR="%s/templates"
} }
}''' }'''
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
shutil.copytree(os.path.join(self.tmpdir, d), shutil.copytree(os.path.join(self.tmpdir, d),
os.path.join(self.tmpdir, d, "somevendor/1.0")) os.path.join(self.tmpdir, d, "somevendor/1.0"))
@ -1725,7 +1713,7 @@ POLICYGROUPS_DIR="%s/templates"
} }
}''' }'''
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
shutil.copytree(os.path.join(self.tmpdir, d), shutil.copytree(os.path.join(self.tmpdir, d),
os.path.join(self.tmpdir, d, "ubuntu/1.0")) os.path.join(self.tmpdir, d, "ubuntu/1.0"))
@ -1854,7 +1842,7 @@ POLICYGROUPS_DIR="%s/templates"
} }
}''' }'''
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
shutil.copytree(os.path.join(self.tmpdir, d), shutil.copytree(os.path.join(self.tmpdir, d),
os.path.join(self.tmpdir, d, "ubuntu/1.0")) os.path.join(self.tmpdir, d, "ubuntu/1.0"))
@ -2070,7 +2058,7 @@ POLICYGROUPS_DIR="%s/templates"
def test_verify_manifest_profile_template_var_bad(self): 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"', for v in ('"VAR1": "f*o"',
'"VAR2": "*foo"', '"VAR2": "*foo"',
'"VAR3": "fo*"', '"VAR3": "fo*"',
'"VAR4": "b{ar"', '"VAR4": "b{ar"',
@ -2079,7 +2067,7 @@ POLICYGROUPS_DIR="%s/templates"
'"VAR7": "bar[0-9]"', '"VAR7": "bar[0-9]"',
'"VAR8": "b{ar"', '"VAR8": "b{ar"',
'"VAR9": "foo/bar"' # this is valid, but potentially unsafe '"VAR9": "foo/bar"' # this is valid, but potentially unsafe
]: ):
m = '''{ m = '''{
"security": { "security": {
"profiles": { "profiles": {
@ -2137,11 +2125,11 @@ POLICYGROUPS_DIR="%s/templates"
def test_manifest_invalid4(self): 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"', for v in ('"VAR1": "/tmp/../etc/passwd"',
'"VAR2": "./"', '"VAR2": "./"',
'"VAR3": "foo\"bar"', '"VAR3": "foo\"bar"',
'"VAR4": "foo//bar"', '"VAR4": "foo//bar"',
]: ):
m = '''{ m = '''{
"security": { "security": {
"profiles": { "profiles": {
@ -2213,7 +2201,7 @@ POLICYGROUPS_DIR="%s/templates"
} }
} }
}''' % (policy_vendor, policy_version) }''' % (policy_vendor, policy_version)
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
shutil.copytree(os.path.join(self.tmpdir, d), shutil.copytree(os.path.join(self.tmpdir, d),
os.path.join(self.tmpdir, d, policy_subdir)) os.path.join(self.tmpdir, d, policy_subdir))
@ -2243,7 +2231,7 @@ POLICYGROUPS_DIR="%s/templates"
policy_subdir = "%s/%s" % (policy_vendor, policy_version) policy_subdir = "%s/%s" % (policy_vendor, policy_version)
# Create the directories # Create the directories
for d in ['policygroups', 'templates']: for d in ('policygroups', 'templates'):
shutil.copytree(os.path.join(self.tmpdir, d), shutil.copytree(os.path.join(self.tmpdir, d),
os.path.join(self.tmpdir, d, policy_subdir)) os.path.join(self.tmpdir, d, policy_subdir))

View file

@ -48,7 +48,7 @@ def cmd(command):
preexec_fn=subprocess_setup preexec_fn=subprocess_setup
) )
except OSError as e: except OSError as e:
return [127, str(e)] return 127, str(e)
stdout, stderr = sp.communicate(input) stdout, stderr = sp.communicate(input)
@ -59,7 +59,7 @@ def cmd(command):
else: else:
out = stdout out = stdout
return [sp.returncode, out.decode('utf-8')] return sp.returncode, out.decode('utf-8')
class AANotifyTest(AATest): class AANotifyTest(AATest):

View file

@ -79,24 +79,24 @@ class AaTest_check_for_apparmor(AaTestWithTempdir):
self.assertEqual('%s/security/apparmor' % self.tmpdir, check_for_apparmor(filesystems, mounts)) self.assertEqual('%s/security/apparmor' % self.tmpdir, check_for_apparmor(filesystems, mounts))
class AATest_get_output(AATest): class AATest_get_output(AATest):
tests = [ tests = (
(['./fake_ldd', '/AATest/lib64/libc-2.22.so'], (0, [' /AATest/lib64/ld-linux-x86-64.so.2 (0x0000556858473000)', ' linux-vdso.so.1 (0x00007ffe98912000)'] )), (('./fake_ldd', '/AATest/lib64/libc-2.22.so'), (0, [' /AATest/lib64/ld-linux-x86-64.so.2 (0x0000556858473000)', ' linux-vdso.so.1 (0x00007ffe98912000)'] )),
(['./fake_ldd', '/tmp/aa-test-foo'], (0, [' not a dynamic executable'] )), (('./fake_ldd', '/tmp/aa-test-foo'), (0, [' not a dynamic executable'] )),
(['./fake_ldd', 'invalid'], (1, [] )), # stderr is not part of output (('./fake_ldd', 'invalid'), (1, [] )), # stderr is not part of output
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(get_output(params), expected) self.assertEqual(get_output(params), expected)
def test_get_output_nonexisting(self): def test_get_output_nonexisting(self):
with self.assertRaises(AppArmorException): with self.assertRaises(AppArmorException):
ret, output = get_output(['./_file_/_not_/_found_']) ret, output = get_output(('./_file_/_not_/_found_',))
class AATest_get_reqs(AATest): class AATest_get_reqs(AATest):
tests = [ tests = (
('/AATest/bin/bash', ['/AATest/lib64/libreadline.so.6', '/AATest/lib64/libtinfo.so.6', '/AATest/lib64/libdl.so.2', '/AATest/lib64/libc.so.6', '/AATest/lib64/ld-linux-x86-64.so.2']), ('/AATest/bin/bash', ['/AATest/lib64/libreadline.so.6', '/AATest/lib64/libtinfo.so.6', '/AATest/lib64/libdl.so.2', '/AATest/lib64/libc.so.6', '/AATest/lib64/ld-linux-x86-64.so.2']),
('/tmp/aa-test-foo', []), ('/tmp/aa-test-foo', []),
('/AATest/sbin/ldconfig', []), # comes with $? == 1 ('/AATest/sbin/ldconfig', []), # comes with $? == 1
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
# for some reason, setting the ldd config option does not get # for some reason, setting the ldd config option does not get
@ -110,12 +110,12 @@ class AATest_get_reqs(AATest):
self.assertEqual(get_reqs(params), expected) self.assertEqual(get_reqs(params), expected)
class AaTest_create_new_profile(AATest): class AaTest_create_new_profile(AATest):
tests = [ tests = (
# file content filename expected interpreter expected abstraction (besides 'base') expected profiles # file content filename expected interpreter expected abstraction (besides 'base') expected profiles
(('#!/bin/bash\ntrue', 'script'), (u'/bin/bash', 'abstractions/bash', ['script'])), (('#!/bin/bash\ntrue', 'script'), (u'/bin/bash', 'abstractions/bash', ['script'])),
(('foo bar', 'fake_binary'), (None, None, ['fake_binary'])), (('foo bar', 'fake_binary'), (None, None, ['fake_binary'])),
(('hats expected', 'apache2'), (None, None, ['apache2', 'apache2//DEFAULT_URI', 'apache2//HANDLING_UNTRUSTED_INPUT'])), (('hats expected', 'apache2'), (None, None, ['apache2', 'apache2//DEFAULT_URI', 'apache2//HANDLING_UNTRUSTED_INPUT'])),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
apparmor.aa.cfg['settings']['ldd'] = './fake_ldd' apparmor.aa.cfg['settings']['ldd'] = './fake_ldd'
# for some reason, setting the ldd config option does not get # for some reason, setting the ldd config option does not get
@ -164,7 +164,7 @@ class AaTest_create_new_profile(AATest):
self.assertEqual(profile[program]['inc_ie'].get_clean(), ['include <abstractions/base>', '']) self.assertEqual(profile[program]['inc_ie'].get_clean(), ['include <abstractions/base>', ''])
class AaTest_get_interpreter_and_abstraction(AATest): class AaTest_get_interpreter_and_abstraction(AATest):
tests = [ tests = (
('#!/bin/bash', ('/bin/bash', 'abstractions/bash')), ('#!/bin/bash', ('/bin/bash', 'abstractions/bash')),
('#!/bin/dash', ('/bin/dash', 'abstractions/bash')), ('#!/bin/dash', ('/bin/dash', 'abstractions/bash')),
('#!/bin/sh', ('/bin/sh', 'abstractions/bash')), ('#!/bin/sh', ('/bin/sh', 'abstractions/bash')),
@ -182,7 +182,7 @@ class AaTest_get_interpreter_and_abstraction(AATest):
('#!/usr/bin/ruby1.9.1', ('/usr/bin/ruby1.9.1', 'abstractions/ruby')), ('#!/usr/bin/ruby1.9.1', ('/usr/bin/ruby1.9.1', 'abstractions/ruby')),
('#!/usr/bin/foobarbaz', ('/usr/bin/foobarbaz', None)), # we don't have an abstraction for "foobarbaz" ('#!/usr/bin/foobarbaz', ('/usr/bin/foobarbaz', None)), # we don't have an abstraction for "foobarbaz"
('foo', (None, None)), # no hashbang - not a script ('foo', (None, None)), # no hashbang - not a script
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
exp_interpreter_path, exp_abstraction = expected exp_interpreter_path, exp_abstraction = expected
@ -406,13 +406,13 @@ class AaTest_change_profile_flags(AaTestWithTempdir):
change_profile_flags('%s/file-not-found' % self.tmpdir, '/foo', 'audit', True) change_profile_flags('%s/file-not-found' % self.tmpdir, '/foo', 'audit', True)
class AaTest_set_options_audit_mode(AATest): class AaTest_set_options_audit_mode(AATest):
tests = [ tests = (
((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']), ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']),
((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']), ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']),
((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']),
((FileRule.parse('/foo/bar r,'), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']),
((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '#include <abstractions/base>']), ['audit /foo/bar r,', 'audit /foo/* r,', '#include <abstractions/base>']), ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '#include <abstractions/base>']), ['audit /foo/bar r,', 'audit /foo/* r,', '#include <abstractions/base>']),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rule_obj, options = params rule_obj, options = params
@ -420,13 +420,13 @@ class AaTest_set_options_audit_mode(AATest):
self.assertEqual(new_options, expected) self.assertEqual(new_options, expected)
class AaTest_set_options_owner_mode(AATest): class AaTest_set_options_owner_mode(AATest):
tests = [ tests = (
((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']), ((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']),
((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']), ((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']),
((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']),
((FileRule.parse('/foo/bar r,'), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']),
((FileRule.parse('audit owner /foo/bar r,'),['audit /foo/bar r,', 'audit /foo/* r,', '#include <abstractions/base>']), ['audit owner /foo/bar r,', 'audit owner /foo/* r,', '#include <abstractions/base>']), ((FileRule.parse('audit owner /foo/bar r,'),['audit /foo/bar r,', 'audit /foo/* r,', '#include <abstractions/base>']), ['audit owner /foo/bar r,', 'audit owner /foo/* r,', '#include <abstractions/base>']),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rule_obj, options = params rule_obj, options = params
@ -540,14 +540,14 @@ class AaTest_parse_profile_data(AATest):
parse_profile_data(d.split(), 'somefile', False, False) parse_profile_data(d.split(), 'somefile', False, False)
class AaTest_get_file_perms_1(AATest): class AaTest_get_file_perms_1(AATest):
tests = [ tests = (
('/usr/share/common-licenses/foo/bar', {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }), ('/usr/share/common-licenses/foo/bar', {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }),
('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }), ('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }),
('/foo/bar', {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/foo/bar'} }), # exec perms not included ('/foo/bar', {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/foo/bar'} }), # exec perms not included
('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }),
('/usr/lib/ispell/', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/usr/lib/ispell/', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }),
('/usr/lib/aspell/*.so', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/usr/lib/aspell/*.so', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.createTmpdir() self.createTmpdir()
@ -567,7 +567,7 @@ class AaTest_get_file_perms_1(AATest):
self.assertEqual(perms, expected) self.assertEqual(perms, expected)
class AaTest_get_file_perms_2(AATest): class AaTest_get_file_perms_2(AATest):
tests = [ tests = (
('/usr/share/common-licenses/foo/bar', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }), ('/usr/share/common-licenses/foo/bar', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }),
('/usr/share/common-licenses/what/ever', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**', '/usr/share/common-licenses/what/ever'} }), ('/usr/share/common-licenses/what/ever', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**', '/usr/share/common-licenses/what/ever'} }),
('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }), ('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }),
@ -575,7 +575,7 @@ class AaTest_get_file_perms_2(AATest):
('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }),
('/usr/lib/ispell/', {'allow': {'all': {'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/ispell/', '/{usr/,}lib{,32,64}/**'} }), # from abstractions/enchant ('/usr/lib/ispell/', {'allow': {'all': {'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/ispell/', '/{usr/,}lib{,32,64}/**'} }), # from abstractions/enchant
('/usr/lib/aspell/*.so', {'allow': {'all': {'m', 'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/aspell/*', '/usr/lib/aspell/*.so', '/{usr/,}lib{,32,64}/**', '/{usr/,}lib{,32,64}/**.so*'} }), # from abstractions/aspell via abstractions/enchant and from abstractions/base ('/usr/lib/aspell/*.so', {'allow': {'all': {'m', 'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/aspell/*', '/usr/lib/aspell/*.so', '/{usr/,}lib{,32,64}/**', '/{usr/,}lib{,32,64}/**.so*'} }), # from abstractions/aspell via abstractions/enchant and from abstractions/base
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.createTmpdir() self.createTmpdir()
@ -605,15 +605,15 @@ class AaTest_get_file_perms_2(AATest):
self.assertEqual(perms, expected) self.assertEqual(perms, expected)
class AaTest_propose_file_rules(AATest): class AaTest_propose_file_rules(AATest):
tests = [ tests = (
# log event path and perms expected proposals # log event path and perms expected proposals
(['/usr/share/common-licenses/foo/bar', 'w'], ['/usr/share/common*/foo/* rw,', '/usr/share/common-licenses/** rw,', '/usr/share/common-licenses/foo/bar rw,'] ), (('/usr/share/common-licenses/foo/bar', 'w'), ['/usr/share/common*/foo/* rw,', '/usr/share/common-licenses/** rw,', '/usr/share/common-licenses/foo/bar rw,'] ),
(['/dev/null', 'wk'], ['/dev/null rwk,'] ), (('/dev/null', 'wk'), ['/dev/null rwk,'] ),
(['/foo/bar', 'rw'], ['/foo/bar rw,'] ), (('/foo/bar', 'rw'), ['/foo/bar rw,'] ),
(['/usr/lib/ispell/', 'w'], ['/{usr/,}lib{,32,64}/** rw,', '/usr/lib/ispell/ rw,'] ), (('/usr/lib/ispell/', 'w'), ['/{usr/,}lib{,32,64}/** rw,', '/usr/lib/ispell/ rw,'] ),
(['/usr/lib/aspell/some.so', 'k'], ['/usr/lib/aspell/* mrk,', '/usr/lib/aspell/*.so mrk,', '/{usr/,}lib{,32,64}/** mrk,', '/{usr/,}lib{,32,64}/**.so* mrk,', '/usr/lib/aspell/some.so mrk,'] ), (('/usr/lib/aspell/some.so', 'k'), ['/usr/lib/aspell/* mrk,', '/usr/lib/aspell/*.so mrk,', '/{usr/,}lib{,32,64}/** mrk,', '/{usr/,}lib{,32,64}/**.so* mrk,', '/usr/lib/aspell/some.so mrk,'] ),
(['/foo/log', 'w'], ['/foo/log w,'] ), (('/foo/log', 'w'), ['/foo/log w,'] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.createTmpdir() self.createTmpdir()
@ -650,13 +650,13 @@ class AaTest_propose_file_rules(AATest):
class AaTest_propose_file_rules_with_absolute_includes(AATest): class AaTest_propose_file_rules_with_absolute_includes(AATest):
tests = [ tests = (
# log event path and perms expected proposals # log event path and perms expected proposals
(['/not/found/anywhere', 'r'], ['/not/found/anywhere r,']), (('/not/found/anywhere', 'r'), ['/not/found/anywhere r,']),
(['/dev/null', 'w'], ['/dev/null rw,']), (('/dev/null', 'w'), ['/dev/null rw,']),
(['/some/random/include', 'r'], ['/some/random/include rw,']), (('/some/random/include', 'r'), ['/some/random/include rw,']),
(['/some/other/include', 'w'], ['/some/other/* rw,', '/some/other/inc* rw,', '/some/other/include rw,']), (('/some/other/include', 'w'), ['/some/other/* rw,', '/some/other/inc* rw,', '/some/other/include rw,']),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.createTmpdir() self.createTmpdir()
@ -690,21 +690,21 @@ class AaTest_propose_file_rules_with_absolute_includes(AATest):
class AaTest_nonexistent_includes(AATest): class AaTest_nonexistent_includes(AATest):
tests = [ tests = (
("/nonexistent/absolute/path", AppArmorException), ("/nonexistent/absolute/path", AppArmorException),
("nonexistent/relative/path", AppArmorBug), # load_include() only accepts absolute paths ("nonexistent/relative/path", AppArmorBug), # load_include() only accepts absolute paths
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
apparmor.aa.load_include(params) apparmor.aa.load_include(params)
class AaTest_merged_to_split(AATest): class AaTest_merged_to_split(AATest):
tests = [ tests = (
("foo", ("foo", "foo")), ("foo", ("foo", "foo")),
("foo//bar", ("foo", "bar")), ("foo//bar", ("foo", "bar")),
("foo//bar//baz", ("foo", "bar")), # XXX known limitation ("foo//bar//baz", ("foo", "bar")), # XXX known limitation
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
merged = {} merged = {}
@ -718,10 +718,10 @@ class AaTest_merged_to_split(AATest):
self.assertTrue(result[profile][hat]) self.assertTrue(result[profile][hat])
class AaTest_split_to_merged(AATest): class AaTest_split_to_merged(AATest):
tests = [ tests = (
(("foo", "foo"), "foo"), (("foo", "foo"), "foo"),
(("foo", "bar"), "foo//bar"), (("foo", "bar"), "foo//bar"),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
old = {} old = {}

View file

@ -19,7 +19,7 @@ from apparmor.common import convert_regexp, AppArmorBug, AppArmorException
from apparmor.aare import AARE, convert_expression_to_aare from apparmor.aare import AARE, convert_expression_to_aare
class TestConvert_regexp(AATest): class TestConvert_regexp(AATest):
tests = [ tests = (
('/foo', '^/foo$'), ('/foo', '^/foo$'),
('/{foo,bar}', '^/(foo|bar)$'), ('/{foo,bar}', '^/(foo|bar)$'),
# ('/\{foo,bar}', '^/\{foo,bar}$'), # XXX gets converted to ^/\(foo|bar)$ # ('/\{foo,bar}', '^/\{foo,bar}$'), # XXX gets converted to ^/\(foo|bar)$
@ -31,13 +31,13 @@ class TestConvert_regexp(AATest):
('/fo?', '^/fo[^/\000]$'), ('/fo?', '^/fo[^/\000]$'),
('/foo/*', '^/foo/(((?<=/)[^/\000]+)|((?<!/)[^/\000]*))$'), ('/foo/*', '^/foo/(((?<=/)[^/\000]+)|((?<!/)[^/\000]*))$'),
('/foo/**.bar', '^/foo/(((?<=/)[^\000]+)|((?<!/)[^\000]*))\.bar$'), ('/foo/**.bar', '^/foo/(((?<=/)[^\000]+)|((?<!/)[^\000]*))\.bar$'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(convert_regexp(params), expected) self.assertEqual(convert_regexp(params), expected)
class Test_convert_expression_to_aare(AATest): class Test_convert_expression_to_aare(AATest):
tests = [ tests = (
# note that \ always needs to be escaped in python, so \\ is actually just \ in the string # note that \ always needs to be escaped in python, so \\ is actually just \ in the string
('/foo', '/foo' ), ('/foo', '/foo' ),
('/foo?', '/foo\\?' ), ('/foo?', '/foo\\?' ),
@ -49,88 +49,88 @@ class Test_convert_expression_to_aare(AATest):
('/foo\\', '/foo\\\\' ), ('/foo\\', '/foo\\\\' ),
('/foo"', '/foo\\"' ), ('/foo"', '/foo\\"' ),
('}]"\\[{', '\\}\\]\\"\\\\\\[\\{' ), ('}]"\\[{', '\\}\\]\\"\\\\\\[\\{' ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(convert_expression_to_aare(params), expected) self.assertEqual(convert_expression_to_aare(params), expected)
class TestConvert_regexpAndAAREMatch(AATest): class TestConvert_regexpAndAAREMatch(AATest):
tests = [ tests = (
# aare path to check match expected? # aare path to check match expected?
(['/foo/**/bar/', '/foo/user/tools/bar/' ], True), (('/foo/**/bar/', '/foo/user/tools/bar/' ), True),
(['/foo/**/bar/', '/foo/apparmor/bar/' ], True), (('/foo/**/bar/', '/foo/apparmor/bar/' ), True),
(['/foo/**/bar/', '/foo/apparmor/bar' ], False), (('/foo/**/bar/', '/foo/apparmor/bar' ), False),
(['/foo/**/bar/', '/a/foo/apparmor/bar/' ], False), (('/foo/**/bar/', '/a/foo/apparmor/bar/' ), False),
(['/foo/**/bar/', '/foo/apparmor/bar/baz' ], False), (('/foo/**/bar/', '/foo/apparmor/bar/baz' ), False),
(['/foo/*/bar/', '/foo/apparmor/bar/' ], True), (('/foo/*/bar/', '/foo/apparmor/bar/' ), True),
(['/foo/*/bar/', '/foo/apparmor/tools/bar/' ], False), (('/foo/*/bar/', '/foo/apparmor/tools/bar/' ), False),
(['/foo/*/bar/', '/foo/apparmor/bar' ], False), (('/foo/*/bar/', '/foo/apparmor/bar' ), False),
(['/foo/user/ba?/', '/foo/user/bar/' ], True), (('/foo/user/ba?/', '/foo/user/bar/' ), True),
(['/foo/user/ba?/', '/foo/user/bar/apparmor/' ], False), (('/foo/user/ba?/', '/foo/user/bar/apparmor/' ), False),
(['/foo/user/ba?/', '/foo/user/ba/' ], False), (('/foo/user/ba?/', '/foo/user/ba/' ), False),
(['/foo/user/ba?/', '/foo/user/ba//' ], False), (('/foo/user/ba?/', '/foo/user/ba//' ), False),
(['/foo/user/bar/**', '/foo/user/bar/apparmor' ], True), (('/foo/user/bar/**', '/foo/user/bar/apparmor' ), True),
(['/foo/user/bar/**', '/foo/user/bar/apparmor/tools' ], True), (('/foo/user/bar/**', '/foo/user/bar/apparmor/tools' ), True),
(['/foo/user/bar/**', '/foo/user/bar/' ], False), (('/foo/user/bar/**', '/foo/user/bar/' ), False),
(['/foo/user/bar/*', '/foo/user/bar/apparmor' ], True), (('/foo/user/bar/*', '/foo/user/bar/apparmor' ), True),
(['/foo/user/bar/*', '/foo/user/bar/apparmor/tools' ], False), (('/foo/user/bar/*', '/foo/user/bar/apparmor/tools' ), False),
(['/foo/user/bar/*', '/foo/user/bar/' ], False), (('/foo/user/bar/*', '/foo/user/bar/' ), False),
(['/foo/user/bar/*', '/foo/user/bar/apparmor/' ], False), (('/foo/user/bar/*', '/foo/user/bar/apparmor/' ), False),
(['/foo/**.jpg', '/foo/bar/baz/foobar.jpg' ], True), (('/foo/**.jpg', '/foo/bar/baz/foobar.jpg' ), True),
(['/foo/**.jpg', '/foo/bar/foobar.jpg' ], True), (('/foo/**.jpg', '/foo/bar/foobar.jpg' ), True),
(['/foo/**.jpg', '/foo/bar/*.jpg' ], True), (('/foo/**.jpg', '/foo/bar/*.jpg' ), True),
(['/foo/**.jpg', '/foo/bar.jpg' ], True), (('/foo/**.jpg', '/foo/bar.jpg' ), True),
(['/foo/**.jpg', '/foo/**.jpg' ], True), (('/foo/**.jpg', '/foo/**.jpg' ), True),
(['/foo/**.jpg', '/foo/*.jpg' ], True), (('/foo/**.jpg', '/foo/*.jpg' ), True),
(['/foo/**.jpg', '/foo/barjpg' ], False), (('/foo/**.jpg', '/foo/barjpg' ), False),
(['/foo/**.jpg', '/foo/.*' ], False), (('/foo/**.jpg', '/foo/.*' ), False),
(['/foo/**.jpg', '/bar.jpg' ], False), (('/foo/**.jpg', '/bar.jpg' ), False),
(['/foo/**.jpg', '/**.jpg' ], False), (('/foo/**.jpg', '/**.jpg' ), False),
(['/foo/**.jpg', '/*.jpg' ], False), (('/foo/**.jpg', '/*.jpg' ), False),
(['/foo/**.jpg', '/foo/*.bar' ], False), (('/foo/**.jpg', '/foo/*.bar' ), False),
(['/foo/{**,}', '/foo/' ], True), (('/foo/{**,}', '/foo/' ), True),
(['/foo/{**,}', '/foo/bar' ], True), (('/foo/{**,}', '/foo/bar' ), True),
(['/foo/{**,}', '/foo/bar/' ], True), (('/foo/{**,}', '/foo/bar/' ), True),
(['/foo/{**,}', '/foo/bar/baz' ], True), (('/foo/{**,}', '/foo/bar/baz' ), True),
(['/foo/{**,}', '/foo/bar/baz/' ], True), (('/foo/{**,}', '/foo/bar/baz/' ), True),
(['/foo/{**,}', '/bar/' ], False), (('/foo/{**,}', '/bar/' ), False),
(['/foo/{,**}', '/foo/' ], True), (('/foo/{,**}', '/foo/' ), True),
(['/foo/{,**}', '/foo/bar' ], True), (('/foo/{,**}', '/foo/bar' ), True),
(['/foo/{,**}', '/foo/bar/' ], True), (('/foo/{,**}', '/foo/bar/' ), True),
(['/foo/{,**}', '/foo/bar/baz' ], True), (('/foo/{,**}', '/foo/bar/baz' ), True),
(['/foo/{,**}', '/foo/bar/baz/' ], True), (('/foo/{,**}', '/foo/bar/baz/' ), True),
(['/foo/{,**}', '/bar/' ], False), (('/foo/{,**}', '/bar/' ), False),
(['/foo/a[bcd]e', '/foo/abe' ], True), (('/foo/a[bcd]e', '/foo/abe' ), True),
(['/foo/a[bcd]e', '/foo/abend' ], False), (('/foo/a[bcd]e', '/foo/abend' ), False),
(['/foo/a[bcd]e', '/foo/axe' ], False), (('/foo/a[bcd]e', '/foo/axe' ), False),
(['/foo/a[b-d]e', '/foo/abe' ], True), (('/foo/a[b-d]e', '/foo/abe' ), True),
(['/foo/a[b-d]e', '/foo/ace' ], True), (('/foo/a[b-d]e', '/foo/ace' ), True),
(['/foo/a[b-d]e', '/foo/abend' ], False), (('/foo/a[b-d]e', '/foo/abend' ), False),
(['/foo/a[b-d]e', '/foo/axe' ], False), (('/foo/a[b-d]e', '/foo/axe' ), False),
(['/foo/a[^bcd]e', '/foo/abe' ], False), (('/foo/a[^bcd]e', '/foo/abe' ), False),
(['/foo/a[^bcd]e', '/foo/abend' ], False), (('/foo/a[^bcd]e', '/foo/abend' ), False),
(['/foo/a[^bcd]e', '/foo/axe' ], True), (('/foo/a[^bcd]e', '/foo/axe' ), True),
(['/foo/{foo,bar,user,other}/bar/', '/foo/user/bar/' ], True), (('/foo/{foo,bar,user,other}/bar/', '/foo/user/bar/' ), True),
(['/foo/{foo,bar,user,other}/bar/', '/foo/bar/bar/' ], True), (('/foo/{foo,bar,user,other}/bar/', '/foo/bar/bar/' ), True),
(['/foo/{foo,bar,user,other}/bar/', '/foo/wrong/bar/' ], False), (('/foo/{foo,bar,user,other}/bar/', '/foo/wrong/bar/' ), False),
(['/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/user/test,ca}se/aa/bar/' ], True), (('/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/user/test,ca}se/aa/bar/' ), True),
(['/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/bar/test,ca}se/sd/bar/' ], True), (('/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/bar/test,ca}se/sd/bar/' ), True),
(['/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/wrong/user/bar/' ], False), (('/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/wrong/user/bar/' ), False),
(['/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/user/wrong/bar/' ], False), (('/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/user/wrong/bar/' ), False),
(['/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/wrong/aa/bar/' ], False), (('/foo/{foo,bar,user,other}/test,ca}se/{aa,sd,nd}/bar/', '/foo/wrong/aa/bar/' ), False),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
regex, path = params regex, path = params
@ -167,18 +167,18 @@ class TestConvert_regexpAndAAREMatch(AATest):
aare_obj.match(set()) aare_obj.match(set())
class TestAAREMatchFromLog(AATest): class TestAAREMatchFromLog(AATest):
tests = [ tests = (
# AARE log event match expected? # AARE log event match expected?
(['/foo/bar', '/foo/bar' ], True), (('/foo/bar', '/foo/bar' ), True),
(['/foo/*', '/foo/bar' ], True), (('/foo/*', '/foo/bar' ), True),
(['/**', '/foo/bar' ], True), (('/**', '/foo/bar' ), True),
(['/foo/*', '/bar/foo' ], False), (('/foo/*', '/bar/foo' ), False),
(['/foo/*', '/foo/"*' ], True), (('/foo/*', '/foo/"*' ), True),
(['/foo/bar', '/foo/*' ], False), (('/foo/bar', '/foo/*' ), False),
(['/foo/?', '/foo/(' ], True), (('/foo/?', '/foo/(' ), True),
(['/foo/{bar,baz}', '/foo/bar' ], True), (('/foo/{bar,baz}', '/foo/bar' ), True),
(['/foo/{bar,baz}', '/foo/bars' ], False), (('/foo/{bar,baz}', '/foo/bars' ), False),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
regex, log_event = params regex, log_event = params
@ -187,12 +187,12 @@ class TestAAREMatchFromLog(AATest):
self.assertEqual(aare_obj_1.match(aare_obj_2), expected) self.assertEqual(aare_obj_1.match(aare_obj_2), expected)
class TestAAREIsEqual(AATest): class TestAAREIsEqual(AATest):
tests = [ tests = (
# regex is path? check for expected # regex is path? check for expected
(['/foo', True, '/foo' ], True ), (('/foo', True, '/foo' ), True ),
(['@{foo}', True, '@{foo}' ], True ), (('@{foo}', True, '@{foo}' ), True ),
(['/**', True, '/foo' ], False), (('/**', True, '/foo' ), False),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
regex, is_path, check_for = params regex, is_path, check_for = params
@ -207,12 +207,12 @@ class TestAAREIsEqual(AATest):
aare_obj.is_equal(42) aare_obj.is_equal(42)
class TestAAREIsPath(AATest): class TestAAREIsPath(AATest):
tests = [ tests = (
# regex is path? match for expected # regex is path? match for expected
(['/foo*', True, '/foobar' ], True ), (('/foo*', True, '/foobar' ), True ),
(['@{PROC}/', True, '/foobar' ], False), (('@{PROC}/', True, '/foobar' ), False),
(['foo*', False, 'foobar' ], True ), (('foo*', False, 'foobar' ), True ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
regex, is_path, check_for = params regex, is_path, check_for = params
@ -229,13 +229,13 @@ class TestAARERepr(AATest):
self.assertEqual(str(obj), "AARE('/foo')") self.assertEqual(str(obj), "AARE('/foo')")
class TestAAREDeepcopy(AATest): class TestAAREDeepcopy(AATest):
tests = [ tests = (
# regex is path? log event expected (dummy value) # regex is path? log event expected (dummy value)
(AARE('/foo', False) , True), (AARE('/foo', False) , True),
(AARE('/foo', False, True) , True), (AARE('/foo', False, True) , True),
(AARE('/foo', True) , True), (AARE('/foo', True) , True),
(AARE('/foo', True, True) , True), (AARE('/foo', True, True) , True),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
dup = deepcopy(params) dup = deepcopy(params)
@ -248,7 +248,7 @@ class TestAAREDeepcopy(AATest):
self.assertEqual(params.orig_regex, dup.orig_regex) self.assertEqual(params.orig_regex, dup.orig_regex)
class TestAAREglobPath(AATest): class TestAAREglobPath(AATest):
tests = [ tests = (
# _run_test() will also run each test with '/' appended # _run_test() will also run each test with '/' appended
# regex expected AARE.regex # regex expected AARE.regex
('/foo/bar/baz**', '/foo/bar/**'), ('/foo/bar/baz**', '/foo/bar/**'),
@ -296,8 +296,7 @@ class TestAAREglobPath(AATest):
('/usr/foo/*/*', '/usr/foo/**',), ('/usr/foo/*/*', '/usr/foo/**',),
('/usr/foo/*/**', '/usr/foo/**',), ('/usr/foo/*/**', '/usr/foo/**',),
('/**', '/**',), ('/**', '/**',),
)
]
def _run_test(self, params, expected): def _run_test(self, params, expected):
# test for files # test for files
@ -311,7 +310,7 @@ class TestAAREglobPath(AATest):
self.assertEqual(expected + '/', newpath.regex) self.assertEqual(expected + '/', newpath.regex)
class TestAAREglobPathWithExt(AATest): class TestAAREglobPathWithExt(AATest):
tests = [ tests = (
# _run_test() will also run each test with '/' appended # _run_test() will also run each test with '/' appended
# regex expected AARE.regex # regex expected AARE.regex
@ -403,9 +402,7 @@ class TestAAREglobPathWithExt(AATest):
('/usr/bin/*foo*.baz', '/usr/bin/*.baz'), ('/usr/bin/*foo*.baz', '/usr/bin/*.baz'),
('/usr/foo/*/*.baz', '/usr/foo/**.baz'), ('/usr/foo/*/*.baz', '/usr/foo/**.baz'),
('/usr/foo/*/**.baz', '/usr/foo/**.baz'), ('/usr/foo/*/**.baz', '/usr/foo/**.baz'),
)
]
def _run_test(self, params, expected): def _run_test(self, params, expected):
# test for files # test for files

View file

@ -24,9 +24,9 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', [ # 'audit', 'allow_keyword', 'deny', exp = namedtuple('exp', ( # 'audit', 'allow_keyword', 'deny',
'comment', 'comment',
'path', 'ifexists', 'ismagic']) 'path', 'ifexists', 'ismagic'))
# --- tests for single AbiRule --- # # --- tests for single AbiRule --- #
@ -43,7 +43,7 @@ class AbiTest(AATest):
self.assertEqual(expected.ismagic, obj.ismagic) self.assertEqual(expected.ismagic, obj.ismagic)
class AbiTestParse(AbiTest): class AbiTestParse(AbiTest):
tests = [ tests = (
# AbiRule object comment path if exists ismagic # AbiRule object comment path if exists ismagic
('abi <abstractions/base>,', exp('', 'abstractions/base', False, True )), # magic path ('abi <abstractions/base>,', exp('', 'abstractions/base', False, True )), # magic path
('abi <abstractions/base>, # comment', exp(' # comment', 'abstractions/base', False, True )), ('abi <abstractions/base>, # comment', exp(' # comment', 'abstractions/base', False, True )),
@ -53,7 +53,7 @@ class AbiTestParse(AbiTest):
('abi "/foo/bar", # comment', exp(' # comment', '/foo/bar', False, False)), ('abi "/foo/bar", # comment', exp(' # comment', '/foo/bar', False, False)),
('abi "/foo/bar",#comment', exp(' #comment', '/foo/bar', False, False)), ('abi "/foo/bar",#comment', exp(' #comment', '/foo/bar', False, False)),
(' abi "/foo/bar" , ', exp('', '/foo/bar', False, False)), (' abi "/foo/bar" , ', exp('', '/foo/bar', False, False)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(AbiRule.match(rawrule)) self.assertTrue(AbiRule.match(rawrule))
@ -62,12 +62,12 @@ class AbiTestParse(AbiTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class AbiTestParseInvalid(AbiTest): class AbiTestParseInvalid(AbiTest):
tests = [ tests = (
# (' some abi <abstractions/base>', AppArmorException), # (' some abi <abstractions/base>', AppArmorException),
# (' /etc/fstab r,', AppArmorException), # (' /etc/fstab r,', AppArmorException),
# ('/usr/abi r,', AppArmorException), # ('/usr/abi r,', AppArmorException),
# ('/abi r,', AppArmorException), # ('/abi r,', AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(AbiRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(AbiRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -77,34 +77,34 @@ class AbiTestParseInvalid(AbiTest):
# class AbiTestParseFromLog(AbiTest): # we'll never have log events for abi # class AbiTestParseFromLog(AbiTest): # we'll never have log events for abi
class AbiFromInit(AbiTest): class AbiFromInit(AbiTest):
tests = [ tests = (
# AbiRule object ifexists ismagic comment path ifexists ismagic # AbiRule object ifexists ismagic comment path ifexists ismagic
(AbiRule('abi/4.19', False, False) , exp('', 'abi/4.19', False, False )), (AbiRule('abi/4.19', False, False) , exp('', 'abi/4.19', False, False )),
(AbiRule('foo', False, False) , exp('', 'foo', False, False )), (AbiRule('foo', False, False) , exp('', 'foo', False, False )),
(AbiRule('bar', False, True) , exp('', 'bar', False, True )), (AbiRule('bar', False, True) , exp('', 'bar', False, True )),
(AbiRule('comment', False, False, comment='# cmt') , exp('# cmt', 'comment', False, False )), (AbiRule('comment', False, False, comment='# cmt') , exp('# cmt', 'comment', False, False )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidAbiInit(AATest): class InvalidAbiInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([False, False, False ] , AppArmorBug), # wrong type for path ((False, False, False ) , AppArmorBug), # wrong type for path
(['', False, False ] , AppArmorBug), # empty path (('', False, False ) , AppArmorBug), # empty path
([None, False, False ] , AppArmorBug), # wrong type for path ((None, False, False ) , AppArmorBug), # wrong type for path
# ([' ', False, False ] , AppArmorBug), # whitespace-only path # ((' ', False, False ) , AppArmorBug), # whitespace-only path
(['foo', None, False ] , AppArmorBug), # wrong type for ifexists (('foo', None, False ) , AppArmorBug), # wrong type for ifexists
(['foo', '', False ] , AppArmorBug), # wrong type for ifexists (('foo', '', False ) , AppArmorBug), # wrong type for ifexists
(['foo', False, None ] , AppArmorBug), # wrong type for ismagic (('foo', False, None ) , AppArmorBug), # wrong type for ismagic
(['foo', False, '' ] , AppArmorBug), # wrong type for ismagic (('foo', False, '' ) , AppArmorBug), # wrong type for ismagic
(['', True, False ] , AppArmorBug), # ifexists set (('', True, False ) , AppArmorBug), # ifexists set
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
AbiRule(params[0], params[1], params[2]) AbiRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -162,7 +162,7 @@ class WriteAbiTestAATest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' abi <foo> , ', 'abi <foo>,' ), (' abi <foo> , ', 'abi <foo>,' ),
(' abi foo , ', 'abi "foo",' ), (' abi foo , ', 'abi "foo",' ),
@ -175,7 +175,7 @@ class WriteAbiTestAATest(AATest):
(' abi "foo", # bar ', 'abi "foo", # bar' ), (' abi "foo", # bar ', 'abi "foo", # bar' ),
(' abi /foo, # bar ', 'abi "/foo", # bar' ), (' abi /foo, # bar ', 'abi "/foo", # bar' ),
(' abi "/foo", # bar ', 'abi "/foo", # bar' ), (' abi "/foo", # bar ', 'abi "/foo", # bar' ),
] )
def test_write_manually(self): def test_write_manually(self):
obj = AbiRule('abs/foo', False, True, comment=' # cmt') obj = AbiRule('abs/foo', False, True, comment=' # cmt')
@ -202,24 +202,24 @@ class AbiCoveredTest(AATest):
class AbiCoveredTest_01(AbiCoveredTest): class AbiCoveredTest_01(AbiCoveredTest):
rule = 'abi <foo>,' rule = 'abi <foo>,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('abi <foo>,' , [ True , True , True , True ]), ('abi <foo>,' , ( True , True , True , True )),
('abi "foo",' , [ False , False , False , False ]), ('abi "foo",' , ( False , False , False , False )),
('abi <foobar>,' , [ False , False , False , False ]), ('abi <foobar>,' , ( False , False , False , False )),
('abi "foo",' , [ False , False , False , False ]), ('abi "foo",' , ( False , False , False , False )),
] )
class AbiCoveredTest_02(AbiCoveredTest): class AbiCoveredTest_02(AbiCoveredTest):
rule = 'abi "foo",' rule = 'abi "foo",'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('abi <foo>,' , [ False , False , False , False ]), ('abi <foo>,' , ( False , False , False , False )),
('abi "foo",' , [ True , True , True , True ]), ('abi "foo",' , ( True , True , True , True )),
('abi "foobar",' , [ False , False , False , False ]), ('abi "foobar",' , ( False , False , False , False )),
('abi foo,' , [ True , False , True , True ]), ('abi foo,' , ( True , False , True , True )),
] )
#class AbiCoveredTest_Invalid(AATest): #class AbiCoveredTest_Invalid(AATest):
# def test_borked_obj_is_covered_1(self): # def test_borked_obj_is_covered_1(self):
@ -266,10 +266,10 @@ class AbiCoveredTest_02(AbiCoveredTest):
# obj.is_equal(testobj) # obj.is_equal(testobj)
class AbiLogprofHeaderTest(AATest): class AbiLogprofHeaderTest(AATest):
tests = [ tests = (
('abi <abi/3.0>,', [_('Abi'), 'abi <abi/3.0>,', ]), ('abi <abi/3.0>,', [_('Abi'), 'abi <abi/3.0>,', ]),
('abi "/foo/bar",', [_('Abi'), 'abi "/foo/bar",', ]), ('abi "/foo/bar",', [_('Abi'), 'abi "/foo/bar",', ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = AbiRule.parse(params) obj = AbiRule.parse(params)
@ -289,10 +289,10 @@ class AbiRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = AbiRuleset() ruleset = AbiRuleset()
rules = [ rules = (
' abi <foo> ,', ' abi <foo> ,',
' abi "/bar", ', ' abi "/bar", ',
] )
expected_raw = [ expected_raw = [
'abi <foo> ,', 'abi <foo> ,',

View file

@ -23,8 +23,7 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['comment', exp = namedtuple('exp', ('comment', 'orig_path', 'target'))
'orig_path', 'target'])
# --- tests for single AliasRule --- # # --- tests for single AliasRule --- #
@ -40,12 +39,12 @@ class AliasTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class AliasTestParse(AliasTest): class AliasTestParse(AliasTest):
tests = [ tests = (
# rawrule comment orig_path target # rawrule comment orig_path target
('alias /foo -> /bar,', exp('', '/foo', '/bar' )), ('alias /foo -> /bar,', exp('', '/foo', '/bar' )),
(' alias /foo -> /bar , # comment', exp(' # comment', '/foo', '/bar' )), (' alias /foo -> /bar , # comment', exp(' # comment', '/foo', '/bar' )),
('alias "/foo 2" -> "/bar 2" ,', exp('', '/foo 2', '/bar 2' )), ('alias "/foo 2" -> "/bar 2" ,', exp('', '/foo 2', '/bar 2' )),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(AliasRule.match(rawrule)) self.assertTrue(AliasRule.match(rawrule))
@ -54,14 +53,14 @@ class AliasTestParse(AliasTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class AliasTestParseInvalid(AliasTest): class AliasTestParseInvalid(AliasTest):
tests = [ tests = (
# rawrule matches regex exception # rawrule matches regex exception
('alias ,' , (False, AppArmorException)), ('alias ,' , (False, AppArmorException)),
('alias /foo ,' , (False, AppArmorException)), ('alias /foo ,' , (False, AppArmorException)),
('alias /foo -> ,' , (True, AppArmorException)), ('alias /foo -> ,' , (True, AppArmorException)),
('alias -> /bar ,' , (True, AppArmorException)), ('alias -> /bar ,' , (True, AppArmorException)),
('/foo -> bar ,' , (False, AppArmorException)), ('/foo -> bar ,' , (False, AppArmorException)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertEqual(AliasRule.match(rawrule), expected[0]) self.assertEqual(AliasRule.match(rawrule), expected[0])
@ -69,31 +68,31 @@ class AliasTestParseInvalid(AliasTest):
AliasRule.parse(rawrule) AliasRule.parse(rawrule)
class AliasFromInit(AliasTest): class AliasFromInit(AliasTest):
tests = [ tests = (
# AliasRule object comment orig_path target # AliasRule object comment orig_path target
(AliasRule('/foo', '/bar'), exp('', '/foo', '/bar' )), (AliasRule('/foo', '/bar'), exp('', '/foo', '/bar' )),
(AliasRule('/foo', '/bar', comment='# cmt'), exp('# cmt', '/foo', '/bar' )), (AliasRule('/foo', '/bar', comment='# cmt'), exp('# cmt', '/foo', '/bar' )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidAliasInit(AATest): class InvalidAliasInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([None, '/bar' ], AppArmorBug), # orig_path not a str ((None, '/bar' ), AppArmorBug), # orig_path not a str
(['', '/bar' ], AppArmorException), # empty orig_path (('', '/bar' ), AppArmorException), # empty orig_path
(['foo', '/bar' ], AppArmorException), # orig_path not starting with / (('foo', '/bar' ), AppArmorException), # orig_path not starting with /
(['/foo', None ], AppArmorBug), # target not a str (('/foo', None ), AppArmorBug), # target not a str
(['/foo', '' ], AppArmorException), # empty target (('/foo', '' ), AppArmorException), # empty target
(['/foo', 'bar' ], AppArmorException), # target not starting with / (('/foo', 'bar' ), AppArmorException), # target not starting with /
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
AliasRule(params[0], params[1]) AliasRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -132,13 +131,13 @@ class InvalidAliasTest(AATest):
class WriteAliasTestAATest(AATest): class WriteAliasTestAATest(AATest):
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' alias /foo -> /bar, ', 'alias /foo -> /bar,'), (' alias /foo -> /bar, ', 'alias /foo -> /bar,'),
(' alias /foo -> /bar, # comment', 'alias /foo -> /bar,'), (' alias /foo -> /bar, # comment', 'alias /foo -> /bar,'),
(' alias "/foo" -> "/bar", ', 'alias /foo -> /bar,'), (' alias "/foo" -> "/bar", ', 'alias /foo -> /bar,'),
(' alias "/foo 2" -> "/bar 2", ', 'alias "/foo 2" -> "/bar 2",'), (' alias "/foo 2" -> "/bar 2", ', 'alias "/foo 2" -> "/bar 2",'),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(AliasRule.match(rawrule)) self.assertTrue(AliasRule.match(rawrule))
@ -182,16 +181,16 @@ class AliasCoveredTest(AATest):
class AliasCoveredTest_01(AliasCoveredTest): class AliasCoveredTest_01(AliasCoveredTest):
rule = 'alias /foo -> /bar,' rule = 'alias /foo -> /bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' alias /foo -> /bar,' , [ True , True , True , True ]), (' alias /foo -> /bar,' , ( True , True , True , True )),
(' alias /foo -> /bar , ' , [ True , False , True , True ]), (' alias /foo -> /bar , ' , ( True , False , True , True )),
(' alias /foo -> /bar, # comment' , [ True , False , True , True ]), (' alias /foo -> /bar, # comment' , ( True , False , True , True )),
(' alias /foo -> /bar, # comment' , [ True , False , True , True ]), (' alias /foo -> /bar, # comment' , ( True , False , True , True )),
(' alias /foo -> /asdf,' , [ False , False , False , False ]), (' alias /foo -> /asdf,' , ( False , False , False , False )),
(' alias /whatever -> /bar,' , [ False , False , False , False ]), (' alias /whatever -> /bar,' , ( False , False , False , False )),
(' alias /whatever -> /asdf,' , [ False , False , False , False ]), (' alias /whatever -> /asdf,' , ( False , False , False , False )),
] )
class AliasCoveredTest_Invalid(AATest): class AliasCoveredTest_Invalid(AATest):
# def test_borked_obj_is_covered_1(self): # def test_borked_obj_is_covered_1(self):
@ -228,9 +227,9 @@ class AliasCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class AliasLogprofHeaderTest(AATest): class AliasLogprofHeaderTest(AATest):
tests = [ tests = (
('alias /foo -> /bar,', [_('Alias'), '/foo -> /bar' ]), ('alias /foo -> /bar,', [_('Alias'), '/foo -> /bar' ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = AliasRule.parse(params) obj = AliasRule.parse(params)

View file

@ -23,8 +23,7 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['comment', exp = namedtuple('exp', ('comment', 'varname', 'value'))
'varname', 'value'])
# --- tests for single BooleanRule --- # # --- tests for single BooleanRule --- #
@ -40,7 +39,7 @@ class BooleanTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class BooleanTestParse(BooleanTest): class BooleanTestParse(BooleanTest):
tests = [ tests = (
# rawrule comment varname value # rawrule comment varname value
('$foo=true', exp('', '$foo', 'true' )), ('$foo=true', exp('', '$foo', 'true' )),
('$foo = false', exp('', '$foo', 'false' )), ('$foo = false', exp('', '$foo', 'false' )),
@ -48,7 +47,7 @@ class BooleanTestParse(BooleanTest):
('$foo = FaLsE', exp('', '$foo', 'false' )), ('$foo = FaLsE', exp('', '$foo', 'false' )),
(' $foo = true ', exp('', '$foo', 'true' )), (' $foo = true ', exp('', '$foo', 'true' )),
(' $foo = true # comment', exp(' # comment', '$foo', 'true' )), (' $foo = true # comment', exp(' # comment', '$foo', 'true' )),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(BooleanRule.match(rawrule)) self.assertTrue(BooleanRule.match(rawrule))
@ -57,7 +56,7 @@ class BooleanTestParse(BooleanTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class BooleanTestParseInvalid(BooleanTest): class BooleanTestParseInvalid(BooleanTest):
tests = [ tests = (
# rawrule matches regex exception # rawrule matches regex exception
('$foo =', (False, AppArmorException)), ('$foo =', (False, AppArmorException)),
('$ foo = # comment', (False, AppArmorException)), ('$ foo = # comment', (False, AppArmorException)),
@ -66,7 +65,7 @@ class BooleanTestParseInvalid(BooleanTest):
# ('$foo = true,', (True, AppArmorException)), # trailing comma # ('$foo = true,', (True, AppArmorException)), # trailing comma
# ('$foo = false , ', (True, AppArmorException)), # trailing comma # ('$foo = false , ', (True, AppArmorException)), # trailing comma
# ('$foo = true, # comment', (True, AppArmorException)), # trailing comma # ('$foo = true, # comment', (True, AppArmorException)), # trailing comma
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertEqual(BooleanRule.match(rawrule), expected[0]) self.assertEqual(BooleanRule.match(rawrule), expected[0])
@ -74,34 +73,34 @@ class BooleanTestParseInvalid(BooleanTest):
BooleanRule.parse(rawrule) BooleanRule.parse(rawrule)
class BooleanFromInit(BooleanTest): class BooleanFromInit(BooleanTest):
# tests = [ # tests = (
# # BooleanRule object comment varname value # # BooleanRule object comment varname value
# (BooleanRule('$foo', True, exp('', '$foo', True ))), # (BooleanRule('$foo', True, exp('', '$foo', True ))),
# (BooleanRule('$foo', False, exp('', '$foo', False ))), # (BooleanRule('$foo', False, exp('', '$foo', False ))),
# (BooleanRule('$foo', True, comment='# cmt'), exp('# cmt', '$foo', True ))), # (BooleanRule('$foo', True, comment='# cmt'), exp('# cmt', '$foo', True ))),
# (BooleanRule('$foo', False, comment='# cmt'), exp('# cmt', '$foo', False ))), # (BooleanRule('$foo', False, comment='# cmt'), exp('# cmt', '$foo', False ))),
# ] # )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidBooleanInit(AATest): class InvalidBooleanInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([None, True ], AppArmorBug), # varname not a str ((None, True ), AppArmorBug), # varname not a str
(['', True ], AppArmorException), # empty varname (('', True ), AppArmorException), # empty varname
(['foo', True ], AppArmorException), # varname not starting with '$' (('foo', True ), AppArmorException), # varname not starting with '$'
(['foo', True ], AppArmorException), # varname not starting with '$' (('foo', True ), AppArmorException), # varname not starting with '$'
(['$foo', None ], AppArmorBug), # value not a string (('$foo', None ), AppArmorBug), # value not a string
(['$foo', '' ], AppArmorException), # empty value (('$foo', '' ), AppArmorException), # empty value
(['$foo', 'maybe' ], AppArmorException), # invalid value (('$foo', 'maybe' ), AppArmorException), # invalid value
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
BooleanRule(params[0], params[1]) BooleanRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -137,13 +136,13 @@ class InvalidBooleanTest(AATest):
class WriteBooleanTestAATest(AATest): class WriteBooleanTestAATest(AATest):
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' $foo = true ', '$foo = true'), (' $foo = true ', '$foo = true'),
(' $foo = true # comment', '$foo = true'), (' $foo = true # comment', '$foo = true'),
(' $foo = false ', '$foo = false'), (' $foo = false ', '$foo = false'),
(' $foo = false # comment', '$foo = false'), (' $foo = false # comment', '$foo = false'),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(BooleanRule.match(rawrule)) self.assertTrue(BooleanRule.match(rawrule))
@ -187,27 +186,27 @@ class BooleanCoveredTest(AATest):
class BooleanCoveredTest_01(BooleanCoveredTest): class BooleanCoveredTest_01(BooleanCoveredTest):
rule = '$foo = true' rule = '$foo = true'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' $foo = true' , [ True , True , True , True ]), (' $foo = true' , ( True , True , True , True )),
(' $foo = TRUE' , [ True , False , True , True ]), # upper vs. lower case (' $foo = TRUE' , ( True , False , True , True )), # upper vs. lower case
(' $foo = true # comment' , [ True , False , True , True ]), (' $foo = true # comment' , ( True , False , True , True )),
(' $foo = false' , [ False , False , False , False ]), (' $foo = false' , ( False , False , False , False )),
(' $foo = false # cmt' , [ False , False , False , False ]), (' $foo = false # cmt' , ( False , False , False , False )),
(' $bar = true' , [ False , False , False , False ]), # different variable name (' $bar = true' , ( False , False , False , False )), # different variable name
] )
class BooleanCoveredTest_02(BooleanCoveredTest): class BooleanCoveredTest_02(BooleanCoveredTest):
rule = '$foo = false' rule = '$foo = false'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' $foo = false' , [ True , True , True , True ]), (' $foo = false' , ( True , True , True , True )),
(' $foo = false # comment' , [ True , False , True , True ]), (' $foo = false # comment' , ( True , False , True , True )),
(' $foo = true' , [ False , False , False , False ]), (' $foo = true' , ( False , False , False , False )),
(' $foo = true # cmt' , [ False , False , False , False ]), (' $foo = true # cmt' , ( False , False , False , False )),
(' $bar = false' , [ False , False , False , False ]), # different variable name (' $bar = false' , ( False , False , False , False )), # different variable name
] )
class BooleanCoveredTest_Invalid(AATest): class BooleanCoveredTest_Invalid(AATest):
def test_borked_obj_is_covered_2(self): def test_borked_obj_is_covered_2(self):
@ -236,9 +235,9 @@ class BooleanCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class BooleanLogprofHeaderTest(AATest): class BooleanLogprofHeaderTest(AATest):
tests = [ tests = (
('$foo = true', [_('Boolean Variable'), '$foo = true' ]), ('$foo = true', [_('Boolean Variable'), '$foo = true' ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = BooleanRule.parse(params) obj = BooleanRule.parse(params)

View file

@ -426,13 +426,13 @@ class CapabilityCoveredTest(AATest):
self.assertTrue(self._is_covered(obj2, 'capability ptrace,')) self.assertTrue(self._is_covered(obj2, 'capability ptrace,'))
class CapabiliySeverityTest(AATest): class CapabiliySeverityTest(AATest):
tests = [ tests = (
('fsetid', 9), ('fsetid', 9),
('dac_read_search', 7), ('dac_read_search', 7),
(['fsetid', 'dac_read_search'], 9), (['fsetid', 'dac_read_search'], 9),
(CapabilityRule.ALL, 10), (CapabilityRule.ALL, 10),
('foo', 'unknown'), ('foo', 'unknown'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
sev_db = severity.Severity('../severity.db', 'unknown') sev_db = severity.Severity('../severity.db', 'unknown')
obj = CapabilityRule(params) obj = CapabilityRule(params)
@ -440,7 +440,7 @@ class CapabiliySeverityTest(AATest):
self.assertEqual(rank, expected) self.assertEqual(rank, expected)
class CapabilityLogprofHeaderTest(AATest): class CapabilityLogprofHeaderTest(AATest):
tests = [ tests = (
('capability,', [ _('Capability'), _('ALL'), ]), ('capability,', [ _('Capability'), _('ALL'), ]),
('capability chown,', [ _('Capability'), 'chown', ]), ('capability chown,', [ _('Capability'), 'chown', ]),
('capability chown fsetid,', [ _('Capability'), 'chown fsetid', ]), ('capability chown fsetid,', [ _('Capability'), 'chown fsetid', ]),
@ -448,7 +448,7 @@ class CapabilityLogprofHeaderTest(AATest):
('deny capability chown,', [_('Qualifier'), 'deny', _('Capability'), 'chown', ]), ('deny capability chown,', [_('Qualifier'), 'deny', _('Capability'), 'chown', ]),
('allow capability chown fsetid,', [_('Qualifier'), 'allow', _('Capability'), 'chown fsetid', ]), ('allow capability chown fsetid,', [_('Qualifier'), 'allow', _('Capability'), 'chown fsetid', ]),
('audit deny capability,', [_('Qualifier'), 'audit deny', _('Capability'), _('ALL'), ]), ('audit deny capability,', [_('Qualifier'), 'audit deny', _('Capability'), _('ALL'), ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = CapabilityRule.parse(params) obj = CapabilityRule.parse(params)

View file

@ -24,8 +24,8 @@ from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'execmode', 'execcond', 'all_execconds', 'targetprofile', 'all_targetprofiles']) 'execmode', 'execcond', 'all_execconds', 'targetprofile', 'all_targetprofiles'))
# --- tests for single ChangeProfileRule --- # # --- tests for single ChangeProfileRule --- #
@ -42,7 +42,7 @@ class ChangeProfileTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class ChangeProfileTestParse(ChangeProfileTest): class ChangeProfileTestParse(ChangeProfileTest):
tests = [ tests = (
# rawrule audit allow deny comment execmode execcond all? targetprof all? # rawrule audit allow deny comment execmode execcond all? targetprof all?
('change_profile,' , exp(False, False, False, '' , None , None , True , None , True )), ('change_profile,' , exp(False, False, False, '' , None , None , True , None , True )),
('change_profile /foo,' , exp(False, False, False, '' , None , '/foo', False, None , True )), ('change_profile /foo,' , exp(False, False, False, '' , None , '/foo', False, None , True )),
@ -70,7 +70,7 @@ class ChangeProfileTestParse(ChangeProfileTest):
('audit allow change_profile /**,' , exp(True , True , False, '' , None , '/**' , False, None , True )), ('audit allow change_profile /**,' , exp(True , True , False, '' , None , '/**' , False, None , True )),
('change_profile -> "ba r",' , exp(False, False, False, '' , None , None , True , 'ba r' , False)), ('change_profile -> "ba r",' , exp(False, False, False, '' , None , None , True , 'ba r' , False)),
('audit allow change_profile -> "ba r",' , exp(True , True , False, '' , None , None , True , 'ba r' , False)), ('audit allow change_profile -> "ba r",' , exp(True , True , False, '' , None , None , True , 'ba r' , False)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(ChangeProfileRule.match(rawrule)) self.assertTrue(ChangeProfileRule.match(rawrule))
@ -79,12 +79,12 @@ class ChangeProfileTestParse(ChangeProfileTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class ChangeProfileTestParseInvalid(ChangeProfileTest): class ChangeProfileTestParseInvalid(ChangeProfileTest):
tests = [ tests = (
('change_profile -> ,' , AppArmorException), ('change_profile -> ,' , AppArmorException),
('change_profile foo -> ,' , AppArmorException), ('change_profile foo -> ,' , AppArmorException),
('change_profile notsafe,' , AppArmorException), ('change_profile notsafe,' , AppArmorException),
('change_profile safety -> /bar,' , AppArmorException), ('change_profile safety -> /bar,' , AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertFalse(ChangeProfileRule.match(rawrule)) self.assertFalse(ChangeProfileRule.match(rawrule))
@ -136,7 +136,7 @@ class ChangeProfileTestParseFromLog(ChangeProfileTest):
class ChangeProfileFromInit(ChangeProfileTest): class ChangeProfileFromInit(ChangeProfileTest):
tests = [ tests = (
# ChangeProfileRule object audit allow deny comment execmode execcond all? targetprof all? # ChangeProfileRule object audit allow deny comment execmode execcond all? targetprof all?
(ChangeProfileRule(None , '/foo', '/bar', deny=True) , exp(False, False, True , '' , None , '/foo', False, '/bar' , False)), (ChangeProfileRule(None , '/foo', '/bar', deny=True) , exp(False, False, True , '' , None , '/foo', False, '/bar' , False)),
(ChangeProfileRule(None , '/foo', '/bar') , exp(False, False, False, '' , None , '/foo', False, '/bar' , False)), (ChangeProfileRule(None , '/foo', '/bar') , exp(False, False, False, '' , None , '/foo', False, '/bar' , False)),
@ -146,30 +146,30 @@ class ChangeProfileFromInit(ChangeProfileTest):
(ChangeProfileRule(None , ChangeProfileRule.ALL, '/bar') , exp(False, False, False, '' , None , None , True , '/bar' , False)), (ChangeProfileRule(None , ChangeProfileRule.ALL, '/bar') , exp(False, False, False, '' , None , None , True , '/bar' , False)),
(ChangeProfileRule(None , ChangeProfileRule.ALL, (ChangeProfileRule(None , ChangeProfileRule.ALL,
ChangeProfileRule.ALL) , exp(False, False, False, '' , None, None , True , None , True )), ChangeProfileRule.ALL) , exp(False, False, False, '' , None, None , True , None , True )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidChangeProfileInit(AATest): class InvalidChangeProfileInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([None , '/foo', '' ] , AppArmorBug), # empty targetprofile ((None , '/foo', '' ) , AppArmorBug), # empty targetprofile
([None , '' , '/bar' ] , AppArmorBug), # empty execcond ((None , '' , '/bar' ) , AppArmorBug), # empty execcond
([None , ' ', '/bar' ] , AppArmorBug), # whitespace execcond ((None , ' ', '/bar' ) , AppArmorBug), # whitespace execcond
([None , '/foo', ' ' ] , AppArmorBug), # whitespace targetprofile ((None , '/foo', ' ' ) , AppArmorBug), # whitespace targetprofile
([None , 'xyxy', '/bar' ] , AppArmorException), # invalid execcond ((None , 'xyxy', '/bar' ) , AppArmorException), # invalid execcond
([None , dict(), '/bar' ] , AppArmorBug), # wrong type for execcond ((None , dict(), '/bar' ) , AppArmorBug), # wrong type for execcond
([None , None , '/bar' ] , AppArmorBug), # wrong type for execcond ((None , None , '/bar' ) , AppArmorBug), # wrong type for execcond
([None , '/foo', dict() ] , AppArmorBug), # wrong type for targetprofile ((None , '/foo', dict() ) , AppArmorBug), # wrong type for targetprofile
([None , '/foo', None ] , AppArmorBug), # wrong type for targetprofile ((None , '/foo', None ) , AppArmorBug), # wrong type for targetprofile
(['maybe' , '/foo', '/bar' ] , AppArmorBug), # invalid keyword for execmode (('maybe' , '/foo', '/bar' ) , AppArmorBug), # invalid keyword for execmode
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
ChangeProfileRule(params[0], params[1], params[2]) ChangeProfileRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -211,7 +211,7 @@ class InvalidChangeProfileTest(AATest):
class WriteChangeProfileTestAATest(AATest): class WriteChangeProfileTestAATest(AATest):
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' change_profile , # foo ' , 'change_profile, # foo'), (' change_profile , # foo ' , 'change_profile, # foo'),
(' audit change_profile /foo,' , 'audit change_profile /foo,'), (' audit change_profile /foo,' , 'audit change_profile /foo,'),
@ -220,7 +220,7 @@ class WriteChangeProfileTestAATest(AATest):
(' allow change_profile -> /bar ,# foo bar' , 'allow change_profile -> /bar, # foo bar'), (' allow change_profile -> /bar ,# foo bar' , 'allow change_profile -> /bar, # foo bar'),
(' allow change_profile unsafe /** -> /bar ,# foo bar' , 'allow change_profile unsafe /** -> /bar, # foo bar'), (' allow change_profile unsafe /** -> /bar ,# foo bar' , 'allow change_profile unsafe /** -> /bar, # foo bar'),
(' allow change_profile "/fo o" -> "/b ar",' , 'allow change_profile "/fo o" -> "/b ar",'), (' allow change_profile "/fo o" -> "/b ar",' , 'allow change_profile "/fo o" -> "/b ar",'),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(ChangeProfileRule.match(rawrule)) self.assertTrue(ChangeProfileRule.match(rawrule))
@ -256,95 +256,95 @@ class ChangeProfileCoveredTest(AATest):
class ChangeProfileCoveredTest_01(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_01(ChangeProfileCoveredTest):
rule = 'change_profile /foo,' rule = 'change_profile /foo,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' change_profile,' , [ False , False , False , False ]), (' change_profile,' , ( False , False , False , False )),
(' change_profile /foo,' , [ True , True , True , True ]), (' change_profile /foo,' , ( True , True , True , True )),
(' change_profile safe /foo,' , [ True , False , True , True ]), (' change_profile safe /foo,' , ( True , False , True , True )),
(' change_profile unsafe /foo,' , [ False , False , False , False ]), (' change_profile unsafe /foo,' , ( False , False , False , False )),
(' change_profile /foo, # comment', [ True , False , True , True ]), (' change_profile /foo, # comment', ( True , False , True , True )),
(' allow change_profile /foo,' , [ True , False , True , True ]), (' allow change_profile /foo,' , ( True , False , True , True )),
(' change_profile /foo,' , [ True , False , True , True ]), (' change_profile /foo,' , ( True , False , True , True )),
(' change_profile /foo -> /bar,' , [ False , False , True , True ]), (' change_profile /foo -> /bar,' , ( False , False , True , True )),
(' change_profile /foo -> bar,' , [ False , False , True , True ]), (' change_profile /foo -> bar,' , ( False , False , True , True )),
('audit change_profile /foo,' , [ False , False , False , False ]), ('audit change_profile /foo,' , ( False , False , False , False )),
('audit change_profile,' , [ False , False , False , False ]), ('audit change_profile,' , ( False , False , False , False )),
(' change_profile /asdf,' , [ False , False , False , False ]), (' change_profile /asdf,' , ( False , False , False , False )),
(' change_profile -> /bar,' , [ False , False , False , False ]), (' change_profile -> /bar,' , ( False , False , False , False )),
('audit deny change_profile /foo,' , [ False , False , False , False ]), ('audit deny change_profile /foo,' , ( False , False , False , False )),
(' deny change_profile /foo,' , [ False , False , False , False ]), (' deny change_profile /foo,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_02(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_02(ChangeProfileCoveredTest):
rule = 'audit change_profile /foo,' rule = 'audit change_profile /foo,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'change_profile /foo,' , [ False , False , True , False ]), ( 'change_profile /foo,' , ( False , False , True , False )),
('audit change_profile /foo,' , [ True , True , True , True ]), ('audit change_profile /foo,' , ( True , True , True , True )),
( 'change_profile /foo -> /bar,' , [ False , False , True , False ]), ( 'change_profile /foo -> /bar,' , ( False , False , True , False )),
( 'change_profile safe /foo -> /bar,' , [ False , False , True , False ]), ( 'change_profile safe /foo -> /bar,' , ( False , False , True , False )),
('audit change_profile /foo -> /bar,' , [ False , False , True , True ]), # XXX is "covered exact" correct here? ('audit change_profile /foo -> /bar,' , ( False , False , True , True )), # XXX is "covered exact" correct here?
( 'change_profile,' , [ False , False , False , False ]), ( 'change_profile,' , ( False , False , False , False )),
('audit change_profile,' , [ False , False , False , False ]), ('audit change_profile,' , ( False , False , False , False )),
(' change_profile -> /bar,' , [ False , False , False , False ]), (' change_profile -> /bar,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_03(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_03(ChangeProfileCoveredTest):
rule = 'change_profile /foo -> /bar,' rule = 'change_profile /foo -> /bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'change_profile /foo -> /bar,' , [ True , True , True , True ]), ( 'change_profile /foo -> /bar,' , ( True , True , True , True )),
('allow change_profile /foo -> /bar,' , [ True , False , True , True ]), ('allow change_profile /foo -> /bar,' , ( True , False , True , True )),
( 'change_profile /foo,' , [ False , False , False , False ]), ( 'change_profile /foo,' , ( False , False , False , False )),
( 'change_profile,' , [ False , False , False , False ]), ( 'change_profile,' , ( False , False , False , False )),
( 'change_profile /foo -> /xyz,' , [ False , False , False , False ]), ( 'change_profile /foo -> /xyz,' , ( False , False , False , False )),
('audit change_profile,' , [ False , False , False , False ]), ('audit change_profile,' , ( False , False , False , False )),
('audit change_profile /foo -> /bar,' , [ False , False , False , False ]), ('audit change_profile /foo -> /bar,' , ( False , False , False , False )),
( 'change_profile -> /bar,' , [ False , False , False , False ]), ( 'change_profile -> /bar,' , ( False , False , False , False )),
( 'change_profile,' , [ False , False , False , False ]), ( 'change_profile,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_04(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_04(ChangeProfileCoveredTest):
rule = 'change_profile,' rule = 'change_profile,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'change_profile,' , [ True , True , True , True ]), ( 'change_profile,' , ( True , True , True , True )),
('allow change_profile,' , [ True , False , True , True ]), ('allow change_profile,' , ( True , False , True , True )),
( 'change_profile /foo,' , [ False , False , True , True ]), ( 'change_profile /foo,' , ( False , False , True , True )),
( 'change_profile /xyz -> bar,' , [ False , False , True , True ]), ( 'change_profile /xyz -> bar,' , ( False , False , True , True )),
( 'change_profile -> /bar,' , [ False , False , True , True ]), ( 'change_profile -> /bar,' , ( False , False , True , True )),
( 'change_profile /foo -> /bar,' , [ False , False , True , True ]), ( 'change_profile /foo -> /bar,' , ( False , False , True , True )),
('audit change_profile,' , [ False , False , False , False ]), ('audit change_profile,' , ( False , False , False , False )),
('deny change_profile,' , [ False , False , False , False ]), ('deny change_profile,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_05(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_05(ChangeProfileCoveredTest):
rule = 'deny change_profile /foo,' rule = 'deny change_profile /foo,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny change_profile /foo,' , [ True , True , True , True ]), ( 'deny change_profile /foo,' , ( True , True , True , True )),
('audit deny change_profile /foo,' , [ False , False , False , False ]), ('audit deny change_profile /foo,' , ( False , False , False , False )),
( 'change_profile /foo,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'change_profile /foo,' , ( False , False , False , False )), # XXX should covered be true here?
( 'deny change_profile /bar,' , [ False , False , False , False ]), ( 'deny change_profile /bar,' , ( False , False , False , False )),
( 'deny change_profile,' , [ False , False , False , False ]), ( 'deny change_profile,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_06(ChangeProfileCoveredTest): class ChangeProfileCoveredTest_06(ChangeProfileCoveredTest):
rule = 'change_profile safe /foo,' rule = 'change_profile safe /foo,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny change_profile /foo,' , [ False , False , False , False ]), ( 'deny change_profile /foo,' , ( False , False , False , False )),
('audit deny change_profile /foo,' , [ False , False , False , False ]), ('audit deny change_profile /foo,' , ( False , False , False , False )),
( 'change_profile /foo,' , [ True , False , True , True ]), ( 'change_profile /foo,' , ( True , False , True , True )),
( 'deny change_profile /bar,' , [ False , False , False , False ]), ( 'deny change_profile /bar,' , ( False , False , False , False )),
( 'deny change_profile,' , [ False , False , False , False ]), ( 'deny change_profile,' , ( False , False , False , False )),
] )
class ChangeProfileCoveredTest_Invalid(AATest): class ChangeProfileCoveredTest_Invalid(AATest):
def test_borked_obj_is_covered_1(self): def test_borked_obj_is_covered_1(self):
@ -382,16 +382,16 @@ class ChangeProfileCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class ChangeProfileLogprofHeaderTest(AATest): class ChangeProfileLogprofHeaderTest(AATest):
tests = [ tests = (
('change_profile,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]), ('change_profile,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]),
('change_profile -> /bin/ping,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]), ('change_profile -> /bin/ping,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]),
('change_profile /bar -> /bin/bar,', [ _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]), ('change_profile /bar -> /bin/bar,', [ _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]),
('change_profile safe /foo,', [ _('Exec Mode'), 'safe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]), ('change_profile safe /foo,', [ _('Exec Mode'), 'safe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]),
('audit change_profile -> /bin/ping,', [_('Qualifier'), 'audit', _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]), ('audit change_profile -> /bin/ping,', [_('Qualifier'), 'audit', _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]),
('deny change_profile /bar -> /bin/bar,', [_('Qualifier'), 'deny', _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]), ('deny change_profile /bar -> /bin/bar,', [_('Qualifier'), 'deny', _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]),
('allow change_profile unsafe /foo,', [_('Qualifier'), 'allow', _('Exec Mode'), 'unsafe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]), ('allow change_profile unsafe /foo,', [_('Qualifier'), 'allow', _('Exec Mode'), 'unsafe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]),
('audit deny change_profile,', [_('Qualifier'), 'audit deny', _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]), ('audit deny change_profile,', [_('Qualifier'), 'audit deny', _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = ChangeProfileRule.parse(params) obj = ChangeProfileRule.parse(params)
@ -410,10 +410,10 @@ class ChangeProfileRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = ChangeProfileRuleset() ruleset = ChangeProfileRuleset()
rules = [ rules = (
'change_profile -> /bar,', 'change_profile -> /bar,',
'change_profile /foo,', 'change_profile /foo,',
] )
expected_raw = [ expected_raw = [
'change_profile -> /bar,', 'change_profile -> /bar,',
@ -435,11 +435,11 @@ class ChangeProfileRulesTest(AATest):
def test_ruleset_2(self): def test_ruleset_2(self):
ruleset = ChangeProfileRuleset() ruleset = ChangeProfileRuleset()
rules = [ rules = (
'change_profile /foo -> /bar,', 'change_profile /foo -> /bar,',
'allow change_profile /asdf,', 'allow change_profile /asdf,',
'deny change_profile -> xy, # example comment', 'deny change_profile -> xy, # example comment',
] )
expected_raw = [ expected_raw = [
' change_profile /foo -> /bar,', ' change_profile /foo -> /bar,',

View file

@ -16,37 +16,37 @@ from apparmor.common import AppArmorBug
from apparmor.common import type_is_str, split_name, combine_profname from apparmor.common import type_is_str, split_name, combine_profname
class TestIs_str_type(AATest): class TestIs_str_type(AATest):
tests = [ tests = (
('foo', True), ('foo', True),
(u'foo', True), (u'foo', True),
(42, False), (42, False),
(True, False), (True, False),
([], False), ([], False),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(type_is_str(params), expected) self.assertEqual(type_is_str(params), expected)
class AaTest_split_name(AATest): class AaTest_split_name(AATest):
tests = [ tests = (
# full profile name expected parts # full profile name expected parts
('foo', ('foo', 'foo')), ('foo', ('foo', 'foo')),
('foo//bar', ('foo', 'bar')), ('foo//bar', ('foo', 'bar')),
('foo//bar//baz', ('foo', 'bar')), # XXX nested child profiles get cut off ('foo//bar//baz', ('foo', 'bar')), # XXX nested child profiles get cut off
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(split_name(params), expected) self.assertEqual(split_name(params), expected)
class AaTest_combine_profname(AATest): class AaTest_combine_profname(AATest):
tests = [ tests = (
# name parts expected full profile name # name parts expected full profile name
(['foo'], 'foo'), (['foo'], 'foo'),
(['foo', 'bar'], 'foo//bar'), (['foo', 'bar'], 'foo//bar'),
(['foo', 'bar', 'baz'], 'foo//bar//baz'), (['foo', 'bar', 'baz'], 'foo//bar//baz'),
(['foo', 'bar', None], 'foo//bar'), (['foo', 'bar', None], 'foo//bar'),
(['foo', 'bar', 'baz', None], 'foo//bar//baz'), (['foo', 'bar', 'baz', None], 'foo//bar//baz'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(combine_profname(params), expected) self.assertEqual(combine_profname(params), expected)

View file

@ -38,7 +38,7 @@ class Test(unittest.TestCase):
easyprof_Policygroup = './policygroups' easyprof_Policygroup = './policygroups'
easyprof_Templates = './templates' easyprof_Templates = './templates'
self.assertEqual(sorted(list(conf[''].keys())), sorted(easyprof_sections)) self.assertEqual(sorted(conf[''].keys()), easyprof_sections)
self.assertEqual(conf['']['POLICYGROUPS_DIR'], easyprof_Policygroup) self.assertEqual(conf['']['POLICYGROUPS_DIR'], easyprof_Policygroup)
self.assertEqual(conf['']['TEMPLATES_DIR'], easyprof_Templates) self.assertEqual(conf['']['TEMPLATES_DIR'], easyprof_Templates)

View file

@ -24,8 +24,8 @@ from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'access', 'all_access', 'bus', 'all_buses', 'path', 'all_paths', 'name', 'all_names', 'interface', 'all_interfaces', 'member', 'all_members', 'peername', 'all_peernames', 'peerlabel', 'all_peerlabels']) 'access', 'all_access', 'bus', 'all_buses', 'path', 'all_paths', 'name', 'all_names', 'interface', 'all_interfaces', 'member', 'all_members', 'peername', 'all_peernames', 'peerlabel', 'all_peerlabels'))
# --- tests for single DbusRule --- # # --- tests for single DbusRule --- #
@ -61,7 +61,7 @@ class DbusTest(AATest):
self.assertEqual(obj, expected) self.assertEqual(obj, expected)
class DbusTestParse(DbusTest): class DbusTestParse(DbusTest):
tests = [ tests = (
# DbusRule object audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? # DbusRule object audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all?
('dbus,' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus,' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)),
('dbus ( ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus ( ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)),
@ -93,7 +93,7 @@ class DbusTestParse(DbusTest):
('dbus bus=system path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified twice, last one wins ('dbus bus=system path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified twice, last one wins
('dbus send peer=(label="foo") bus=session,' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, 'foo', False)), ('dbus send peer=(label="foo") bus=session,' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, 'foo', False)),
('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6,' , exp(False, False, False, '', None , True , '6', False, None, True, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified multiple times, last one wins ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6,' , exp(False, False, False, '', None , True , '6', False, None, True, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified multiple times, last one wins
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(DbusRule.match(rawrule)) self.assertTrue(DbusRule.match(rawrule))
@ -102,7 +102,7 @@ class DbusTestParse(DbusTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class DbusTestParseInvalid(DbusTest): class DbusTestParseInvalid(DbusTest):
tests = [ tests = (
('dbus foo,' , AppArmorException), ('dbus foo,' , AppArmorException),
('dbus foo bar,' , AppArmorException), ('dbus foo bar,' , AppArmorException),
('dbus foo int,' , AppArmorException), ('dbus foo int,' , AppArmorException),
@ -114,7 +114,7 @@ class DbusTestParseInvalid(DbusTest):
('dbus peer=,' , AppArmorException), ('dbus peer=,' , AppArmorException),
('dbus bus=session bind bus=system,', AppArmorException), ('dbus bus=session bind bus=system,', AppArmorException),
('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6 bus=7,', AppArmorException), ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6 bus=7,', AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(DbusRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(DbusRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -170,7 +170,7 @@ class DbusTestParseFromLog(DbusTest):
# self.assertEqual(obj.get_raw(1), ' dbus send bus=system path=/org/freedesktop/DBus name=org.freedesktop.DBus member=Hello peer=(name=unconfined),') # self.assertEqual(obj.get_raw(1), ' dbus send bus=system path=/org/freedesktop/DBus name=org.freedesktop.DBus member=Hello peer=(name=unconfined),')
class DbusFromInit(DbusTest): class DbusFromInit(DbusTest):
tests = [ tests = (
#DbusRule# access bus path name interface member peername peerlabel audit=, deny=, allow_keyword, comment=, log_event) #DbusRule# access bus path name interface member peername peerlabel audit=, deny=, allow_keyword, comment=, log_event)
(DbusRule( 'send' , 'session', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL), (DbusRule( 'send' , 'session', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL),
#exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? #exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all?
@ -185,13 +185,13 @@ class DbusFromInit(DbusTest):
(DbusRule(DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label'), (DbusRule(DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label'),
#exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? #exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all?
exp( False, False, False, '', None , True , None, True, None, True, None, True, '/int/face',False, '/mem/ber', False, '/peer/name', False, '/peer/label', False)), exp( False, False, False, '', None , True , None, True, None, True, None, True, '/int/face',False, '/mem/ber', False, '/peer/name', False, '/peer/label', False)),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidDbusInit(AATest): class InvalidDbusInit(AATest):
tests = [ tests = (
# access bus path name interface member peername peerlabel expected exception # access bus path name interface member peername peerlabel expected exception
# empty fields # empty fields
@ -260,11 +260,11 @@ class InvalidDbusInit(AATest):
( (DbusRule.ALL, DbusRule.ALL, 'foo/bar', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # path doesn't start with / ( (DbusRule.ALL, DbusRule.ALL, 'foo/bar', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # path doesn't start with /
( (('foo'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # invalid access keyword ( (('foo'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # invalid access keyword
( (('foo', 'send'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # valid + invalid access keyword ( (('foo', 'send'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # valid + invalid access keyword
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
DbusRule(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]) DbusRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -377,7 +377,7 @@ class WriteDbusTest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' dbus , # foo ' , 'dbus, # foo'), (' dbus , # foo ' , 'dbus, # foo'),
(' audit dbus send,' , 'audit dbus send,'), (' audit dbus send,' , 'audit dbus send,'),
@ -403,7 +403,7 @@ class WriteDbusTest(AATest):
('dbus (send receive) peer=(name=/usr/bin/bar),' , 'dbus (receive send) peer=(name=/usr/bin/bar),'), ('dbus (send receive) peer=(name=/usr/bin/bar),' , 'dbus (receive send) peer=(name=/usr/bin/bar),'),
('dbus (, receive ,,, send ,) interface=/sbin/baz,' , 'dbus (receive send) interface=/sbin/baz,'), # XXX leading and trailing ',' inside (...) causes error ('dbus (, receive ,,, send ,) interface=/sbin/baz,' , 'dbus (receive send) interface=/sbin/baz,'), # XXX leading and trailing ',' inside (...) causes error
# XXX add more complex rules # XXX add more complex rules
] )
def test_write_manually_1(self): def test_write_manually_1(self):
# access bus path name interface member peername peerlabel expected exception # access bus path name interface member peername peerlabel expected exception
@ -440,251 +440,251 @@ class DbusCoveredTest(AATest):
class DbusCoveredTest_01(DbusCoveredTest): class DbusCoveredTest_01(DbusCoveredTest):
rule = 'dbus send,' rule = 'dbus send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ True , True , True , True ]), ('dbus send,' , ( True , True , True , True )),
('dbus send member=unconfined,' , [ False , False , True , True ]), ('dbus send member=unconfined,' , ( False , False , True , True )),
('dbus send, # comment' , [ True , False , True , True ]), ('dbus send, # comment' , ( True , False , True , True )),
('allow dbus send,' , [ True , False , True , True ]), ('allow dbus send,' , ( True , False , True , True )),
('dbus send,' , [ True , False , True , True ]), ('dbus send,' , ( True , False , True , True )),
('dbus send bus=session,' , [ False , False , True , True ]), ('dbus send bus=session,' , ( False , False , True , True )),
('dbus send member=(label=foo),' , [ False , False , True , True ]), ('dbus send member=(label=foo),' , ( False , False , True , True )),
('audit dbus send,' , [ False , False , False , False ]), ('audit dbus send,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus member=(label=foo),' , [ False , False , False , False ]), ('dbus member=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_02(DbusCoveredTest): class DbusCoveredTest_02(DbusCoveredTest):
rule = 'audit dbus send,' rule = 'audit dbus send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'dbus send,' , [ False , False , True , False ]), ( 'dbus send,' , ( False , False , True , False )),
('audit dbus send,' , [ True , True , True , True ]), ('audit dbus send,' , ( True , True , True , True )),
( 'dbus send bus=session,' , [ False , False , True , False ]), ( 'dbus send bus=session,' , ( False , False , True , False )),
('audit dbus send bus=session,' , [ False , False , True , True ]), ('audit dbus send bus=session,' , ( False , False , True , True )),
( 'dbus,' , [ False , False , False , False ]), ( 'dbus,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
] )
class DbusCoveredTest_03(DbusCoveredTest): class DbusCoveredTest_03(DbusCoveredTest):
rule = 'dbus send bus=session,' rule = 'dbus send bus=session,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'dbus send bus=session,' , [ True , True , True , True ]), ( 'dbus send bus=session,' , ( True , True , True , True )),
('allow dbus send bus=session,' , [ True , False , True , True ]), ('allow dbus send bus=session,' , ( True , False , True , True )),
( 'dbus send,' , [ False , False , False , False ]), ( 'dbus send,' , ( False , False , False , False )),
( 'dbus,' , [ False , False , False , False ]), ( 'dbus,' , ( False , False , False , False )),
( 'dbus send member=(label=foo),' , [ False , False , False , False ]), ( 'dbus send member=(label=foo),' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('audit dbus send bus=session,' , [ False , False , False , False ]), ('audit dbus send bus=session,' , ( False , False , False , False )),
('audit dbus bus=session,' , [ False , False , False , False ]), ('audit dbus bus=session,' , ( False , False , False , False )),
( 'dbus send,' , [ False , False , False , False ]), ( 'dbus send,' , ( False , False , False , False )),
( 'dbus,' , [ False , False , False , False ]), ( 'dbus,' , ( False , False , False , False )),
] )
class DbusCoveredTest_04(DbusCoveredTest): class DbusCoveredTest_04(DbusCoveredTest):
rule = 'dbus,' rule = 'dbus,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'dbus,' , [ True , True , True , True ]), ( 'dbus,' , ( True , True , True , True )),
('allow dbus,' , [ True , False , True , True ]), ('allow dbus,' , ( True , False , True , True )),
( 'dbus send,' , [ False , False , True , True ]), ( 'dbus send,' , ( False , False , True , True )),
( 'dbus receive bus=session,' , [ False , False , True , True ]), ( 'dbus receive bus=session,' , ( False , False , True , True )),
( 'dbus member=(label=foo),' , [ False , False , True , True ]), ( 'dbus member=(label=foo),' , ( False , False , True , True )),
( 'dbus send bus=session,' , [ False , False , True , True ]), ( 'dbus send bus=session,' , ( False , False , True , True )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('deny dbus,' , [ False , False , False , False ]), ('deny dbus,' , ( False , False , False , False )),
] )
class DbusCoveredTest_05(DbusCoveredTest): class DbusCoveredTest_05(DbusCoveredTest):
rule = 'deny dbus send,' rule = 'deny dbus send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny dbus send,' , [ True , True , True , True ]), ( 'deny dbus send,' , ( True , True , True , True )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
( 'dbus send,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'dbus send,' , ( False , False , False , False )), # XXX should covered be true here?
( 'deny dbus receive,' , [ False , False , False , False ]), ( 'deny dbus receive,' , ( False , False , False , False )),
( 'deny dbus,' , [ False , False , False , False ]), ( 'deny dbus,' , ( False , False , False , False )),
] )
class DbusCoveredTest_06(DbusCoveredTest): class DbusCoveredTest_06(DbusCoveredTest):
rule = 'dbus send peer=(name=unconfined),' rule = 'dbus send peer=(name=unconfined),'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send peer=(name=unconfined),' , [ True , True , True , True ]), ('dbus send peer=(name=unconfined),' , ( True , True , True , True )),
('dbus peer=(name=unconfined),' , [ False , False , False , False ]), ('dbus peer=(name=unconfined),' , ( False , False , False , False )),
('dbus send, # comment' , [ False , False , False , False ]), ('dbus send, # comment' , ( False , False , False , False )),
('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send,' , ( False , False , False , False )),
('allow dbus send peer=(name=unconfined),' , [ True , False , True , True ]), ('allow dbus send peer=(name=unconfined),' , ( True , False , True , True )),
('allow dbus send peer=(name=/foo/bar),' , [ False , False , False , False ]), ('allow dbus send peer=(name=/foo/bar),' , ( False , False , False , False )),
('allow dbus send peer=(name=/**),' , [ False , False , False , False ]), ('allow dbus send peer=(name=/**),' , ( False , False , False , False )),
('allow dbus send peer=(name=**),' , [ False , False , False , False ]), ('allow dbus send peer=(name=**),' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send peer=(name=unconfined),' , [ True , False , True , True ]), ('dbus send peer=(name=unconfined),' , ( True , False , True , True )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send peer=(name=unconfined label=foo),' , [ False , False , True , True ]), ('dbus send peer=(name=unconfined label=foo),' , ( False , False , True , True )),
('audit dbus send peer=(name=unconfined),' , [ False , False , False , False ]), ('audit dbus send peer=(name=unconfined),' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus peer=(label=foo),' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_07(DbusCoveredTest): class DbusCoveredTest_07(DbusCoveredTest):
rule = 'dbus send peer=(label=unconfined),' rule = 'dbus send peer=(label=unconfined),'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send peer=(label=unconfined),' , [ True , True , True , True ]), ('dbus send peer=(label=unconfined),' , ( True , True , True , True )),
('dbus peer=(label=unconfined),' , [ False , False , False , False ]), ('dbus peer=(label=unconfined),' , ( False , False , False , False )),
('dbus send, # comment' , [ False , False , False , False ]), ('dbus send, # comment' , ( False , False , False , False )),
('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send,' , ( False , False , False , False )),
('allow dbus send peer=(label=unconfined),' , [ True , False , True , True ]), ('allow dbus send peer=(label=unconfined),' , ( True , False , True , True )),
('allow dbus send peer=(label=/foo/bar),' , [ False , False , False , False ]), ('allow dbus send peer=(label=/foo/bar),' , ( False , False , False , False )),
('allow dbus send peer=(label=/**),' , [ False , False , False , False ]), ('allow dbus send peer=(label=/**),' , ( False , False , False , False )),
('allow dbus send peer=(label=**),' , [ False , False , False , False ]), ('allow dbus send peer=(label=**),' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send peer=(label=unconfined),' , [ True , False , True , True ]), ('dbus send peer=(label=unconfined),' , ( True , False , True , True )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send peer=(label=unconfined name=foo),' , [ False , False , True , True ]), ('dbus send peer=(label=unconfined name=foo),' , ( False , False , True , True )),
('audit dbus send peer=(label=unconfined),' , [ False , False , False , False ]), ('audit dbus send peer=(label=unconfined),' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus peer=(label=foo),' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_08(DbusCoveredTest): class DbusCoveredTest_08(DbusCoveredTest):
rule = 'dbus send path=/foo/bar,' rule = 'dbus send path=/foo/bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send path=/foo/bar,' , [ True , True , True , True ]), ('dbus send path=/foo/bar,' , ( True , True , True , True )),
('dbus send path=/foo/*,' , [ False , False , False , False ]), ('dbus send path=/foo/*,' , ( False , False , False , False )),
('dbus send path=/**,' , [ False , False , False , False ]), ('dbus send path=/**,' , ( False , False , False , False )),
('dbus send path=/what/*,' , [ False , False , False , False ]), ('dbus send path=/what/*,' , ( False , False , False , False )),
('dbus path=/foo/bar,' , [ False , False , False , False ]), ('dbus path=/foo/bar,' , ( False , False , False , False )),
('dbus send, # comment' , [ False , False , False , False ]), ('dbus send, # comment' , ( False , False , False , False )),
('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send,' , ( False , False , False , False )),
('allow dbus send path=/foo/bar,' , [ True , False , True , True ]), ('allow dbus send path=/foo/bar,' , ( True , False , True , True )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send path=/foo/bar,' , [ True , False , True , True ]), ('dbus send path=/foo/bar,' , ( True , False , True , True )),
('dbus send path=/what/ever,' , [ False , False , False , False ]), ('dbus send path=/what/ever,' , ( False , False , False , False )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send path=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('dbus send path=/foo/bar peer=(label=foo),' , ( False , False , True , True )),
('audit dbus send path=/foo/bar,' , [ False , False , False , False ]), ('audit dbus send path=/foo/bar,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus peer=(label=foo),' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_09(DbusCoveredTest): class DbusCoveredTest_09(DbusCoveredTest):
rule = 'dbus send member=**,' rule = 'dbus send member=**,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send member=/foo/bar,' , [ False , False , True , True ]), ('dbus send member=/foo/bar,' , ( False , False , True , True )),
('dbus send member=/foo/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('dbus send member=/foo/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('dbus send member=/**,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('dbus send member=/**,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('dbus send member=/what/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('dbus send member=/what/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('dbus member=/foo/bar,' , [ False , False , False , False ]), ('dbus member=/foo/bar,' , ( False , False , False , False )),
('dbus send, # comment' , [ False , False , False , False ]), ('dbus send, # comment' , ( False , False , False , False )),
('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send,' , ( False , False , False , False )),
('allow dbus send member=/foo/bar,' , [ False , False , True , True ]), ('allow dbus send member=/foo/bar,' , ( False , False , True , True )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send member=/foo/bar,' , [ False , False , True , True ]), ('dbus send member=/foo/bar,' , ( False , False , True , True )),
('dbus send member=/what/ever,' , [ False , False , True , True ]), ('dbus send member=/what/ever,' , ( False , False , True , True )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send member=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('dbus send member=/foo/bar peer=(label=foo),' , ( False , False , True , True )),
('audit dbus send member=/foo/bar,' , [ False , False , False , False ]), ('audit dbus send member=/foo/bar,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus member=(label=foo),' , [ False , False , False , False ]), ('dbus member=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_10(DbusCoveredTest): class DbusCoveredTest_10(DbusCoveredTest):
rule = 'dbus (send, receive) interface=foo,' rule = 'dbus (send, receive) interface=foo,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send interface=foo,' , [ False , False , True , True ]), ('dbus send interface=foo,' , ( False , False , True , True )),
('dbus receive bus=session interface=foo,' , [ False , False , True , True ]), ('dbus receive bus=session interface=foo,' , ( False , False , True , True )),
('dbus (receive,send) interface=foo,' , [ True , False , True , True ]), ('dbus (receive,send) interface=foo,' , ( True , False , True , True )),
('dbus (receive,send),' , [ False , False , False , False ]), ('dbus (receive,send),' , ( False , False , False , False )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send member=/foo/bar,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , ( False , False , False , False )),
('dbus send member=/foo/*,' , [ False , False , False , False ]), ('dbus send member=/foo/*,' , ( False , False , False , False )),
('dbus send member=/**,' , [ False , False , False , False ]), ('dbus send member=/**,' , ( False , False , False , False )),
('dbus send member=/what/*,' , [ False , False , False , False ]), ('dbus send member=/what/*,' , ( False , False , False , False )),
('dbus member=/foo/bar,' , [ False , False , False , False ]), ('dbus member=/foo/bar,' , ( False , False , False , False )),
('dbus send, # comment' , [ False , False , False , False ]), ('dbus send, # comment' , ( False , False , False , False )),
('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send,' , ( False , False , False , False )),
('allow dbus send member=/foo/bar,' , [ False , False , False , False ]), ('allow dbus send member=/foo/bar,' , ( False , False , False , False )),
('dbus send,' , [ False , False , False , False ]), ('dbus send,' , ( False , False , False , False )),
('dbus send member=/foo/bar,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , ( False , False , False , False )),
('dbus send member=/what/ever,' , [ False , False , False , False ]), ('dbus send member=/what/ever,' , ( False , False , False , False )),
('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session,' , ( False , False , False , False )),
('dbus send bus=session interface=foo,' , [ False , False , True , True ]), ('dbus send bus=session interface=foo,' , ( False , False , True , True )),
('dbus send member=/foo/bar peer=(label=foo),' , [ False , False , False , False ]), ('dbus send member=/foo/bar peer=(label=foo),' , ( False , False , False , False )),
('audit dbus send member=/foo/bar,' , [ False , False , False , False ]), ('audit dbus send member=/foo/bar,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus peer=(label=foo),' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , ( False , False , False , False )),
('audit deny dbus send,' , [ False , False , False , False ]), ('audit deny dbus send,' , ( False , False , False , False )),
('deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , ( False , False , False , False )),
] )
class DbusCoveredTest_11(DbusCoveredTest): class DbusCoveredTest_11(DbusCoveredTest):
rule = 'dbus name=/foo/bar,' rule = 'dbus name=/foo/bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('dbus,' , [ False , False , False , False ]), ('dbus,' , ( False , False , False , False )),
('dbus name=/foo/bar,' , [ True , True , True , True ]), ('dbus name=/foo/bar,' , ( True , True , True , True )),
('dbus name=/foo/*,' , [ False , False , False , False ]), ('dbus name=/foo/*,' , ( False , False , False , False )),
('dbus name=/**,' , [ False , False , False , False ]), ('dbus name=/**,' , ( False , False , False , False )),
('dbus name=/what/*,' , [ False , False , False , False ]), ('dbus name=/what/*,' , ( False , False , False , False )),
('dbus, # comment' , [ False , False , False , False ]), ('dbus, # comment' , ( False , False , False , False )),
('allow dbus,' , [ False , False , False , False ]), ('allow dbus,' , ( False , False , False , False )),
('allow dbus name=/foo/bar,' , [ True , False , True , True ]), ('allow dbus name=/foo/bar,' , ( True , False , True , True )),
('dbus ,' , [ False , False , False , False ]), ('dbus ,' , ( False , False , False , False )),
('dbus name=/foo/bar,' , [ True , False , True , True ]), ('dbus name=/foo/bar,' , ( True , False , True , True )),
('dbus name=/what/ever,' , [ False , False , False , False ]), ('dbus name=/what/ever,' , ( False , False , False , False )),
('dbus bus=session,' , [ False , False , False , False ]), ('dbus bus=session,' , ( False , False , False , False )),
('dbus name=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('dbus name=/foo/bar peer=(label=foo),' , ( False , False , True , True )),
('audit dbus name=/foo/bar,' , [ False , False , False , False ]), ('audit dbus name=/foo/bar,' , ( False , False , False , False )),
('audit dbus,' , [ False , False , False , False ]), ('audit dbus,' , ( False , False , False , False )),
('dbus receive,' , [ False , False , False , False ]), ('dbus receive,' , ( False , False , False , False )),
('dbus peer=(label=foo),' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , ( False , False , False , False )),
('audit deny dbus,' , [ False , False , False , False ]), ('audit deny dbus,' , ( False , False , False , False )),
('deny dbus,' , [ False , False , False , False ]), ('deny dbus,' , ( False , False , False , False )),
] )
@ -764,7 +764,7 @@ class DbusCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class DbusLogprofHeaderTest(AATest): class DbusLogprofHeaderTest(AATest):
tests = [ tests = (
('dbus,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]),
('dbus (send receive),', [ _('Access mode'), 'receive send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus (send receive),', [ _('Access mode'), 'receive send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]),
('dbus send bus=session,', [ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus send bus=session,', [ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]),
@ -776,7 +776,7 @@ class DbusLogprofHeaderTest(AATest):
('dbus send bus=session path=/path interface=aa.test member=ExMbr peer=(name=(peer.name)),', ('dbus send bus=session path=/path interface=aa.test member=ExMbr peer=(name=(peer.name)),',
[ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), '/path', _('Name'), _('ALL'), _('Interface'), 'aa.test', _('Member'), 'ExMbr', _('Peer name'), 'peer.name',_('Peer label'), _('ALL')]), [ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), '/path', _('Name'), _('ALL'), _('Interface'), 'aa.test', _('Member'), 'ExMbr', _('Peer name'), 'peer.name',_('Peer label'), _('ALL')]),
('dbus send peer=(label=foo),', [ _('Access mode'), 'send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), 'foo' ]), ('dbus send peer=(label=foo),', [ _('Access mode'), 'send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), 'foo' ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = DbusRule.parse(params) obj = DbusRule.parse(params)

View file

@ -14,20 +14,20 @@ from common_test import AATest, setup_all_loops # , setup_aa
# import apparmor.aa as aa # see the setup_aa() call for details # import apparmor.aa as aa # see the setup_aa() call for details
class TestFoo(AATest): class TestFoo(AATest):
tests = [ tests = (
(0, 0 ), (0, 0 ),
(42, 42), (42, 42),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(params, expected) self.assertEqual(params, expected)
class TestBar(AATest): class TestBar(AATest):
tests = [ tests = (
('a', 'foo'), ('a', 'foo'),
('b', 'bar'), ('b', 'bar'),
('c', 'baz'), ('c', 'baz'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertNotEqual(params, expected) self.assertNotEqual(params, expected)

View file

@ -25,8 +25,8 @@ from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'path', 'all_paths', 'perms', 'all_perms', 'exec_perms', 'target', 'all_targets', 'owner', 'file_keyword', 'leading_perms']) 'path', 'all_paths', 'perms', 'all_perms', 'exec_perms', 'target', 'all_targets', 'owner', 'file_keyword', 'leading_perms'))
# --- tests for single FileRule --- # # --- tests for single FileRule --- #
@ -57,7 +57,7 @@ class FileTest(AATest):
self.assertEqual(obj, expected) self.assertEqual(obj, expected)
class FileTestParse(FileTest): class FileTestParse(FileTest):
tests = [ tests = (
# FileRule object audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms # FileRule object audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms
# bare file rules # bare file rules
@ -96,7 +96,7 @@ class FileTestParse(FileTest):
# link rules # link rules
('link /foo -> /bar,' , exp(False, False, False, '', '/foo', False, {'link'}, False, None, '/bar', False, False, False, True )), ('link /foo -> /bar,' , exp(False, False, False, '', '/foo', False, {'link'}, False, None, '/bar', False, False, False, True )),
('link subset /foo -> /bar,' , exp(False, False, False, '', '/foo', False, {'link', 'subset'}, False, None, '/bar', False, False, False, True )), ('link subset /foo -> /bar,' , exp(False, False, False, '', '/foo', False, {'link', 'subset'}, False, None, '/bar', False, False, False, True )),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(FileRule.match(rawrule)) self.assertTrue(FileRule.match(rawrule))
@ -105,7 +105,7 @@ class FileTestParse(FileTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class FileTestParseInvalid(FileTest): class FileTestParseInvalid(FileTest):
tests = [ tests = (
('/foo x,' , AppArmorException), # should be *x ('/foo x,' , AppArmorException), # should be *x
('/foo raw,' , AppArmorException), # r and a conflict ('/foo raw,' , AppArmorException), # r and a conflict
('deny /foo ix,' , AppArmorException), # endy only allows x, but not *x ('deny /foo ix,' , AppArmorException), # endy only allows x, but not *x
@ -117,7 +117,7 @@ class FileTestParseInvalid(FileTest):
('/foo PxUx,' , AppArmorException), # exec mode conflict ('/foo PxUx,' , AppArmorException), # exec mode conflict
('/foo PUxPix,' , AppArmorException), # exec mode conflict ('/foo PUxPix,' , AppArmorException), # exec mode conflict
('/foo Pi,' , AppArmorException), # missing 'x' ('/foo Pi,' , AppArmorException), # missing 'x'
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(FileRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(FileRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -125,7 +125,7 @@ class FileTestParseInvalid(FileTest):
FileRule.parse(rawrule) FileRule.parse(rawrule)
class FileTestNonMatch(AATest): class FileTestNonMatch(AATest):
tests = [ tests = (
('file /foo,' , False ), ('file /foo,' , False ),
('file rw,' , False ), ('file rw,' , False ),
('file -> bar,' , False ), ('file -> bar,' , False ),
@ -136,7 +136,7 @@ class FileTestNonMatch(AATest):
('link -> /bar,' , False ), # missing path ('link -> /bar,' , False ), # missing path
('/foo -> bar link,', False ), # link has to be leading keyword ('/foo -> bar link,', False ), # link has to be leading keyword
('link,' , False ), # link isn't available as bare keyword ('link,' , False ), # link isn't available as bare keyword
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertFalse(FileRule.match(rawrule)) self.assertFalse(FileRule.match(rawrule))
@ -187,7 +187,7 @@ class FileTestParseFromLog(FileTest):
# TODO: add logparser example for link event # TODO: add logparser example for link event
class FileFromInit(FileTest): class FileFromInit(FileTest):
tests = [ tests = (
#FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms
(FileRule( '/foo', 'rw', None, FileRule.ALL, False, False, False, audit=True, deny=True ), (FileRule( '/foo', 'rw', None, FileRule.ALL, False, False, False, audit=True, deny=True ),
@ -204,13 +204,13 @@ class FileFromInit(FileTest):
#exp# audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms #exp# audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms
exp( True, False, True, '', '/foo', False, {'link', 'subset'}, False, None, '/bar', False, False, False, True )), exp( True, False, True, '', '/foo', False, {'link', 'subset'}, False, None, '/bar', False, False, False, True )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidFileInit(AATest): class InvalidFileInit(AATest):
tests = [ tests = (
#FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms
# empty fields # empty fields
@ -263,11 +263,11 @@ class InvalidFileInit(AATest):
( ( '/foo', {'subset'}, None, '/bar', False, False, False, ), AppArmorBug), # subset without link ( ( '/foo', {'subset'}, None, '/bar', False, False, False, ), AppArmorBug), # subset without link
( ( '/foo', {'link'}, 'ix', '/bar', False, False, False, ), AppArmorBug), # link rule with exec perms ( ( '/foo', {'link'}, 'ix', '/bar', False, False, False, ), AppArmorBug), # link rule with exec perms
( ( '/foo', {'link', 'subset'}, 'ix', '/bar', False, False, False, ), AppArmorBug), # link subset rule with exec perms ( ( '/foo', {'link', 'subset'}, 'ix', '/bar', False, False, False, ), AppArmorBug), # link subset rule with exec perms
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
FileRule(params[0], params[1], params[2], params[3], params[4], params[5], params[6]) FileRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -362,7 +362,7 @@ class FileGlobTest(AATest):
# These tests are meant to ensure AARE integration in FileRule works as expected. # These tests are meant to ensure AARE integration in FileRule works as expected.
# test-aare.py has more comprehensive globbing tests. # test-aare.py has more comprehensive globbing tests.
tests = [ tests = (
# rule can glob can glob_ext globbed rule globbed_ext rule # rule can glob can glob_ext globbed rule globbed_ext rule
('/foo/bar r,', (True, True, '/foo/* r,', '/foo/bar r,')), ('/foo/bar r,', (True, True, '/foo/* r,', '/foo/bar r,')),
('/foo/* r,', (True, True, '/** r,', '/foo/* r,')), ('/foo/* r,', (True, True, '/** r,', '/foo/* r,')),
@ -370,7 +370,7 @@ class FileGlobTest(AATest):
('/foo/*.xy r,', (True, True, '/foo/* r,', '/**.xy r,')), ('/foo/*.xy r,', (True, True, '/foo/* r,', '/**.xy r,')),
('file,', (False, False, 'file,', 'file,')), # bare 'file,' rules can't be globbed ('file,', (False, False, 'file,', 'file,')), # bare 'file,' rules can't be globbed
('link /a/b -> /c,', (True, True, 'link /a/* -> /c,', 'link /a/b -> /c,')), ('link /a/b -> /c,', (True, True, 'link /a/* -> /c,', 'link /a/b -> /c,')),
] )
class WriteFileTest(AATest): class WriteFileTest(AATest):
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
@ -382,7 +382,7 @@ class WriteFileTest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
('file,' , 'file,'), ('file,' , 'file,'),
(' file , # foo ' , 'file, # foo'), (' file , # foo ' , 'file, # foo'),
@ -417,7 +417,7 @@ class WriteFileTest(AATest):
(' link /foo -> /bar,' , 'link /foo -> /bar,'), (' link /foo -> /bar,' , 'link /foo -> /bar,'),
(' audit deny owner link subset /foo -> /bar,' , 'audit deny owner link subset /foo -> /bar,'), (' audit deny owner link subset /foo -> /bar,' , 'audit deny owner link subset /foo -> /bar,'),
(' link subset /foo -> /bar,' , 'link subset /foo -> /bar,') (' link subset /foo -> /bar,' , 'link subset /foo -> /bar,')
] )
def test_write_manually_1(self): def test_write_manually_1(self):
#FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms
@ -458,212 +458,212 @@ class FileCoveredTest(AATest):
class FileCoveredTest_01(FileCoveredTest): class FileCoveredTest_01(FileCoveredTest):
rule = 'file /foo r,' rule = 'file /foo r,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('file /foo r,' , [ True , True , True , True ]), ('file /foo r,' , ( True , True , True , True )),
('file /foo r ,' , [ True , False , True , True ]), ('file /foo r ,' , ( True , False , True , True )),
('allow file /foo r,' , [ True , False , True , True ]), ('allow file /foo r,' , ( True , False , True , True )),
('allow /foo r, # comment' , [ True , False , True , True ]), ('allow /foo r, # comment' , ( True , False , True , True )),
('allow owner /foo r,' , [ False , False , True , True ]), ('allow owner /foo r,' , ( False , False , True , True )),
('/foo r -> bar,' , [ False , False , True , True ]), ('/foo r -> bar,' , ( False , False , True , True )),
('file r /foo,' , [ True , False , True , True ]), ('file r /foo,' , ( True , False , True , True )),
('allow file r /foo,' , [ True , False , True , True ]), ('allow file r /foo,' , ( True , False , True , True )),
('allow r /foo, # comment' , [ True , False , True , True ]), ('allow r /foo, # comment' , ( True , False , True , True )),
('allow owner r /foo,' , [ False , False , True , True ]), ('allow owner r /foo,' , ( False , False , True , True )),
('r /foo -> bar,' , [ False , False , True , True ]), ('r /foo -> bar,' , ( False , False , True , True )),
('file,' , [ False , False , False , False ]), ('file,' , ( False , False , False , False )),
('file /foo w,' , [ False , False , False , False ]), ('file /foo w,' , ( False , False , False , False )),
('file /foo rw,' , [ False , False , False , False ]), ('file /foo rw,' , ( False , False , False , False )),
('file /bar r,' , [ False , False , False , False ]), ('file /bar r,' , ( False , False , False , False )),
('audit /foo r,' , [ False , False , False , False ]), ('audit /foo r,' , ( False , False , False , False )),
('audit file,' , [ False , False , False , False ]), ('audit file,' , ( False , False , False , False )),
('audit deny /foo r,' , [ False , False , False , False ]), ('audit deny /foo r,' , ( False , False , False , False )),
('deny file /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , ( False , False , False , False )),
('/foo rPx,' , [ False , False , False , False ]), ('/foo rPx,' , ( False , False , False , False )),
('/foo Pxr,' , [ False , False , False , False ]), ('/foo Pxr,' , ( False , False , False , False )),
('/foo Px,' , [ False , False , False , False ]), ('/foo Px,' , ( False , False , False , False )),
('/foo ix,' , [ False , False , False , False ]), ('/foo ix,' , ( False , False , False , False )),
('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo ix -> bar,' , ( False , False , False , False )),
('/foo rPx -> bar,' , [ False , False , False , False ]), ('/foo rPx -> bar,' , ( False , False , False , False )),
] )
class FileCoveredTest_02(FileCoveredTest): class FileCoveredTest_02(FileCoveredTest):
rule = 'audit /foo r,' rule = 'audit /foo r,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('file /foo r,' , [ False , False , True , False ]), ('file /foo r,' , ( False , False , True , False )),
('allow file /foo r,' , [ False , False , True , False ]), ('allow file /foo r,' , ( False , False , True , False )),
('allow /foo r, # comment' , [ False , False , True , False ]), ('allow /foo r, # comment' , ( False , False , True , False )),
('allow owner /foo r,' , [ False , False , True , False ]), ('allow owner /foo r,' , ( False , False , True , False )),
('/foo r -> bar,' , [ False , False , True , False ]), ('/foo r -> bar,' , ( False , False , True , False )),
('file r /foo,' , [ False , False , True , False ]), ('file r /foo,' , ( False , False , True , False )),
('allow file r /foo,' , [ False , False , True , False ]), ('allow file r /foo,' , ( False , False , True , False )),
('allow r /foo, # comment' , [ False , False , True , False ]), ('allow r /foo, # comment' , ( False , False , True , False )),
('allow owner r /foo,' , [ False , False , True , False ]), ('allow owner r /foo,' , ( False , False , True , False )),
('r /foo -> bar,' , [ False , False , True , False ]), # XXX exact ('r /foo -> bar,' , ( False , False , True , False )), # XXX exact
('file,' , [ False , False , False , False ]), ('file,' , ( False , False , False , False )),
('file /foo w,' , [ False , False , False , False ]), ('file /foo w,' , ( False , False , False , False )),
('file /foo rw,' , [ False , False , False , False ]), ('file /foo rw,' , ( False , False , False , False )),
('file /bar r,' , [ False , False , False , False ]), ('file /bar r,' , ( False , False , False , False )),
('audit /foo r,' , [ True , True , True , True ]), ('audit /foo r,' , ( True , True , True , True )),
('audit file,' , [ False , False , False , False ]), ('audit file,' , ( False , False , False , False )),
('audit deny /foo r,' , [ False , False , False , False ]), ('audit deny /foo r,' , ( False , False , False , False )),
('deny file /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , ( False , False , False , False )),
('/foo rPx,' , [ False , False , False , False ]), ('/foo rPx,' , ( False , False , False , False )),
('/foo Pxr,' , [ False , False , False , False ]), ('/foo Pxr,' , ( False , False , False , False )),
('/foo Px,' , [ False , False , False , False ]), ('/foo Px,' , ( False , False , False , False )),
('/foo ix,' , [ False , False , False , False ]), ('/foo ix,' , ( False , False , False , False )),
('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo ix -> bar,' , ( False , False , False , False )),
('/foo rPx -> bar,' , [ False , False , False , False ]), ('/foo rPx -> bar,' , ( False , False , False , False )),
] )
class FileCoveredTest_03(FileCoveredTest): class FileCoveredTest_03(FileCoveredTest):
rule = '/foo mrwPx,' rule = '/foo mrwPx,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('file /foo r,' , [ False , False , True , True ]), ('file /foo r,' , ( False , False , True , True )),
('allow file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , ( False , False , True , True )),
('allow /foo r, # comment' , [ False , False , True , True ]), ('allow /foo r, # comment' , ( False , False , True , True )),
('allow owner /foo r,' , [ False , False , True , True ]), ('allow owner /foo r,' , ( False , False , True , True )),
('/foo r -> bar,' , [ False , False , True , True ]), ('/foo r -> bar,' , ( False , False , True , True )),
('file r /foo,' , [ False , False , True , True ]), ('file r /foo,' , ( False , False , True , True )),
('allow file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , ( False , False , True , True )),
('allow r /foo, # comment' , [ False , False , True , True ]), ('allow r /foo, # comment' , ( False , False , True , True )),
('allow owner r /foo,' , [ False , False , True , True ]), ('allow owner r /foo,' , ( False , False , True , True )),
('r /foo -> bar,' , [ False , False , True , True ]), ('r /foo -> bar,' , ( False , False , True , True )),
('file,' , [ False , False , False , False ]), ('file,' , ( False , False , False , False )),
('file /foo w,' , [ False , False , True , True ]), ('file /foo w,' , ( False , False , True , True )),
('file /foo rw,' , [ False , False , True , True ]), ('file /foo rw,' , ( False , False , True , True )),
('file /bar r,' , [ False , False , False , False ]), ('file /bar r,' , ( False , False , False , False )),
('audit /foo r,' , [ False , False , False , False ]), ('audit /foo r,' , ( False , False , False , False )),
('audit file,' , [ False , False , False , False ]), ('audit file,' , ( False , False , False , False )),
('audit deny /foo r,' , [ False , False , False , False ]), ('audit deny /foo r,' , ( False , False , False , False )),
('deny file /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , ( False , False , False , False )),
('/foo mrwPx,' , [ True , True , True , True ]), ('/foo mrwPx,' , ( True , True , True , True )),
('/foo wPxrm,' , [ True , False , True , True ]), ('/foo wPxrm,' , ( True , False , True , True )),
('/foo rm,' , [ False , False , True , True ]), ('/foo rm,' , ( False , False , True , True )),
('/foo Px,' , [ False , False , True , True ]), ('/foo Px,' , ( False , False , True , True )),
('/foo ix,' , [ False , False , False , False ]), ('/foo ix,' , ( False , False , False , False )),
('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo ix -> bar,' , ( False , False , False , False )),
('/foo mrwPx -> bar,' , [ False , False , False , False ]), ('/foo mrwPx -> bar,' , ( False , False , False , False )),
] )
class FileCoveredTest_04(FileCoveredTest): class FileCoveredTest_04(FileCoveredTest):
rule = '/foo mrwPx -> bar,' rule = '/foo mrwPx -> bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('file /foo r,' , [ False , False , True , True ]), ('file /foo r,' , ( False , False , True , True )),
('allow file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , ( False , False , True , True )),
('allow /foo r, # comment' , [ False , False , True , True ]), ('allow /foo r, # comment' , ( False , False , True , True )),
('allow owner /foo r,' , [ False , False , True , True ]), ('allow owner /foo r,' , ( False , False , True , True )),
('/foo r -> bar,' , [ False , False , True , True ]), ('/foo r -> bar,' , ( False , False , True , True )),
('file r /foo,' , [ False , False , True , True ]), ('file r /foo,' , ( False , False , True , True )),
('allow file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , ( False , False , True , True )),
('allow r /foo, # comment' , [ False , False , True , True ]), ('allow r /foo, # comment' , ( False , False , True , True )),
('allow owner r /foo,' , [ False , False , True , True ]), ('allow owner r /foo,' , ( False , False , True , True )),
('r /foo -> bar,' , [ False , False , True , True ]), ('r /foo -> bar,' , ( False , False , True , True )),
('file,' , [ False , False , False , False ]), ('file,' , ( False , False , False , False )),
('file /foo w,' , [ False , False , True , True ]), ('file /foo w,' , ( False , False , True , True )),
('file /foo rw,' , [ False , False , True , True ]), ('file /foo rw,' , ( False , False , True , True )),
('file /bar r,' , [ False , False , False , False ]), ('file /bar r,' , ( False , False , False , False )),
('audit /foo r,' , [ False , False , False , False ]), ('audit /foo r,' , ( False , False , False , False )),
('audit file,' , [ False , False , False , False ]), ('audit file,' , ( False , False , False , False )),
('audit deny /foo r,' , [ False , False , False , False ]), ('audit deny /foo r,' , ( False , False , False , False )),
('deny file /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , ( False , False , False , False )),
('/foo mrwPx,' , [ False , False , False , False ]), ('/foo mrwPx,' , ( False , False , False , False )),
('/foo wPxrm,' , [ False , False , False , False ]), ('/foo wPxrm,' , ( False , False , False , False )),
('/foo rm,' , [ False , False , True , True ]), ('/foo rm,' , ( False , False , True , True )),
('/foo Px,' , [ False , False , False , False ]), ('/foo Px,' , ( False , False , False , False )),
('/foo ix,' , [ False , False , False , False ]), ('/foo ix,' , ( False , False , False , False )),
('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo ix -> bar,' , ( False , False , False , False )),
('/foo mrwPx -> bar,' , [ True , True , True , True ]), ('/foo mrwPx -> bar,' , ( True , True , True , True )),
] )
class FileCoveredTest_05(FileCoveredTest): class FileCoveredTest_05(FileCoveredTest):
rule = 'file,' rule = 'file,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('file /foo r,' , [ False , False , True , True ]), ('file /foo r,' , ( False , False , True , True )),
('allow file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , ( False , False , True , True )),
('allow /foo r, # comment' , [ False , False , True , True ]), ('allow /foo r, # comment' , ( False , False , True , True )),
('allow owner /foo r,' , [ False , False , True , True ]), ('allow owner /foo r,' , ( False , False , True , True )),
('/foo r -> bar,' , [ False , False , True , True ]), ('/foo r -> bar,' , ( False , False , True , True )),
('file r /foo,' , [ False , False , True , True ]), ('file r /foo,' , ( False , False , True , True )),
('allow file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , ( False , False , True , True )),
('allow r /foo, # comment' , [ False , False , True , True ]), ('allow r /foo, # comment' , ( False , False , True , True )),
('allow owner r /foo,' , [ False , False , True , True ]), ('allow owner r /foo,' , ( False , False , True , True )),
('r /foo -> bar,' , [ False , False , True , True ]), ('r /foo -> bar,' , ( False , False , True , True )),
('file,' , [ True , True , True , True ]), ('file,' , ( True , True , True , True )),
('file /foo w,' , [ False , False , True , True ]), ('file /foo w,' , ( False , False , True , True )),
('file /foo rw,' , [ False , False , True , True ]), ('file /foo rw,' , ( False , False , True , True )),
('file /bar r,' , [ False , False , True , True ]), ('file /bar r,' , ( False , False , True , True )),
('audit /foo r,' , [ False , False , False , False ]), ('audit /foo r,' , ( False , False , False , False )),
('audit file,' , [ False , False , False , False ]), ('audit file,' , ( False , False , False , False )),
('audit deny /foo r,' , [ False , False , False , False ]), ('audit deny /foo r,' , ( False , False , False , False )),
('deny file /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , ( False , False , False , False )),
('/foo mrwPx,' , [ False , False , False , False ]), ('/foo mrwPx,' , ( False , False , False , False )),
('/foo wPxrm,' , [ False , False , False , False ]), ('/foo wPxrm,' , ( False , False , False , False )),
('/foo rm,' , [ False , False , True , True ]), ('/foo rm,' , ( False , False , True , True )),
('/foo Px,' , [ False , False , False , False ]), ('/foo Px,' , ( False , False , False , False )),
('/foo ix,' , [ False , False , False , False ]), ('/foo ix,' , ( False , False , False , False )),
('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo ix -> bar,' , ( False , False , False , False )),
('/foo mrwPx -> bar,' , [ False , False , False , False ]), ('/foo mrwPx -> bar,' , ( False , False , False , False )),
] )
class FileCoveredTest_06(FileCoveredTest): class FileCoveredTest_06(FileCoveredTest):
rule = 'deny /foo w,' rule = 'deny /foo w,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('/foo w,' , [ False , False , False , False ]), ('/foo w,' , ( False , False , False , False )),
('/foo a,' , [ False , False , False , False ]), ('/foo a,' , ( False , False , False , False )),
('deny /foo w,' , [ True , True , True , True ]), ('deny /foo w,' , ( True , True , True , True )),
('deny /foo a,' , [ False , False , True , True ]), ('deny /foo a,' , ( False , False , True , True )),
] )
class FileCoveredTest_07(FileCoveredTest): class FileCoveredTest_07(FileCoveredTest):
rule = '/foo w,' rule = '/foo w,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('/foo w,' , [ True , True , True , True ]), ('/foo w,' , ( True , True , True , True )),
('/foo a,' , [ False , False , True , True ]), ('/foo a,' , ( False , False , True , True )),
('deny /foo w,' , [ False , False , False , False ]), ('deny /foo w,' , ( False , False , False , False )),
('deny /foo a,' , [ False , False , False , False ]), ('deny /foo a,' , ( False , False , False , False )),
] )
class FileCoveredTest_08(FileCoveredTest): class FileCoveredTest_08(FileCoveredTest):
rule = 'link /foo -> /bar,' rule = 'link /foo -> /bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('link /foo -> /bar,' , [ True , True , True , True ]), ('link /foo -> /bar,' , ( True , True , True , True )),
('link /asdf -> /bar,' , [ False , False , False , False ]), ('link /asdf -> /bar,' , ( False , False , False , False )),
('link /foo -> /asdf,' , [ False , False , False , False ]), ('link /foo -> /asdf,' , ( False , False , False , False )),
('deny link /foo -> /bar,' , [ False , False , False , False ]), ('deny link /foo -> /bar,' , ( False , False , False , False )),
('deny link /foo -> /bar,' , [ False , False , False , False ]), ('deny link /foo -> /bar,' , ( False , False , False , False )),
('link subset /foo -> /bar,' , [ False , False , True , True ]), # subset makes the rule more strict ('link subset /foo -> /bar,' , ( False , False , True , True )), # subset makes the rule more strict
# ('/foo l -> /bar,' , [ ? , ? , ? , ? ]), # TODO # ('/foo l -> /bar,' , ( ? , ? , ? , ? )), # TODO
# ('l /foo -> /bar,' , [ ? , ? , ? , ? ]), # TODO # ('l /foo -> /bar,' , ( ? , ? , ? , ? )), # TODO
] )
class FileCoveredTest_09(FileCoveredTest): class FileCoveredTest_09(FileCoveredTest):
rule = 'link subset /foo -> /bar,' rule = 'link subset /foo -> /bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('link subset /foo -> /bar,' , [ True , True , True , True ]), ('link subset /foo -> /bar,' , ( True , True , True , True )),
('link subset /asdf -> /bar,' , [ False , False , False , False ]), ('link subset /asdf -> /bar,' , ( False , False , False , False )),
('link subset /foo -> /asdf,' , [ False , False , False , False ]), ('link subset /foo -> /asdf,' , ( False , False , False , False )),
('deny link subset /foo -> /bar,' , [ False , False , False , False ]), ('deny link subset /foo -> /bar,' , ( False , False , False , False )),
('deny link subset /foo -> /bar,' , [ False , False , False , False ]), ('deny link subset /foo -> /bar,' , ( False , False , False , False )),
('link /foo -> /bar,' , [ False , False , False , False ]), # no subset means more permissions ('link /foo -> /bar,' , ( False , False , False , False )), # no subset means more permissions
# ('/foo l -> /bar,' , [ ? , ? , ? , ? ]), # TODO # ('/foo l -> /bar,' , ( ? , ? , ? , ? )), # TODO
# ('l /foo -> /bar,' , [ ? , ? , ? , ? ]), # TODO # ('l /foo -> /bar,' , ( ? , ? , ? , ? )), # TODO
] )
class FileCoveredTest_ManualOrInvalid(AATest): class FileCoveredTest_ManualOrInvalid(AATest):
def AASetup(self): def AASetup(self):
@ -782,7 +782,7 @@ class FileCoveredTest_ManualOrInvalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class FileSeverityTest(AATest): class FileSeverityTest(AATest):
tests = [ tests = (
('/usr/bin/whatis ix,', 5), ('/usr/bin/whatis ix,', 5),
('/etc ix,', 'unknown'), ('/etc ix,', 'unknown'),
('/dev/doublehit ix,', 0), ('/dev/doublehit ix,', 0),
@ -795,7 +795,7 @@ class FileSeverityTest(AATest):
('/usr/foo@bar r,', 'unknown'), # filename containing @ ('/usr/foo@bar r,', 'unknown'), # filename containing @
('/home/foo@bar rw,', 6), # filename containing @ ('/home/foo@bar rw,', 6), # filename containing @
('file,', 'unknown'), # bare file rule XXX should return maximum severity ('file,', 'unknown'), # bare file rule XXX should return maximum severity
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
sev_db = severity.Severity('../severity.db', 'unknown') sev_db = severity.Severity('../severity.db', 'unknown')
@ -804,24 +804,24 @@ class FileSeverityTest(AATest):
self.assertEqual(rank, expected) self.assertEqual(rank, expected)
class FileLogprofHeaderTest(AATest): class FileLogprofHeaderTest(AATest):
tests = [ tests = (
# log event old perms ALL / owner # log event old perms ALL / owner
(['file,', set(), set() ], [ _('Path'), _('ALL'), _('New Mode'), _('ALL') ]), (('file,', set(), set() ), [ _('Path'), _('ALL'), _('New Mode'), _('ALL') ]),
(['/foo r,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'r' ]), (('/foo r,', set(), set() ), [ _('Path'), '/foo', _('New Mode'), 'r' ]),
(['file /bar Px -> foo,', set(), set() ], [ _('Path'), '/bar', _('New Mode'), 'Px -> foo' ]), (('file /bar Px -> foo,', set(), set() ), [ _('Path'), '/bar', _('New Mode'), 'Px -> foo' ]),
(['deny file,', set(), set() ], [_('Qualifier'), 'deny', _('Path'), _('ALL'), _('New Mode'), _('ALL') ]), (('deny file,', set(), set() ), [_('Qualifier'), 'deny', _('Path'), _('ALL'), _('New Mode'), _('ALL') ]),
(['allow file /baz rwk,', set(), set() ], [_('Qualifier'), 'allow', _('Path'), '/baz', _('New Mode'), 'rwk' ]), (('allow file /baz rwk,', set(), set() ), [_('Qualifier'), 'allow', _('Path'), '/baz', _('New Mode'), 'rwk' ]),
(['audit file /foo mr,', set(), set() ], [_('Qualifier'), 'audit', _('Path'), '/foo', _('New Mode'), 'mr' ]), (('audit file /foo mr,', set(), set() ), [_('Qualifier'), 'audit', _('Path'), '/foo', _('New Mode'), 'mr' ]),
(['audit deny /foo wk,', set(), set() ], [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'wk' ]), (('audit deny /foo wk,', set(), set() ), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'wk' ]),
(['owner file /foo ix,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'owner ix' ]), (('owner file /foo ix,', set(), set() ), [ _('Path'), '/foo', _('New Mode'), 'owner ix' ]),
(['audit deny file /foo rlx -> /baz,', set(), set() ], [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'rlx -> /baz' ]), (('audit deny file /foo rlx -> /baz,', set(), set() ), [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'rlx -> /baz' ]),
(['/foo rw,', set('r'), set() ], [ _('Path'), '/foo', _('Old Mode'), _('r'), _('New Mode'), _('rw') ]), (('/foo rw,', set('r'), set() ), [ _('Path'), '/foo', _('Old Mode'), _('r'), _('New Mode'), _('rw') ]),
(['/foo rw,', set(), set('rw') ], [ _('Path'), '/foo', _('Old Mode'), _('owner rw'), _('New Mode'), _('rw') ]), (('/foo rw,', set(), set('rw') ), [ _('Path'), '/foo', _('Old Mode'), _('owner rw'), _('New Mode'), _('rw') ]),
(['/foo mrw,', set('r'), set('k') ], [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]), (('/foo mrw,', set('r'), set('k') ), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]),
(['/foo mrw,', set('r'), set('rk') ], [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]), (('/foo mrw,', set('r'), set('rk') ), [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]),
(['link /foo -> /bar,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'link -> /bar' ]), (('link /foo -> /bar,', set(), set() ), [ _('Path'), '/foo', _('New Mode'), 'link -> /bar' ]),
(['link subset /foo -> /bar,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'link subset -> /bar' ]), (('link subset /foo -> /bar,', set(), set() ), [ _('Path'), '/foo', _('New Mode'), 'link subset -> /bar' ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = FileRule.parse(params[0]) obj = FileRule.parse(params[0])
@ -841,11 +841,11 @@ class FileEditHeaderTest(AATest):
prompt, path_to_edit = rule_obj.edit_header() prompt, path_to_edit = rule_obj.edit_header()
self.assertEqual(path_to_edit, expected) self.assertEqual(path_to_edit, expected)
tests = [ tests = (
('/foo/bar/baz r,', '/foo/bar/baz'), ('/foo/bar/baz r,', '/foo/bar/baz'),
('/foo/**/baz r,', '/foo/**/baz'), ('/foo/**/baz r,', '/foo/**/baz'),
('link /foo/** -> /bar,', '/foo/**'), ('link /foo/** -> /bar,', '/foo/**'),
] )
def test_edit_header_bare_file(self): def test_edit_header_bare_file(self):
rule_obj = FileRule.parse('file,') rule_obj = FileRule.parse('file,')
@ -862,14 +862,14 @@ class FileValidateAndStoreEditTest(AATest):
rule_obj.store_edit(params) rule_obj.store_edit(params)
self.assertEqual(rule_obj.get_raw(), '%s r,' % params) self.assertEqual(rule_obj.get_raw(), '%s r,' % params)
tests = [ tests = (
# edited path match # edited path match
('/foo/bar/baz', True), ('/foo/bar/baz', True),
('/foo/bar/*', True), ('/foo/bar/*', True),
('/foo/bar/???', True), ('/foo/bar/???', True),
('/foo/xy**', False), ('/foo/xy**', False),
('/foo/bar/baz/', False), ('/foo/bar/baz/', False),
] )
def test_validate_not_a_path(self): def test_validate_not_a_path(self):
rule_obj = FileRule.parse('/foo/bar/baz r,') rule_obj = FileRule.parse('/foo/bar/baz r,')
@ -1008,7 +1008,7 @@ class FileRulesTest(AATest):
# pass # pass
class FileGetRulesForPath(AATest): class FileGetRulesForPath(AATest):
tests = [ tests = (
# path audit deny expected # path audit deny expected
(('/etc/foo/dovecot.conf', False, False), ['/etc/foo/* r,', '/etc/foo/dovecot.conf rw,', '']), (('/etc/foo/dovecot.conf', False, False), ['/etc/foo/* r,', '/etc/foo/dovecot.conf rw,', '']),
(('/etc/foo/foo.conf', False, False), ['/etc/foo/* r,', '']), (('/etc/foo/foo.conf', False, False), ['/etc/foo/* r,', '']),
@ -1019,10 +1019,10 @@ class FileGetRulesForPath(AATest):
(('/etc/foo/dovecot-deny.conf', False, True ), ['deny /etc/foo/dovecot-deny.conf r,', '']), (('/etc/foo/dovecot-deny.conf', False, True ), ['deny /etc/foo/dovecot-deny.conf r,', '']),
(('/etc/foo/foo.conf', False, True ), [ ]), (('/etc/foo/foo.conf', False, True ), [ ]),
(('/etc/foo/owner.conf', False, False), ['/etc/foo/* r,', 'owner /etc/foo/owner.conf w,', '']), (('/etc/foo/owner.conf', False, False), ['/etc/foo/* r,', 'owner /etc/foo/owner.conf w,', '']),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/etc/foo/* r,', '/etc/foo/* r,',
'/etc/foo/dovecot.conf rw,', '/etc/foo/dovecot.conf rw,',
'/etc/foo/{auth,conf}.d/*.conf r,', '/etc/foo/{auth,conf}.d/*.conf r,',
@ -1030,18 +1030,18 @@ class FileGetRulesForPath(AATest):
'/etc/foo/dovecot-database.conf.ext w,', '/etc/foo/dovecot-database.conf.ext w,',
'owner /etc/foo/owner.conf w,', 'owner /etc/foo/owner.conf w,',
'deny /etc/foo/dovecot-deny.conf r,', 'deny /etc/foo/dovecot-deny.conf r,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:
ruleset.add(FileRule.parse(rule)) ruleset.add(FileRule.parse(rule))
matching = ruleset.get_rules_for_path(params[0], params[1], params[2]) matching = ruleset.get_rules_for_path(*params)
self. assertEqual(matching.get_clean(), expected) self. assertEqual(matching.get_clean(), expected)
class FileGetPermsForPath_1(AATest): class FileGetPermsForPath_1(AATest):
tests = [ tests = (
# path audit deny expected # path audit deny expected
(('/etc/foo/dovecot.conf', False, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }), (('/etc/foo/dovecot.conf', False, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }),
(('/etc/foo/foo.conf', False, False), {'allow': {'all': {'r' }, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*' } }), (('/etc/foo/foo.conf', False, False), {'allow': {'all': {'r' }, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*' } }),
@ -1052,10 +1052,10 @@ class FileGetPermsForPath_1(AATest):
(('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': {'r' }, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }), (('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': {'r' }, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }),
(('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), (('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }),
(('/usr/lib/dovecot/config', False, False), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), # exec perms are not honored by get_perms_for_path() (('/usr/lib/dovecot/config', False, False), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), # exec perms are not honored by get_perms_for_path()
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/etc/foo/* r,', '/etc/foo/* r,',
'/etc/foo/dovecot.conf rw,', '/etc/foo/dovecot.conf rw,',
'/etc/foo/{auth,conf}.d/*.conf r,', '/etc/foo/{auth,conf}.d/*.conf r,',
@ -1063,17 +1063,17 @@ class FileGetPermsForPath_1(AATest):
'/etc/foo/dovecot-database.conf.ext w,', '/etc/foo/dovecot-database.conf.ext w,',
'deny /etc/foo/dovecot-deny.conf r,', 'deny /etc/foo/dovecot-deny.conf r,',
'/usr/lib/dovecot/config ix,', '/usr/lib/dovecot/config ix,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:
ruleset.add(FileRule.parse(rule)) ruleset.add(FileRule.parse(rule))
perms = ruleset.get_perms_for_path(params[0], params[1], params[2]) perms = ruleset.get_perms_for_path(*params)
self. assertEqual(perms, expected) self. assertEqual(perms, expected)
class FileGetPermsForPath_2(AATest): class FileGetPermsForPath_2(AATest):
tests = [ tests = (
# path audit deny expected # path audit deny expected
(('/etc/foo/dovecot.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }), (('/etc/foo/dovecot.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }),
(('/etc/foo/dovecot.conf', True, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/dovecot.conf' } }), (('/etc/foo/dovecot.conf', True, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/dovecot.conf' } }),
@ -1086,10 +1086,10 @@ class FileGetPermsForPath_2(AATest):
(('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }), (('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }),
(('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': set() }), (('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': set() }),
# (('/etc/foo/owner.conf', False, True ), {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/owner.conf' } }), # XXX doesn't work yet # (('/etc/foo/owner.conf', False, True ), {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/owner.conf' } }), # XXX doesn't work yet
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/etc/foo/* r,', '/etc/foo/* r,',
'audit /etc/foo/dovecot.conf rw,', 'audit /etc/foo/dovecot.conf rw,',
'/etc/foo/{auth,conf}.d/*.conf r,', '/etc/foo/{auth,conf}.d/*.conf r,',
@ -1099,29 +1099,29 @@ class FileGetPermsForPath_2(AATest):
'file,', 'file,',
'owner /etc/foo/owner.conf w,', 'owner /etc/foo/owner.conf w,',
'deny file,', 'deny file,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:
ruleset.add(FileRule.parse(rule)) ruleset.add(FileRule.parse(rule))
perms = ruleset.get_perms_for_path(params[0], params[1], params[2]) perms = ruleset.get_perms_for_path(*params)
self. assertEqual(perms, expected) self. assertEqual(perms, expected)
class FileGetExecRulesForPath_1(AATest): class FileGetExecRulesForPath_1(AATest):
tests = [ tests = (
('/bin/foo', ['audit /bin/foo ix,', ''] ), ('/bin/foo', ['audit /bin/foo ix,', ''] ),
('/bin/bar', ['deny /bin/bar x,', ''] ), ('/bin/bar', ['deny /bin/bar x,', ''] ),
('/foo', [] ), ('/foo', [] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/foo r,', '/foo r,',
'audit /bin/foo ix,', 'audit /bin/foo ix,',
'/bin/b* Px,', '/bin/b* Px,',
'deny /bin/bar x,', 'deny /bin/bar x,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:
@ -1132,19 +1132,19 @@ class FileGetExecRulesForPath_1(AATest):
self. assertEqual(matches, expected) self. assertEqual(matches, expected)
class FileGetExecRulesForPath_2(AATest): class FileGetExecRulesForPath_2(AATest):
tests = [ tests = (
('/bin/foo', ['audit /bin/foo ix,', ''] ), ('/bin/foo', ['audit /bin/foo ix,', ''] ),
('/bin/bar', ['deny /bin/bar x,', '', '/bin/b* Px,', ''] ), ('/bin/bar', ['deny /bin/bar x,', '', '/bin/b* Px,', ''] ),
('/foo', [] ), ('/foo', [] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/foo r,', '/foo r,',
'audit /bin/foo ix,', 'audit /bin/foo ix,',
'/bin/b* Px,', '/bin/b* Px,',
'deny /bin/bar x,', 'deny /bin/bar x,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:
@ -1155,22 +1155,22 @@ class FileGetExecRulesForPath_2(AATest):
self. assertEqual(matches, expected) self. assertEqual(matches, expected)
class FileGetExecConflictRules_1(AATest): class FileGetExecConflictRules_1(AATest):
tests = [ tests = (
('/bin/foo ix,', ['/bin/foo Px,', ''] ), ('/bin/foo ix,', ['/bin/foo Px,', ''] ),
('/bin/bar Px,', ['deny /bin/bar x,', '', '/bin/bar cx,', ''] ), ('/bin/bar Px,', ['deny /bin/bar x,', '', '/bin/bar cx,', ''] ),
('/bin/bar cx,', ['deny /bin/bar x,','',] ), ('/bin/bar cx,', ['deny /bin/bar x,','',] ),
('/bin/foo r,', [] ), ('/bin/foo r,', [] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
rules = [ rules = (
'/foo r,', '/foo r,',
'audit /bin/foo ix,', 'audit /bin/foo ix,',
'/bin/foo Px,', '/bin/foo Px,',
'/bin/b* Px,', '/bin/b* Px,',
'/bin/bar cx,', '/bin/bar cx,',
'deny /bin/bar x,', 'deny /bin/bar x,',
] )
ruleset = FileRuleset() ruleset = FileRuleset()
for rule in rules: for rule in rules:

View file

@ -27,9 +27,9 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', [ # 'audit', 'allow_keyword', 'deny', exp = namedtuple('exp', ( # 'audit', 'allow_keyword', 'deny',
'comment', 'comment',
'path', 'ifexists', 'ismagic']) 'path', 'ifexists', 'ismagic'))
# --- tests for single IncludeRule --- # # --- tests for single IncludeRule --- #
@ -45,7 +45,7 @@ class IncludeTest(AATest):
self.assertEqual(expected.ismagic, obj.ismagic) self.assertEqual(expected.ismagic, obj.ismagic)
class IncludeTestParse(IncludeTest): class IncludeTestParse(IncludeTest):
tests = [ tests = (
# IncludeRule object comment path if exists ismagic # IncludeRule object comment path if exists ismagic
# #include # #include
('#include <abstractions/base>', exp('', 'abstractions/base', False, True )), # magic path ('#include <abstractions/base>', exp('', 'abstractions/base', False, True )), # magic path
@ -83,7 +83,7 @@ class IncludeTestParse(IncludeTest):
('include if exists "/foo/bar" # comment', exp(' # comment', '/foo/bar', True, False)), ('include if exists "/foo/bar" # comment', exp(' # comment', '/foo/bar', True, False)),
('include if exists "/foo/bar"#comment', exp(' #comment', '/foo/bar', True, False)), ('include if exists "/foo/bar"#comment', exp(' #comment', '/foo/bar', True, False)),
(' include if exists "/foo/bar" ', exp('', '/foo/bar', True, False)), (' include if exists "/foo/bar" ', exp('', '/foo/bar', True, False)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(IncludeRule.match(rawrule)) self.assertTrue(IncludeRule.match(rawrule))
@ -92,12 +92,12 @@ class IncludeTestParse(IncludeTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class IncludeTestParseInvalid(IncludeTest): class IncludeTestParseInvalid(IncludeTest):
tests = [ tests = (
# (' some #include if exists <abstractions/base>', AppArmorException), # (' some #include if exists <abstractions/base>', AppArmorException),
# (' /etc/fstab r,', AppArmorException), # (' /etc/fstab r,', AppArmorException),
# ('/usr/include r,', AppArmorException), # ('/usr/include r,', AppArmorException),
# ('/include r,', AppArmorException), # ('/include r,', AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(IncludeRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(IncludeRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -107,34 +107,34 @@ class IncludeTestParseInvalid(IncludeTest):
# class IncludeTestParseFromLog(IncludeTest): # we'll never have log events for includes # class IncludeTestParseFromLog(IncludeTest): # we'll never have log events for includes
class IncludeFromInit(IncludeTest): class IncludeFromInit(IncludeTest):
tests = [ tests = (
# IncludeRule object ifexists ismagic comment path ifexists ismagic # IncludeRule object ifexists ismagic comment path ifexists ismagic
(IncludeRule('abstractions/base', False, False) , exp('', 'abstractions/base', False, False )), (IncludeRule('abstractions/base', False, False) , exp('', 'abstractions/base', False, False )),
(IncludeRule('foo', True, False) , exp('', 'foo', True, False )), (IncludeRule('foo', True, False) , exp('', 'foo', True, False )),
(IncludeRule('bar', False, True) , exp('', 'bar', False, True )), (IncludeRule('bar', False, True) , exp('', 'bar', False, True )),
(IncludeRule('baz', True, True) , exp('', 'baz', True, True )), (IncludeRule('baz', True, True) , exp('', 'baz', True, True )),
(IncludeRule('comment', False, False, comment='# cmt') , exp('# cmt', 'comment', False, False )), (IncludeRule('comment', False, False, comment='# cmt') , exp('# cmt', 'comment', False, False )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidIncludeInit(AATest): class InvalidIncludeInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([False, False, False ] , AppArmorBug), # wrong type for path ((False, False, False ) , AppArmorBug), # wrong type for path
(['', False, False ] , AppArmorBug), # empty path (('', False, False ) , AppArmorBug), # empty path
([None, False, False ] , AppArmorBug), # wrong type for path ((None, False, False ) , AppArmorBug), # wrong type for path
# ([' ', False, False ] , AppArmorBug), # whitespace-only path # ((' ', False, False ) , AppArmorBug), # whitespace-only path
(['foo', None, False ] , AppArmorBug), # wrong type for ifexists (('foo', None, False ) , AppArmorBug), # wrong type for ifexists
(['foo', '', False ] , AppArmorBug), # wrong type for ifexists (('foo', '', False ) , AppArmorBug), # wrong type for ifexists
(['foo', False, None ] , AppArmorBug), # wrong type for ismagic (('foo', False, None ) , AppArmorBug), # wrong type for ismagic
(['foo', False, '' ] , AppArmorBug), # wrong type for ismagic (('foo', False, '' ) , AppArmorBug), # wrong type for ismagic
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
IncludeRule(params[0], params[1], params[2]) IncludeRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -188,7 +188,7 @@ class WriteIncludeTestAATest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' include <foo> ', 'include <foo>' ), (' include <foo> ', 'include <foo>' ),
# (' include foo ', 'include "foo"' ), # several test cases disabled due to implementation restrictions, see re_match_include_parse() # (' include foo ', 'include "foo"' ), # several test cases disabled due to implementation restrictions, see re_match_include_parse()
@ -226,7 +226,7 @@ class WriteIncludeTestAATest(AATest):
# (' #include if exists "foo" ', 'include if exists "foo"' ), # (' #include if exists "foo" ', 'include if exists "foo"' ),
# (' #include if exists /foo ', 'include if exists "/foo"' ), # (' #include if exists /foo ', 'include if exists "/foo"' ),
(' #include if exists "/foo" ', 'include if exists "/foo"' ), (' #include if exists "/foo" ', 'include if exists "/foo"' ),
] )
def test_write_manually(self): def test_write_manually(self):
obj = IncludeRule('abs/foo', False, True, comment=' # cmt') obj = IncludeRule('abs/foo', False, True, comment=' # cmt')
@ -253,29 +253,29 @@ class IncludeCoveredTest(AATest):
class IncludeCoveredTest_01(IncludeCoveredTest): class IncludeCoveredTest_01(IncludeCoveredTest):
rule = 'include <foo>' rule = 'include <foo>'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('include <foo>' , [ True , True , True , True ]), ('include <foo>' , ( True , True , True , True )),
('#include <foo>' , [ True , False , True , True ]), ('#include <foo>' , ( True , False , True , True )),
('include if exists <foo>' , [ False , False , True , True ]), ('include if exists <foo>' , ( False , False , True , True )),
('#include if exists <foo>' , [ False , False , True , True ]), ('#include if exists <foo>' , ( False , False , True , True )),
('include <foobar>' , [ False , False , False , False ]), ('include <foobar>' , ( False , False , False , False )),
# ('include "foo"' , [ False , False , False , False ]), # disabled due to implementation restrictions, see re_match_include_parse() # ('include "foo"' , ( False , False , False , False )), # disabled due to implementation restrictions, see re_match_include_parse()
# ('include if exists "foo"' , [ False , False , False , False ]), # ('include if exists "foo"' , ( False , False , False , False )),
] )
class IncludeCoveredTest_02(IncludeCoveredTest): class IncludeCoveredTest_02(IncludeCoveredTest):
rule = 'include if exists <foo>' rule = 'include if exists <foo>'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('include <foo>' , [ False , False , False , False ]), ('include <foo>' , ( False , False , False , False )),
('#include <foo>' , [ False , False , False , False ]), ('#include <foo>' , ( False , False , False , False )),
('#include if exists <foo>' , [ True , False , True , True ]), ('#include if exists <foo>' , ( True , False , True , True )),
('include <foobar>' , [ False , False , False , False ]), ('include <foobar>' , ( False , False , False , False )),
# ('include "foo"' , [ False , False , False , False ]), # disabled due to implementation restrictions, see re_match_include_parse() # ('include "foo"' , ( False , False , False , False )), # disabled due to implementation restrictions, see re_match_include_parse()
# ('include if exists "foo"' , [ False , False , False , False ]), # ('include if exists "foo"' , ( False , False , False , False )),
] )
class IncludeCoveredTest_Invalid(AATest): class IncludeCoveredTest_Invalid(AATest):
# def test_borked_obj_is_covered_1(self): # def test_borked_obj_is_covered_1(self):
@ -304,10 +304,10 @@ class IncludeCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class IncludeLogprofHeaderTest(AATest): class IncludeLogprofHeaderTest(AATest):
tests = [ tests = (
('include <abstractions/base>', [_('Include'), 'include <abstractions/base>' ]), ('include <abstractions/base>', [_('Include'), 'include <abstractions/base>' ]),
('include "/what/ever"', [_('Include'), 'include "/what/ever"', ]), ('include "/what/ever"', [_('Include'), 'include "/what/ever"', ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = IncludeRule.parse(params) obj = IncludeRule.parse(params)
@ -333,16 +333,16 @@ class IncludeFullPathsTest(AATest):
empty_dir = os.path.join(self.profile_dir, 'abstractions/empty.d') empty_dir = os.path.join(self.profile_dir, 'abstractions/empty.d')
os.mkdir(empty_dir, 0o755) os.mkdir(empty_dir, 0o755)
tests = [ tests = (
# @@ will be replaced with self.profile_dir # @@ will be replaced with self.profile_dir
('include <abstractions/base>', ['@@/abstractions/base'] ), ('include <abstractions/base>', ('@@/abstractions/base',) ),
# ('include "foo"', ['@@/foo'] ), # TODO: adjust logic to honor quoted vs. magic paths (and allow quoted relative paths in re_match_include_parse()) # ('include "foo"', ('@@/foo',) ), # TODO: adjust logic to honor quoted vs. magic paths (and allow quoted relative paths in re_match_include_parse())
('include "/foo/bar"', ['/foo/bar'] ), ('include "/foo/bar"', ('/foo/bar',) ),
('include <abstractions/inc.d>', ['@@/abstractions/inc.d/incbar', '@@/abstractions/inc.d/incfoo'] ), ('include <abstractions/inc.d>', ('@@/abstractions/inc.d/incbar', '@@/abstractions/inc.d/incfoo') ),
('include <abstractions/empty.d>', [] ), ('include <abstractions/empty.d>', () ),
('include <abstractions/not_found>', ['@@/abstractions/not_found'] ), ('include <abstractions/not_found>', ('@@/abstractions/not_found',) ),
('include if exists <abstractions/not_found>', [] ), ('include if exists <abstractions/not_found>', () ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
exp2 = [] exp2 = []
@ -376,10 +376,10 @@ class IncludeRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = IncludeRuleset() ruleset = IncludeRuleset()
rules = [ rules = (
' include <foo> ', ' include <foo> ',
' #include "/bar" ', ' #include "/bar" ',
] )
expected_raw = [ expected_raw = [
'include <foo>', 'include <foo>',
@ -414,12 +414,12 @@ class IncludeRulesTest(AATest):
def test_ruleset_2(self): def test_ruleset_2(self):
ruleset = IncludeRuleset() ruleset = IncludeRuleset()
rules = [ rules = (
' include if exists <baz> ', ' include if exists <baz> ',
' include <foo> ', ' include <foo> ',
' #include "/bar" ', ' #include "/bar" ',
'#include if exists "/asdf" ', '#include if exists "/asdf" ',
] )
expected_raw = [ expected_raw = [
'include if exists <baz>', 'include if exists <baz>',

View file

@ -52,7 +52,7 @@ class TestLibapparmorTestMulti(AATest):
raise Exception("Log event doesn't match RE_LOG_ALL") raise Exception("Log event doesn't match RE_LOG_ALL")
for label in expected: for label in expected:
if label in [ if label in (
'file', # filename of the *.in file 'file', # filename of the *.in file
'event_type', # mapped to aamode 'event_type', # mapped to aamode
'audit_id', 'audit_sub_id', # not set nor relevant 'audit_id', 'audit_sub_id', # not set nor relevant
@ -66,9 +66,9 @@ class TestLibapparmorTestMulti(AATest):
'src_name', # pivotroot 'src_name', # pivotroot
'dbus_bus', 'dbus_interface', 'dbus_member', 'dbus_path', # dbus 'dbus_bus', 'dbus_interface', 'dbus_member', 'dbus_path', # dbus
'peer_pid', 'peer_profile', # dbus 'peer_pid', 'peer_profile', # dbus
]: ):
pass pass
elif parsed_items['operation'] == 'exec' and label in ['sock_type', 'family', 'protocol']: elif parsed_items['operation'] == 'exec' and label in ('sock_type', 'family', 'protocol'):
pass # XXX 'exec' + network? really? pass # XXX 'exec' + network? really?
elif parsed_items['operation'] == 'ptrace' and label == 'name2' and params.endswith('/ptrace_garbage_lp1689667_1'): elif parsed_items['operation'] == 'ptrace' and label == 'name2' and params.endswith('/ptrace_garbage_lp1689667_1'):
pass # libapparmor would better qualify this case as invalid event pass # libapparmor would better qualify this case as invalid event
@ -215,10 +215,10 @@ def logfile_to_profile(logfile):
aamode = parsed_event['aamode'] aamode = parsed_event['aamode']
if aamode in['AUDIT', 'STATUS', 'HINT']: # ignore some event types # XXX maybe we shouldn't ignore AUDIT events? if aamode in ('AUDIT', 'STATUS', 'HINT'): # ignore some event types # XXX maybe we shouldn't ignore AUDIT events?
return None, aamode return None, aamode
if aamode not in ['PERMITTING', 'REJECTING']: if aamode not in ('PERMITTING', 'REJECTING'):
raise Exception('Unexpected aamode %s' % parsed_event['aamode']) raise Exception('Unexpected aamode %s' % parsed_event['aamode'])
# cleanup apparmor.aa storage # cleanup apparmor.aa storage
@ -288,7 +288,7 @@ def find_test_multi(log_dir):
for file in files: for file in files:
if file.endswith('.in'): if file.endswith('.in'):
file_with_path = os.path.join(root, file[:-3]) # filename without '.in' file_with_path = os.path.join(root, file[:-3]) # filename without '.in'
tests.append([file_with_path, True]) # True is a dummy testresult, parsing of the *.out files is done while running the tests tests.append((file_with_path, True)) # True is a dummy testresult, parsing of the *.out files is done while running the tests
elif file.endswith('.out') or file.endswith('.err') or file.endswith('.profile'): elif file.endswith('.out') or file.endswith('.err') or file.endswith('.profile'):
pass pass

View file

@ -20,7 +20,7 @@ from common_test import AATest, setup_all_loops # , setup_aa
from apparmor.common import AppArmorException from apparmor.common import AppArmorException
class TestParseEvent(AATest): class TestParseEvent(AATest):
tests = [] tests = ()
def setUp(self): def setUp(self):
self.parser = ReadLog('', '', '') self.parser = ReadLog('', '', '')
@ -100,10 +100,10 @@ class TestParseEvent(AATest):
self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event))
class TestParseEventForTreeInvalid(AATest): class TestParseEventForTreeInvalid(AATest):
tests = [ tests = (
('type=AVC msg=audit(1556742870.707:3614): apparmor="ALLOWED" operation="open" profile="/bin/hello" name="/dev/tty" pid=12856 comm="hello" requested_mask="wr" denied_mask="foo" fsuid=1000 ouid=0', AppArmorException), # invalid file permissions "foo" ('type=AVC msg=audit(1556742870.707:3614): apparmor="ALLOWED" operation="open" profile="/bin/hello" name="/dev/tty" pid=12856 comm="hello" requested_mask="wr" denied_mask="foo" fsuid=1000 ouid=0', AppArmorException), # invalid file permissions "foo"
('type=AVC msg=audit(1556742870.707:3614): apparmor="ALLOWED" operation="open" profile="/bin/hello" name="/dev/tty" pid=12856 comm="hello" requested_mask="wr" denied_mask="wr::w" fsuid=1000 ouid=0', AppArmorException), # "wr::w" mixes owner and other ('type=AVC msg=audit(1556742870.707:3614): apparmor="ALLOWED" operation="open" profile="/bin/hello" name="/dev/tty" pid=12856 comm="hello" requested_mask="wr" denied_mask="wr::w" fsuid=1000 ouid=0', AppArmorException), # "wr::w" mixes owner and other
] )
def _fake_profile_exists(self, program): def _fake_profile_exists(self, program):
return True return True

View file

@ -18,26 +18,26 @@ class BaseAAParseMountTest(AAParseTest):
self.parse_function = aa.parse_mount_rule self.parse_function = aa.parse_mount_rule
class AAParseMountTest(BaseAAParseMountTest): class AAParseMountTest(BaseAAParseMountTest):
tests = [ tests = (
('mount,', 'mount base keyword rule'), ('mount,', 'mount base keyword rule'),
('mount -o ro,', 'mount ro rule'), ('mount -o ro,', 'mount ro rule'),
('mount -o rw /dev/sdb1 -> /mnt/external,', 'mount rw with mount point'), ('mount -o rw /dev/sdb1 -> /mnt/external,', 'mount rw with mount point'),
] )
class AAParseRemountTest(BaseAAParseMountTest): class AAParseRemountTest(BaseAAParseMountTest):
tests = [ tests = (
('remount,', 'remount base keyword rule'), ('remount,', 'remount base keyword rule'),
('remount -o ro,', 'remount ro rule'), ('remount -o ro,', 'remount ro rule'),
('remount -o ro /,', 'remount ro with mountpoint'), ('remount -o ro /,', 'remount ro with mountpoint'),
] )
class AAParseUmountTest(BaseAAParseMountTest): class AAParseUmountTest(BaseAAParseMountTest):
tests = [ tests = (
('umount,', 'umount base keyword rule'), ('umount,', 'umount base keyword rule'),
('umount /mnt/external,', 'umount with mount point'), ('umount /mnt/external,', 'umount with mount point'),
('unmount,', 'unmount base keyword rule'), ('unmount,', 'unmount base keyword rule'),
('unmount /mnt/external,', 'unmount with mount point'), ('unmount /mnt/external,', 'unmount with mount point'),
] )
setup_aa(aa) setup_aa(aa)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -24,8 +24,8 @@ from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'domain', 'all_domains', 'type_or_protocol', 'all_type_or_protocols']) 'domain', 'all_domains', 'type_or_protocol', 'all_type_or_protocols'))
# --- check if the keyword list is up to date --- # # --- check if the keyword list is up to date --- #
@ -65,7 +65,7 @@ class NetworkTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class NetworkTestParse(NetworkTest): class NetworkTestParse(NetworkTest):
tests = [ tests = (
# rawrule audit allow deny comment domain all? type/proto all? # rawrule audit allow deny comment domain all? type/proto all?
('network,' , exp(False, False, False, '' , None , True , None , True )), ('network,' , exp(False, False, False, '' , None , True , None , True )),
('network inet,' , exp(False, False, False, '' , 'inet', False, None , True )), ('network inet,' , exp(False, False, False, '' , 'inet', False, None , True )),
@ -73,7 +73,7 @@ class NetworkTestParse(NetworkTest):
('deny network inet stream, # comment' , exp(False, False, True , ' # comment' , 'inet', False, 'stream' , False)), ('deny network inet stream, # comment' , exp(False, False, True , ' # comment' , 'inet', False, 'stream' , False)),
('audit allow network tcp,' , exp(True , True , False, '' , None , True , 'tcp' , False)), ('audit allow network tcp,' , exp(True , True , False, '' , None , True , 'tcp' , False)),
('network stream,' , exp(False, False, False, '' , None , True , 'stream' , False)), ('network stream,' , exp(False, False, False, '' , None , True , 'stream' , False)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(NetworkRule.match(rawrule)) self.assertTrue(NetworkRule.match(rawrule))
@ -82,12 +82,12 @@ class NetworkTestParse(NetworkTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class NetworkTestParseInvalid(NetworkTest): class NetworkTestParseInvalid(NetworkTest):
tests = [ tests = (
('network foo,' , AppArmorException), ('network foo,' , AppArmorException),
('network foo bar,' , AppArmorException), ('network foo bar,' , AppArmorException),
('network foo tcp,' , AppArmorException), ('network foo tcp,' , AppArmorException),
('network inet bar,' , AppArmorException), ('network inet bar,' , AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(NetworkRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(NetworkRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -135,7 +135,7 @@ class NetworkTestParseFromLog(NetworkTest):
class NetworkFromInit(NetworkTest): class NetworkFromInit(NetworkTest):
tests = [ tests = (
# NetworkRule object audit allow deny comment domain all? type/proto all? # NetworkRule object audit allow deny comment domain all? type/proto all?
(NetworkRule('inet', 'raw', deny=True) , exp(False, False, True , '' , 'inet', False, 'raw' , False)), (NetworkRule('inet', 'raw', deny=True) , exp(False, False, True , '' , 'inet', False, 'raw' , False)),
(NetworkRule('inet', 'raw') , exp(False, False, False, '' , 'inet', False, 'raw' , False)), (NetworkRule('inet', 'raw') , exp(False, False, False, '' , 'inet', False, 'raw' , False)),
@ -143,30 +143,30 @@ class NetworkFromInit(NetworkTest):
(NetworkRule(NetworkRule.ALL, NetworkRule.ALL) , exp(False, False, False, '' , None , True , None , True )), (NetworkRule(NetworkRule.ALL, NetworkRule.ALL) , exp(False, False, False, '' , None , True , None , True )),
(NetworkRule(NetworkRule.ALL, 'tcp') , exp(False, False, False, '' , None , True , 'tcp' , False)), (NetworkRule(NetworkRule.ALL, 'tcp') , exp(False, False, False, '' , None , True , 'tcp' , False)),
(NetworkRule(NetworkRule.ALL, 'stream') , exp(False, False, False, '' , None , True , 'stream' , False)), (NetworkRule(NetworkRule.ALL, 'stream') , exp(False, False, False, '' , None , True , 'stream' , False)),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidNetworkInit(AATest): class InvalidNetworkInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
(['inet', '' ] , AppArmorBug), # empty type_or_protocol (('inet', '' ) , AppArmorBug), # empty type_or_protocol
(['' , 'tcp' ] , AppArmorBug), # empty domain (('' , 'tcp' ) , AppArmorBug), # empty domain
([' ', 'tcp' ] , AppArmorBug), # whitespace domain ((' ', 'tcp' ) , AppArmorBug), # whitespace domain
(['inet', ' ' ] , AppArmorBug), # whitespace type_or_protocol (('inet', ' ' ) , AppArmorBug), # whitespace type_or_protocol
(['xyxy', 'tcp' ] , AppArmorBug), # invalid domain (('xyxy', 'tcp' ) , AppArmorBug), # invalid domain
(['inet', 'xyxy' ] , AppArmorBug), # invalid type_or_protocol (('inet', 'xyxy' ) , AppArmorBug), # invalid type_or_protocol
([dict(), 'tcp' ] , AppArmorBug), # wrong type for domain ((dict(), 'tcp' ) , AppArmorBug), # wrong type for domain
([None , 'tcp' ] , AppArmorBug), # wrong type for domain ((None , 'tcp' ) , AppArmorBug), # wrong type for domain
(['inet', dict() ] , AppArmorBug), # wrong type for type_or_protocol (('inet', dict() ) , AppArmorBug), # wrong type for type_or_protocol
(['inet', None ] , AppArmorBug), # wrong type for type_or_protocol (('inet', None ) , AppArmorBug), # wrong type for type_or_protocol
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
NetworkRule(params[0], params[1]) NetworkRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -217,14 +217,14 @@ class WriteNetworkTestAATest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' network , # foo ' , 'network, # foo'), (' network , # foo ' , 'network, # foo'),
(' audit network inet,' , 'audit network inet,'), (' audit network inet,' , 'audit network inet,'),
(' deny network inet stream,# foo bar' , 'deny network inet stream, # foo bar'), (' deny network inet stream,# foo bar' , 'deny network inet stream, # foo bar'),
(' deny network inet ,# foo bar' , 'deny network inet, # foo bar'), (' deny network inet ,# foo bar' , 'deny network inet, # foo bar'),
(' allow network tcp ,# foo bar' , 'allow network tcp, # foo bar'), (' allow network tcp ,# foo bar' , 'allow network tcp, # foo bar'),
] )
def test_write_manually(self): def test_write_manually(self):
obj = NetworkRule('inet', 'stream', allow_keyword=True) obj = NetworkRule('inet', 'stream', allow_keyword=True)
@ -251,80 +251,80 @@ class NetworkCoveredTest(AATest):
class NetworkCoveredTest_01(NetworkCoveredTest): class NetworkCoveredTest_01(NetworkCoveredTest):
rule = 'network inet,' rule = 'network inet,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('network,' , [ False , False , False , False ]), ('network,' , ( False , False , False , False )),
('network inet,' , [ True , True , True , True ]), ('network inet,' , ( True , True , True , True )),
('network inet, # comment' , [ True , False , True , True ]), ('network inet, # comment' , ( True , False , True , True )),
('allow network inet,' , [ True , False , True , True ]), ('allow network inet,' , ( True , False , True , True )),
('network inet,' , [ True , False , True , True ]), ('network inet,' , ( True , False , True , True )),
('network inet stream,' , [ False , False , True , True ]), ('network inet stream,' , ( False , False , True , True )),
('network inet tcp,' , [ False , False , True , True ]), ('network inet tcp,' , ( False , False , True , True )),
('audit network inet,' , [ False , False , False , False ]), ('audit network inet,' , ( False , False , False , False )),
('audit network,' , [ False , False , False , False ]), ('audit network,' , ( False , False , False , False )),
('network unix,' , [ False , False , False , False ]), ('network unix,' , ( False , False , False , False )),
('network tcp,' , [ False , False , False , False ]), ('network tcp,' , ( False , False , False , False )),
('audit deny network inet,' , [ False , False , False , False ]), ('audit deny network inet,' , ( False , False , False , False )),
('deny network inet,' , [ False , False , False , False ]), ('deny network inet,' , ( False , False , False , False )),
] )
class NetworkCoveredTest_02(NetworkCoveredTest): class NetworkCoveredTest_02(NetworkCoveredTest):
rule = 'audit network inet,' rule = 'audit network inet,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'network inet,' , [ False , False , True , False ]), ( 'network inet,' , ( False , False , True , False )),
('audit network inet,' , [ True , True , True , True ]), ('audit network inet,' , ( True , True , True , True )),
( 'network inet stream,' , [ False , False , True , False ]), ( 'network inet stream,' , ( False , False , True , False )),
('audit network inet stream,' , [ False , False , True , True ]), ('audit network inet stream,' , ( False , False , True , True )),
( 'network,' , [ False , False , False , False ]), ( 'network,' , ( False , False , False , False )),
('audit network,' , [ False , False , False , False ]), ('audit network,' , ( False , False , False , False )),
('network unix,' , [ False , False , False , False ]), ('network unix,' , ( False , False , False , False )),
] )
class NetworkCoveredTest_03(NetworkCoveredTest): class NetworkCoveredTest_03(NetworkCoveredTest):
rule = 'network inet stream,' rule = 'network inet stream,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'network inet stream,' , [ True , True , True , True ]), ( 'network inet stream,' , ( True , True , True , True )),
('allow network inet stream,' , [ True , False , True , True ]), ('allow network inet stream,' , ( True , False , True , True )),
( 'network inet,' , [ False , False , False , False ]), ( 'network inet,' , ( False , False , False , False )),
( 'network,' , [ False , False , False , False ]), ( 'network,' , ( False , False , False , False )),
( 'network inet tcp,' , [ False , False , False , False ]), ( 'network inet tcp,' , ( False , False , False , False )),
('audit network,' , [ False , False , False , False ]), ('audit network,' , ( False , False , False , False )),
('audit network inet stream,' , [ False , False , False , False ]), ('audit network inet stream,' , ( False , False , False , False )),
( 'network unix,' , [ False , False , False , False ]), ( 'network unix,' , ( False , False , False , False )),
( 'network,' , [ False , False , False , False ]), ( 'network,' , ( False , False , False , False )),
] )
class NetworkCoveredTest_04(NetworkCoveredTest): class NetworkCoveredTest_04(NetworkCoveredTest):
rule = 'network,' rule = 'network,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'network,' , [ True , True , True , True ]), ( 'network,' , ( True , True , True , True )),
('allow network,' , [ True , False , True , True ]), ('allow network,' , ( True , False , True , True )),
( 'network inet,' , [ False , False , True , True ]), ( 'network inet,' , ( False , False , True , True )),
( 'network inet6 stream,' , [ False , False , True , True ]), ( 'network inet6 stream,' , ( False , False , True , True )),
( 'network tcp,' , [ False , False , True , True ]), ( 'network tcp,' , ( False , False , True , True )),
( 'network inet raw,' , [ False , False , True , True ]), ( 'network inet raw,' , ( False , False , True , True )),
('audit network,' , [ False , False , False , False ]), ('audit network,' , ( False , False , False , False )),
('deny network,' , [ False , False , False , False ]), ('deny network,' , ( False , False , False , False )),
] )
class NetworkCoveredTest_05(NetworkCoveredTest): class NetworkCoveredTest_05(NetworkCoveredTest):
rule = 'deny network inet,' rule = 'deny network inet,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny network inet,' , [ True , True , True , True ]), ( 'deny network inet,' , ( True , True , True , True )),
('audit deny network inet,' , [ False , False , False , False ]), ('audit deny network inet,' , ( False , False , False , False )),
( 'network inet,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'network inet,' , ( False , False , False , False )), # XXX should covered be true here?
( 'deny network unix,' , [ False , False , False , False ]), ( 'deny network unix,' , ( False , False , False , False )),
( 'deny network,' , [ False , False , False , False ]), ( 'deny network,' , ( False , False , False , False )),
] )
class NetworkCoveredTest_Invalid(AATest): class NetworkCoveredTest_Invalid(AATest):
@ -363,7 +363,7 @@ class NetworkCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class NetworkLogprofHeaderTest(AATest): class NetworkLogprofHeaderTest(AATest):
tests = [ tests = (
('network,', [ _('Network Family'), _('ALL'), _('Socket Type'), _('ALL'), ]), ('network,', [ _('Network Family'), _('ALL'), _('Socket Type'), _('ALL'), ]),
('network inet,', [ _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ('network inet,', [ _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]),
('network inet stream,', [ _('Network Family'), 'inet', _('Socket Type'), 'stream', ]), ('network inet stream,', [ _('Network Family'), 'inet', _('Socket Type'), 'stream', ]),
@ -371,17 +371,17 @@ class NetworkLogprofHeaderTest(AATest):
('allow network inet,', [_('Qualifier'), 'allow', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ('allow network inet,', [_('Qualifier'), 'allow', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]),
('audit network inet stream,', [_('Qualifier'), 'audit', _('Network Family'), 'inet', _('Socket Type'), 'stream', ]), ('audit network inet stream,', [_('Qualifier'), 'audit', _('Network Family'), 'inet', _('Socket Type'), 'stream', ]),
('audit deny network inet,', [_('Qualifier'), 'audit deny', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ('audit deny network inet,', [_('Qualifier'), 'audit deny', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = NetworkRule.parse(params) obj = NetworkRule.parse(params)
self.assertEqual(obj.logprof_header(), expected) self.assertEqual(obj.logprof_header(), expected)
class NetworkRuleReprTest(AATest): class NetworkRuleReprTest(AATest):
tests = [ tests = (
(NetworkRule('inet', 'stream'), '<NetworkRule> network inet stream,'), (NetworkRule('inet', 'stream'), '<NetworkRule> network inet stream,'),
(NetworkRule.parse(' allow network inet stream, # foo'), '<NetworkRule> allow network inet stream, # foo'), (NetworkRule.parse(' allow network inet stream, # foo'), '<NetworkRule> allow network inet stream, # foo'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(str(params), expected) self.assertEqual(str(params), expected)
@ -399,10 +399,10 @@ class NetworkRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = NetworkRuleset() ruleset = NetworkRuleset()
rules = [ rules = (
'network tcp,', 'network tcp,',
'network inet,', 'network inet,',
] )
expected_raw = [ expected_raw = [
'network tcp,', 'network tcp,',
@ -424,11 +424,11 @@ class NetworkRulesTest(AATest):
def test_ruleset_2(self): def test_ruleset_2(self):
ruleset = NetworkRuleset() ruleset = NetworkRuleset()
rules = [ rules = (
'network inet6 raw,', 'network inet6 raw,',
'allow network inet,', 'allow network inet,',
'deny network udp, # example comment', 'deny network udp, # example comment',
] )
expected_raw = [ expected_raw = [
' network inet6 raw,', ' network inet6 raw,',

View file

@ -16,27 +16,27 @@ from apparmor.common import AppArmorBug
from apparmor.notify import get_last_login_timestamp, sane_timestamp from apparmor.notify import get_last_login_timestamp, sane_timestamp
class TestSane_timestamp(AATest): class TestSane_timestamp(AATest):
tests = [ tests = (
(2524704400, False), # Sun Jan 2 03:46:40 CET 2050 (2524704400, False), # Sun Jan 2 03:46:40 CET 2050
( 944780400, False), # Fri Dec 10 00:00:00 CET 1999 ( 944780400, False), # Fri Dec 10 00:00:00 CET 1999
(1635026400, True ), # Sun Oct 24 00:00:00 CEST 2021 (1635026400, True ), # Sun Oct 24 00:00:00 CEST 2021
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(sane_timestamp(params), expected) self.assertEqual(sane_timestamp(params), expected)
class TestGet_last_login_timestamp(AATest): class TestGet_last_login_timestamp(AATest):
tests = [ tests = (
(['wtmp-x86_64', 'root' ], 1635070346), # Sun Oct 24 12:12:26 CEST 2021 (('wtmp-x86_64', 'root' ), 1635070346), # Sun Oct 24 12:12:26 CEST 2021
(['wtmp-x86_64', 'whoever' ], 0), (('wtmp-x86_64', 'whoever' ), 0),
(['wtmp-s390x', 'root' ], 1626368763), # Thu Jul 15 19:06:03 CEST 2021 (('wtmp-s390x', 'root' ), 1626368763), # Thu Jul 15 19:06:03 CEST 2021
(['wtmp-s390x', 'linux1' ], 1626368772), # Thu Jul 15 19:06:12 CEST 2021 (('wtmp-s390x', 'linux1' ), 1626368772), # Thu Jul 15 19:06:12 CEST 2021
(['wtmp-s390x', 'whoever' ], 0), (('wtmp-s390x', 'whoever' ), 0),
(['wtmp-aarch64', 'guillaume' ], 1611562789), # Mon Jan 25 09:19:49 CET 2021 (('wtmp-aarch64', 'guillaume' ), 1611562789), # Mon Jan 25 09:19:49 CET 2021
(['wtmp-aarch64', 'whoever' ], 0), (('wtmp-aarch64', 'whoever' ), 0),
(['wtmp-truncated', 'root' ], 0), (('wtmp-truncated', 'root' ), 0),
(['wtmp-truncated', 'whoever' ], 0), (('wtmp-truncated', 'whoever' ), 0),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
filename, user = params filename, user = params

View file

@ -38,7 +38,7 @@ skip_startswith = (
) )
# testcases that should raise an exception, but don't # testcases that should raise an exception, but don't
exception_not_raised = [ exception_not_raised = (
# most abi/bad_* aren't detected as bad by the basic implementation in the tools # most abi/bad_* aren't detected as bad by the basic implementation in the tools
'abi/bad_10.sd', 'abi/bad_10.sd',
'abi/bad_11.sd', 'abi/bad_11.sd',
@ -218,10 +218,10 @@ exception_not_raised = [
'xtrans/simple_bad_conflicting_x_6.sd', 'xtrans/simple_bad_conflicting_x_6.sd',
'xtrans/simple_bad_conflicting_x_8.sd', 'xtrans/simple_bad_conflicting_x_8.sd',
'xtrans/x-conflict.sd', 'xtrans/x-conflict.sd',
] )
# testcases with lines that don't match any regex and end up as "unknown line" # testcases with lines that don't match any regex and end up as "unknown line"
unknown_line = [ unknown_line = (
# 'other' keyword # 'other' keyword
'file/allow/ok_other_1.sd', 'file/allow/ok_other_1.sd',
'file/allow/ok_other_2.sd', 'file/allow/ok_other_2.sd',
@ -298,10 +298,10 @@ unknown_line = [
'bare_include_tests/ok_84.sd', 'bare_include_tests/ok_84.sd',
'bare_include_tests/ok_85.sd', 'bare_include_tests/ok_85.sd',
'bare_include_tests/ok_86.sd', 'bare_include_tests/ok_86.sd',
] )
# testcases with various unexpected failures # testcases with various unexpected failures
syntax_failure = [ syntax_failure = (
# missing profile keywords # missing profile keywords
'profile/re_named_ok2.sd', 'profile/re_named_ok2.sd',
@ -404,7 +404,7 @@ syntax_failure = [
'vars/vars_dbus_8.sd', # Path doesn't start with / or variable: {/@{TLDS}/foo,/com/@{DOMAINS}} 'vars/vars_dbus_8.sd', # Path doesn't start with / or variable: {/@{TLDS}/foo,/com/@{DOMAINS}}
'vars/vars_simple_assignment_12.sd', # Redefining existing variable @{BAR} ('\' not handled) 'vars/vars_simple_assignment_12.sd', # Redefining existing variable @{BAR} ('\' not handled)
'bare_include_tests/ok_2.sd', # two #include<...> in one line 'bare_include_tests/ok_2.sd', # two #include<...> in one line
] )
class TestParseParserTests(AATest): class TestParseParserTests(AATest):
tests = [] # filled by parse_test_profiles() tests = [] # filled by parse_test_profiles()

View file

@ -17,12 +17,12 @@ class AAParsePivotRootTest(AAParseTest):
def setUp(self): def setUp(self):
self.parse_function = aa.parse_pivot_root_rule self.parse_function = aa.parse_pivot_root_rule
tests = [ tests = (
('pivot_root,', 'pivot_root base keyword'), ('pivot_root,', 'pivot_root base keyword'),
('pivot_root /old,', 'pivot_root oldroot rule'), ('pivot_root /old,', 'pivot_root oldroot rule'),
('pivot_root /old /new,', 'pivot_root old and new root rule'), ('pivot_root /old /new,', 'pivot_root old and new root rule'),
('pivot_root /old /new -> /usr/bin/child,', 'pivot_root child rule'), ('pivot_root /old /new -> /usr/bin/child,', 'pivot_root child rule'),
] )
setup_aa(aa) setup_aa(aa)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -99,13 +99,13 @@ class TestAdd_profile(AATest):
self.pl.add_profile('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo', 'wrong_type') self.pl.add_profile('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo', 'wrong_type')
class TestFilename_from_profile_name(AATest): class TestFilename_from_profile_name(AATest):
tests = [ tests = (
('foo', '/etc/apparmor.d/bin.foo'), ('foo', '/etc/apparmor.d/bin.foo'),
('/bin/foo', None), ('/bin/foo', None),
('bar', None), ('bar', None),
('/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', '/etc/apparmor.d/usr.bin.wine'), ('/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', '/etc/apparmor.d/usr.bin.wine'),
('/usr/lib/wine/bin/wine-preloader-staging-foo', None), # no AARE matching for profile names ('/usr/lib/wine/bin/wine-preloader-staging-foo', None), # no AARE matching for profile names
] )
def AASetup(self): def AASetup(self):
self.pl = ProfileList() self.pl = ProfileList()
@ -117,7 +117,7 @@ class TestFilename_from_profile_name(AATest):
self.assertEqual(self.pl.filename_from_profile_name(params), expected) self.assertEqual(self.pl.filename_from_profile_name(params), expected)
class TestFilename_from_attachment(AATest): class TestFilename_from_attachment(AATest):
tests = [ tests = (
('/bin/foo', '/etc/apparmor.d/bin.foo'), ('/bin/foo', '/etc/apparmor.d/bin.foo'),
('/bin/baz', '/etc/apparmor.d/bin.baz'), ('/bin/baz', '/etc/apparmor.d/bin.baz'),
('/bin/foobar', '/etc/apparmor.d/bin.foobar'), ('/bin/foobar', '/etc/apparmor.d/bin.foobar'),
@ -125,7 +125,7 @@ class TestFilename_from_attachment(AATest):
('/bin/404', None), ('/bin/404', None),
('/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', '/etc/apparmor.d/usr.bin.wine'), # XXX should this really match, or should attachment matching only use AARE? ('/usr{,{/lib,/lib32,/lib64}/wine}/bin/wine{,-preloader,server}{,-staging-*,-vanilla-*}', '/etc/apparmor.d/usr.bin.wine'), # XXX should this really match, or should attachment matching only use AARE?
('/usr/lib/wine/bin/wine-preloader-staging-foo', '/etc/apparmor.d/usr.bin.wine'), # AARE match ('/usr/lib/wine/bin/wine-preloader-staging-foo', '/etc/apparmor.d/usr.bin.wine'), # AARE match
] )
def AASetup(self): def AASetup(self):
self.pl = ProfileList() self.pl = ProfileList()
@ -331,7 +331,7 @@ class TestGet(AATest):
self.pl.get_raw('/etc/apparmor.d/not.found') self.pl.get_raw('/etc/apparmor.d/not.found')
class AaTest_get_all_merged_variables(AATest): class AaTest_get_all_merged_variables(AATest):
tests = [] tests = ()
def AASetup(self): def AASetup(self):
self.createTmpdir() self.createTmpdir()

View file

@ -36,33 +36,33 @@ class TestUnknownKey(AATest):
self.storage['foo'] = 'bar' self.storage['foo'] = 'bar'
class AaTest_get_header(AATest): class AaTest_get_header(AATest):
tests = [ tests = (
# name embedded_hat depth flags attachment xattrs prof.keyw. comment expected # name embedded_hat depth flags attachment xattrs prof.keyw. comment expected
(['/foo', False, 1, 'complain', '', '', False, '' ], ' /foo flags=(complain) {'), (('/foo', False, 1, 'complain', '', '', False, '' ), ' /foo flags=(complain) {'),
(['/foo', True, 1, 'complain', '', '', False, '' ], ' profile /foo flags=(complain) {'), (('/foo', True, 1, 'complain', '', '', False, '' ), ' profile /foo flags=(complain) {'),
(['/foo sp', False, 2, 'complain', '', '', False, '' ], ' "/foo sp" flags=(complain) {'), (('/foo sp', False, 2, 'complain', '', '', False, '' ), ' "/foo sp" flags=(complain) {'),
(['/foo', True, 2, 'complain', '', '', False, '' ], ' profile /foo flags=(complain) {'), (('/foo', True, 2, 'complain', '', '', False, '' ), ' profile /foo flags=(complain) {'),
(['/foo', False, 0, None, '', '', False, '' ], '/foo {'), (('/foo', False, 0, None, '', '', False, '' ), '/foo {'),
(['/foo', False, 0, None, '', 'user.foo=bar', False, '' ], '/foo xattrs=(user.foo=bar) {'), (('/foo', False, 0, None, '', 'user.foo=bar', False, '' ), '/foo xattrs=(user.foo=bar) {'),
(['/foo', True, 0, None, '', '', False, '' ], 'profile /foo {'), (('/foo', True, 0, None, '', '', False, '' ), 'profile /foo {'),
(['bar', False, 1, 'complain', '', '', False, '' ], ' profile bar flags=(complain) {'), (('bar', False, 1, 'complain', '', '', False, '' ), ' profile bar flags=(complain) {'),
(['bar', False, 1, 'complain', '/foo', '', False, '' ], ' profile bar /foo flags=(complain) {'), (('bar', False, 1, 'complain', '/foo', '', False, '' ), ' profile bar /foo flags=(complain) {'),
(['bar', True, 1, 'complain', '/foo', '', False, '' ], ' profile bar /foo flags=(complain) {'), (('bar', True, 1, 'complain', '/foo', '', False, '' ), ' profile bar /foo flags=(complain) {'),
(['bar baz', False, 1, None, '/foo', '', False, '' ], ' profile "bar baz" /foo {'), (('bar baz', False, 1, None, '/foo', '', False, '' ), ' profile "bar baz" /foo {'),
(['bar', True, 1, None, '/foo', '', False, '' ], ' profile bar /foo {'), (('bar', True, 1, None, '/foo', '', False, '' ), ' profile bar /foo {'),
(['bar baz', False, 1, 'complain', '/foo sp', '', False, '' ], ' profile "bar baz" "/foo sp" flags=(complain) {'), (('bar baz', False, 1, 'complain', '/foo sp', '', False, '' ), ' profile "bar baz" "/foo sp" flags=(complain) {'),
(['bar baz', False, 1, 'complain', '/foo sp', 'user.foo=bar', False, '' ], ' profile "bar baz" "/foo sp" xattrs=(user.foo=bar) flags=(complain) {'), (('bar baz', False, 1, 'complain', '/foo sp', 'user.foo=bar', False, '' ), ' profile "bar baz" "/foo sp" xattrs=(user.foo=bar) flags=(complain) {'),
(['^foo', False, 1, 'complain', '', '', False, '' ], ' profile ^foo flags=(complain) {'), (('^foo', False, 1, 'complain', '', '', False, '' ), ' profile ^foo flags=(complain) {'),
(['^foo', True, 1, 'complain', '', '', False, '' ], ' ^foo flags=(complain) {'), (('^foo', True, 1, 'complain', '', '', False, '' ), ' ^foo flags=(complain) {'),
(['^foo', True, 1.5, 'complain', '', '', False, '' ], ' ^foo flags=(complain) {'), (('^foo', True, 1.5, 'complain', '', '', False, '' ), ' ^foo flags=(complain) {'),
(['^foo', True, 1.3, 'complain', '', '', False, '' ], ' ^foo flags=(complain) {'), (('^foo', True, 1.3, 'complain', '', '', False, '' ), ' ^foo flags=(complain) {'),
(['/foo', False, 1, 'complain', '', '', True, '' ], ' profile /foo flags=(complain) {'), (('/foo', False, 1, 'complain', '', '', True, '' ), ' profile /foo flags=(complain) {'),
(['/foo', True, 1, 'complain', '', '', True, '' ], ' profile /foo flags=(complain) {'), (('/foo', True, 1, 'complain', '', '', True, '' ), ' profile /foo flags=(complain) {'),
(['/foo', False, 1, 'complain', '', '', False, '# x' ], ' /foo flags=(complain) { # x'), (('/foo', False, 1, 'complain', '', '', False, '# x' ), ' /foo flags=(complain) { # x'),
(['/foo', True, 1, None, '', '', False, '# x' ], ' profile /foo { # x'), (('/foo', True, 1, None, '', '', False, '# x' ), ' profile /foo { # x'),
(['/foo', False, 1, None, '', '', True, '# x' ], ' profile /foo { # x'), (('/foo', False, 1, None, '', '', True, '# x' ), ' profile /foo { # x'),
(['/foo', True, 1, 'complain', '', '', True, '# x' ], ' profile /foo flags=(complain) { # x'), (('/foo', True, 1, 'complain', '', '', True, '# x' ), ' profile /foo flags=(complain) { # x'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
name = params[0] name = params[0]
@ -80,13 +80,13 @@ class AaTest_get_header(AATest):
self.assertEqual(result, [expected]) self.assertEqual(result, [expected])
class AaTest_get_header_01(AATest): class AaTest_get_header_01(AATest):
tests = [ tests = (
({'name': '/foo', 'depth': 1, 'flags': 'complain' }, ' /foo flags=(complain) {', ), ({'name': '/foo', 'depth': 1, 'flags': 'complain' }, ' /foo flags=(complain) {', ),
({'name': '/foo', 'depth': 1, 'flags': 'complain', 'profile_keyword': True }, ' profile /foo flags=(complain) {', ), ({'name': '/foo', 'depth': 1, 'flags': 'complain', 'profile_keyword': True }, ' profile /foo flags=(complain) {', ),
({'name': '/foo', 'flags': 'complain' }, '/foo flags=(complain) {', ), ({'name': '/foo', 'flags': 'complain' }, '/foo flags=(complain) {', ),
({'name': '/foo', 'xattrs': 'user.foo=bar', 'flags': 'complain' }, '/foo xattrs=(user.foo=bar) flags=(complain) {', ), ({'name': '/foo', 'xattrs': 'user.foo=bar', 'flags': 'complain' }, '/foo xattrs=(user.foo=bar) flags=(complain) {', ),
({'name': '/foo', 'xattrs': 'user.foo=bar', 'embedded_hat': True }, 'profile /foo xattrs=(user.foo=bar) {', ), ({'name': '/foo', 'xattrs': 'user.foo=bar', 'embedded_hat': True }, 'profile /foo xattrs=(user.foo=bar) {', ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
name = params['name'] name = params['name']
@ -96,7 +96,7 @@ class AaTest_get_header_01(AATest):
prof_storage = ProfileStorage(name, '', 'test') prof_storage = ProfileStorage(name, '', 'test')
for param in ['flags', 'attachment', 'profile_keyword', 'header_comment', 'xattrs']: for param in ('flags', 'attachment', 'profile_keyword', 'header_comment', 'xattrs'):
if params.get(param) is not None: if params.get(param) is not None:
prof_storage[param] = params[param] prof_storage[param] = params[param]
@ -105,14 +105,14 @@ class AaTest_get_header_01(AATest):
class TestSetInvalid(AATest): class TestSetInvalid(AATest):
tests = [ tests = (
(('profile_keyword', None), AppArmorBug), # expects bool (('profile_keyword', None), AppArmorBug), # expects bool
(('profile_keyword', 'foo'), AppArmorBug), (('profile_keyword', 'foo'), AppArmorBug),
(('attachment', False), AppArmorBug), # expects string (('attachment', False), AppArmorBug), # expects string
(('attachment', None), AppArmorBug), (('attachment', None), AppArmorBug),
(('filename', True), AppArmorBug), # expects string or None (('filename', True), AppArmorBug), # expects string or None
(('allow', None), AppArmorBug), # doesn't allow overwriting at all (('allow', None), AppArmorBug), # doesn't allow overwriting at all
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.storage = ProfileStorage('/test/foo', 'hat', 'TEST') self.storage = ProfileStorage('/test/foo', 'hat', 'TEST')
@ -120,7 +120,7 @@ class TestSetInvalid(AATest):
self.storage[params[0]] = params[1] self.storage[params[0]] = params[1]
class AaTest_parse_profile_start(AATest): class AaTest_parse_profile_start(AATest):
tests = [ tests = (
# profile start line profile hat profile hat attachment xattrs flags pps_set_hat_external # profile start line profile hat profile hat attachment xattrs flags pps_set_hat_external
(('/foo {', None, None), ('/foo', '/foo', '', '', None, False)), (('/foo {', None, None), ('/foo', '/foo', '', '', None, False)),
(('/foo (complain) {', None, None), ('/foo', '/foo', '', '', 'complain', False)), (('/foo (complain) {', None, None), ('/foo', '/foo', '', '', 'complain', False)),
@ -131,7 +131,7 @@ class AaTest_parse_profile_start(AATest):
(('profile "/foo" xattrs=(user.bar=bar) {', None, None), ('/foo', '/foo', '', 'user.bar=bar', None, False)), (('profile "/foo" xattrs=(user.bar=bar) {', None, None), ('/foo', '/foo', '', 'user.bar=bar', None, False)),
(('profile "/foo" xattrs=(user.bar=bar user.foo=*) {', None, None), ('/foo', '/foo', '', 'user.bar=bar user.foo=*', None, False)), (('profile "/foo" xattrs=(user.bar=bar user.foo=*) {', None, None), ('/foo', '/foo', '', 'user.bar=bar user.foo=*', None, False)),
(('/usr/bin/xattrs-test xattrs=(myvalue="foo.bar") {', None, None), ('/usr/bin/xattrs-test', '/usr/bin/xattrs-test', '', 'myvalue="foo.bar"', None, False)), (('/usr/bin/xattrs-test xattrs=(myvalue="foo.bar") {', None, None), ('/usr/bin/xattrs-test', '/usr/bin/xattrs-test', '', 'myvalue="foo.bar"', None, False)),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
(profile, hat, prof_storage) = ProfileStorage.parse(params[0], 'somefile', 1, params[1], params[2]) (profile, hat, prof_storage) = ProfileStorage.parse(params[0], 'somefile', 1, params[1], params[2])
@ -145,14 +145,14 @@ class AaTest_parse_profile_start(AATest):
self.assertEqual(prof_storage['external'], expected[5]) self.assertEqual(prof_storage['external'], expected[5])
class AaTest_parse_profile_start_errors(AATest): class AaTest_parse_profile_start_errors(AATest):
tests = [ tests = (
(('/foo///bar///baz {', None, None), AppArmorException), # XXX deeply nested external hat (('/foo///bar///baz {', None, None), AppArmorException), # XXX deeply nested external hat
(('profile asdf {', '/foo', '/bar'), AppArmorException), # nested child profile (('profile asdf {', '/foo', '/bar'), AppArmorException), # nested child profile
(('/foo {', '/bar', None), AppArmorException), # child profile without profile keyword (('/foo {', '/bar', None), AppArmorException), # child profile without profile keyword
(('/foo {', '/bar', '/bar'), AppArmorException), # child profile without profile keyword (('/foo {', '/bar', '/bar'), AppArmorException), # child profile without profile keyword
(('xy', '/bar', None), AppArmorBug), # not a profile start (('xy', '/bar', None), AppArmorBug), # not a profile start
(('xy', '/bar', '/bar'), AppArmorBug), # not a profile start (('xy', '/bar', '/bar'), AppArmorBug), # not a profile start
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
@ -160,36 +160,36 @@ class AaTest_parse_profile_start_errors(AATest):
class AaTest_add_or_remove_flag(AATest): class AaTest_add_or_remove_flag(AATest):
tests = [ tests = (
# existing flag(s) flag to change add or remove? expected flags # existing flag(s) flag to change add or remove? expected flags
([ [], 'complain', True ], ['complain'] ), (( [], 'complain', True ), ['complain'] ),
([ [], 'complain', False ], [] ), (( [], 'complain', False ), [] ),
([ ['complain'], 'complain', True ], ['complain'] ), (( ['complain'], 'complain', True ), ['complain'] ),
([ ['complain'], 'complain', False ], [] ), (( ['complain'], 'complain', False ), [] ),
([ [], 'audit', True ], ['audit'] ), (( [], 'audit', True ), ['audit'] ),
([ [], 'audit', False ], [] ), (( [], 'audit', False ), [] ),
([ ['complain'], 'audit', True ], ['audit', 'complain'] ), (( ['complain'], 'audit', True ), ['audit', 'complain'] ),
([ ['complain'], 'audit', False ], ['complain'] ), (( ['complain'], 'audit', False ), ['complain'] ),
([ '', 'audit', True ], ['audit'] ), (( '', 'audit', True ), ['audit'] ),
([ None, 'audit', False ], [] ), (( None, 'audit', False ), [] ),
([ 'complain', 'audit', True ], ['audit', 'complain'] ), (( 'complain', 'audit', True ), ['audit', 'complain'] ),
([ ' complain ', 'audit', False ], ['complain'] ), (( ' complain ', 'audit', False ), ['complain'] ),
([ 'audit complain', ['audit', 'complain'], False ], [] ), (( 'audit complain', ('audit', 'complain'), False ), [] ),
([ 'audit complain', 'audit complain', False ], [] ), (( 'audit complain', 'audit complain', False ), [] ),
([ 'audit complain', ['audit', 'enforce'], False ], ['complain'] ), (( 'audit complain', ('audit', 'enforce'), False ), ['complain'] ),
([ 'audit complain', 'audit enforce', False ], ['complain'] ), (( 'audit complain', 'audit enforce', False ), ['complain'] ),
([ '', ['audit', 'complain'], True ], ['audit', 'complain'] ), (( '', ('audit', 'complain'), True ), ['audit', 'complain'] ),
([ '', 'audit complain', True ], ['audit', 'complain'] ), (( '', 'audit complain', True ), ['audit', 'complain'] ),
([ 'audit', ['audit', 'enforce'], True ], ['audit', 'enforce'] ), (( 'audit', ('audit', 'enforce'), True ), ['audit', 'enforce'] ),
([ 'audit', 'audit enforce', True ], ['audit', 'enforce'] ), (( 'audit', 'audit enforce', True ), ['audit', 'enforce'] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
new_flags = add_or_remove_flag(params[0], params[1], params[2]) new_flags = add_or_remove_flag(*params)
self.assertEqual(new_flags, expected) self.assertEqual(new_flags, expected)
class AaTest_split_flags(AATest): class AaTest_split_flags(AATest):
tests = [ tests = (
(None , [] ), (None , [] ),
('' , [] ), ('' , [] ),
(' ' , [] ), (' ' , [] ),
@ -198,19 +198,19 @@ class AaTest_split_flags(AATest):
(' complain attach_disconnected' , ['attach_disconnected', 'complain'] ), (' complain attach_disconnected' , ['attach_disconnected', 'complain'] ),
(' complain , attach_disconnected' , ['attach_disconnected', 'complain'] ), (' complain , attach_disconnected' , ['attach_disconnected', 'complain'] ),
(' complain , , audit , , ' , ['audit', 'complain'] ), (' complain , , audit , , ' , ['audit', 'complain'] ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
split = split_flags(params) split = split_flags(params)
self.assertEqual(split, expected) self.assertEqual(split, expected)
class AaTest_var_transform(AATest): class AaTest_var_transform(AATest):
tests = [ tests = (
(['foo', ''], '"" foo' ), (('foo', ''), '"" foo' ),
(['foo', 'bar'], 'bar foo' ), (('foo', 'bar'), 'bar foo' ),
([''], '""' ), (('',), '""' ),
(['bar baz', 'foo'], '"bar baz" foo' ), (('bar baz', 'foo'), '"bar baz" foo' ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(var_transform(params), expected) self.assertEqual(var_transform(params), expected)

View file

@ -24,8 +24,8 @@ from apparmor.logparser import ReadLog
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'access', 'all_access', 'peer', 'all_peers']) 'access', 'all_access', 'peer', 'all_peers'))
# # --- tests for single PtraceRule --- # # # --- tests for single PtraceRule --- #
@ -44,7 +44,7 @@ class PtraceTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class PtraceTestParse(PtraceTest): class PtraceTestParse(PtraceTest):
tests = [ tests = (
# PtraceRule object audit allow deny comment access all? peer all? # PtraceRule object audit allow deny comment access all? peer all?
('ptrace,' , exp(False, False, False, '', None , True , None, True )), ('ptrace,' , exp(False, False, False, '', None , True , None, True )),
# ('ptrace (),' , exp(False, False, False, '', None , True , None, True )), # XXX also broken in SignalRule? # ('ptrace (),' , exp(False, False, False, '', None , True , None, True )), # XXX also broken in SignalRule?
@ -59,7 +59,7 @@ class PtraceTestParse(PtraceTest):
('ptrace peer=/foo,' , exp(False, False, False, '', None , True , '/foo', False )), ('ptrace peer=/foo,' , exp(False, False, False, '', None , True , '/foo', False )),
('ptrace r peer=/foo,' , exp(False, False, False, '', {'r'}, False, '/foo', False )), ('ptrace r peer=/foo,' , exp(False, False, False, '', {'r'}, False, '/foo', False )),
('ptrace r peer="/foo bar",' , exp(False, False, False, '', {'r'}, False, '/foo bar', False )), ('ptrace r peer="/foo bar",' , exp(False, False, False, '', {'r'}, False, '/foo bar', False )),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(PtraceRule.match(rawrule)) self.assertTrue(PtraceRule.match(rawrule))
@ -68,14 +68,14 @@ class PtraceTestParse(PtraceTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class PtraceTestParseInvalid(PtraceTest): class PtraceTestParseInvalid(PtraceTest):
tests = [ tests = (
('ptrace foo,' , AppArmorException), ('ptrace foo,' , AppArmorException),
('ptrace foo bar,' , AppArmorException), ('ptrace foo bar,' , AppArmorException),
('ptrace foo int,' , AppArmorException), ('ptrace foo int,' , AppArmorException),
('ptrace read bar,' , AppArmorException), ('ptrace read bar,' , AppArmorException),
('ptrace read tracedby,' , AppArmorException), ('ptrace read tracedby,' , AppArmorException),
('ptrace peer=,' , AppArmorException), ('ptrace peer=,' , AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(PtraceRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(PtraceRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -124,7 +124,7 @@ class PtraceTestParseFromLog(PtraceTest):
self.assertEqual(obj.get_raw(1), ' ptrace tracedby peer=/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace,') self.assertEqual(obj.get_raw(1), ' ptrace tracedby peer=/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace,')
class PtraceFromInit(PtraceTest): class PtraceFromInit(PtraceTest):
tests = [ tests = (
# PtraceRule object audit allow deny comment access all? peer all? # PtraceRule object audit allow deny comment access all? peer all?
(PtraceRule('r', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, 'unconfined', False)), (PtraceRule('r', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, 'unconfined', False)),
(PtraceRule(('r', 'read'), '/bin/foo') , exp(False, False, False, '' , {'r', 'read'},False, '/bin/foo', False)), (PtraceRule(('r', 'read'), '/bin/foo') , exp(False, False, False, '' , {'r', 'read'},False, '/bin/foo', False)),
@ -132,29 +132,29 @@ class PtraceFromInit(PtraceTest):
(PtraceRule('rw', '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, '/bin/foo', False )), (PtraceRule('rw', '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, '/bin/foo', False )),
(PtraceRule('rw', PtraceRule.ALL) , exp(False, False, False, '' , {'rw'}, False, None, True )), (PtraceRule('rw', PtraceRule.ALL) , exp(False, False, False, '' , {'rw'}, False, None, True )),
(PtraceRule(PtraceRule.ALL, PtraceRule.ALL) , exp(False, False, False, '' , None , True, None, True )), (PtraceRule(PtraceRule.ALL, PtraceRule.ALL) , exp(False, False, False, '' , None , True, None, True )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidPtraceInit(AATest): class InvalidPtraceInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
(['' , '/foo' ] , AppArmorBug), # empty access (('' , '/foo' ) , AppArmorBug), # empty access
(['read', '' ] , AppArmorBug), # empty peer (('read', '' ) , AppArmorBug), # empty peer
([' ', '/foo' ] , AppArmorBug), # whitespace access ((' ', '/foo' ) , AppArmorBug), # whitespace access
(['read', ' ' ] , AppArmorBug), # whitespace peer (('read', ' ' ) , AppArmorBug), # whitespace peer
(['xyxy', '/foo' ] , AppArmorException), # invalid access (('xyxy', '/foo' ) , AppArmorException), # invalid access
# XXX is 'invalid peer' possible at all? # XXX is 'invalid peer' possible at all?
([dict(), '/foo' ] , AppArmorBug), # wrong type for access ((dict(), '/foo' ) , AppArmorBug), # wrong type for access
([None , '/foo' ] , AppArmorBug), # wrong type for access ((None , '/foo' ) , AppArmorBug), # wrong type for access
(['read', dict() ] , AppArmorBug), # wrong type for peer (('read', dict() ) , AppArmorBug), # wrong type for peer
(['read', None ] , AppArmorBug), # wrong type for peer (('read', None ) , AppArmorBug), # wrong type for peer
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
PtraceRule(params[0], params[1]) PtraceRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -204,7 +204,7 @@ class WritePtraceTestAATest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
('ptrace,' , 'ptrace,'), ('ptrace,' , 'ptrace,'),
(' ptrace , # foo ' , 'ptrace, # foo'), (' ptrace , # foo ' , 'ptrace, # foo'),
@ -232,7 +232,7 @@ class WritePtraceTestAATest(AATest):
('ptrace (read tracedby) peer=/usr/bin/bar,' , 'ptrace (read tracedby) peer=/usr/bin/bar,'), ('ptrace (read tracedby) peer=/usr/bin/bar,' , 'ptrace (read tracedby) peer=/usr/bin/bar,'),
('ptrace (trace read) peer=/usr/bin/bar,' , 'ptrace (read trace) peer=/usr/bin/bar,'), ('ptrace (trace read) peer=/usr/bin/bar,' , 'ptrace (read trace) peer=/usr/bin/bar,'),
('ptrace wr peer=/sbin/baz,' , 'ptrace wr peer=/sbin/baz,'), ('ptrace wr peer=/sbin/baz,' , 'ptrace wr peer=/sbin/baz,'),
] )
def test_write_manually(self): def test_write_manually(self):
obj = PtraceRule('read', '/foo', allow_keyword=True) obj = PtraceRule('read', '/foo', allow_keyword=True)
@ -259,160 +259,160 @@ class PtraceCoveredTest(AATest):
class PtraceCoveredTest_01(PtraceCoveredTest): class PtraceCoveredTest_01(PtraceCoveredTest):
rule = 'ptrace read,' rule = 'ptrace read,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('ptrace,' , [ False , False , False , False ]), ('ptrace,' , ( False , False , False , False )),
('ptrace read,' , [ True , True , True , True ]), ('ptrace read,' , ( True , True , True , True )),
('ptrace read peer=unconfined,' , [ False , False , True , True ]), ('ptrace read peer=unconfined,' , ( False , False , True , True )),
('ptrace read, # comment' , [ True , False , True , True ]), ('ptrace read, # comment' , ( True , False , True , True )),
('allow ptrace read,' , [ True , False , True , True ]), ('allow ptrace read,' , ( True , False , True , True )),
('ptrace read,' , [ True , False , True , True ]), ('ptrace read,' , ( True , False , True , True )),
('audit ptrace read,' , [ False , False , False , False ]), ('audit ptrace read,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
('audit deny ptrace read,' , [ False , False , False , False ]), ('audit deny ptrace read,' , ( False , False , False , False )),
('deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_02(PtraceCoveredTest): class PtraceCoveredTest_02(PtraceCoveredTest):
rule = 'audit ptrace read,' rule = 'audit ptrace read,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'ptrace read,' , [ False , False , True , False ]), ( 'ptrace read,' , ( False , False , True , False )),
('audit ptrace read,' , [ True , True , True , True ]), ('audit ptrace read,' , ( True , True , True , True )),
( 'ptrace,' , [ False , False , False , False ]), ( 'ptrace,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_03(PtraceCoveredTest): class PtraceCoveredTest_03(PtraceCoveredTest):
rule = 'ptrace,' rule = 'ptrace,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'ptrace,' , [ True , True , True , True ]), ( 'ptrace,' , ( True , True , True , True )),
('allow ptrace,' , [ True , False , True , True ]), ('allow ptrace,' , ( True , False , True , True )),
( 'ptrace read,' , [ False , False , True , True ]), ( 'ptrace read,' , ( False , False , True , True )),
( 'ptrace w,' , [ False , False , True , True ]), ( 'ptrace w,' , ( False , False , True , True )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('deny ptrace,' , [ False , False , False , False ]), ('deny ptrace,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_04(PtraceCoveredTest): class PtraceCoveredTest_04(PtraceCoveredTest):
rule = 'deny ptrace read,' rule = 'deny ptrace read,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny ptrace read,' , [ True , True , True , True ]), ( 'deny ptrace read,' , ( True , True , True , True )),
('audit deny ptrace read,' , [ False , False , False , False ]), ('audit deny ptrace read,' , ( False , False , False , False )),
( 'ptrace read,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'ptrace read,' , ( False , False , False , False )), # XXX should covered be true here?
( 'deny ptrace tracedby,' , [ False , False , False , False ]), ( 'deny ptrace tracedby,' , ( False , False , False , False )),
( 'deny ptrace,' , [ False , False , False , False ]), ( 'deny ptrace,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_05(PtraceCoveredTest): class PtraceCoveredTest_05(PtraceCoveredTest):
rule = 'ptrace read peer=unconfined,' rule = 'ptrace read peer=unconfined,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('ptrace,' , [ False , False , False , False ]), ('ptrace,' , ( False , False , False , False )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=unconfined,' , [ True , True , True , True ]), ('ptrace read peer=unconfined,' , ( True , True , True , True )),
('ptrace peer=unconfined,' , [ False , False , False , False ]), ('ptrace peer=unconfined,' , ( False , False , False , False )),
('ptrace read, # comment' , [ False , False , False , False ]), ('ptrace read, # comment' , ( False , False , False , False )),
('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read,' , ( False , False , False , False )),
('allow ptrace read peer=unconfined,' , [ True , False , True , True ]), ('allow ptrace read peer=unconfined,' , ( True , False , True , True )),
('allow ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('allow ptrace read peer=/foo/bar,' , ( False , False , False , False )),
('allow ptrace read peer=/**,' , [ False , False , False , False ]), ('allow ptrace read peer=/**,' , ( False , False , False , False )),
('allow ptrace read peer=**,' , [ False , False , False , False ]), ('allow ptrace read peer=**,' , ( False , False , False , False )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=unconfined,' , [ True , False , True , True ]), ('ptrace read peer=unconfined,' , ( True , False , True , True )),
('audit ptrace read peer=unconfined,' , [ False , False , False , False ]), ('audit ptrace read peer=unconfined,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
('audit deny ptrace read,' , [ False , False , False , False ]), ('audit deny ptrace read,' , ( False , False , False , False )),
('deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_06(PtraceCoveredTest): class PtraceCoveredTest_06(PtraceCoveredTest):
rule = 'ptrace read peer=/foo/bar,' rule = 'ptrace read peer=/foo/bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('ptrace,' , [ False , False , False , False ]), ('ptrace,' , ( False , False , False , False )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=/foo/bar,' , [ True , True , True , True ]), ('ptrace read peer=/foo/bar,' , ( True , True , True , True )),
('ptrace read peer=/foo/*,' , [ False , False , False , False ]), ('ptrace read peer=/foo/*,' , ( False , False , False , False )),
('ptrace read peer=/**,' , [ False , False , False , False ]), ('ptrace read peer=/**,' , ( False , False , False , False )),
('ptrace read peer=/what/*,' , [ False , False , False , False ]), ('ptrace read peer=/what/*,' , ( False , False , False , False )),
('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace peer=/foo/bar,' , ( False , False , False , False )),
('ptrace read, # comment' , [ False , False , False , False ]), ('ptrace read, # comment' , ( False , False , False , False )),
('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read,' , ( False , False , False , False )),
('allow ptrace read peer=/foo/bar,' , [ True , False , True , True ]), ('allow ptrace read peer=/foo/bar,' , ( True , False , True , True )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=/foo/bar,' , [ True , False , True , True ]), ('ptrace read peer=/foo/bar,' , ( True , False , True , True )),
('ptrace read peer=/what/ever,' , [ False , False , False , False ]), ('ptrace read peer=/what/ever,' , ( False , False , False , False )),
('audit ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace read peer=/foo/bar,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
('audit deny ptrace read,' , [ False , False , False , False ]), ('audit deny ptrace read,' , ( False , False , False , False )),
('deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_07(PtraceCoveredTest): class PtraceCoveredTest_07(PtraceCoveredTest):
rule = 'ptrace read peer=**,' rule = 'ptrace read peer=**,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('ptrace,' , [ False , False , False , False ]), ('ptrace,' , ( False , False , False , False )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace read peer=/foo/bar,' , ( False , False , True , True )),
('ptrace read peer=/foo/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('ptrace read peer=/foo/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('ptrace read peer=/**,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('ptrace read peer=/**,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('ptrace read peer=/what/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('ptrace read peer=/what/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace peer=/foo/bar,' , ( False , False , False , False )),
('ptrace read, # comment' , [ False , False , False , False ]), ('ptrace read, # comment' , ( False , False , False , False )),
('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read,' , ( False , False , False , False )),
('allow ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('allow ptrace read peer=/foo/bar,' , ( False , False , True , True )),
('ptrace read,' , [ False , False , False , False ]), ('ptrace read,' , ( False , False , False , False )),
('ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace read peer=/foo/bar,' , ( False , False , True , True )),
('ptrace read peer=/what/ever,' , [ False , False , True , True ]), ('ptrace read peer=/what/ever,' , ( False , False , True , True )),
('audit ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace read peer=/foo/bar,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
('audit deny ptrace read,' , [ False , False , False , False ]), ('audit deny ptrace read,' , ( False , False , False , False )),
('deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , ( False , False , False , False )),
] )
class PtraceCoveredTest_08(PtraceCoveredTest): class PtraceCoveredTest_08(PtraceCoveredTest):
rule = 'ptrace (trace, tracedby) peer=/foo/*,' rule = 'ptrace (trace, tracedby) peer=/foo/*,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('ptrace,' , [ False , False , False , False ]), ('ptrace,' , ( False , False , False , False )),
('ptrace trace,' , [ False , False , False , False ]), ('ptrace trace,' , ( False , False , False , False )),
('ptrace (tracedby, trace),' , [ False , False , False , False ]), ('ptrace (tracedby, trace),' , ( False , False , False , False )),
('ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace trace peer=/foo/bar,' , ( False , False , True , True )),
('ptrace (tracedby trace) peer=/foo/bar,',[ False , False , True , True ]), ('ptrace (tracedby trace) peer=/foo/bar,',( False , False , True , True )),
('ptrace (tracedby, trace) peer=/foo/*,', [ True , False , True , True ]), ('ptrace (tracedby, trace) peer=/foo/*,', ( True , False , True , True )),
('ptrace tracedby peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace tracedby peer=/foo/bar,' , ( False , False , True , True )),
('ptrace trace peer=/foo/*,' , [ False , False , True , True ]), ('ptrace trace peer=/foo/*,' , ( False , False , True , True )),
('ptrace trace peer=/**,' , [ False , False , False , False ]), ('ptrace trace peer=/**,' , ( False , False , False , False )),
('ptrace trace peer=/what/*,' , [ False , False , False , False ]), ('ptrace trace peer=/what/*,' , ( False , False , False , False )),
('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace peer=/foo/bar,' , ( False , False , False , False )),
('ptrace trace, # comment' , [ False , False , False , False ]), ('ptrace trace, # comment' , ( False , False , False , False )),
('allow ptrace trace,' , [ False , False , False , False ]), ('allow ptrace trace,' , ( False , False , False , False )),
('allow ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('allow ptrace trace peer=/foo/bar,' , ( False , False , True , True )),
('ptrace trace,' , [ False , False , False , False ]), ('ptrace trace,' , ( False , False , False , False )),
('ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace trace peer=/foo/bar,' , ( False , False , True , True )),
('ptrace trace peer=/what/ever,' , [ False , False , False , False ]), ('ptrace trace peer=/what/ever,' , ( False , False , False , False )),
('audit ptrace trace peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace trace peer=/foo/bar,' , ( False , False , False , False )),
('audit ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , ( False , False , False , False )),
('ptrace tracedby,' , [ False , False , False , False ]), ('ptrace tracedby,' , ( False , False , False , False )),
('audit deny ptrace trace,' , [ False , False , False , False ]), ('audit deny ptrace trace,' , ( False , False , False , False )),
('deny ptrace trace,' , [ False , False , False , False ]), ('deny ptrace trace,' , ( False , False , False , False )),
] )
@ -462,7 +462,7 @@ class PtraceCoveredTest_Invalid(AATest):
class PtraceLogprofHeaderTest(AATest): class PtraceLogprofHeaderTest(AATest):
tests = [ tests = (
('ptrace,', [ _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]), ('ptrace,', [ _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]),
('ptrace read,', [ _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('ptrace read,', [ _('Access mode'), 'read', _('Peer'), _('ALL'), ]),
('deny ptrace,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]), ('deny ptrace,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]),
@ -470,7 +470,7 @@ class PtraceLogprofHeaderTest(AATest):
('audit ptrace read,', [_('Qualifier'), 'audit', _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('audit ptrace read,', [_('Qualifier'), 'audit', _('Access mode'), 'read', _('Peer'), _('ALL'), ]),
('audit deny ptrace read,', [_('Qualifier'), 'audit deny', _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('audit deny ptrace read,', [_('Qualifier'), 'audit deny', _('Access mode'), 'read', _('Peer'), _('ALL'), ]),
('ptrace (read, tracedby) peer=/foo,', [ _('Access mode'), 'read tracedby', _('Peer'), '/foo', ]), ('ptrace (read, tracedby) peer=/foo,', [ _('Access mode'), 'read tracedby', _('Peer'), '/foo', ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = PtraceRule.parse(params) obj = PtraceRule.parse(params)
@ -493,10 +493,10 @@ class PtraceRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = PtraceRuleset() ruleset = PtraceRuleset()
rules = [ rules = (
'ptrace peer=/foo,', 'ptrace peer=/foo,',
'ptrace read,', 'ptrace read,',
] )
expected_raw = [ expected_raw = [
'ptrace peer=/foo,', 'ptrace peer=/foo,',
@ -522,11 +522,11 @@ class PtraceRulesTest(AATest):
def test_ruleset_2(self): def test_ruleset_2(self):
ruleset = PtraceRuleset() ruleset = PtraceRuleset()
rules = [ rules = (
'ptrace read peer=/foo,', 'ptrace read peer=/foo,',
'allow ptrace read,', 'allow ptrace read,',
'deny ptrace peer=/bar, # example comment', 'deny ptrace peer=/bar, # example comment',
] )
expected_raw = [ expected_raw = [
' ptrace read peer=/foo,', ' ptrace read peer=/foo,',

View file

@ -57,7 +57,7 @@ class AARegexHasComma(AATest):
else: else:
self.assertEqual(None, result, 'Found an unexpected comma in "%s"' % line) self.assertEqual(None, result, 'Found an unexpected comma in "%s"' % line)
regex_has_comma_testcases = [ regex_has_comma_testcases = (
('dbus send%s', 'simple'), ('dbus send%s', 'simple'),
('dbus (r, w, bind, eavesdrop)%s', 'embedded parens 01'), ('dbus (r, w, bind, eavesdrop)%s', 'embedded parens 01'),
('dbus (r, w,, bind, eavesdrop) %s', 'embedded parens 02'), ('dbus (r, w,, bind, eavesdrop) %s', 'embedded parens 02'),
@ -112,7 +112,7 @@ regex_has_comma_testcases = [
# ('@{BAR}={bar,baz,blort, %s', 'tricksy variable declaration') # ('@{BAR}={bar,baz,blort, %s', 'tricksy variable declaration')
# The following fails the comma test, because it's really a no comma situation # The following fails the comma test, because it's really a no comma situation
# ('@{BAR}="{bar,baz,blort%s" ', 'tricksy variable declaration') # ('@{BAR}="{bar,baz,blort%s" ', 'tricksy variable declaration')
] )
def setup_has_comma_testcases(): def setup_has_comma_testcases():
i = 0 i = 0
@ -145,7 +145,7 @@ class AARegexSplitComment(AATest):
# Tuples of (string, expected result), where expected result is False if # Tuples of (string, expected result), where expected result is False if
# the string should not be considered as having a comment, or a second # the string should not be considered as having a comment, or a second
# tuple of the not comment and comment sections split apart # tuple of the not comment and comment sections split apart
regex_split_comment_testcases = [ regex_split_comment_testcases = (
('dbus send # this is a comment', ('dbus send ', '# this is a comment')), ('dbus send # this is a comment', ('dbus send ', '# this is a comment')),
('dbus send member=no_comment', False), ('dbus send member=no_comment', False),
('dbus send member=no_comment, ', False), ('dbus send member=no_comment, ', False),
@ -160,7 +160,7 @@ regex_split_comment_testcases = [
('ptrace (trace read) peer=/usr/bin/foo,', False), ('ptrace (trace read) peer=/usr/bin/foo,', False),
('pivot_root, # comment', ('pivot_root, ', '# comment')), ('pivot_root, # comment', ('pivot_root, ', '# comment')),
('pivot_root /old /new -> child,', False), ('pivot_root /old /new -> child,', False),
] )
def setup_split_comment_testcases(): def setup_split_comment_testcases():
i = 0 i = 0
@ -208,13 +208,13 @@ class AARegexCapability(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = RE_PROFILE_CAP self.regex = RE_PROFILE_CAP
tests = [ tests = (
(' capability net_raw,', (None, None, 'net_raw', 'net_raw', None)), (' capability net_raw,', (None, None, 'net_raw', 'net_raw', None)),
('capability net_raw , ', (None, None, 'net_raw', 'net_raw', None)), ('capability net_raw , ', (None, None, 'net_raw', 'net_raw', None)),
(' capability,', (None, None, None, None, None)), (' capability,', (None, None, None, None, None)),
(' capability , ', (None, None, None, None, None)), (' capability , ', (None, None, None, None, None)),
(' capabilitynet_raw,', False) (' capabilitynet_raw,', False)
] )
class AARegexDbus(AARegexTest): class AARegexDbus(AARegexTest):
'''Tests for RE_PROFILE_DBUS''' '''Tests for RE_PROFILE_DBUS'''
@ -222,7 +222,7 @@ class AARegexDbus(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = RE_PROFILE_DBUS self.regex = RE_PROFILE_DBUS
tests = [ tests = (
(' dbus,', (None, None, 'dbus,', None, None)), (' dbus,', (None, None, 'dbus,', None, None)),
(' audit dbus,', ('audit', None, 'dbus,', None, None)), (' audit dbus,', ('audit', None, 'dbus,', None, None)),
(' dbus send member=no_comment,', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)), (' dbus send member=no_comment,', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)),
@ -230,7 +230,7 @@ class AARegexDbus(AARegexTest):
(' dbusdriver,', False), (' dbusdriver,', False),
(' audit dbusdriver,', False), (' audit dbusdriver,', False),
] )
class AARegexMount(AARegexTest): class AARegexMount(AARegexTest):
'''Tests for RE_PROFILE_MOUNT''' '''Tests for RE_PROFILE_MOUNT'''
@ -238,7 +238,7 @@ class AARegexMount(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = aa.RE_PROFILE_MOUNT self.regex = aa.RE_PROFILE_MOUNT
tests = [ tests = (
(' mount,', (None, None, 'mount,', 'mount', None, None)), (' mount,', (None, None, 'mount,', 'mount', None, None)),
(' audit mount,', ('audit', None, 'mount,', 'mount', None, None)), (' audit mount,', ('audit', None, 'mount,', 'mount', None, None)),
(' umount,', (None, None, 'umount,', 'umount', None, None)), (' umount,', (None, None, 'umount,', 'umount', None, None)),
@ -252,7 +252,7 @@ class AARegexMount(AARegexTest):
(' mountain,', False), (' mountain,', False),
(' audit mountain,', False), (' audit mountain,', False),
] )
@ -262,7 +262,7 @@ class AARegexSignal(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = RE_PROFILE_SIGNAL self.regex = RE_PROFILE_SIGNAL
tests = [ tests = (
(' signal,', (None, None, 'signal,', None, None)), (' signal,', (None, None, 'signal,', None, None)),
(' audit signal,', ('audit', None, 'signal,', None, None)), (' audit signal,', ('audit', None, 'signal,', None, None)),
(' signal receive,', (None, None, 'signal receive,', 'receive', None)), (' signal receive,', (None, None, 'signal receive,', 'receive', None)),
@ -275,7 +275,7 @@ class AARegexSignal(AARegexTest):
(' signalling,', False), (' signalling,', False),
(' audit signalling,', False), (' audit signalling,', False),
(' signalling receive,', False), (' signalling receive,', False),
] )
class AARegexPtrace(AARegexTest): class AARegexPtrace(AARegexTest):
@ -284,7 +284,7 @@ class AARegexPtrace(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = RE_PROFILE_PTRACE self.regex = RE_PROFILE_PTRACE
tests = [ tests = (
# audit allow rule rule details comment # audit allow rule rule details comment
(' ptrace,', (None, None, 'ptrace,', None, None)), (' ptrace,', (None, None, 'ptrace,', None, None)),
(' audit ptrace,', ('audit', None, 'ptrace,', None, None)), (' audit ptrace,', ('audit', None, 'ptrace,', None, None)),
@ -296,7 +296,7 @@ class AARegexPtrace(AARegexTest):
(' ptraceback,', False), (' ptraceback,', False),
(' audit ptraceback,', False), (' audit ptraceback,', False),
(' ptraceback trace,', False), (' ptraceback trace,', False),
] )
class AARegexPivotRoot(AARegexTest): class AARegexPivotRoot(AARegexTest):
@ -305,7 +305,7 @@ class AARegexPivotRoot(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = aa.RE_PROFILE_PIVOT_ROOT self.regex = aa.RE_PROFILE_PIVOT_ROOT
tests = [ tests = (
(' pivot_root,', (None, None, 'pivot_root,', None)), (' pivot_root,', (None, None, 'pivot_root,', None)),
(' audit pivot_root,', ('audit', None, 'pivot_root,', None)), (' audit pivot_root,', ('audit', None, 'pivot_root,', None)),
(' pivot_root oldroot=/new/old,', (' pivot_root oldroot=/new/old,',
@ -324,7 +324,7 @@ class AARegexPivotRoot(AARegexTest):
('pivot_rootbeer, # comment', False), ('pivot_rootbeer, # comment', False),
('pivot_rootbeer /new, ', False), ('pivot_rootbeer /new, ', False),
('pivot_rootbeer /new, # comment', False), ('pivot_rootbeer /new, # comment', False),
] )
class AARegexUnix(AARegexTest): class AARegexUnix(AARegexTest):
'''Tests for RE_PROFILE_UNIX''' '''Tests for RE_PROFILE_UNIX'''
@ -332,7 +332,7 @@ class AARegexUnix(AARegexTest):
def AASetup(self): def AASetup(self):
self.regex = aa.RE_PROFILE_UNIX self.regex = aa.RE_PROFILE_UNIX
tests = [ tests = (
(' unix,', (None, None, 'unix,', None)), (' unix,', (None, None, 'unix,', None)),
(' audit unix,', ('audit', None, 'unix,', None)), (' audit unix,', ('audit', None, 'unix,', None)),
(' unix accept,', (None, None, 'unix accept,', None)), (' unix accept,', (None, None, 'unix accept,', None)),
@ -349,7 +349,7 @@ class AARegexUnix(AARegexTest):
(None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', None)), (None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', None)),
('unixlike', False), ('unixlike', False),
('deny unixlike,', False), ('deny unixlike,', False),
] )
class AANamedRegexProfileStart_2(AANamedRegexTest): class AANamedRegexProfileStart_2(AANamedRegexTest):
'''Tests for RE_PROFILE_START''' '''Tests for RE_PROFILE_START'''
@ -357,7 +357,7 @@ class AANamedRegexProfileStart_2(AANamedRegexTest):
def AASetup(self): def AASetup(self):
self.regex = RE_PROFILE_START self.regex = RE_PROFILE_START
tests = [ tests = (
('/bin/foo ', False), # no '{' ('/bin/foo ', False), # no '{'
('/bin/foo /bin/bar', False), # missing 'profile' keyword ('/bin/foo /bin/bar', False), # missing 'profile' keyword
('profile {', False), # no attachment ('profile {', False), # no attachment
@ -387,11 +387,11 @@ class AANamedRegexProfileStart_2(AANamedRegexTest):
('/foo {', { 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': '' }), ('/foo {', { 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': '' }),
(' profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': ' ' }), (' profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': ' ' }),
('profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': '' }), ('profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': '' }),
] )
class Test_parse_profile_start_line(AATest): class Test_parse_profile_start_line(AATest):
tests = [ tests = (
(' /foo {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' /foo {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }),
(' "/foo" {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' "/foo" {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }),
(' profile /foo {', { 'profile': '/foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': '/foo', 'attachment': None, 'flags': None, 'comment': None }), (' profile /foo {', { 'profile': '/foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': '/foo', 'attachment': None, 'flags': None, 'comment': None }),
@ -414,7 +414,7 @@ class Test_parse_profile_start_line(AATest):
(' profile @{foo} /bar {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '/bar', 'flags': None, 'comment': None }), (' profile @{foo} /bar {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '/bar', 'flags': None, 'comment': None }),
(' profile foo @{bar} {', { 'profile': 'foo', 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '@{bar}', 'flags': None, 'comment': None }), (' profile foo @{bar} {', { 'profile': 'foo', 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '@{bar}', 'flags': None, 'comment': None }),
(' profile @{foo} @{bar} {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '@{bar}', 'flags': None, 'comment': None }), (' profile @{foo} @{bar} {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '@{bar}', 'flags': None, 'comment': None }),
] )
def _run_test(self, line, expected): def _run_test(self, line, expected):
matches = parse_profile_start_line(line, 'somefile') matches = parse_profile_start_line(line, 'somefile')
@ -425,19 +425,19 @@ class Test_parse_profile_start_line(AATest):
self.assertEqual(matches[exp], expected[exp], 'Group %s mismatch in rule %s' % (exp,line)) self.assertEqual(matches[exp], expected[exp], 'Group %s mismatch in rule %s' % (exp,line))
class TestInvalid_parse_profile_start_line(AATest): class TestInvalid_parse_profile_start_line(AATest):
tests = [ tests = (
('/bin/foo ', False), # no '{' ('/bin/foo ', False), # no '{'
('/bin/foo /bin/bar', False), # missing 'profile' keyword ('/bin/foo /bin/bar', False), # missing 'profile' keyword
('profile {', False), # no attachment ('profile {', False), # no attachment
(' profile foo bar /foo {', False), # missing quotes around "foo bar" (' profile foo bar /foo {', False), # missing quotes around "foo bar"
] )
def _run_test(self, line, expected): def _run_test(self, line, expected):
with self.assertRaises(AppArmorBug): with self.assertRaises(AppArmorBug):
parse_profile_start_line(line, 'somefile') parse_profile_start_line(line, 'somefile')
class Test_re_match_include(AATest): class Test_re_match_include(AATest):
tests = [ tests = (
# #include # #include
('#include <abstractions/base>', 'abstractions/base' ), # magic path ('#include <abstractions/base>', 'abstractions/base' ), # magic path
('#include <abstractions/base> # comment', 'abstractions/base' ), ('#include <abstractions/base> # comment', 'abstractions/base' ),
@ -463,13 +463,13 @@ class Test_re_match_include(AATest):
('/include r,', None, ), ('/include r,', None, ),
(' #include if exists <abstractions/base>', None, ), # include if exists (' #include if exists <abstractions/base>', None, ), # include if exists
(' #include if exists "/foo/bar"', None, ), (' #include if exists "/foo/bar"', None, ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(re_match_include(params), expected) self.assertEqual(re_match_include(params), expected)
class TestInvalid_re_match_include(AATest): class TestInvalid_re_match_include(AATest):
tests = [ tests = (
('#include <>', AppArmorException ), # '#include' ('#include <>', AppArmorException ), # '#include'
('#include < >', AppArmorException ), ('#include < >', AppArmorException ),
('#include ""', AppArmorException ), ('#include ""', AppArmorException ),
@ -517,14 +517,14 @@ class TestInvalid_re_match_include(AATest):
('include /foo bar', AppArmorException ), ('include /foo bar', AppArmorException ),
('include "/foo bar"', AppArmorException ), ('include "/foo bar"', AppArmorException ),
('include "foo bar/baz"', AppArmorException ), ('include "foo bar/baz"', AppArmorException ),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
re_match_include(params) re_match_include(params)
class Test_re_match_include_parse(AATest): class Test_re_match_include_parse(AATest):
tests = [ tests = (
# path if exists magic path # path if exists magic path
# #include # #include
('#include <abstractions/base>', ('abstractions/base', False, True ) ), # magic path ('#include <abstractions/base>', ('abstractions/base', False, True ) ), # magic path
@ -568,13 +568,13 @@ class Test_re_match_include_parse(AATest):
('/usr/include r,', (None, None, None ) ), ('/usr/include r,', (None, None, None ) ),
('/include r,', (None, None, None ) ), ('/include r,', (None, None, None ) ),
('abi <abi/4.19>,', (None, None, None ) ), # abi rule ('abi <abi/4.19>,', (None, None, None ) ), # abi rule
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(re_match_include_parse(params, 'include'), expected) self.assertEqual(re_match_include_parse(params, 'include'), expected)
class Test_re_match_include_parse_abi(AATest): class Test_re_match_include_parse_abi(AATest):
tests = [ tests = (
# path if exists magic path # path if exists magic path
('abi <abi/4.19>,', ('abi/4.19', False, True ) ), # magic path ('abi <abi/4.19>,', ('abi/4.19', False, True ) ), # magic path
('abi <abi/4.19>, # comment', ('abi/4.19', False, True ) ), ('abi <abi/4.19>, # comment', ('abi/4.19', False, True ) ),
@ -589,13 +589,13 @@ class Test_re_match_include_parse_abi(AATest):
('/usr/abi r,', (None, None, None ) ), ('/usr/abi r,', (None, None, None ) ),
('/abi r,', (None, None, None ) ), ('/abi r,', (None, None, None ) ),
('#include <abstractions/base>', (None, None, None ) ), # include rule path ('#include <abstractions/base>', (None, None, None ) ), # include rule path
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(re_match_include_parse(params, 'abi'), expected) self.assertEqual(re_match_include_parse(params, 'abi'), expected)
class Test_re_match_include_parse_errors(AATest): class Test_re_match_include_parse_errors(AATest):
tests = [ tests = (
(('include <>', 'include'), AppArmorException), # various rules with empty filename (('include <>', 'include'), AppArmorException), # various rules with empty filename
(('include ""', 'include'), AppArmorException), (('include ""', 'include'), AppArmorException),
(('include ', 'include'), AppArmorException), (('include ', 'include'), AppArmorException),
@ -603,7 +603,7 @@ class Test_re_match_include_parse_errors(AATest):
(('abi "",', 'abi'), AppArmorException), (('abi "",', 'abi'), AppArmorException),
(('abi ,', 'abi'), AppArmorException), (('abi ,', 'abi'), AppArmorException),
(('abi <foo>,', 'invalid'), AppArmorBug), # invalid rule name (('abi <foo>,', 'invalid'), AppArmorBug), # invalid rule name
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
@ -611,7 +611,7 @@ class Test_re_match_include_parse_errors(AATest):
re_match_include_parse(rule, rule_name) re_match_include_parse(rule, rule_name)
class TestStripParenthesis(AATest): class TestStripParenthesis(AATest):
tests = [ tests = (
('foo', 'foo' ), ('foo', 'foo' ),
('(foo)', 'foo' ), ('(foo)', 'foo' ),
('( foo )', 'foo' ), ('( foo )', 'foo' ),
@ -623,13 +623,13 @@ class TestStripParenthesis(AATest):
('(())', '()' ), ('(())', '()' ),
(' (foo)', '(foo)' ), # parenthesis not first char, whitespace stripped nevertheless (' (foo)', '(foo)' ), # parenthesis not first char, whitespace stripped nevertheless
('(foo) ', '(foo)' ), # parenthesis not last char, whitespace stripped nevertheless ('(foo) ', '(foo)' ), # parenthesis not last char, whitespace stripped nevertheless
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(strip_parenthesis(params), expected) self.assertEqual(strip_parenthesis(params), expected)
class TestStripQuotes(AATest): class TestStripQuotes(AATest):
tests = [ tests = (
('foo', 'foo'), ('foo', 'foo'),
('"foo"', 'foo'), ('"foo"', 'foo'),
('"foo', '"foo'), ('"foo', '"foo'),
@ -641,7 +641,7 @@ class TestStripQuotes(AATest):
('', ''), ('', ''),
('/', '/'), ('/', '/'),
('"', '"'), ('"', '"'),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(strip_quotes(params), expected) self.assertEqual(strip_quotes(params), expected)

View file

@ -24,8 +24,8 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', exp = namedtuple('exp', ('audit', 'allow_keyword', 'deny', 'comment',
'rlimit', 'value', 'all_values']) 'rlimit', 'value', 'all_values'))
# --- tests for single RlimitRule --- # # --- tests for single RlimitRule --- #
@ -40,7 +40,7 @@ class RlimitTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class RlimitTestParse(RlimitTest): class RlimitTestParse(RlimitTest):
tests = [ tests = (
# rawrule audit allow deny comment rlimit value all/infinity? # rawrule audit allow deny comment rlimit value all/infinity?
('set rlimit as <= 2047MB,' , exp(False, False, False, '' , 'as' , '2047MB' , False)), ('set rlimit as <= 2047MB,' , exp(False, False, False, '' , 'as' , '2047MB' , False)),
('set rlimit as <= 2047 MB,' , exp(False, False, False, '' , 'as' , '2047 MB' , False)), ('set rlimit as <= 2047 MB,' , exp(False, False, False, '' , 'as' , '2047 MB' , False)),
@ -64,7 +64,7 @@ class RlimitTestParse(RlimitTest):
('set rlimit rss <= infinity, # cmt' , exp(False, False, False, ' # cmt' , 'rss' , None , True )), ('set rlimit rss <= infinity, # cmt' , exp(False, False, False, ' # cmt' , 'rss' , None , True )),
('set rlimit memlock <= 10240,' , exp(False, False, False, '' , 'memlock' , '10240' , False)), ('set rlimit memlock <= 10240,' , exp(False, False, False, '' , 'memlock' , '10240' , False)),
('set rlimit sigpending <= 42,' , exp(False, False, False, '' , 'sigpending' , '42' , False)), ('set rlimit sigpending <= 42,' , exp(False, False, False, '' , 'sigpending' , '42' , False)),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(RlimitRule.match(rawrule)) self.assertTrue(RlimitRule.match(rawrule))
@ -73,7 +73,7 @@ class RlimitTestParse(RlimitTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class RlimitTestParseInvalid(RlimitTest): class RlimitTestParseInvalid(RlimitTest):
tests = [ tests = (
('set rlimit,' , AppArmorException), # missing parts ('set rlimit,' , AppArmorException), # missing parts
('set rlimit <= 5,' , AppArmorException), ('set rlimit <= 5,' , AppArmorException),
('set rlimit cpu <= ,' , AppArmorException), ('set rlimit cpu <= ,' , AppArmorException),
@ -86,7 +86,7 @@ class RlimitTestParseInvalid(RlimitTest):
('set rlimit cpu <= 20MB,' , AppArmorException), ('set rlimit cpu <= 20MB,' , AppArmorException),
('set rlimit data <= 20seconds,' , AppArmorException), ('set rlimit data <= 20seconds,' , AppArmorException),
('set rlimit locks <= 20seconds,' , AppArmorException), ('set rlimit locks <= 20seconds,' , AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
#self.assertFalse(RlimitRule.match(rawrule)) # the main regex isn't very strict #self.assertFalse(RlimitRule.match(rawrule)) # the main regex isn't very strict
@ -117,7 +117,7 @@ class RlimitTestParseFromLog(RlimitTest):
class RlimitFromInit(RlimitTest): class RlimitFromInit(RlimitTest):
tests = [ tests = (
# RlimitRule object audit allow deny comment rlimit value all/infinity? # RlimitRule object audit allow deny comment rlimit value all/infinity?
(RlimitRule('as', '2047MB') , exp(False, False, False, '' , 'as' , '2047MB' , False)), (RlimitRule('as', '2047MB') , exp(False, False, False, '' , 'as' , '2047MB' , False)),
(RlimitRule('as', '2047 MB') , exp(False, False, False, '' , 'as' , '2047 MB' , False)), (RlimitRule('as', '2047 MB') , exp(False, False, False, '' , 'as' , '2047 MB' , False)),
@ -125,30 +125,30 @@ class RlimitFromInit(RlimitTest):
(RlimitRule('rttime', '60minutes') , exp(False, False, False, '' , 'rttime' , '60minutes', False)), (RlimitRule('rttime', '60minutes') , exp(False, False, False, '' , 'rttime' , '60minutes', False)),
(RlimitRule('nice', '-10') , exp(False, False, False, '' , 'nice' , '-10' , False)), (RlimitRule('nice', '-10') , exp(False, False, False, '' , 'nice' , '-10' , False)),
(RlimitRule('rss', RlimitRule.ALL) , exp(False, False, False, '' , 'rss' , None , True )), (RlimitRule('rss', RlimitRule.ALL) , exp(False, False, False, '' , 'rss' , None , True )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidRlimitInit(AATest): class InvalidRlimitInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
(['as' , '' ] , AppArmorBug), # empty value (('as' , '' ) , AppArmorBug), # empty value
(['' , '1024' ] , AppArmorException), # empty rlimit (('' , '1024' ) , AppArmorException), # empty rlimit
([' ', '1024' ] , AppArmorException), # whitespace rlimit ((' ', '1024' ) , AppArmorException), # whitespace rlimit
(['as' , ' ' ] , AppArmorBug), # whitespace value (('as' , ' ' ) , AppArmorBug), # whitespace value
(['xyxy', '1024' ] , AppArmorException), # invalid rlimit (('xyxy', '1024' ) , AppArmorException), # invalid rlimit
([dict(), '1024' ] , AppArmorBug), # wrong type for rlimit ((dict(), '1024' ) , AppArmorBug), # wrong type for rlimit
([None , '1024' ] , AppArmorBug), # wrong type for rlimit ((None , '1024' ) , AppArmorBug), # wrong type for rlimit
(['as' , dict() ] , AppArmorBug), # wrong type for value (('as' , dict() ) , AppArmorBug), # wrong type for value
(['as' , None ] , AppArmorBug), # wrong type for value (('as' , None ) , AppArmorBug), # wrong type for value
(['cpu' , '100xy2' ] , AppArmorException), # invalid unit (('cpu' , '100xy2' ) , AppArmorException), # invalid unit
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
RlimitRule(params[0], params[1]) RlimitRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -202,7 +202,7 @@ class InvalidRlimitTest(AATest):
class WriteRlimitTest(AATest): class WriteRlimitTest(AATest):
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' set rlimit cpu <= 1024 , # foo ' , 'set rlimit cpu <= 1024, # foo'), (' set rlimit cpu <= 1024 , # foo ' , 'set rlimit cpu <= 1024, # foo'),
(' set rlimit stack <= 1024GB ,' , 'set rlimit stack <= 1024GB,'), (' set rlimit stack <= 1024GB ,' , 'set rlimit stack <= 1024GB,'),
@ -211,7 +211,7 @@ class WriteRlimitTest(AATest):
(' set rlimit msgqueue <= 4444 , ' , 'set rlimit msgqueue <= 4444,'), (' set rlimit msgqueue <= 4444 , ' , 'set rlimit msgqueue <= 4444,'),
(' set rlimit nice <= 5 , # foo bar' , 'set rlimit nice <= 5, # foo bar'), (' set rlimit nice <= 5 , # foo bar' , 'set rlimit nice <= 5, # foo bar'),
(' set rlimit nice <= -5 , # cmt' , 'set rlimit nice <= -5, # cmt'), (' set rlimit nice <= -5 , # cmt' , 'set rlimit nice <= -5, # cmt'),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(RlimitRule.match(rawrule)) self.assertTrue(RlimitRule.match(rawrule))
@ -247,73 +247,73 @@ class RlimitCoveredTest(AATest):
class RlimitCoveredTest_01(RlimitCoveredTest): class RlimitCoveredTest_01(RlimitCoveredTest):
rule = 'set rlimit cpu <= 150,' rule = 'set rlimit cpu <= 150,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('set rlimit as <= 100MB,' , [ False , False , False , False ]), ('set rlimit as <= 100MB,' , ( False , False , False , False )),
('set rlimit rttime <= 150,' , [ False , False , False , False ]), ('set rlimit rttime <= 150,' , ( False , False , False , False )),
('set rlimit cpu <= 100,' , [ False , False , True , True ]), ('set rlimit cpu <= 100,' , ( False , False , True , True )),
('set rlimit cpu <= 150,' , [ True , True , True , True ]), ('set rlimit cpu <= 150,' , ( True , True , True , True )),
('set rlimit cpu <= 300,' , [ False , False , False , False ]), ('set rlimit cpu <= 300,' , ( False , False , False , False )),
('set rlimit cpu <= 10seconds,' , [ False , False , True , True ]), ('set rlimit cpu <= 10seconds,' , ( False , False , True , True )),
('set rlimit cpu <= 150seconds,', [ True , False , True , True ]), ('set rlimit cpu <= 150seconds,', ( True , False , True , True )),
('set rlimit cpu <= 300seconds,', [ False , False , False , False ]), ('set rlimit cpu <= 300seconds,', ( False , False , False , False )),
('set rlimit cpu <= 1minutes,' , [ False , False , True , True ]), ('set rlimit cpu <= 1minutes,' , ( False , False , True , True )),
('set rlimit cpu <= 1min,' , [ False , False , True , True ]), ('set rlimit cpu <= 1min,' , ( False , False , True , True )),
('set rlimit cpu <= 3minutes,' , [ False , False , False , False ]), ('set rlimit cpu <= 3minutes,' , ( False , False , False , False )),
('set rlimit cpu <= 1hour,' , [ False , False , False , False ]), ('set rlimit cpu <= 1hour,' , ( False , False , False , False )),
('set rlimit cpu <= 2 days,' , [ False , False , False , False ]), ('set rlimit cpu <= 2 days,' , ( False , False , False , False )),
('set rlimit cpu <= 1 week,' , [ False , False , False , False ]), ('set rlimit cpu <= 1 week,' , ( False , False , False , False )),
] )
class RlimitCoveredTest_02(RlimitCoveredTest): class RlimitCoveredTest_02(RlimitCoveredTest):
rule = 'set rlimit data <= 4MB,' rule = 'set rlimit data <= 4MB,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('set rlimit data <= 100,' , [ False , False , True , True ]), ('set rlimit data <= 100,' , ( False , False , True , True )),
('set rlimit data <= 2KB,' , [ False , False , True , True ]), ('set rlimit data <= 2KB,' , ( False , False , True , True )),
('set rlimit data <= 2MB,' , [ False , False , True , True ]), ('set rlimit data <= 2MB,' , ( False , False , True , True )),
('set rlimit data <= 4194304,' , [ True , False , True , True ]), ('set rlimit data <= 4194304,' , ( True , False , True , True )),
('set rlimit data <= 4096KB,' , [ True , False , True , True ]), ('set rlimit data <= 4096KB,' , ( True , False , True , True )),
('set rlimit data <= 4MB,' , [ True , True , True , True ]), ('set rlimit data <= 4MB,' , ( True , True , True , True )),
('set rlimit data <= 4 MB,' , [ True , False , True , True ]), ('set rlimit data <= 4 MB,' , ( True , False , True , True )),
('set rlimit data <= 6MB,' , [ False , False , False , False ]), ('set rlimit data <= 6MB,' , ( False , False , False , False )),
('set rlimit data <= 6 MB,' , [ False , False , False , False ]), ('set rlimit data <= 6 MB,' , ( False , False , False , False )),
('set rlimit data <= 1GB,' , [ False , False , False , False ]), ('set rlimit data <= 1GB,' , ( False , False , False , False )),
] )
class RlimitCoveredTest_03(RlimitCoveredTest): class RlimitCoveredTest_03(RlimitCoveredTest):
rule = 'set rlimit nice <= -1,' rule = 'set rlimit nice <= -1,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('set rlimit nice <= 5,' , [ False , False , True , True ]), ('set rlimit nice <= 5,' , ( False , False , True , True )),
('set rlimit nice <= 0,' , [ False , False , True , True ]), ('set rlimit nice <= 0,' , ( False , False , True , True )),
('set rlimit nice <= -1,' , [ True , True , True , True ]), ('set rlimit nice <= -1,' , ( True , True , True , True )),
('set rlimit nice <= -3,' , [ False , False , False , False ]), ('set rlimit nice <= -3,' , ( False , False , False , False )),
] )
class RlimitCoveredTest_04(RlimitCoveredTest): class RlimitCoveredTest_04(RlimitCoveredTest):
rule = 'set rlimit locks <= 42,' rule = 'set rlimit locks <= 42,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('set rlimit locks <= 20,' , [ False , False , True , True ]), ('set rlimit locks <= 20,' , ( False , False , True , True )),
('set rlimit locks <= 40,' , [ False , False , True , True ]), ('set rlimit locks <= 40,' , ( False , False , True , True )),
('set rlimit locks <= 42,' , [ True , True , True , True ]), ('set rlimit locks <= 42,' , ( True , True , True , True )),
('set rlimit locks <= 60,' , [ False , False , False , False ]), ('set rlimit locks <= 60,' , ( False , False , False , False )),
('set rlimit locks <= infinity,', [ False , False , False , False ]), ('set rlimit locks <= infinity,', ( False , False , False , False )),
] )
class RlimitCoveredTest_05(RlimitCoveredTest): class RlimitCoveredTest_05(RlimitCoveredTest):
rule = 'set rlimit locks <= infinity,' rule = 'set rlimit locks <= infinity,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('set rlimit locks <= 20,' , [ False , False , True , True ]), ('set rlimit locks <= 20,' , ( False , False , True , True )),
('set rlimit cpu <= 40,' , [ False , False , False , False ]), ('set rlimit cpu <= 40,' , ( False , False , False , False )),
('set rlimit locks <= infinity,', [ True , True , True , True ]), ('set rlimit locks <= infinity,', ( True , True , True , True )),
] )
class RlimitCoveredTest_Invalid(AATest): class RlimitCoveredTest_Invalid(AATest):
def test_borked_obj_is_covered_1(self): def test_borked_obj_is_covered_1(self):
@ -351,12 +351,12 @@ class RlimitCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class RlimitLogprofHeaderTest(AATest): class RlimitLogprofHeaderTest(AATest):
tests = [ tests = (
('set rlimit cpu <= infinity,', [_('Rlimit'), 'cpu', _('Value'), 'infinity', ]), ('set rlimit cpu <= infinity,', [_('Rlimit'), 'cpu', _('Value'), 'infinity', ]),
('set rlimit as <= 200MB,', [_('Rlimit'), 'as', _('Value'), '200MB', ]), ('set rlimit as <= 200MB,', [_('Rlimit'), 'as', _('Value'), '200MB', ]),
('set rlimit rttime <= 200ms,', [_('Rlimit'), 'rttime', _('Value'), '200ms', ]), ('set rlimit rttime <= 200ms,', [_('Rlimit'), 'rttime', _('Value'), '200ms', ]),
('set rlimit nproc <= 1,', [_('Rlimit'), 'nproc', _('Value'), '1', ]), ('set rlimit nproc <= 1,', [_('Rlimit'), 'nproc', _('Value'), '1', ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = RlimitRule.parse(params) obj = RlimitRule.parse(params)
@ -424,11 +424,11 @@ class RlimitDeleteTestAATest(AATest):
# --- other tests --- # # --- other tests --- #
class RlimitSplit_unitTest(AATest): class RlimitSplit_unitTest(AATest):
tests = [ tests = (
('40MB' , ( 40, 'MB',)), ('40MB' , ( 40, 'MB',)),
('40 MB' , ( 40, 'MB',)), ('40 MB' , ( 40, 'MB',)),
('40' , ( 40, '', )), ('40' , ( 40, '', )),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(split_unit(params), expected) self.assertEqual(split_unit(params), expected)
@ -441,12 +441,12 @@ class RlimitSize_to_intTest(AATest):
def AASetup(self): def AASetup(self):
self.obj = RlimitRule('cpu', '1') self.obj = RlimitRule('cpu', '1')
tests = [ tests = (
('40GB' , 40 * 1024 * 1024 * 1024), ('40GB' , 40 * 1024 * 1024 * 1024),
('40MB' , 41943040), ('40MB' , 41943040),
('40KB' , 40960), ('40KB' , 40960),
('40' , 40), ('40' , 40),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(self.obj.size_to_int(params), expected) self.assertEqual(self.obj.size_to_int(params), expected)
@ -459,7 +459,7 @@ class RlimitTime_to_intTest(AATest):
def AASetup(self): def AASetup(self):
self.obj = RlimitRule('cpu', '1') self.obj = RlimitRule('cpu', '1')
tests = [ tests = (
('40' , 0.00004), ('40' , 0.00004),
('30us' , 0.00003), ('30us' , 0.00003),
('40ms' , 0.04), ('40ms' , 0.04),
@ -468,7 +468,7 @@ class RlimitTime_to_intTest(AATest):
('2hours' , 2*60*60), ('2hours' , 2*60*60),
('1 day' , 1*60*60*24), ('1 day' , 1*60*60*24),
('2 weeks' , 2*60*60*24*7), ('2 weeks' , 2*60*60*24*7),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.assertEqual(self.obj.time_to_int(params, 'us'), expected) self.assertEqual(self.obj.time_to_int(params, 'us'), expected)

View file

@ -36,22 +36,22 @@ class SeverityBaseTest(AATest):
'expected rank %s, got %s' % (expected_rank, rank)) 'expected rank %s, got %s' % (expected_rank, rank))
class SeverityTest(SeverityBaseTest): class SeverityTest(SeverityBaseTest):
tests = [ tests = (
(['/usr/bin/whatis', 'x' ], 5), (('/usr/bin/whatis', 'x' ), 5),
(['/etc', 'x' ], 'unknown'), (('/etc', 'x' ), 'unknown'),
(['/dev/doublehit', 'x' ], 0), (('/dev/doublehit', 'x' ), 0),
(['/dev/doublehit', 'rx' ], 4), (('/dev/doublehit', 'rx' ), 4),
(['/dev/doublehit', 'rwx' ], 8), (('/dev/doublehit', 'rwx'), 8),
(['/dev/tty10', 'rwx' ], 9), (('/dev/tty10', 'rwx'), 9),
(['/var/adm/foo/**', 'rx' ], 3), (('/var/adm/foo/**', 'rx' ), 3),
(['/etc/apparmor/**', 'r' ], 6), (('/etc/apparmor/**', 'r' ), 6),
(['/etc/**', 'r' ], 'unknown'), (('/etc/**', 'r' ), 'unknown'),
(['/usr/foo@bar', 'r' ], 'unknown'), ## filename containing @ (('/usr/foo@bar', 'r' ), 'unknown'), ## filename containing @
(['/home/foo@bar', 'rw' ], 6), ## filename containing @ (('/home/foo@bar', 'rw' ), 6), ## filename containing @
(['/etc/apache2/ssl.key/bar', 'r' ], 7), # /etc/apache2/** (3) vs. /etc/apache2/**ssl** (7) (('/etc/apache2/ssl.key/bar', 'r' ), 7), # /etc/apache2/** (3) vs. /etc/apache2/**ssl** (7)
(['/etc/apache2/foo/ssl/bar', 'r' ], 7), # additional path level triggers otherwise untested branch (('/etc/apache2/foo/ssl/bar', 'r' ), 7), # additional path level triggers otherwise untested branch
(['/proc/sys/kernel/hotplug', 'rwx' ], 10), # non-glob filename, severity depends on mode (('/proc/sys/kernel/hotplug', 'rwx'), 10), # non-glob filename, severity depends on mode
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self._simple_severity_w_perm(params[0], params[1], expected) ## filename containing @ self._simple_severity_w_perm(params[0], params[1], expected) ## filename containing @
@ -61,14 +61,14 @@ class SeverityTest(SeverityBaseTest):
self._simple_severity_w_perm('unexpected_unput', 'rw', 6) self._simple_severity_w_perm('unexpected_unput', 'rw', 6)
class SeverityTestCap(SeverityBaseTest): class SeverityTestCap(SeverityBaseTest):
tests = [ tests = (
('KILL', 8), ('KILL', 8),
('SETPCAP', 9), ('SETPCAP', 9),
('setpcap', 9), ('setpcap', 9),
('UNKNOWN', 'unknown'), ('UNKNOWN', 'unknown'),
('K*', 'unknown'), ('K*', 'unknown'),
('__ALL__', 10), ('__ALL__', 10),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self._capability_severity_test(params, expected) self._capability_severity_test(params, expected)
@ -78,14 +78,14 @@ class SeverityTestCap(SeverityBaseTest):
class SeverityVarsTest(SeverityBaseTest): class SeverityVarsTest(SeverityBaseTest):
tests = [ tests = (
(['@{PROC}/sys/vm/overcommit_memory', 'r'], 6), (('@{PROC}/sys/vm/overcommit_memory', 'r'), 6),
(['@{HOME}/sys/@{PROC}/overcommit_memory', 'r'], 4), (('@{HOME}/sys/@{PROC}/overcommit_memory', 'r'), 4),
(['/overco@{multiarch}mmit_memory', 'r'], 'unknown'), (('/overco@{multiarch}mmit_memory', 'r'), 'unknown'),
(['@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r'], 6), (('@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r'), 6),
(['@{somepaths}/somefile', 'r'], 7), (('@{somepaths}/somefile', 'r'), 7),
(['@{strangevar}/somefile', 'r'], 6), (('@{strangevar}/somefile', 'r'), 6),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
vars = { vars = {
@ -107,7 +107,7 @@ class SeverityDBTest(AATest):
self.sev_db = severity.Severity(self.db_file) self.sev_db = severity.Severity(self.db_file)
return self.sev_db return self.sev_db
tests = [ tests = (
("CAP_LEASE 18\n" , AppArmorException), # out of range ("CAP_LEASE 18\n" , AppArmorException), # out of range
("CAP_LEASE -1\n" , AppArmorException), # out of range ("CAP_LEASE -1\n" , AppArmorException), # out of range
("/etc/passwd* 0 4\n" , AppArmorException), # insufficient vals ("/etc/passwd* 0 4\n" , AppArmorException), # insufficient vals
@ -119,7 +119,7 @@ class SeverityDBTest(AATest):
("/etc/passwd 2 4 -12\n" , AppArmorException), # out of range ("/etc/passwd 2 4 -12\n" , AppArmorException), # out of range
("/etc/passwd 2 4 4294967297\n" , AppArmorException), # out of range ("/etc/passwd 2 4 4294967297\n" , AppArmorException), # out of range
("garbage line\n" , AppArmorException), ("garbage line\n" , AppArmorException),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):

View file

@ -46,7 +46,7 @@ class SignalTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class SignalTestParse(SignalTest): class SignalTestParse(SignalTest):
tests = [ tests = (
# SignalRule object audit allow deny comment access all? signal all? peer all? # SignalRule object audit allow deny comment access all? signal all? peer all?
('signal,' , exp(False, False, False, '', None , True , None, True, None, True )), ('signal,' , exp(False, False, False, '', None , True , None, True, None, True )),
('signal send,' , exp(False, False, False, '', {'send'}, False, None, True, None, True )), ('signal send,' , exp(False, False, False, '', {'send'}, False, None, True, None, True )),
@ -61,7 +61,7 @@ class SignalTestParse(SignalTest):
('signal send set = ( quit , int ) ,' , exp(False, False, False, '', {'send'}, False, {'quit', 'int'}, False, None, True )), ('signal send set = ( quit , int ) ,' , exp(False, False, False, '', {'send'}, False, {'quit', 'int'}, False, None, True )),
('signal peer=/foo,' , exp(False, False, False, '', None , True , None, True, '/foo', False )), ('signal peer=/foo,' , exp(False, False, False, '', None , True , None, True, '/foo', False )),
('signal r set=quit set=int peer=/foo,' , exp(False, False, False, '', {'r'}, False, {'quit', 'int'}, False, '/foo', False )), ('signal r set=quit set=int peer=/foo,' , exp(False, False, False, '', {'r'}, False, {'quit', 'int'}, False, '/foo', False )),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(SignalRule.match(rawrule)) self.assertTrue(SignalRule.match(rawrule))
@ -70,7 +70,7 @@ class SignalTestParse(SignalTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class SignalTestParseInvalid(SignalTest): class SignalTestParseInvalid(SignalTest):
tests = [ tests = (
('signal foo,' , AppArmorException), ('signal foo,' , AppArmorException),
('signal foo bar,' , AppArmorException), ('signal foo bar,' , AppArmorException),
('signal foo int,' , AppArmorException), ('signal foo int,' , AppArmorException),
@ -80,7 +80,7 @@ class SignalTestParseInvalid(SignalTest):
('signal set=int set=,' , AppArmorException), ('signal set=int set=,' , AppArmorException),
('signal set=invalid,' , AppArmorException), ('signal set=invalid,' , AppArmorException),
('signal peer=,' , AppArmorException), ('signal peer=,' , AppArmorException),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(SignalRule.match(rawrule)) # the above invalid rules still match the main regex! self.assertTrue(SignalRule.match(rawrule)) # the above invalid rules still match the main regex!
@ -129,7 +129,7 @@ class SignalTestParseFromLog(SignalTest):
self.assertEqual(obj.get_raw(1), ' signal send set=term peer=/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper,') self.assertEqual(obj.get_raw(1), ' signal send set=term peer=/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper,')
class SignalFromInit(SignalTest): class SignalFromInit(SignalTest):
tests = [ tests = (
# SignalRule object audit allow deny comment access all? signal all? peer all? # SignalRule object audit allow deny comment access all? signal all? peer all?
(SignalRule('r', 'hup', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, {'hup'}, False, 'unconfined', False)), (SignalRule('r', 'hup', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, {'hup'}, False, 'unconfined', False)),
(SignalRule(('r', 'send'), ('hup', 'int'), '/bin/foo') , exp(False, False, False, '' , {'r', 'send'},False, {'hup', 'int'}, False, '/bin/foo', False)), (SignalRule(('r', 'send'), ('hup', 'int'), '/bin/foo') , exp(False, False, False, '' , {'r', 'send'},False, {'hup', 'int'}, False, '/bin/foo', False)),
@ -137,34 +137,34 @@ class SignalFromInit(SignalTest):
(SignalRule('rw', SignalRule.ALL, '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, None, True, '/bin/foo', False )), (SignalRule('rw', SignalRule.ALL, '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, None, True, '/bin/foo', False )),
(SignalRule('rw', ('int'), SignalRule.ALL) , exp(False, False, False, '' , {'rw'}, False, {'int'}, False, None, True )), (SignalRule('rw', ('int'), SignalRule.ALL) , exp(False, False, False, '' , {'rw'}, False, {'int'}, False, None, True )),
(SignalRule(SignalRule.ALL, SignalRule.ALL, SignalRule.ALL) , exp(False, False, False, '' , None , True, None, True, None, True )), (SignalRule(SignalRule.ALL, SignalRule.ALL, SignalRule.ALL) , exp(False, False, False, '' , None , True, None, True, None, True )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidSignalInit(AATest): class InvalidSignalInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
(['send', '' , '/foo' ] , AppArmorBug), # empty signal (('send', '' , '/foo' ) , AppArmorBug), # empty signal
(['' , 'int' , '/foo' ] , AppArmorBug), # empty access (('' , 'int' , '/foo' ) , AppArmorBug), # empty access
(['send', 'int' , '' ] , AppArmorBug), # empty peer (('send', 'int' , '' ) , AppArmorBug), # empty peer
([' ', 'int' , '/foo' ] , AppArmorBug), # whitespace access ((' ', 'int' , '/foo' ) , AppArmorBug), # whitespace access
(['send', ' ' , '/foo' ] , AppArmorBug), # whitespace signal (('send', ' ' , '/foo' ) , AppArmorBug), # whitespace signal
(['send', 'int' , ' ' ] , AppArmorBug), # whitespace peer (('send', 'int' , ' ' ) , AppArmorBug), # whitespace peer
(['xyxy', 'int' , '/foo' ] , AppArmorException), # invalid access (('xyxy', 'int' , '/foo' ) , AppArmorException), # invalid access
(['send', 'xyxy', '/foo' ] , AppArmorException), # invalid signal (('send', 'xyxy', '/foo' ) , AppArmorException), # invalid signal
# XXX is 'invalid peer' possible at all? # XXX is 'invalid peer' possible at all?
([dict(), 'int' , '/foo' ] , AppArmorBug), # wrong type for access ((dict(), 'int' , '/foo' ) , AppArmorBug), # wrong type for access
([None , 'int' , '/foo' ] , AppArmorBug), # wrong type for access ((None , 'int' , '/foo' ) , AppArmorBug), # wrong type for access
(['send', dict(), '/foo' ] , AppArmorBug), # wrong type for signal (('send', dict(), '/foo' ) , AppArmorBug), # wrong type for signal
(['send', None , '/foo' ] , AppArmorBug), # wrong type for signal (('send', None , '/foo' ) , AppArmorBug), # wrong type for signal
(['send', 'int' , dict() ] , AppArmorBug), # wrong type for peer (('send', 'int' , dict() ) , AppArmorBug), # wrong type for peer
(['send', 'int' , None ] , AppArmorBug), # wrong type for peer (('send', 'int' , None ) , AppArmorBug), # wrong type for peer
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
SignalRule(params[0], params[1], params[2]) SignalRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -225,7 +225,7 @@ class WriteSignalTestAATest(AATest):
self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(expected.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' signal , # foo ' , 'signal, # foo'), (' signal , # foo ' , 'signal, # foo'),
(' audit signal send,' , 'audit signal send,'), (' audit signal send,' , 'audit signal send,'),
@ -250,7 +250,7 @@ class WriteSignalTestAATest(AATest):
('signal receive peer=foo,' , 'signal receive peer=foo,'), ('signal receive peer=foo,' , 'signal receive peer=foo,'),
('signal (send receive) peer=/usr/bin/bar,' , 'signal (receive send) peer=/usr/bin/bar,'), ('signal (send receive) peer=/usr/bin/bar,' , 'signal (receive send) peer=/usr/bin/bar,'),
('signal wr set=(pipe, usr1) peer=/sbin/baz,' , 'signal wr set=(pipe usr1) peer=/sbin/baz,'), ('signal wr set=(pipe, usr1) peer=/sbin/baz,' , 'signal wr set=(pipe usr1) peer=/sbin/baz,'),
] )
def test_write_manually(self): def test_write_manually(self):
obj = SignalRule('send', 'quit', '/foo', allow_keyword=True) obj = SignalRule('send', 'quit', '/foo', allow_keyword=True)
@ -277,197 +277,197 @@ class SignalCoveredTest(AATest):
class SignalCoveredTest_01(SignalCoveredTest): class SignalCoveredTest_01(SignalCoveredTest):
rule = 'signal send,' rule = 'signal send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('signal,' , [ False , False , False , False ]), ('signal,' , ( False , False , False , False )),
('signal send,' , [ True , True , True , True ]), ('signal send,' , ( True , True , True , True )),
('signal send peer=unconfined,' , [ False , False , True , True ]), ('signal send peer=unconfined,' , ( False , False , True , True )),
('signal send, # comment' , [ True , False , True , True ]), ('signal send, # comment' , ( True , False , True , True )),
('allow signal send,' , [ True , False , True , True ]), ('allow signal send,' , ( True , False , True , True )),
('signal send,' , [ True , False , True , True ]), ('signal send,' , ( True , False , True , True )),
('signal send set=quit,' , [ False , False , True , True ]), ('signal send set=quit,' , ( False , False , True , True )),
('signal send set=int,' , [ False , False , True , True ]), ('signal send set=int,' , ( False , False , True , True )),
('audit signal send,' , [ False , False , False , False ]), ('audit signal send,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
('signal set=int,' , [ False , False , False , False ]), ('signal set=int,' , ( False , False , False , False )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
('deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , ( False , False , False , False )),
] )
class SignalCoveredTest_02(SignalCoveredTest): class SignalCoveredTest_02(SignalCoveredTest):
rule = 'audit signal send,' rule = 'audit signal send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'signal send,' , [ False , False , True , False ]), ( 'signal send,' , ( False , False , True , False )),
('audit signal send,' , [ True , True , True , True ]), ('audit signal send,' , ( True , True , True , True )),
( 'signal send set=quit,' , [ False , False , True , False ]), ( 'signal send set=quit,' , ( False , False , True , False )),
('audit signal send set=quit,' , [ False , False , True , True ]), ('audit signal send set=quit,' , ( False , False , True , True )),
( 'signal,' , [ False , False , False , False ]), ( 'signal,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
] )
class SignalCoveredTest_03(SignalCoveredTest): class SignalCoveredTest_03(SignalCoveredTest):
rule = 'signal send set=quit,' rule = 'signal send set=quit,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'signal send set=quit,' , [ True , True , True , True ]), ( 'signal send set=quit,' , ( True , True , True , True )),
('allow signal send set=quit,' , [ True , False , True , True ]), ('allow signal send set=quit,' , ( True , False , True , True )),
( 'signal send,' , [ False , False , False , False ]), ( 'signal send,' , ( False , False , False , False )),
( 'signal,' , [ False , False , False , False ]), ( 'signal,' , ( False , False , False , False )),
( 'signal send set=int,' , [ False , False , False , False ]), ( 'signal send set=int,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('audit signal send set=quit,' , [ False , False , False , False ]), ('audit signal send set=quit,' , ( False , False , False , False )),
('audit signal set=quit,' , [ False , False , False , False ]), ('audit signal set=quit,' , ( False , False , False , False )),
( 'signal send,' , [ False , False , False , False ]), ( 'signal send,' , ( False , False , False , False )),
( 'signal,' , [ False , False , False , False ]), ( 'signal,' , ( False , False , False , False )),
] )
class SignalCoveredTest_04(SignalCoveredTest): class SignalCoveredTest_04(SignalCoveredTest):
rule = 'signal,' rule = 'signal,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'signal,' , [ True , True , True , True ]), ( 'signal,' , ( True , True , True , True )),
('allow signal,' , [ True , False , True , True ]), ('allow signal,' , ( True , False , True , True )),
( 'signal send,' , [ False , False , True , True ]), ( 'signal send,' , ( False , False , True , True )),
( 'signal w set=quit,' , [ False , False , True , True ]), ( 'signal w set=quit,' , ( False , False , True , True )),
( 'signal set=int,' , [ False , False , True , True ]), ( 'signal set=int,' , ( False , False , True , True )),
( 'signal send set=quit,' , [ False , False , True , True ]), ( 'signal send set=quit,' , ( False , False , True , True )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('deny signal,' , [ False , False , False , False ]), ('deny signal,' , ( False , False , False , False )),
] )
class SignalCoveredTest_05(SignalCoveredTest): class SignalCoveredTest_05(SignalCoveredTest):
rule = 'deny signal send,' rule = 'deny signal send,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
( 'deny signal send,' , [ True , True , True , True ]), ( 'deny signal send,' , ( True , True , True , True )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
( 'signal send,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'signal send,' , ( False , False , False , False )), # XXX should covered be true here?
( 'deny signal receive,' , [ False , False , False , False ]), ( 'deny signal receive,' , ( False , False , False , False )),
( 'deny signal,' , [ False , False , False , False ]), ( 'deny signal,' , ( False , False , False , False )),
] )
class SignalCoveredTest_06(SignalCoveredTest): class SignalCoveredTest_06(SignalCoveredTest):
rule = 'signal send peer=unconfined,' rule = 'signal send peer=unconfined,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('signal,' , [ False , False , False , False ]), ('signal,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=unconfined,' , [ True , True , True , True ]), ('signal send peer=unconfined,' , ( True , True , True , True )),
('signal peer=unconfined,' , [ False , False , False , False ]), ('signal peer=unconfined,' , ( False , False , False , False )),
('signal send, # comment' , [ False , False , False , False ]), ('signal send, # comment' , ( False , False , False , False )),
('allow signal send,' , [ False , False , False , False ]), ('allow signal send,' , ( False , False , False , False )),
('allow signal send peer=unconfined,' , [ True , False , True , True ]), ('allow signal send peer=unconfined,' , ( True , False , True , True )),
('allow signal send peer=/foo/bar,' , [ False , False , False , False ]), ('allow signal send peer=/foo/bar,' , ( False , False , False , False )),
('allow signal send peer=/**,' , [ False , False , False , False ]), ('allow signal send peer=/**,' , ( False , False , False , False )),
('allow signal send peer=**,' , [ False , False , False , False ]), ('allow signal send peer=**,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=unconfined,' , [ True , False , True , True ]), ('signal send peer=unconfined,' , ( True , False , True , True )),
('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=quit,' , ( False , False , False , False )),
('signal send set=int peer=unconfined,',[ False , False , True , True ]), ('signal send set=int peer=unconfined,',( False , False , True , True )),
('audit signal send peer=unconfined,' , [ False , False , False , False ]), ('audit signal send peer=unconfined,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
('signal set=int,' , [ False , False , False , False ]), ('signal set=int,' , ( False , False , False , False )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
('deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , ( False , False , False , False )),
] )
class SignalCoveredTest_07(SignalCoveredTest): class SignalCoveredTest_07(SignalCoveredTest):
rule = 'signal send peer=/foo/bar,' rule = 'signal send peer=/foo/bar,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('signal,' , [ False , False , False , False ]), ('signal,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=/foo/bar,' , [ True , True , True , True ]), ('signal send peer=/foo/bar,' , ( True , True , True , True )),
('signal send peer=/foo/*,' , [ False , False , False , False ]), ('signal send peer=/foo/*,' , ( False , False , False , False )),
('signal send peer=/**,' , [ False , False , False , False ]), ('signal send peer=/**,' , ( False , False , False , False )),
('signal send peer=/what/*,' , [ False , False , False , False ]), ('signal send peer=/what/*,' , ( False , False , False , False )),
('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal peer=/foo/bar,' , ( False , False , False , False )),
('signal send, # comment' , [ False , False , False , False ]), ('signal send, # comment' , ( False , False , False , False )),
('allow signal send,' , [ False , False , False , False ]), ('allow signal send,' , ( False , False , False , False )),
('allow signal send peer=/foo/bar,' , [ True , False , True , True ]), ('allow signal send peer=/foo/bar,' , ( True , False , True , True )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=/foo/bar,' , [ True , False , True , True ]), ('signal send peer=/foo/bar,' , ( True , False , True , True )),
('signal send peer=/what/ever,' , [ False , False , False , False ]), ('signal send peer=/what/ever,' , ( False , False , False , False )),
('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=quit,' , ( False , False , False , False )),
('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('signal send set=int peer=/foo/bar,' , ( False , False , True , True )),
('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal send peer=/foo/bar,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
('signal set=int,' , [ False , False , False , False ]), ('signal set=int,' , ( False , False , False , False )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
('deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , ( False , False , False , False )),
] )
class SignalCoveredTest_08(SignalCoveredTest): class SignalCoveredTest_08(SignalCoveredTest):
rule = 'signal send peer=**,' rule = 'signal send peer=**,'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('signal,' , [ False , False , False , False ]), ('signal,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=/foo/bar,' , [ False , False , True , True ]), ('signal send peer=/foo/bar,' , ( False , False , True , True )),
('signal send peer=/foo/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('signal send peer=/foo/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('signal send peer=/**,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('signal send peer=/**,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('signal send peer=/what/*,' , [ False , False , False , False ]), # TODO: wildcard vs. wildcard never matches in is_covered_aare() ('signal send peer=/what/*,' , ( False , False , False , False )), # TODO: wildcard vs. wildcard never matches in is_covered_aare()
('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal peer=/foo/bar,' , ( False , False , False , False )),
('signal send, # comment' , [ False , False , False , False ]), ('signal send, # comment' , ( False , False , False , False )),
('allow signal send,' , [ False , False , False , False ]), ('allow signal send,' , ( False , False , False , False )),
('allow signal send peer=/foo/bar,' , [ False , False , True , True ]), ('allow signal send peer=/foo/bar,' , ( False , False , True , True )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=/foo/bar,' , [ False , False , True , True ]), ('signal send peer=/foo/bar,' , ( False , False , True , True )),
('signal send peer=/what/ever,' , [ False , False , True , True ]), ('signal send peer=/what/ever,' , ( False , False , True , True )),
('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=quit,' , ( False , False , False , False )),
('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('signal send set=int peer=/foo/bar,' , ( False , False , True , True )),
('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal send peer=/foo/bar,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
('signal set=int,' , [ False , False , False , False ]), ('signal set=int,' , ( False , False , False , False )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
('deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , ( False , False , False , False )),
] )
class SignalCoveredTest_09(SignalCoveredTest): class SignalCoveredTest_09(SignalCoveredTest):
rule = 'signal (send, receive) set=(int, quit),' rule = 'signal (send, receive) set=(int, quit),'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
('signal,' , [ False , False , False , False ]), ('signal,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send set=int,' , [ False , False , True , True ]), ('signal send set=int,' , ( False , False , True , True )),
('signal receive set=quit,' , [ False , False , True , True ]), ('signal receive set=quit,' , ( False , False , True , True )),
('signal (receive,send) set=int,' , [ False , False , True , True ]), ('signal (receive,send) set=int,' , ( False , False , True , True )),
('signal (receive,send) set=(int quit),',[True , False , True , True ]), ('signal (receive,send) set=(int quit),',(True , False , True , True )),
('signal send set=(quit int),' , [ False , False , True , True ]), ('signal send set=(quit int),' , ( False , False , True , True )),
('signal send peer=/foo/bar,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , ( False , False , False , False )),
('signal send peer=/foo/*,' , [ False , False , False , False ]), ('signal send peer=/foo/*,' , ( False , False , False , False )),
('signal send peer=/**,' , [ False , False , False , False ]), ('signal send peer=/**,' , ( False , False , False , False )),
('signal send peer=/what/*,' , [ False , False , False , False ]), ('signal send peer=/what/*,' , ( False , False , False , False )),
('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal peer=/foo/bar,' , ( False , False , False , False )),
('signal send, # comment' , [ False , False , False , False ]), ('signal send, # comment' , ( False , False , False , False )),
('allow signal send,' , [ False , False , False , False ]), ('allow signal send,' , ( False , False , False , False )),
('allow signal send peer=/foo/bar,' , [ False , False , False , False ]), ('allow signal send peer=/foo/bar,' , ( False , False , False , False )),
('signal send,' , [ False , False , False , False ]), ('signal send,' , ( False , False , False , False )),
('signal send peer=/foo/bar,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , ( False , False , False , False )),
('signal send peer=/what/ever,' , [ False , False , False , False ]), ('signal send peer=/what/ever,' , ( False , False , False , False )),
('signal send set=quit,' , [ False , False , True , True ]), ('signal send set=quit,' , ( False , False , True , True )),
('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('signal send set=int peer=/foo/bar,' , ( False , False , True , True )),
('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal send peer=/foo/bar,' , ( False , False , False , False )),
('audit signal,' , [ False , False , False , False ]), ('audit signal,' , ( False , False , False , False )),
('signal receive,' , [ False , False , False , False ]), ('signal receive,' , ( False , False , False , False )),
('signal set=int,' , [ False , False , False , False ]), ('signal set=int,' , ( False , False , False , False )),
('audit deny signal send,' , [ False , False , False , False ]), ('audit deny signal send,' , ( False , False , False , False )),
('deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , ( False , False , False , False )),
] )
@ -516,7 +516,7 @@ class SignalCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class SignalLogprofHeaderTest(AATest): class SignalLogprofHeaderTest(AATest):
tests = [ tests = (
('signal,', [ _('Access mode'), _('ALL'), _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('signal,', [ _('Access mode'), _('ALL'), _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]),
('signal send,', [ _('Access mode'), 'send', _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('signal send,', [ _('Access mode'), 'send', _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]),
('signal send set=quit,', [ _('Access mode'), 'send', _('Signal'), 'quit', _('Peer'), _('ALL'), ]), ('signal send set=quit,', [ _('Access mode'), 'send', _('Signal'), 'quit', _('Peer'), _('ALL'), ]),
@ -527,7 +527,7 @@ class SignalLogprofHeaderTest(AATest):
('signal set=(int, quit),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]), ('signal set=(int, quit),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]),
('signal set=( quit, int),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]), ('signal set=( quit, int),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]),
('signal (send, receive) set=( quit, int) peer=/foo,', [ _('Access mode'), 'receive send', _('Signal'), 'int quit', _('Peer'), '/foo', ]), ('signal (send, receive) set=( quit, int) peer=/foo,', [ _('Access mode'), 'receive send', _('Signal'), 'int quit', _('Peer'), '/foo', ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = SignalRule.parse(params) obj = SignalRule.parse(params)
@ -546,10 +546,10 @@ class SignalRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = SignalRuleset() ruleset = SignalRuleset()
rules = [ rules = (
'signal set=int,', 'signal set=int,',
'signal send,', 'signal send,',
] )
expected_raw = [ expected_raw = [
'signal set=int,', 'signal set=int,',
@ -571,11 +571,11 @@ class SignalRulesTest(AATest):
def test_ruleset_2(self): def test_ruleset_2(self):
ruleset = SignalRuleset() ruleset = SignalRuleset()
rules = [ rules = (
'signal send set=int,', 'signal send set=int,',
'allow signal send,', 'allow signal send,',
'deny signal set=quit, # example comment', 'deny signal set=quit, # example comment',
] )
expected_raw = [ expected_raw = [
' signal send set=int,', ' signal send set=int,',

View file

@ -20,24 +20,24 @@ from apparmor.ui import CMDS, get_translated_hotkey
class TestHotkeyConflicts(AATest): class TestHotkeyConflicts(AATest):
# check if there are any hotkey conflicts in one of the apparmor-utils translations # check if there are any hotkey conflicts in one of the apparmor-utils translations
tests = [ tests = (
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_ON (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_ON
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_OFF (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_OFF
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_ON (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_ON
(['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_OFF (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_OFF
(['CMD_SAVE_CHANGES', 'CMD_SAVE_SELECTED', 'CMD_VIEW_CHANGES', 'CMD_VIEW_CHANGES_CLEAN', 'CMD_ABORT'], True), # aa.py save_profiles() (('CMD_SAVE_CHANGES', 'CMD_SAVE_SELECTED', 'CMD_VIEW_CHANGES', 'CMD_VIEW_CHANGES_CLEAN', 'CMD_ABORT'), True), # aa.py save_profiles()
(['CMD_VIEW_PROFILE', 'CMD_USE_PROFILE', 'CMD_CREATE_PROFILE', 'CMD_ABORT'], True), # aa.py get_profile() (('CMD_VIEW_PROFILE', 'CMD_USE_PROFILE', 'CMD_CREATE_PROFILE', 'CMD_ABORT'), True), # aa.py get_profile()
(['CMD_ix', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_EXEC_IX_OFF', 'CMD_ux', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py build_x_functions() with exec_toggle (('CMD_ix', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_EXEC_IX_OFF', 'CMD_ux', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py build_x_functions() with exec_toggle
(['CMD_ix', 'CMD_cx', 'CMD_px', 'CMD_nx', 'CMD_ux', 'CMD_EXEC_IX_ON', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py build_x_functions() without exec_toggle (('CMD_ix', 'CMD_cx', 'CMD_px', 'CMD_nx', 'CMD_ux', 'CMD_EXEC_IX_ON', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py build_x_functions() without exec_toggle
(['CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py ask_addhat() (('CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py ask_addhat()
(['CMD_YES', 'CMD_NO', 'CMD_CANCEL'], True), # ui.py UI_YesNo() and UI_YesNoCancel (('CMD_YES', 'CMD_NO', 'CMD_CANCEL'), True), # ui.py UI_YesNo() and UI_YesNoCancel
(['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT', 'CMD_IGNORE_ENTRY'], True), # aa-mergeprof act() (('CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT', 'CMD_IGNORE_ENTRY'), True), # aa-mergeprof act()
(['CMD_ALLOW', 'CMD_ABORT'], True), # aa-mergeprof conflict_mode() (('CMD_ALLOW', 'CMD_ABORT'), True), # aa-mergeprof conflict_mode()
(['CMD_ADDSUBPROFILE', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa-mergeprof ask_the_questions() - new subprofile (('CMD_ADDSUBPROFILE', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa-mergeprof ask_the_questions() - new subprofile
(['CMD_ADDHAT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa-mergeprof ask_the_questions() - new hat (('CMD_ADDHAT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa-mergeprof ask_the_questions() - new hat
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
self.createTmpdir() self.createTmpdir()

View file

@ -18,7 +18,7 @@ class AAParseUnixTest(AAParseTest):
def setUp(self): def setUp(self):
self.parse_function = aa.parse_unix_rule self.parse_function = aa.parse_unix_rule
tests = [ tests = (
('unix,', 'unix base keyword'), ('unix,', 'unix base keyword'),
('unix r,', 'unix r rule'), ('unix r,', 'unix r rule'),
('unix w,', 'unix w rule'), ('unix w,', 'unix w rule'),
@ -32,7 +32,7 @@ class AAParseUnixTest(AAParseTest):
('unix (receive),', 'unix (receive) rule'), ('unix (receive),', 'unix (receive) rule'),
('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/.X11-unix/X[0-9]*"),', ('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/.X11-unix/X[0-9]*"),',
'complex unix rule'), 'complex unix rule'),
] )
setup_aa(aa) setup_aa(aa)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -23,8 +23,8 @@ from apparmor.common import AppArmorException, AppArmorBug
from apparmor.translations import init_translation from apparmor.translations import init_translation
_ = init_translation() _ = init_translation()
exp = namedtuple('exp', ['comment', exp = namedtuple('exp', ('comment',
'varname', 'mode', 'values']) 'varname', 'mode', 'values'))
# --- tests for single VariableRule --- # # --- tests for single VariableRule --- #
@ -41,7 +41,7 @@ class VariableTest(AATest):
self.assertEqual(expected.comment, obj.comment) self.assertEqual(expected.comment, obj.comment)
class AaTest_separate_vars(AATest): class AaTest_separate_vars(AATest):
tests = [ tests = (
('' , set() ), ('' , set() ),
(' ' , set() ), (' ' , set() ),
(' foo bar' , {'foo', 'bar' }), (' foo bar' , {'foo', 'bar' }),
@ -59,7 +59,7 @@ class AaTest_separate_vars(AATest):
('"" foo' , {'', 'foo' }), # empty value + 'foo' ('"" foo' , {'', 'foo' }), # empty value + 'foo'
('"" foo "bar"' , {'', 'foo', 'bar' }), # empty value + 'foo' + 'bar' (bar has superfluous quotes) ('"" foo "bar"' , {'', 'foo', 'bar' }), # empty value + 'foo' + 'bar' (bar has superfluous quotes)
('"bar"' , {'bar' }), # 'bar' with superfluous quotes ('"bar"' , {'bar' }), # 'bar' with superfluous quotes
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
if expected == AppArmorException: if expected == AppArmorException:
@ -70,7 +70,7 @@ class AaTest_separate_vars(AATest):
self.assertEqual(result, expected) self.assertEqual(result, expected)
class VariableTestParse(VariableTest): class VariableTestParse(VariableTest):
tests = [ tests = (
# rawrule comment varname mode values # rawrule comment varname mode values
('@{foo}=/bar', exp('', '@{foo}', '=', {'/bar'} )), ('@{foo}=/bar', exp('', '@{foo}', '=', {'/bar'} )),
('@{foo}+=/bar', exp('', '@{foo}', '+=', {'/bar'} )), ('@{foo}+=/bar', exp('', '@{foo}', '+=', {'/bar'} )),
@ -80,7 +80,7 @@ class VariableTestParse(VariableTest):
(' @{foo} += /bar # comment', exp(' # comment', '@{foo}', '+=', {'/bar'} )), (' @{foo} += /bar # comment', exp(' # comment', '@{foo}', '+=', {'/bar'} )),
('@{foo}=/bar /baz', exp('', '@{foo}', '=', {'/bar', '/baz'} )), ('@{foo}=/bar /baz', exp('', '@{foo}', '=', {'/bar', '/baz'} )),
('@{foo} = "/bar," # comment', exp(' # comment', '@{foo}', '=', {'/bar,'} )), # value with trailing comma, needs to be quoted ('@{foo} = "/bar," # comment', exp(' # comment', '@{foo}', '=', {'/bar,'} )), # value with trailing comma, needs to be quoted
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(VariableRule.match(rawrule)) self.assertTrue(VariableRule.match(rawrule))
@ -89,7 +89,7 @@ class VariableTestParse(VariableTest):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class VariableTestParseInvalid(VariableTest): class VariableTestParseInvalid(VariableTest):
tests = [ tests = (
# rawrule matches regex exception # rawrule matches regex exception
('@{foo} =', (False, AppArmorException)), ('@{foo} =', (False, AppArmorException)),
('@ {foo} = # comment', (False, AppArmorException)), ('@ {foo} = # comment', (False, AppArmorException)),
@ -99,7 +99,7 @@ class VariableTestParseInvalid(VariableTest):
('@{foo} = /foo, # comment', (True, AppArmorException)), # trailing comma ('@{foo} = /foo, # comment', (True, AppArmorException)), # trailing comma
('@{foo} = /foo, /bar', (True, AppArmorException)), # trailing comma in first value ('@{foo} = /foo, /bar', (True, AppArmorException)), # trailing comma in first value
('@{foo = /foo f', (True, AppArmorException)), # variable name broken, missing } ('@{foo = /foo f', (True, AppArmorException)), # variable name broken, missing }
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertEqual(VariableRule.match(rawrule), expected[0]) self.assertEqual(VariableRule.match(rawrule), expected[0])
@ -107,7 +107,7 @@ class VariableTestParseInvalid(VariableTest):
VariableRule.parse(rawrule) VariableRule.parse(rawrule)
class VariableFromInit(VariableTest): class VariableFromInit(VariableTest):
tests = [ tests = (
# VariableRule object comment varname mode values # VariableRule object comment varname mode values
(VariableRule('@{foo}', '=', {'/bar'}), exp('', '@{foo}', '=', {'/bar'} )), (VariableRule('@{foo}', '=', {'/bar'}), exp('', '@{foo}', '=', {'/bar'} )),
(VariableRule('@{foo}', '+=', {'/bar'}), exp('', '@{foo}', '+=', {'/bar'} )), (VariableRule('@{foo}', '+=', {'/bar'}), exp('', '@{foo}', '+=', {'/bar'} )),
@ -115,32 +115,32 @@ class VariableFromInit(VariableTest):
(VariableRule('@{foo}', '+=', {'/bar', '/baz'}), exp('', '@{foo}', '+=', {'/bar', '/baz'} )), (VariableRule('@{foo}', '+=', {'/bar', '/baz'}), exp('', '@{foo}', '+=', {'/bar', '/baz'} )),
(VariableRule('@{foo}', '=', {'/bar'}, comment='# cmt'), exp('# cmt', '@{foo}', '=', {'/bar'} )), (VariableRule('@{foo}', '=', {'/bar'}, comment='# cmt'), exp('# cmt', '@{foo}', '=', {'/bar'} )),
(VariableRule('@{foo}', '+=', {'/bar'}, comment='# cmt'), exp('# cmt', '@{foo}', '+=', {'/bar'} )), (VariableRule('@{foo}', '+=', {'/bar'}, comment='# cmt'), exp('# cmt', '@{foo}', '+=', {'/bar'} )),
] )
def _run_test(self, obj, expected): def _run_test(self, obj, expected):
self._compare_obj(obj, expected) self._compare_obj(obj, expected)
class InvalidVariableInit(AATest): class InvalidVariableInit(AATest):
tests = [ tests = (
# init params expected exception # init params expected exception
([None, '=', ['/bar'] ], AppArmorBug), # varname not a str ((None, '=', ['/bar']), AppArmorBug), # varname not a str
(['', '=', ['/bar'] ], AppArmorException), # empty varname (('', '=', ['/bar']), AppArmorException), # empty varname
(['foo', '=', ['/bar'] ], AppArmorException), # varname not starting with '@{' (('foo', '=', ['/bar']), AppArmorException), # varname not starting with '@{'
(['foo', '=', ['/bar'] ], AppArmorException), # varname not starting with '@{' (('foo', '=', ['/bar']), AppArmorException), # varname not starting with '@{'
(['@{foo}', '', ['/bar'] ], AppArmorBug), # mode not '=' or '+=' (('@{foo}', '', ['/bar']), AppArmorBug), # mode not '=' or '+='
(['@{foo}', '-=', ['/bar'] ], AppArmorBug), # mode not '=' or '+=' (('@{foo}', '-=', ['/bar']), AppArmorBug), # mode not '=' or '+='
(['@{foo}', ' ', ['/bar'] ], AppArmorBug), # mode not '=' or '+=' (('@{foo}', ' ', ['/bar']), AppArmorBug), # mode not '=' or '+='
(['@{foo}', None, ['/bar'] ], AppArmorBug), # mode not '=' or '+=' (('@{foo}', None, ['/bar']), AppArmorBug), # mode not '=' or '+='
(['@{foo}', '=', None ], AppArmorBug), # values not a set (('@{foo}', '=', None ), AppArmorBug), # values not a set
(['@{foo}', '=', set() ], AppArmorException), # empty values (('@{foo}', '=', set() ), AppArmorException), # empty values
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
with self.assertRaises(expected): with self.assertRaises(expected):
VariableRule(params[0], params[1], params[2]) VariableRule(*params)
def test_missing_params_1(self): def test_missing_params_1(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
@ -180,7 +180,7 @@ class InvalidVariableTest(AATest):
class WriteVariableTestAATest(AATest): class WriteVariableTestAATest(AATest):
tests = [ tests = (
# raw rule clean rule # raw rule clean rule
(' @{foo} = /bar ', '@{foo} = /bar'), (' @{foo} = /bar ', '@{foo} = /bar'),
(' @{foo} = /bar # comment', '@{foo} = /bar'), (' @{foo} = /bar # comment', '@{foo} = /bar'),
@ -191,7 +191,7 @@ class WriteVariableTestAATest(AATest):
(' @{foo} += /bar /baz', '@{foo} += /bar /baz'), (' @{foo} += /bar /baz', '@{foo} += /bar /baz'),
(' @{foo} += /bar @{baz}', '@{foo} += /bar @{baz}'), (' @{foo} += /bar @{baz}', '@{foo} += /bar @{baz}'),
(' @{foo} += /bar @{baz}', '@{foo} += /bar @{baz}'), (' @{foo} += /bar @{baz}', '@{foo} += /bar @{baz}'),
] )
def _run_test(self, rawrule, expected): def _run_test(self, rawrule, expected):
self.assertTrue(VariableRule.match(rawrule)) self.assertTrue(VariableRule.match(rawrule))
@ -235,40 +235,40 @@ class VariableCoveredTest(AATest):
class VariableCoveredTest_01(VariableCoveredTest): class VariableCoveredTest_01(VariableCoveredTest):
rule = '@{foo} = /bar' rule = '@{foo} = /bar'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' @{foo} = /bar' , [ True , True , True , True ]), (' @{foo} = /bar' , ( True , True , True , True )),
(' @{foo} += /bar' , [ False , False , False , False ]), (' @{foo} += /bar' , ( False , False , False , False )),
(' @{foo} = /bar # comment' , [ True , False , True , True ]), (' @{foo} = /bar # comment' , ( True , False , True , True )),
(' @{foo} += /bar # comment' , [ False , False , False , False ]), (' @{foo} += /bar # comment' , ( False , False , False , False )),
(' @{foo} = /baz /bar' , [ False , False , False , False ]), (' @{foo} = /baz /bar' , ( False , False , False , False )),
(' @{foo} += /baz /bar' , [ False , False , False , False ]), (' @{foo} += /baz /bar' , ( False , False , False , False )),
(' @{foo} = /baz /bar # cmt' , [ False , False , False , False ]), (' @{foo} = /baz /bar # cmt' , ( False , False , False , False )),
(' @{foo} += /baz /bar # cmt' , [ False , False , False , False ]), (' @{foo} += /baz /bar # cmt' , ( False , False , False , False )),
(' @{bar} = /bar' , [ False , False , False , False ]), # different variable name (' @{bar} = /bar' , ( False , False , False , False )), # different variable name
] )
class VariableCoveredTest_02(VariableCoveredTest): class VariableCoveredTest_02(VariableCoveredTest):
rule = '@{foo} = /bar /baz' rule = '@{foo} = /bar /baz'
tests = [ tests = (
# rule equal strict equal covered covered exact # rule equal strict equal covered covered exact
(' @{foo} = /bar /baz' , [ True , True , True , True ]), (' @{foo} = /bar /baz' , ( True , True , True , True )),
(' @{foo} += /bar /baz' , [ False , False , False , False ]), (' @{foo} += /bar /baz' , ( False , False , False , False )),
(' @{foo} = /bar /baz # cmt' , [ True , False , True , True ]), (' @{foo} = /bar /baz # cmt' , ( True , False , True , True )),
(' @{foo} += /bar /baz # cmt' , [ False , False , False , False ]), (' @{foo} += /bar /baz # cmt' , ( False , False , False , False )),
# changed order of values # changed order of values
(' @{foo} = /baz /bar' , [ True , False , True , True ]), (' @{foo} = /baz /bar' , ( True , False , True , True )),
(' @{foo} += /baz /bar' , [ False , False , False , False ]), (' @{foo} += /baz /bar' , ( False , False , False , False )),
(' @{foo} = /baz /bar # cmt' , [ True , False , True , True ]), (' @{foo} = /baz /bar # cmt' , ( True , False , True , True )),
(' @{foo} += /baz /bar # cmt' , [ False , False , False , False ]), (' @{foo} += /baz /bar # cmt' , ( False , False , False , False )),
# only one value # only one value
(' @{foo} = /bar' , [ False , False , True , True ]), (' @{foo} = /bar' , ( False , False , True , True )),
(' @{foo} += /bar' , [ False , False , False , False ]), (' @{foo} += /bar' , ( False , False , False , False )),
(' @{foo} = /bar # comment' , [ False , False , True , True ]), (' @{foo} = /bar # comment' , ( False , False , True , True )),
(' @{foo} += /bar # comment' , [ False , False , False , False ]), (' @{foo} += /bar # comment' , ( False , False , False , False )),
(' @{bar} = /bar' , [ False , False , False , False ]), # different variable name (' @{bar} = /bar' , ( False , False , False , False )), # different variable name
] )
class VariableCoveredTest_Invalid(AATest): class VariableCoveredTest_Invalid(AATest):
# def test_borked_obj_is_covered_1(self): # def test_borked_obj_is_covered_1(self):
@ -306,9 +306,9 @@ class VariableCoveredTest_Invalid(AATest):
obj.is_equal(testobj) obj.is_equal(testobj)
class VariableLogprofHeaderTest(AATest): class VariableLogprofHeaderTest(AATest):
tests = [ tests = (
('@{foo} = /bar', [_('Variable'), '@{foo} = /bar' ]), ('@{foo} = /bar', [_('Variable'), '@{foo} = /bar' ]),
] )
def _run_test(self, params, expected): def _run_test(self, params, expected):
obj = VariableRule.parse(params) obj = VariableRule.parse(params)
@ -328,12 +328,12 @@ class VariableRulesTest(AATest):
def test_ruleset_1(self): def test_ruleset_1(self):
ruleset = VariableRuleset() ruleset = VariableRuleset()
rules = [ rules = (
'@{foo} = /bar', '@{foo} = /bar',
'@{baz}= /asdf', '@{baz}= /asdf',
'@{foo} += /whatever', '@{foo} += /whatever',
'@{foo} += /morestuff', '@{foo} += /morestuff',
] )
expected_raw = [ expected_raw = [
'@{foo} = /bar', '@{foo} = /bar',

View file

@ -15,14 +15,14 @@ import subprocess
import sys import sys
# dangerous capabilities # dangerous capabilities
danger_caps = ["audit_control", danger_caps = ("audit_control",
"audit_write", "audit_write",
"mac_override", "mac_override",
"mac_admin", "mac_admin",
"setfcap", "setfcap",
"sys_admin", "sys_admin",
"sys_module", "sys_module",
"sys_rawio"] "sys_rawio")
def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=None): def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=None):
@ -32,7 +32,7 @@ def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, s
try: try:
sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, universal_newlines=True) sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, universal_newlines=True)
except OSError as ex: except OSError as ex:
return [127, str(ex)] return 127, str(ex)
out, outerr = sp.communicate(input) out, outerr = sp.communicate(input)
@ -42,10 +42,10 @@ def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, s
# Handle redirection of stderr # Handle redirection of stderr
if outerr is None: if outerr is None:
outerr = '' outerr = ''
return [sp.returncode, out, outerr] return sp.returncode, out, outerr
# get capabilities list # get capabilities list
(rc, output, outerr) = cmd(['../../common/list_capabilities.sh']) (rc, output, outerr) = cmd(('../../common/list_capabilities.sh',))
if rc != 0: if rc != 0:
sys.stderr.write("make list_capabilities failed: " + output + outerr) sys.stderr.write("make list_capabilities failed: " + output + outerr)
exit(rc) exit(rc)
@ -57,7 +57,7 @@ for cap in capabilities:
benign_caps.append(cap) benign_caps.append(cap)
# get network protos list # get network protos list
(rc, output, outerr) = cmd(['../../common/list_af_names.sh']) (rc, output, outerr) = cmd(('../../common/list_af_names.sh',))
if rc != 0: if rc != 0:
sys.stderr.write("make list_af_names failed: " + output + outerr) sys.stderr.write("make list_af_names failed: " + output + outerr)
exit(rc) exit(rc)
@ -76,7 +76,7 @@ for af_pair in af_pairs:
aa_network_types = r'\s+tcp|\s+udp|\s+icmp' aa_network_types = r'\s+tcp|\s+udp|\s+icmp'
aa_flags = ['complain', aa_flags = ('complain',
'audit', 'audit',
'attach_disconnected', 'attach_disconnected',
'no_attach_disconnected', 'no_attach_disconnected',
@ -85,7 +85,7 @@ aa_flags = ['complain',
'chroot_relative', 'chroot_relative',
'namespace_relative', 'namespace_relative',
'mediate_deleted', 'mediate_deleted',
'delegate_deleted'] 'delegate_deleted')
filename = r'(\/|\@\{\S*\})\S*' filename = r'(\/|\@\{\S*\})\S*'