[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Extend 'xm dumppolicy' to support Xen-API
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1191416691 -3600 # Node ID 2e5e948bf69d6e59751020bff44c63828862b532 # Parent 385b9b6bb61f076d06bbffba2ef3bf667428168c Extend 'xm dumppolicy' to support Xen-API I am extending 'xm dumppolicy' to be used via the Xen-API. For this there are two new functions in the ACM policy class: - get the currently enforced policy including statistical data from the hypervisor - get the ACM 'ssidref' of a Domain. Since this may be a ACM-specific variable or type (int) I put it into the ACM class. I extended the Xen-API documentation with the two new functions. Signed-off-by: Stefan Berger <Stefanb@xxxxxxxxxx> --- docs/xen-api/xenapi-datamodel.tex | 74 +++++++++++++ tools/libxen/include/xen/api/xen_acmpolicy.h | 17 ++- tools/libxen/src/xen_acmpolicy.c | 35 ++++++ tools/python/xen/lowlevel/acm/acm.c | 37 ++++++ tools/python/xen/util/acmpolicy.py | 8 + tools/python/xen/util/xsm/acm/acm.py | 30 +++++ tools/python/xen/xend/XendXSPolicy.py | 31 +++++ tools/python/xen/xend/XendXSPolicyAdmin.py | 5 tools/python/xen/xm/dumppolicy.py | 31 +++++ tools/security/secpol_tool.c | 150 +++++++++++++++++++-------- 10 files changed, 373 insertions(+), 45 deletions(-) diff -r 385b9b6bb61f -r 2e5e948bf69d docs/xen-api/xenapi-datamodel.tex --- a/docs/xen-api/xenapi-datamodel.tex Tue Oct 02 17:07:18 2007 +0100 +++ b/docs/xen-api/xenapi-datamodel.tex Wed Oct 03 14:04:51 2007 +0100 @@ -15057,7 +15057,7 @@ Get the binary policy representation of Get the binary policy representation of the referenced policy. \noindent {\bf Signature:} -\begin{verbatim} string get_map (session_id s, xs ref self)\end{verbatim} +\begin{verbatim} string get_binary (session_id s, xs ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -15080,6 +15080,78 @@ string Base64-encoded representation of the binary policy. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_enforced\_binary} + +{\bf Overview:} +Get the binary policy representation of the currently enforced ACM policy. +In case the default policy is loaded in the hypervisor, a policy may be +managed by xend that is not yet loaded into the hypervisor. + + \noindent {\bf Signature:} +\begin{verbatim} string get_enforced_binary (session_id s, xs ref self)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +Base64-encoded representation of the binary policy. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_VM\_ssidref} + +{\bf Overview:} +Get the ACM ssidref of the given virtual machine. + + \noindent {\bf Signature:} +\begin{verbatim} string get_VM_ssidref (session_id s, vm ref vm)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt vm ref } & vm & reference to a valid VM \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +The ssidref of the given virtual machine. + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} + {\tt HANDLE\_INVALID, VM\_BAD\_POWER\_STATE, SECURITY\_ERROR} + \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} diff -r 385b9b6bb61f -r 2e5e948bf69d tools/libxen/include/xen/api/xen_acmpolicy.h --- a/tools/libxen/include/xen/api/xen_acmpolicy.h Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/libxen/include/xen/api/xen_acmpolicy.h Wed Oct 03 14:04:51 2007 +0100 @@ -108,7 +108,22 @@ xen_acmpolicy_get_binary(xen_session *se xen_xspolicy xspolicy); /** - * Get the UUID filed of the given policy. + * Get the binary representation (base64-encoded) of the currently + * enforced policy. + */ +extern bool +xen_acmpolicy_get_enforced_binary(xen_session *session, char **binary, + xen_xspolicy xspolicy); + +/** + * Get the ACM ssidref of the given VM. + */ +bool +xen_acmpolicy_get_VM_ssidref(xen_session *session, int64_t *result, + xen_vm vm); + +/** + * Get the UUID field of the given policy. */ bool xen_acmpolicy_get_uuid(xen_session *session, char **result, diff -r 385b9b6bb61f -r 2e5e948bf69d tools/libxen/src/xen_acmpolicy.c --- a/tools/libxen/src/xen_acmpolicy.c Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/libxen/src/xen_acmpolicy.c Wed Oct 03 14:04:51 2007 +0100 @@ -217,6 +217,41 @@ xen_acmpolicy_get_binary(xen_session *se bool +xen_acmpolicy_get_enforced_binary(xen_session *session, char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_enforced_binary"); + return session->ok; +} + + +bool +xen_acmpolicy_get_VM_ssidref(xen_session *session, + int64_t *result, xen_vm vm) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm } + }; + + abstract_type result_type = abstract_type_int; + + XEN_CALL_("ACMPolicy.get_VM_ssidref"); + return session->ok; +} + + +bool xen_acmpolicy_get_uuid(xen_session *session, char **result, xen_xspolicy xspolicy) { diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/lowlevel/acm/acm.c --- a/tools/python/xen/lowlevel/acm/acm.c Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/lowlevel/acm/acm.c Wed Oct 03 14:04:51 2007 +0100 @@ -26,6 +26,7 @@ #include <sys/mman.h> #include <sys/types.h> #include <stdlib.h> +#include <arpa/inet.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <xen/xsm/acm.h> @@ -258,6 +259,41 @@ static PyObject *chgpolicy(PyObject *sel } +static PyObject *getpolicy(PyObject *self, PyObject *args) +{ + struct acm_getpolicy getpolicy; + int xc_handle, rc; + uint8_t pull_buffer[8192]; + PyObject *result; + uint32_t len = sizeof(pull_buffer); + + memset(&getpolicy, 0x0, sizeof(getpolicy)); + set_xen_guest_handle(getpolicy.pullcache, pull_buffer); + getpolicy.pullcache_size = sizeof(pull_buffer); + + if ((xc_handle = xc_interface_open()) <= 0) { + PyErr_SetString(PyExc_IOError, ctrlif_op); + return NULL; + } + + rc = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy)); + + xc_interface_close(xc_handle); + + if (rc == 0) { + struct acm_policy_buffer *header = + (struct acm_policy_buffer *)pull_buffer; + if (ntohl(header->len) < sizeof(pull_buffer)) + len = ntohl(header->len); + } else { + len = 0; + } + + result = Py_BuildValue("is#", rc, pull_buffer, len); + return result; +} + + static PyObject *relabel_domains(PyObject *self, PyObject *args) { struct acm_relabel_doms reldoms; @@ -313,6 +349,7 @@ static PyMethodDef acmMethods[] = { {"getssid", getssid, METH_VARARGS, "Retrieve label information and ssidref for a domain"}, {"getdecision", getdecision, METH_VARARGS, "Retrieve ACM access control decision"}, {"chgpolicy", chgpolicy, METH_VARARGS, "Change the policy in one step"}, + {"getpolicy", getpolicy, METH_NOARGS , "Get the binary policy from the hypervisor"}, {"relabel_domains", relabel_domains, METH_VARARGS, "Relabel domains"}, /* end of list (extend list above this line) */ {NULL, NULL, 0, NULL} diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/util/acmpolicy.py --- a/tools/python/xen/util/acmpolicy.py Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/util/acmpolicy.py Wed Oct 03 14:04:51 2007 +0100 @@ -1264,3 +1264,11 @@ class ACMPolicy(XSPolicy): log.info("The following Ch. Wall types in labels were unknown:" \ " %s" % list(unknown_chw)) return rc, mapfile, all_bin.tostring() + + def get_enforced_binary(self): + rc, binpol = security.hv_get_policy() + if rc != 0: + raise SecurityError(-xsconstants.XSERR_HV_OP_FAILED) + return binpol + + get_enforced_binary = classmethod(get_enforced_binary) diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/util/xsm/acm/acm.py --- a/tools/python/xen/util/xsm/acm/acm.py Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/util/xsm/acm/acm.py Wed Oct 03 14:04:51 2007 +0100 @@ -507,6 +507,22 @@ def hv_chg_policy(bin_pol, del_array, ch rc = -xsconstants.XSERR_HV_OP_FAILED return rc, errors +def hv_get_policy(): + """ + Gte the binary policy enforced in the hypervisor + """ + rc = -xsconstants.XSERR_GENERAL_FAILURE + bin_pol = "" + if not on(): + err("No policy active.") + try: + rc, bin_pol = acm.getpolicy() + except Exception, e: + pass + if len(bin_pol) == 0: + bin_pol = None + return rc, bin_pol + def make_policy(policy_name): policy_file = string.join(string.split(policy_name, "."), "/") @@ -546,9 +562,21 @@ def dump_policy(): (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy") if ret: - err("Dumping hypervisor policy failed:\n" + output) + err("Dumping hypervisor policy failed:\n" + output) + print output + +def dump_policy_file(filename, ssidref=None): + ssid = "" + if ssidref: + ssid = " " + str(ssidref) + (ret, output) = commands.getstatusoutput(xensec_tool + " dumppolicy " + + filename + ssid) + if ret: + err("Dumping policy failed:\n" + output) + + print output def list_labels(policy_name, condition): diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/xend/XendXSPolicy.py --- a/tools/python/xen/xend/XendXSPolicy.py Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/xend/XendXSPolicy.py Wed Oct 03 14:04:51 2007 +0100 @@ -16,13 +16,15 @@ # Copyright (c) 2006 Xensource #============================================================================ +import base64 import logging +from xen.xend import XendDomain from xen.xend.XendBase import XendBase from xen.xend.XendError import * +from xen.xend.XendAPIConstants import * from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance from xen.util import xsconstants import xen.util.xsm.xsm as security -import base64 log = logging.getLogger("xend.XendXSPolicy") log.setLevel(logging.TRACE) @@ -184,8 +186,13 @@ class XendACMPolicy(XendXSPolicy): 'header' ] return XendXSPolicy.getAttrRO() + attrRO + def getFuncs(self): + funcs = [ 'get_enforced_binary', 'get_VM_ssidref' ] + return XendBase.getFuncs() + funcs + getClass = classmethod(getClass) getAttrRO = classmethod(getAttrRO) + getFuncs = classmethod(getFuncs) def __init__(self, acmpol, record, uuid): """ acmpol = actual ACMPolicy object """ @@ -221,3 +228,25 @@ class XendACMPolicy(XendXSPolicy): def get_binary(self): polbin = self.acmpol.get_bin() return base64.b64encode(polbin) + + def get_VM_ssidref(self, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + if not dom: + raise InvalidHandleError("VM", vm_ref) + if dom._stateGet() not in [ XEN_API_VM_POWER_STATE_RUNNING, \ + XEN_API_VM_POWER_STATE_PAUSED ]: + raise VMBadState("Domain is not running or paused.") + ssid = security.get_ssid(dom.getDomid()) + if not ssid: + raise SecurityError(-xsconstants.XSERR_GENERAL_FAILURE) + return ssid[3] + + def get_enforced_binary(self): + polbin = XSPolicyAdminInstance(). \ + get_enforced_binary(xsconstants.XS_POLICY_ACM) + if polbin: + return base64.b64encode(polbin) + return None + + get_enforced_binary = classmethod(get_enforced_binary) + get_VM_ssidref = classmethod(get_VM_ssidref) diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/xend/XendXSPolicyAdmin.py --- a/tools/python/xen/xend/XendXSPolicyAdmin.py Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/xend/XendXSPolicyAdmin.py Wed Oct 03 14:04:51 2007 +0100 @@ -324,6 +324,11 @@ class XSPolicyAdmin: stes = loadedpol.policy_get_stes_of_vmlabel(tmp[2]) return stes + def get_enforced_binary(self, xstype): + res = None + if xstype == xsconstants.XS_POLICY_ACM: + res = ACMPolicy.get_enforced_binary() + return res poladmin = None diff -r 385b9b6bb61f -r 2e5e948bf69d tools/python/xen/xm/dumppolicy.py --- a/tools/python/xen/xm/dumppolicy.py Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/python/xen/xm/dumppolicy.py Wed Oct 03 14:04:51 2007 +0100 @@ -17,9 +17,18 @@ #============================================================================ """Display currently enforced policy (low-level hypervisor representation). """ +import os import sys -from xen.util.xsm.xsm import XSMError, err, dump_policy +import base64 +import tempfile +import commands +from xen.util.xsm.xsm import XSMError, err, dump_policy, dump_policy_file from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server +from xen.util import xsconstants + +DOM0_UUID = "00000000-0000-0000-0000-000000000000" def help(): return """ @@ -30,7 +39,25 @@ def main(argv): if len(argv) != 1: raise OptionError("No arguments expected.") - dump_policy() + if xm_main.serverType == xm_main.SERVER_XEN_API: + try: + bin_pol = server.xenapi.ACMPolicy.get_enforced_binary() + if bin_pol: + dom0_ssid = server.xenapi.ACMPolicy.get_VM_ssidref(DOM0_UUID) + bin = base64.b64decode(bin_pol) + try: + fd, filename = tempfile.mkstemp(suffix=".bin") + os.write(fd, bin) + os.close(fd) + dump_policy_file(filename, dom0_ssid) + finally: + os.unlink(filename) + else: + err("No policy is installed.") + except Exception, e: + err("An error occurred getting the running policy: %s" % str(e)) + else: + dump_policy() if __name__ == '__main__': try: diff -r 385b9b6bb61f -r 2e5e948bf69d tools/security/secpol_tool.c --- a/tools/security/secpol_tool.c Tue Oct 02 17:07:18 2007 +0100 +++ b/tools/security/secpol_tool.c Wed Oct 03 14:04:51 2007 +0100 @@ -49,7 +49,9 @@ void usage(char *progname) "ACTION is one of:\n" "\t getpolicy\n" "\t dumpstats\n" - "\t loadpolicy <binary policy file>\n", progname); + "\t loadpolicy <binary policy file>\n" + "\t dumppolicy <binary policy file> [Dom-0 ssidref]\n", + progname); exit(-1); } @@ -288,53 +290,93 @@ int acm_domain_getpolicy(int xc_handle) return ret; } -/************************ load binary policy ******************************/ - -int acm_domain_loadpolicy(int xc_handle, const char *filename) +/************************ dump binary policy ******************************/ + +static int load_file(const char *filename, + uint8_t **buffer, off_t *len) { struct stat mystat; - int ret, fd; - off_t len; - uint8_t *buffer; - uint16_t chwall_ssidref, ste_ssidref; - - if ((ret = stat(filename, &mystat))) { + int ret = 0; + int fd; + + if ((ret = stat(filename, &mystat)) != 0) { printf("File %s not found.\n", filename); + ret = errno; goto out; } - len = mystat.st_size; - if ((buffer = malloc(len)) == NULL) { + *len = mystat.st_size; + + if ((*buffer = malloc(*len)) == NULL) { ret = -ENOMEM; goto out; } + if ((fd = open(filename, O_RDONLY)) <= 0) { ret = -ENOENT; printf("File %s not found.\n", filename); goto free_out; } - ret =acm_get_ssidref(xc_handle, 0, &chwall_ssidref, &ste_ssidref); - if (ret < 0) { + + if (*len == read(fd, *buffer, *len)) + return 0; + +free_out: + free(*buffer); + *buffer = NULL; + *len = 0; +out: + return ret; +} + +static int acm_domain_dumppolicy(const char *filename, uint32_t ssidref) +{ + uint8_t *buffer = NULL; + off_t len; + int ret = 0; + uint16_t chwall_ssidref, ste_ssidref; + + chwall_ssidref = (ssidref ) & 0xffff; + ste_ssidref = (ssidref >> 16) & 0xffff; + + if ((ret = load_file(filename, &buffer, &len)) == 0) { + acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref); + free(buffer); + } + + return ret; +} + +/************************ load binary policy ******************************/ + +int acm_domain_loadpolicy(int xc_handle, const char *filename) +{ + int ret; + off_t len; + uint8_t *buffer; + uint16_t chwall_ssidref, ste_ssidref; + struct acm_setpolicy setpolicy; + + ret = load_file(filename, &buffer, &len); + if (ret != 0) + goto out; + + ret = acm_get_ssidref(xc_handle, 0, &chwall_ssidref, &ste_ssidref); + if (ret < 0) goto free_out; - } - if (len == read(fd, buffer, len)) { - struct acm_setpolicy setpolicy; - /* dump it and then push it down into xen/acm */ - acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref); - set_xen_guest_handle(setpolicy.pushcache, buffer); - setpolicy.pushcache_size = len; - ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy)); - - if (ret) - printf - ("ERROR setting policy.\n"); - else - printf("Successfully changed policy.\n"); - + + /* dump it and then push it down into xen/acm */ + acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref); + set_xen_guest_handle(setpolicy.pushcache, buffer); + setpolicy.pushcache_size = len; + ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy)); + + if (ret) { + printf("ERROR setting policy.\n"); } else { - ret = -1; - } - close(fd); + printf("Successfully changed policy.\n"); + } + free_out: free(buffer); out: @@ -435,26 +477,56 @@ int main(int argc, char **argv) if (argc < 2) usage(argv[0]); - if ((xc_handle = xc_interface_open()) <= 0) { - printf("ERROR: Could not open xen privcmd device!\n"); - exit(-1); - } if (!strcmp(argv[1], "getpolicy")) { if (argc != 2) usage(argv[0]); + + if ((xc_handle = xc_interface_open()) <= 0) { + printf("ERROR: Could not open xen privcmd device!\n"); + exit(-1); + } + ret = acm_domain_getpolicy(xc_handle); + + xc_interface_close(xc_handle); } else if (!strcmp(argv[1], "loadpolicy")) { if (argc != 3) usage(argv[0]); + + if ((xc_handle = xc_interface_open()) <= 0) { + printf("ERROR: Could not open xen privcmd device!\n"); + exit(-1); + } + ret = acm_domain_loadpolicy(xc_handle, argv[2]); + + xc_interface_close(xc_handle); } else if (!strcmp(argv[1], "dumpstats")) { if (argc != 2) usage(argv[0]); + + if ((xc_handle = xc_interface_open()) <= 0) { + printf("ERROR: Could not open xen privcmd device!\n"); + exit(-1); + } + ret = acm_domain_dumpstats(xc_handle); + + xc_interface_close(xc_handle); + } else if (!strcmp(argv[1], "dumppolicy")) { + uint32_t ssidref = 0xffffffff; + if (argc < 3 || argc > 4) + usage(argv[0]); + if (argc == 4) { + if (!sscanf(argv[3], "%i", &ssidref)) { + printf("Error: Could not parse ssidref.\n"); + exit(-1); + } + } + ret = acm_domain_dumppolicy(argv[2], ssidref); } else usage(argv[0]); - xc_interface_close(xc_handle); - return ret; -} + return ret; +} _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |