[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xense-devel
Subject:    [Xen-devel] [Xense-devel] [PATCH] [3/4] Flask XSM tools
From:       "George S. Coker, II" <gscoker () alpha ! ncsc ! mil>
Date:       2006-12-20 14:08:58
Message-ID: 1166623739.4824.266.camel () moss-walleye ! epoch ! ncsc ! mil
[Download RAW message or body]

This patch implements the Flask tools for the xen control plane (xm &
xend).  The patch also refactors the ACM toolchain so that a common
security API (based on the existing ACM toolchain) is exported to xm and
xend.

To create a domain with the Flask module, add the following (for
example) to a domain's configuration file

access_control = ["policy=,label=system_u:object_r:domU_t"]

This will cause a domain to be created with the label
"system_u:object_r:domU_t".  Flask does not use the policy value in the
access_control structure.

Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>

["tools-xsm-flask-121906-xen-unstable.diff" (tools-xsm-flask-121906-xen-unstable.diff)]

diff -r 12923ba929c8 -r 0655af4eae49 tools/Makefile
--- a/tools/Makefile	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/Makefile	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/libxc/xc_acm.c
--- a/tools/libxc/xc_acm.c	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/libxc/xc_acm.c	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/misc/xenperf.c
--- a/tools/misc/xenperf.c	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/misc/xenperf.c	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/Makefile
--- a/tools/python/Makefile	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/Makefile	Tue Dec 19 21:50:31 2006 -0500
@@ -1,11 +1,32 @@ 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
+
+xen/util/xsm/xsm.py:
+	@(set -e; \
+	  echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \
+	  echo "";\
+	  echo "if XEN_SECURITY_MODULE == 'flask':"; \
+	  echo "    from xen.util.xsm.flask.flask import *"; \
+	  echo "elif XEN_SECURITY_MODULE == 'acm':"; \
+	  echo "    from xen.util.xsm.acm.acm import *"; \
+	  echo "else:"; \
+	  echo "    from xen.util.xsm.dummy.dummy import *"; \
+	  echo "") >$@
 
 .PHONY: all
 all: build
 
 .PHONY: build
 build:
+	$(MAKE) xen/util/xsm/xsm.py
 	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build
 
 .PHONY: install
@@ -23,4 +44,5 @@ test:
 
 .PHONY: clean
 clean:
+	rm xen/util/xsm/xsm.py
 	rm -rf build *.pyc *.pyo *.o *.a *~
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/setup.py
--- a/tools/python/setup.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/setup.py	Tue Dec 19 21:50:31 2006 -0500
@@ -1,6 +1,7 @@
 
 from distutils.core import setup, Extension
 import os
+
 
 XEN_ROOT = "../.."
 
@@ -37,12 +38,24 @@ 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" ] + 
+                                        [ "/tools/flask/libflask/include" ],
+               library_dirs       = library_dirs + [ "/tools/flask/libflask" ],
+               libraries          = libraries + [ "flask" ],
+               sources            = [ "xen/lowlevel/flask/flask.c" ])
+
 setup(name            = 'xen',
       version         = '3.0',
       description     = 'Xen',
       packages        = ['xen',
                          'xen.lowlevel',
                          'xen.util',
+                         'xen.util.xsm',
+                         'xen.util.xsm.flask',
+                         'xen.util.xsm.acm',
+                         'xen.util.xsm.dummy',
                          'xen.xend',
                          'xen.xend.server',
                          'xen.xend.xenstore',
@@ -56,7 +69,7 @@ setup(name            = 'xen',
                          'xen.xm.tests'
                          ],
       ext_package = "xen.lowlevel",
-      ext_modules = [ xc, xs, acm ]
+      ext_modules = [ xc, xs, acm, flask ],
       )
 
 os.chdir('logging')
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/sv/CreateDomain.py
--- a/tools/python/xen/sv/CreateDomain.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/sv/CreateDomain.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xend/XendDomain.py	Tue Dec 19 21:50:31 2006 -0500
@@ -45,7 +45,8 @@ from xen.xend.XendDevices import XendDev
 
 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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Dec 19 21:50:31 2006 -0500
@@ -35,7 +35,7 @@ import xen.lowlevel.xc
 import xen.lowlevel.xc
 from xen.util import asserts
 from xen.util.blkif import blkdev_uname_to_file
-from xen.util import security
+import xen.util.xsm.xsm as security
 
 from xen.xend import balloon, sxp, uuid, image, arch
 from xen.xend import XendRoot, XendNode, XendConfig
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xend/server/blkif.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/addlabel.py
--- a/tools/python/xen/xm/addlabel.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/addlabel.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/cfgbootpolicy.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/create.py	Tue Dec 19 21:50:31 2006 -0500
@@ -31,7 +31,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.opts import *
 
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/dry-run.py
--- a/tools/python/xen/xm/dry-run.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/dry-run.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/dumppolicy.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/getlabel.py
--- a/tools/python/xen/xm/getlabel.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/getlabel.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/labels.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/loadpolicy.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/main.py	Tue Dec 19 21:50:31 2006 -0500
@@ -45,7 +45,7 @@ from xen.xend.XendConstants import *
 
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
-from xen.util import security
+import xen.util.xsm.xsm as security
 from xen.util.xmlrpclib2 import ServerProxy
 
 import XenAPI
@@ -676,12 +676,12 @@ 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'
     
     for dom in doms:
         d = parse_doms_info(dom)
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/makepolicy.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/resources.py
--- a/tools/python/xen/xm/resources.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/resources.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/xm/rmlabel.py
--- a/tools/python/xen/xm/rmlabel.py	Sat Dec 16 11:54:25 2006 -0500
+++ b/tools/python/xen/xm/rmlabel.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/flask/Makefile
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/Makefile	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/flask/libflask/Makefile
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/libflask/Makefile	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,93 @@
+
+INSTALL        = install
+INSTALL_PROG    = $(INSTALL) -m0755
+INSTALL_DATA    = $(INSTALL) -m0644
+INSTALL_DIR    = $(INSTALL) -d -m0755
+
+MAJOR    = 3.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)
+# Define this to make it possible to run valgrind on code linked with these
+# libraries.
+#CFLAGS   += -DVALGRIND -O0 -ggdb3
+
+# 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: check-for-zlib mk-symlinks
+	$(MAKE) $(LIB)
+
+.PHONY: check-for-zlib
+check-for-zlib:
+	@if [ ! -e /usr/include/zlib.h ]; then \
+	echo "***********************************************************"; \
+	echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
+	echo "***********************************************************"; \
+	false; \
+	fi
+
+.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
+
+.PHONY: rpm
+rpm: build
+	rm -rf staging
+	mkdir staging
+	mkdir staging/i386
+	rpmbuild --define "staging$$PWD/staging" --define '_builddir.' \
+		--define "_rpmdir$$PWD/staging" -bb rpm.spec
+	mv staging/i386/*.rpm .
+	rm -rf staging
+
+# 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 12923ba929c8 -r 0655af4eae49 tools/flask/libflask/flask_op.c
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/libflask/flask_op.c	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,104 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *            George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ *    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 <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+
+#include <xc_private.h>
+
+#include "flask_op.h"
+
+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 12923ba929c8 -r 0655af4eae49 tools/flask/libflask/include/flask_op.h
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/libflask/include/flask_op.h	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,49 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *            George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ *    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 UTIL_FLASK_OP_H
+#define UTIL_FLASK_OP_H
+
+struct flask_op {
+    int   size;
+    char *buf;
+};
+
+
+struct flask_op_t;
+typedef struct flask_op flask_op_t;
+
+#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
+
+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 12923ba929c8 -r 0655af4eae49 tools/flask/loadpolicy/Makefile
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/loadpolicy/Makefile	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/flask/loadpolicy/loadpolicy.c
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/flask/loadpolicy/loadpolicy.c	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,117 @@
+/*
+ *
+ *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *            George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ *    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 <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <xenctrl.h>
+#include <flask_op.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+
+#define USE_MMAP
+
+static void usage (int argCnt, const char *args[]) {
+    fprintf(stderr, "Usage: %s <policy.file>\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 12923ba929c8 -r 0655af4eae49 tools/python/xen/lowlevel/flask/flask.c
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/lowlevel/flask/flask.c	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,139 @@
+/******************************************************************************
+ * flask.c
+ * 
+ * Authors: George Coker, <gscoker@alpha.ncsc.mil>
+ *          Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *
+ *
+ *    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 <Python.h>
+#include <xenctrl.h>
+
+#include <flask_op.h>
+
+#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 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/__init__.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/__init__.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,1 @@
+ 
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/acm/__init__.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/acm/__init__.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,1 @@
+ 
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/acm/acm.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/acm/acm.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,668 @@
+#===========================================================================
+# 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 <bdpayne@us.ibm.com>
+#============================================================================
+
+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
+
+    #build canonical resource name
+    resource = unify_resname(resource)
+
+    # if security is on, ask the hypervisor for a decision
+    if on():
+        (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:
+        (label, policy) = get_res_label(resource)
+        if policy != 'NULL':
+            raise ACMError("Security is off, but '"+resource+"' is labeled")
+            rtnval = 0
+
+    return rtnval
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/dummy/__init__.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/dummy/__init__.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,1 @@
+ 
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/dummy/dummy.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/dummy/dummy.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,4 @@
+active_policy = "";
+
+def on():
+    return 0
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/flask/__init__.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/flask/__init__.py	Tue Dec 19 21:50:31 2006 -0500
@@ -0,0 +1,1 @@
+ 
diff -r 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/xsm/flask/flask.py
--- /dev/null	Thu Jan  1 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xsm/flask/flask.py	Tue Dec 19 21:50:31 2006 -0500
@@ -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 12923ba929c8 -r 0655af4eae49 tools/python/xen/util/security.py
--- a/tools/python/xen/util/security.py	Sat Dec 16 11:54:25 2006 -0500
+++ /dev/null	Thu Jan  1 00:00:00 1970 +0000
@@ -1,668 +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 <bdpayne@us.ibm.com>
-#============================================================================
-
-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
-
-    #build canonical resource name
-    resource = unify_resname(resource)
-
-    # if security is on, ask the hypervisor for a decision
-    if on():
-        (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:
-        (label, policy) = get_res_label(resource)
-        if policy != 'NULL':
-            raise ACMError("Security is off, but '"+resource+"' is labeled")
-            rtnval = 0
-
-    return rtnval



_______________________________________________
Xense-devel mailing list
Xense-devel@lists.xensource.com
http://lists.xensource.com/xense-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic