[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH][ACM][UPDATE] python tools and support for resource labeling
Same as previous patch, except that we no longer use xml marshaling. Signed-off-by: Bryan D. Payne <bdpayne@xxxxxxxxxx> Signed-off-by: Reiner Sailer <sailer@xxxxxxxxxx> --- docs/man/xm.pod.1 | 93 +++++++++++++++++++-- tools/python/xen/util/dictio.py | 50 +++++++++++ tools/python/xen/util/security.py | 98 ++++++++++++++++++++++ tools/python/xen/xend/server/blkif.py | 12 ++ tools/python/xen/xm/addlabel.py | 149 +++++++++++++++++++++++++++------- tools/python/xen/xm/create.py | 59 ++++++++++++- tools/python/xen/xm/dry-run.py | 95 +++++++++++++++++++++ tools/python/xen/xm/getlabel.py | 131 +++++++++++++++++++++++++++++ tools/python/xen/xm/main.py | 28 ++++++ tools/python/xen/xm/resources.py | 61 +++++++++++++ tools/python/xen/xm/rmlabel.py | 130 +++++++++++++++++++++++++++++ 11 files changed, 862 insertions(+), 44 deletions(-) Index: xen-unstable.hg-shype/docs/man/xm.pod.1 =================================================================== --- xen-unstable.hg-shype.orig/docs/man/xm.pod.1 +++ xen-unstable.hg-shype/docs/man/xm.pod.1 @@ -875,14 +875,43 @@ defined in the I<policy>. Unless specifi the currently enforced access control policy. The default for I<type> is 'dom'. The labels are arranged in alphabetical order. -=item B<addlabel> I<configfile> I<label> [I<policy>] +=item B<addlabel> I<label> dom I<configfile> [I<policy>] + +=item B<addlabel> I<label> res I<resource> [I<policy>] Adds the security label with name I<label> to a domain -I<configfile>. Unless specified, the default I<policy> is the +I<configfile> (dom) or to the global resource label file for the +given I<resource> (res). Unless specified, the default I<policy> is the currently enforced access control policy. This subcommand also verifies that the I<policy> definition supports the specified I<label> name. +=item B<rmlabel> dom I<configfile> + +=item B<rmlabel> res I<resource> + +Works the same as the I<addlabel> command (above), except that this +command will remove the label from the domain I<configfile> (dom) or +the global resource label file (res). + +=item B<getlabel> dom I<configfile> + +=item B<getlabel> res I<resource> + +Shows the label for the given I<configfile> or I<resource> + +=item B<resources> + +Lists all resources in the global resource label file. Each resource +is listed with its associated label and policy name. + +=item B<dry-run> I<configfile> + +Determines if the specified I<configfile> describes a domain with a valid +security configuration for type enforcement. The test shows the policy +decision made for each resource label against the domain label as well as +the overall decision. + B<CONFIGURING SECURITY> =over 4 @@ -960,17 +989,18 @@ B<ATTACHING A SECURITY LABEL TO A DOMAIN =over 4 -This subcommand attaches a security label to a domain configuration -file, here a HomeBanking label. The example policy ensures that this -domain does not share information with other non-hombanking user -domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it -will not run simultaneously with domains labeled as dom_Fun. +The I<addlabel> subcommand can attach a security label to a domain +configuration file, here a HomeBanking label. The example policy +ensures that this domain does not share information with other +non-hombanking user domains (i.e., domains labeled as dom_Fun or +dom_Boinc) and that it will not run simultaneously with domains +labeled as dom_Fun. We assume that the specified myconfig.xm configuration file actually instantiates a domain that runs workloads related to home-banking, probably just a browser environment for online-banking. - xm addlabel myconfig.xm dom_HomeBanking + xm addlabel dom_HomeBanking dom myconfig.xm The very simple configuration file might now look as printed below. The I<addlabel> subcommand added the B<access_control> entry at @@ -997,6 +1027,38 @@ permitted". =back +B<ATTACHING A SECURITY LABEL TO A RESOURCE> + +=over 4 + +The I<addlabel> subcommand can also be used to attach a security +label to a resource. Following the home banking example from above, +we can label a disk resource (e.g., a physical partition or a file) +to make it accessible to the home banking domain. The example policy +provides a resource label, res_LogicalDiskPartition1(hda1), that is +compatible with the HomeBanking domain label. + + xm addlabel "res_LogicalDiskPartition1(hda1)" res phy:hda6 + +After labeling this disk resource, it can be attached to the domain +by adding a line to the domain configuration file. The line below +attaches this disk to the domain at boot time. + + disk = [ 'phy:hda6,sda2,w' ] + +Alternatively, the resource can be attached after booting the domain +by using the I<block-attach> subcommand. + + xm block-attach homebanking phy:hda6 sda2 w + +Note that labeled resources cannot be used when security is turned +off. Any attempt to use labeled resources with security turned off +will result in a failure with a corresponding error message. The +solution is to enable security or, if security is no longer desired, +to remove the resource label using the I<rmlabel> subcommand. + +=back + B<STARTING AND LISTING LABELED DOMAINS> =over 4 @@ -1011,6 +1073,21 @@ B<STARTING AND LISTING LABELED DOMAINS> =back +B<LISTING LABELED RESOURCES> + +=over 4 + + xm resources + + phy:hda6 + policy: example.chwall_ste.client_v1 + label: res_LogicalDiskPartition1(hda1) + file:/xen/disk_image/disk.img + policy: example.chwall_ste.client_v1 + label: res_LogicalDiskPartition2(hda2) + +=back + B<POLICY REPRESENTATIONS> =over 4 Index: xen-unstable.hg-shype/tools/python/xen/util/dictio.py =================================================================== --- /dev/null +++ xen-unstable.hg-shype/tools/python/xen/util/dictio.py @@ -0,0 +1,50 @@ +#=========================================================================== +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> +#============================================================================ + + +def dict_read(dictname, filename): + """Loads <filename> and returns the dictionary named <dictname> from + the file. + """ + dict = {} + + # read in the config file + globs = {} + locs = {} + execfile(filename, globs, locs) + + for (k, v) in locs.items(): + if k == dictname: + dict = v + break + + return dict + +def dict_write(dict, dictname, filename): + """Writes <dict> to <filename> using the name <dictname>. If the file + contains any other data, it will be overwritten. + """ + prefix = dictname + " = {\n" + suffix = "}\n" + fd = open(filename, "wb") + fd.write(prefix) + for key in dict: + line = " '" + str(key) + "': " + str(dict[key]) + ",\n" + fd.write(line) + fd.write(suffix) + fd.close() Index: xen-unstable.hg-shype/tools/python/xen/util/security.py =================================================================== --- xen-unstable.hg-shype.orig/tools/python/xen/util/security.py +++ xen-unstable.hg-shype/tools/python/xen/util/security.py @@ -14,6 +14,7 @@ #============================================================================ # Copyright (C) 2006 International Business Machines Corp. # Author: Reiner Sailer +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> #============================================================================ import commands @@ -23,9 +24,12 @@ import traceback import shutil from xen.lowlevel import acm from xen.xend import sxp +from xen.xend.XendLogging import log +from xen.util import dictio #global directories and tools for security management policy_dir_prefix = "/etc/xen/acm-security/policies" +res_label_filename = policy_dir_prefix + "/resource_labels" boot_filename = "/boot/grub/menu.lst" xensec_xml2bin = "/usr/sbin/xensec_xml2bin" xensec_tool = "/usr/sbin/xensec_tool" @@ -530,3 +534,97 @@ def list_labels(policy_name, condition): if label not in labels: labels.append(label) return labels + + +def get_res_label(resource): + """Returns resource label information (label, policy) if it exists. + Otherwise returns null label and policy. + """ + def default_res_label(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + return (label, 'NULL') + + (label, policy) = default_res_label() + + # load the resource label file + res_label_cache = {} + try: + res_label_cache = dictio.dict_read("resources", res_label_filename) + except: + log.info("Resource label file not found.") + return default_res_label() + + # find the resource information + if res_label_cache.has_key(resource): + (policy, label) = res_label_cache[resource] + + return (label, policy) + + +def get_res_security_details(resource): + """Returns the (label, ssidref, policy) associated with a given + resource from the global resource label file. + """ + def default_security_details(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + policy = active_policy + return (label, ssidref, policy) + + (label, ssidref, policy) = default_security_details() + + # find the entry associated with this resource + (label, policy) = get_res_label(resource) + if policy == 'NULL': + log.info("Resource label for "+resource+" not in file, using DEFAULT.") + return default_security_details() + + # is this resource label for the running policy? + if policy == active_policy: + ssidref = label2ssidref(label, policy, 'res') + else: + log.info("Resource label not for active policy, using DEFAULT.") + return default_security_details() + + return (label, ssidref, policy) + + +def res_security_check(resource, domain_label): + """Checks if the given resource can be used by the given domain + label. Returns 1 if the resource can be used, otherwise 0. + """ + rtnval = 1 + + # if security is on, ask the hypervisor for a decision + if on(): + (label, ssidref, policy) = get_res_security_details(resource) + domac = ['access_control'] + domac.append(['policy', active_policy]) + domac.append(['label', domain_label]) + domac.append(['type', 'dom']) + decision = get_decision(domac, ['ssidref', str(ssidref)]) + + # provide descriptive error messages + if decision == 'DENIED': + if label == ssidref2label(NULL_SSIDREF): + raise ACMError("Resource '"+resource+"' is not labeled") + rtnval = 0 + else: + raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed") + rtnval = 0 + + # security is off, make sure resource isn't labeled + else: + (label, policy) = get_res_label(resource) + if policy != 'NULL': + raise ACMError("Security is off, but '"+resource+"' is labeled") + rtnval = 0 + + return rtnval Index: xen-unstable.hg-shype/tools/python/xen/xend/server/blkif.py =================================================================== --- xen-unstable.hg-shype.orig/tools/python/xen/xend/server/blkif.py +++ xen-unstable.hg-shype/tools/python/xen/xend/server/blkif.py @@ -21,6 +21,7 @@ import re import string from xen.util import blkif +from xen.util import security from xen.xend import sxp from xen.xend.XendError import VmError @@ -40,15 +41,22 @@ class BlkifController(DevController): def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" + uname = sxp.child_value(config, 'uname') dev = sxp.child_value(config, 'dev') - (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1) + (typ, params) = string.split(uname, ':', 1) back = { 'dev' : dev, 'type' : typ, 'params' : params, 'mode' : sxp.child_value(config, 'mode', 'r') - } + } + + if security.on(): + (label, ssidref, policy) = security.get_res_security_details(uname) + back.update({'acm_label' : label, + 'acm_ssidref': str(ssidref), + 'acm_policy' : policy}) if 'ioemu:' in dev: (dummy, dev1) = string.split(dev, ':', 1) Index: xen-unstable.hg-shype/tools/python/xen/xm/addlabel.py =================================================================== --- xen-unstable.hg-shype.orig/tools/python/xen/xm/addlabel.py +++ xen-unstable.hg-shype/tools/python/xen/xm/addlabel.py @@ -14,61 +14,150 @@ #============================================================================ # Copyright (C) 2006 International Business Machines Corp. # Author: Reiner Sailer <sailer@xxxxxxxxxx> +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> #============================================================================ -"""Labeling a domain configuration file. +"""Labeling a domain configuration file or a resoruce. """ import sys, os +import string import traceback - - -from xen.util.security import ACMError, err, active_policy, label2ssidref, on, access_control_re - +from xen.util import dictio +from xen.util import security def usage(): - print "\nUsage: xm addlabel <configfile> <label> [<policy>]\n" - print " This program adds an acm_label entry into the 'configfile'." - print " It derives the policy from the running hypervisor if it" - print " is not given (optional parameter). If the configfile is" - print " already labeled, then addlabel fails.\n" - err("Usage") - + print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]" + print " xm addlabel <label> res <resource> [<policy>]\n" + print " This program adds an acm_label entry into the 'configfile'" + print " for a domain or to the global resource label file for a" + print " resource. It derives the policy from the running hypervisor" + print " if it is not given (optional parameter). If a label already" + print " exists for the given domain or resource, then addlabel fails.\n" + security.err("Usage") + +def validate_config_file(configfile): + """Performs a simple sanity check on the configuration file passed on + the command line. We basically just want to make sure that it's + not a domain image file so we check for a few configuration values + and then we are satisfied. Returned 1 on success, otherwise 0. + """ + # read in the config file + globs = {} + locs = {} + try: + execfile(configfile, globs, locs) + except: + print "Invalid configuration file." + return 0 -def main(argv): + # sanity check on the data from the file + count = 0 + required = ['kernel', 'memory', 'name'] + for (k, v) in locs.items(): + if k in required: + count += 1 + if count != 3: + print "Invalid configuration file." + return 0 + else: + return 1 + + +def add_resource_label(label, resource, policyref): + """Adds a resource label to the global resource label file. + """ try: - policyref = None - if len(argv) not in [3,4]: - usage() - configfile = argv[1] - label = argv[2] + # sanity check: make sure this label can be instantiated later on + ssidref = security.label2ssidref(label, policyref, 'res') - if len(argv) == 4: - policyref = argv[3] - elif on(): - policyref = active_policy - else: - err("No active policy. Policy must be specified in command line.") + # sanity check on resource name + (type, file) = resource.split(":") + if type == "phy": + file = "/dev/" + file + if not os.path.exists(file): + print "Invalid resource '"+resource+"'" + return + + # see if this resource is already in the file + access_control = {} + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + print "Resource file not found, creating new file at:" + print "%s" % (file) + + if access_control.has_key(resource): + security.err("This resource is already labeled.") + + # write the data to file + new_entry = { resource : tuple([policyref, label]) } + access_control.update(new_entry) + dictio.dict_write(access_control, "resources", file) + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) - #sanity checks: make sure this label can be instantiated later on - ssidref = label2ssidref(label, policyref, 'dom') +def add_domain_label(label, configfile, policyref): + try: + # sanity checks: make sure this label can be instantiated later on + ssidref = security.label2ssidref(label, policyref, 'dom') new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label) if not os.path.isfile(configfile): - err("Configuration file \'" + configfile + "\' not found.") + security.err("Configuration file \'" + configfile + "\' not found.") config_fd = open(configfile, "ra+") for line in config_fd: - if not access_control_re.match(line): + if not security.access_control_re.match(line): continue config_fd.close() - err("Config file \'" + configfile + "\' is already labeled.") + security.err("Config file \'" + configfile + "\' is already labeled.") config_fd.write(new_label) config_fd.close() - except ACMError: + except security.ACMError: pass except: traceback.print_exc(limit=1) +def main (argv): + try: + policyref = None + if len(argv) not in [4,5]: + usage() + label = argv[1] + + if len(argv) == 5: + policyref = argv[4] + elif security.on(): + policyref = security.active_policy + else: + security.err("No active policy. Policy must be specified in command line.") + + if argv[2].lower() == "dom": + configfile = argv[3] + if configfile[0] != '/': + for prefix in [".", "/etc/xen"]: + configfile = prefix + "/" + configfile + if os.path.isfile(configfile): + fd = open(configfile, "rb") + break + if not validate_config_file(configfile): + usage() + else: + add_domain_label(label, configfile, policyref) + elif argv[2].lower() == "res": + resource = argv[3] + add_resource_label(label, resource, policyref) + else: + usage() + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) if __name__ == '__main__': main(sys.argv) Index: xen-unstable.hg-shype/tools/python/xen/xm/create.py =================================================================== --- xen-unstable.hg-shype.orig/tools/python/xen/xm/create.py +++ xen-unstable.hg-shype/tools/python/xen/xm/create.py @@ -988,6 +988,56 @@ def parseCommandLine(argv): return (gopts, config) +def config_security_check(config, verbose): + """Checks each resource listed in the config to see if the active + policy will permit creation of a new domain using the config. + Returns 1 if the config passes all tests, otherwise 0. + """ + answer = 1 + + # get the domain acm_label + domain_label = None + domain_policy = None + for x in sxp.children(config): + if sxp.name(x) == 'security': + domain_label = sxp.child_value(sxp.name(sxp.child0(x)), 'label') + domain_policy = sxp.child_value(sxp.name(sxp.child0(x)), 'policy') + + # if no domain label, use default + if not domain_label and security.on(): + domain_label = security.ssidref2label(security.NULL_SSIDREF) + domain_policy = 'NULL' + elif not domain_label: + domain_label = "" + domain_policy = 'NULL' + + if verbose: + print "Checking resources:" + + # build a list of all resources in the config file + resources = [] + for x in sxp.children(config): + if sxp.name(x) == 'device': + if sxp.name(sxp.child0(x)) == 'vbd': + resources.append(sxp.child_value(sxp.child0(x), 'uname')) + + # perform a security check on each resource + for resource in resources: + try: + security.res_security_check(resource, domain_label) + if verbose: + print " %s: PERMITTED" % (resource) + + except security.ACMError: + print " %s: DENIED" % (resource) + (res_label, res_policy) = security.get_res_label(resource) + print " --> res:"+res_label+" ("+res_policy+")" + print " --> dom:"+domain_label+" ("+domain_policy+")" + answer = 0 + + return answer + + def main(argv): try: (opts, config) = parseCommandLine(argv) @@ -1000,9 +1050,12 @@ def main(argv): if opts.vals.dryrun: PrettyPrint.prettyprint(config) else: - dom = make_domain(opts, config) - if opts.vals.console_autoconnect: - console.execConsole(dom) + if not config_security_check(config, verbose=0): + err("Resource access violation") + else: + dom = make_domain(opts, config) + if opts.vals.console_autoconnect: + console.execConsole(dom) if __name__ == '__main__': main(sys.argv) Index: xen-unstable.hg-shype/tools/python/xen/xm/dry-run.py =================================================================== --- /dev/null +++ xen-unstable.hg-shype/tools/python/xen/xm/dry-run.py @@ -0,0 +1,95 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> +#============================================================================ + +"""Tests the security settings for a domain and its resources. +""" +from xen.util import security +from xen.xm import create +from xen.xend import sxp + +def usage(): + print "\nUsage: xm dry-run <configfile>\n" + print "This program checks each resource listed in the configfile" + print "to see if the domain created by the configfile can access" + print "the resources. The status of each resource is listed" + print "individually along with the final security decision.\n" + + +def check_domain_label(config): + """All that we need to check here is that the domain label exists and + is not null when security is on. Other error conditions are + handled when the config file is parsed. + """ + answer = 0 + secon = 0 + default_label = security.ssidref2label(security.NULL_SSIDREF) + if security.on(): + secon = 1 + + # get the domain acm_label + dom_label = None + dom_name = None + for x in sxp.children(config): + if sxp.name(x) == 'security': + dom_label = sxp.child_value(sxp.name(sxp.child0(x)), 'label') + if sxp.name(x) == 'name': + dom_name = sxp.child0(x) + + # sanity check on domain label + print "Checking domain:" + if (not secon) and (not dom_label): + print " %s: PERMITTED" % (dom_name) + answer = 1 + elif (secon) and (dom_label) and (dom_label != default_label): + print " %s: PERMITTED" % (dom_name) + answer = 1 + else: + print " %s: DENIED" % (dom_name) + if not secon: + print " --> Security off, but domain labeled" + else: + print " --> Domain not labeled" + answer = 0 + + return answer + + +def main (argv): + if len(argv) != 2: + usage() + return + + try: + passed = 0 + (opts, config) = create.parseCommandLine(argv) + if check_domain_label(config): + if create.config_security_check(config, verbose=1): + passed = 1 + else: + print "Checking resources: (skipped)" + + if passed: + print "Dry Run: PASSED" + else: + print "Dry Run: FAILED" + except security.ACMError: + pass + + +if __name__ == '__main__': + main(sys.argv) Index: xen-unstable.hg-shype/tools/python/xen/xm/getlabel.py =================================================================== --- /dev/null +++ xen-unstable.hg-shype/tools/python/xen/xm/getlabel.py @@ -0,0 +1,131 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> +#============================================================================ + +"""Show the label for a domain or resoruce. +""" +import sys, os, re +import string +import traceback +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm getlabel dom <configfile>" + print " xm getlabel res <resource>\n" + print " This program shows the label for a domain or resource.\n" + + +def get_resource_label(resource): + """Gets the resource label + """ + # read in the resource file + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + print "Resource label file not found" + return + + try: + # get the entry and print label + if access_control.has_key(resource): + policy = access_control[resource][0] + label = access_control[resource][1] + print "policy="+policy+",label="+label + else: + print "Resource not labeled" + return + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) + + +def get_domain_label(configfile): + try: + # open the domain config file + fd = None + file = None + if configfile[0] == '/': + fd = open(configfile, "rb") + else: + for prefix in [".", "/etc/xen"]: + file = prefix + "/" + configfile + if os.path.isfile(file): + fd = open(file, "rb") + break + if not fd: + print "Configuration file '"+configfile+"' not found." + return + + # read in the domain config file, finding the label line + ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) + ac_exit_re = re.compile(".*'\].*") + acline = "" + record = 0 + for line in fd.readlines(): + if ac_entry_re.match(line): + record = 1 + if record: + acline = acline + line + if record and ac_exit_re.match(line): + record = 0 + fd.close() + + # send error message if we didn't find anything + if acline == "": + print "Label does not exist in domain configuration file." + return + + # print out the label + (title, data) = acline.split("=", 1) + data = data.strip() + data = data.lstrip("[\'") + data = data.rstrip("\']") + print data + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) + + +def main (argv): + try: + if len(argv) != 3: + usage() + return + + if argv[1].lower() == "dom": + configfile = argv[2] + get_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + get_resource_label(resource) + else: + usage() + + except security.ACMError: + traceback.print_exc(limit=1) + + +if __name__ == '__main__': + main(sys.argv) + + Index: xen-unstable.hg-shype/tools/python/xen/xm/main.py =================================================================== --- xen-unstable.hg-shype.orig/tools/python/xen/xm/main.py +++ xen-unstable.hg-shype/tools/python/xen/xm/main.py @@ -30,6 +30,7 @@ import socket import warnings warnings.filterwarnings('ignore', category=FutureWarning) import xmlrpclib +import traceback import xen.xend.XendProtocol @@ -119,7 +120,11 @@ vnet_list_help = "vnet-list [-l|--long] vnet_create_help = "vnet-create <config> create a vnet from a config file" vnet_delete_help = "vnet-delete <vnetid> delete a vnet" vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices" -addlabel_help = "addlabel <ConfigFile> <label> Add security label to ConfigFile" +addlabel_help = "addlabel <label> dom <configfile> Add security label to domain\n <label> res <resource> or resource" +rmlabel_help = "rmlabel dom <configfile> Remove security label from domain\n res <resource> or resource" +getlabel_help = "getlabel dom <configfile> Show security label for domain\n res <resource> or resource" +dry_run_help = "dry-run <configfile> Tests if domain can access its resources" +resources_help = "resources Show info for each labeled resource" cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration " dumppolicy_help = "dumppolicy Print hypervisor ACM state information" loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor" @@ -203,6 +208,10 @@ vnet_commands = [ acm_commands = [ "labels", "addlabel", + "rmlabel", + "getlabel", + "dry-run", + "resources", "makepolicy", "loadpolicy", "cfgbootpolicy", @@ -999,6 +1008,19 @@ def xm_block_attach(args): if len(args) == 5: vbd.append(['backend', args[4]]) + # verify that policy permits attaching this resource + try: + dominfo = server.xend.domain(dom) + domid = sxp.child_value(dominfo, 'domid') + (tmp1, label, tmp2, tmp3) = security.get_ssid(domid) + security.res_security_check(args[1], label) + except security.ACMError, e: + print e.value + sys.exit(1) + except: + traceback.print_exc(limit=1) + sys.exit(1) + server.xend.domain.device_create(dom, vbd) @@ -1131,6 +1153,10 @@ subcommands = [ 'shutdown', 'labels', 'addlabel', + 'rmlabel', + 'getlabel', + 'dry-run', + 'resources', 'cfgbootpolicy', 'makepolicy', 'loadpolicy', Index: xen-unstable.hg-shype/tools/python/xen/xm/resources.py =================================================================== --- /dev/null +++ xen-unstable.hg-shype/tools/python/xen/xm/resources.py @@ -0,0 +1,61 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> +#============================================================================ + +"""List the resource label information from the global resource label file +""" +import sys, os +import string +import traceback +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm resource\n" + print " This program lists information for each resource in the" + print " global resource label file\n" + + +def print_resource_data(access_control): + """Prints out a resource dictionary to stdout + """ + for resource in access_control: + (policy, label) = access_control[resource] + print resource + print " policy: "+policy + print " label: "+label + + +def main (argv): + try: + file = security.res_label_filename + access_control = dictio.dict_read("resources", file) + except: + security.err("Resource file not found.") + + try: + print_resource_data(access_control) + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) + + +if __name__ == '__main__': + main(sys.argv) + + Index: xen-unstable.hg-shype/tools/python/xen/xm/rmlabel.py =================================================================== --- /dev/null +++ xen-unstable.hg-shype/tools/python/xen/xm/rmlabel.py @@ -0,0 +1,130 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Bryan D. Payne <bdpayne@xxxxxxxxxx> +#============================================================================ + +"""Remove a label from a domain configuration file or a resoruce. +""" +import sys, os, re +import string +import traceback +from xen.util import dictio +from xen.util import security + +def usage(): + print "\nUsage: xm rmlabel dom <configfile>" + print " xm rmlabel res <resource>\n" + print " This program removes an acm_label entry from the 'configfile'" + print " for a domain or from the global resource label file for a" + print " resource. If the label does not exist for the given domain or" + print " resource, then rmlabel fails.\n" + + +def rm_resource_label(resource): + """Removes a resource label from the global resource label file. + """ + # read in the resource file + file = security.res_label_filename + try: + access_control = dictio.dict_read("resources", file) + except: + security.err("Resource file not found, cannot remove label!") + + try: + # remove the entry and update file + if access_control.has_key(resource): + del access_control[resource] + dictio.dict_write(access_control, "resources", file) + else: + security.err("Label does not exist in resource label file.") + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) + + +def rm_domain_label(configfile): + try: + # open the domain config file + fd = None + file = None + if configfile[0] == '/': + fd = open(configfile, "rb") + else: + for prefix in [".", "/etc/xen"]: + file = prefix + "/" + configfile + if os.path.isfile(file): + fd = open(file, "rb") + break + if not fd: + security.err("Configuration file '"+configfile+"' not found.") + + # read in the domain config file, removing label + ac_entry_re = re.compile("^access_control\s*=.*", re.IGNORECASE) + ac_exit_re = re.compile(".*'\].*") + file_contents = "" + comment = 0 + removed = 0 + for line in fd.readlines(): + if ac_entry_re.match(line): + comment = 1 + if comment: + removed = 1 + line = "#"+line + if comment and ac_exit_re.match(line): + comment = 0 + file_contents = file_contents + line + fd.close() + + # send error message if we didn't find anything to remove + if not removed: + security.err("Label does not exist in domain configuration file.") + + # write the data back out to the file + fd = open(file, "wb") + fd.writelines(file_contents) + fd.close() + + except security.ACMError: + pass + except: + traceback.print_exc(limit=1) + + +def main (argv): + try: + if len(argv) != 3: + usage() + return + + if argv[1].lower() == "dom": + configfile = argv[2] + rm_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + rm_resource_label(resource) + else: + usage() + + except security.ACMError: + traceback.print_exc(limit=1) + + +if __name__ == '__main__': + main(sys.argv) + + _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |