ia64/xen-unstable

view tools/python/xen/util/acmpolicy.py @ 16522:54482c56e435

Implement legacy XML-RPC interface for ACM commands.

This patch moves the directory of files where xend is writing policies
and resource labels into to /var/lib/xend/security/policies.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 05 09:45:13 2007 +0000 (2007-12-05)
parents 5255eac35270
children 3221dff4b460
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006,2007 International Business Machines Corp.
16 # Author: Stefan Berger <stefanb@us.ibm.com>
17 #============================================================================
19 import os
20 import stat
21 import array
22 import struct
23 import shutil
24 import commands
25 from xml.dom import minidom, Node
26 from xen.xend.XendLogging import log
27 from xen.util import xsconstants, bootloader, mkdir
28 from xen.util.xspolicy import XSPolicy
29 from xen.xend.XendError import SecurityError
30 import xen.util.xsm.acm.acm as security
31 from xen.util.xsm.xsm import XSMError
32 from xen.xend import XendOptions
34 ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
36 # Constants needed for generating a binary policy from its XML
37 # representation
38 ACM_POLICY_VERSION = 3 # Latest one
39 ACM_CHWALL_VERSION = 1
41 ACM_STE_VERSION = 1
43 ACM_MAGIC = 0x001debc;
45 ACM_NULL_POLICY = 0
46 ACM_CHINESE_WALL_POLICY = 1
47 ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY = 2
48 ACM_POLICY_UNDEFINED = 15
51 ACM_SCHEMA_FILE = ACM_POLICIES_DIR + "security_policy.xsd"
53 ACM_LABEL_UNLABELED = "__UNLABELED__"
54 ACM_LABEL_UNLABELED_DISPLAY = "unlabeled"
56 """
57 Error codes reported in when trying to test for a new policy
58 These error codes are reported in an array of tuples where
59 each error code is followed by a parameter describing the error
60 more closely, such as a domain id.
61 """
62 ACM_EVTCHN_SHARING_VIOLATION = 0x100
63 ACM_GNTTAB_SHARING_VIOLATION = 0x101
64 ACM_DOMAIN_LOOKUP = 0x102
65 ACM_CHWALL_CONFLICT = 0x103
66 ACM_SSIDREF_IN_USE = 0x104
69 DEFAULT_policy = \
70 "<?xml version=\"1.0\" ?>\n" +\
71 "<SecurityPolicyDefinition xmlns=\"http://www.ibm.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.ibm.com ../../security_policy.xsd\">\n" +\
72 " <PolicyHeader>\n" +\
73 " <PolicyName>DEFAULT</PolicyName>\n" +\
74 " <Version>1.0</Version>\n" +\
75 " </PolicyHeader>\n" +\
76 " <SimpleTypeEnforcement>\n" +\
77 " <SimpleTypeEnforcementTypes>\n" +\
78 " <Type>SystemManagement</Type>\n" +\
79 " </SimpleTypeEnforcementTypes>\n" +\
80 " </SimpleTypeEnforcement>\n" +\
81 " <ChineseWall>\n" +\
82 " <ChineseWallTypes>\n" +\
83 " <Type>SystemManagement</Type>\n" +\
84 " </ChineseWallTypes>\n" +\
85 " </ChineseWall>\n" +\
86 " <SecurityLabelTemplate>\n" +\
87 " <SubjectLabels bootstrap=\"SystemManagement\">\n" +\
88 " <VirtualMachineLabel>\n" +\
89 " <Name>SystemManagement</Name>\n" +\
90 " <SimpleTypeEnforcementTypes>\n" +\
91 " <Type>SystemManagement</Type>\n" +\
92 " </SimpleTypeEnforcementTypes>\n" +\
93 " <ChineseWallTypes>\n" +\
94 " <Type/>\n" +\
95 " </ChineseWallTypes>\n" +\
96 " </VirtualMachineLabel>\n" +\
97 " </SubjectLabels>\n" +\
98 " </SecurityLabelTemplate>\n" +\
99 "</SecurityPolicyDefinition>\n"
102 def get_DEFAULT_policy():
103 return DEFAULT_policy
105 def initialize():
106 xoptions = XendOptions.instance()
107 basedir = xoptions.get_xend_security_path()
108 policiesdir = basedir + "/policies"
109 mkdir.parents(policiesdir, stat.S_IRWXU)
111 instdir = security.install_policy_dir_prefix
112 DEF_policy_file = "DEFAULT-security_policy.xml"
113 xsd_file = "security_policy.xsd"
115 files = [ xsd_file ]
117 for file in files:
118 if not os.path.isfile(policiesdir + "/" + file ):
119 try:
120 shutil.copyfile(instdir + "/" + file,
121 policiesdir + "/" + file)
122 except Exception, e:
123 log.info("could not copy '%s': %s" %
124 (file, str(e)))
125 #Install default policy.
126 f = open(policiesdir + "/" + DEF_policy_file, 'w')
127 if f:
128 f.write(get_DEFAULT_policy())
129 f.close()
130 else:
131 log.error("Could not write the default policy's file.")
132 defpol = ACMPolicy(xml=get_DEFAULT_policy())
133 defpol.compile()
136 class ACMPolicy(XSPolicy):
137 """
138 ACMPolicy class. Implements methods for getting information from
139 the XML representation of the policy as well as compilation and
140 loading of a policy into the HV.
141 """
143 def __init__(self, name=None, dom=None, ref=None, xml=None):
144 if name:
145 self.name = name
146 try:
147 self.dom = minidom.parse(self.path_from_policy_name(name))
148 except Exception, e:
149 raise SecurityError(-xsconstants.XSERR_XML_PROCESSING,
150 str(e))
151 elif dom:
152 self.dom = dom
153 self.name = self.get_name()
154 elif xml:
155 try:
156 self.dom = minidom.parseString(xml)
157 except Exception, e:
158 raise SecurityError(-xsconstants.XSERR_XML_PROCESSING,
159 str(e))
160 self.name = self.get_name()
161 rc = self.validate()
162 if rc != xsconstants.XSERR_SUCCESS:
163 raise SecurityError(rc)
164 if ref:
165 from xen.xend.XendXSPolicy import XendACMPolicy
166 self.xendacmpolicy = XendACMPolicy(self, {}, ref)
167 else:
168 self.xendacmpolicy = None
169 XSPolicy.__init__(self, name=self.name, ref=ref)
171 def get_dom(self):
172 return self.dom
174 def get_name(self):
175 return self.policy_dom_get_hdr_item("PolicyName")
177 def get_type(self):
178 return xsconstants.XS_POLICY_ACM
180 def get_type_name(self):
181 return xsconstants.ACM_POLICY_ID
183 def __str__(self):
184 return self.get_name()
187 def validate(self):
188 """
189 validate against the policy's schema Does not fail if the
190 libxml2 python lib is not installed
191 """
192 rc = xsconstants.XSERR_SUCCESS
193 try:
194 import libxml2
195 except Exception, e:
196 log.warn("Libxml2 python-wrapper is not installed on the system.")
197 return xsconstants.XSERR_SUCCESS
198 try:
199 parserctxt = libxml2.schemaNewParserCtxt(ACM_SCHEMA_FILE)
200 schemaparser = parserctxt.schemaParse()
201 valid = schemaparser.schemaNewValidCtxt()
202 doc = libxml2.parseDoc(self.toxml())
203 if doc.schemaValidateDoc(valid) != 0:
204 rc = -xsconstants.XSERR_BAD_XML
205 except Exception, e:
206 log.warn("Problem with the schema: %s" % str(e))
207 rc = -xsconstants.XSERR_GENERAL_FAILURE
208 if rc != xsconstants.XSERR_SUCCESS:
209 log.warn("XML did not validate against schema")
210 if rc == xsconstants.XSERR_SUCCESS:
211 rc = self.__validate_name_and_labels()
212 return rc
214 def __validate_name_and_labels(self):
215 """ no ':' allowed in the policy name and the labels """
216 if ':' in self.get_name():
217 return -xsconstants.XSERR_BAD_POLICY_NAME
218 for s in self.policy_get_resourcelabel_names():
219 if ':' in s:
220 return -xsconstants.XSERR_BAD_LABEL
221 for s in self.policy_get_virtualmachinelabel_names():
222 if ':' in s:
223 return -xsconstants.XSERR_BAD_LABEL
224 return xsconstants.XSERR_SUCCESS
227 def is_default_policy(self):
228 """
229 Determine whether this is the default policy
230 """
231 default = ['SystemManagement']
232 if self.policy_get_virtualmachinelabel_names() == default and \
233 self.policy_get_bootstrap_vmlabel() == default[0] and \
234 self.policy_get_stetypes_types() == default and \
235 self.policy_get_stes_of_vmlabel(default[0]) == default and \
236 self.policy_get_resourcelabel_names() == [] and \
237 self.policy_get_chwall_types() == default and \
238 self.get_name() == "DEFAULT":
239 return True
240 return False
242 def update(self, xml_new):
243 """
244 Update the policy with the new XML. The hypervisor decides
245 whether the new policy can be applied.
246 """
247 rc = -xsconstants.XSERR_XML_PROCESSING
248 errors = ""
249 acmpol_old = self
250 try:
251 acmpol_new = ACMPolicy(xml=xml_new)
252 except Exception:
253 return -xsconstants.XSERR_XML_PROCESSING, errors
255 vmlabel_map = acmpol_new.policy_get_vmlabel_translation_map()
257 # An update requires version information in the current
258 # and new policy. The version number of the current policy
259 # must be the same as what is in the FromPolicy/Version node
260 # in the new one and the current policy's name must be the
261 # same as in FromPolicy/PolicyName
262 # The default policy when it is set skips this step.
263 if not acmpol_new.is_default_policy() and \
264 not acmpol_old.is_default_policy():
265 irc = self.__do_update_version_check(acmpol_new)
266 if irc != xsconstants.XSERR_SUCCESS:
267 return irc, errors
269 if self.isloaded():
270 newvmnames = \
271 acmpol_new.policy_get_virtualmachinelabel_names_sorted()
272 oldvmnames = \
273 acmpol_old.policy_get_virtualmachinelabel_names_sorted()
274 del_array = ""
275 chg_array = ""
277 for o in oldvmnames:
278 if o not in newvmnames:
279 old_idx = oldvmnames.index(o)
280 if vmlabel_map.has_key(o):
281 #not a deletion, but a renaming
282 new = vmlabel_map[o]
283 new_idx = newvmnames.index(new)
284 chg_array += struct.pack("ii", old_idx, new_idx)
285 else:
286 del_array += struct.pack("i", old_idx)
287 for v in newvmnames:
288 if v in oldvmnames:
289 old_idx = oldvmnames.index(v)
290 new_idx = newvmnames.index(v)
291 if old_idx != new_idx:
292 chg_array += struct.pack("ii", old_idx, new_idx)
294 # VM labels indicated in the 'from' attribute of a VM or
295 # resource node but that did not exist in the old policy
296 # are considered bad labels.
297 bad_renamings = set(vmlabel_map.keys()) - set(oldvmnames)
298 if len(bad_renamings) > 0:
299 log.error("Bad VM label renamings: %s" %
300 list(bad_renamings))
301 return -xsconstants.XSERR_BAD_LABEL, errors
303 reslabel_map = acmpol_new.policy_get_reslabel_translation_map()
304 oldresnames = acmpol_old.policy_get_resourcelabel_names()
305 bad_renamings = set(reslabel_map.keys()) - set(oldresnames)
306 if len(bad_renamings) > 0:
307 log.error("Bad resource label renamings: %s" %
308 list(bad_renamings))
309 return -xsconstants.XSERR_BAD_LABEL, errors
311 #Get binary and map from the new policy
312 rc, pol_map, bin_pol = acmpol_new.policy_create_map_and_bin()
313 if rc != xsconstants.XSERR_SUCCESS:
314 log.error("Could not build the map and binary policy.")
315 return rc, errors
317 #Need to do / check the following:
318 # - relabel all resources where there is a 'from' field in
319 # the policy and mark those as unlabeled where the label
320 # does not appear in the new policy anymore
321 # - relabel all VMs where there is a 'from' field in the
322 # policy and mark those as unlabeled where the label
323 # does not appear in the new policy anymore; no running
324 # or paused VM may be unlabeled through this
325 # - check that under the new labeling conditions the VMs
326 # still have access to their resources as before. Unlabeled
327 # resources are inaccessible. If this check fails, the
328 # update failed.
329 # - Attempt changes in the hypervisor; if this step fails,
330 # roll back the relabeling of resources and VMs
331 # - Commit the relabeling of resources
334 rc, errors = security.change_acm_policy(bin_pol,
335 del_array, chg_array,
336 vmlabel_map, reslabel_map,
337 self, acmpol_new)
339 if rc == 0:
340 # Replace the old DOM with the new one and save it
341 self.dom = acmpol_new.dom
342 self.compile()
343 log.info("ACM policy update was successful")
344 else:
345 #Not loaded in HV
346 self.dom = acmpol_new.dom
347 rc = self.compile()
348 return rc, errors
351 def __do_update_version_check(self, acmpol_new):
352 acmpol_old = self
354 now_vers = acmpol_old.policy_dom_get_hdr_item("Version")
355 now_name = acmpol_old.policy_dom_get_hdr_item("PolicyName")
356 req_oldvers = acmpol_new.policy_dom_get_frompol_item("Version")
357 req_oldname = acmpol_new.policy_dom_get_frompol_item("PolicyName")
359 if now_vers == "" or \
360 now_vers != req_oldvers or \
361 now_name != req_oldname:
362 log.info("Policy rejected: %s != %s or %s != %s" % \
363 (now_vers,req_oldvers,now_name,req_oldname))
364 return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE
366 if not self.isVersionUpdate(acmpol_new):
367 log.info("Policy rejected since new version is not an update.")
368 return -xsconstants.XSERR_VERSION_PREVENTS_UPDATE
370 return xsconstants.XSERR_SUCCESS
373 def compareVersions(self, v1, v2):
374 """
375 Compare two policy versions given their tuples of major and
376 minor.
377 Return '0' if versions are equal, '>0' if v1 > v2 and
378 '<' if v1 < v2
379 """
380 rc = v1[0] - v2[0]
381 if rc == 0:
382 rc = v1[1] - v2[1]
383 return rc
385 def getVersionTuple(self, item="Version"):
386 v_str = self.policy_dom_get_hdr_item(item)
387 return self.__convVersionToTuple(v_str)
389 def get_version(self):
390 return self.policy_dom_get_hdr_item("Version")
392 def isVersionUpdate(self, polnew):
393 if self.compareVersions(polnew.getVersionTuple(),
394 self.getVersionTuple()) > 0:
395 return True
396 return False
398 def __convVersionToTuple(self, v_str):
399 """ Convert a version string, formatted according to the scheme
400 "%d.%d" into a tuple of (major, minor). Return (0,0) if the
401 string is empty.
402 """
403 major = 0
404 minor = 0
405 if v_str != "":
406 tmp = v_str.split(".")
407 major = int(tmp[0])
408 if len(tmp) > 1:
409 minor = int(tmp[1])
410 return (major, minor)
412 def get_policies_path(self):
413 xoptions = XendOptions.instance()
414 basedir = xoptions.get_xend_security_path()
415 return basedir + "/policies/"
417 def policy_path(self, name):
418 prefix = self.get_policies_path()
419 path = prefix + name.replace('.','/')
420 _path = path.split("/")
421 del _path[-1]
422 mkdir.parents("/".join(_path), stat.S_IRWXU)
423 return path
425 def path_from_policy_name(self, name):
426 return self.policy_path(name) + "-security_policy.xml"
428 #
429 # Functions interacting with the bootloader
430 #
431 def vmlabel_to_ssidref(self, vm_label):
432 """ Convert a VMlabel into an ssidref given the current
433 policy
434 Return xsconstants.INVALID_SSIDREF if conversion failed.
435 """
436 ssidref = xsconstants.INVALID_SSIDREF
437 names = self.policy_get_virtualmachinelabel_names_sorted()
438 try:
439 vmidx = names.index(vm_label)
440 ssidref = (vmidx << 16) | vmidx
441 except:
442 pass
443 return ssidref
445 def set_vm_bootlabel(self, vm_label, remove=False):
446 parms="<>"
447 if vm_label != "":
448 ssidref = self.vmlabel_to_ssidref(vm_label)
449 if ssidref == xsconstants.INVALID_SSIDREF:
450 return -xsconstants.XSERR_BAD_LABEL
451 parms = "0x%08x:%s:%s:%s" % \
452 (ssidref, xsconstants.ACM_POLICY_ID, \
453 self.get_name(),vm_label)
454 else:
455 ssidref = 0 #Identifier for removal
457 if remove == True:
458 parms = "<>"
460 try:
461 def_title = bootloader.get_default_title()
462 bootloader.set_kernel_attval(def_title, "ssidref", parms)
463 except:
464 return -xsconstants.XSERR_GENERAL_FAILURE
465 return ssidref
467 #
468 # Utility functions related to the policy's files
469 #
470 def get_filename(self, postfix, prefix=None, dotted=False):
471 """
472 Create the filename for the policy. The prefix is prepended
473 to the path. If dotted is True, then a policy name like
474 'a.b.c' will remain as is, otherwise it will become 'a/b/c'
475 """
476 if prefix == None:
477 prefix = self.get_policies_path()
478 name = self.get_name()
479 if name:
480 p = name.split(".")
481 path = ""
482 if dotted:
483 sep = "."
484 else:
485 sep = "/"
486 if len(p) > 1:
487 path = sep.join(p[0:len(p)-1])
488 if prefix != "" or path != "":
489 allpath = prefix + path + sep + p[-1] + postfix
490 else:
491 allpath = p[-1] + postfix
492 return allpath
493 return None
495 def __readfile(self, name):
496 cont = ""
497 filename = self.get_filename(name)
498 f = open(filename, "r")
499 if f:
500 cont = f.read()
501 f.close()
502 return cont
504 def get_map(self):
505 return self.__readfile(".map")
507 def get_bin(self):
508 return self.__readfile(".bin")
510 def copy_policy_file(self, suffix, destdir):
511 spolfile = self.get_filename(suffix)
512 dpolfile = destdir + "/" + self.get_filename(suffix,"",dotted=True)
513 try:
514 shutil.copyfile(spolfile, dpolfile)
515 except Exception, e:
516 log.error("Could not copy policy file %s to %s: %s" %
517 (spolfile, dpolfile, str(e)))
518 return -xsconstants.XSERR_FILE_ERROR
519 return xsconstants.XSERR_SUCCESS
521 #
522 # DOM-related functions
523 #
525 def policy_dom_get(self, parent, key, createit=False):
526 for node in parent.childNodes:
527 if node.nodeType == Node.ELEMENT_NODE:
528 if node.nodeName == key:
529 return node
530 if createit:
531 self.dom_create_node(parent, key)
532 return self.policy_dom_get(parent, key)
534 def dom_create_node(self, parent, newname, value=" "):
535 xml = "<a><"+newname+">"+ value +"</"+newname+"></a>"
536 frag = minidom.parseString(xml)
537 frag.childNodes[0].nodeType = Node.DOCUMENT_FRAGMENT_NODE
538 parent.appendChild(frag.childNodes[0])
539 return frag.childNodes[0]
541 def dom_get_node(self, path, createit=False):
542 node = None
543 parts = path.split("/")
544 doc = self.get_dom()
545 if len(parts) > 0:
546 node = self.policy_dom_get(doc.documentElement, parts[0])
547 if node:
548 i = 1
549 while i < len(parts):
550 _node = self.policy_dom_get(node, parts[i], createit)
551 if not _node:
552 if not createit:
553 break
554 else:
555 self.dom_create_node(node, parts[i])
556 _node = self.policy_dom_get(node, parts[i])
557 node = _node
558 i += 1
559 return node
561 #
562 # Header-related functions
563 #
564 def policy_dom_get_header_subnode(self, nodename):
565 node = self.dom_get_node("PolicyHeader/%s" % nodename)
566 return node
568 def policy_dom_get_hdr_item(self, name, default=""):
569 node = self.policy_dom_get_header_subnode(name)
570 if node and len(node.childNodes) > 0:
571 return node.childNodes[0].nodeValue
572 return default
574 def policy_dom_get_frompol_item(self, name, default="", createit=False):
575 node = self.dom_get_node("PolicyHeader/FromPolicy",createit)
576 if node:
577 node = self.policy_dom_get(node, name, createit)
578 if node and len(node.childNodes) > 0:
579 return node.childNodes[0].nodeValue
580 return default
582 def get_header_fields_map(self):
583 header = {
584 'policyname' : self.policy_dom_get_hdr_item("PolicyName"),
585 'policyurl' : self.policy_dom_get_hdr_item("PolicyUrl"),
586 'reference' : self.policy_dom_get_hdr_item("Reference"),
587 'date' : self.policy_dom_get_hdr_item("Date"),
588 'namespaceurl' : self.policy_dom_get_hdr_item("NameSpaceUrl"),
589 'version' : self.policy_dom_get_hdr_item("Version")
590 }
591 return header
593 def set_frompolicy_name(self, name):
594 """ For tools to adapt the header of the policy """
595 node = self.dom_get_node("PolicyHeader/FromPolicy/PolicyName",
596 createit=True)
597 node.childNodes[0].nodeValue = name
599 def set_frompolicy_version(self, version):
600 """ For tools to adapt the header of the policy """
601 node = self.dom_get_node("PolicyHeader/FromPolicy/Version",
602 createit=True)
603 node.childNodes[0].nodeValue = version
605 def set_policy_name(self, name):
606 """ For tools to adapt the header of the policy """
607 node = self.dom_get_node("PolicyHeader/PolicyName")
608 node.childNodes[0].nodeValue = name
610 def set_policy_version(self, version):
611 """ For tools to adapt the header of the policy """
612 node = self.dom_get_node("PolicyHeader/Version")
613 node.childNodes[0].nodeValue = version
615 def update_frompolicy(self, curpol):
616 self.set_frompolicy_name(curpol.policy_dom_get_hdr_item("PolicyName"))
617 version = curpol.policy_dom_get_hdr_item("Version")
618 self.set_frompolicy_version(version)
619 (maj, minor) = self.__convVersionToTuple(version)
620 self.set_policy_version("%s.%s" % (maj, minor+1))
622 #
623 # Get all types that are part of a node
624 #
626 def policy_get_types(self, node):
627 strings = []
628 i = 0
629 while i < len(node.childNodes):
630 if node.childNodes[i].nodeName == "Type" and \
631 len(node.childNodes[i].childNodes) > 0:
632 strings.append(node.childNodes[i].childNodes[0].nodeValue)
633 i += 1
634 return strings
636 #
637 # Simple Type Enforcement-related functions
638 #
640 def policy_get_stetypes_node(self):
641 node = self.dom_get_node("SimpleTypeEnforcement/SimpleTypeEnforcementTypes")
642 return node
644 def policy_get_stetypes_types(self):
645 strings = []
646 node = self.policy_get_stetypes_node()
647 if node:
648 strings = self.policy_get_types(node)
649 return strings
651 #
652 # Chinese Wall Type-related functions
653 #
655 def policy_get_chwall_types(self):
656 strings = []
657 node = self.dom_get_node("ChineseWall/ChineseWallTypes")
658 if node:
659 strings = self.policy_get_types(node)
660 return strings
662 def policy_get_chwall_cfses(self):
663 cfs = []
664 node = self.dom_get_node("ChineseWall/ConflictSets")
665 if node:
666 i = 0
667 while i < len(node.childNodes):
668 _cfs = {}
669 if node.childNodes[i].nodeName == "Conflict":
670 _cfs['name'] = node.childNodes[i].getAttribute('name')
671 _cfs['chws'] = self.policy_get_types(node.childNodes[i])
672 cfs.append(_cfs)
673 i += 1
674 return cfs
676 def policy_get_chwall_cfses_names_sorted(self):
677 """
678 Return the list of all conflict set names in alphabetical
679 order.
680 """
681 cfs_names = []
682 node = self.dom_get_node("ChineseWall/ConflictSets")
683 if node:
684 i = 0
685 while i < len(node.childNodes):
686 if node.childNodes[i].nodeName == "Conflict":
687 n = node.childNodes[i].getAttribute('name')
688 #it better have a name!
689 if n:
690 cfs_names.append(n)
691 i += 1
692 cfs_names.sort()
693 return cfs_names
695 #
696 # Subject Label-related functions
697 #
699 def policy_get_bootstrap_vmlabel(self):
700 node = self.dom_get_node("SecurityLabelTemplate/SubjectLabels")
701 if node:
702 vmlabel = node.getAttribute("bootstrap")
703 return vmlabel
705 # Get the names of all virtual machine labels; returns an array
706 def policy_get_virtualmachinelabel_names(self):
707 strings = []
708 node = self.dom_get_node("SecurityLabelTemplate/SubjectLabels")
709 if node:
710 i = 0
711 while i < len(node.childNodes):
712 if node.childNodes[i].nodeName == "VirtualMachineLabel":
713 name = self.policy_dom_get(node.childNodes[i], "Name")
714 if len(name.childNodes) > 0:
715 strings.append(name.childNodes[0].nodeValue)
716 i += 1
717 return strings
719 def policy_sort_virtualmachinelabel_names(self, vmnames):
720 bootstrap = self.policy_get_bootstrap_vmlabel()
721 if bootstrap not in vmnames:
722 raise SecurityError(-xsconstants.XSERR_POLICY_INCONSISTENT)
723 vmnames.remove(bootstrap)
724 vmnames.sort()
725 vmnames.insert(0, bootstrap)
726 if ACM_LABEL_UNLABELED in vmnames:
727 vmnames.remove(ACM_LABEL_UNLABELED)
728 vmnames.insert(0, ACM_LABEL_UNLABELED)
729 return vmnames
731 def policy_get_virtualmachinelabel_names_sorted(self):
732 """ Get a sorted list of VMlabel names. The bootstrap VM's
733 label will be the first one in that list, followed
734 by an alphabetically sorted list of VM label names """
735 vmnames = self.policy_get_virtualmachinelabel_names()
736 res = self.policy_sort_virtualmachinelabel_names(vmnames)
737 if res[0] != ACM_LABEL_UNLABELED:
738 res.insert(0, ACM_LABEL_UNLABELED)
739 return res
741 def policy_get_virtualmachinelabels(self):
742 """ Get a list of all virtual machine labels in this policy """
743 res = []
744 node = self.dom_get_node("SecurityLabelTemplate/SubjectLabels")
745 if node:
746 i = 0
747 while i < len(node.childNodes):
748 if node.childNodes[i].nodeName == "VirtualMachineLabel":
749 name = self.policy_dom_get(node.childNodes[i], "Name")
750 if len(name.childNodes) > 0:
751 _res = {}
752 _res['type'] = xsconstants.ACM_LABEL_VM
753 _res['name'] = name.childNodes[0].nodeValue
754 stes = self.policy_dom_get(node.childNodes[i],
755 "SimpleTypeEnforcementTypes")
756 if stes:
757 _res['stes'] = self.policy_get_types(stes)
758 else:
759 _res['stes'] = []
760 chws = self.policy_dom_get(node.childNodes[i],
761 "ChineseWallTypes")
762 if chws:
763 _res['chws'] = self.policy_get_types(chws)
764 else:
765 _res['chws'] = []
766 res.append(_res)
767 i += 1
768 return res
770 def policy_get_stes_of_vmlabel(self, vmlabel):
771 """ Get a list of all STEs of a given VMlabel """
772 return self.__policy_get_stes_of_labeltype(vmlabel,
773 "/SubjectLabels", "VirtualMachineLabel")
775 def policy_get_stes_of_resource(self, reslabel):
776 """ Get a list of all resources of a given VMlabel """
777 return self.__policy_get_stes_of_labeltype(reslabel,
778 "/ObjectLabels", "ResourceLabel")
780 def __policy_get_stes_of_labeltype(self, label, path, labeltype):
781 node = self.dom_get_node("SecurityLabelTemplate" + path)
782 if node:
783 i = 0
784 while i < len(node.childNodes):
785 if node.childNodes[i].nodeName == labeltype:
786 name = self.policy_dom_get(node.childNodes[i], "Name")
787 if len(name.childNodes) > 0 and \
788 name.childNodes[0].nodeValue == label:
789 stes = self.policy_dom_get(node.childNodes[i],
790 "SimpleTypeEnforcementTypes")
791 if not stes:
792 return []
793 return self.policy_get_types(stes)
794 i += 1
795 return []
797 def policy_check_vmlabel_against_reslabels(self, vmlabel, resources):
798 """
799 Check whether the given vmlabel is compatible with the given
800 resource labels. Do this by getting all the STEs of the
801 vmlabel and the STEs of the resources. Any STE type of the
802 VM label must match an STE type of the resource.
803 """
804 vm_stes = self.policy_get_stes_of_vmlabel(vmlabel)
805 if len(vm_stes) == 0:
806 return False
807 for res in resources:
808 res_stes = self.policy_get_stes_of_resource(res)
809 if len(res_stes) == 0 or \
810 len( set(res_stes).intersection( set(vm_stes) ) ) == 0:
811 return False
812 return True
814 def __policy_get_label_translation_map(self, path, labeltype):
815 res = {}
816 node = self.dom_get_node("SecurityLabelTemplate/" + path)
817 if node:
818 i = 0
819 while i < len(node.childNodes):
820 if node.childNodes[i].nodeName == labeltype:
821 name = self.policy_dom_get(node.childNodes[i], "Name")
822 from_name = name.getAttribute("from")
823 if from_name and len(name.childNodes) > 0:
824 res.update({from_name : name.childNodes[0].nodeValue})
825 i += 1
826 return res
828 def policy_get_vmlabel_translation_map(self):
829 """
830 Get a dictionary of virtual machine mappings from their
831 old VMlabel name to the new VMlabel name.
832 """
833 return self.__policy_get_label_translation_map("SubjectLabels",
834 "VirtualMachineLabel")
836 def policy_get_reslabel_translation_map(self):
837 """
838 Get a dictionary of resource mappings from their
839 old resource label name to the new resource label name.
840 """
841 return self.__policy_get_label_translation_map("ObjectLabels",
842 "ResourceLabel")
844 #
845 # Object Label-related functions
846 #
847 def policy_get_resourcelabel_names(self):
848 """
849 Get the names of all resource labels in an array but
850 only those that actually have types
851 """
852 strings = []
853 node = self.dom_get_node("SecurityLabelTemplate/ObjectLabels")
854 if node:
855 i = 0
856 while i < len(node.childNodes):
857 if node.childNodes[i].nodeName == "ResourceLabel":
858 name = self.policy_dom_get(node.childNodes[i], "Name")
859 stes = self.policy_dom_get(node.childNodes[i],
860 "SimpleTypeEnforcementTypes")
861 if stes and len(name.childNodes) > 0:
862 strings.append(name.childNodes[0].nodeValue)
863 i += 1
864 return strings
866 def policy_get_resourcelabels(self):
867 """
868 Get all information about all resource labels of this policy.
869 """
870 res = []
871 node = self.dom_get_node("SecurityLabelTemplate/ObjectLabels")
872 if node:
873 i = 0
874 while i < len(node.childNodes):
875 if node.childNodes[i].nodeName == "ResourceLabel":
876 name = self.policy_dom_get(node.childNodes[i], "Name")
877 if len(name.childNodes) > 0:
878 _res = {}
879 _res['type'] = xsconstants.ACM_LABEL_RES
880 _res['name'] = name.childNodes[0].nodeValue
881 stes = self.policy_dom_get(node.childNodes[i],
882 "SimpleTypeEnforcementTypes")
883 if stes:
884 _res['stes'] = self.policy_get_types(stes)
885 else:
886 _res['stes'] = []
887 _res['chws'] = []
888 res.append(_res)
889 i += 1
890 return res
893 def policy_find_reslabels_with_stetype(self, stetype):
894 """
895 Find those resource labels that hold a given STE type.
896 """
897 res = []
898 reslabels = self.policy_get_resourcelabels()
899 for resl in reslabels:
900 if stetype in resl['stes']:
901 res.append(resl['name'])
902 return res
905 def toxml(self):
906 dom = self.get_dom()
907 if dom:
908 return dom.toxml()
909 return None
911 def save(self):
912 ### Save the XML policy into a file ###
913 rc = -xsconstants.XSERR_FILE_ERROR
914 name = self.get_name()
915 if name:
916 path = self.path_from_policy_name(name)
917 if path:
918 f = open(path, 'w')
919 if f:
920 try:
921 try:
922 f.write(self.toxml())
923 rc = 0
924 except:
925 pass
926 finally:
927 f.close()
928 return rc
930 def __write_to_file(self, suffix, data):
931 #write the data into a file with the given suffix
932 f = open(self.get_filename(suffix),"w")
933 if f:
934 try:
935 try:
936 f.write(data)
937 except Exception, e:
938 log.error("Error writing file: %s" % str(e))
939 return -xsconstants.XSERR_FILE_ERROR
940 finally:
941 f.close()
942 else:
943 return -xsconstants.XSERR_FILE_ERROR
944 return xsconstants.XSERR_SUCCESS
947 def compile(self):
948 rc = self.save()
949 if rc == 0:
950 rc, mapfile, bin_pol = self.policy_create_map_and_bin()
952 if rc == 0:
953 try:
954 security.mapfile_lock()
956 rc = self.__write_to_file(".map", mapfile)
957 if rc != 0:
958 log.error("Error writing map file")
960 finally:
961 security.mapfile_unlock()
963 if rc == 0:
964 rc = self.__write_to_file(".bin", bin_pol)
965 if rc != 0:
966 log.error("Error writing binary policy file")
967 return rc
969 def loadintohv(self):
970 """
971 load this policy into the hypervisor
972 if successful,the policy's flags will indicate that the
973 policy is the one loaded into the hypervisor
974 """
975 if not self.isloaded():
976 (ret, output) = commands.getstatusoutput(
977 security.xensec_tool +
978 " loadpolicy " +
979 self.get_filename(".bin"))
980 if ret != 0:
981 return -xsconstants.XSERR_POLICY_LOAD_FAILED
982 return xsconstants.XSERR_SUCCESS
984 def isloaded(self):
985 """
986 Determine whether this policy is the active one.
987 """
988 if self.get_name() == security.get_active_policy_name():
989 return True
990 return False
992 def destroy(self):
993 """
994 Destroy the policy including its binary, mapping and
995 XML files.
996 This only works if the policy is not the one that's loaded
997 """
998 if self.isloaded():
999 return -xsconstants.XSERR_POLICY_LOADED
1000 files = [ self.get_filename(".map",""),
1001 self.get_filename(".bin","") ]
1002 for f in files:
1003 try:
1004 os.unlink(f)
1005 except:
1006 pass
1007 if self.xendacmpolicy:
1008 self.xendacmpolicy.destroy()
1009 XSPolicy.destroy(self)
1010 return xsconstants.XSERR_SUCCESS
1012 def policy_get_domain_label(self, domid):
1013 """
1014 Given a domain's ID, retrieve the label it has using
1015 its ssidref for reverse calculation.
1016 """
1017 try:
1018 mgmt_dom = security.get_ssid(domid)
1019 except:
1020 return ""
1021 return self.policy_get_domain_label_by_ssidref(int(mgmt_dom[3]))
1023 def policy_get_domain_label_by_ssidref(self, ssidref):
1024 """ Given an ssidref, find the corresponding VM label """
1025 chwall_ref = ssidref & 0xffff
1026 try:
1027 allvmtypes = self.policy_get_virtualmachinelabel_names_sorted()
1028 except:
1029 return None
1030 return allvmtypes[chwall_ref]
1032 def policy_get_domain_label_formatted(self, domid):
1033 label = self.policy_get_domain_label(domid)
1034 if label == "":
1035 label = ACM_LABEL_UNLABELED
1036 return "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, self.get_name(), label)
1038 def policy_get_domain_label_by_ssidref_formatted(self, ssidref):
1039 label = self.policy_get_domain_label_by_ssidref(ssidref)
1040 if label == "":
1041 return ""
1042 return "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, self.get_name(), label)
1044 def policy_create_map_and_bin(self):
1045 """
1046 Create the policy's map and binary files -- compile the policy.
1047 """
1048 def roundup8(len):
1049 return ((len + 7) & ~7)
1051 rc = xsconstants.XSERR_SUCCESS
1052 mapfile = ""
1053 primpolcode = ACM_POLICY_UNDEFINED
1054 secpolcode = ACM_POLICY_UNDEFINED
1055 unknown_ste = set()
1056 unknown_chw = set()
1057 unlabeled_ste = "__NULL_LABEL__"
1058 unlabeled_chw = "__NULL_LABEL__"
1060 rc = self.validate()
1061 if rc:
1062 return rc, "", ""
1064 stes = self.policy_get_stetypes_types()
1065 if stes:
1066 stes.sort()
1068 chws = self.policy_get_chwall_types()
1069 if chws:
1070 chws.sort()
1072 vms = self.policy_get_virtualmachinelabels()
1073 bootstrap = self.policy_get_bootstrap_vmlabel()
1075 vmlabels = self.policy_get_virtualmachinelabel_names_sorted()
1076 if bootstrap not in vmlabels:
1077 log.error("Bootstrap label '%s' not found among VM labels '%s'." \
1078 % (bootstrap, vmlabels))
1079 return -xsconstants.XSERR_POLICY_INCONSISTENT, "", ""
1081 vms_with_chws = []
1082 chws_by_vm = { ACM_LABEL_UNLABELED : [] }
1083 for v in vms:
1084 if v.has_key("chws"):
1085 vms_with_chws.append(v["name"])
1086 chws_by_vm[v["name"]] = v["chws"]
1089 if bootstrap in vms_with_chws:
1090 vms_with_chws.remove(bootstrap)
1091 vms_with_chws.sort()
1092 vms_with_chws.insert(0, bootstrap)
1093 else:
1094 vms_with_chws.sort()
1096 if ACM_LABEL_UNLABELED in vms_with_chws:
1097 unlabeled_chw = ACM_LABEL_UNLABELED
1098 vms_with_chws.remove(ACM_LABEL_UNLABELED) ; # @1
1100 vms_with_stes = []
1101 stes_by_vm = { ACM_LABEL_UNLABELED : [] }
1102 for v in vms:
1103 if v.has_key("stes"):
1104 vms_with_stes.append(v["name"])
1105 stes_by_vm[v["name"]] = v["stes"]
1107 if bootstrap in vms_with_stes:
1108 vms_with_stes.remove(bootstrap)
1109 vms_with_stes.sort()
1110 vms_with_stes.insert(0, bootstrap)
1111 else:
1112 vms_with_stes.sort()
1114 if ACM_LABEL_UNLABELED in vms_with_stes:
1115 unlabeled_ste = ACM_LABEL_UNLABELED
1116 vms_with_stes.remove(ACM_LABEL_UNLABELED) ; # @2
1118 resnames = self.policy_get_resourcelabel_names()
1119 resnames.sort()
1120 stes_by_res = {}
1121 res = self.policy_get_resourcelabels()
1122 for r in res:
1123 if r.has_key("stes"):
1124 stes_by_res[r["name"]] = r["stes"]
1126 if ACM_LABEL_UNLABELED in resnames:
1127 resnames.remove(ACM_LABEL_UNLABELED)
1129 max_chw_ssids = 1 + len(vms_with_chws)
1130 max_chw_types = 1 + len(vms_with_chws)
1131 max_ste_ssids = 1 + len(vms_with_stes) + len(resnames)
1132 max_ste_types = 1 + len(vms_with_stes) + len(resnames)
1134 mapfile = "POLICYREFERENCENAME %s\n" % self.get_name()
1135 mapfile += "MAGIC %08x\n" % ACM_MAGIC
1136 mapfile += "POLICFILE %s\n" % \
1137 self.path_from_policy_name(self.get_name())
1138 mapfile += "BINARYFILE %s\n" % self.get_filename(".bin")
1139 mapfile += "MAX-CHWALL-TYPES %08x\n" % len(chws)
1140 mapfile += "MAX-CHWALL-SSIDS %08x\n" % max_chw_ssids
1141 mapfile += "MAX-CHWALL-LABELS %08x\n" % max_chw_ssids
1142 mapfile += "MAX-STE-TYPES %08x\n" % len(stes)
1143 mapfile += "MAX-STE-SSIDS %08x\n" % max_ste_ssids
1144 mapfile += "MAX-STE-LABELS %08x\n" % max_ste_ssids
1145 mapfile += "\n"
1147 if chws:
1148 mapfile += \
1149 "PRIMARY CHWALL\n"
1150 primpolcode = ACM_CHINESE_WALL_POLICY
1151 if stes:
1152 mapfile += \
1153 "SECONDARY STE\n"
1154 else:
1155 mapfile += \
1156 "SECONDARY NULL\n"
1157 secpolcode = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
1158 else:
1159 if stes:
1160 mapfile += \
1161 "PRIMARY STE\n"
1162 primpolcode = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY
1163 mapfile += \
1164 "SECONDARY NULL\n"
1166 mapfile += "\n"
1168 if len(vms_with_chws) > 0:
1169 mapfile += \
1170 "LABEL->SSID ANY CHWALL %-20s %x\n" % \
1171 (unlabeled_chw, 0)
1172 i = 0
1173 for v in vms_with_chws:
1174 mapfile += \
1175 "LABEL->SSID VM CHWALL %-20s %x\n" % \
1176 (v, i+1)
1177 i += 1
1178 mapfile += "\n"
1180 if len(vms_with_stes) > 0 or len(resnames) > 0:
1181 mapfile += \
1182 "LABEL->SSID ANY STE %-20s %08x\n" % \
1183 (unlabeled_ste, 0)
1184 i = 0
1185 for v in vms_with_stes:
1186 mapfile += \
1187 "LABEL->SSID VM STE %-20s %x\n" % (v, i+1)
1188 i += 1
1189 j = 0
1190 for r in resnames:
1191 mapfile += \
1192 "LABEL->SSID RES STE %-20s %x\n" % (r, j+i+1)
1193 j += 1
1194 mapfile += "\n"
1196 if vms_with_chws:
1197 mapfile += \
1198 "SSID->TYPE CHWALL %08x\n" % 0
1199 i = 1
1200 for v in vms_with_chws:
1201 mapfile += \
1202 "SSID->TYPE CHWALL %08x" % i
1203 for c in chws_by_vm[v]:
1204 mapfile += " %s" % c
1205 mapfile += "\n"
1206 i += 1
1207 mapfile += "\n"
1209 if len(vms_with_stes) > 0 or len(resnames) > 0:
1210 mapfile += \
1211 "SSID->TYPE STE %08x\n" % 0
1212 i = 1
1213 for v in vms_with_stes:
1214 mapfile += \
1215 "SSID->TYPE STE %08x" % i
1216 for s in stes_by_vm[v]:
1217 mapfile += " %s" % s
1218 mapfile += "\n"
1219 i += 1
1221 for r in resnames:
1222 mapfile += \
1223 "SSID->TYPE STE %08x" % i
1224 for s in stes_by_res[r]:
1225 mapfile += " %s" % s
1226 mapfile += "\n"
1227 i += 1
1228 mapfile += "\n"
1230 if chws:
1231 i = 0
1232 while i < len(chws):
1233 mapfile += \
1234 "TYPE CHWALL %-20s %d\n" % (chws[i], i)
1235 i += 1
1236 mapfile += "\n"
1237 if stes:
1238 i = 0
1239 while i < len(stes):
1240 mapfile += \
1241 "TYPE STE %-20s %d\n" % (stes[i], i)
1242 i += 1
1243 mapfile += "\n"
1245 mapfile += "\n"
1247 # Build header with policy name
1248 length = roundup8(4 + len(self.get_name()) + 1)
1249 polname = self.get_name();
1250 pr_bin = struct.pack("!i", len(polname)+1)
1251 pr_bin += polname;
1252 while len(pr_bin) < length:
1253 pr_bin += "\x00"
1255 # Build chinese wall part
1256 vms_with_chws.insert(0, ACM_LABEL_UNLABELED)
1258 cfses_names = self.policy_get_chwall_cfses_names_sorted()
1259 cfses = self.policy_get_chwall_cfses()
1261 chwformat = "!iiiiiiiii"
1262 max_chw_cfs = len(cfses)
1263 chw_ssid_offset = struct.calcsize(chwformat)
1264 chw_confset_offset = chw_ssid_offset + \
1265 2 * len(chws) * max_chw_types
1266 chw_running_types_offset = 0
1267 chw_conf_agg_offset = 0
1269 chw_bin = struct.pack(chwformat,
1270 ACM_CHWALL_VERSION,
1271 ACM_CHINESE_WALL_POLICY,
1272 len(chws),
1273 max_chw_ssids,
1274 max_chw_cfs,
1275 chw_ssid_offset,
1276 chw_confset_offset,
1277 chw_running_types_offset,
1278 chw_conf_agg_offset)
1279 chw_bin_body = ""
1281 # VMs that are listed and their chinese walls
1282 for v in vms_with_chws:
1283 for c in chws:
1284 unknown_chw |= (set(chws_by_vm[v]) - set(chws))
1285 if c in chws_by_vm[v]:
1286 chw_bin_body += struct.pack("!h",1)
1287 else:
1288 chw_bin_body += struct.pack("!h",0)
1290 # Conflict sets -- they need to be processed in alphabetical order
1291 for cn in cfses_names:
1292 if cn == "" or cn is None:
1293 return -xsconstants.XSERR_BAD_CONFLICTSET, "", ""
1294 i = 0
1295 while i < len(cfses):
1296 if cfses[i]['name'] == cn:
1297 conf = cfses[i]['chws']
1298 break
1299 i += 1
1300 for c in chws:
1301 if c in conf:
1302 chw_bin_body += struct.pack("!h",1)
1303 else:
1304 chw_bin_body += struct.pack("!h",0)
1305 del cfses[i]
1307 if len(cfses) != 0:
1308 return -xsconstants.XSERR_BAD_CONFLICTSET, "", ""
1310 chw_bin += chw_bin_body
1312 while len(chw_bin) < roundup8(len(chw_bin)):
1313 chw_bin += "\x00"
1315 # Build STE part
1316 vms_with_stes.insert(0, ACM_LABEL_UNLABELED) # Took out in @2
1318 steformat="!iiiii"
1319 ste_bin = struct.pack(steformat,
1320 ACM_STE_VERSION,
1321 ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
1322 len(stes),
1323 max_ste_types,
1324 struct.calcsize(steformat))
1325 ste_bin_body = ""
1326 if stes:
1327 # VMs that are listed and their STE types
1328 for v in vms_with_stes:
1329 unknown_ste |= (set(stes_by_vm[v]) - set(stes))
1330 for s in stes:
1331 if s in stes_by_vm[v]:
1332 ste_bin_body += struct.pack("!h",1)
1333 else:
1334 ste_bin_body += struct.pack("!h",0)
1335 for r in resnames:
1336 unknown_ste |= (set(stes_by_res[r]) - set(stes))
1337 for s in stes:
1338 if s in stes_by_res[r]:
1339 ste_bin_body += struct.pack("!h",1)
1340 else:
1341 ste_bin_body += struct.pack("!h",0)
1343 ste_bin += ste_bin_body;
1345 while len(ste_bin) < roundup8(len(ste_bin)):
1346 ste_bin += "\x00"
1348 #Write binary header:
1349 headerformat="!iiiiiiiiii"
1350 totallen_bin = struct.calcsize(headerformat) + \
1351 len(pr_bin) + len(chw_bin) + len(ste_bin)
1352 polref_offset = struct.calcsize(headerformat)
1353 primpoloffset = polref_offset + len(pr_bin)
1354 if primpolcode == ACM_CHINESE_WALL_POLICY:
1355 secpoloffset = primpoloffset + len(chw_bin)
1356 elif primpolcode == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
1357 secpoloffset = primpoloffset + len(ste_bin)
1358 else:
1359 secpoloffset = primpoloffset
1361 (major, minor) = self.getVersionTuple()
1362 hdr_bin = struct.pack(headerformat,
1363 ACM_MAGIC,
1364 ACM_POLICY_VERSION,
1365 totallen_bin,
1366 polref_offset,
1367 primpolcode,
1368 primpoloffset,
1369 secpolcode,
1370 secpoloffset,
1371 major, minor)
1373 all_bin = array.array('B')
1374 for s in [ hdr_bin, pr_bin, chw_bin, ste_bin ]:
1375 for c in s:
1376 all_bin.append(ord(c))
1378 log.info("Compiled policy: rc = %s" % hex(rc))
1379 if len(unknown_ste) > 0:
1380 log.info("The following STEs in VM/res labels were unknown:" \
1381 " %s" % list(unknown_ste))
1382 rc = -xsconstants.XSERR_BAD_LABEL
1383 if len(unknown_chw) > 0:
1384 log.info("The following Ch. Wall types in labels were unknown:" \
1385 " %s" % list(unknown_chw))
1386 rc = -xsconstants.XSERR_BAD_LABEL
1387 return rc, mapfile, all_bin.tostring()
1389 def get_enforced_binary(self):
1390 rc, binpol = security.hv_get_policy()
1391 if rc != 0:
1392 raise SecurityError(-xsconstants.XSERR_HV_OP_FAILED)
1393 return binpol
1395 get_enforced_binary = classmethod(get_enforced_binary)