WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] This patch integrates the new access control management

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] This patch integrates the new access control management tools into 'xm'
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 24 Apr 2006 14:30:11 +0000
Delivery-date: Mon, 24 Apr 2006 08:01:02 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User smh22@xxxxxxxxxxxxxxxxxxxx
# Node ID 681a18bf049e320ddb11dde9cca08fa7bba4192e
# Parent  cf20dbbf5c2b3c2331ae3f37e85589d0b0237dc6
This patch integrates the new access control management tools into 'xm' 
and 'xend' and supports label/ssid translation support for 
migration/life-migration/resume.

Signed-off by: Reiner Sailer <sailer@xxxxxxxxxx>

diff -r cf20dbbf5c2b -r 681a18bf049e tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Mon Apr 24 10:58:25 2006 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Mon Apr 24 10:59:17 2006 +0100
@@ -38,6 +38,7 @@ from xen.xend.XendLogging import log
 from xen.xend.XendLogging import log
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
+from xen.util import security
 
 
 xc = xen.lowlevel.xc.xc()
@@ -265,7 +266,7 @@ class XendDomain:
             # handling in the relocation-socket handling code (relocate.py) is
             # poor, so we need to log this for debugging.
             log.exception("Restore failed")
-            raise
+            raise XendError("Restore failed")
 
 
     def restore_(self, config):
@@ -283,6 +284,7 @@ class XendDomain:
         """
         self.domains_lock.acquire()
         try:
+            security.refresh_ssidref(config)
             dominfo = XendDomainInfo.restore(config)
             self._add_domain(dominfo)
             return dominfo
diff -r cf20dbbf5c2b -r 681a18bf049e tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Apr 24 10:58:25 2006 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Apr 24 10:59:17 2006 +0100
@@ -33,7 +33,7 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file
-
+from xen.util import security
 import balloon
 import image
 import sxp
@@ -126,7 +126,6 @@ VM_CONFIG_PARAMS = [
 # file, so those are handled separately.
 ROUNDTRIPPING_CONFIG_ENTRIES = [
     ('uuid',       str),
-    ('ssidref',    int),
     ('vcpus',      int),
     ('vcpu_avail', int),
     ('cpu_weight', float),
@@ -144,7 +143,6 @@ ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFI
 #
 VM_STORE_ENTRIES = [
     ('uuid',       str),
-    ('ssidref',    int),
     ('vcpus',      int),
     ('vcpu_avail', int),
     ('memory',     int),
@@ -297,6 +295,9 @@ def parseConfig(config):
     result['cpu']   = get_cfg('cpu',  int)
     result['cpus']  = get_cfg('cpus', str)
     result['image'] = get_cfg('image')
+    tmp_security = get_cfg('security')
+    if tmp_security:
+        result['security'] = tmp_security
 
     try:
         if result['image']:
@@ -443,7 +444,7 @@ class XendDomainInfo:
         self.validateInfo()
 
         self.image = None
-
+        self.security = None
         self.store_port = None
         self.store_mfn = None
         self.console_port = None
@@ -521,6 +522,7 @@ class XendDomainInfo:
         else:
             entries = VM_STORE_ENTRIES
         entries.append(('image', str))
+        entries.append(('security', str))
 
         map(lambda x, y: useIfNeeded(x[0], y), entries,
             self.readVMDetails(entries))
@@ -544,7 +546,6 @@ class XendDomainInfo:
 
         try:
             defaultInfo('name',         lambda: "Domain-%d" % self.domid)
-            defaultInfo('ssidref',      lambda: 0)
             defaultInfo('on_poweroff',  lambda: "destroy")
             defaultInfo('on_reboot',    lambda: "restart")
             defaultInfo('on_crash',     lambda: "restart")
@@ -571,11 +572,15 @@ class XendDomainInfo:
             defaultInfo('backend',      lambda: [])
             defaultInfo('device',       lambda: [])
             defaultInfo('image',        lambda: None)
+            defaultInfo('security',     lambda: None)
 
             self.check_name(self.info['name'])
 
             if isinstance(self.info['image'], str):
                 self.info['image'] = sxp.from_string(self.info['image'])
+
+            if isinstance(self.info['security'], str):
+                self.info['security'] = sxp.from_string(self.info['security'])
 
             if self.info['memory'] == 0:
                 if self.infoIsSet('mem_kb'):
@@ -673,6 +678,20 @@ class XendDomainInfo:
 
         if self.infoIsSet('image'):
             to_store['image'] = sxp.to_string(self.info['image'])
+
+        if self.infoIsSet('security'):
+            security = self.info['security']
+            to_store['security'] = sxp.to_string(security)
+            for idx in range(0, len(security)):
+                if security[idx][0] == 'access_control':
+                    to_store['security/access_control'] = sxp.to_string([ 
security[idx][1] , security[idx][2] ])
+                    for aidx in range(1, len(security[idx])):
+                        if security[idx][aidx][0] == 'label':
+                            to_store['security/access_control/label'] = 
security[idx][aidx][1]
+                        if security[idx][aidx][0] == 'policy':
+                            to_store['security/access_control/policy'] = 
security[idx][aidx][1]
+                if security[idx][0] == 'ssidref':
+                    to_store['security/ssidref'] = str(security[idx][1])
 
         log.debug("Storing VM details: %s", to_store)
 
@@ -766,9 +785,8 @@ class XendDomainInfo:
         self.storeVm('vcpu_avail', self.info['vcpu_avail'])
         self.writeDom(self.vcpuDomDetails())
 
-
-    def getSsidref(self):
-        return self.info['ssidref']
+    def getLabel(self):
+        return security.get_security_info(self.info, 'label')
 
     def getMemoryTarget(self):
         """Get this domain's target memory size, in KB."""
@@ -960,12 +978,21 @@ class XendDomainInfo:
         """
 
         log.trace("XendDomainInfo.update(%s) on domain %d", info, self.domid)
-
         if not info:
             info = dom_get(self.domid)
             if not info:
                 return
             
+        #manually update ssidref / security fields
+        if security.on() and info.has_key('ssidref'):
+            if (info['ssidref'] != 0) and self.info.has_key('security'):
+                security_field = self.info['security']
+                if not security_field:
+                    #create new security element
+                    self.info.update({'security': [['ssidref', 
str(info['ssidref'])]]})
+            #ssidref field not used any longer
+        info.pop('ssidref')
+
         self.info.update(info)
         self.validateInfo()
         self.refreshShutdown(info)
@@ -1002,7 +1029,6 @@ class XendDomainInfo:
         s += " id=" + str(self.domid)
         s += " name=" + self.info['name']
         s += " memory=" + str(self.info['memory'])
-        s += " ssidref=" + str(self.info['ssidref'])
         s += ">"
         return s
 
@@ -1063,6 +1089,9 @@ class XendDomainInfo:
         
         if self.infoIsSet('image'):
             sxpr.append(['image', self.info['image']])
+
+        if self.infoIsSet('security'):
+            sxpr.append(['security', self.info['security']])
 
         for cls in controllerClasses:
             for config in self.getDeviceConfigurations(cls):
@@ -1165,12 +1194,11 @@ class XendDomainInfo:
         @raise: VmError on error
         """
 
-        log.debug('XendDomainInfo.construct: %s %s',
-                  self.domid,
-                  self.info['ssidref'])
+        log.debug('XendDomainInfo.construct: %s',
+                  self.domid)
 
         self.domid = xc.domain_create(
-            dom = 0, ssidref = self.info['ssidref'],
+            dom = 0, ssidref = security.get_security_info(self.info, 
'ssidref'),
             handle = uuid.fromString(self.info['uuid']))
 
         if self.domid < 0:
diff -r cf20dbbf5c2b -r 681a18bf049e tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Mon Apr 24 10:58:25 2006 +0100
+++ b/tools/python/xen/xm/create.py     Mon Apr 24 10:59:17 2006 +0100
@@ -35,6 +35,7 @@ from xen.xend.XendClient import server
 from xen.xend.XendClient import server
 from xen.xend.XendBootloader import bootloader
 from xen.util import blkif
+from xen.util import security
 
 from xen.xm.opts import *
 
