Hi, Attached is a patch that implements the following:
=item --include-templates-dir=PATH Include PATH when searching for templates in addition to the system templates directory (or the one specified with --templates-dir). System templates will match before those in PATH. =item --include-policy-groups-dir=PATH Include PATH when searching for policy groups in addition to the system policy-groups directory (or the one specified with --policy-groups-dir). System policy-groups will match before those in PATH. It makes the following changes: * utils/aa-easyprof: - update --show-template to handle --include-templates-dir - update --show-policy-group to handle --include-policy-groups-dir * utils/aa-easyprof.pod - minor corrections for --show-template and --show-policy-group - add --include-templates-dir and --include-policy-groups-dir * utils/apparmor/easyprof.py: implement these options according to man page * utils/test/test-aa-easyprof.py: - implement tests to exercise the changed/added code - correct test_policygroups_list() and test_policygroups_show() which were copy and wasted This option can be used to extend the available templates and policy groups beyond what are in the system directories. This is being implemented in support of Snappy for Ubuntu Core. The changes do not change aa-easyprof default behavior. --include-templates-dir and --include-policy-groups-dir cannot be used to override system templates and policy groups. Signed-off-by: Jamie Strandboge <ja...@canonical.com> -- Jamie Strandboge http://www.ubuntu.com/
Author: Jamie Strandboge <ja...@canonical.com> Description: add --include-templates-dir and --include-policy-groups-dir options to easyprof to support framework policy on snappy Forwarded: no Index: apparmor-2.9.1/utils/aa-easyprof =================================================================== --- apparmor-2.9.1.orig/utils/aa-easyprof +++ apparmor-2.9.1/utils/aa-easyprof @@ -1,7 +1,7 @@ #! /usr/bin/env python # ------------------------------------------------------------------ # -# Copyright (C) 2011-2013 Canonical Ltd. +# Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -68,16 +68,38 @@ if __name__ == "__main__": apparmor.easyprof.print_basefilenames(easyp.get_templates()) sys.exit(0) elif options.template and options.show_template: - files = [os.path.join(easyp.dirs['templates'], options.template)] - apparmor.easyprof.print_files(files) + sys_t = os.path.join(easyp.dirs['templates'], options.template) + inc_t = None + if options.include_templates_dir: + inc_t = os.path.join(easyp.dirs['templates_include'], + options.template) + + if os.path.exists(sys_t): + apparmor.easyprof.print_files([sys_t]) + elif os.path.exists(inc_t): + apparmor.easyprof.print_files([inc_t]) + else: + error("Could not find '%s'" % options.template) sys.exit(0) elif options.list_policy_groups: apparmor.easyprof.print_basefilenames(easyp.get_policy_groups()) sys.exit(0) elif options.policy_groups and options.show_policy_group: + files = [] for g in options.policy_groups.split(','): - files = [os.path.join(easyp.dirs['policygroups'], g)] - apparmor.easyprof.print_files(files) + sys_g = os.path.join(easyp.dirs['policygroups'], g) + inc_g = None + if options.include_policy_groups_dir: + inc_g = os.path.join(easyp.dirs['policygroups_include'], g) + + if os.path.exists(sys_g): + files.append(sys_g) + elif os.path.exists(inc_g): + files.append(inc_g) + else: + warn("Could not find '%s'" % g) + + apparmor.easyprof.print_files(files) sys.exit(0) elif binary == None and not options.profile_name and \ not options.manifest: Index: apparmor-2.9.1/utils/aa-easyprof.pod =================================================================== --- apparmor-2.9.1.orig/utils/aa-easyprof.pod +++ apparmor-2.9.1/utils/aa-easyprof.pod @@ -97,7 +97,7 @@ the specified template uses this value. List available templates. -=item --show-template=TEMPLATE +=item --show-template Display template specified with --template. @@ -105,18 +105,30 @@ Display template specified with --templa Use PATH instead of system templates directory. +=item --include-templates-dir=PATH + +Include PATH when searching for templates in addition to the system templates +directory (or the one specified with --templates-dir). System templates will +match before those in PATH. + =item --list-policy-groups List available policy groups. =item --show-policy-group -Display policy groups specified with --policy. +Display policy groups specified with --policy-groups. =item --policy-groups-dir=PATH Use PATH instead of system policy-groups directory. +=item --include-policy-groups-dir=PATH + +Include PATH when searching for policy groups in addition to the system +policy-groups directory (or the one specified with --policy-groups-dir). System +policy-groups will match before those in PATH. + =item --policy-version=VERSION Must be used with --policy-vendor and is used to specify the version of policy Index: apparmor-2.9.1/utils/apparmor/easyprof.py =================================================================== --- apparmor-2.9.1.orig/utils/apparmor/easyprof.py +++ apparmor-2.9.1/utils/apparmor/easyprof.py @@ -1,6 +1,6 @@ # ------------------------------------------------------------------ # -# Copyright (C) 2011-2013 Canonical Ltd. +# Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -312,15 +312,26 @@ class AppArmorEasyProfile: # the templates directory to the parent of the template so we don't # have to require --template-dir with absolute paths. self.dirs['templates'] = os.path.abspath(os.path.dirname(opt.template)) + + if opt.include_templates_dir and \ + os.path.isdir(opt.include_templates_dir): + self.dirs['templates_include'] = os.path.abspath(opt.include_templates_dir) + if opt.policy_groups_dir and os.path.isdir(opt.policy_groups_dir): self.dirs['policygroups'] = os.path.abspath(opt.policy_groups_dir) + if opt.include_policy_groups_dir and \ + os.path.isdir(opt.include_policy_groups_dir): + self.dirs['policygroups_include'] = os.path.abspath(opt.include_policy_groups_dir) self.policy_version = None self.policy_vendor = None if (opt.policy_version and not opt.policy_vendor) or \ (opt.policy_vendor and not opt.policy_version): raise AppArmorException("Must specify both policy version and vendor") + + # If specified --policy-version and --policy-vendor, use + # templates_dir/policy_vendor/policy_version if opt.policy_version and opt.policy_vendor: self.policy_vendor = opt.policy_vendor self.policy_version = str(opt.policy_version) @@ -361,11 +372,22 @@ class AppArmorEasyProfile: for f in get_directory_contents(self.dirs['templates']): if os.path.isfile(f): self.templates.append(f) + + if 'templates_include' in self.dirs: + for f in get_directory_contents(self.dirs['templates_include']): + if os.path.isfile(f) and f not in self.templates: + self.templates.append(f) + self.policy_groups = [] for f in get_directory_contents(self.dirs['policygroups']): if os.path.isfile(f): self.policy_groups.append(f) + if 'policygroups_include' in self.dirs: + for f in get_directory_contents(self.dirs['policygroups_include']): + if os.path.isfile(f) and f not in self.policy_groups: + self.policy_groups.append(f) + def _get_defaults(self): '''Read in defaults from configuration''' if not os.path.exists(self.conffile): @@ -411,13 +433,25 @@ class AppArmorEasyProfile: elif template.startswith('/') and not allow_abs_path: raise AppArmorException("Cannot use an absolute path template '%s'" % template) + # If have abs path, just use it if template.startswith('/'): + if not os.path.exists(template): + raise AppArmorException('%s does not exist' % (template)) self.template = template - else: - self.template = os.path.join(self.dirs['templates'], template) + return - if not os.path.exists(self.template): - raise AppArmorException('%s does not exist' % (self.template)) + # Find the template since we don't have an abs path + sys_t = os.path.join(self.dirs['templates'], template) + inc_t = None + if 'templates_include' in self.dirs: + inc_t = os.path.join(self.dirs['templates_include'], template) + + if os.path.exists(sys_t): + self.template = sys_t + elif inc_t is not None and os.path.exists(inc_t): + self.template = inc_t + else: + raise AppArmorException('%s does not exist' % (template)) def get_templates(self): '''Get list of all available templates by filename''' @@ -427,7 +461,16 @@ class AppArmorEasyProfile: '''Get contents of specific policygroup''' p = policygroup if not p.startswith('/'): - p = os.path.join(self.dirs['policygroups'], p) + sys_p = os.path.join(self.dirs['policygroups'], p) + inc_p = None + if 'policygroups_include' in self.dirs: + inc_p = os.path.join(self.dirs['policygroups_include'], p) + + if os.path.exists(sys_p): + p = sys_p + elif inc_p is not None and os.path.exists(inc_p): + p = inc_p + if self.policy_groups == None or not p in self.policy_groups: raise AppArmorException("Policy group '%s' does not exist" % p) return open(p).read() @@ -437,11 +480,25 @@ class AppArmorEasyProfile: self.policy_groups = [] if policygroups != None: for p in policygroups.split(','): - if not p.startswith('/'): - p = os.path.join(self.dirs['policygroups'], p) - if not os.path.exists(p): + # If have abs path, just use it + if p.startswith('/'): + if not os.path.exists(p): + raise AppArmorException('%s does not exist' % (p)) + self.policy_groups.append(p) + continue + + # Find the policy group since we don't have and abs path + sys_p = os.path.join(self.dirs['policygroups'], p) + inc_p = None + if 'policygroups_include' in self.dirs: + inc_p = os.path.join(self.dirs['policygroups_include'], p) + + if os.path.exists(sys_p): + self.policy_groups.append(sys_p) + elif inc_p is not None and os.path.exists(inc_p): + self.policy_groups.append(inc_p) + else: raise AppArmorException('%s does not exist' % (p)) - self.policy_groups.append(p) def get_policy_groups(self): '''Get list of all policy groups by filename''' @@ -777,6 +834,10 @@ def add_parser_policy_args(parser): dest="templates_dir", help="Use non-default templates directory", metavar="DIR") + parser.add_option("--include-templates-dir", + dest="include_templates_dir", + help="Also search DIR for templates", + metavar="DIR") parser.add_option("-p", "--policy-groups", action="callback", callback=check_for_manifest_arg, @@ -787,6 +848,10 @@ def add_parser_policy_args(parser): dest="policy_groups_dir", help="Use non-default policy-groups directory", metavar="DIR") + parser.add_option("--include-policy-groups-dir", + dest="include_policy_groups_dir", + help="Also search DIR for policy groups", + metavar="DIR") parser.add_option("--policy-version", action="callback", callback=check_for_manifest_arg, Index: apparmor-2.9.1/utils/test/test-aa-easyprof.py =================================================================== --- apparmor-2.9.1.orig/utils/test/test-aa-easyprof.py +++ apparmor-2.9.1/utils/test/test-aa-easyprof.py @@ -1,7 +1,7 @@ #! /usr/bin/env python # ------------------------------------------------------------------ # -# Copyright (C) 2011-2013 Canonical Ltd. +# Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -112,7 +112,8 @@ class T(unittest.TestCase): # Copy everything into place for d in ['easyprof/policygroups', 'easyprof/templates']: - shutil.copytree(os.path.join(topdir, d), os.path.join(self.tmpdir, os.path.basename(d))) + shutil.copytree(os.path.join(topdir, d), + os.path.join(self.tmpdir, os.path.basename(d))) # Create a test template self.test_template = "test-template" @@ -167,6 +168,17 @@ TEMPLATES_DIR="%s/templates" (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) + # Now create some differently prefixed files in the include-dir + self.test_include_dir = os.path.join(self.tmpdir, '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, "policygroups")) + for d in ['policygroups', 'templates']: + for f in easyprof.get_directory_contents(os.path.join( + self.tmpdir, d)): + shutil.copy(f, os.path.join(self.test_include_dir, d, + "inc_%s" % os.path.basename(f))) + def tearDown(self): '''Teardown for tests''' if os.path.exists(self.tmpdir): @@ -505,6 +517,53 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() + def test_templates_list_include(self): + '''Test templates (list with --include-templates-dir)''' + args = self.full_args + args.append('--list-templates') + (self.options, self.args) = easyprof.parse_args(args) + + easyp = easyprof.AppArmorEasyProfile(None, self.options) + orig_templates = easyp.get_templates() + + args = self.full_args + args.append('--list-templates') + args.append('--include-templates-dir=%s' % + os.path.join(self.test_include_dir, 'templates')) + (self.options, self.args) = easyprof.parse_args(args) + + easyp = easyprof.AppArmorEasyProfile(None, self.options) + inc_templates = easyp.get_templates() + self.assertTrue(len(inc_templates) == len(orig_templates) * 2, + "templates missing: %s" % inc_templates) + + for i in inc_templates: + self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) + + def test_templates_show_include(self): + '''Test templates (show with --include-templates-dir)''' + files = [] + for f in glob.glob("%s/templates/*" % self.test_include_dir): + files.append(f) + + for f in files: + args = self.full_args + args += ['--show-template', + '--template', f, + '--include-templates-dir=%s' % + os.path.join(self.test_include_dir, 'templates')] + (self.options, self.args) = easyprof.parse_args(args) + easyp = easyprof.AppArmorEasyProfile(None, self.options) + + path = os.path.join(easyp.dirs['templates_include'], f) + self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) + open(path).read() + + bn = os.path.basename(f) + # setup() copies everything in the include prefixed with inc_ + self.assertTrue(bn.startswith('inc_'), + "'%s' does not start with 'inc_'" % bn) + # # Policygroups tests # @@ -515,7 +574,7 @@ POLICYGROUPS_DIR="%s/templates" (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) - for i in easyp.get_templates(): + for i in easyp.get_policy_groups(): self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_policygroups_show(self): @@ -526,7 +585,8 @@ POLICYGROUPS_DIR="%s/templates" for f in files: args = self.full_args - args += ['--show-template', '--template', f] + args += ['--show-policy-group', + '--policy-groups', os.path.basename(f)] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) @@ -534,6 +594,53 @@ POLICYGROUPS_DIR="%s/templates" self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() + def test_policygroups_list_include(self): + '''Test policygroups (list with --include-policy-groups-dir)''' + args = self.full_args + args.append('--list-policy-groups') + (self.options, self.args) = easyprof.parse_args(args) + + easyp = easyprof.AppArmorEasyProfile(None, self.options) + orig_policy_groups = easyp.get_policy_groups() + + args = self.full_args + args.append('--list-policy-groups') + args.append('--include-policy-groups-dir=%s' % + os.path.join(self.test_include_dir, 'policygroups')) + (self.options, self.args) = easyprof.parse_args(args) + + easyp = easyprof.AppArmorEasyProfile(None, self.options) + inc_policy_groups = easyp.get_policy_groups() + self.assertTrue(len(inc_policy_groups) == len(orig_policy_groups) * 2, + "policy_groups missing: %s" % inc_policy_groups) + + for i in inc_policy_groups: + self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) + + def test_policygroups_show_include(self): + '''Test policygroups (show with --include-policy-groups-dir)''' + files = [] + for f in glob.glob("%s/policygroups/*" % self.test_include_dir): + files.append(f) + + for f in files: + args = self.full_args + args += ['--show-policy-group', + '--policy-groups', os.path.basename(f), + '--include-policy-groups-dir=%s' % + os.path.join(self.test_include_dir, 'policygroups')] + (self.options, self.args) = easyprof.parse_args(args) + easyp = easyprof.AppArmorEasyProfile(None, self.options) + + path = os.path.join(easyp.dirs['policygroups_include'], f) + self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) + open(path).read() + + bn = os.path.basename(f) + # setup() copies everything in the include prefixed with inc_ + self.assertTrue(bn.startswith('inc_'), + "'%s' does not start with 'inc_'" % bn) + # # Manifest file argument tests #
signature.asc
Description: OpenPGP digital signature
-- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor