diff -r 2b79cd115561 -r 9646637a0c86 tools/Makefile --- a/tools/Makefile Mon May 07 14:51:17 2007 -0400 +++ b/tools/Makefile Mon May 07 14:52:12 2007 -0400 @@ -3,6 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk SUBDIRS-y := SUBDIRS-y += libxc +ifeq ($(FLASK_ENABLE),y) +SUBDIRS-y += flask +endif SUBDIRS-y += xenstore SUBDIRS-y += misc SUBDIRS-y += examples diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/Makefile Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,26 @@ +XEN_ROOT = ../.. +include $(XEN_ROOT)/tools/Rules.mk + +SUBDIRS := +SUBDIRS += libflask +SUBDIRS += loadpolicy + +.PHONY: all +all: + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + +.PHONY: install +install: + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + +.PHONY: clean +clean: + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + + diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/libflask/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/libflask/Makefile Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,65 @@ +MAJOR = 1.0 +MINOR = 0 + +XEN_ROOT = ../../.. +include $(XEN_ROOT)/tools/Rules.mk + +XEN_LIBXC = $(XEN_ROOT)/tools/libxc + +SRCS := +SRCS += flask_op.c + +CFLAGS += -Werror +CFLAGS += -fno-strict-aliasing +CFLAGS += $(INCLUDES) -I./include -I$(XEN_LIBXC) + +# Get gcc to generate the dependencies for us. +CFLAGS += -Wp,-MD,.$(@F).d +LDFLAGS += -L. +DEPS = .*.d + +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) + +LIB := libflask.a +LIB += libflask.so libflask.so.$(MAJOR) libflask.so.$(MAJOR).$(MINOR) + +.PHONY: all +all: build + +.PHONY: build +build: + $(MAKE) $(LIB) + +.PHONY: install +install: build + [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR) + [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include + $(INSTALL_PROG) libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DATA) libflask.a $(DESTDIR)/usr/$(LIBDIR) + ln -sf libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so.$(MAJOR) + ln -sf libflask.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so + $(INSTALL_DATA) include/flask_op.h $(DESTDIR)/usr/include + +.PHONY: TAGS +TAGS: + etags -t *.c *.h + +.PHONY: clean +clean: + rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen + +# libflask + +libflask.a: $(LIB_OBJS) + $(AR) rc $@ $^ + +libflask.so: libflask.so.$(MAJOR) + ln -sf $< $@ +libflask.so.$(MAJOR): libflask.so.$(MAJOR).$(MINOR) + ln -sf $< $@ + +libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libflask.so.$(MAJOR) -shared -o $@ $^ + +-include $(DEPS) diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/libflask/flask_op.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/libflask/flask_op.c Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,104 @@ +/* + * + * Authors: Michael LeMay, + * George Coker, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +int flask_load(int xc_handle, char *buf, int size) +{ + int err; + int cmd; + flask_op_t op; + + cmd = FLASK_LOAD; + op.buf = buf; + op.size = size; + + if ( (err = do_flask_op(xc_handle, cmd, &op)) != 0 ) + return err; + + return 0; +} + +int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid) +{ + int err; + int cmd; + flask_op_t op; + + cmd = FLASK_CONTEXT_TO_SID; + op.buf = buf; + op.size = size; + + if ( (err = do_flask_op(xc_handle, cmd, &op)) != 0 ) + return err; + + sscanf(buf, "%u", sid); + + return 0; +} + +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size) +{ + int err; + int cmd; + flask_op_t op; + + cmd = FLASK_SID_TO_CONTEXT; + op.buf = buf; + op.size = size; + + snprintf(buf, size, "%u", sid); + + if ( (err = do_flask_op(xc_handle, cmd, &op)) != 0 ) + return err; + + return 0; +} + +int do_flask_op(int xc_handle, int cmd, flask_op_t *op) +{ + int ret = -1; + DECLARE_HYPERCALL; + + hypercall.op = __HYPERVISOR_xsm_op; + hypercall.arg[0] = cmd; + hypercall.arg[1] = (unsigned long)op; + + if ( mlock(op, sizeof(*op)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out; + } + + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) + { + if ( errno == EACCES ) + fprintf(stderr, "XSM operation failed!\n"); + } + + safe_munlock(op, sizeof(*op)); + + out: + return ret; +} + diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/libflask/include/flask_op.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/libflask/include/flask_op.h Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,45 @@ +/* + * + * Authors: Michael LeMay, + * George Coker, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#ifndef __FLASK_OP_H +#define __FLASK_OP_H + +#define FLASK_LOAD 1 +#define FLASK_GETENFORCE 2 +#define FLASK_SETENFORCE 3 +#define FLASK_CONTEXT_TO_SID 4 +#define FLASK_SID_TO_CONTEXT 5 +#define FLASK_ACCESS 6 +#define FLASK_CREATE 7 +#define FLASK_RELABEL 8 +#define FLASK_USER 9 +#define FLASK_POLICYVERS 10 +#define FLASK_GETBOOL 11 +#define FLASK_SETBOOL 12 +#define FLASK_COMMITBOOLS 13 +#define FLASK_MLS 14 +#define FLASK_DISABLE 15 +#define FLASK_GETAVC_THRESHOLD 16 +#define FLASK_SETAVC_THRESHOLD 17 +#define FLASK_AVC_HASHSTATS 18 +#define FLASK_AVC_CACHESTATS 19 +#define FLASK_MEMBER 20 + +typedef struct flask_op { + int size; + char *buf; +} flask_op_t; + +int flask_load(int xc_handle, char *buf, int size); +int flask_context_to_sid(int xc_handle, char *buf, int size, u_int32_t *sid); +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size); +int do_flask_op(int xc_handle, int cmd, flask_op_t *op); + +#endif diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/loadpolicy/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/loadpolicy/Makefile Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,61 @@ +XEN_ROOT=../../.. +include $(XEN_ROOT)/tools/Rules.mk +XEN_LIBXC = $(XEN_ROOT)/tools/libxc + +INSTALL = install +INSTALL_DATA = $(INSTALL) -m0644 +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 + +LIBXC_ROOT = $(XEN_ROOT)/tools/libxc +LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask + +PROFILE=#-pg +BASECFLAGS=-Wall -g -Werror +# Make gcc generate dependencies. +BASECFLAGS += -Wp,-MD,.$(@F).d +PROG_DEP = .*.d +BASECFLAGS+= $(PROFILE) +#BASECFLAGS+= -I$(XEN_ROOT)/tools +BASECFLAGS+= -I$(LIBXC_ROOT) +BASECFLAGS+= -I$(LIBFLASK_ROOT)/include +BASECFLAGS+= -I. + +CFLAGS += $(BASECFLAGS) +LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT) +TESTDIR = testsuite/tmp +TESTFLAGS= -DTESTING +TESTENV = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR) + +CLIENTS := flask-loadpolicy +CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS)) + +.PHONY: all +all: $(CLIENTS) + +$(CLIENTS): flask-%: %.o + $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lflask -lxenctrl -o $@ + +.PHONY: clean +clean: + rm -f *.o *.opic *.so + rm -f $(CLIENTS) + $(RM) $(PROG_DEP) + +.PHONY: print-dir +print-dir: + @echo -n tools/flask/loadpolicy: + +.PHONY: print-end +print-end: + @echo + +.PHONY: install +install: all + $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin + $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/sbin + +-include $(PROG_DEP) + +# never delete any intermediate files. +.SECONDARY: diff -r 2b79cd115561 -r 9646637a0c86 tools/flask/loadpolicy/loadpolicy.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/loadpolicy/loadpolicy.c Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,118 @@ +/* + * + * Authors: Michael LeMay, + * George Coker, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define USE_MMAP + +static void usage (int argCnt, const char *args[]) { + fprintf(stderr, "Usage: %s \n", args[0]); + + exit(1); +} + +int main (int argCnt, const char *args[]) { + const char *polFName; + int polFd = 0; + void *polMem = NULL; + void *polMemCp = NULL; + struct stat info; + int ret; + int xch = 0; + + if (argCnt != 2) + usage(argCnt, args); + + polFName = args[1]; + polFd = open(polFName, O_RDONLY); + if (polFd < 0) { + fprintf(stderr, "Error occurred opening policy file '%s': %s\n", + polFName, strerror(errno)); + ret = -1; + goto cleanup; + } + + ret = stat(polFName, &info); + if (ret < 0) { + fprintf(stderr, "Error occurred retrieving information about" + "policy file '%s': %s\n", polFName, strerror(errno)); + goto cleanup; + } + + polMemCp = malloc(info.st_size); + +#ifdef USE_MMAP + polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0); + if (!polMem) { + fprintf(stderr, "Error occurred mapping policy file in memory: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } + + xch = xc_interface_open(); + if (xch < 0) { + fprintf(stderr, "Unable to create interface to xenctrl: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } + + memcpy(polMemCp, polMem, info.st_size); +#else + ret = read(polFd, polMemCp, info.st_size); + if (ret < 0) { + fprintf(stderr, "Unable to read new Flask policy file: %s\n", + strerror(errno)); + goto cleanup; + } else { + printf("Read %d bytes from policy file '%s'.\n", ret, polFName); + } +#endif + + ret = flask_load(xch, polMemCp, info.st_size); + if (ret < 0) { + errno = -ret; + fprintf(stderr, "Unable to load new Flask policy: %s\n", + strerror(errno)); + ret = -1; + goto cleanup; + } else { + printf("Successfully loaded policy.\n"); + } + +done: + if (polMemCp) + free(polMemCp); + if (polMem) { + ret = munmap(polMem, info.st_size); + if (ret < 0) + fprintf(stderr, "Unable to unmap policy memory: %s\n", strerror(errno)); + } + if (polFd) + close(polFd); + if (xch) + xc_interface_close(xch); + + return ret; + +cleanup: + goto done; +} diff -r 2b79cd115561 -r 9646637a0c86 tools/libxc/xc_acm.c --- a/tools/libxc/xc_acm.c Mon May 07 14:51:17 2007 -0400 +++ b/tools/libxc/xc_acm.c Mon May 07 14:52:12 2007 -0400 @@ -19,7 +19,7 @@ int xc_acm_op(int xc_handle, int cmd, vo int ret = -1; DECLARE_HYPERCALL; - hypercall.op = __HYPERVISOR_acm_op; + hypercall.op = __HYPERVISOR_xsm_op; hypercall.arg[0] = cmd; hypercall.arg[1] = (unsigned long) arg; diff -r 2b79cd115561 -r 9646637a0c86 tools/misc/xenperf.c --- a/tools/misc/xenperf.c Mon May 07 14:51:17 2007 -0400 +++ b/tools/misc/xenperf.c Mon May 07 14:52:12 2007 -0400 @@ -46,7 +46,7 @@ const char *hypercall_name_table[64] = X(vcpu_op), X(set_segment_base), X(mmuext_op), - X(acm_op), + X(xsm_op), X(nmi_op), X(sched_op), X(callback_op), diff -r 2b79cd115561 -r 9646637a0c86 tools/python/Makefile --- a/tools/python/Makefile Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/Makefile Mon May 07 14:52:12 2007 -0400 @@ -1,5 +1,13 @@ XEN_ROOT = ../.. XEN_ROOT = ../.. include $(XEN_ROOT)/tools/Rules.mk + +XEN_SECURITY_MODULE = dummy +ifeq ($(FLASK_ENABLE),y) +XEN_SECURITY_MODULE = flask +endif +ifeq ($(ACM_SECURITY),y) +XEN_SECURITY_MODULE = acm +endif .PHONY: all all: build @@ -16,9 +24,9 @@ NLSDIR = /usr/share/locale .PHONY: build buildpy buildpy: - CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build + CC="$(CC)" CFLAGS="$(CFLAGS)" XEN_SECURITY_MODULE="$(XEN_SECURITY_MODULE)" python setup.py build -build: buildpy refresh-pot refresh-po $(CATALOGS) +build: xsm.py buildpy refresh-pot refresh-po $(CATALOGS) # NB we take care to only update the .pot file it strings have # actually changed. This is complicated by the embedded date @@ -53,6 +61,13 @@ refresh-po: $(POTFILE) %.mo: %.po $(MSGFMT) -c -o $@ $< +xsm.py: + @(set -e; \ + echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \ + echo ""; \ + echo "from xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" import *"; \ + echo "") >xen/util/xsm/$@ + .PHONY: install ifndef XEN_PYTHON_NATIVE_INSTALL install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()") @@ -84,4 +99,4 @@ test: .PHONY: clean clean: - rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) + rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/xsm/xsm.py diff -r 2b79cd115561 -r 9646637a0c86 tools/python/setup.py --- a/tools/python/setup.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/setup.py Mon May 07 14:52:12 2007 -0400 @@ -1,6 +1,7 @@ from distutils.core import setup, Extension import os + XEN_ROOT = "../.." @@ -44,6 +45,14 @@ acm = Extension("acm", libraries = libraries, sources = [ "xen/lowlevel/acm/acm.c" ]) +flask = Extension("flask", + extra_compile_args = extra_compile_args, + include_dirs = include_dirs + [ "xen/lowlevel/flask" ] + + [ "../flask/libflask/include" ], + library_dirs = library_dirs + [ "../flask/libflask" ], + libraries = libraries + [ "flask" ], + sources = [ "xen/lowlevel/flask/flask.c" ]) + ptsname = Extension("ptsname", extra_compile_args = extra_compile_args, include_dirs = include_dirs + [ "ptsname" ], @@ -51,9 +60,14 @@ ptsname = Extension("ptsname", libraries = libraries, sources = [ "ptsname/ptsname.c" ]) -modules = [ xc, xs, acm, ptsname ] +modules = [ xc, xs, ptsname ] if os.uname()[0] == 'SunOS': modules.append(scf) + +if os.environ.get('XEN_SECURITY_MODULE') == 'acm': + modules.append(acm) +if os.environ.get('XEN_SECURITY_MODULE') == 'flask': + modules.append(flask) setup(name = 'xen', version = '3.0', @@ -61,6 +75,10 @@ setup(name = 'xen', packages = ['xen', 'xen.lowlevel', 'xen.util', + 'xen.util.xsm', + 'xen.util.xsm.dummy', + 'xen.util.xsm.flask', + 'xen.util.xsm.acm', 'xen.xend', 'xen.xend.server', 'xen.xend.xenstore', diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/lowlevel/flask/flask.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/lowlevel/flask/flask.c Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,139 @@ +/****************************************************************************** + * flask.c + * + * Authors: George Coker, + * Michael LeMay, + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + */ + +#include +#include + +#include + +#define PKG "xen.lowlevel.flask" +#define CLS "flask" + +#define CTX_LEN 1024 + +static PyObject *xc_error_obj; + +typedef struct { + PyObject_HEAD; + int xc_handle; +} XcObject; + +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args, + PyObject *kwds) +{ + int xc_handle; + char *ctx; + char *buf; + uint32_t len; + uint32_t sid; + int ret; + + static char *kwd_list[] = { "context", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, + &ctx) ) + return NULL; + + len = strlen(ctx); + + buf = malloc(len); + if (!buf) { + errno = -ENOMEM; + PyErr_SetFromErrno(xc_error_obj); + } + + memcpy(buf, ctx, len); + + xc_handle = xc_interface_open(); + if (xc_handle < 0) { + errno = xc_handle; + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = flask_context_to_sid(xc_handle, buf, len, &sid); + + xc_interface_close(xc_handle); + + free(buf); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return PyInt_FromLong(sid); +} + +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args, + PyObject *kwds) +{ + int xc_handle; + uint32_t sid; + char ctx[CTX_LEN]; + uint32_t ctx_len = CTX_LEN; + int ret; + + static char *kwd_list[] = { "sid", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &sid) ) + return NULL; + + xc_handle = xc_interface_open(); + if (xc_handle < 0) { + errno = xc_handle; + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = flask_sid_to_context(xc_handle, sid, ctx, ctx_len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("s", ctx, ctx_len); +} + + +static PyMethodDef pyflask_methods[] = { + { "flask_context_to_sid", + (PyCFunction)pyflask_context_to_sid, + METH_KEYWORDS, "\n" + "Convert a context string to a dynamic SID.\n" + " context [str]: String specifying context to be converted\n" + "Returns: [int]: Numeric SID on success; -1 on error.\n" }, + + { "flask_sid_to_context", + (PyCFunction)pyflask_sid_to_context, + METH_KEYWORDS, "\n" + "Convert a dynamic SID to context string.\n" + " context [int]: SID to be converted\n" + "Returns: [str]: Numeric SID on success; -1 on error.\n" }, + + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC initflask(void) +{ + Py_InitModule("flask", pyflask_methods); +} + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/sv/CreateDomain.py --- a/tools/python/xen/sv/CreateDomain.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/sv/CreateDomain.py Mon May 07 14:52:12 2007 -0400 @@ -178,6 +178,7 @@ class CreateFinish( Sheet ): vals.console = None vals.ramdisk = None vals.ssidref = -1 + vals.context = None vals.bootloader = None vals.usb = [] vals.acpi = [] diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/security.py --- a/tools/python/xen/util/security.py Mon May 07 14:51:17 2007 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,670 +0,0 @@ -#=========================================================================== -# 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. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#============================================================================ -# Copyright (C) 2006 International Business Machines Corp. -# Author: Reiner Sailer -# Author: Bryan D. Payne -#============================================================================ - -import commands -import logging -import sys, os, string, re -import traceback -import shutil -from xen.lowlevel import acm -from xen.xend import sxp -from xen.xend.XendLogging import log -from xen.util import dictio - -#global directories and tools for security management -policy_dir_prefix = "/etc/xen/acm-security/policies" -res_label_filename = policy_dir_prefix + "/resource_labels" -boot_filename = "/boot/grub/menu.lst" -altboot_filename = "/boot/grub/grub.conf" -xensec_xml2bin = "/usr/sbin/xensec_xml2bin" -xensec_tool = "/usr/sbin/xensec_tool" - -#global patterns for map file -#police_reference_tagname = "POLICYREFERENCENAME" -primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE) -secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE) -label_template_re = re.compile(".*security_label_template.xml", re.IGNORECASE) -mapping_filename_re = re.compile(".*\.map", re.IGNORECASE) -policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE) -vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE) -res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE) -all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE) -access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE) - -#global patterns for boot configuration file -xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE) -any_title_re = re.compile("\s*title\s", re.IGNORECASE) -xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE) -kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE) -any_module_re = re.compile("\s*module\s", re.IGNORECASE) -empty_line_re = re.compile("^\s*$") -binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE) -policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE) - -#other global variables -NULL_SSIDREF = 0 - -log = logging.getLogger("xend.util.security") - -# Our own exception definition. It is masked (pass) if raised and -# whoever raises this exception must provide error information. -class ACMError(Exception): - def __init__(self,value): - self.value = value - def __str__(self): - return repr(self.value) - - - -def err(msg): - """Raise ACM exception. - """ - sys.stderr.write("ACMError: " + msg + "\n") - raise ACMError(msg) - - - -active_policy = None - - -def refresh_security_policy(): - """ - retrieves security policy - """ - global active_policy - - try: - active_policy = acm.policy() - except: - active_policy = "INACTIVE" - -# now set active_policy -refresh_security_policy() - -def on(): - """ - returns none if security policy is off (not compiled), - any string otherwise, use it: if not security.on() ... - """ - refresh_security_policy() - return (active_policy not in ['INACTIVE', 'NULL']) - - - -# Assumes a 'security' info [security access_control ...] [ssidref ...] -def get_security_info(info, field): - """retrieves security field from self.info['security']) - allowed search fields: ssidref, label, policy - """ - if isinstance(info, dict): - security = info['security'] - elif isinstance(info, list): - security = sxp.child_value(info, 'security') - if not security: - if field == 'ssidref': - #return default ssid - return 0 - else: - err("Security information not found in info struct.") - - if field == 'ssidref': - search = 'ssidref' - elif field in ['policy', 'label']: - search = 'access_control' - else: - err("Illegal field in get_security_info.") - - for idx in range(0, len(security)): - if search != security[idx][0]: - continue - if search == 'ssidref': - return int(security[idx][1]) - else: - for aidx in range(0, len(security[idx])): - if security[idx][aidx][0] == field: - return str(security[idx][aidx][1]) - - if search == 'ssidref': - return 0 - else: - return None - - - -def get_security_printlabel(info): - """retrieves printable security label from self.info['security']), - preferably the label name and otherwise (if label is not specified - in config and cannot be found in mapping file) a hex string of the - ssidref or none if both not available - """ - try: - if not on(): - return "INACTIVE" - if active_policy in ["DEFAULT"]: - return "DEFAULT" - - printlabel = get_security_info(info, 'label') - if printlabel: - return printlabel - ssidref = get_security_info(info, 'ssidref') - if not ssidref: - return None - #try to translate ssidref to a label - result = ssidref2label(ssidref) - if not result: - printlabel = "0x%08x" % ssidref - else: - printlabel = result - return printlabel - except ACMError: - #don't throw an exception in xm list - return "ERROR" - - - -def getmapfile(policyname): - """ - in: if policyname is None then the currently - active hypervisor policy is used - out: 1. primary policy, 2. secondary policy, - 3. open file descriptor for mapping file, and - 4. True if policy file is available, False otherwise - """ - if not policyname: - policyname = active_policy - map_file_ok = False - primary = None - secondary = None - #strip last part of policy as file name part - policy_dir_list = string.split(policyname, ".") - policy_file = policy_dir_list.pop() - if len(policy_dir_list) > 0: - policy_dir = string.join(policy_dir_list, "/") + "/" - else: - policy_dir = "" - - map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map" - # check if it is there, if not check if policy file is there - if not os.path.isfile(map_filename): - policy_filename = policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml" - if not os.path.isfile(policy_filename): - err("Policy file \'" + policy_filename + "\' not found.") - else: - err("Mapping file \'" + map_filename + "\' not found." + - " Use xm makepolicy to create it.") - - f = open(map_filename) - for line in f: - if policy_reference_entry_re.match(line): - l = line.split() - if (len(l) == 2) and (l[1] == policyname): - map_file_ok = True - elif primary_entry_re.match(line): - l = line.split() - if len(l) == 2: - primary = l[1] - elif secondary_entry_re.match(line): - l = line.split() - if len(l) == 2: - secondary = l[1] - f.close() - f = open(map_filename) - if map_file_ok and primary and secondary: - return (primary, secondary, f, True) - else: - err("Mapping file inconsistencies found. Try makepolicy to create a new one.") - - - -def ssidref2label(ssidref_var): - """ - returns labelname corresponding to ssidref; - maps current policy to default directory - to find mapping file - """ - #1. translated permitted input formats - if isinstance(ssidref_var, str): - ssidref_var.strip() - if ssidref_var[0:2] == "0x": - ssidref = int(ssidref_var[2:], 16) - else: - ssidref = int(ssidref_var) - elif isinstance(ssidref_var, int): - ssidref = ssidref_var - else: - err("Instance type of ssidref not supported (must be of type 'str' or 'int')") - - (primary, secondary, f, pol_exists) = getmapfile(None) - if not f: - if (pol_exists): - err("Mapping file for policy \'" + policyname + "\' not found.\n" + - "Please use makepolicy command to create mapping file!") - else: - err("Policy file for \'" + active_policy + "\' not found.") - - #2. get labelnames for both ssidref parts - pri_ssid = ssidref & 0xffff - sec_ssid = ssidref >> 16 - pri_null_ssid = NULL_SSIDREF & 0xffff - sec_null_ssid = NULL_SSIDREF >> 16 - pri_labels = [] - sec_labels = [] - labels = [] - - for line in f: - l = line.split() - if (len(l) < 5) or (l[0] != "LABEL->SSID"): - continue - if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid): - pri_labels.append(l[3]) - if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid): - sec_labels.append(l[3]) - f.close() - - #3. get the label that is in both lists (combination must be a single label) - if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid): - labels = sec_labels - elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid): - labels = pri_labels - elif secondary == "NULL": - labels = pri_labels - else: - for i in pri_labels: - for j in sec_labels: - if (i==j): - labels.append(i) - if len(labels) != 1: - err("Label for ssidref \'" + str(ssidref) + - "\' unknown or not unique in policy \'" + active_policy + "\'") - - return labels[0] - - - -def label2ssidref(labelname, policyname, type): - """ - returns ssidref corresponding to labelname; - maps current policy to default directory - to find mapping file """ - - if policyname in ['NULL', 'INACTIVE', 'DEFAULT']: - err("Cannot translate labels for \'" + policyname + "\' policy.") - - allowed_types = ['ANY'] - if type == 'dom': - allowed_types.append('VM') - elif type == 'res': - allowed_types.append('RES') - else: - err("Invalid type. Must specify 'dom' or 'res'.") - - (primary, secondary, f, pol_exists) = getmapfile(policyname) - - #2. get labelnames for ssidref parts and find a common label - pri_ssid = [] - sec_ssid = [] - for line in f: - l = line.split() - if (len(l) < 5) or (l[0] != "LABEL->SSID"): - continue - if primary and (l[1] in allowed_types) and (l[2] == primary) and (l[3] == labelname): - pri_ssid.append(int(l[4], 16)) - if secondary and (l[1] in allowed_types) and (l[2] == secondary) and (l[3] == labelname): - sec_ssid.append(int(l[4], 16)) - f.close() - if (type == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0): - pri_ssid.append(NULL_SSIDREF) - elif (type == 'res') and (secondary == "CHWALL") and (len(sec_ssid) == 0): - sec_ssid.append(NULL_SSIDREF) - - #3. sanity check and composition of ssidref - if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and (secondary != "NULL")): - err("Label \'" + labelname + "\' not found.") - elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1): - err("Label \'" + labelname + "\' not unique in policy (policy error)") - if secondary == "NULL": - return pri_ssid[0] - else: - return (sec_ssid[0] << 16) | pri_ssid[0] - - - -def refresh_ssidref(config): - """ - looks up ssidref from security field - and refreshes the value if label exists - """ - #called by dom0, policy could have changed after xen.utils.security was initialized - refresh_security_policy() - - security = None - if isinstance(config, dict): - security = config['security'] - elif isinstance(config, list): - security = sxp.child_value(config, 'security') - else: - err("Instance type of config parameter not supported.") - if not security: - #nothing to do (no security label attached) - return config - - policyname = None - labelname = None - # compose new security field - for idx in range(0, len(security)): - if security[idx][0] == 'ssidref': - security.pop(idx) - break - elif security[idx][0] == 'access_control': - for jdx in [1, 2]: - if security[idx][jdx][0] == 'label': - labelname = security[idx][jdx][1] - elif security[idx][jdx][0] == 'policy': - policyname = security[idx][jdx][1] - else: - err("Illegal field in access_control") - #verify policy is correct - if active_policy != policyname: - err("Policy \'" + policyname + "\' in label does not match active policy \'" - + active_policy +"\'!") - - new_ssidref = label2ssidref(labelname, policyname, 'dom') - if not new_ssidref: - err("SSIDREF refresh failed!") - - security.append([ 'ssidref',str(new_ssidref)]) - security = ['security', security ] - - for idx in range(0,len(config)): - if config[idx][0] == 'security': - config.pop(idx) - break - config.append(security) - - - -def get_ssid(domain): - """ - enables domains to retrieve the label / ssidref of a running domain - """ - if not on(): - err("No policy active.") - - if isinstance(domain, str): - domain_int = int(domain) - elif isinstance(domain, int): - domain_int = domain - else: - err("Illegal parameter type.") - try: - ssid_info = acm.getssid(int(domain_int)) - except: - err("Cannot determine security information.") - - if active_policy in ["DEFAULT"]: - label = "DEFAULT" - else: - label = ssidref2label(ssid_info["ssidref"]) - return(ssid_info["policyreference"], - label, - ssid_info["policytype"], - ssid_info["ssidref"]) - - - -def get_decision(arg1, arg2): - """ - enables domains to retrieve access control decisions from - the hypervisor Access Control Module. - IN: args format = ['domid', id] or ['ssidref', ssidref] - or ['access_control', ['policy', policy], ['label', label], ['type', type]] - """ - - if not on(): - err("No policy active.") - - #translate labels before calling low-level function - if arg1[0] == 'access_control': - if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'): - err("Argument type not supported.") - ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1]) - arg1 = ['ssidref', str(ssidref)] - if arg2[0] == 'access_control': - if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'): - err("Argument type not supported.") - ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1]) - arg2 = ['ssidref', str(ssidref)] - - # accept only int or string types for domid and ssidref - if isinstance(arg1[1], int): - arg1[1] = str(arg1[1]) - if isinstance(arg2[1], int): - arg2[1] = str(arg2[1]) - if not isinstance(arg1[1], str) or not isinstance(arg2[1], str): - err("Invalid id or ssidref type, string or int required") - - try: - decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1]) - except: - err("Cannot determine decision.") - - if decision: - return decision - else: - err("Cannot determine decision (Invalid parameter).") - - - -def make_policy(policy_name): - policy_file = string.join(string.split(policy_name, "."), "/") - if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"): - err("Unknown policy \'" + policy_name + "\'") - - (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file) - if ret: - err("Creating policy failed:\n" + output) - - - -def load_policy(policy_name): - global active_policy - policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/") - if not os.path.isfile(policy_file + ".bin"): - if os.path.isfile(policy_file + "-security_policy.xml"): - err("Binary file does not exist." + - "Please use makepolicy to build the policy binary.") - else: - err("Unknown Policy " + policy_name) - - #require this policy to be the first or the same as installed - if active_policy not in ['DEFAULT', policy_name]: - err("Active policy \'" + active_policy + - "\' incompatible with new policy \'" + policy_name + "\'") - (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin") - if ret: - err("Loading policy failed:\n" + output) - else: - # refresh active policy - refresh_security_policy() - - - -def dump_policy(): - if active_policy in ['NULL', 'INACTIVE']: - err("\'" + active_policy + "\' policy. Nothing to dump.") - - (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy") - if ret: - err("Dumping hypervisor policy failed:\n" + output) - print output - - - -def list_labels(policy_name, condition): - if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]: - err("Current policy \'" + active_policy + "\' has no labels defined.\n") - - (primary, secondary, f, pol_exists) = getmapfile(policy_name) - if not f: - if pol_exists: - err("Cannot find mapfile for policy \'" + policy_name + - "\'.\nPlease use makepolicy to create mapping file.") - else: - err("Unknown policy \'" + policy_name + "\'") - - labels = [] - for line in f: - if condition.match(line): - label = line.split()[3] - if label not in labels: - labels.append(label) - return labels - - -def get_res_label(resource): - """Returns resource label information (label, policy) if it exists. - Otherwise returns null label and policy. - """ - def default_res_label(): - ssidref = NULL_SSIDREF - if on(): - label = ssidref2label(ssidref) - else: - label = None - return (label, 'NULL') - - (label, policy) = default_res_label() - - # load the resource label file - res_label_cache = {} - try: - res_label_cache = dictio.dict_read("resources", res_label_filename) - except: - log.info("Resource label file not found.") - return default_res_label() - - # find the resource information - if res_label_cache.has_key(resource): - (policy, label) = res_label_cache[resource] - - return (label, policy) - - -def get_res_security_details(resource): - """Returns the (label, ssidref, policy) associated with a given - resource from the global resource label file. - """ - def default_security_details(): - ssidref = NULL_SSIDREF - if on(): - label = ssidref2label(ssidref) - else: - label = None - policy = active_policy - return (label, ssidref, policy) - - (label, ssidref, policy) = default_security_details() - - # find the entry associated with this resource - (label, policy) = get_res_label(resource) - if policy == 'NULL': - log.info("Resource label for "+resource+" not in file, using DEFAULT.") - return default_security_details() - - # is this resource label for the running policy? - if policy == active_policy: - ssidref = label2ssidref(label, policy, 'res') - else: - log.info("Resource label not for active policy, using DEFAULT.") - return default_security_details() - - return (label, ssidref, policy) - - -def unify_resname(resource): - """Makes all resource locations absolute. In case of physical - resources, '/dev/' is added to local file names""" - - if not resource: - return resource - - # sanity check on resource name - try: - (type, resfile) = resource.split(":", 1) - except: - err("Resource spec '%s' contains no ':' delimiter" % resource) - - if type == "tap": - try: - (subtype, resfile) = resfile.split(":") - except: - err("Resource spec '%s' contains no tap subtype" % resource) - - if type in ["phy", "tap"]: - if not resfile.startswith("/"): - resfile = "/dev/" + resfile - - #file: resources must specified with absolute path - if (not resfile.startswith("/")) or (not os.path.exists(resfile)): - err("Invalid resource.") - - # from here on absolute file names with resources - if type == "tap": - type = type + ":" + subtype - resource = type + ":" + resfile - return resource - - -def res_security_check(resource, domain_label): - """Checks if the given resource can be used by the given domain - label. Returns 1 if the resource can be used, otherwise 0. - """ - rtnval = 1 - - # if security is on, ask the hypervisor for a decision - if on(): - #build canonical resource name - resource = unify_resname(resource) - - (label, ssidref, policy) = get_res_security_details(resource) - domac = ['access_control'] - domac.append(['policy', active_policy]) - domac.append(['label', domain_label]) - domac.append(['type', 'dom']) - decision = get_decision(domac, ['ssidref', str(ssidref)]) - - # provide descriptive error messages - if decision == 'DENIED': - if label == ssidref2label(NULL_SSIDREF): - raise ACMError("Resource '"+resource+"' is not labeled") - rtnval = 0 - else: - raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed") - rtnval = 0 - - # security is off, make sure resource isn't labeled - else: - # Note, we can't canonicalise the resource here, because people using - # xm without ACM are free to use relative paths. - (label, policy) = get_res_label(resource) - if policy != 'NULL': - raise ACMError("Security is off, but '"+resource+"' is labeled") - rtnval = 0 - - return rtnval diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/__init__.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,1 @@ + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/acm/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/acm/__init__.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,1 @@ + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/acm/acm.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/acm/acm.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,670 @@ +#=========================================================================== +# 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. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 International Business Machines Corp. +# Author: Reiner Sailer +# Author: Bryan D. Payne +#============================================================================ + +import commands +import logging +import sys, os, string, re +import traceback +import shutil +from xen.lowlevel import acm +from xen.xend import sxp +from xen.xend.XendLogging import log +from xen.util import dictio + +#global directories and tools for security management +policy_dir_prefix = "/etc/xen/acm-security/policies" +res_label_filename = policy_dir_prefix + "/resource_labels" +boot_filename = "/boot/grub/menu.lst" +altboot_filename = "/boot/grub/grub.conf" +xensec_xml2bin = "/usr/sbin/xensec_xml2bin" +xensec_tool = "/usr/sbin/xensec_tool" + +#global patterns for map file +#police_reference_tagname = "POLICYREFERENCENAME" +primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE) +secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE) +label_template_re = re.compile(".*security_label_template.xml", re.IGNORECASE) +mapping_filename_re = re.compile(".*\.map", re.IGNORECASE) +policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE) +vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE) +res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE) +all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE) +access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE) + +#global patterns for boot configuration file +xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE) +any_title_re = re.compile("\s*title\s", re.IGNORECASE) +xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE) +kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE) +any_module_re = re.compile("\s*module\s", re.IGNORECASE) +empty_line_re = re.compile("^\s*$") +binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE) +policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE) + +#other global variables +NULL_SSIDREF = 0 + +log = logging.getLogger("xend.util.security") + +# Our own exception definition. It is masked (pass) if raised and +# whoever raises this exception must provide error information. +class ACMError(Exception): + def __init__(self,value): + self.value = value + def __str__(self): + return repr(self.value) + + + +def err(msg): + """Raise ACM exception. + """ + sys.stderr.write("ACMError: " + msg + "\n") + raise ACMError(msg) + + + +active_policy = None + + +def refresh_security_policy(): + """ + retrieves security policy + """ + global active_policy + + try: + active_policy = acm.policy() + except: + active_policy = "INACTIVE" + +# now set active_policy +refresh_security_policy() + +def on(): + """ + returns none if security policy is off (not compiled), + any string otherwise, use it: if not security.on() ... + """ + refresh_security_policy() + return (active_policy not in ['INACTIVE', 'NULL']) + + + +# Assumes a 'security' info [security access_control ...] [ssidref ...] +def get_security_info(info, field): + """retrieves security field from self.info['security']) + allowed search fields: ssidref, label, policy + """ + if isinstance(info, dict): + security = info['security'] + elif isinstance(info, list): + security = sxp.child_value(info, 'security') + if not security: + if field == 'ssidref': + #return default ssid + return 0 + else: + err("Security information not found in info struct.") + + if field == 'ssidref': + search = 'ssidref' + elif field in ['policy', 'label']: + search = 'access_control' + else: + err("Illegal field in get_security_info.") + + for idx in range(0, len(security)): + if search != security[idx][0]: + continue + if search == 'ssidref': + return int(security[idx][1]) + else: + for aidx in range(0, len(security[idx])): + if security[idx][aidx][0] == field: + return str(security[idx][aidx][1]) + + if search == 'ssidref': + return 0 + else: + return None + + + +def get_security_printlabel(info): + """retrieves printable security label from self.info['security']), + preferably the label name and otherwise (if label is not specified + in config and cannot be found in mapping file) a hex string of the + ssidref or none if both not available + """ + try: + if not on(): + return "INACTIVE" + if active_policy in ["DEFAULT"]: + return "DEFAULT" + + printlabel = get_security_info(info, 'label') + if printlabel: + return printlabel + ssidref = get_security_info(info, 'ssidref') + if not ssidref: + return None + #try to translate ssidref to a label + result = ssidref2label(ssidref) + if not result: + printlabel = "0x%08x" % ssidref + else: + printlabel = result + return printlabel + except ACMError: + #don't throw an exception in xm list + return "ERROR" + + + +def getmapfile(policyname): + """ + in: if policyname is None then the currently + active hypervisor policy is used + out: 1. primary policy, 2. secondary policy, + 3. open file descriptor for mapping file, and + 4. True if policy file is available, False otherwise + """ + if not policyname: + policyname = active_policy + map_file_ok = False + primary = None + secondary = None + #strip last part of policy as file name part + policy_dir_list = string.split(policyname, ".") + policy_file = policy_dir_list.pop() + if len(policy_dir_list) > 0: + policy_dir = string.join(policy_dir_list, "/") + "/" + else: + policy_dir = "" + + map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map" + # check if it is there, if not check if policy file is there + if not os.path.isfile(map_filename): + policy_filename = policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml" + if not os.path.isfile(policy_filename): + err("Policy file \'" + policy_filename + "\' not found.") + else: + err("Mapping file \'" + map_filename + "\' not found." + + " Use xm makepolicy to create it.") + + f = open(map_filename) + for line in f: + if policy_reference_entry_re.match(line): + l = line.split() + if (len(l) == 2) and (l[1] == policyname): + map_file_ok = True + elif primary_entry_re.match(line): + l = line.split() + if len(l) == 2: + primary = l[1] + elif secondary_entry_re.match(line): + l = line.split() + if len(l) == 2: + secondary = l[1] + f.close() + f = open(map_filename) + if map_file_ok and primary and secondary: + return (primary, secondary, f, True) + else: + err("Mapping file inconsistencies found. Try makepolicy to create a new one.") + + + +def ssidref2label(ssidref_var): + """ + returns labelname corresponding to ssidref; + maps current policy to default directory + to find mapping file + """ + #1. translated permitted input formats + if isinstance(ssidref_var, str): + ssidref_var.strip() + if ssidref_var[0:2] == "0x": + ssidref = int(ssidref_var[2:], 16) + else: + ssidref = int(ssidref_var) + elif isinstance(ssidref_var, int): + ssidref = ssidref_var + else: + err("Instance type of ssidref not supported (must be of type 'str' or 'int')") + + (primary, secondary, f, pol_exists) = getmapfile(None) + if not f: + if (pol_exists): + err("Mapping file for policy \'" + policyname + "\' not found.\n" + + "Please use makepolicy command to create mapping file!") + else: + err("Policy file for \'" + active_policy + "\' not found.") + + #2. get labelnames for both ssidref parts + pri_ssid = ssidref & 0xffff + sec_ssid = ssidref >> 16 + pri_null_ssid = NULL_SSIDREF & 0xffff + sec_null_ssid = NULL_SSIDREF >> 16 + pri_labels = [] + sec_labels = [] + labels = [] + + for line in f: + l = line.split() + if (len(l) < 5) or (l[0] != "LABEL->SSID"): + continue + if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid): + pri_labels.append(l[3]) + if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid): + sec_labels.append(l[3]) + f.close() + + #3. get the label that is in both lists (combination must be a single label) + if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid): + labels = sec_labels + elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid): + labels = pri_labels + elif secondary == "NULL": + labels = pri_labels + else: + for i in pri_labels: + for j in sec_labels: + if (i==j): + labels.append(i) + if len(labels) != 1: + err("Label for ssidref \'" + str(ssidref) + + "\' unknown or not unique in policy \'" + active_policy + "\'") + + return labels[0] + + + +def label2ssidref(labelname, policyname, type): + """ + returns ssidref corresponding to labelname; + maps current policy to default directory + to find mapping file """ + + if policyname in ['NULL', 'INACTIVE', 'DEFAULT']: + err("Cannot translate labels for \'" + policyname + "\' policy.") + + allowed_types = ['ANY'] + if type == 'dom': + allowed_types.append('VM') + elif type == 'res': + allowed_types.append('RES') + else: + err("Invalid type. Must specify 'dom' or 'res'.") + + (primary, secondary, f, pol_exists) = getmapfile(policyname) + + #2. get labelnames for ssidref parts and find a common label + pri_ssid = [] + sec_ssid = [] + for line in f: + l = line.split() + if (len(l) < 5) or (l[0] != "LABEL->SSID"): + continue + if primary and (l[1] in allowed_types) and (l[2] == primary) and (l[3] == labelname): + pri_ssid.append(int(l[4], 16)) + if secondary and (l[1] in allowed_types) and (l[2] == secondary) and (l[3] == labelname): + sec_ssid.append(int(l[4], 16)) + f.close() + if (type == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0): + pri_ssid.append(NULL_SSIDREF) + elif (type == 'res') and (secondary == "CHWALL") and (len(sec_ssid) == 0): + sec_ssid.append(NULL_SSIDREF) + + #3. sanity check and composition of ssidref + if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and (secondary != "NULL")): + err("Label \'" + labelname + "\' not found.") + elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1): + err("Label \'" + labelname + "\' not unique in policy (policy error)") + if secondary == "NULL": + return pri_ssid[0] + else: + return (sec_ssid[0] << 16) | pri_ssid[0] + + + +def refresh_ssidref(config): + """ + looks up ssidref from security field + and refreshes the value if label exists + """ + #called by dom0, policy could have changed after xen.utils.security was initialized + refresh_security_policy() + + security = None + if isinstance(config, dict): + security = config['security'] + elif isinstance(config, list): + security = sxp.child_value(config, 'security') + else: + err("Instance type of config parameter not supported.") + if not security: + #nothing to do (no security label attached) + return config + + policyname = None + labelname = None + # compose new security field + for idx in range(0, len(security)): + if security[idx][0] == 'ssidref': + security.pop(idx) + break + elif security[idx][0] == 'access_control': + for jdx in [1, 2]: + if security[idx][jdx][0] == 'label': + labelname = security[idx][jdx][1] + elif security[idx][jdx][0] == 'policy': + policyname = security[idx][jdx][1] + else: + err("Illegal field in access_control") + #verify policy is correct + if active_policy != policyname: + err("Policy \'" + policyname + "\' in label does not match active policy \'" + + active_policy +"\'!") + + new_ssidref = label2ssidref(labelname, policyname, 'dom') + if not new_ssidref: + err("SSIDREF refresh failed!") + + security.append([ 'ssidref',str(new_ssidref)]) + security = ['security', security ] + + for idx in range(0,len(config)): + if config[idx][0] == 'security': + config.pop(idx) + break + config.append(security) + + + +def get_ssid(domain): + """ + enables domains to retrieve the label / ssidref of a running domain + """ + if not on(): + err("No policy active.") + + if isinstance(domain, str): + domain_int = int(domain) + elif isinstance(domain, int): + domain_int = domain + else: + err("Illegal parameter type.") + try: + ssid_info = acm.getssid(int(domain_int)) + except: + err("Cannot determine security information.") + + if active_policy in ["DEFAULT"]: + label = "DEFAULT" + else: + label = ssidref2label(ssid_info["ssidref"]) + return(ssid_info["policyreference"], + label, + ssid_info["policytype"], + ssid_info["ssidref"]) + + + +def get_decision(arg1, arg2): + """ + enables domains to retrieve access control decisions from + the hypervisor Access Control Module. + IN: args format = ['domid', id] or ['ssidref', ssidref] + or ['access_control', ['policy', policy], ['label', label], ['type', type]] + """ + + if not on(): + err("No policy active.") + + #translate labels before calling low-level function + if arg1[0] == 'access_control': + if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'): + err("Argument type not supported.") + ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1]) + arg1 = ['ssidref', str(ssidref)] + if arg2[0] == 'access_control': + if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'): + err("Argument type not supported.") + ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1]) + arg2 = ['ssidref', str(ssidref)] + + # accept only int or string types for domid and ssidref + if isinstance(arg1[1], int): + arg1[1] = str(arg1[1]) + if isinstance(arg2[1], int): + arg2[1] = str(arg2[1]) + if not isinstance(arg1[1], str) or not isinstance(arg2[1], str): + err("Invalid id or ssidref type, string or int required") + + try: + decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1]) + except: + err("Cannot determine decision.") + + if decision: + return decision + else: + err("Cannot determine decision (Invalid parameter).") + + + +def make_policy(policy_name): + policy_file = string.join(string.split(policy_name, "."), "/") + if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"): + err("Unknown policy \'" + policy_name + "\'") + + (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file) + if ret: + err("Creating policy failed:\n" + output) + + + +def load_policy(policy_name): + global active_policy + policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/") + if not os.path.isfile(policy_file + ".bin"): + if os.path.isfile(policy_file + "-security_policy.xml"): + err("Binary file does not exist." + + "Please use makepolicy to build the policy binary.") + else: + err("Unknown Policy " + policy_name) + + #require this policy to be the first or the same as installed + if active_policy not in ['DEFAULT', policy_name]: + err("Active policy \'" + active_policy + + "\' incompatible with new policy \'" + policy_name + "\'") + (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin") + if ret: + err("Loading policy failed:\n" + output) + else: + # refresh active policy + refresh_security_policy() + + + +def dump_policy(): + if active_policy in ['NULL', 'INACTIVE']: + err("\'" + active_policy + "\' policy. Nothing to dump.") + + (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy") + if ret: + err("Dumping hypervisor policy failed:\n" + output) + print output + + + +def list_labels(policy_name, condition): + if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]: + err("Current policy \'" + active_policy + "\' has no labels defined.\n") + + (primary, secondary, f, pol_exists) = getmapfile(policy_name) + if not f: + if pol_exists: + err("Cannot find mapfile for policy \'" + policy_name + + "\'.\nPlease use makepolicy to create mapping file.") + else: + err("Unknown policy \'" + policy_name + "\'") + + labels = [] + for line in f: + if condition.match(line): + label = line.split()[3] + if label not in labels: + labels.append(label) + return labels + + +def get_res_label(resource): + """Returns resource label information (label, policy) if it exists. + Otherwise returns null label and policy. + """ + def default_res_label(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + return (label, 'NULL') + + (label, policy) = default_res_label() + + # load the resource label file + res_label_cache = {} + try: + res_label_cache = dictio.dict_read("resources", res_label_filename) + except: + log.info("Resource label file not found.") + return default_res_label() + + # find the resource information + if res_label_cache.has_key(resource): + (policy, label) = res_label_cache[resource] + + return (label, policy) + + +def get_res_security_details(resource): + """Returns the (label, ssidref, policy) associated with a given + resource from the global resource label file. + """ + def default_security_details(): + ssidref = NULL_SSIDREF + if on(): + label = ssidref2label(ssidref) + else: + label = None + policy = active_policy + return (label, ssidref, policy) + + (label, ssidref, policy) = default_security_details() + + # find the entry associated with this resource + (label, policy) = get_res_label(resource) + if policy == 'NULL': + log.info("Resource label for "+resource+" not in file, using DEFAULT.") + return default_security_details() + + # is this resource label for the running policy? + if policy == active_policy: + ssidref = label2ssidref(label, policy, 'res') + else: + log.info("Resource label not for active policy, using DEFAULT.") + return default_security_details() + + return (label, ssidref, policy) + + +def unify_resname(resource): + """Makes all resource locations absolute. In case of physical + resources, '/dev/' is added to local file names""" + + if not resource: + return resource + + # sanity check on resource name + try: + (type, resfile) = resource.split(":", 1) + except: + err("Resource spec '%s' contains no ':' delimiter" % resource) + + if type == "tap": + try: + (subtype, resfile) = resfile.split(":") + except: + err("Resource spec '%s' contains no tap subtype" % resource) + + if type in ["phy", "tap"]: + if not resfile.startswith("/"): + resfile = "/dev/" + resfile + + #file: resources must specified with absolute path + if (not resfile.startswith("/")) or (not os.path.exists(resfile)): + err("Invalid resource.") + + # from here on absolute file names with resources + if type == "tap": + type = type + ":" + subtype + resource = type + ":" + resfile + return resource + + +def res_security_check(resource, domain_label): + """Checks if the given resource can be used by the given domain + label. Returns 1 if the resource can be used, otherwise 0. + """ + rtnval = 1 + + # if security is on, ask the hypervisor for a decision + if on(): + #build canonical resource name + resource = unify_resname(resource) + + (label, ssidref, policy) = get_res_security_details(resource) + domac = ['access_control'] + domac.append(['policy', active_policy]) + domac.append(['label', domain_label]) + domac.append(['type', 'dom']) + decision = get_decision(domac, ['ssidref', str(ssidref)]) + + # provide descriptive error messages + if decision == 'DENIED': + if label == ssidref2label(NULL_SSIDREF): + raise ACMError("Resource '"+resource+"' is not labeled") + rtnval = 0 + else: + raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed") + rtnval = 0 + + # security is off, make sure resource isn't labeled + else: + # Note, we can't canonicalise the resource here, because people using + # xm without ACM are free to use relative paths. + (label, policy) = get_res_label(resource) + if policy != 'NULL': + raise ACMError("Security is off, but '"+resource+"' is labeled") + rtnval = 0 + + return rtnval diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/dummy/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/dummy/__init__.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,1 @@ + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/dummy/dummy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/dummy/dummy.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,60 @@ +import sys + +active_policy = ""; +NULL_SSIDREF = 0; + +class ACMError(Exception): + def __init__(self,value): + self.value = value + def __str__(self): + return repr(self.value) + +def err(msg): + """Raise ACM exception. + """ + sys.stderr.write("ACMError: " + msg + "\n") + raise ACMError(msg) + +def on(): + return 0 + +def get_security_info(info, field): + return 0 + +def get_security_printlabel(info): + return 0 + +def ssidref2label(ssidref): + return 0 + +def label2ssidref(label, policy, type): + return 0 + +def res_security_check(resource, domain_label): + return 1 + +def get_res_security_details(resource): + return ("","","") + +def get_res_label(resource): + return ("","") + +def unify_resname(resource): + return "" + +def make_policy(policy_name): + return 1 + +def load_policy(policy_name): + return 1 + +def dump_policy(): + print "" + +def list_labels(policy_name, condition): + labels = [] + return labels + +def refresh_ssidref(config): + return config + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/flask/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/flask/__init__.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,1 @@ + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/util/xsm/flask/flask.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/flask/flask.py Mon May 07 14:52:12 2007 -0400 @@ -0,0 +1,75 @@ +import sys +from xen.lowlevel import flask +from xen.xend import sxp + +active_policy = ""; +NULL_SSIDREF = 0; + +class ACMError(Exception): + def __init__(self,value): + self.value = value + def __str__(self): + return repr(self.value) + +def err(msg): + """Raise ACM exception. + """ + sys.stderr.write("ACMError: " + msg + "\n") + raise ACMError(msg) + +def on(): + return 1 + +def get_security_info(info, field): + if isinstance(info, dict): + security = info['security'] + elif isinstance(info, list): + security = sxp.child_value(info, 'security', ) + + for idx in range(0, len(security)): + if security[idx][0] != 'ssidref': + continue + if field == 'ssidref': + return int(security[idx][1]) + elif field == 'label': + return flask.flask_sid_to_context(int(security[idx][1])) + else: + err("Field not found!") + +def get_security_printlabel(info): + return get_security_info(info, 'label') + +def ssidref2label(ssidref): + return flask.flask_sid_to_context(ssidref) + +def label2ssidref(label, policy, type): + return flask.flask_context_to_sid(label) + +def res_security_check(resource, domain_label): + return 1 + +def get_res_security_details(resource): + return ("","","") + +def get_res_label(resource): + return ("","") + +def unify_resname(resource): + return "" + +def make_policy(policy_name): + return 1 + +def load_policy(policy_name): + return 1 + +def dump_policy(): + print "" + +def list_labels(policy_name, condition): + labels = [] + return labels + +def refresh_ssidref(config): + return config + diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xend/XendDomain.py Mon May 07 14:52:12 2007 -0400 @@ -49,7 +49,8 @@ from xen.xend.XendAPIConstants import * from xen.xend.xenstore.xstransact import xstransact from xen.xend.xenstore.xswatch import xswatch -from xen.util import mkdir, security +from xen.util import mkdir +import xen.util.xsm.xsm as security from xen.xend import uuid xc = xen.lowlevel.xc.xc() diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon May 07 14:52:12 2007 -0400 @@ -36,7 +36,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc from xen.util import asserts from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype -from xen.util import security +import xen.util.xsm.xsm as security from xen.xend import balloon, sxp, uuid, image, arch, osdep from xen.xend import XendOptions, XendNode, XendConfig diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xend/server/blkif.py Mon May 07 14:52:12 2007 -0400 @@ -20,7 +20,7 @@ import string import string from xen.util import blkif -from xen.util import security +import xen.util.xsm.xsm as security from xen.xend.XendError import VmError from xen.xend.server.DevController import DevController diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/addlabel.py Mon May 07 14:52:12 2007 -0400 @@ -23,7 +23,7 @@ import sys import sys from xen.util import dictio -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/cfgbootpolicy.py --- a/tools/python/xen/xm/cfgbootpolicy.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/cfgbootpolicy.py Mon May 07 14:52:12 2007 -0400 @@ -26,11 +26,11 @@ import shutil import shutil import string import re -from xen.util.security import err -from xen.util.security import policy_dir_prefix, xen_title_re -from xen.util.security import boot_filename, altboot_filename -from xen.util.security import any_title_re, xen_kernel_re, any_module_re -from xen.util.security import empty_line_re, binary_name_re, policy_name_re +from xen.util.xsm.xsm import err +from xen.util.xsm.xsm import policy_dir_prefix, xen_title_re +from xen.util.xsm.xsm import boot_filename, altboot_filename +from xen.util.xsm.xsm import any_title_re, xen_kernel_re, any_module_re +from xen.util.xsm.xsm import empty_line_re, binary_name_re, policy_name_re from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/create.py Mon May 07 14:52:12 2007 -0400 @@ -33,7 +33,7 @@ import xen.xend.XendClient import xen.xend.XendClient from xen.xend.XendBootloader import bootloader from xen.util import blkif -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm from xen.xm.opts import * diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/dry-run.py --- a/tools/python/xen/xm/dry-run.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/dry-run.py Mon May 07 14:52:12 2007 -0400 @@ -19,7 +19,7 @@ """Tests the security settings for a domain and its resources. """ import sys -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm import create from xen.xend import sxp from xen.xm.opts import OptionError diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/dumppolicy.py --- a/tools/python/xen/xm/dumppolicy.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/dumppolicy.py Mon May 07 14:52:12 2007 -0400 @@ -18,7 +18,7 @@ """Display currently enforced policy (low-level hypervisor representation). """ import sys -from xen.util.security import ACMError, err, dump_policy +from xen.util.xsm.xsm import ACMError, err, dump_policy from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/getlabel.py --- a/tools/python/xen/xm/getlabel.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/getlabel.py Mon May 07 14:52:12 2007 -0400 @@ -20,7 +20,7 @@ """ import sys, os, re from xen.util import dictio -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/labels.py --- a/tools/python/xen/xm/labels.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/labels.py Mon May 07 14:52:12 2007 -0400 @@ -21,8 +21,8 @@ import sys import sys import traceback import string -from xen.util.security import ACMError, err, list_labels, active_policy -from xen.util.security import vm_label_re, res_label_re, all_label_re +from xen.util.xsm.xsm import ACMError, err, list_labels, active_policy +from xen.util.xsm.xsm import vm_label_re, res_label_re, all_label_re from xen.xm.opts import OptionError diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/loadpolicy.py --- a/tools/python/xen/xm/loadpolicy.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/loadpolicy.py Mon May 07 14:52:12 2007 -0400 @@ -20,7 +20,7 @@ """ import sys import traceback -from xen.util.security import ACMError, err, load_policy +from xen.util.xsm.xsm import ACMError, err, load_policy from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/main.py Mon May 07 14:52:12 2007 -0400 @@ -866,7 +866,7 @@ def parse_doms_info(info): # We're not supporting security stuff just yet via XenAPI if serverType != SERVER_XEN_API: - from xen.util import security + import xen.util.xsm.xsm as security parsed_info['seclabel'] = security.get_security_printlabel(info) else: parsed_info['seclabel'] = "" @@ -927,15 +927,15 @@ def xm_brief_list(doms): print format % d def xm_label_list(doms): - print '%-32s %3s %5s %5s %5s %9s %-8s' % \ + print '%-40s %3s %5s %5s %10s %9s %-10s' % \ ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label') output = [] - format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \ - '%(cpu_time)8.1f %(seclabel)9s' + format = '%(name)-40s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \ + '%(cpu_time)8.1f %(seclabel)10s' if serverType != SERVER_XEN_API: - from xen.util import security + import xen.util.xsm.xsm as security for dom in doms: d = parse_doms_info(dom) @@ -1985,7 +1985,7 @@ def parse_block_configuration(args): if serverType != SERVER_XEN_API: # verify that policy permits attaching this resource - from xen.util import security + import xen.util.xsm.xsm as security if security.on(): dominfo = server.xend.domain(dom) @@ -2519,7 +2519,7 @@ def _run_cmd(cmd, cmd_name, args): err(str(e)) except Exception, e: if serverType != SERVER_XEN_API: - from xen.util import security + import xen.util.xsm.xsm as security if isinstance(e, security.ACMError): err(str(e)) return False, 1 diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/makepolicy.py --- a/tools/python/xen/xm/makepolicy.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/makepolicy.py Mon May 07 14:52:12 2007 -0400 @@ -19,7 +19,7 @@ """ import sys import traceback -from xen.util.security import ACMError, err, make_policy +from xen.util.xsm.xsm import ACMError, err, make_policy from xen.xm.opts import OptionError def usage(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/resources.py --- a/tools/python/xen/xm/resources.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/resources.py Mon May 07 14:52:12 2007 -0400 @@ -20,7 +20,7 @@ """ import sys from xen.util import dictio -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm.opts import OptionError def help(): diff -r 2b79cd115561 -r 9646637a0c86 tools/python/xen/xm/rmlabel.py --- a/tools/python/xen/xm/rmlabel.py Mon May 07 14:51:17 2007 -0400 +++ b/tools/python/xen/xm/rmlabel.py Mon May 07 14:52:12 2007 -0400 @@ -20,7 +20,7 @@ """ import sys, os, re from xen.util import dictio -from xen.util import security +import xen.util.xsm.xsm as security from xen.xm.opts import OptionError def help():