@@ -144,10 +145,6 @@ gopts.var('memory', val='MEMORY',
 gopts.var('memory', val='MEMORY',
           fn=set_int, default=128,
           use="Domain memory in MB.")
-
-gopts.var('ssidref', val='SSIDREF',
-          fn=set_u32, default=0, 
-          use="Security Identifier.")
 
 gopts.var('maxmem', val='MEMORY',
           fn=set_int, default=None,
@@ -293,6 +290,14 @@ gopts.var('vtpm', val="instance=INSTANCE
           number can be found in /etc/xen/vtpm.db. Use the backend in the
           given domain.""")
 
+gopts.var('access_control', val="policy=POLICY,label=LABEL",
+          fn=append_value, default=[],
+          use="""Add a security label and the security policy reference that 
defines it.
+          The local ssid reference is calculated when starting/resuming the 
domain. At
+          this time, the policy is checked against the active policy as well. 
This way,
+          migrating through save/restore is covered and local labels are 
automatically
+          created correctly on the system where a domain is started / 
resumed.""")
+
 gopts.var('nics', val="NUM",
           fn=set_int, default=-1,
           use="""DEPRECATED.  Use empty vif entries instead.
@@ -501,6 +506,43 @@ def configure_usb(config_devs, vals):
     for path in vals.usb:
         config_usb = ['usb', ['path', path]]
         config_devs.append(['device', config_usb])
+
+
+def configure_security(config, vals):
+    """Create the config for ACM security labels.
+    """
+    access_control = vals.access_control
+    num = len(access_control)
+    if num == 1:
+        d = access_control[0]
+        policy = d.get('policy')
+        label = d.get('label')
+        if policy != security.active_policy:
+            err("Security policy (" + policy + ") incompatible with enforced 
policy ("
+                + security.active_policy + ")." )
+        config_access_control = ['access_control',
+                                 ['policy', policy],
+                                 ['label', label] ]
+
+        #ssidref cannot be specified together with access_control
+        if sxp.child_value(config, 'ssidref'):
+            err("ERROR: SSIDREF and access_control are mutually exclusive but 
both specified!")
+        #else calculate ssidre from label
+        ssidref = security.label2ssidref(label, policy)
+        if not ssidref :
+            err("ERROR calculating ssidref from access_control.")
+        security_label = ['security', [ config_access_control, ['ssidref' , 
ssidref ] ] ]
+        config.append(security_label)
+    elif num == 0:
+        if hasattr(vals, 'ssidref'):
+            if not security.on():
+                err("ERROR: Security ssidref specified but no policy active.")
+            ssidref = getattr(vals, 'ssidref')
+            security_label = ['security', [ [ 'ssidref' , int(ssidref) ] ] ]
+            config.append(security_label)
+    elif num > 1:
+        err("VM config error: Multiple access_control definitions!")
+
 
 def configure_vtpm(config_devs, vals):
     """Create the config for virtual TPM interfaces.
@@ -595,9 +637,9 @@ def make_config(vals):
             if v:
                 config.append([n, v])
 
-    map(add_conf, ['name', 'memory', 'ssidref', 'maxmem', 'restart',
-                   'on_poweroff', 'on_reboot', 'on_crash', 'vcpus'])
-    
+    map(add_conf, ['name', 'memory', 'maxmem', 'restart', 'on_poweroff',
+                   'on_reboot', 'on_crash', 'vcpus'])
+
     if vals.uuid is not None:
         config.append(['uuid', vals.uuid])
     if vals.cpu is not None:
@@ -628,6 +670,7 @@ def make_config(vals):
     configure_vifs(config_devs, vals)
     configure_usb(config_devs, vals)
     configure_vtpm(config_devs, vals)
+    configure_security(config, vals)
     config += config_devs
 
     return config
@@ -696,6 +739,29 @@ def preprocess_vtpm(vals):
         vtpms.append(d)
     vals.vtpm = vtpms
 
+def preprocess_access_control(vals):
+    if not vals.access_control:
+        return
+    access_controls = []
+    num = len(vals.access_control)
+    if num == 1:
+        access_control = (vals.access_control)[0]
+        d = {}
+        a = access_control.split(',')
+        if len(a) > 2:
+            err('Too many elements in access_control specifier: ' + 
access_control)
+        for b in a:
+            (k, v) = b.strip().split('=', 1)
+            k = k.strip()
+            v = v.strip()
+            if k not in ['policy','label']:
+                err('Invalid access_control specifier: ' + access_control)
+            d[k] = v
+        access_controls.append(d)
+        vals.access_control = access_controls
+    elif num > 1:
+        err('Multiple access_control definitions.')
+
 def preprocess_ip(vals):
     if vals.ip or vals.dhcp != 'off':
         dummy_nfs_server = '1.2.3.4'
@@ -785,6 +851,7 @@ def preprocess(vals):
     preprocess_nfs(vals)
     preprocess_vnc(vals)
     preprocess_vtpm(vals)
+    preprocess_access_control(vals)
 
 
 def comma_sep_kv_to_dict(c):
diff -r cf20dbbf5c2b -r 681a18bf049e tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Apr 24 10:58:25 2006 +0100
+++ b/tools/python/xen/xm/main.py       Mon Apr 24 10:59:17 2006 +0100
@@ -40,6 +40,7 @@ import console
 import console
 import xen.xend.XendClient
 from xen.xend.XendClient import server
+from xen.util import security
 
 # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
 # getopt.getopt if gnu_getopt is not available.  This will mean that options
@@ -55,6 +56,8 @@ destroy_help = "destroy <DomId>         
 destroy_help = "destroy <DomId>                  Terminate a domain 
immediately"
 help_help =    "help                             Display this message"
 list_help =    "list [--long] [DomId, ...]       List information about 
domains"
+list_label_help = "list [--label] [DomId, ...]      List information about 
domains including their labels"
+
 mem_max_help = "mem-max <DomId> <Mem>            Set maximum memory 
reservation for a domain"
 mem_set_help = "mem-set <DomId> <Mem>            Adjust the current memory 
usage for a domain"
 migrate_help = "migrate <DomId> <Host>           Migrate a domain to another 
machine"
@@ -114,6 +117,12 @@ vnet_create_help = "vnet-create <config>
 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"
+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"
+makepolicy_help = "makepolicy <policy>              Build policy and create 
.bin/.map files"
+labels_help     = "labels [policy] [type=DOM|..]    List <type> labels for 
(active) policy."
 
 short_command_list = [
     "console",
@@ -140,6 +149,7 @@ domain_commands = [
     "domid",
     "domname",
     "list",
+    "list_label",
     "mem-max",
     "mem-set",
     "migrate",
@@ -185,8 +195,17 @@ vnet_commands = [
     "vnet-delete",
     ]
 
+acm_commands = [
+    "labels",
+    "addlabel",
+    "makepolicy",
+    "loadpolicy",
+    "cfgbootpolicy",
+    "dumppolicy"
+    ]
+
 all_commands = (domain_commands + host_commands + scheduler_commands +
-                device_commands + vnet_commands)
+                device_commands + vnet_commands + acm_commands)
 
 
 def commandToHelp(cmd):
@@ -224,6 +243,9 @@ xm full list of subcommands:
 
   Vnet commands:
    """ + help_spacer.join(map(commandToHelp,  vnet_commands)) + """
+
+  Access Control commands:
+   """ + help_spacer.join(map(commandToHelp,  acm_commands)) + """
 
 <DomName> can be substituted for <DomId> in xm subcommands.
 
@@ -332,8 +354,9 @@ def xm_list(args):
 def xm_list(args):
     use_long = 0
     show_vcpus = 0
+    show_labels = 0
     try:
-        (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus'])
+        (options, params) = getopt.gnu_getopt(args, 'lv', 
['long','vcpus','label'])
     except getopt.GetoptError, opterr:
         err(opterr)
         sys.exit(1)
@@ -343,6 +366,8 @@ def xm_list(args):
             use_long = 1
         if k in ['-v', '--vcpus']:
             show_vcpus = 1
+        if k in ['--label']:
+            show_labels = 1
 
     if show_vcpus:
         print >>sys.stderr, (
@@ -354,6 +379,8 @@ def xm_list(args):
 
     if use_long:
         map(PrettyPrint.prettyprint, doms)
+    elif show_labels:
+        xm_label_list(doms)
     else:
         xm_brief_list(doms)
 
@@ -369,7 +396,7 @@ def parse_doms_info(info):
         'vcpus'    : get_info('online_vcpus', int,   0),
         'state'    : get_info('state',        str,   '??'),
         'cpu_time' : get_info('cpu_time',     float, 0),
-        'ssidref'  : get_info('ssidref',      int,   0),
+        'seclabel' : security.get_security_printlabel(info),
         }
 
 
@@ -391,13 +418,29 @@ def xm_brief_list(doms):
     print 'Name                              ID Mem(MiB) VCPUs State  Time(s)'
     for dom in doms:
         d = parse_doms_info(dom)
-        if (d['ssidref'] != 0):
-            d['ssidstr'] = (" s:%04x/p:%04x" % 
-                            ((d['ssidref'] >> 16) & 0xffff,
-                              d['ssidref']        & 0xffff))
+        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s 
%(cpu_time)7.1f" % d)
+
+
+def xm_label_list(doms):
+    output = []
+    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)  
Label'
+    for dom in doms:
+        d = parse_doms_info(dom)
+        l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s 
%(cpu_time)7.1f  " % d
+        if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
+            if d['seclabel']:
+                line = (l, d['seclabel'])
+            else:
+                line = (l, "ERROR")
+        elif security.active_policy in ['DEFAULT']:
+            line = (l, "DEFAULT")
         else:
-            d['ssidstr'] = ""
-        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s 
%(cpu_time)7.1f%(ssidstr)s" % d)
+            line = (l, "INACTIVE")
+        output.append(line)
+    #sort by labels
+    output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
+    for l in output:
+        print l[0] + l[1]
 
 
 def xm_vcpu_list(args):
@@ -1010,7 +1053,13 @@ subcommands = [
     'create',
     'migrate',
     'sysrq',
-    'shutdown'
+    'shutdown',
+    'labels',
+    'addlabel',
+    'cfgbootpolicy',
+    'makepolicy',
+    'loadpolicy',
+    'dumppolicy'
     ]
 
 for c in subcommands:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] This patch integrates the new access control management tools into 'xm', Xen patchbot -unstable <=