mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
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>
This commit is contained in:
1 parent
0ea4d2fb34
commit
4eb5685edc
8 files changed
+146
-63
No files matched your search
@@ -1,4 +1,4 @@
|
||||
#============================================================================
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
@@ -17,10 +17,11 @@
|
||||
#============================================================================
|
||||
|
||||
import os
|
||||
import commands
|
||||
import struct
|
||||
import stat
|
||||
import array
|
||||
import struct
|
||||
import shutil
|
||||
import commands
|
||||
from xml.dom import minidom, Node
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.util import xsconstants, bootloader, mkdir
|
||||
@@ -28,6 +29,7 @@ from xen.util.xspolicy import XSPolicy
|
||||
from xen.xend.XendError import SecurityError
|
||||
import xen.util.xsm.acm.acm as security
|
||||
from xen.util.xsm.xsm import XSMError
|
||||
from xen.xend import XendOptions
|
||||
|
||||
ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
|
||||
|
||||
@@ -64,6 +66,73 @@ ACM_CHWALL_CONFLICT = 0x103
|
||||
ACM_SSIDREF_IN_USE = 0x104
|
||||
|
||||
|
||||
DEFAULT_policy = \
|
||||
"<?xml version=\"1.0\" ?>\n" +\
|
||||
"<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" +\
|
||||
" <PolicyHeader>\n" +\
|
||||
" <PolicyName>DEFAULT</PolicyName>\n" +\
|
||||
" <Version>1.0</Version>\n" +\
|
||||
" </PolicyHeader>\n" +\
|
||||
" <SimpleTypeEnforcement>\n" +\
|
||||
" <SimpleTypeEnforcementTypes>\n" +\
|
||||
" <Type>SystemManagement</Type>\n" +\
|
||||
" </SimpleTypeEnforcementTypes>\n" +\
|
||||
" </SimpleTypeEnforcement>\n" +\
|
||||
" <ChineseWall>\n" +\
|
||||
" <ChineseWallTypes>\n" +\
|
||||
" <Type>SystemManagement</Type>\n" +\
|
||||
" </ChineseWallTypes>\n" +\
|
||||
" </ChineseWall>\n" +\
|
||||
" <SecurityLabelTemplate>\n" +\
|
||||
" <SubjectLabels bootstrap=\"SystemManagement\">\n" +\
|
||||
" <VirtualMachineLabel>\n" +\
|
||||
" <Name>SystemManagement</Name>\n" +\
|
||||
" <SimpleTypeEnforcementTypes>\n" +\
|
||||
" <Type>SystemManagement</Type>\n" +\
|
||||
" </SimpleTypeEnforcementTypes>\n" +\
|
||||
" <ChineseWallTypes>\n" +\
|
||||
" <Type/>\n" +\
|
||||
" </ChineseWallTypes>\n" +\
|
||||
" </VirtualMachineLabel>\n" +\
|
||||
" </SubjectLabels>\n" +\
|
||||
" </SecurityLabelTemplate>\n" +\
|
||||
"</SecurityPolicyDefinition>\n"
|
||||
|
||||
|
||||
def get_DEFAULT_policy():
|
||||
return DEFAULT_policy
|
||||
|
||||
def initialize():
|
||||
xoptions = XendOptions.instance()
|
||||
basedir = xoptions.get_xend_security_path()
|
||||
policiesdir = basedir + "/policies"
|
||||
mkdir.parents(policiesdir, stat.S_IRWXU)
|
||||
|
||||
instdir = security.install_policy_dir_prefix
|
||||
DEF_policy_file = "DEFAULT-security_policy.xml"
|
||||
xsd_file = "security_policy.xsd"
|
||||
|
||||
files = [ xsd_file ]
|
||||
|
||||
for file in files:
|
||||
if not os.path.isfile(policiesdir + "/" + file ):
|
||||
try:
|
||||
shutil.copyfile(instdir + "/" + file,
|
||||
policiesdir + "/" + file)
|
||||
except Exception, e:
|
||||
log.info("could not copy '%s': %s" %
|
||||
(file, str(e)))
|
||||
#Install default policy.
|
||||
f = open(policiesdir + "/" + DEF_policy_file, 'w')
|
||||
if f:
|
||||
f.write(get_DEFAULT_policy())
|
||||
f.close()
|
||||
else:
|
||||
log.error("Could not write the default policy's file.")
|
||||
defpol = ACMPolicy(xml=get_DEFAULT_policy())
|
||||
defpol.compile()
|
||||
|
||||
|
||||
class ACMPolicy(XSPolicy):
|
||||
"""
|
||||
ACMPolicy class. Implements methods for getting information from
|
||||
@@ -92,7 +161,6 @@ class ACMPolicy(XSPolicy):
|
||||
rc = self.validate()
|
||||
if rc != xsconstants.XSERR_SUCCESS:
|
||||
raise SecurityError(rc)
|
||||
mkdir.parents(ACM_POLICIES_DIR, stat.S_IRWXU)
|
||||
if ref:
|
||||
from xen.xend.XendXSPolicy import XendACMPolicy
|
||||
self.xendacmpolicy = XendACMPolicy(self, {}, ref)
|
||||
@@ -341,8 +409,13 @@ class ACMPolicy(XSPolicy):
|
||||
minor = int(tmp[1])
|
||||
return (major, minor)
|
||||
|
||||
def get_policies_path(self):
|
||||
xoptions = XendOptions.instance()
|
||||
basedir = xoptions.get_xend_security_path()
|
||||
return basedir + "/policies/"
|
||||
|
||||
def policy_path(self, name, prefix = ACM_POLICIES_DIR ):
|
||||
def policy_path(self, name):
|
||||
prefix = self.get_policies_path()
|
||||
path = prefix + name.replace('.','/')
|
||||
_path = path.split("/")
|
||||
del _path[-1]
|
||||
@@ -394,12 +467,14 @@ class ACMPolicy(XSPolicy):
|
||||
#
|
||||
# Utility functions related to the policy's files
|
||||
#
|
||||
def get_filename(self, postfix, prefix = ACM_POLICIES_DIR, dotted=False):
|
||||
def get_filename(self, postfix, prefix=None, dotted=False):
|
||||
"""
|
||||
Create the filename for the policy. The prefix is prepended
|
||||
to the path. If dotted is True, then a policy name like
|
||||
'a.b.c' will remain as is, otherwise it will become 'a/b/c'
|
||||
"""
|
||||
if prefix == None:
|
||||
prefix = self.get_policies_path()
|
||||
name = self.get_name()
|
||||
if name:
|
||||
p = name.split(".")
|
||||
@@ -432,6 +507,17 @@ class ACMPolicy(XSPolicy):
|
||||
def get_bin(self):
|
||||
return self.__readfile(".bin")
|
||||
|
||||
def copy_policy_file(self, suffix, destdir):
|
||||
spolfile = self.get_filename(suffix)
|
||||
dpolfile = destdir + "/" + self.get_filename(suffix,"",dotted=True)
|
||||
try:
|
||||
shutil.copyfile(spolfile, dpolfile)
|
||||
except Exception, e:
|
||||
log.error("Could not copy policy file %s to %s: %s" %
|
||||
(spolfile, dpolfile, str(e)))
|
||||
return -xsconstants.XSERR_FILE_ERROR
|
||||
return xsconstants.XSERR_SUCCESS
|
||||
|
||||
#
|
||||
# DOM-related functions
|
||||
#
|
||||
@@ -831,9 +917,14 @@ class ACMPolicy(XSPolicy):
|
||||
if path:
|
||||
f = open(path, 'w')
|
||||
if f:
|
||||
f.write(self.toxml())
|
||||
f.close()
|
||||
rc = 0
|
||||
try:
|
||||
try:
|
||||
f.write(self.toxml())
|
||||
rc = 0
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
f.close()
|
||||
return rc
|
||||
|
||||
def __write_to_file(self, suffix, data):
|
||||
|
||||
@@ -35,7 +35,8 @@ from xen.util import dictio, xsconstants
|
||||
from xen.xend.XendConstants import *
|
||||
|
||||
#global directories and tools for security management
|
||||
security_dir_prefix = "/etc/xen/acm-security"
|
||||
install_policy_dir_prefix = "/etc/xen/acm-security/policies"
|
||||
security_dir_prefix = XendOptions.instance().get_xend_security_path()
|
||||
policy_dir_prefix = security_dir_prefix + "/policies"
|
||||
res_label_filename = policy_dir_prefix + "/resource_labels"
|
||||
boot_filename = "/boot/grub/menu.lst"
|
||||
@@ -323,7 +324,7 @@ def label2ssidref(labelname, policyname, typ):
|
||||
maps current policy to default directory
|
||||
to find mapping file """
|
||||
|
||||
if policyname in ['NULL', 'INACTIVE', 'DEFAULT', 'INACCESSIBLE' ]:
|
||||
if policyname in ['NULL', 'INACTIVE', 'INACCESSIBLE' ]:
|
||||
err("Cannot translate labels for \'" + policyname + "\' policy.")
|
||||
|
||||
allowed_types = ['ANY']
|
||||
@@ -447,10 +448,8 @@ def get_ssid(domain):
|
||||
except:
|
||||
err("Cannot determine security information.")
|
||||
|
||||
if active_policy in ["DEFAULT"]:
|
||||
label = "DEFAULT"
|
||||
else:
|
||||
label = ssidref2label(ssid_info["ssidref"])
|
||||
label = ssidref2label(ssid_info["ssidref"])
|
||||
|
||||
return(ssid_info["policyreference"],
|
||||
label,
|
||||
ssid_info["policytype"],
|
||||
|
||||
@@ -120,6 +120,9 @@ class XendOptions:
|
||||
"""Default xend QCoW storage repository location."""
|
||||
xend_storage_path_default = '/var/lib/xend/storage'
|
||||
|
||||
"""Default xend security state storage path."""
|
||||
xend_security_path_default = '/var/lib/xend/security'
|
||||
|
||||
"""Default script to configure a backend network interface"""
|
||||
vif_script = osdep.vif_script
|
||||
|
||||
@@ -245,6 +248,11 @@ class XendOptions:
|
||||
"""
|
||||
return self.get_config_string("xend-storage-path", self.xend_storage_path_default)
|
||||
|
||||
def get_xend_security_path(self):
|
||||
""" Get the path for security state
|
||||
"""
|
||||
return self.get_config_string("xend-security-path", self.xend_security_path_default)
|
||||
|
||||
def get_network_script(self):
|
||||
"""@return the script used to alter the network configuration when
|
||||
Xend starts and stops, or None if no such script is specified."""
|
||||
|
||||
@@ -22,10 +22,10 @@ from xml.dom import minidom, Node
|
||||
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend import uuid
|
||||
from xen.util import xsconstants, dictio, bootloader
|
||||
from xen.util import xsconstants, bootloader
|
||||
import xen.util.xsm.acm.acm as security
|
||||
from xen.util.xspolicy import XSPolicy
|
||||
from xen.util.acmpolicy import ACMPolicy
|
||||
from xen.util.acmpolicy import ACMPolicy, initialize
|
||||
from xen.xend.XendError import SecurityError
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class XSPolicyAdmin:
|
||||
self.xsobjs = {}
|
||||
|
||||
act_pol_name = self.get_hv_loaded_policy_name()
|
||||
initialize()
|
||||
|
||||
ref = uuid.createString()
|
||||
try:
|
||||
@@ -59,6 +60,7 @@ class XSPolicyAdmin:
|
||||
|
||||
log.debug("XSPolicyAdmin: Known policies: %s" % self.policies)
|
||||
|
||||
|
||||
def isXSEnabled(self):
|
||||
""" Check whether 'security' is enabled on this system.
|
||||
This currently only checks for ACM-enablement.
|
||||
@@ -99,12 +101,23 @@ class XSPolicyAdmin:
|
||||
# This is meant as an update to a currently loaded policy
|
||||
if flags & xsconstants.XS_INST_LOAD == 0:
|
||||
raise SecurityError(-xsconstants.XSERR_POLICY_LOADED)
|
||||
if flags & xsconstants.XS_INST_BOOT == 0:
|
||||
self.rm_bootpolicy()
|
||||
|
||||
# Remember old flags, so they can be restored if update fails
|
||||
old_flags = self.get_policy_flags(loadedpol)
|
||||
|
||||
# Remove policy from bootloader in case of new name of policy
|
||||
self.rm_bootpolicy()
|
||||
|
||||
rc, errors = loadedpol.update(xmltext)
|
||||
if rc == 0:
|
||||
irc = self.activate_xspolicy(loadedpol, flags)
|
||||
# policy is loaded; if setting the boot flag fails it's ok.
|
||||
else:
|
||||
old_flags = old_flags & xsconstants.XS_INST_BOOT
|
||||
log.info("OLD FLAGS TO RESTORE: %s" % str(old_flags))
|
||||
if old_flags != 0:
|
||||
self.activate_xspolicy(loadedpol, xsconstants.XS_INST_BOOT)
|
||||
|
||||
return (loadedpol, rc, errors)
|
||||
|
||||
try:
|
||||
@@ -161,15 +174,11 @@ class XSPolicyAdmin:
|
||||
return (acmpol, xsconstants.XSERR_SUCCESS, errors)
|
||||
|
||||
def make_boot_policy(self, acmpol):
|
||||
spolfile = acmpol.get_filename(".bin")
|
||||
dpolfile = "/boot/" + acmpol.get_filename(".bin","",dotted=True)
|
||||
if not os.path.isfile(spolfile):
|
||||
log.error("binary policy file does not exist.")
|
||||
return -xsconstants.XSERR_FILE_ERROR
|
||||
try:
|
||||
shutil.copyfile(spolfile, dpolfile)
|
||||
except:
|
||||
return -xsconstants.XSERR_FILE_ERROR
|
||||
if acmpol.is_default_policy():
|
||||
return xsconstants.XSERR_SUCCESS
|
||||
rc = acmpol.copy_policy_file(".bin","/boot")
|
||||
if rc != xsconstants.XSERR_SUCCESS:
|
||||
return rc
|
||||
|
||||
try:
|
||||
filename = acmpol.get_filename(".bin","",dotted=True)
|
||||
@@ -231,7 +240,8 @@ class XSPolicyAdmin:
|
||||
flags = 0
|
||||
|
||||
filename = acmpol.get_filename(".bin","", dotted=True)
|
||||
if bootloader.loads_default_policy(filename):
|
||||
if bootloader.loads_default_policy(filename) or \
|
||||
acmpol.is_default_policy():
|
||||
flags |= xsconstants.XS_INST_BOOT
|
||||
|
||||
if acmpol.isloaded():
|
||||
|
||||
@@ -25,6 +25,7 @@ import base64
|
||||
import struct
|
||||
import xen.util.xsm.xsm as security
|
||||
from xen.util import xsconstants
|
||||
from xen.util.xsm.acm.acm import install_policy_dir_prefix
|
||||
from xen.util.acmpolicy import ACMPolicy, \
|
||||
ACM_EVTCHN_SHARING_VIOLATION,\
|
||||
ACM_GNTTAB_SHARING_VIOLATION, \
|
||||
@@ -32,7 +33,6 @@ from xen.util.acmpolicy import ACMPolicy, \
|
||||
ACM_CHWALL_CONFLICT, \
|
||||
ACM_SSIDREF_IN_USE
|
||||
from xen.xm.opts import OptionError
|
||||
from xen.util.xsm.acm.acm import policy_dir_prefix
|
||||
from xen.xm import main as xm_main
|
||||
from xen.xm.getpolicy import getpolicy
|
||||
from xen.xm.main import server
|
||||
@@ -86,7 +86,7 @@ def setpolicy(policytype, policy_name, flags, overwrite):
|
||||
if policytype.upper() == xsconstants.ACM_POLICY_ID:
|
||||
xs_type = xsconstants.XS_POLICY_ACM
|
||||
|
||||
for prefix in [ './', policy_dir_prefix+"/" ]:
|
||||
for prefix in [ './', install_policy_dir_prefix+"/" ]:
|
||||
policy_file = prefix + "/".join(policy_name.split(".")) + \
|
||||
"-security_policy.xml"
|
||||
|
||||
@@ -99,9 +99,12 @@ def setpolicy(policytype, policy_name, flags, overwrite):
|
||||
f.close()
|
||||
except:
|
||||
raise OptionError("Could not read policy file from current"
|
||||
" directory or '%s'." % policy_dir_prefix)
|
||||
" directory or '%s'." %
|
||||
install_policy_dir_prefix)
|
||||
|
||||
if xm_main.serverType == xm_main.SERVER_XEN_API:
|
||||
if xs_type != int(server.xenapi.XSPolicy.get_xstype()):
|
||||
raise security.XSMError("ACM policy type not supported.")
|
||||
|
||||
try:
|
||||
policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type,
|
||||
@@ -124,6 +127,8 @@ def setpolicy(policytype, policy_name, flags, overwrite):
|
||||
getpolicy(False)
|
||||
else:
|
||||
# Non-Xen-API call.
|
||||
if xs_type != server.xend.security.get_xstype():
|
||||
raise security.XSMError("ACM policy type not supported.")
|
||||
|
||||
rc, errors = server.xend.security.set_policy(xs_type,
|
||||
xml,
|
||||
|
||||