From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Bryan D. Payne" Subject: [PATCH][ACM][RESEND] python tools and support for resource labeling Date: Mon, 10 Jul 2006 09:29:24 -0400 Message-ID: <44B25634.4070900@us.ibm.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------090406020103040207010804" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: sailer@us.ibm.com, bdpayne@us.ibm.com List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------090406020103040207010804 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit (same patch as the one sent previously, updated to patch cleanly against the current changeset) This patch adds new xm subcommands to support working with resource labels. The new subcommands are 'xm resources', 'xm rmlabel', 'xm getlabel' and 'xm dry-run'. In addition, the 'xm addlabel' subcommand now uses an updated syntax to support labeling both domains and resources. See the xm man page for details on each subcommand. Beyond the new subcommands, this patch allows users to immediately see when security checks will fail by pushing some basic security checking into the beginning of 'xm create' and 'xm block-attach'. ACM security attributes for block devices are added to XenStore in order to support the final security enforcement, which will be performed in the kernel and included in a separate patch. Signed-off-by: Bryan D. Payne Signed-off-by: Reiner Sailer --------------090406020103040207010804 Content-Type: text/x-patch; name="shype-reslabel-enforce-python-20.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="shype-reslabel-enforce-python-20.diff" --- 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 | 150 ++++++++++++++++++++++++++-------- tools/python/xen/xm/create.py | 121 ++++++++++++++++++++++++++- tools/python/xen/xm/dry-run.py | 56 ++++++++++++ tools/python/xen/xm/getlabel.py | 114 +++++++++++++++++++++++++ tools/python/xen/xm/main.py | 30 ++++++ tools/python/xen/xm/resources.py | 56 ++++++++++++ tools/python/xen/xm/rmlabel.py | 118 ++++++++++++++++++++++++++ 10 files changed, 764 insertions(+), 41 deletions(-) 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 +#============================================================================ + + +def dict_read(dictname, filename): + """Loads and returns the dictionary named 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 to using the name . 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 #============================================================================ 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,59 +14,139 @@ #============================================================================ # Copyright (C) 2006 International Business Machines Corp. # Author: Reiner Sailer +# Author: Bryan D. Payne #============================================================================ -"""Labeling a domain configuration file. +"""Labeling a domain configuration file or a resoruce. """ import sys, os +import string import traceback +from xen.util import dictio +from xen.util import security +def usage(): + print "\nUsage: xm addlabel