mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-03 15:55:46 +00:00
IncludeRule: add get_full_paths()
This function returns a list of paths for an include rule. This can be - a single path if the include file is a file and exists - a single path if the include file doesn't exist, but doesn't have 'if exists' (this will cause a 'file not found' error when used) - a list of paths if the include is a directory - an empty list if the rule has 'if exists' and the file doesn't exist Also add some tests for get_full_paths()
This commit is contained in:
@@ -13,8 +13,9 @@
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.regex import RE_INCLUDE, re_match_include_parse
|
||||
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
|
||||
from apparmor.common import AppArmorBug, AppArmorException, is_skippable_file, type_is_str
|
||||
from apparmor.rule import BaseRule, BaseRuleset, parse_comment
|
||||
import os
|
||||
|
||||
# setup module translations
|
||||
from apparmor.translations import init_translation
|
||||
@@ -124,6 +125,34 @@ class IncludeRule(BaseRule):
|
||||
_('Include'), self.get_clean(),
|
||||
]
|
||||
|
||||
def get_full_paths(self, profile_dir):
|
||||
''' get list of full paths of an include (can contain multiple paths if self.path is a directory) '''
|
||||
|
||||
# currently this section is based on aa.py get_include_path() (with variable names changed)
|
||||
# TODO: improve/fix logic to honor magic vs. quoted include paths
|
||||
if self.path.startswith('/'):
|
||||
full_path = self.path
|
||||
else:
|
||||
full_path = os.path.join(profile_dir, self.path)
|
||||
|
||||
files = []
|
||||
|
||||
if os.path.isdir(full_path):
|
||||
for path in os.listdir(full_path):
|
||||
if is_skippable_file(path):
|
||||
continue
|
||||
|
||||
file_name = os.path.join(full_path, path)
|
||||
if os.path.isfile(file_name): # only add files, but not subdirectories etc.
|
||||
files.append(file_name)
|
||||
|
||||
elif os.path.exists(full_path):
|
||||
files.append(full_path)
|
||||
|
||||
elif self.ifexists == False:
|
||||
files.append(full_path) # add full_path even if it doesn't exist on disk. Might cause a 'file not found' error later.
|
||||
|
||||
return files
|
||||
|
||||
class IncludeRuleset(BaseRuleset):
|
||||
'''Class to handle and store a collection of include rules'''
|
||||
|
@@ -15,7 +15,10 @@
|
||||
|
||||
import unittest
|
||||
from collections import namedtuple
|
||||
from common_test import AATest, setup_all_loops
|
||||
from common_test import AATest, setup_all_loops, write_file
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from apparmor.rule.include import IncludeRule, IncludeRuleset
|
||||
#from apparmor.rule import BaseRule
|
||||
@@ -336,6 +339,45 @@ class IncludeLogprofHeaderTest(AATest):
|
||||
obj = IncludeRule._parse(params)
|
||||
self.assertEqual(obj.logprof_header(), expected)
|
||||
|
||||
class IncludeFullPathsTest(AATest):
|
||||
def AASetup(self):
|
||||
self.createTmpdir()
|
||||
|
||||
#copy the local profiles to the test directory
|
||||
self.profile_dir = '%s/profiles' % self.tmpdir
|
||||
shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True)
|
||||
|
||||
inc_dir = os.path.join(self.profile_dir, 'abstractions/inc.d')
|
||||
os.mkdir(inc_dir, 0o755)
|
||||
write_file(inc_dir, 'incfoo', '/incfoo r,')
|
||||
write_file(inc_dir, 'incbar', '/incbar r,')
|
||||
write_file(inc_dir, 'README', '# README') # gets skipped
|
||||
|
||||
sub_dir = os.path.join(self.profile_dir, 'abstractions/inc.d/subdir') # gets skipped
|
||||
os.mkdir(sub_dir, 0o755)
|
||||
|
||||
empty_dir = os.path.join(self.profile_dir, 'abstractions/empty.d')
|
||||
os.mkdir(empty_dir, 0o755)
|
||||
|
||||
tests = [
|
||||
# @@ will be replaced with self.profile_dir
|
||||
('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/bar"', ['/foo/bar'] ),
|
||||
('include <abstractions/inc.d>', ['@@/abstractions/inc.d/incfoo', '@@/abstractions/inc.d/incbar'] ),
|
||||
('include <abstractions/empty.d>', [] ),
|
||||
('include <abstractions/not_found>', ['@@/abstractions/not_found'] ),
|
||||
('include if exists <abstractions/not_found>', [] ),
|
||||
]
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
exp2 = []
|
||||
for path in expected:
|
||||
exp2.append(path.replace('@@', self.profile_dir))
|
||||
|
||||
obj = IncludeRule._parse(params)
|
||||
self.assertEqual(obj.get_full_paths(self.profile_dir), exp2)
|
||||
|
||||
## --- tests for IncludeRuleset --- #
|
||||
|
||||
class IncludeRulesTest(AATest):
|
||||
|
Reference in New Issue
Block a user