ia64/xen-unstable

changeset 15575:73b6733e4bb1

[XM] Tools support for extensions of the Xen-API for managing security policies

This patch adds a couple of new commands for using the Xen-API
extensions for security policies. Older tools are converted to support
going through the Xen-API for their operations rather than doing the
operations directly in their own code.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kfraser@localhost.localdomain
date Wed Jul 11 10:49:43 2007 +0100 (2007-07-11)
parents 637ff26be6ff
children eae9dc5e7898
files tools/python/xen/xm/activatepolicy.py tools/python/xen/xm/addlabel.py tools/python/xen/xm/cfgbootpolicy.py tools/python/xen/xm/create.dtd tools/python/xen/xm/create.py tools/python/xen/xm/getlabel.py tools/python/xen/xm/getpolicy.py tools/python/xen/xm/labels.py tools/python/xen/xm/loadpolicy.py tools/python/xen/xm/main.py tools/python/xen/xm/makepolicy.py tools/python/xen/xm/resources.py tools/python/xen/xm/rmlabel.py tools/python/xen/xm/setpolicy.py tools/python/xen/xm/xenapi_create.py
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/python/xen/xm/activatepolicy.py	Wed Jul 11 10:49:43 2007 +0100
     1.3 @@ -0,0 +1,86 @@
     1.4 +#============================================================================
     1.5 +# This library is free software; you can redistribute it and/or
     1.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     1.7 +# License as published by the Free Software Foundation.
     1.8 +#
     1.9 +# This library is distributed in the hope that it will be useful,
    1.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.12 +# Lesser General Public License for more details.
    1.13 +#
    1.14 +# You should have received a copy of the GNU Lesser General Public
    1.15 +# License along with this library; if not, write to the Free Software
    1.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.17 +#============================================================================
    1.18 +# Copyright (C) 2007 International Business Machines Corp.
    1.19 +# Author: Stefan Berger <stefanb@us.ibm.com>
    1.20 +#============================================================================
    1.21 +
    1.22 +"""Activate the managed policy of the system.
    1.23 +"""
    1.24 +
    1.25 +import sys
    1.26 +from xen.util import xsconstants
    1.27 +from xml.dom import minidom
    1.28 +from xen.xm.opts import OptionError
    1.29 +from xen.xm import getpolicy
    1.30 +from xen.xm import main as xm_main
    1.31 +from xen.xm.main import server
    1.32 +
    1.33 +def help():
    1.34 +    return """
    1.35 +    Usage: xm activatepolicy [options]
    1.36 +
    1.37 +    Activate the xend-managed policy.
    1.38 +
    1.39 +    The following options are defined:
    1.40 +      --load     Load the policy into the hypervisor.
    1.41 +      --boot     Have the system boot with the policy. Changes the default
    1.42 +                 title in grub.conf.
    1.43 +      --noboot   Remove the policy from the default entry in grub.conf.
    1.44 +    """
    1.45 +
    1.46 +def activate_policy(flags):
    1.47 +    policystate = server.xenapi.XSPolicy.get_xspolicy()
    1.48 +    xs_ref = policystate['xs_ref']
    1.49 +    if int(policystate['type']) == 0 or xs_ref == "":
    1.50 +        print "No policy is installed."
    1.51 +        return
    1.52 +    rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags))
    1.53 +    if rc == flags:
    1.54 +        print "Successfully activated the policy."
    1.55 +    else:
    1.56 +        print "An error occurred trying to activate the policy: %s" % \
    1.57 +              xsconstants.xserr2string(rc)
    1.58 +
    1.59 +def remove_bootpolicy():
    1.60 +    server.xenapi.XSPolicy.rm_xsbootpolicy()
    1.61 +
    1.62 +def main(argv):
    1.63 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
    1.64 +        raise OptionError('xm needs to be configured to use the xen-api.')
    1.65 +    flags = 0
    1.66 +    c = 1
    1.67 +
    1.68 +    while c < len(argv):
    1.69 +        if '--boot' == argv[c]:
    1.70 +            flags |= xsconstants.XS_INST_BOOT
    1.71 +        elif '--load' == argv[c]:
    1.72 +            flags |= xsconstants.XS_INST_LOAD
    1.73 +        elif '--noboot' == argv[c]:
    1.74 +            remove_bootpolicy()
    1.75 +        else:
    1.76 +            raise OptionError("Unknown command line option '%s'" % argv[c])
    1.77 +        c += 1
    1.78 +
    1.79 +    if flags != 0:
    1.80 +        activate_policy(flags)
    1.81 +
    1.82 +    getpolicy.getpolicy(False)
    1.83 +
    1.84 +if __name__ == '__main__':
    1.85 +    try:
    1.86 +        main(sys.argv)
    1.87 +    except Exception, e:
    1.88 +        sys.stderr.write('Error: %s\n' % str(e))
    1.89 +        sys.exit(-1)
     2.1 --- a/tools/python/xen/xm/addlabel.py	Wed Jul 11 10:48:15 2007 +0100
     2.2 +++ b/tools/python/xen/xm/addlabel.py	Wed Jul 11 10:49:43 2007 +0100
     2.3 @@ -25,17 +25,29 @@ import sys
     2.4  from xen.util import dictio
     2.5  from xen.util import security
     2.6  from xen.xm.opts import OptionError
     2.7 +from xen.util import xsconstants
     2.8 +from xen.xm import main as xm_main
     2.9 +from xen.xm.main import server
    2.10  
    2.11  def help():
    2.12      return """
    2.13      Format: xm addlabel <label> dom <configfile> [<policy>]
    2.14 -            xm addlabel <label> res <resource> [<policy>]
    2.15 +            xm addlabel <label> mgt <domain name> [<policy type>:<policy>]
    2.16 +            xm addlabel <label> res <resource> [[<policy type>:]<policy>]
    2.17      
    2.18      This program adds an acm_label entry into the 'configfile'
    2.19 -    for a domain or to the global resource label file for a
    2.20 -    resource. It derives the policy from the running hypervisor
    2.21 +    for a domain or allows to label a xend-managed domain.
    2.22 +    The global resource label file for is extended with labels for
    2.23 +    resources. It derives the policy from the running hypervisor
    2.24      if it is not given (optional parameter). If a label already
    2.25 -    exists for the given domain or resource, then addlabel fails."""
    2.26 +    exists for the given domain or resource, then addlabel fails.
    2.27 +
    2.28 +    For xend-managed domains, the 'mgt' parameter should be used and
    2.29 +    the 'xm' tool must have been configured to use the xen-api for
    2.30 +    communication with xen. If a policy is provided as last parameter,
    2.31 +    its type must also be given. Currently only one type of policy is
    2.32 +    supported and identified as 'ACM'. An example for a valid string
    2.33 +    is 'ACM:xm-test'. """
    2.34  
    2.35  
    2.36  def validate_config_file(configfile):
    2.37 @@ -66,32 +78,47 @@ def validate_config_file(configfile):
    2.38          return 1
    2.39  
    2.40  
    2.41 -def add_resource_label(label, resource, policyref):
    2.42 +def add_resource_label(label, resource, policyref, policy_type):
    2.43      """Adds a resource label to the global resource label file.
    2.44      """
    2.45 -    # sanity check: make sure this label can be instantiated later on
    2.46 -    ssidref = security.label2ssidref(label, policyref, 'res')
    2.47 +
    2.48 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
    2.49 +
    2.50 +        # sanity check: make sure this label can be instantiated later on
    2.51 +        ssidref = security.label2ssidref(label, policyref, 'res')
    2.52 +
    2.53 +        #build canonical resource name
    2.54 +        resource = security.unify_resname(resource,mustexist=False)
    2.55  
    2.56 -    #build canonical resource name
    2.57 -    resource = security.unify_resname(resource)
    2.58 +        # see if this resource is already in the file
    2.59 +        access_control = {}
    2.60 +        fil = security.res_label_filename
    2.61 +        try:
    2.62 +            access_control = dictio.dict_read("resources", fil)
    2.63 +        except:
    2.64 +            print "Resource file not found, creating new file at:"
    2.65 +            print "%s" % (fil)
    2.66  
    2.67 -    # see if this resource is already in the file
    2.68 -    access_control = {}
    2.69 -    file = security.res_label_filename
    2.70 -    try:
    2.71 -        access_control = dictio.dict_read("resources", file)
    2.72 -    except:
    2.73 -        print "Resource file not found, creating new file at:"
    2.74 -        print "%s" % (file)
    2.75 +        if access_control.has_key(resource):
    2.76 +            security.err("This resource is already labeled.")
    2.77  
    2.78 -    if access_control.has_key(resource):
    2.79 -        security.err("This resource is already labeled.")
    2.80 -
    2.81 -    # write the data to file
    2.82 -    new_entry = { resource : tuple([policyref, label]) }
    2.83 -    access_control.update(new_entry)
    2.84 -    dictio.dict_write(access_control, "resources", file)
    2.85 -
    2.86 +        # write the data to file
    2.87 +        new_entry = { resource : tuple([policy_type, policyref, label]) }
    2.88 +        access_control.update(new_entry)
    2.89 +        dictio.dict_write(access_control, "resources", fil)
    2.90 +    else:
    2.91 +        res = [ policy_type, policyref, label ]
    2.92 +        res_xapi = security.format_resource_label(res)
    2.93 +        old = server.xenapi.XSPolicy.get_resource_label(resource)
    2.94 +        if old == "":
    2.95 +            try:
    2.96 +                server.xenapi.XSPolicy.set_resource_label(resource,
    2.97 +                                                          res_xapi,
    2.98 +                                                          "")
    2.99 +            except Exception, e:
   2.100 +                security.err("Could not label this resource: %s" % e)
   2.101 +        else:
   2.102 +            security.err("'%s' is already labeled with '%s'" % (resource,old))
   2.103  
   2.104  def add_domain_label(label, configfile, policyref):
   2.105      # sanity checks: make sure this label can be instantiated later on
   2.106 @@ -109,9 +136,35 @@ def add_domain_label(label, configfile, 
   2.107      config_fd.write(new_label)
   2.108      config_fd.close()
   2.109  
   2.110 +def add_domain_label_xapi(label, domainname, policyref, policy_type):
   2.111 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
   2.112 +        raise OptionError('Xm must be configured to use the xen-api.')
   2.113 +    uuids = server.xenapi.VM.get_by_name_label(domainname)
   2.114 +    if len(uuids) == 0:
   2.115 +        raise OptionError('A VM with that name does not exist.')
   2.116 +    if len(uuids) != 1:
   2.117 +        raise OptionError('There are multiple domains with the same name.')
   2.118 +    uuid = uuids[0]
   2.119 +    sec_lab = "%s:%s:%s" % (policy_type, policyref, label)
   2.120 +    try:
   2.121 +        old_lab = server.xenapi.VM.get_security_label(uuid)
   2.122 +        rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab)
   2.123 +    except:
   2.124 +        rc = -1
   2.125 +    if int(rc) < 0:
   2.126 +        raise OptionError('Could not label domain.')
   2.127 +    else:
   2.128 +        ssidref = int(rc)
   2.129 +        if ssidref != 0:
   2.130 +            print "Set the label of domain '%s' to '%s'. New ssidref = %08x" % \
   2.131 +                  (domainname,label,ssidref)
   2.132 +        else:
   2.133 +            print "Set the label of dormant domain '%s' to '%s'." % \
   2.134 +                  (domainname,label)
   2.135  
   2.136  def main(argv):
   2.137      policyref = None
   2.138 +    policy_type = ""
   2.139      if len(argv) not in (4, 5):
   2.140          raise OptionError('Needs either 2 or 3 arguments')
   2.141      
   2.142 @@ -121,6 +174,7 @@ def main(argv):
   2.143          policyref = argv[4]
   2.144      elif security.on():
   2.145          policyref = security.active_policy
   2.146 +        policy_type = xsconstants.ACM_POLICY_ID
   2.147      else:
   2.148          raise OptionError("No active policy. Must specify policy on the "
   2.149                            "command line.")
   2.150 @@ -136,11 +190,27 @@ def main(argv):
   2.151              raise OptionError('Invalid config file')
   2.152          else:
   2.153              add_domain_label(label, configfile, policyref)
   2.154 +    elif argv[2].lower() == "mgt":
   2.155 +        domain = argv[3]
   2.156 +        if policy_type == "":
   2.157 +            tmp = policyref.split(":")
   2.158 +            if len(tmp) != 2:
   2.159 +                raise OptionError("Policy name in wrong format.")
   2.160 +            policy_type, policyref = tmp
   2.161 +        add_domain_label_xapi(label, domain, policyref, policy_type)
   2.162      elif argv[2].lower() == "res":
   2.163          resource = argv[3]
   2.164 -        add_resource_label(label, resource, policyref)
   2.165 +        if policy_type == "":
   2.166 +            tmp = policyref.split(":")
   2.167 +            if len(tmp) == 1:
   2.168 +                policy_type = xsconstants.ACM_POLICY_ID
   2.169 +            elif len(tmp) == 2:
   2.170 +                policy_type, policyref = tmp
   2.171 +            else:
   2.172 +                raise OptionError("Policy name in wrong format.")
   2.173 +        add_resource_label(label, resource, policyref, policy_type)
   2.174      else:
   2.175 -        raise OptionError('Need to specify either "dom" or "res" as '
   2.176 +        raise OptionError('Need to specify either "dom", "mgt" or "res" as '
   2.177                            'object to add label to.')
   2.178              
   2.179  if __name__ == '__main__':
   2.180 @@ -149,6 +219,3 @@ if __name__ == '__main__':
   2.181      except Exception, e:
   2.182          sys.stderr.write('Error: %s\n' % str(e))
   2.183          sys.exit(-1)
   2.184 -    
   2.185 -
   2.186 -
     3.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Wed Jul 11 10:48:15 2007 +0100
     3.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Wed Jul 11 10:49:43 2007 +0100
     3.3 @@ -31,7 +31,11 @@ from xen.util.security import policy_dir
     3.4  from xen.util.security import boot_filename, altboot_filename
     3.5  from xen.util.security import any_title_re, xen_kernel_re, any_module_re
     3.6  from xen.util.security import empty_line_re, binary_name_re, policy_name_re
     3.7 +from xen.util import xsconstants
     3.8  from xen.xm.opts import OptionError
     3.9 +from xen.xm import main as xm_main
    3.10 +from xen.xm.main import server
    3.11 +from xen.util.acmpolicy import ACMPolicy
    3.12  
    3.13  def help():
    3.14      return """
    3.15 @@ -144,6 +148,39 @@ def insert_policy(boot_file, alt_boot_fi
    3.16          pass
    3.17      return extended_titles[0]
    3.18  
    3.19 +def cfgbootpolicy_xapi(policy, user_title=None):
    3.20 +    xstype = int(server.xenapi.XSPolicy.get_xstype())
    3.21 +    if xstype & xsconstants.XS_POLICY_ACM == 0:
    3.22 +        raise OptionError("ACM policy not supported on system.")
    3.23 +    if user_title:
    3.24 +        raise OptionError("Only the default title is supported with Xen-API.")
    3.25 +
    3.26 +    policystate = server.xenapi.XSPolicy.get_xspolicy()
    3.27 +    if int(policystate['type']) == 0:
    3.28 +        print "No policy is installed."
    3.29 +        return
    3.30 +
    3.31 +    if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
    3.32 +        print "Unknown policy type '%s'." % policystate['type']
    3.33 +        return
    3.34 +    else:
    3.35 +        xml = policystate['repr']
    3.36 +        xs_ref = policystate['xs_ref']
    3.37 +        if not xml:
    3.38 +            OptionError("No policy installed on system?")
    3.39 +        acmpol = ACMPolicy(xml=xml)
    3.40 +        if acmpol.get_name() != policy:
    3.41 +            OptionError("Policy installed on system '%s' does not match the "
    3.42 +                        "request policy '%s'" % (acmpol.get_name(), policy))
    3.43 +        flags = int(policystate['flags']) | xsconstants.XS_INST_BOOT
    3.44 +        rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags))
    3.45 +        if rc == flags:
    3.46 +            print "Successfully enabled the policy for having the system" \
    3.47 +                  " booted with."
    3.48 +        else:
    3.49 +            print "An error occurred during the operation: %s" % \
    3.50 +                  xsconstants.xserr2string(rc)
    3.51 +
    3.52  
    3.53  def main(argv):
    3.54      user_kver = None
    3.55 @@ -159,24 +196,27 @@ def main(argv):
    3.56      if not policy_name_re.match(policy):
    3.57          raise OptionError("Illegal policy name: '%s'" % policy)
    3.58  
    3.59 -    policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
    3.60 -    src_binary_policy_file = policy_file + ".bin"
    3.61 -    #check if .bin exists or if policy file exists
    3.62 -    if not os.path.isfile(src_binary_policy_file):
    3.63 -        if not os.path.isfile(policy_file + "-security_policy.xml"):
    3.64 -            raise OptionError("Unknown policy '%s'" % policy)
    3.65 -        else:
    3.66 -            err_msg = "Cannot find binary file for policy '%s'." % policy
    3.67 -            err_msg += " Please use makepolicy to create binary file."
    3.68 -            raise OptionError(err_msg)
    3.69 +    if xm_main.serverType == xm_main.SERVER_XEN_API:
    3.70 +        cfgbootpolicy_xapi(policy)
    3.71 +    else:
    3.72 +        policy_file = '/'.join([policy_dir_prefix] + policy.split('.'))
    3.73 +        src_binary_policy_file = policy_file + ".bin"
    3.74 +        #check if .bin exists or if policy file exists
    3.75 +        if not os.path.isfile(src_binary_policy_file):
    3.76 +            if not os.path.isfile(policy_file + "-security_policy.xml"):
    3.77 +                raise OptionError("Unknown policy '%s'" % policy)
    3.78 +            else:
    3.79 +                err_msg = "Cannot find binary file for policy '%s'." % policy
    3.80 +                err_msg += " Please use makepolicy to create binary file."
    3.81 +                raise OptionError(err_msg)
    3.82      
    3.83 -    dst_binary_policy_file = "/boot/" + policy + ".bin"
    3.84 -    shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
    3.85 +        dst_binary_policy_file = "/boot/" + policy + ".bin"
    3.86 +        shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
    3.87      
    3.88 -    entryname = insert_policy(boot_filename, altboot_filename,
    3.89 -                              user_title, policy)
    3.90 -    print "Boot entry '%s' extended and \'%s\' copied to /boot" \
    3.91 -          % (entryname, policy + ".bin")
    3.92 +        entryname = insert_policy(boot_filename, altboot_filename,
    3.93 +                                  user_title, policy)
    3.94 +        print "Boot entry '%s' extended and \'%s\' copied to /boot" \
    3.95 +              % (entryname, policy + ".bin")
    3.96  
    3.97  if __name__ == '__main__':
    3.98      try:
     4.1 --- a/tools/python/xen/xm/create.dtd	Wed Jul 11 10:48:15 2007 +0100
     4.2 +++ b/tools/python/xen/xm/create.dtd	Wed Jul 11 10:49:43 2007 +0100
     4.3 @@ -38,6 +38,7 @@
     4.4                   memory,
     4.5                   vbd*,
     4.6                   vif*,
     4.7 +                 vtpm*,
     4.8                   console*,
     4.9                   platform*,
    4.10                   vcpu_param*,
    4.11 @@ -49,7 +50,8 @@
    4.12                   actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
    4.13                   actions_after_reboot   %NORMAL_EXIT; #REQUIRED
    4.14                   actions_after_crash    %CRASH_BEHAVIOUR; #REQUIRED
    4.15 -                 PCI_bus                CDATA #REQUIRED> 
    4.16 +                 PCI_bus                CDATA #REQUIRED
    4.17 +                 security_label         CDATA #IMPLIED>
    4.18  
    4.19  <!ELEMENT memory EMPTY> 
    4.20  <!ATTLIST memory static_min      CDATA #REQUIRED
    4.21 @@ -74,6 +76,9 @@
    4.22                   qos_algorithm_type CDATA    #REQUIRED
    4.23                   network         CDATA       #IMPLIED> 
    4.24  
    4.25 +<!ELEMENT vtpm   (name*)>
    4.26 +<!ATTLIST vtpm   backend         CDATA #REQUIRED>
    4.27 +
    4.28  <!ELEMENT console (other_config*)>
    4.29  <!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
    4.30  
     5.1 --- a/tools/python/xen/xm/create.py	Wed Jul 11 10:48:15 2007 +0100
     5.2 +++ b/tools/python/xen/xm/create.py	Wed Jul 11 10:49:43 2007 +0100
     5.3 @@ -643,22 +643,12 @@ def configure_security(config, vals):
     5.4                                   ['policy', policy],
     5.5                                   ['label', label] ]
     5.6  
     5.7 -        #ssidref cannot be specified together with access_control
     5.8 -        if sxp.child_value(config, 'ssidref'):
     5.9 -            err("ERROR: SSIDREF and access_control are mutually exclusive but both specified!")
    5.10 -        #else calculate ssidre from label
    5.11 +        #calculate ssidref from label
    5.12          ssidref = security.label2ssidref(label, policy, 'dom')
    5.13          if not ssidref :
    5.14              err("ERROR calculating ssidref from access_control.")
    5.15          security_label = ['security', [ config_access_control, ['ssidref' , ssidref ] ] ]
    5.16          config.append(security_label)
    5.17 -    elif num == 0:
    5.18 -        if hasattr(vals, 'ssidref'):
    5.19 -            if not security.on():
    5.20 -                err("ERROR: Security ssidref specified but no policy active.")
    5.21 -            ssidref = getattr(vals, 'ssidref')
    5.22 -            security_label = ['security', [ [ 'ssidref' , int(ssidref) ] ] ]
    5.23 -            config.append(security_label)
    5.24      elif num > 1:
    5.25          err("VM config error: Multiple access_control definitions!")
    5.26  
    5.27 @@ -1231,13 +1221,13 @@ def config_security_check(config, verbos
    5.28  
    5.29          except security.ACMError:
    5.30              print "   %s: DENIED" % (resource)
    5.31 -            (res_label, res_policy) = security.get_res_label(resource)
    5.32 +            (poltype, res_label, res_policy) = security.get_res_label(resource)
    5.33              if not res_label:
    5.34                  res_label = ""
    5.35 -            print "   --> res: %s (%s)" % (str(res_label),
    5.36 -                                           str(res_policy))
    5.37 -            print "   --> dom: %s (%s)" % (str(domain_label),
    5.38 -                                           str(domain_policy))
    5.39 +            print "   --> res: %s (%s:%s)" % (str(res_label),
    5.40 +                                           str(poltype), str(res_policy))
    5.41 +            print "   --> dom: %s (%s:%s)" % (str(domain_label),
    5.42 +                                           str(poltype), str(domain_policy))
    5.43  
    5.44              answer = 0
    5.45  
     6.1 --- a/tools/python/xen/xm/getlabel.py	Wed Jul 11 10:48:15 2007 +0100
     6.2 +++ b/tools/python/xen/xm/getlabel.py	Wed Jul 11 10:49:43 2007 +0100
     6.3 @@ -21,14 +21,19 @@
     6.4  import sys, os, re
     6.5  from xen.util import dictio
     6.6  from xen.util import security
     6.7 +from xen.util import xsconstants
     6.8  from xen.xm.opts import OptionError
     6.9 +from xen.xm import main as xm_main
    6.10 +from xen.xm.main import server
    6.11  
    6.12  def help():
    6.13      return """
    6.14      Usage: xm getlabel dom <configfile>
    6.15 +           xm getlabel mgt <domain name>
    6.16             xm getlabel res <resource>
    6.17             
    6.18 -    This program shows the label for a domain or resource."""
    6.19 +    This program shows the label for a domain, resource or virtual network
    6.20 +    interface of a Xend-managed domain."""
    6.21  
    6.22  def get_resource_label(resource):
    6.23      """Gets the resource label
    6.24 @@ -37,17 +42,24 @@ def get_resource_label(resource):
    6.25      resource = security.unify_resname(resource)
    6.26  
    6.27      # read in the resource file
    6.28 -    file = security.res_label_filename
    6.29 +    fil = security.res_label_filename
    6.30      try:
    6.31 -        access_control = dictio.dict_read("resources", file)
    6.32 +        access_control = dictio.dict_read("resources", fil)
    6.33      except:
    6.34          raise OptionError("Resource label file not found")
    6.35  
    6.36      # get the entry and print label
    6.37      if access_control.has_key(resource):
    6.38 -        policy = access_control[resource][0]
    6.39 -        label = access_control[resource][1]
    6.40 -        print "policy="+policy+",label="+label
    6.41 +        tmp = access_control[resource]
    6.42 +        if len(tmp) == 2:
    6.43 +            policy, label = tmp
    6.44 +            policytype = xsconstants.ACM_POLICY_ID
    6.45 +        elif len(tmp) == 3:
    6.46 +            policytype, policy, label = tmp
    6.47 +        else:
    6.48 +            raise security.ACMError("Resource not properly labeled. "
    6.49 +                                    "Please relabel the resource.")
    6.50 +        print policytype+":"+policy+":"+label
    6.51      else:
    6.52          raise security.ACMError("Resource not labeled")
    6.53  
    6.54 @@ -89,8 +101,19 @@ def get_domain_label(configfile):
    6.55      data = data.strip()
    6.56      data = data.lstrip("[\'")
    6.57      data = data.rstrip("\']")
    6.58 -    print data
    6.59 +    print "policytype=%s," % xsconstants.ACM_POLICY_ID + data
    6.60  
    6.61 +def get_domain_label_xapi(domainname):
    6.62 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
    6.63 +        raise OptionError('xm needs to be configure to use the xen-api.')
    6.64 +    uuids = server.xenapi.VM.get_by_name_label(domainname)
    6.65 +    if len(uuids) == 0:
    6.66 +        raise OptionError('A VM with that name does not exist.')
    6.67 +    if len(uuids) != 1:
    6.68 +        raise OptionError('There are multiple domains with the same name.')
    6.69 +    uuid = uuids[0]
    6.70 +    sec_lab = server.xenapi.VM.get_security_label(uuid)
    6.71 +    print "%s" %sec_lab
    6.72  
    6.73  def main(argv):
    6.74      if len(argv) != 3:
    6.75 @@ -99,11 +122,15 @@ def main(argv):
    6.76      if argv[1].lower() == "dom":
    6.77          configfile = argv[2]
    6.78          get_domain_label(configfile)
    6.79 +    elif argv[1].lower() == "mgt":
    6.80 +        domainname = argv[2]
    6.81 +        get_domain_label_xapi(domainname)
    6.82      elif argv[1].lower() == "res":
    6.83          resource = argv[2]
    6.84          get_resource_label(resource)
    6.85      else:
    6.86 -        raise OptionError('First subcommand argument must be "dom" or "res"')
    6.87 +        raise OptionError('First subcommand argument must be "dom"'
    6.88 +                          ', "mgt" or "res"')
    6.89  
    6.90  if __name__ == '__main__':
    6.91      try:
    6.92 @@ -111,6 +138,4 @@ if __name__ == '__main__':
    6.93      except Exception, e:
    6.94          sys.stderr.write('Error: %s\n' % str(e))
    6.95          sys.exit(-1)
    6.96 -        
    6.97  
    6.98 -
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/python/xen/xm/getpolicy.py	Wed Jul 11 10:49:43 2007 +0100
     7.3 @@ -0,0 +1,94 @@
     7.4 +#============================================================================
     7.5 +# This library is free software; you can redistribute it and/or
     7.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     7.7 +# License as published by the Free Software Foundation.
     7.8 +#
     7.9 +# This library is distributed in the hope that it will be useful,
    7.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.12 +# Lesser General Public License for more details.
    7.13 +#
    7.14 +# You should have received a copy of the GNU Lesser General Public
    7.15 +# License along with this library; if not, write to the Free Software
    7.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.17 +#============================================================================
    7.18 +# Copyright (C) 2007 International Business Machines Corp.
    7.19 +# Author: Stefan Berger <stefanb@us.ibm.com>
    7.20 +#============================================================================
    7.21 +
    7.22 +"""Get the managed policy of the system.
    7.23 +"""
    7.24 +
    7.25 +import sys
    7.26 +from xen.util import xsconstants
    7.27 +from xml.dom import minidom
    7.28 +from xen.xm.opts import OptionError
    7.29 +from xen.util.acmpolicy import ACMPolicy
    7.30 +from xen.xm import main as xm_main
    7.31 +from xen.xm.main import server
    7.32 +
    7.33 +def help():
    7.34 +    return """
    7.35 +    Usage: xm getpolicy [options]
    7.36 +
    7.37 +    The following options are defined
    7.38 +      --dumpxml     Display the XML of the policy
    7.39 +
    7.40 +    Get the policy managed by xend."""
    7.41 +
    7.42 +def getpolicy(dumpxml):
    7.43 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
    7.44 +        raise OptionError('xm needs to be configured to use the xen-api.')
    7.45 +    types = []
    7.46 +    xstype = int(server.xenapi.XSPolicy.get_xstype())
    7.47 +    if xstype & xsconstants.XS_POLICY_ACM:
    7.48 +        types.append("ACM")
    7.49 +        xstype ^= xsconstants.XS_POLICY_ACM
    7.50 +    if xstype != 0:
    7.51 +        types.append("unsupported (%08x)" % xstype)
    7.52 +    print "Supported security subsystems   : %s \n" % ", ".join(types)
    7.53 +
    7.54 +    policystate = server.xenapi.XSPolicy.get_xspolicy()
    7.55 +    if int(policystate['type']) == 0:
    7.56 +        print "No policy is installed."
    7.57 +        return
    7.58 +    if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
    7.59 +        print "Unknown policy type '%s'." % policystate['type']
    7.60 +    else:
    7.61 +        xml = policystate['repr']
    7.62 +        acmpol = None
    7.63 +        if xml:
    7.64 +            acmpol = ACMPolicy(xml=xml)
    7.65 +        print "Policy installed on the system:"
    7.66 +        if acmpol:
    7.67 +            print "Policy name           : %s" % acmpol.get_name()
    7.68 +        print "Policy type           : %s" % xsconstants.ACM_POLICY_ID
    7.69 +        print "Reference             : %s" % policystate['xs_ref']
    7.70 +        print "Version of XML policy : %s" % policystate['version']
    7.71 +        state = []
    7.72 +        flags = int(policystate['flags'])
    7.73 +        if flags & xsconstants.XS_INST_LOAD:
    7.74 +            state.append("loaded")
    7.75 +        if flags & xsconstants.XS_INST_BOOT:
    7.76 +            state.append("system booted with")
    7.77 +        print "State of the policy   : %s" % ", ".join(state)
    7.78 +        if dumpxml:
    7.79 +            xml = policystate['repr']
    7.80 +            if xml:
    7.81 +                dom = minidom.parseString(xml.encode("utf-8"))
    7.82 +                print "%s" % dom.toprettyxml(indent="   ",newl="\n")
    7.83 +
    7.84 +def main(argv):
    7.85 +    dumpxml = False
    7.86 +
    7.87 +    if '--dumpxml' in argv:
    7.88 +        dumpxml = True
    7.89 +
    7.90 +    getpolicy(dumpxml)
    7.91 +
    7.92 +if __name__ == '__main__':
    7.93 +    try:
    7.94 +        main(sys.argv)
    7.95 +    except Exception, e:
    7.96 +        sys.stderr.write('Error: %s\n' % str(e))
    7.97 +        sys.exit(-1)
     8.1 --- a/tools/python/xen/xm/labels.py	Wed Jul 11 10:48:15 2007 +0100
     8.2 +++ b/tools/python/xen/xm/labels.py	Wed Jul 11 10:49:43 2007 +0100
     8.3 @@ -24,6 +24,10 @@ import string
     8.4  from xen.util.security import ACMError, err, list_labels, active_policy
     8.5  from xen.util.security import vm_label_re, res_label_re, all_label_re
     8.6  from xen.xm.opts import OptionError
     8.7 +from xen.util.acmpolicy import ACMPolicy
     8.8 +from xen.util import xsconstants
     8.9 +from xen.xm.main import server
    8.10 +from xen.xm import main as xm_main
    8.11  
    8.12  
    8.13  def help():
    8.14 @@ -48,6 +52,12 @@ def main(argv):
    8.15          else:
    8.16              raise OptionError('Unrecognised option: %s' % arg)
    8.17  
    8.18 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
    8.19 +        labels(policy, ptype)
    8.20 +    else:
    8.21 +        labels_xapi(policy, ptype)
    8.22 +
    8.23 +def labels(policy, ptype):
    8.24      if not policy:
    8.25          policy = active_policy
    8.26          if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
    8.27 @@ -73,7 +83,30 @@ def main(argv):
    8.28      except:
    8.29          traceback.print_exc(limit = 1)
    8.30  
    8.31 +def labels_xapi(policy, ptype):
    8.32 +    policystate = server.xenapi.XSPolicy.get_xspolicy()
    8.33 +    if int(policystate['type']) == xsconstants.XS_POLICY_ACM:
    8.34 +        acmpol = ACMPolicy(xml=policystate['repr'])
    8.35 +        if policy and policy != acmpol.get_name():
    8.36 +            print "Warning: '%s' is not the currently loaded policy." % policy
    8.37 +            return labels(policy, ptype)
    8.38 +        names1 = []
    8.39 +        names2 = []
    8.40 +        if not ptype or ptype == 'dom' or ptype == 'any':
    8.41 +            names1 = acmpol.policy_get_virtualmachinelabel_names()
    8.42 +        if ptype == 'res' or ptype == 'any':
    8.43 +            names2 = acmpol.policy_get_resourcelabel_names()
    8.44 +        if len(names1) > 0:
    8.45 +            names = set(names1)
    8.46 +            names.union(names2)
    8.47 +        else:
    8.48 +            names = set(names2)
    8.49 +        for n in names:
    8.50 +            print n
    8.51 +    elif int(policystate['type']) == 0:
    8.52 +        print "No policy installed on the system."
    8.53 +    else:
    8.54 +        print "Unsupported type of policy installed on the system."
    8.55 +
    8.56  if __name__ == '__main__':
    8.57      main(sys.argv)
    8.58 -
    8.59 -
     9.1 --- a/tools/python/xen/xm/loadpolicy.py	Wed Jul 11 10:48:15 2007 +0100
     9.2 +++ b/tools/python/xen/xm/loadpolicy.py	Wed Jul 11 10:49:43 2007 +0100
     9.3 @@ -22,6 +22,11 @@ import sys
     9.4  import traceback
     9.5  from xen.util.security import ACMError, err, load_policy
     9.6  from xen.xm.opts import OptionError
     9.7 +from xen.xm import main as xm_main
     9.8 +from xen.util import xsconstants
     9.9 +from xen.xm.activatepolicy import activate_policy
    9.10 +from xen.xm.main import server
    9.11 +from xen.util.acmpolicy import ACMPolicy
    9.12  
    9.13  def help():
    9.14      return """Load the compiled binary (.bin) policy into the running
    9.15 @@ -30,8 +35,31 @@ def help():
    9.16  def main(argv):
    9.17      if len(argv) != 2:
    9.18          raise OptionError('No policy defined')
    9.19 -    
    9.20 -    load_policy(argv[1])
    9.21 +    if xm_main.serverType == xm_main.SERVER_XEN_API:
    9.22 +        policy = argv[1]
    9.23 +        print "This command is deprecated for use with Xen-API " \
    9.24 +              "configuration. Consider using\n'xm activatepolicy'."
    9.25 +        policystate = server.xenapi.XSPolicy.get_xspolicy()
    9.26 +        if int(policystate['type']) == 0:
    9.27 +            print "No policy is installed."
    9.28 +            return
    9.29 +
    9.30 +        if int(policystate['type']) != xsconstants.XS_POLICY_ACM:
    9.31 +            print "Unknown policy type '%s'." % policystate['type']
    9.32 +            return
    9.33 +        else:
    9.34 +            xml = policystate['repr']
    9.35 +            xs_ref = policystate['xs_ref']
    9.36 +            if not xml:
    9.37 +                OptionError("No policy installed on system?")
    9.38 +            acmpol = ACMPolicy(xml=xml)
    9.39 +            if acmpol.get_name() != policy:
    9.40 +                OptionError("Policy installed on system '%s' does not match"\
    9.41 +                            " the request policy '%s'" % \
    9.42 +                            (acmpol.get_name(), policy))
    9.43 +            activate_policy(xsconstants.XS_INST_LOAD)
    9.44 +    else:
    9.45 +        load_policy(argv[1])
    9.46  
    9.47  if __name__ == '__main__':
    9.48      try:
    10.1 --- a/tools/python/xen/xm/main.py	Wed Jul 11 10:48:15 2007 +0100
    10.2 +++ b/tools/python/xen/xm/main.py	Wed Jul 11 10:49:43 2007 +0100
    10.3 @@ -50,6 +50,7 @@ from xen.xend.XendConstants import *
    10.4  from xen.xm.opts import OptionError, Opts, wrap, set_true
    10.5  from xen.xm import console
    10.6  from xen.util.xmlrpcclient import ServerProxy
    10.7 +from xen.util.security import ACMError
    10.8  
    10.9  import XenAPI
   10.10  
   10.11 @@ -171,11 +172,12 @@ SUBCOMMAND_HELP = {
   10.12  
   10.13      # security
   10.14  
   10.15 -    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
   10.16 +    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>|mgt <managed domain>}\n'
   10.17 +                        '                   [<policy>]',
   10.18                          'Add security label to domain.'),
   10.19 -    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>}',
   10.20 +    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>|mgt<managed domain>}',
   10.21                          'Remove a security label from domain.'),
   10.22 -    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>}',
   10.23 +    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>|mgt <managed domain>}',
   10.24                          'Show security label for domain or resource.'),
   10.25      'dry-run'       :  ('<ConfigFile>',
   10.26                          'Test if a domain can access its resources.'),
   10.27 @@ -186,6 +188,10 @@ SUBCOMMAND_HELP = {
   10.28      'loadpolicy'    :  ('<policy.bin>', 'Load binary policy into hypervisor.'),
   10.29      'makepolicy'    :  ('<policy>', 'Build policy and create .bin/.map '
   10.30                          'files.'),
   10.31 +    'setpolicy'     :  ('<policytype> <policyfile> [options]',
   10.32 +                        'Set the policy of the system.'),
   10.33 +    'getpolicy'     :  ('[options]', 'Get the policy of the system.'),
   10.34 +    'activatepolicy':  ('[options]', 'Activate the xend-managed policy.'),
   10.35      'labels'        :  ('[policy] [type=dom|res|any]',
   10.36                          'List <type> labels for (active) policy.'),
   10.37      'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
   10.38 @@ -343,6 +349,9 @@ acm_commands = [
   10.39      "loadpolicy",
   10.40      "cfgbootpolicy",
   10.41      "dumppolicy",
   10.42 +    "activatepolicy",
   10.43 +    "setpolicy",
   10.44 +    "getpolicy",
   10.45      ]
   10.46  
   10.47  all_commands = (domain_commands + host_commands + scheduler_commands +
   10.48 @@ -861,13 +870,17 @@ def parse_doms_info(info):
   10.49          'up_time'  : up_time
   10.50          }
   10.51  
   10.52 -    # We're not supporting security stuff just yet via XenAPI
   10.53 -
   10.54      if serverType != SERVER_XEN_API:
   10.55          from xen.util import security
   10.56          parsed_info['seclabel'] = security.get_security_printlabel(info)
   10.57      else:
   10.58 -        parsed_info['seclabel'] = ""
   10.59 +        label = get_info('security_label', unicode, '')
   10.60 +        tmp = label.split(":")
   10.61 +        if len(tmp) != 3:
   10.62 +            label = ""
   10.63 +        else:
   10.64 +            label = tmp[2]
   10.65 +        parsed_info['seclabel'] = label
   10.66  
   10.67      if serverType == SERVER_XEN_API:
   10.68          parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
   10.69 @@ -925,28 +938,26 @@ def xm_brief_list(doms):
   10.70          print format % d
   10.71  
   10.72  def xm_label_list(doms):
   10.73 -    print '%-32s %5s %5s %5s %5s %9s %-8s' % \
   10.74 +    print '%-32s %5s %5s %5s %10s %9s %-8s' % \
   10.75            ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
   10.76      
   10.77      output = []
   10.78      format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
   10.79               '%(cpu_time)8.1f %(seclabel)9s'
   10.80  
   10.81 -    if serverType != SERVER_XEN_API:
   10.82 -        from xen.util import security
   10.83 +    from xen.util import security
   10.84          
   10.85 -        for dom in doms:
   10.86 -            d = parse_doms_info(dom)
   10.87 +    for dom in doms:
   10.88 +        d = parse_doms_info(dom)
   10.89 +        if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
   10.90 +            if not d['seclabel']:
   10.91 +                d['seclabel'] = 'ERROR'
   10.92 +        elif security.active_policy in ['DEFAULT']:
   10.93 +            d['seclabel'] = 'DEFAULT'
   10.94 +        else:
   10.95 +            d['seclabel'] = 'INACTIVE'
   10.96  
   10.97 -            if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
   10.98 -                if not d['seclabel']:
   10.99 -                    d['seclabel'] = 'ERROR'
  10.100 -            elif security.active_policy in ['DEFAULT']:
  10.101 -                d['seclabel'] = 'DEFAULT'
  10.102 -            else:
  10.103 -                d['seclabel'] = 'INACTIVE'
  10.104 -
  10.105 -            output.append((format % d, d['seclabel']))
  10.106 +        output.append((format % d, d['seclabel']))
  10.107          
  10.108      #sort by labels
  10.109      output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
  10.110 @@ -1989,16 +2000,24 @@ def xm_block_list(args):
  10.111                     % ni)
  10.112  
  10.113  def xm_vtpm_list(args):
  10.114 -    xenapi_unsupported()
  10.115      (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
  10.116  
  10.117      dom = params[0]
  10.118 +
  10.119 +    if serverType == SERVER_XEN_API:
  10.120 +        vtpm_refs = server.xenapi.VM.get_VTPMs(get_single_vm(dom))
  10.121 +        vtpm_properties = \
  10.122 +            map(server.xenapi.VTPM.get_runtime_properties, vtpm_refs)
  10.123 +        devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
  10.124 +                   zip(range(len(vtpm_properties)), vtpm_properties))
  10.125 +    else:
  10.126 +        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
  10.127 +
  10.128      if use_long:
  10.129 -        devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
  10.130          map(PrettyPrint.prettyprint, devs)
  10.131      else:
  10.132          hdr = 0
  10.133 -        for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
  10.134 +        for x in devs:
  10.135              if hdr == 0:
  10.136                  print 'Idx  BE handle state evt-ch ring-ref BE-path'
  10.137                  hdr = 1
  10.138 @@ -2440,6 +2459,9 @@ IMPORTED_COMMANDS = [
  10.139      'getlabel',
  10.140      'dry-run',
  10.141      'resources',
  10.142 +    'getpolicy',
  10.143 +    'setpolicy',
  10.144 +    'activatepolicy',
  10.145      ]
  10.146  
  10.147  for c in IMPORTED_COMMANDS:
  10.148 @@ -2563,6 +2585,8 @@ def _run_cmd(cmd, cmd_name, args):
  10.149          print e.usage
  10.150      except XenAPIUnsupportedException, e:
  10.151          err(str(e))
  10.152 +    except ACMError, e:
  10.153 +        err(str(e))
  10.154      except Exception, e:
  10.155          if serverType != SERVER_XEN_API:
  10.156             from xen.util import security
    11.1 --- a/tools/python/xen/xm/makepolicy.py	Wed Jul 11 10:48:15 2007 +0100
    11.2 +++ b/tools/python/xen/xm/makepolicy.py	Wed Jul 11 10:49:43 2007 +0100
    11.3 @@ -20,7 +20,10 @@
    11.4  import sys
    11.5  import traceback
    11.6  from xen.util.security import ACMError, err, make_policy
    11.7 +from xen.util import xsconstants
    11.8  from xen.xm.opts import OptionError
    11.9 +from xen.xm import main as xm_main
   11.10 +from xen.xm.setpolicy import setpolicy
   11.11  
   11.12  def usage():
   11.13      print "\nUsage: xm makepolicy <policy>\n"
   11.14 @@ -32,8 +35,13 @@ def usage():
   11.15  def main(argv):
   11.16      if len(argv) != 2:
   11.17          raise OptionError('No XML policy file specified')
   11.18 -
   11.19 -    make_policy(argv[1])
   11.20 +    if xm_main.serverType == xm_main.SERVER_XEN_API:
   11.21 +        print "This command is deprecated for use with Xen-API " \
   11.22 +              "configuration. Consider using\n'xm setpolicy'."
   11.23 +        setpolicy(xsconstants.ACM_POLICY_ID, argv[1],
   11.24 +                  xsconstants.XS_INST_LOAD, True)
   11.25 +    else:
   11.26 +        make_policy(argv[1])
   11.27  
   11.28  if __name__ == '__main__':
   11.29      try:
   11.30 @@ -41,5 +49,3 @@ if __name__ == '__main__':
   11.31      except Exception, e:
   11.32          sys.stderr.write('Error: %s\n' % str(e))
   11.33          sys.exit(-1)
   11.34 -
   11.35 -
    12.1 --- a/tools/python/xen/xm/resources.py	Wed Jul 11 10:48:15 2007 +0100
    12.2 +++ b/tools/python/xen/xm/resources.py	Wed Jul 11 10:49:43 2007 +0100
    12.3 @@ -21,7 +21,10 @@
    12.4  import sys
    12.5  from xen.util import dictio
    12.6  from xen.util import security
    12.7 +from xen.util import xsconstants
    12.8  from xen.xm.opts import OptionError
    12.9 +from xen.xm import main as xm_main
   12.10 +from xen.xm.main import server
   12.11  
   12.12  def help():
   12.13      return """
   12.14 @@ -32,20 +35,32 @@ def print_resource_data(access_control):
   12.15      """Prints out a resource dictionary to stdout
   12.16      """
   12.17      for resource in access_control:
   12.18 -        (policy, label) = access_control[resource]
   12.19 +        tmp = access_control[resource]
   12.20 +        if len(tmp) == 2:
   12.21 +            policytype = xsconstants.ACM_POLICY_ID
   12.22 +            (policy, label) = access_control[resource]
   12.23 +        elif len(tmp) == 3:
   12.24 +            policytype, policy, label = access_control[resource]
   12.25          print resource
   12.26 -        print "    policy: "+policy
   12.27 -        print "    label:  "+label
   12.28 +        print "      type: "+ policytype
   12.29 +        print "    policy: "+ policy
   12.30 +        print "    label:  "+ label
   12.31  
   12.32  def main (argv):
   12.33      if len(argv) > 1:
   12.34          raise OptionError("No arguments required")
   12.35 -    
   12.36 -    try:
   12.37 -        filename = security.res_label_filename
   12.38 -        access_control = dictio.dict_read("resources", filename)
   12.39 -    except:
   12.40 -        raise OptionError("Resource file not found")
   12.41 +
   12.42 +    if xm_main.serverType == xm_main.SERVER_XEN_API:
   12.43 +        access_control = server.xenapi.XSPolicy.get_labeled_resources()
   12.44 +        for key, value in access_control.items():
   12.45 +            access_control[key] = tuple(value.split(':'))
   12.46 +    else:
   12.47 +        try:
   12.48 +            filename = security.res_label_filename
   12.49 +            access_control = dictio.dict_read("resources", filename)
   12.50 +            print access_control
   12.51 +        except:
   12.52 +            raise OptionError("Resource file not found")
   12.53  
   12.54      print_resource_data(access_control)
   12.55  
    13.1 --- a/tools/python/xen/xm/rmlabel.py	Wed Jul 11 10:48:15 2007 +0100
    13.2 +++ b/tools/python/xen/xm/rmlabel.py	Wed Jul 11 10:49:43 2007 +0100
    13.3 @@ -22,35 +22,52 @@ import sys, os, re
    13.4  from xen.util import dictio
    13.5  from xen.util import security
    13.6  from xen.xm.opts import OptionError
    13.7 +from xen.xm import main as xm_main
    13.8 +from xen.xm.main import server
    13.9  
   13.10  def help():
   13.11      return """
   13.12      Example: xm rmlabel dom <configfile>
   13.13               xm rmlabel res <resource>
   13.14 +             xm rmlabel mgt <domain name>
   13.15  
   13.16      This program removes an acm_label entry from the 'configfile'
   13.17 -    for a domain or from the global resource label file for a
   13.18 -    resource. If the label does not exist for the given domain or
   13.19 -    resource, then rmlabel fails."""
   13.20 +    for a domain, from a Xend-managed domain, from the global resource label
   13.21 +    file for a resource or from the virtual network interface of a Xend-managed
   13.22 +    domain. If the label does not exist for the given domain or resource, then
   13.23 +    rmlabel fails."""
   13.24  
   13.25  
   13.26  def rm_resource_label(resource):
   13.27      """Removes a resource label from the global resource label file.
   13.28      """
   13.29 +    # Try Xen-API first if configured to use it
   13.30 +    if xm_main.serverType == xm_main.SERVER_XEN_API:
   13.31 +        try:
   13.32 +            oldlabel = server.xenapi.XSPolicy.get_resource_label(resource)
   13.33 +            if oldlabel != "":
   13.34 +                server.xenapi.XSPolicy.set_resource_label(resource,"",
   13.35 +                                                          oldlabel)
   13.36 +            else:
   13.37 +                raise security.ACMError("Resource not labeled")
   13.38 +        except Exception, e:
   13.39 +            print "Could not remove label from resource: %s" % e
   13.40 +        return
   13.41 +
   13.42      #build canonical resource name
   13.43      resource = security.unify_resname(resource)
   13.44  
   13.45      # read in the resource file
   13.46 -    file = security.res_label_filename
   13.47 +    fil = security.res_label_filename
   13.48      try:
   13.49 -        access_control = dictio.dict_read("resources", file)
   13.50 +        access_control = dictio.dict_read("resources", fil)
   13.51      except:
   13.52          raise security.ACMError("Resource file not found, cannot remove label!")
   13.53  
   13.54      # remove the entry and update file
   13.55      if access_control.has_key(resource):
   13.56          del access_control[resource]
   13.57 -        dictio.dict_write(access_control, "resources", file)
   13.58 +        dictio.dict_write(access_control, "resources", fil)
   13.59      else:
   13.60          raise security.ACMError("Resource not labeled")
   13.61  
   13.62 @@ -58,15 +75,15 @@ def rm_resource_label(resource):
   13.63  def rm_domain_label(configfile):
   13.64      # open the domain config file
   13.65      fd = None
   13.66 -    file = None
   13.67 +    fil = None
   13.68      if configfile[0] == '/':
   13.69 -        file = configfile
   13.70 -        fd = open(file, "rb")
   13.71 +        fil = configfile
   13.72 +        fd = open(fil, "rb")
   13.73      else:
   13.74          for prefix in [".", "/etc/xen"]:
   13.75 -            file = prefix + "/" + configfile
   13.76 -            if os.path.isfile(file):
   13.77 -                fd = open(file, "rb")
   13.78 +            fil = prefix + "/" + configfile
   13.79 +            if os.path.isfile(fil):
   13.80 +                fd = open(fil, "rb")
   13.81                  break
   13.82      if not fd:
   13.83          raise OptionError("Configuration file '%s' not found." % configfile)
   13.84 @@ -93,22 +110,40 @@ def rm_domain_label(configfile):
   13.85          raise security.ACMError('Domain not labeled')
   13.86  
   13.87      # write the data back out to the file
   13.88 -    fd = open(file, "wb")
   13.89 +    fd = open(fil, "wb")
   13.90      fd.writelines(file_contents)
   13.91      fd.close()
   13.92  
   13.93 +def rm_domain_label_xapi(domainname):
   13.94 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
   13.95 +        raise OptionError('Need to be configure for using xen-api.')
   13.96 +    uuids = server.xenapi.VM.get_by_name_label(domainname)
   13.97 +    if len(uuids) == 0:
   13.98 +        raise OptionError('A VM with that name does not exist.')
   13.99 +    if len(uuids) != 1:
  13.100 +        raise OptionError('Too many domains with the same name.')
  13.101 +    uuid = uuids[0]
  13.102 +    try:
  13.103 +        old_lab = server.xenapi.VM.get_security_label(uuid)
  13.104 +        server.xenapi.VM.set_security_label(uuid, "", old_lab)
  13.105 +    except Exception, e:
  13.106 +        print('Could not remove label from domain: %s' % e)
  13.107 +
  13.108  
  13.109  def main (argv):
  13.110  
  13.111      if len(argv) != 3:
  13.112          raise OptionError('Requires 2 arguments')
  13.113      
  13.114 -    if argv[1].lower() not in ('dom', 'res'):
  13.115 +    if argv[1].lower() not in ('dom', 'mgt', 'res'):
  13.116          raise OptionError('Unrecognised type argument: %s' % argv[1])
  13.117  
  13.118      if argv[1].lower() == "dom":
  13.119          configfile = argv[2]
  13.120          rm_domain_label(configfile)
  13.121 +    elif argv[1].lower() == "mgt":
  13.122 +        domain = argv[2]
  13.123 +        rm_domain_label_xapi(domain)
  13.124      elif argv[1].lower() == "res":
  13.125          resource = argv[2]
  13.126          rm_resource_label(resource)
  13.127 @@ -119,5 +154,3 @@ if __name__ == '__main__':
  13.128      except Exception, e:
  13.129          sys.stderr.write('Error: %s\n' % str(e))
  13.130          sys.exit(-1)    
  13.131 -
  13.132 -
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/python/xen/xm/setpolicy.py	Wed Jul 11 10:49:43 2007 +0100
    14.3 @@ -0,0 +1,117 @@
    14.4 +#============================================================================
    14.5 +# This library is free software; you can redistribute it and/or
    14.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    14.7 +# License as published by the Free Software Foundation.
    14.8 +#
    14.9 +# This library is distributed in the hope that it will be useful,
   14.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14.12 +# Lesser General Public License for more details.
   14.13 +#
   14.14 +# You should have received a copy of the GNU Lesser General Public
   14.15 +# License along with this library; if not, write to the Free Software
   14.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   14.17 +#============================================================================
   14.18 +# Copyright (C) 2007 International Business Machines Corp.
   14.19 +# Author: Stefan Berger <stefanb@us.ibm.com>
   14.20 +#============================================================================
   14.21 +
   14.22 +"""Get the managed policy of the system.
   14.23 +"""
   14.24 +
   14.25 +import base64
   14.26 +import struct
   14.27 +import sys
   14.28 +import string
   14.29 +from xen.util import xsconstants
   14.30 +from xen.xm.opts import OptionError
   14.31 +from xen.util.security import policy_dir_prefix
   14.32 +from xen.xm import main as xm_main
   14.33 +from xen.xm.main import server
   14.34 +
   14.35 +def help():
   14.36 +    return """
   14.37 +    Usage: xm setpolicy <policytype> <policy> [options]
   14.38 +
   14.39 +    Set the policy managed by xend.
   14.40 +
   14.41 +    The only policytype that is currently supported is 'ACM'.
   14.42 +
   14.43 +    The following options are defined
   14.44 +      --load     Load the policy immediately
   14.45 +      --boot     Have the system load the policy during boot
   14.46 +    """
   14.47 +
   14.48 +def setpolicy(policytype, policy_name, flags, overwrite):
   14.49 +    if xm_main.serverType != xm_main.SERVER_XEN_API:
   14.50 +        raise OptionError('xm needs to be configured to use the xen-api.')
   14.51 +    if policytype != xsconstants.ACM_POLICY_ID:
   14.52 +        raise OptionError("Unsupported policytype '%s'." % policytype)
   14.53 +    else:
   14.54 +        xs_type = xsconstants.XS_POLICY_ACM
   14.55 +
   14.56 +        policy_file = policy_dir_prefix + "/" + \
   14.57 +                      string.join(string.split(policy_name, "."), "/")
   14.58 +        policy_file += "-security_policy.xml"
   14.59 +
   14.60 +        try:
   14.61 +            f = open(policy_file,"r")
   14.62 +            xml = f.read(-1)
   14.63 +            f.close()
   14.64 +        except:
   14.65 +            raise OptionError("Not a valid policy file")
   14.66 +
   14.67 +        try:
   14.68 +            policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type,
   14.69 +                                                              xml,
   14.70 +                                                              flags,
   14.71 +                                                              overwrite)
   14.72 +        except Exception, e:
   14.73 +            print "An error occurred setting the policy: %s" % str(e)
   14.74 +            return
   14.75 +        xserr = int(policystate['xserr'])
   14.76 +        if xserr != 0:
   14.77 +            print "An error occurred trying to set the policy: %s" % \
   14.78 +                  xsconstants.xserr2string(abs(xserr))
   14.79 +            errors = policystate['errors']
   14.80 +            if len(errors) > 0:
   14.81 +                print "Hypervisor reported errors:"
   14.82 +                err = base64.b64decode(errors)
   14.83 +                i = 0
   14.84 +                while i + 7 < len(err):
   14.85 +                    code, data = struct.unpack("!ii", errors[i:i+8])
   14.86 +                    print "(0x%08x, 0x%08x)" % (code, data)
   14.87 +                    i += 8
   14.88 +        else:
   14.89 +            print "Successfully set the new policy."
   14.90 +
   14.91 +
   14.92 +def main(argv):
   14.93 +    if len(argv) < 3:
   14.94 +       raise OptionError("Need at least 3 arguments.")
   14.95 +
   14.96 +    if "-?" in argv:
   14.97 +        help()
   14.98 +        return
   14.99 +
  14.100 +    policytype  = argv[1]
  14.101 +    policy_name = argv[2]
  14.102 +
  14.103 +    flags = 0
  14.104 +    if '--load' in argv:
  14.105 +        flags |= xsconstants.XS_INST_LOAD
  14.106 +    if '--boot' in argv:
  14.107 +        flags |= xsconstants.XS_INST_BOOT
  14.108 +
  14.109 +    overwrite = True
  14.110 +    if '--nooverwrite' in argv:
  14.111 +        overwrite = False
  14.112 +
  14.113 +    setpolicy(policytype, policy_name, flags, overwrite)
  14.114 +
  14.115 +if __name__ == '__main__':
  14.116 +    try:
  14.117 +        main(sys.argv)
  14.118 +    except Exception, e:
  14.119 +        sys.stderr.write('Error: %s\n' % str(e))
  14.120 +        sys.exit(-1)
    15.1 --- a/tools/python/xen/xm/xenapi_create.py	Wed Jul 11 10:48:15 2007 +0100
    15.2 +++ b/tools/python/xen/xm/xenapi_create.py	Wed Jul 11 10:49:43 2007 +0100
    15.3 @@ -25,6 +25,7 @@ from xen.xend import sxp
    15.4  from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
    15.5       XEN_API_ON_CRASH_BEHAVIOUR
    15.6  from xen.xm.opts import OptionError
    15.7 +from xen.util import xsconstants
    15.8  
    15.9  import sys
   15.10  import os
   15.11 @@ -308,6 +309,12 @@ class xenapi_create:
   15.12                 ""
   15.13              }
   15.14  
   15.15 +        if vm.attributes.has_key("security_label"):
   15.16 +            vm_record.update({
   15.17 +                "security_label":
   15.18 +                    vm.attributes["security_label"].value
   15.19 +                })
   15.20 +
   15.21          if len(vm.getElementsByTagName("pv")) > 0:
   15.22              vm_record.update({
   15.23                  "PV_bootloader":
   15.24 @@ -348,6 +355,12 @@ class xenapi_create:
   15.25  
   15.26              self.create_vifs(vm_ref, vifs, networks)
   15.27  
   15.28 +            # Now create vtpms
   15.29 +
   15.30 +            vtpms = vm.getElementsByTagName("vtpm")
   15.31 +
   15.32 +            self.create_vtpms(vm_ref, vtpms)
   15.33 +
   15.34              # Now create consoles
   15.35  
   15.36              consoles = vm.getElementsByTagName("console")
   15.37 @@ -441,6 +454,21 @@ class xenapi_create:
   15.38              self._network_refs = server.xenapi.network.get_all()
   15.39              return self._network_refs.pop(0)
   15.40  
   15.41 +    def create_vtpms(self, vm_ref, vtpms):
   15.42 +        if len(vtpms) > 1:
   15.43 +            vtpms = [ vtpms[0] ]
   15.44 +        log(DEBUG, "create_vtpms")
   15.45 +        return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms)
   15.46 +
   15.47 +    def create_vtpm(self, vm_ref, vtpm):
   15.48 +        vtpm_record = {
   15.49 +            "VM":
   15.50 +                vm_ref,
   15.51 +            "backend":
   15.52 +                vtpm.attributes["backend"].value
   15.53 +        }
   15.54 +        return server.xenapi.VTPM.create(vtpm_record)
   15.55 +
   15.56      def create_consoles(self, vm_ref, consoles):
   15.57          log(DEBUG, "create_consoles")
   15.58          return map(lambda console: self.create_console(vm_ref, console),
   15.59 @@ -482,6 +510,10 @@ class sxp2xml:
   15.60  
   15.61          vifs_sxp = map(lambda x: x[1], [device for device in devices
   15.62                                          if device[1][0] == "vif"])
   15.63 +
   15.64 +        vtpms_sxp = map(lambda x: x[1], [device for device in devices
   15.65 +                                         if device[1][0] == "vtpm"])
   15.66 +
   15.67          # Create XML Document
   15.68          
   15.69          impl = getDOMImplementation()
   15.70 @@ -531,6 +563,14 @@ class sxp2xml:
   15.71          vm.attributes["vcpus_at_startup"] \
   15.72              = str(get_child_by_name(config, "vcpus", 1))
   15.73  
   15.74 +        sec_data = get_child_by_name(config, "security")
   15.75 +        if sec_data:
   15.76 +            try :
   15.77 +                vm.attributes['security_label'] = \
   15.78 +                      "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, sec_data[0][1][1],sec_data[0][2][1])
   15.79 +            except Exception, e:
   15.80 +                raise "Invalid security data format: %s" % str(sec_data)
   15.81 +
   15.82          # Make the name tag
   15.83  
   15.84          vm.appendChild(self.make_name_tag(
   15.85 @@ -601,6 +641,12 @@ class sxp2xml:
   15.86  
   15.87          map(vm.appendChild, vifs)
   15.88  
   15.89 +        # And now the vTPMs
   15.90 +
   15.91 +        vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp)
   15.92 +
   15.93 +        map(vm.appendChild, vtpms)
   15.94 +
   15.95          # Last but not least the consoles...
   15.96  
   15.97          consoles = self.extract_consoles(image, document)
   15.98 @@ -708,6 +754,15 @@ class sxp2xml:
   15.99          
  15.100          return vif
  15.101  
  15.102 +    def extract_vtpm(self, vtpm_sxp, document):
  15.103 +
  15.104 +        vtpm = document.createElement("vtpm")
  15.105 +
  15.106 +        vtpm.attributes["backend"] \
  15.107 +             = get_child_by_name(vtpm_sxp, "backend", "0")
  15.108 +
  15.109 +        return vtpm
  15.110 +
  15.111      _eths = -1
  15.112  
  15.113      def mk_other_config(self, key, value, document):