ia64/xen-unstable

changeset 15817:993655d24b55

Xen Security Modules: Tools.
Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>
author kfraser@localhost.localdomain
date Fri Aug 31 11:37:20 2007 +0100 (2007-08-31)
parents 6c8c934b235c
children fa4d44c9d9f6
files tools/Makefile tools/flask/Makefile tools/flask/libflask/Makefile tools/flask/libflask/flask_op.c tools/flask/libflask/include/flask_op.h tools/flask/loadpolicy/Makefile tools/flask/loadpolicy/loadpolicy.c tools/misc/xenperf.c tools/python/Makefile tools/python/setup.py tools/python/xen/lowlevel/flask/flask.c tools/python/xen/util/acmpolicy.py tools/python/xen/util/xsm/__init__.py tools/python/xen/util/xsm/acm/__init__.py tools/python/xen/util/xsm/acm/acm.py tools/python/xen/util/xsm/dummy/__init__.py tools/python/xen/util/xsm/dummy/dummy.py tools/python/xen/util/xsm/flask/__init__.py tools/python/xen/util/xsm/flask/flask.py tools/python/xen/util/xsm/xsm_core.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendVDI.py tools/python/xen/xend/XendXSPolicy.py tools/python/xen/xend/XendXSPolicyAdmin.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/addlabel.py tools/python/xen/xm/cfgbootpolicy.py tools/python/xen/xm/create.py tools/python/xen/xm/dry-run.py tools/python/xen/xm/dumppolicy.py tools/python/xen/xm/getlabel.py tools/python/xen/xm/labels.py tools/python/xen/xm/loadpolicy.py tools/python/xen/xm/main.py tools/python/xen/xm/makepolicy.py tools/python/xen/xm/resources.py tools/python/xen/xm/rmlabel.py tools/python/xen/xm/setpolicy.py
line diff
     1.1 --- a/tools/Makefile	Fri Aug 31 11:31:18 2007 +0100
     1.2 +++ b/tools/Makefile	Fri Aug 31 11:37:20 2007 +0100
     1.3 @@ -3,6 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk
     1.4  
     1.5  SUBDIRS-y :=
     1.6  SUBDIRS-y += libxc
     1.7 +ifeq ($(FLASK_ENABLE),y)
     1.8 +SUBDIRS-y += flask
     1.9 +endif
    1.10  SUBDIRS-y += xenstore
    1.11  SUBDIRS-y += misc
    1.12  SUBDIRS-y += examples
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/flask/Makefile	Fri Aug 31 11:37:20 2007 +0100
     2.3 @@ -0,0 +1,26 @@
     2.4 +XEN_ROOT = ../..
     2.5 +include $(XEN_ROOT)/tools/Rules.mk
     2.6 +
     2.7 +SUBDIRS :=
     2.8 +SUBDIRS += libflask
     2.9 +SUBDIRS += loadpolicy
    2.10 +
    2.11 +.PHONY: all
    2.12 +all:
    2.13 +	@set -e; for subdir in $(SUBDIRS); do \
    2.14 +		$(MAKE) -C $$subdir $@; \
    2.15 +	done
    2.16 +
    2.17 +.PHONY: install
    2.18 +install:
    2.19 +	@set -e; for subdir in $(SUBDIRS); do \
    2.20 +		$(MAKE) -C $$subdir $@; \
    2.21 +	done
    2.22 +
    2.23 +.PHONY: clean
    2.24 +clean:
    2.25 +	@set -e; for subdir in $(SUBDIRS); do \
    2.26 +		$(MAKE) -C $$subdir $@; \
    2.27 +	done
    2.28 +
    2.29 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/flask/libflask/Makefile	Fri Aug 31 11:37:20 2007 +0100
     3.3 @@ -0,0 +1,65 @@
     3.4 +MAJOR    = 1.0
     3.5 +MINOR    = 0
     3.6 +
     3.7 +XEN_ROOT = ../../..
     3.8 +include $(XEN_ROOT)/tools/Rules.mk
     3.9 +
    3.10 +XEN_LIBXC = $(XEN_ROOT)/tools/libxc
    3.11 +
    3.12 +SRCS       :=
    3.13 +SRCS       += flask_op.c
    3.14 +
    3.15 +CFLAGS   += -Werror
    3.16 +CFLAGS   += -fno-strict-aliasing
    3.17 +CFLAGS   += $(INCLUDES) -I./include -I$(XEN_LIBXC) 
    3.18 +
    3.19 +# Get gcc to generate the dependencies for us.
    3.20 +CFLAGS   += -Wp,-MD,.$(@F).d
    3.21 +LDFLAGS  += -L.
    3.22 +DEPS     = .*.d
    3.23 +
    3.24 +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
    3.25 +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
    3.26 +
    3.27 +LIB := libflask.a
    3.28 +LIB += libflask.so libflask.so.$(MAJOR) libflask.so.$(MAJOR).$(MINOR)
    3.29 +
    3.30 +.PHONY: all
    3.31 +all: build
    3.32 +
    3.33 +.PHONY: build
    3.34 +build:
    3.35 +	$(MAKE) $(LIB)
    3.36 +
    3.37 +.PHONY: install
    3.38 +install: build
    3.39 +	[ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)
    3.40 +	[ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include
    3.41 +	$(INSTALL_PROG) libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
    3.42 +	$(INSTALL_DATA) libflask.a $(DESTDIR)/usr/$(LIBDIR)
    3.43 +	ln -sf libflask.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so.$(MAJOR)
    3.44 +	ln -sf libflask.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libflask.so
    3.45 +	$(INSTALL_DATA) include/flask_op.h $(DESTDIR)/usr/include
    3.46 +
    3.47 +.PHONY: TAGS
    3.48 +TAGS:
    3.49 +	etags -t *.c *.h
    3.50 +
    3.51 +.PHONY: clean
    3.52 +clean:
    3.53 +	rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen
    3.54 +
    3.55 +# libflask
    3.56 +
    3.57 +libflask.a: $(LIB_OBJS)
    3.58 +	$(AR) rc $@ $^
    3.59 +
    3.60 +libflask.so: libflask.so.$(MAJOR)
    3.61 +	ln -sf $< $@
    3.62 +libflask.so.$(MAJOR): libflask.so.$(MAJOR).$(MINOR)
    3.63 +	ln -sf $< $@
    3.64 +
    3.65 +libflask.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
    3.66 +	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libflask.so.$(MAJOR) -shared -o $@ $^
    3.67 +
    3.68 +-include $(DEPS)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/flask/libflask/flask_op.c	Fri Aug 31 11:37:20 2007 +0100
     4.3 @@ -0,0 +1,100 @@
     4.4 +/*
     4.5 + *
     4.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
     4.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
     4.8 + *
     4.9 + *  This program is free software; you can redistribute it and/or modify
    4.10 + *  it under the terms of the GNU General Public License version 2,
    4.11 + *  as published by the Free Software Foundation.
    4.12 + */
    4.13 +
    4.14 +#include <unistd.h>
    4.15 +#include <stdio.h>
    4.16 +#include <errno.h>
    4.17 +#include <fcntl.h>
    4.18 +#include <string.h>
    4.19 +#include <sys/mman.h>
    4.20 +#include <sys/types.h>
    4.21 +#include <sys/stat.h>
    4.22 +#include <stdlib.h>
    4.23 +#include <sys/ioctl.h>
    4.24 +
    4.25 +#include <xc_private.h>
    4.26 +
    4.27 +#include <flask_op.h>
    4.28 +
    4.29 +int flask_load(int xc_handle, char *buf, int size)
    4.30 +{
    4.31 +    int err;
    4.32 +    flask_op_t op;
    4.33 +    
    4.34 +    op.cmd = FLASK_LOAD;
    4.35 +    op.buf = buf;
    4.36 +    op.size = size;
    4.37 +    
    4.38 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
    4.39 +        return err;
    4.40 +
    4.41 +    return 0;
    4.42 +}
    4.43 +
    4.44 +int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid)
    4.45 +{
    4.46 +    int err;
    4.47 +    flask_op_t op;
    4.48 +    
    4.49 +    op.cmd = FLASK_CONTEXT_TO_SID;
    4.50 +    op.buf = buf;
    4.51 +    op.size = size;
    4.52 +    
    4.53 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
    4.54 +        return err;
    4.55 +    
    4.56 +    sscanf(buf, "%u", sid);
    4.57 +
    4.58 +    return 0;
    4.59 +}
    4.60 +
    4.61 +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size)
    4.62 +{
    4.63 +    int err;
    4.64 +    flask_op_t op;
    4.65 +    
    4.66 +    op.cmd = FLASK_SID_TO_CONTEXT;
    4.67 +    op.buf = buf;
    4.68 +    op.size = size;
    4.69 +    
    4.70 +    snprintf(buf, size, "%u", sid);
    4.71 +
    4.72 +    if ( (err = do_flask_op(xc_handle, &op)) != 0 )
    4.73 +        return err;
    4.74 +
    4.75 +    return 0;
    4.76 +}
    4.77 +
    4.78 +int do_flask_op(int xc_handle, flask_op_t *op)
    4.79 +{
    4.80 +    int ret = -1;
    4.81 +    DECLARE_HYPERCALL;
    4.82 +
    4.83 +    hypercall.op     = __HYPERVISOR_xsm_op;
    4.84 +    hypercall.arg[0] = (unsigned long)op;
    4.85 +
    4.86 +    if ( mlock(op, sizeof(*op)) != 0 )
    4.87 +    {
    4.88 +        PERROR("Could not lock memory for Xen hypercall");
    4.89 +        goto out;
    4.90 +    }
    4.91 +
    4.92 +    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
    4.93 +    {
    4.94 +        if ( errno == EACCES )
    4.95 +            fprintf(stderr, "XSM operation failed!\n");
    4.96 +    }
    4.97 +
    4.98 +    safe_munlock(op, sizeof(*op));
    4.99 +
   4.100 + out:
   4.101 +    return ret;
   4.102 +}
   4.103 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/flask/libflask/include/flask_op.h	Fri Aug 31 11:37:20 2007 +0100
     5.3 @@ -0,0 +1,46 @@
     5.4 +/*
     5.5 + *
     5.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
     5.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
     5.8 + *
     5.9 + *  This program is free software; you can redistribute it and/or modify
    5.10 + *  it under the terms of the GNU General Public License version 2,
    5.11 + *  as published by the Free Software Foundation.
    5.12 + */
    5.13 +
    5.14 +#ifndef __FLASK_OP_H
    5.15 +#define __FLASK_OP_H
    5.16 +
    5.17 +#define FLASK_LOAD              1
    5.18 +#define FLASK_GETENFORCE        2
    5.19 +#define FLASK_SETENFORCE        3
    5.20 +#define FLASK_CONTEXT_TO_SID    4
    5.21 +#define FLASK_SID_TO_CONTEXT    5
    5.22 +#define FLASK_ACCESS            6
    5.23 +#define FLASK_CREATE            7
    5.24 +#define FLASK_RELABEL           8
    5.25 +#define FLASK_USER              9
    5.26 +#define FLASK_POLICYVERS        10
    5.27 +#define FLASK_GETBOOL           11
    5.28 +#define FLASK_SETBOOL           12
    5.29 +#define FLASK_COMMITBOOLS       13
    5.30 +#define FLASK_MLS               14
    5.31 +#define FLASK_DISABLE           15
    5.32 +#define FLASK_GETAVC_THRESHOLD  16
    5.33 +#define FLASK_SETAVC_THRESHOLD  17
    5.34 +#define FLASK_AVC_HASHSTATS     18
    5.35 +#define FLASK_AVC_CACHESTATS    19
    5.36 +#define FLASK_MEMBER            20
    5.37 +
    5.38 +typedef struct flask_op {
    5.39 +    int   cmd;
    5.40 +    int   size;
    5.41 +    char *buf;
    5.42 +} flask_op_t;
    5.43 +
    5.44 +int flask_load(int xc_handle, char *buf, int size);
    5.45 +int flask_context_to_sid(int xc_handle, char *buf, int size, u_int32_t *sid);
    5.46 +int flask_sid_to_context(int xc_handle, int sid, char *buf, int size);
    5.47 +int do_flask_op(int xc_handle, flask_op_t *op);
    5.48 +
    5.49 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/flask/loadpolicy/Makefile	Fri Aug 31 11:37:20 2007 +0100
     6.3 @@ -0,0 +1,61 @@
     6.4 +XEN_ROOT=../../..
     6.5 +include $(XEN_ROOT)/tools/Rules.mk
     6.6 +XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
     6.7 +
     6.8 +INSTALL         = install
     6.9 +INSTALL_DATA    = $(INSTALL) -m0644
    6.10 +INSTALL_PROG    = $(INSTALL) -m0755
    6.11 +INSTALL_DIR     = $(INSTALL) -d -m0755
    6.12 +
    6.13 +LIBXC_ROOT = $(XEN_ROOT)/tools/libxc
    6.14 +LIBFLASK_ROOT = $(XEN_ROOT)/tools/flask/libflask
    6.15 +
    6.16 +PROFILE=#-pg
    6.17 +BASECFLAGS=-Wall -g -Werror
    6.18 +# Make gcc generate dependencies.
    6.19 +BASECFLAGS += -Wp,-MD,.$(@F).d
    6.20 +PROG_DEP = .*.d
    6.21 +BASECFLAGS+= $(PROFILE)
    6.22 +#BASECFLAGS+= -I$(XEN_ROOT)/tools
    6.23 +BASECFLAGS+= -I$(LIBXC_ROOT)
    6.24 +BASECFLAGS+= -I$(LIBFLASK_ROOT)/include
    6.25 +BASECFLAGS+= -I.
    6.26 +
    6.27 +CFLAGS  += $(BASECFLAGS)
    6.28 +LDFLAGS += $(PROFILE) -L$(XEN_LIBXC) -L$(LIBFLASK_ROOT)
    6.29 +TESTDIR  = testsuite/tmp
    6.30 +TESTFLAGS= -DTESTING
    6.31 +TESTENV  = XENSTORED_ROOTDIR=$(TESTDIR) XENSTORED_RUNDIR=$(TESTDIR)
    6.32 +
    6.33 +CLIENTS := flask-loadpolicy
    6.34 +CLIENTS_OBJS := $(patsubst flask-%,%.o,$(CLIENTS))
    6.35 +
    6.36 +.PHONY: all
    6.37 +all: $(CLIENTS)
    6.38 +
    6.39 +$(CLIENTS): flask-%: %.o
    6.40 +	$(LINK.o) $< $(LOADLIBES) $(LDLIBS) -L. -lflask -lxenctrl -o $@
    6.41 +
    6.42 +.PHONY: clean
    6.43 +clean: 
    6.44 +	rm -f *.o *.opic *.so
    6.45 +	rm -f $(CLIENTS)
    6.46 +	$(RM) $(PROG_DEP)
    6.47 +
    6.48 +.PHONY: print-dir
    6.49 +print-dir:
    6.50 +	@echo -n tools/flask/loadpolicy: 
    6.51 +
    6.52 +.PHONY: print-end
    6.53 +print-end:
    6.54 +	@echo
    6.55 +
    6.56 +.PHONY: install
    6.57 +install: all
    6.58 +	$(INSTALL_DIR) -p $(DESTDIR)/usr/sbin
    6.59 +	$(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/sbin
    6.60 +
    6.61 +-include $(PROG_DEP)
    6.62 +
    6.63 +# never delete any intermediate files.
    6.64 +.SECONDARY:
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/flask/loadpolicy/loadpolicy.c	Fri Aug 31 11:37:20 2007 +0100
     7.3 @@ -0,0 +1,130 @@
     7.4 +/*
     7.5 + *
     7.6 + *  Authors:  Michael LeMay, <mdlemay@epoch.ncsc.mil>
     7.7 + *            George Coker, <gscoker@alpha.ncsc.mil>
     7.8 + *
     7.9 + *    This program is free software; you can redistribute it and/or modify
    7.10 + *    it under the terms of the GNU General Public License version 2,
    7.11 + *      as published by the Free Software Foundation.
    7.12 + */
    7.13 +
    7.14 +#include <stdlib.h>
    7.15 +#include <errno.h>
    7.16 +#include <stdio.h>
    7.17 +#include <xenctrl.h>
    7.18 +#include <fcntl.h>
    7.19 +#include <sys/mman.h>
    7.20 +#include <sys/stat.h>
    7.21 +#include <string.h>
    7.22 +#include <unistd.h>
    7.23 +
    7.24 +#include <flask_op.h>
    7.25 +
    7.26 +#define USE_MMAP
    7.27 +
    7.28 +static void usage (int argCnt, const char *args[])
    7.29 +{
    7.30 +    fprintf(stderr, "Usage: %s <policy.file>\n", args[0]);
    7.31 +    exit(1);
    7.32 +}
    7.33 +
    7.34 +int main (int argCnt, const char *args[])
    7.35 +{
    7.36 +    const char *polFName;
    7.37 +    int polFd = 0;
    7.38 +    void *polMem = NULL;
    7.39 +    void *polMemCp = NULL;
    7.40 +    struct stat info;
    7.41 +    int ret;
    7.42 +    int xch = 0;
    7.43 +
    7.44 +    if (argCnt != 2)
    7.45 +        usage(argCnt, args);
    7.46 +
    7.47 +    polFName = args[1];
    7.48 +    polFd = open(polFName, O_RDONLY);
    7.49 +    if ( polFd < 0 )
    7.50 +    {
    7.51 +        fprintf(stderr, "Error occurred opening policy file '%s': %s\n",
    7.52 +                polFName, strerror(errno));
    7.53 +        ret = -1;
    7.54 +        goto cleanup;
    7.55 +    }
    7.56 +    
    7.57 +    ret = stat(polFName, &info);
    7.58 +    if ( ret < 0 )
    7.59 +    {
    7.60 +        fprintf(stderr, "Error occurred retrieving information about"
    7.61 +                "policy file '%s': %s\n", polFName, strerror(errno));
    7.62 +        goto cleanup;
    7.63 +    }
    7.64 +
    7.65 +    polMemCp = malloc(info.st_size);
    7.66 +
    7.67 +#ifdef USE_MMAP
    7.68 +    polMem = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, polFd, 0);
    7.69 +    if ( !polMem )
    7.70 +    {
    7.71 +        fprintf(stderr, "Error occurred mapping policy file in memory: %s\n",
    7.72 +                strerror(errno));
    7.73 +        ret = -1;
    7.74 +        goto cleanup;
    7.75 +    }
    7.76 +
    7.77 +    xch = xc_interface_open();
    7.78 +    if ( xch < 0 )
    7.79 +    {
    7.80 +        fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
    7.81 +                strerror(errno));
    7.82 +        ret = -1;
    7.83 +        goto cleanup;
    7.84 +    }
    7.85 +
    7.86 +    memcpy(polMemCp, polMem, info.st_size);
    7.87 +#else
    7.88 +    ret = read(polFd, polMemCp, info.st_size);
    7.89 +    if ( ret < 0 )
    7.90 +    {
    7.91 +        fprintf(stderr, "Unable to read new Flask policy file: %s\n",
    7.92 +                strerror(errno));
    7.93 +        goto cleanup;
    7.94 +    }
    7.95 +    else
    7.96 +    {
    7.97 +        printf("Read %d bytes from policy file '%s'.\n", ret, polFName);
    7.98 +    }
    7.99 +#endif
   7.100 +
   7.101 +    ret = flask_load(xch, polMemCp, info.st_size);
   7.102 +    if ( ret < 0 )
   7.103 +    {
   7.104 +        errno = -ret;
   7.105 +        fprintf(stderr, "Unable to load new Flask policy: %s\n",
   7.106 +                strerror(errno));
   7.107 +        ret = -1;
   7.108 +        goto cleanup;
   7.109 +    }
   7.110 +    else
   7.111 +    {
   7.112 +        printf("Successfully loaded policy.\n");
   7.113 +    }
   7.114 +
   7.115 +done:
   7.116 +    if ( polMemCp )
   7.117 +        free(polMemCp);
   7.118 +    if ( polMem )
   7.119 +    {
   7.120 +        ret = munmap(polMem, info.st_size);
   7.121 +        if ( ret < 0 )
   7.122 +            fprintf(stderr, "Unable to unmap policy memory: %s\n", strerror(errno));
   7.123 +    }
   7.124 +    if ( polFd )
   7.125 +        close(polFd);
   7.126 +    if ( xch )
   7.127 +        xc_interface_close(xch);
   7.128 +
   7.129 +    return ret;
   7.130 +
   7.131 +cleanup:
   7.132 +    goto done;
   7.133 +}
     8.1 --- a/tools/misc/xenperf.c	Fri Aug 31 11:31:18 2007 +0100
     8.2 +++ b/tools/misc/xenperf.c	Fri Aug 31 11:37:20 2007 +0100
     8.3 @@ -46,7 +46,7 @@ const char *hypercall_name_table[64] =
     8.4      X(vcpu_op),
     8.5      X(set_segment_base),
     8.6      X(mmuext_op),
     8.7 -    X(acm_op),
     8.8 +    X(xsm_op),
     8.9      X(nmi_op),
    8.10      X(sched_op),
    8.11      X(callback_op),
     9.1 --- a/tools/python/Makefile	Fri Aug 31 11:31:18 2007 +0100
     9.2 +++ b/tools/python/Makefile	Fri Aug 31 11:37:20 2007 +0100
     9.3 @@ -1,6 +1,14 @@
     9.4  XEN_ROOT = ../..
     9.5  include $(XEN_ROOT)/tools/Rules.mk
     9.6  
     9.7 +XEN_SECURITY_MODULE = dummy
     9.8 +ifeq ($(FLASK_ENABLE),y)
     9.9 +XEN_SECURITY_MODULE = flask
    9.10 +endif
    9.11 +ifeq ($(ACM_SECURITY),y)
    9.12 +XEN_SECURITY_MODULE = acm
    9.13 +endif
    9.14 +
    9.15  .PHONY: all
    9.16  all: build
    9.17  
    9.18 @@ -16,9 +24,9 @@ NLSDIR = /usr/share/locale
    9.19  
    9.20  .PHONY: build buildpy
    9.21  buildpy:
    9.22 -	CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build
    9.23 +	CC="$(CC)" CFLAGS="$(CFLAGS)" XEN_SECURITY_MODULE="$(XEN_SECURITY_MODULE)" python setup.py build
    9.24  
    9.25 -build: buildpy refresh-pot refresh-po $(CATALOGS)
    9.26 +build: xsm.py buildpy refresh-pot refresh-po $(CATALOGS)
    9.27  
    9.28  # NB we take care to only update the .pot file it strings have
    9.29  # actually changed. This is complicated by the embedded date
    9.30 @@ -53,6 +61,18 @@ refresh-po: $(POTFILE)
    9.31  %.mo: %.po
    9.32  	$(MSGFMT) -c -o $@ $<
    9.33  
    9.34 +xsm.py:
    9.35 +	@(set -e; \
    9.36 +	  echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \
    9.37 +	  echo "from xsm_core import *"; \
    9.38 +	  echo ""; \
    9.39 +	  echo "import xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" as xsm_module"; \
    9.40 +	  echo ""; \
    9.41 +	  echo "xsm_init(xsm_module)"; \
    9.42 +	  echo "from xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" import *"; \
    9.43 +	  echo "del xsm_module"; \
    9.44 +	  echo "") >xen/util/xsm/$@
    9.45 +
    9.46  .PHONY: install
    9.47  ifndef XEN_PYTHON_NATIVE_INSTALL
    9.48  install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()")
    9.49 @@ -84,4 +104,4 @@ test:
    9.50  
    9.51  .PHONY: clean
    9.52  clean:
    9.53 -	rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS)
    9.54 +	rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/xsm/xsm.py
    10.1 --- a/tools/python/setup.py	Fri Aug 31 11:31:18 2007 +0100
    10.2 +++ b/tools/python/setup.py	Fri Aug 31 11:37:20 2007 +0100
    10.3 @@ -44,6 +44,14 @@ acm = Extension("acm",
    10.4                 libraries          = libraries,
    10.5                 sources            = [ "xen/lowlevel/acm/acm.c" ])
    10.6  
    10.7 +flask = Extension("flask",
    10.8 +               extra_compile_args = extra_compile_args,
    10.9 +               include_dirs       = include_dirs + [ "xen/lowlevel/flask" ] + 
   10.10 +                                        [ "../flask/libflask/include" ],
   10.11 +               library_dirs       = library_dirs + [ "../flask/libflask" ],
   10.12 +               libraries          = libraries + [ "flask" ],
   10.13 +               sources            = [ "xen/lowlevel/flask/flask.c" ])
   10.14 +
   10.15  ptsname = Extension("ptsname",
   10.16                 extra_compile_args = extra_compile_args,
   10.17                 include_dirs       = include_dirs + [ "ptsname" ],
   10.18 @@ -51,16 +59,25 @@ ptsname = Extension("ptsname",
   10.19                 libraries          = libraries,
   10.20                 sources            = [ "ptsname/ptsname.c" ])
   10.21  
   10.22 -modules = [ xc, xs, acm, ptsname ]
   10.23 +modules = [ xc, xs, ptsname ]
   10.24  if os.uname()[0] == 'SunOS':
   10.25      modules.append(scf)
   10.26  
   10.27 +if os.environ.get('XEN_SECURITY_MODULE') == 'acm':
   10.28 +    modules.append(acm)
   10.29 +if os.environ.get('XEN_SECURITY_MODULE') == 'flask':
   10.30 +    modules.append(flask)
   10.31 +
   10.32  setup(name            = 'xen',
   10.33        version         = '3.0',
   10.34        description     = 'Xen',
   10.35        packages        = ['xen',
   10.36                           'xen.lowlevel',
   10.37                           'xen.util',
   10.38 +                         'xen.util.xsm',
   10.39 +                         'xen.util.xsm.dummy',
   10.40 +                         'xen.util.xsm.flask',
   10.41 +                         'xen.util.xsm.acm',
   10.42                           'xen.xend',
   10.43                           'xen.xend.server',
   10.44                           'xen.xend.xenstore',
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/python/xen/lowlevel/flask/flask.c	Fri Aug 31 11:37:20 2007 +0100
    11.3 @@ -0,0 +1,139 @@
    11.4 +/******************************************************************************
    11.5 + * flask.c
    11.6 + * 
    11.7 + * Authors: George Coker, <gscoker@alpha.ncsc.mil>
    11.8 + *          Michael LeMay, <mdlemay@epoch.ncsc.mil>
    11.9 + *
   11.10 + *
   11.11 + *    This program is free software; you can redistribute it and/or modify
   11.12 + *    it under the terms of the GNU General Public License version 2,
   11.13 + *    as published by the Free Software Foundation.
   11.14 + */
   11.15 +
   11.16 +#include <Python.h>
   11.17 +#include <xenctrl.h>
   11.18 +
   11.19 +#include <flask_op.h>
   11.20 +
   11.21 +#define PKG "xen.lowlevel.flask"
   11.22 +#define CLS "flask"
   11.23 +
   11.24 +#define CTX_LEN 1024
   11.25 +
   11.26 +static PyObject *xc_error_obj;
   11.27 +
   11.28 +typedef struct {
   11.29 +    PyObject_HEAD;
   11.30 +    int xc_handle;
   11.31 +} XcObject;
   11.32 +
   11.33 +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
   11.34 +                                                                 PyObject *kwds)
   11.35 +{
   11.36 +    int xc_handle;
   11.37 +    char *ctx;
   11.38 +    char *buf;
   11.39 +    uint32_t len;
   11.40 +    uint32_t sid;
   11.41 +    int ret;
   11.42 +
   11.43 +    static char *kwd_list[] = { "context", NULL };
   11.44 +
   11.45 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list,
   11.46 +                                      &ctx) )
   11.47 +        return NULL;
   11.48 +
   11.49 +    len = strlen(ctx);
   11.50 +
   11.51 +    buf = malloc(len);
   11.52 +    if (!buf) {
   11.53 +        errno = -ENOMEM;
   11.54 +        PyErr_SetFromErrno(xc_error_obj);
   11.55 +    }
   11.56 +    
   11.57 +    memcpy(buf, ctx, len);
   11.58 +    
   11.59 +    xc_handle = xc_interface_open();
   11.60 +    if (xc_handle < 0) {
   11.61 +        errno = xc_handle;
   11.62 +        return PyErr_SetFromErrno(xc_error_obj);
   11.63 +    }
   11.64 +    
   11.65 +    ret = flask_context_to_sid(xc_handle, buf, len, &sid);
   11.66 +        
   11.67 +    xc_interface_close(xc_handle);
   11.68 +
   11.69 +    free(buf);
   11.70 +    
   11.71 +    if ( ret != 0 ) {
   11.72 +        errno = -ret;
   11.73 +        return PyErr_SetFromErrno(xc_error_obj);
   11.74 +    }
   11.75 +
   11.76 +    return PyInt_FromLong(sid);
   11.77 +}
   11.78 +
   11.79 +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args,
   11.80 +                                                                 PyObject *kwds)
   11.81 +{
   11.82 +    int xc_handle;
   11.83 +    uint32_t sid;
   11.84 +    char ctx[CTX_LEN];
   11.85 +    uint32_t ctx_len = CTX_LEN;
   11.86 +    int ret;
   11.87 +
   11.88 +    static char *kwd_list[] = { "sid", NULL };
   11.89 +
   11.90 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list,
   11.91 +                                      &sid) )
   11.92 +        return NULL;
   11.93 +
   11.94 +    xc_handle = xc_interface_open();
   11.95 +    if (xc_handle < 0) {
   11.96 +        errno = xc_handle;
   11.97 +        return PyErr_SetFromErrno(xc_error_obj);
   11.98 +    }
   11.99 +    
  11.100 +    ret = flask_sid_to_context(xc_handle, sid, ctx, ctx_len);
  11.101 +    
  11.102 +    xc_interface_close(xc_handle);
  11.103 +    
  11.104 +    if ( ret != 0 ) {
  11.105 +        errno = -ret;
  11.106 +        return PyErr_SetFromErrno(xc_error_obj);
  11.107 +    }
  11.108 +
  11.109 +    return Py_BuildValue("s", ctx, ctx_len);
  11.110 +}
  11.111 +
  11.112 +
  11.113 +static PyMethodDef pyflask_methods[] = {
  11.114 +    { "flask_context_to_sid",
  11.115 +      (PyCFunction)pyflask_context_to_sid,
  11.116 +      METH_KEYWORDS, "\n"
  11.117 +      "Convert a context string to a dynamic SID.\n"
  11.118 +      " context [str]: String specifying context to be converted\n"
  11.119 +      "Returns: [int]: Numeric SID on success; -1 on error.\n" },
  11.120 +
  11.121 +    { "flask_sid_to_context",
  11.122 +      (PyCFunction)pyflask_sid_to_context,
  11.123 +      METH_KEYWORDS, "\n"
  11.124 +      "Convert a dynamic SID to context string.\n"
  11.125 +      " context [int]: SID to be converted\n"
  11.126 +      "Returns: [str]: Numeric SID on success; -1 on error.\n" },
  11.127 +
  11.128 +    { NULL, NULL, 0, NULL }
  11.129 +};
  11.130 +
  11.131 +PyMODINIT_FUNC initflask(void)
  11.132 +{
  11.133 +    Py_InitModule("flask", pyflask_methods);
  11.134 +}
  11.135 +
  11.136 +
  11.137 +/*
  11.138 + * Local variables:
  11.139 + *  c-indent-level: 4
  11.140 + *  c-basic-offset: 4
  11.141 + * End:
  11.142 + */
    12.1 --- a/tools/python/xen/util/acmpolicy.py	Fri Aug 31 11:31:18 2007 +0100
    12.2 +++ b/tools/python/xen/util/acmpolicy.py	Fri Aug 31 11:37:20 2007 +0100
    12.3 @@ -1,4 +1,4 @@
    12.4 -#============================================================================
    12.5 + #============================================================================
    12.6  # This library is free software; you can redistribute it and/or
    12.7  # modify it under the terms of version 2.1 of the GNU Lesser General Public
    12.8  # License as published by the Free Software Foundation.
    12.9 @@ -23,10 +23,11 @@ import stat
   12.10  import array
   12.11  from xml.dom import minidom, Node
   12.12  from xen.xend.XendLogging import log
   12.13 -from xen.util import security, xsconstants, bootloader, mkdir
   12.14 +from xen.util import xsconstants, bootloader, mkdir
   12.15  from xen.util.xspolicy import XSPolicy
   12.16 -from xen.util.security import ACMError
   12.17  from xen.xend.XendError import SecurityError
   12.18 +import xen.util.xsm.acm.acm as security
   12.19 +from xen.util.xsm.xsm import XSMError
   12.20  
   12.21  ACM_POLICIES_DIR = security.policy_dir_prefix + "/"
   12.22  
   12.23 @@ -1240,8 +1241,8 @@ class ACMPolicy(XSPolicy):
   12.24  
   12.25          (major, minor) = self.getVersionTuple()
   12.26          hdr_bin = struct.pack(headerformat,
   12.27 +                              ACM_MAGIC,
   12.28                                ACM_POLICY_VERSION,
   12.29 -                              ACM_MAGIC,
   12.30                                totallen_bin,
   12.31                                polref_offset,
   12.32                                primpolcode,
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/python/xen/util/xsm/__init__.py	Fri Aug 31 11:37:20 2007 +0100
    13.3 @@ -0,0 +1,2 @@
    13.4 +
    13.5 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/python/xen/util/xsm/acm/__init__.py	Fri Aug 31 11:37:20 2007 +0100
    14.3 @@ -0,0 +1,1 @@
    14.4 + 
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/python/xen/util/xsm/acm/acm.py	Fri Aug 31 11:37:20 2007 +0100
    15.3 @@ -0,0 +1,1283 @@
    15.4 +#===========================================================================
    15.5 +# This library is free software; you can redistribute it and/or
    15.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    15.7 +# License as published by the Free Software Foundation.
    15.8 +#
    15.9 +# This library is distributed in the hope that it will be useful,
   15.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15.12 +# Lesser General Public License for more details.
   15.13 +#
   15.14 +# You should have received a copy of the GNU Lesser General Public
   15.15 +# License along with this library; if not, write to the Free Software
   15.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.17 +#============================================================================
   15.18 +# Copyright (C) 2006 International Business Machines Corp.
   15.19 +# Author: Reiner Sailer
   15.20 +# Author: Bryan D. Payne <bdpayne@us.ibm.com>
   15.21 +# Author: Stefan Berger <stefanb@us.ibm.com>
   15.22 +#============================================================================
   15.23 +
   15.24 +import commands
   15.25 +import logging
   15.26 +import os, string, re
   15.27 +import threading
   15.28 +import struct
   15.29 +import stat
   15.30 +from xen.lowlevel import acm
   15.31 +from xen.xend import sxp
   15.32 +from xen.xend import XendConstants
   15.33 +from xen.xend.XendLogging import log
   15.34 +from xen.xend.XendError import VmError
   15.35 +from xen.util import dictio, xsconstants
   15.36 +from xen.xend.XendConstants import *
   15.37 +
   15.38 +#global directories and tools for security management
   15.39 +policy_dir_prefix = "/etc/xen/acm-security/policies"
   15.40 +res_label_filename = policy_dir_prefix + "/resource_labels"
   15.41 +boot_filename = "/boot/grub/menu.lst"
   15.42 +altboot_filename = "/boot/grub/grub.conf"
   15.43 +xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
   15.44 +xensec_tool = "/usr/sbin/xensec_tool"
   15.45 +
   15.46 +#global patterns for map file
   15.47 +#police_reference_tagname = "POLICYREFERENCENAME"
   15.48 +primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
   15.49 +secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
   15.50 +label_template_re =  re.compile(".*security_label_template.xml", re.IGNORECASE)
   15.51 +mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
   15.52 +policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE)
   15.53 +vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
   15.54 +res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
   15.55 +all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
   15.56 +access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
   15.57 +
   15.58 +#global patterns for boot configuration file
   15.59 +xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
   15.60 +any_title_re = re.compile("\s*title\s", re.IGNORECASE)
   15.61 +xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
   15.62 +kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
   15.63 +any_module_re = re.compile("\s*module\s", re.IGNORECASE)
   15.64 +empty_line_re = re.compile("^\s*$")
   15.65 +binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
   15.66 +policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
   15.67 +
   15.68 +#decision hooks known to the hypervisor
   15.69 +ACMHOOK_sharing = 1
   15.70 +ACMHOOK_authorization = 2
   15.71 +
   15.72 +#other global variables
   15.73 +NULL_SSIDREF = 0
   15.74 +
   15.75 +#general Rlock for map files; only one lock for all mapfiles
   15.76 +__mapfile_lock = threading.RLock()
   15.77 +__resfile_lock = threading.RLock()
   15.78 +
   15.79 +log = logging.getLogger("xend.util.security")
   15.80 +
   15.81 +# Our own exception definition. It is masked (pass) if raised and
   15.82 +# whoever raises this exception must provide error information.
   15.83 +class ACMError(Exception):
   15.84 +    def __init__(self,value):
   15.85 +        self.value = value
   15.86 +    def __str__(self):
   15.87 +        return repr(self.value)
   15.88 +
   15.89 +
   15.90 +
   15.91 +def err(msg):
   15.92 +    """Raise ACM exception.
   15.93 +    """
   15.94 +    raise ACMError(msg)
   15.95 +
   15.96 +
   15.97 +
   15.98 +active_policy = None
   15.99 +
  15.100 +
  15.101 +def mapfile_lock():
  15.102 +    __mapfile_lock.acquire()
  15.103 +
  15.104 +def mapfile_unlock():
  15.105 +    __mapfile_lock.release()
  15.106 +
  15.107 +
  15.108 +def refresh_security_policy():
  15.109 +    """
  15.110 +    retrieves security policy
  15.111 +    """
  15.112 +    global active_policy
  15.113 +
  15.114 +    try:
  15.115 +        active_policy = acm.policy()
  15.116 +    except:
  15.117 +        active_policy = "INACTIVE"
  15.118 +
  15.119 +# now set active_policy
  15.120 +refresh_security_policy()
  15.121 +
  15.122 +def on():
  15.123 +    """
  15.124 +    returns none if security policy is off (not compiled),
  15.125 +    any string otherwise, use it: if not security.on() ...
  15.126 +    """
  15.127 +    refresh_security_policy()
  15.128 +    return (active_policy not in ['INACTIVE', 'NULL'])
  15.129 +
  15.130 +
  15.131 +def calc_dom_ssidref_from_info(info):
  15.132 +    """
  15.133 +       Calculate a domain's ssidref from the security_label in its
  15.134 +       info.
  15.135 +       This function is called before the domain is started and
  15.136 +       makes sure that:
  15.137 +        - the type of the policy is the same as indicated in the label
  15.138 +        - the name of the policy is the same as indicated in the label
  15.139 +        - calculates an up-to-date ssidref for the domain
  15.140 +       The latter is necessary since the domain's ssidref could have
  15.141 +       changed due to changes to the policy.
  15.142 +    """
  15.143 +    import xen.xend.XendConfig
  15.144 +    if isinstance(info, xen.xend.XendConfig.XendConfig):
  15.145 +        if info.has_key('security_label'):
  15.146 +            seclab = info['security_label']
  15.147 +            tmp = seclab.split(":")
  15.148 +            if len(tmp) != 3:
  15.149 +                raise VmError("VM label '%s' in wrong format." % seclab)
  15.150 +            typ, policyname, vmlabel = seclab.split(":")
  15.151 +            if typ != xsconstants.ACM_POLICY_ID:
  15.152 +                raise VmError("Policy type '%s' must be changed." % typ)
  15.153 +            refresh_security_policy()
  15.154 +            if active_policy != policyname:
  15.155 +                raise VmError("Active policy '%s' different than "
  15.156 +                              "what in VM's label ('%s')." %
  15.157 +                              (active_policy, policyname))
  15.158 +            ssidref = label2ssidref(vmlabel, policyname, "dom")
  15.159 +            return ssidref
  15.160 +        else:
  15.161 +            return 0x0
  15.162 +    raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'"
  15.163 +                  "not supported." % type(info))
  15.164 +
  15.165 +
  15.166 +def getmapfile(policyname):
  15.167 +    """
  15.168 +    in: if policyname is None then the currently
  15.169 +    active hypervisor policy is used
  15.170 +    out: 1. primary policy, 2. secondary policy,
  15.171 +    3. open file descriptor for mapping file, and
  15.172 +    4. True if policy file is available, False otherwise
  15.173 +    """
  15.174 +    if not policyname:
  15.175 +        policyname = active_policy
  15.176 +    map_file_ok = False
  15.177 +    primary = None
  15.178 +    secondary = None
  15.179 +    #strip last part of policy as file name part
  15.180 +    policy_dir_list = string.split(policyname, ".")
  15.181 +    policy_file = policy_dir_list.pop()
  15.182 +    if len(policy_dir_list) > 0:
  15.183 +        policy_dir = string.join(policy_dir_list, "/") + "/"
  15.184 +    else:
  15.185 +        policy_dir = ""
  15.186 +
  15.187 +    map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
  15.188 +    # check if it is there, if not check if policy file is there
  15.189 +    if not os.path.isfile(map_filename):
  15.190 +        policy_filename =  policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml"
  15.191 +        if not os.path.isfile(policy_filename):
  15.192 +            err("Policy file \'" + policy_filename + "\' not found.")
  15.193 +        else:
  15.194 +            err("Mapping file \'" + map_filename + "\' not found." +
  15.195 +                " Use xm makepolicy to create it.")
  15.196 +
  15.197 +    f = open(map_filename)
  15.198 +    for line in f:
  15.199 +        if policy_reference_entry_re.match(line):
  15.200 +            l = line.split()
  15.201 +            if (len(l) == 2) and (l[1] == policyname):
  15.202 +                map_file_ok = True
  15.203 +        elif primary_entry_re.match(line):
  15.204 +            l = line.split()
  15.205 +            if len(l) == 2:
  15.206 +                primary = l[1]
  15.207 +        elif secondary_entry_re.match(line):
  15.208 +            l = line.split()
  15.209 +            if len(l) == 2:
  15.210 +                secondary = l[1]
  15.211 +    f.close()
  15.212 +    f = open(map_filename)
  15.213 +    if map_file_ok and primary and secondary:
  15.214 +        return (primary, secondary, f, True)
  15.215 +    else:
  15.216 +        err("Mapping file inconsistencies found. Try makepolicy to create a new one.")
  15.217 +
  15.218 +
  15.219 +
  15.220 +def ssidref2label(ssidref_var):
  15.221 +    """
  15.222 +    returns labelname corresponding to ssidref;
  15.223 +    maps current policy to default directory
  15.224 +    to find mapping file
  15.225 +    """
  15.226 +    #1. translated permitted input formats
  15.227 +    if isinstance(ssidref_var, str):
  15.228 +        ssidref_var.strip()
  15.229 +        if ssidref_var[0:2] == "0x":
  15.230 +            ssidref = int(ssidref_var[2:], 16)
  15.231 +        else:
  15.232 +            ssidref = int(ssidref_var)
  15.233 +    elif isinstance(ssidref_var, int):
  15.234 +        ssidref = ssidref_var
  15.235 +    else:
  15.236 +        err("Instance type of ssidref not supported (must be of type 'str' or 'int')")
  15.237 +
  15.238 +    if ssidref == 0:
  15.239 +        from xen.util.acmpolicy import ACM_LABEL_UNLABELED
  15.240 +        return ACM_LABEL_UNLABELED
  15.241 +
  15.242 +    try:
  15.243 +        mapfile_lock()
  15.244 +
  15.245 +        (primary, secondary, f, pol_exists) = getmapfile(None)
  15.246 +        if not f:
  15.247 +            if (pol_exists):
  15.248 +                err("Mapping file for policy not found.\n" +
  15.249 +                    "Please use makepolicy command to create mapping file!")
  15.250 +            else:
  15.251 +                err("Policy file for \'" + active_policy + "\' not found.")
  15.252 +
  15.253 +        #2. get labelnames for both ssidref parts
  15.254 +        pri_ssid = ssidref & 0xffff
  15.255 +        sec_ssid = ssidref >> 16
  15.256 +        pri_null_ssid = NULL_SSIDREF & 0xffff
  15.257 +        sec_null_ssid = NULL_SSIDREF >> 16
  15.258 +        pri_labels = []
  15.259 +        sec_labels = []
  15.260 +        labels = []
  15.261 +
  15.262 +        for line in f:
  15.263 +            l = line.split()
  15.264 +            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  15.265 +                continue
  15.266 +            if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
  15.267 +                pri_labels.append(l[3])
  15.268 +            if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid):
  15.269 +                sec_labels.append(l[3])
  15.270 +        f.close()
  15.271 +    finally:
  15.272 +        mapfile_unlock()
  15.273 +
  15.274 +    #3. get the label that is in both lists (combination must be a single label)
  15.275 +    if (primary == "CHWALL") and (pri_ssid == pri_null_ssid) and (sec_ssid != sec_null_ssid):
  15.276 +        labels = sec_labels
  15.277 +    elif (secondary == "CHWALL") and (pri_ssid != pri_null_ssid) and (sec_ssid == sec_null_ssid):
  15.278 +        labels = pri_labels
  15.279 +    elif secondary == "NULL":
  15.280 +        labels = pri_labels
  15.281 +    else:
  15.282 +        for i in pri_labels:
  15.283 +            for j in sec_labels:
  15.284 +                if (i==j):
  15.285 +                    labels.append(i)
  15.286 +    if len(labels) != 1:
  15.287 +        err("Label for ssidref \'" +  str(ssidref) +
  15.288 +            "\' unknown or not unique in policy \'" + active_policy + "\'")
  15.289 +
  15.290 +    return labels[0]
  15.291 +
  15.292 +
  15.293 +
  15.294 +def label2ssidref(labelname, policyname, typ):
  15.295 +    """
  15.296 +    returns ssidref corresponding to labelname;
  15.297 +    maps current policy to default directory
  15.298 +    to find mapping file    """
  15.299 +
  15.300 +    if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
  15.301 +        err("Cannot translate labels for \'" + policyname + "\' policy.")
  15.302 +
  15.303 +    allowed_types = ['ANY']
  15.304 +    if typ == 'dom':
  15.305 +        allowed_types.append('VM')
  15.306 +    elif typ == 'res':
  15.307 +        allowed_types.append('RES')
  15.308 +    else:
  15.309 +        err("Invalid type.  Must specify 'dom' or 'res'.")
  15.310 +
  15.311 +    try:
  15.312 +        mapfile_lock()
  15.313 +        (primary, secondary, f, pol_exists) = getmapfile(policyname)
  15.314 +
  15.315 +        #2. get labelnames for ssidref parts and find a common label
  15.316 +        pri_ssid = []
  15.317 +        sec_ssid = []
  15.318 +        for line in f:
  15.319 +            l = line.split()
  15.320 +            if (len(l) < 5) or (l[0] != "LABEL->SSID"):
  15.321 +                continue
  15.322 +            if primary and (l[1] in allowed_types) and \
  15.323 +                           (l[2] == primary) and \
  15.324 +                           (l[3] == labelname):
  15.325 +                pri_ssid.append(int(l[4], 16))
  15.326 +            if secondary and (l[1] in allowed_types) and \
  15.327 +                             (l[2] == secondary) and \
  15.328 +                             (l[3] == labelname):
  15.329 +                sec_ssid.append(int(l[4], 16))
  15.330 +        f.close()
  15.331 +        if (typ == 'res') and (primary == "CHWALL") and (len(pri_ssid) == 0):
  15.332 +            pri_ssid.append(NULL_SSIDREF)
  15.333 +        elif (typ == 'res') and (secondary == "CHWALL") and \
  15.334 +             (len(sec_ssid) == 0):
  15.335 +            sec_ssid.append(NULL_SSIDREF)
  15.336 +
  15.337 +        #3. sanity check and composition of ssidref
  15.338 +        if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and \
  15.339 +            (secondary != "NULL")):
  15.340 +            err("Label \'" + labelname + "\' not found.")
  15.341 +        elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
  15.342 +            err("Label \'" + labelname + "\' not unique in policy (policy error)")
  15.343 +        if secondary == "NULL":
  15.344 +            return pri_ssid[0]
  15.345 +        else:
  15.346 +            return (sec_ssid[0] << 16) | pri_ssid[0]
  15.347 +    finally:
  15.348 +       mapfile_unlock()
  15.349 +
  15.350 +
  15.351 +def refresh_ssidref(config):
  15.352 +    """
  15.353 +    looks up ssidref from security field
  15.354 +    and refreshes the value if label exists
  15.355 +    """
  15.356 +    #called by dom0, policy could have changed after xen.utils.security was initialized
  15.357 +    refresh_security_policy()
  15.358 +
  15.359 +    security = None
  15.360 +    if isinstance(config, dict):
  15.361 +        security = config['security']
  15.362 +    elif isinstance(config, list):
  15.363 +        security = sxp.child_value(config, 'security')
  15.364 +    else:
  15.365 +        err("Instance type of config parameter not supported.")
  15.366 +    if not security:
  15.367 +        #nothing to do (no security label attached)
  15.368 +        return config
  15.369 +
  15.370 +    policyname = None
  15.371 +    labelname = None
  15.372 +    # compose new security field
  15.373 +    for idx in range(0, len(security)):
  15.374 +        if security[idx][0] == 'ssidref':
  15.375 +            security.pop(idx)
  15.376 +            break
  15.377 +        elif security[idx][0] == 'access_control':
  15.378 +            for jdx in [1, 2]:
  15.379 +                if security[idx][jdx][0] == 'label':
  15.380 +                    labelname = security[idx][jdx][1]
  15.381 +                elif security[idx][jdx][0] == 'policy':
  15.382 +                    policyname = security[idx][jdx][1]
  15.383 +                else:
  15.384 +                    err("Illegal field in access_control")
  15.385 +    #verify policy is correct
  15.386 +    if active_policy != policyname:
  15.387 +        err("Policy \'" + str(policyname) +
  15.388 +            "\' in label does not match active policy \'"
  15.389 +            + str(active_policy) +"\'!")
  15.390 +
  15.391 +    new_ssidref = label2ssidref(labelname, policyname, 'dom')
  15.392 +    if not new_ssidref:
  15.393 +        err("SSIDREF refresh failed!")
  15.394 +
  15.395 +    security.append([ 'ssidref',str(new_ssidref)])
  15.396 +    security = ['security', security ]
  15.397 +
  15.398 +    for idx in range(0,len(config)):
  15.399 +        if config[idx][0] == 'security':
  15.400 +            config.pop(idx)
  15.401 +            break
  15.402 +        config.append(security)
  15.403 +
  15.404 +
  15.405 +
  15.406 +def get_ssid(domain):
  15.407 +    """
  15.408 +    enables domains to retrieve the label / ssidref of a running domain
  15.409 +    """
  15.410 +    if not on():
  15.411 +        err("No policy active.")
  15.412 +
  15.413 +    if isinstance(domain, str):
  15.414 +        domain_int = int(domain)
  15.415 +    elif isinstance(domain, int):
  15.416 +        domain_int = domain
  15.417 +    else:
  15.418 +        err("Illegal parameter type.")
  15.419 +    try:
  15.420 +        ssid_info = acm.getssid(int(domain_int))
  15.421 +    except:
  15.422 +        err("Cannot determine security information.")
  15.423 +
  15.424 +    if active_policy in ["DEFAULT"]:
  15.425 +        label = "DEFAULT"
  15.426 +    else:
  15.427 +        label = ssidref2label(ssid_info["ssidref"])
  15.428 +    return(ssid_info["policyreference"],
  15.429 +           label,
  15.430 +           ssid_info["policytype"],
  15.431 +           ssid_info["ssidref"])
  15.432 +
  15.433 +
  15.434 +
  15.435 +def get_decision(arg1, arg2):
  15.436 +    """
  15.437 +    enables domains to retrieve access control decisions from
  15.438 +    the hypervisor Access Control Module.
  15.439 +    IN: args format = ['domid', id] or ['ssidref', ssidref]
  15.440 +    or ['access_control', ['policy', policy], ['label', label], ['type', type]]
  15.441 +    """
  15.442 +
  15.443 +    if not on():
  15.444 +        err("No policy active.")
  15.445 +
  15.446 +    #translate labels before calling low-level function
  15.447 +    if arg1[0] == 'access_control':
  15.448 +        if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') or (arg1[3][0] != 'type'):
  15.449 +            err("Argument type not supported.")
  15.450 +        ssidref = label2ssidref(arg1[2][1], arg1[1][1], arg1[3][1])
  15.451 +        arg1 = ['ssidref', str(ssidref)]
  15.452 +    if arg2[0] == 'access_control':
  15.453 +        if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') or (arg2[3][0] != 'type'):
  15.454 +            err("Argument type not supported.")
  15.455 +        ssidref = label2ssidref(arg2[2][1], arg2[1][1], arg2[3][1])
  15.456 +        arg2 = ['ssidref', str(ssidref)]
  15.457 +
  15.458 +    # accept only int or string types for domid and ssidref
  15.459 +    if isinstance(arg1[1], int):
  15.460 +        arg1[1] = str(arg1[1])
  15.461 +    if isinstance(arg2[1], int):
  15.462 +        arg2[1] = str(arg2[1])
  15.463 +    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
  15.464 +        err("Invalid id or ssidref type, string or int required")
  15.465 +
  15.466 +    try:
  15.467 +        decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1],
  15.468 +                                   ACMHOOK_sharing)
  15.469 +    except:
  15.470 +        err("Cannot determine decision.")
  15.471 +
  15.472 +    if decision:
  15.473 +        return decision
  15.474 +    else:
  15.475 +        err("Cannot determine decision (Invalid parameter).")
  15.476 +
  15.477 +
  15.478 +def has_authorization(ssidref):
  15.479 +    """ Check if the domain with the given ssidref has authorization to
  15.480 +        run on this system. To have authoriztion dom0's STE types must
  15.481 +        be a superset of that of the domain's given through its ssidref.
  15.482 +    """
  15.483 +    rc = True
  15.484 +    dom0_ssidref = int(acm.getssid(0)['ssidref'])
  15.485 +    decision = acm.getdecision('ssidref', str(dom0_ssidref),
  15.486 +                               'ssidref', str(ssidref),
  15.487 +                               ACMHOOK_authorization)
  15.488 +    if decision == "DENIED":
  15.489 +        rc = False
  15.490 +    return rc
  15.491 +
  15.492 +
  15.493 +def hv_chg_policy(bin_pol, del_array, chg_array):
  15.494 +    """
  15.495 +        Change the binary policy in the hypervisor
  15.496 +        The 'del_array' and 'chg_array' give hints about deleted ssidrefs
  15.497 +        and changed ssidrefs which can be due to deleted VM labels
  15.498 +        or reordered VM labels
  15.499 +    """
  15.500 +    rc = -xsconstants.XSERR_GENERAL_FAILURE
  15.501 +    errors = ""
  15.502 +    if not on():
  15.503 +        err("No policy active.")
  15.504 +    try:
  15.505 +        rc, errors = acm.chgpolicy(bin_pol, del_array, chg_array)
  15.506 +    except Exception, e:
  15.507 +        pass
  15.508 +    if len(errors) > 0:
  15.509 +        rc = -xsconstants.XSERR_HV_OP_FAILED
  15.510 +    return rc, errors
  15.511 +
  15.512 +
  15.513 +def make_policy(policy_name):
  15.514 +    policy_file = string.join(string.split(policy_name, "."), "/")
  15.515 +    if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"):
  15.516 +        err("Unknown policy \'" + policy_name + "\'")
  15.517 +
  15.518 +    (ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file)
  15.519 +    if ret:
  15.520 +        err("Creating policy failed:\n" + output)
  15.521 +
  15.522 +def load_policy(policy_name):
  15.523 +    global active_policy
  15.524 +    policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/")
  15.525 +    if not os.path.isfile(policy_file + ".bin"):
  15.526 +        if os.path.isfile(policy_file + "-security_policy.xml"):
  15.527 +            err("Binary file does not exist." +
  15.528 +                "Please use makepolicy to build the policy binary.")
  15.529 +        else:
  15.530 +            err("Unknown Policy " + policy_name)
  15.531 +
  15.532 +    #require this policy to be the first or the same as installed
  15.533 +    if active_policy not in ['DEFAULT', policy_name]:
  15.534 +        err("Active policy \'" + active_policy +
  15.535 +            "\' incompatible with new policy \'" + policy_name + "\'")
  15.536 +    (ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin")
  15.537 +    if ret:
  15.538 +        err("Loading policy failed:\n" + output)
  15.539 +    else:
  15.540 +        # refresh active policy
  15.541 +        refresh_security_policy()
  15.542 +
  15.543 +
  15.544 +
  15.545 +def dump_policy():
  15.546 +    if active_policy in ['NULL', 'INACTIVE']:
  15.547 +        err("\'" + active_policy + "\' policy. Nothing to dump.")
  15.548 +
  15.549 +    (ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
  15.550 +    if ret:
  15.551 +       err("Dumping hypervisor policy failed:\n" + output)
  15.552 +    print output
  15.553 +
  15.554 +
  15.555 +
  15.556 +def list_labels(policy_name, condition):
  15.557 +    if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]:
  15.558 +        err("Current policy \'" + active_policy + "\' has no labels defined.\n")
  15.559 +
  15.560 +    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
  15.561 +    if not f:
  15.562 +        if pol_exists:
  15.563 +            err("Cannot find mapfile for policy \'" + policy_name +
  15.564 +                "\'.\nPlease use makepolicy to create mapping file.")
  15.565 +        else:
  15.566 +            err("Unknown policy \'" + policy_name + "\'")
  15.567 +
  15.568 +    labels = []
  15.569 +    for line in f:
  15.570 +        if condition.match(line):
  15.571 +            label = line.split()[3]
  15.572 +            if label not in labels:
  15.573 +                labels.append(label)
  15.574 +    return labels
  15.575 +
  15.576 +
  15.577 +def get_res_label(resource):
  15.578 +    """Returns resource label information (policytype, label, policy) if
  15.579 +       it exists. Otherwise returns null label and policy.
  15.580 +    """
  15.581 +    def default_res_label():
  15.582 +        ssidref = NULL_SSIDREF
  15.583 +        if on():
  15.584 +            label = ssidref2label(ssidref)
  15.585 +        else:
  15.586 +            label = None
  15.587 +        return (xsconstants.ACM_POLICY_ID, 'NULL', label)
  15.588 +
  15.589 +
  15.590 +    tmp = get_resource_label(resource)
  15.591 +    if len(tmp) == 2:
  15.592 +        policytype = xsconstants.ACM_POLICY_ID
  15.593 +        policy, label = tmp
  15.594 +    elif len(tmp) == 3:
  15.595 +        policytype, policy, label = tmp
  15.596 +    else:
  15.597 +        policytype, policy, label = default_res_label()
  15.598 +
  15.599 +    return (policytype, label, policy)
  15.600 +
  15.601 +
  15.602 +def get_res_security_details(resource):
  15.603 +    """Returns the (label, ssidref, policy) associated with a given
  15.604 +       resource from the global resource label file.
  15.605 +    """
  15.606 +    def default_security_details():
  15.607 +        ssidref = NULL_SSIDREF
  15.608 +        if on():
  15.609 +            label = ssidref2label(ssidref)
  15.610 +        else:
  15.611 +            label = None
  15.612 +        policy = active_policy
  15.613 +        return (label, ssidref, policy)
  15.614 +
  15.615 +    (label, ssidref, policy) = default_security_details()
  15.616 +
  15.617 +    # find the entry associated with this resource
  15.618 +    (policytype, label, policy) = get_res_label(resource)
  15.619 +    if policy == 'NULL':
  15.620 +        log.info("Resource label for "+resource+" not in file, using DEFAULT.")
  15.621 +        return default_security_details()
  15.622 +
  15.623 +    # is this resource label for the running policy?
  15.624 +    if policy == active_policy:
  15.625 +        ssidref = label2ssidref(label, policy, 'res')
  15.626 +    else:
  15.627 +        log.info("Resource label not for active policy, using DEFAULT.")
  15.628 +        return default_security_details()
  15.629 +
  15.630 +    return (label, ssidref, policy)
  15.631 +
  15.632 +def security_label_to_details(seclab):
  15.633 +    """ Convert a Xen-API type of security label into details """
  15.634 +    def default_security_details():
  15.635 +        ssidref = NULL_SSIDREF
  15.636 +        if on():
  15.637 +            label = ssidref2label(ssidref)
  15.638 +        else:
  15.639 +            label = None
  15.640 +        policy = active_policy
  15.641 +        return (label, ssidref, policy)
  15.642 +
  15.643 +    (policytype, policy, label) = seclab.split(":")
  15.644 +
  15.645 +    # is this resource label for the running policy?
  15.646 +    if policy == active_policy:
  15.647 +        ssidref = label2ssidref(label, policy, 'res')
  15.648 +    else:
  15.649 +        log.info("Resource label not for active policy, using DEFAULT.")
  15.650 +        return default_security_details()
  15.651 +
  15.652 +    return (label, ssidref, policy)
  15.653 +
  15.654 +def unify_resname(resource, mustexist=True):
  15.655 +    """Makes all resource locations absolute. In case of physical
  15.656 +    resources, '/dev/' is added to local file names"""
  15.657 +
  15.658 +    if not resource:
  15.659 +        return resource
  15.660 +
  15.661 +    # sanity check on resource name
  15.662 +    try:
  15.663 +        (typ, resfile) = resource.split(":", 1)
  15.664 +    except:
  15.665 +        err("Resource spec '%s' contains no ':' delimiter" % resource)
  15.666 +
  15.667 +    if typ == "tap":
  15.668 +        try:
  15.669 +            (subtype, resfile) = resfile.split(":")
  15.670 +        except:
  15.671 +            err("Resource spec '%s' contains no tap subtype" % resource)
  15.672 +
  15.673 +    import os
  15.674 +    if typ in ["phy", "tap"]:
  15.675 +        if not resfile.startswith("/"):
  15.676 +            resfile = "/dev/" + resfile
  15.677 +        if mustexist:
  15.678 +            stats = os.lstat(resfile)
  15.679 +            if stat.S_ISLNK(stats[stat.ST_MODE]):
  15.680 +                resolved = os.readlink(resfile)
  15.681 +                if resolved[0] != "/":
  15.682 +                    resfile = os.path.join(os.path.dirname(resfile), resolved)
  15.683 +                    resfile = os.path.abspath(resfile)
  15.684 +                else:
  15.685 +                    resfile = resolved
  15.686 +                stats = os.lstat(resfile)
  15.687 +            if not (stat.S_ISBLK(stats[stat.ST_MODE])):
  15.688 +                err("Invalid resource")
  15.689 +
  15.690 +    if typ in [ "file", "tap" ]:
  15.691 +        if mustexist:
  15.692 +            stats = os.lstat(resfile)
  15.693 +            if stat.S_ISLNK(stats[stat.ST_MODE]):
  15.694 +                resfile = os.readlink(resfile)
  15.695 +                stats = os.lstat(resfile)
  15.696 +            if not stat.S_ISREG(stats[stat.ST_MODE]):
  15.697 +                err("Invalid resource")
  15.698 +
  15.699 +    #file: resources must specified with absolute path
  15.700 +    #vlan resources don't start with '/'
  15.701 +    if typ != "vlan":
  15.702 +        if (not resfile.startswith("/")) or \
  15.703 +           (mustexist and not os.path.exists(resfile)):
  15.704 +            err("Invalid resource.")
  15.705 +
  15.706 +    # from here on absolute file names with resources
  15.707 +    if typ == "tap":
  15.708 +        typ = typ + ":" + subtype
  15.709 +    resource = typ + ":" + resfile
  15.710 +    return resource
  15.711 +
  15.712 +
  15.713 +def res_security_check(resource, domain_label):
  15.714 +    """Checks if the given resource can be used by the given domain
  15.715 +       label.  Returns 1 if the resource can be used, otherwise 0.
  15.716 +    """
  15.717 +    rtnval = 1
  15.718 +
  15.719 +    # if security is on, ask the hypervisor for a decision
  15.720 +    if on():
  15.721 +        #build canonical resource name
  15.722 +        resource = unify_resname(resource)
  15.723 +
  15.724 +        (label, ssidref, policy) = get_res_security_details(resource)
  15.725 +        domac = ['access_control']
  15.726 +        domac.append(['policy', active_policy])
  15.727 +        domac.append(['label', domain_label])
  15.728 +        domac.append(['type', 'dom'])
  15.729 +        decision = get_decision(domac, ['ssidref', str(ssidref)])
  15.730 +
  15.731 +        # provide descriptive error messages
  15.732 +        if decision == 'DENIED':
  15.733 +            if label == ssidref2label(NULL_SSIDREF):
  15.734 +                raise ACMError("Resource '"+resource+"' is not labeled")
  15.735 +                rtnval = 0
  15.736 +            else:
  15.737 +                raise ACMError("Permission denied for resource '"+resource+"' because label '"+label+"' is not allowed")
  15.738 +                rtnval = 0
  15.739 +
  15.740 +    # security is off, make sure resource isn't labeled
  15.741 +    else:
  15.742 +        # Note, we can't canonicalise the resource here, because people using
  15.743 +        # xm without ACM are free to use relative paths.
  15.744 +        (policytype, label, policy) = get_res_label(resource)
  15.745 +        if policy != 'NULL':
  15.746 +            raise ACMError("Security is off, but '"+resource+"' is labeled")
  15.747 +            rtnval = 0
  15.748 +
  15.749 +    return rtnval
  15.750 +
  15.751 +def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
  15.752 +    """Checks if the given resource can be used by the given domain
  15.753 +       label.  Returns 1 if the resource can be used, otherwise 0.
  15.754 +    """
  15.755 +    rtnval = 1
  15.756 +    # if security is on, ask the hypervisor for a decision
  15.757 +    if on():
  15.758 +        typ, dpolicy, domain_label = xapi_dom_label.split(":")
  15.759 +        if not dpolicy or not domain_label:
  15.760 +            raise VmError("VM security label in wrong format.")
  15.761 +        if active_policy != rpolicy:
  15.762 +            raise VmError("Resource's policy '%s' != active policy '%s'" %
  15.763 +                          (rpolicy, active_policy))
  15.764 +        domac = ['access_control']
  15.765 +        domac.append(['policy', active_policy])
  15.766 +        domac.append(['label', domain_label])
  15.767 +        domac.append(['type', 'dom'])
  15.768 +        decision = get_decision(domac, ['ssidref', str(rssidref)])
  15.769 +
  15.770 +        log.info("Access Control Decision : %s" % decision)
  15.771 +        # provide descriptive error messages
  15.772 +        if decision == 'DENIED':
  15.773 +            if rlabel == ssidref2label(NULL_SSIDREF):
  15.774 +                #raise ACMError("Resource is not labeled")
  15.775 +                rtnval = 0
  15.776 +            else:
  15.777 +                #raise ACMError("Permission denied for resource because label '"+rlabel+"' is not allowed")
  15.778 +                rtnval = 0
  15.779 +
  15.780 +    # security is off, make sure resource isn't labeled
  15.781 +    else:
  15.782 +        # Note, we can't canonicalise the resource here, because people using
  15.783 +        # xm without ACM are free to use relative paths.
  15.784 +        if rpolicy != 'NULL':
  15.785 +            #raise ACMError("Security is off, but resource is labeled")
  15.786 +            rtnval = 0
  15.787 +
  15.788 +    return rtnval
  15.789 +
  15.790 +
  15.791 +def validate_label(label, policyref):
  15.792 +    """
  15.793 +       Make sure that this label is part of the currently enforced policy
  15.794 +       and that it reference the current policy.
  15.795 +    """
  15.796 +    rc = xsconstants.XSERR_SUCCESS
  15.797 +    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  15.798 +    curpol = XSPolicyAdminInstance().get_loaded_policy()
  15.799 +    if not curpol or curpol.get_name() != policyref:
  15.800 +        rc = -xsconstants.XSERR_BAD_LABEL
  15.801 +    else:
  15.802 +        try:
  15.803 +            label2ssidref(label, curpol.get_name() , 'res')
  15.804 +        except:
  15.805 +            rc = -xsconstants.XSERR_BAD_LABEL
  15.806 +    return rc
  15.807 +
  15.808 +
  15.809 +def set_resource_label_xapi(resource, reslabel_xapi, oldlabel_xapi):
  15.810 +    """Assign a resource label to a resource
  15.811 +    @param resource: The name of a resource, i.e., "phy:/dev/hda", or
  15.812 +              "tap:qcow:/path/to/file.qcow"
  15.813 +
  15.814 +    @param reslabel_xapi: A resource label foramtted as in all other parts of
  15.815 +                          the Xen-API, i.e., ACM:xm-test:blue"
  15.816 +    @rtype: int
  15.817 +    @return Success (0) or failure value (< 0)
  15.818 +    """
  15.819 +    olabel = ""
  15.820 +    if reslabel_xapi == "":
  15.821 +        return rm_resource_label(resource, oldlabel_xapi)
  15.822 +    typ, policyref, label = reslabel_xapi.split(":")
  15.823 +    if typ != xsconstants.ACM_POLICY_ID:
  15.824 +        return -xsconstants.XSERR_WRONG_POLICY_TYPE
  15.825 +    if not policyref or not label:
  15.826 +        return -xsconstants.XSERR_BAD_LABEL_FORMAT
  15.827 +    if oldlabel_xapi not in [ "" ]:
  15.828 +        tmp = oldlabel_xapi.split(":")
  15.829 +        if len(tmp) != 3:
  15.830 +            return -xsconstants.XSERR_BAD_LABEL_FORMAT
  15.831 +        otyp, opolicyref, olabel = tmp
  15.832 +        # Only ACM is supported
  15.833 +        if otyp != xsconstants.ACM_POLICY_ID  and \
  15.834 +           otyp != xsconstants.INVALID_POLICY_PREFIX + \
  15.835 +                   xsconstants.ACM_POLICY_ID:
  15.836 +            return -xsconstants.XSERR_WRONG_POLICY_TYPE
  15.837 +    rc = validate_label(label, policyref)
  15.838 +    if rc != xsconstants.XSERR_SUCCESS:
  15.839 +        return rc
  15.840 +    return set_resource_label(resource, typ, policyref, label, olabel)
  15.841 +
  15.842 +
  15.843 +def is_resource_in_use(resource):
  15.844 +    """ Investigate all running domains whether they use this device """
  15.845 +    from xen.xend import XendDomain
  15.846 +    dominfos = XendDomain.instance().list('all')
  15.847 +    lst = []
  15.848 +    for dominfo in dominfos:
  15.849 +        if is_resource_in_use_by_dom(dominfo, resource):
  15.850 +            lst.append(dominfo)
  15.851 +    return lst
  15.852 +
  15.853 +def devices_equal(res1, res2, mustexist=True):
  15.854 +    """ Determine whether two devices are equal """
  15.855 +    return (unify_resname(res1, mustexist) ==
  15.856 +            unify_resname(res2, mustexist))
  15.857 +
  15.858 +def is_resource_in_use_by_dom(dominfo, resource):
  15.859 +    """ Determine whether a resources is in use by a given domain
  15.860 +        @return True or False
  15.861 +    """
  15.862 +    if not dominfo.domid:
  15.863 +        return False
  15.864 +    if dominfo._stateGet() not in [ DOM_STATE_RUNNING ]:
  15.865 +        return False
  15.866 +    devs = dominfo.info['devices']
  15.867 +    uuids = devs.keys()
  15.868 +    for uuid in uuids:
  15.869 +        dev = devs[uuid]
  15.870 +        if len(dev) >= 2 and dev[1].has_key('uname'):
  15.871 +            # dev[0] is type, i.e. 'vbd'
  15.872 +            if devices_equal(dev[1]['uname'], resource, mustexist=False):
  15.873 +                log.info("RESOURCE IN USE: Domain %d uses %s." %
  15.874 +                         (dominfo.domid, resource))
  15.875 +                return True
  15.876 +    return False
  15.877 +
  15.878 +
  15.879 +def get_domain_resources(dominfo):
  15.880 +    """ Collect all resources of a domain in a map where each entry of
  15.881 +        the map is a list.
  15.882 +        Entries are strored in the following formats:
  15.883 +          tap:qcow:/path/xyz.qcow
  15.884 +    """
  15.885 +    resources = { 'vbd' : [], 'tap' : [], 'vif' : []}
  15.886 +    devs = dominfo.info['devices']
  15.887 +    uuids = devs.keys()
  15.888 +    for uuid in uuids:
  15.889 +        dev = devs[uuid]
  15.890 +        typ = dev[0]
  15.891 +        if typ in [ 'vbd', 'tap' ]:
  15.892 +            resources[typ].append(dev[1]['uname'])
  15.893 +        if typ in [ 'vif' ]:
  15.894 +            sec_lab = dev[1].get('security_label')
  15.895 +            if sec_lab:
  15.896 +                resources[typ].append(sec_lab)
  15.897 +            else:
  15.898 +                resources[typ].append("%s:%s:%s" %
  15.899 +                                      (xsconstants.ACM_POLICY_ID,
  15.900 +                                       active_policy,
  15.901 +                                       ACM_LABEL_UNLABELED))
  15.902 +
  15.903 +    return resources
  15.904 +
  15.905 +
  15.906 +def resources_compatible_with_vmlabel(xspol, dominfo, vmlabel):
  15.907 +    """
  15.908 +       Check whether the resources' labels are compatible with the
  15.909 +       given VM label. This is a function to be used when for example
  15.910 +       a running domain is to get the new label 'vmlabel'
  15.911 +    """
  15.912 +    if not xspol:
  15.913 +        return False
  15.914 +
  15.915 +    try:
  15.916 +        __resfile_lock.acquire()
  15.917 +        try:
  15.918 +            access_control = dictio.dict_read("resources",
  15.919 +                                              res_label_filename)
  15.920 +        except:
  15.921 +            return False
  15.922 +        return __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  15.923 +                                                   access_control)
  15.924 +    finally:
  15.925 +        __resfile_lock.release()
  15.926 +    return False
  15.927 +
  15.928 +
  15.929 +def __resources_compatible_with_vmlabel(xspol, dominfo, vmlabel,
  15.930 +                                        access_control):
  15.931 +    """
  15.932 +        Check whether the resources' labels are compatible with the
  15.933 +        given VM label. The access_control parameter provides a
  15.934 +        dictionary of the resource name to resource label mappings
  15.935 +        under which the evaluation should be done.
  15.936 +    """
  15.937 +    def collect_labels(reslabels, s_label, polname):
  15.938 +        if len(s_label) != 3 or polname != s_label[1]:
  15.939 +            return False
  15.940 +        label = s_label[2]
  15.941 +        if not label in reslabels:
  15.942 +            reslabels.append(label)
  15.943 +        return True
  15.944 +
  15.945 +    resources = get_domain_resources(dominfo)
  15.946 +    reslabels = []  # all resource labels
  15.947 +
  15.948 +    polname = xspol.get_name()
  15.949 +    for key, value in resources.items():
  15.950 +        if key in [ 'vbd', 'tap' ]:
  15.951 +            for res in resources[key]:
  15.952 +                try:
  15.953 +                    label = access_control[res]
  15.954 +                    if not collect_labels(reslabels, label, polname):
  15.955 +                        return False
  15.956 +                except:
  15.957 +                    return False
  15.958 +        elif key in [ 'vif' ]:
  15.959 +            for xapi_label in value:
  15.960 +                label = xapi_label.split(":")
  15.961 +                if not collect_labels(reslabels, label, polname):
  15.962 +                    return False
  15.963 +        else:
  15.964 +            log.error("Unhandled device type: %s" % key)
  15.965 +            return False
  15.966 +
  15.967 +    # Check that all resource labes have a common STE type with the
  15.968 +    # vmlabel
  15.969 +    rc = xspol.policy_check_vmlabel_against_reslabels(vmlabel, reslabels)
  15.970 +    return rc;
  15.971 +
  15.972 +def set_resource_label(resource, policytype, policyref, reslabel, \
  15.973 +                       oreslabel = None):
  15.974 +    """Assign a label to a resource
  15.975 +       If the old label (oreslabel) is given, then the resource must have
  15.976 +       that old label.
  15.977 +       A resource label may be changed if
  15.978 +       - the resource is not in use
  15.979 +    @param resource  : The name of a resource, i.e., "phy:/dev/hda"
  15.980 +    @param policyref : The name of the policy
  15.981 +    @param reslabel     : the resource label within the policy
  15.982 +    @param oreslabel    : optional current resource label
  15.983 +
  15.984 +    @rtype: int
  15.985 +    @return Success (0) or failure value (< 0)
  15.986 +    """
  15.987 +    try:
  15.988 +        resource = unify_resname(resource, mustexist=False)
  15.989 +    except Exception:
  15.990 +        return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
  15.991 +
  15.992 +    domains = is_resource_in_use(resource)
  15.993 +    if len(domains) > 0:
  15.994 +        return -xsconstants.XSERR_RESOURCE_IN_USE
  15.995 +
  15.996 +    try:
  15.997 +        __resfile_lock.acquire()
  15.998 +        access_control = {}
  15.999 +        try:
 15.1000 +             access_control = dictio.dict_read("resources", res_label_filename)
 15.1001 +        except:
 15.1002 +            pass
 15.1003 +        if oreslabel:
 15.1004 +            if not access_control.has_key(resource):
 15.1005 +                return -xsconstants.XSERR_BAD_LABEL
 15.1006 +            tmp = access_control[resource]
 15.1007 +            if len(tmp) != 3:
 15.1008 +                return -xsconstants.XSERR_BAD_LABEL
 15.1009 +            if tmp[2] != oreslabel:
 15.1010 +                return -xsconstants.XSERR_BAD_LABEL
 15.1011 +        if reslabel != "":
 15.1012 +            new_entry = { resource : tuple([policytype, policyref, reslabel])}
 15.1013 +            access_control.update(new_entry)
 15.1014 +        else:
 15.1015 +            if access_control.has_key(resource):
 15.1016 +                del access_control[resource]
 15.1017 +        dictio.dict_write(access_control, "resources", res_label_filename)
 15.1018 +    finally:
 15.1019 +        __resfile_lock.release()
 15.1020 +    return xsconstants.XSERR_SUCCESS
 15.1021 +
 15.1022 +def rm_resource_label(resource, oldlabel_xapi):
 15.1023 +    """Remove a resource label from a physical resource
 15.1024 +    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 15.1025 +
 15.1026 +    @rtype: int
 15.1027 +    @return Success (0) or failure value (< 0)
 15.1028 +    """
 15.1029 +    tmp = oldlabel_xapi.split(":")
 15.1030 +    if len(tmp) != 3:
 15.1031 +        return -xsconstants.XSERR_BAD_LABEL_FORMAT
 15.1032 +    otyp, opolicyref, olabel = tmp
 15.1033 +    # Only ACM is supported
 15.1034 +    if otyp != xsconstants.ACM_POLICY_ID and \
 15.1035 +       otyp != xsconstants.INVALID_POLICY_PREFIX + xsconstants.ACM_POLICY_ID:
 15.1036 +        return -xsconstants.XSERR_WRONG_POLICY_TYPE
 15.1037 +    return set_resource_label(resource, "", "", "", olabel)
 15.1038 +
 15.1039 +def get_resource_label_xapi(resource):
 15.1040 +    """Get the assigned resource label of a physical resource
 15.1041 +      in the format used by then Xen-API, i.e., "ACM:xm-test:blue"
 15.1042 +
 15.1043 +      @rtype: string
 15.1044 +      @return the string representing policy type, policy name and label of
 15.1045 +              the resource
 15.1046 +    """
 15.1047 +    res = get_resource_label(resource)
 15.1048 +    return format_resource_label(res)
 15.1049 +
 15.1050 +def format_resource_label(res):
 15.1051 +    if res:
 15.1052 +        if len(res) == 2:
 15.1053 +            return xsconstants.ACM_POLICY_ID + ":" + res[0] + ":" + res[1]
 15.1054 +        if len(res) == 3:
 15.1055 +            return ":".join(res)
 15.1056 +    return ""
 15.1057 +
 15.1058 +def get_resource_label(resource):
 15.1059 +    """Get the assigned resource label of a given resource
 15.1060 +    @param resource: The name of a resource, i.e., "phy:/dev/hda"
 15.1061 +
 15.1062 +    @rtype: list
 15.1063 +    @return tuple of (policy name, resource label), i.e., (xm-test, blue)
 15.1064 +    """
 15.1065 +    try:
 15.1066 +        resource = unify_resname(resource, mustexist=False)
 15.1067 +    except Exception:
 15.1068 +        return []
 15.1069 +
 15.1070 +    reslabel_map = get_labeled_resources()
 15.1071 +
 15.1072 +    if reslabel_map.has_key(resource):
 15.1073 +        return list(reslabel_map[resource])
 15.1074 +    else:
 15.1075 +        #Try to resolve each label entry
 15.1076 +        for key, value in reslabel_map.items():
 15.1077 +            try:
 15.1078 +                if resource == unify_resname(key):
 15.1079 +                    return list(value)
 15.1080 +            except:
 15.1081 +                pass
 15.1082 +
 15.1083 +    return []
 15.1084 +
 15.1085 +
 15.1086 +def get_labeled_resources_xapi():
 15.1087 +    """ Get a map of all labeled resource with the labels formatted in the
 15.1088 +        xen-api resource label format.
 15.1089 +    """
 15.1090 +    reslabel_map = get_labeled_resources()
 15.1091 +    for key, labeldata in reslabel_map.items():
 15.1092 +        reslabel_map[key] = format_resource_label(labeldata)
 15.1093 +    return reslabel_map
 15.1094 +
 15.1095 +
 15.1096 +def get_labeled_resources():
 15.1097 +    """Get a map of all labeled resources
 15.1098 +    @rtype: list
 15.1099 +    @return list of labeled resources
 15.1100 +    """
 15.1101 +    try:
 15.1102 +        __resfile_lock.acquire()
 15.1103 +        try:
 15.1104 +            access_control = dictio.dict_read("resources", res_label_filename)
 15.1105 +        except:
 15.1106 +            return {}
 15.1107 +    finally:
 15.1108 +        __resfile_lock.release()
 15.1109 +    return access_control
 15.1110 +
 15.1111 +
 15.1112 +def relabel_domains(relabel_list):
 15.1113 +    """
 15.1114 +      Relabel the given domains to have a new ssidref.
 15.1115 +      @param relabel_list: a list containing tuples of domid, ssidref
 15.1116 +                           example: [ [0, 0x00020002] ]
 15.1117 +    """
 15.1118 +    rel_rules = ""
 15.1119 +    for r in relabel_list:
 15.1120 +        log.info("Relabeling domain with domid %d to new ssidref 0x%08x",
 15.1121 +                r[0], r[1])
 15.1122 +        rel_rules += struct.pack("ii", r[0], r[1])
 15.1123 +    try:
 15.1124 +        rc, errors = acm.relabel_domains(rel_rules)
 15.1125 +    except Exception, e:
 15.1126 +        log.info("Error after relabel_domains: %s" % str(e))
 15.1127 +        rc = -xsconstants.XSERR_GENERAL_FAILURE
 15.1128 +        errors = ""
 15.1129 +    if (len(errors) > 0):
 15.1130 +        rc = -xsconstants.XSERR_HV_OP_FAILED
 15.1131 +    return rc, errors
 15.1132 +
 15.1133 +
 15.1134 +def change_acm_policy(bin_pol, del_array, chg_array,
 15.1135 +                      vmlabel_map, reslabel_map, cur_acmpol, new_acmpol):
 15.1136 +    """
 15.1137 +       Change the ACM policy of the system by relabeling
 15.1138 +       domains and resources first and doing some access checks.
 15.1139 +       Then update the policy in the hypervisor. If this is all successful,
 15.1140 +       relabel the domains permanently and commit the relabed resources.
 15.1141 +
 15.1142 +       Need to do / check the following:
 15.1143 +        - relabel all resources where there is a 'from' field in
 15.1144 +          the policy. [ NOT DOING THIS: and mark those as unlabeled where the label
 15.1145 +          does not appear in the new policy anymore (deletion) ]
 15.1146 +        - relabel all VMs where there is a 'from' field in the
 15.1147 +          policy and mark those as unlabeled where the label
 15.1148 +          does not appear in the new policy anymore; no running
 15.1149 +          or paused VM may be unlabeled through this
 15.1150 +        - check that under the new labeling conditions the VMs
 15.1151 +          still have access to their resources as before. Unlabeled
 15.1152 +          resources are inaccessible. If this check fails, the
 15.1153 +          update failed.
 15.1154 +        - Attempt changes in the hypervisor; if this step fails,
 15.1155 +          roll back the relabeling of resources and VMs
 15.1156 +        - Make the relabeling of resources and VMs permanent
 15.1157 +    """
 15.1158 +    rc = xsconstants.XSERR_SUCCESS
 15.1159 +
 15.1160 +    domain_label_map = {}
 15.1161 +    new_policyname = new_acmpol.get_name()
 15.1162 +    new_policytype = new_acmpol.get_type_name()
 15.1163 +    cur_policyname = cur_acmpol.get_name()
 15.1164 +    cur_policytype = cur_acmpol.get_type_name()
 15.1165 +    polnew_reslabels = new_acmpol.policy_get_resourcelabel_names()
 15.1166 +    errors=""
 15.1167 +
 15.1168 +    try:
 15.1169 +        __resfile_lock.acquire()
 15.1170 +        mapfile_lock()
 15.1171 +
 15.1172 +        # Get all domains' dominfo.
 15.1173 +        from xen.xend import XendDomain
 15.1174 +        dominfos = XendDomain.instance().list('all')
 15.1175 +
 15.1176 +        log.info("----------------------------------------------")
 15.1177 +        # relabel resources
 15.1178 +
 15.1179 +        access_control = {}
 15.1180 +        try:
 15.1181 +            access_control = dictio.dict_read("resources", res_label_filename)
 15.1182 +        finally:
 15.1183 +            pass
 15.1184 +        for key, labeldata in access_control.items():
 15.1185 +            if len(labeldata) == 2:
 15.1186 +                policy, label = labeldata
 15.1187 +                policytype = xsconstants.ACM_POLICY_ID
 15.1188 +            elif len(labeldata) == 3:
 15.1189 +                policytype, policy, label = labeldata
 15.1190 +            else:
 15.1191 +                return -xsconstants.XSERR_BAD_LABEL_FORMAT, ""
 15.1192 +
 15.1193 +            if policytype != cur_policytype or \
 15.1194 +               policy     != cur_policyname:
 15.1195 +                continue
 15.1196 +
 15.1197 +            # label been renamed or deleted?
 15.1198 +            if reslabel_map.has_key(label) and cur_policyname == policy:
 15.1199 +                label = reslabel_map[label]
 15.1200 +            elif label not in polnew_reslabels:
 15.1201 +                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 15.1202 +            # Update entry
 15.1203 +            access_control[key] = \
 15.1204 +                   tuple([ policytype, new_policyname, label ])
 15.1205 +
 15.1206 +        # All resources have new labels in the access_control map
 15.1207 +        # There may still be labels in there that are invalid now.
 15.1208 +
 15.1209 +        # Do this in memory without writing to disk:
 15.1210 +        #  - Relabel all domains independent of whether they are running
 15.1211 +        #    or not
 15.1212 +        #  - later write back to config files
 15.1213 +        polnew_vmlabels = new_acmpol.policy_get_virtualmachinelabel_names()
 15.1214 +
 15.1215 +        for dominfo in dominfos:
 15.1216 +            sec_lab = dominfo.get_security_label()
 15.1217 +            if not sec_lab:
 15.1218 +                continue
 15.1219 +            policytype, policy, vmlabel = sec_lab.split(":")
 15.1220 +            name  = dominfo.getName()
 15.1221 +
 15.1222 +            if policytype != cur_policytype or \
 15.1223 +               policy     != cur_policyname:
 15.1224 +                continue
 15.1225 +
 15.1226 +            new_vmlabel = vmlabel
 15.1227 +            if vmlabel_map.has_key(vmlabel):
 15.1228 +                new_vmlabel = vmlabel_map[vmlabel]
 15.1229 +            if new_vmlabel not in polnew_vmlabels:
 15.1230 +                policytype = xsconstants.INVALID_POLICY_PREFIX + policytype
 15.1231 +            new_seclab = "%s:%s:%s" % \
 15.1232 +                    (policytype, new_policyname, new_vmlabel)
 15.1233 +
 15.1234 +            domain_label_map[dominfo] = [ sec_lab, new_seclab ]
 15.1235 +
 15.1236 +            if dominfo._stateGet() in (DOM_STATE_PAUSED, DOM_STATE_RUNNING):
 15.1237 +                compatible = __resources_compatible_with_vmlabel(new_acmpol,
 15.1238 +                                                      dominfo,
 15.1239 +                                                      new_vmlabel,
 15.1240 +                                                      access_control)
 15.1241 +                log.info("Domain %s with new label '%s' can access its "
 15.1242 +                         "resources? : %s" %
 15.1243 +                         (name, new_vmlabel, str(compatible)))
 15.1244 +                log.info("VM labels in new domain: %s" %
 15.1245 +                         new_acmpol.policy_get_virtualmachinelabel_names())
 15.1246 +                if not compatible:
 15.1247 +                    return (-xsconstants.XSERR_RESOURCE_ACCESS, "")
 15.1248 +
 15.1249 +        rc, errors = hv_chg_policy(bin_pol, del_array, chg_array)
 15.1250 +        if rc == 0:
 15.1251 +            # Write the relabeled resources back into the file
 15.1252 +            dictio.dict_write(access_control, "resources", res_label_filename)
 15.1253 +            # Properly update all VMs to their new labels
 15.1254 +            for dominfo, labels in domain_label_map.items():
 15.1255 +                sec_lab, new_seclab = labels
 15.1256 +                if sec_lab != new_seclab:
 15.1257 +                    log.info("Updating domain %s to new label '%s'." % \
 15.1258 +                             (sec_lab, new_seclab))
 15.1259 +                    # This better be working!
 15.1260 +                    dominfo.set_security_label(new_seclab,
 15.1261 +                                               sec_lab,
 15.1262 +                                               new_acmpol)
 15.1263 +    finally:
 15.1264 +        log.info("----------------------------------------------")
 15.1265 +        mapfile_unlock()
 15.1266 +        __resfile_lock.release()
 15.1267 +
 15.1268 +    return rc, errors
 15.1269 +
 15.1270 +def parse_security_label(security_label):
 15.1271 +    tmp = security_label.split(":")
 15.1272 +    if len(tmp) != 3:
 15.1273 +        return ""
 15.1274 +    else:
 15.1275 +        return security_label
 15.1276 +
 15.1277 +def set_security_label(policy, label):
 15.1278 +    policytype = xsconstants.ACM_POLICY_ID
 15.1279 +    if label != "" and policy != "":
 15.1280 +        return "%s:%s:%s" % (policytype, policy, label)
 15.1281 +    else:
 15.1282 +        return ""
 15.1283 +
 15.1284 +def ssidref2security_label(ssidref):
 15.1285 +    from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
 15.1286 +    return XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/python/xen/util/xsm/dummy/__init__.py	Fri Aug 31 11:37:20 2007 +0100
    16.3 @@ -0,0 +1,1 @@
    16.4 + 
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/python/xen/util/xsm/dummy/dummy.py	Fri Aug 31 11:37:20 2007 +0100
    17.3 @@ -0,0 +1,53 @@
    17.4 +import sys
    17.5 +
    17.6 +class XSMError(Exception):
    17.7 +    def __init__(self,value):
    17.8 +        self.value = value
    17.9 +    def __str__(self):
   17.10 +        return repr(self.value)
   17.11 +
   17.12 +policy_dir_prefix = "";
   17.13 +active_policy = "";
   17.14 +NULL_SSIDREF = 0;
   17.15 +
   17.16 +def err(msg):
   17.17 +    """Raise XSM-dummy exception.
   17.18 +    """
   17.19 +    sys.stderr.write("XSM-dummyError: " + msg + "\n")
   17.20 +    raise XSMError(msg)
   17.21 +
   17.22 +def on():
   17.23 +    return 0
   17.24 +
   17.25 +def ssidref2label(ssidref):
   17.26 +    return 0
   17.27 +
   17.28 +def label2ssidref(label, policy, type):
   17.29 +    return 0
   17.30 +
   17.31 +def res_security_check(resource, domain_label):
   17.32 +    return 1
   17.33 +
   17.34 +def get_res_security_details(resource):
   17.35 +    return ("","","")
   17.36 +
   17.37 +def get_res_label(resource):
   17.38 +    return ("","")
   17.39 +
   17.40 +def res_security_check_xapi(rlabel, rssidref, rpolicy, xapi_dom_label):
   17.41 +    return 1
   17.42 +
   17.43 +def parse_security_label(security_label):
   17.44 +    return ""
   17.45 +
   17.46 +def calc_dom_ssidref_from_info(info):
   17.47 +    return ""
   17.48 +
   17.49 +def set_security_label(policy, label):
   17.50 +     return ""
   17.51 +
   17.52 +def ssidref2security_label(ssidref):
   17.53 +    return ""
   17.54 +
   17.55 +def has_authorization(ssidref):
   17.56 +    return True
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/python/xen/util/xsm/flask/__init__.py	Fri Aug 31 11:37:20 2007 +0100
    18.3 @@ -0,0 +1,1 @@
    18.4 + 
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/python/xen/util/xsm/flask/flask.py	Fri Aug 31 11:37:20 2007 +0100
    19.3 @@ -0,0 +1,37 @@
    19.4 +import sys
    19.5 +from xen.lowlevel import flask
    19.6 +from xen.xend import sxp
    19.7 +
    19.8 +def err(msg):
    19.9 +    """Raise XSM-Flask exception.
   19.10 +    """
   19.11 +    sys.stderr.write("XSM-FlaskError: " + msg + "\n")
   19.12 +    raise XSMError(msg)
   19.13 +
   19.14 +def on():
   19.15 +    return 1
   19.16 +
   19.17 +def ssidref2label(ssidref):
   19.18 +    try:
   19.19 +        return flask.flask_sid_to_context(ssidref)
   19.20 +    except:
   19.21 +        return ""
   19.22 +
   19.23 +def label2ssidref(label, policy, type):
   19.24 +    try:
   19.25 +        return flask.flask_context_to_sid(label)
   19.26 +    except:
   19.27 +        return ""
   19.28 +
   19.29 +def parse_security_label(security_label):
   19.30 +    return security_label
   19.31 +
   19.32 +def calc_dom_ssidref_from_info(info):
   19.33 +    ssidref = label2ssidref(info['security_label'], "", "")
   19.34 +    return ssidref
   19.35 +
   19.36 +def set_security_label(policy, label):
   19.37 +    return label
   19.38 +
   19.39 +def ssidref2security_label(ssidref):
   19.40 +    return ssidref2label(ssidref)
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/python/xen/util/xsm/xsm_core.py	Fri Aug 31 11:37:20 2007 +0100
    20.3 @@ -0,0 +1,7 @@
    20.4 +import sys
    20.5 +import xen.util.xsm.dummy.dummy as dummy
    20.6 +
    20.7 +def xsm_init(self):
    20.8 +    for op in dir(dummy):
    20.9 +        if not hasattr(self, op):
   20.10 +            setattr(self, op, getattr(dummy, op, None))
    21.1 --- a/tools/python/xen/xend/XendConfig.py	Fri Aug 31 11:31:18 2007 +0100
    21.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Aug 31 11:37:20 2007 +0100
    21.3 @@ -30,7 +30,6 @@ from xen.xend.PrettyPrint import prettyp
    21.4  from xen.xend.XendConstants import DOM_STATE_HALTED
    21.5  from xen.xend.server.netif import randomMAC
    21.6  from xen.util.blkif import blkdev_name_to_number
    21.7 -from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    21.8  from xen.util import xsconstants
    21.9  
   21.10  log = logging.getLogger("xend.XendConfig")
   21.11 @@ -433,7 +432,8 @@ class XendConfig(dict):
   21.12          self['cpu_time'] = dominfo['cpu_time']/1e9
   21.13          if dominfo.get('ssidref'):
   21.14              ssidref = int(dominfo.get('ssidref'))
   21.15 -            self['security_label'] = XSPolicyAdminInstance().ssidref_to_vmlabel(ssidref)
   21.16 +            import xen.util.xsm.xsm as security
   21.17 +            self['security_label'] = security.ssidref2security_label(ssidref)
   21.18  
   21.19          self['shutdown_reason'] = dominfo['shutdown_reason']
   21.20  
   21.21 @@ -651,7 +651,6 @@ class XendConfig(dict):
   21.22                  #                     ['ssidref', 196611]]
   21.23                  policy = ""
   21.24                  label = ""
   21.25 -                policytype = xsconstants.ACM_POLICY_ID
   21.26                  for idx in range(0, len(secinfo)):
   21.27                      if secinfo[idx][0] == "access_control":
   21.28                          for aidx in range(1, len(secinfo[idx])):
   21.29 @@ -659,9 +658,10 @@ class XendConfig(dict):
   21.30                                  policy = secinfo[idx][aidx][1]
   21.31                              if secinfo[idx][aidx][0] == "label":
   21.32                                  label  = secinfo[idx][aidx][1]
   21.33 -                if label != "" and policy != "":
   21.34 -                    cfg['security_label'] = "%s:%s:%s" % \
   21.35 -                            (policytype, policy, label)
   21.36 +                import xen.util.xsm.xsm as security
   21.37 +                cfg['security_label'] = \
   21.38 +                    security.set_security_label(policy, label)
   21.39 +                if not sxp.child_value(sxp_cfg, 'security_label'):
   21.40                      del cfg['security']
   21.41  
   21.42          old_state = sxp.child_value(sxp_cfg, 'state')
    22.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 31 11:31:18 2007 +0100
    22.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Aug 31 11:37:20 2007 +0100
    22.3 @@ -36,7 +36,7 @@ from types import StringTypes
    22.4  import xen.lowlevel.xc
    22.5  from xen.util import asserts
    22.6  from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
    22.7 -from xen.util import security
    22.8 +import xen.util.xsm.xsm as security
    22.9  
   22.10  from xen.xend import balloon, sxp, uuid, image, arch, osdep
   22.11  from xen.xend import XendOptions, XendNode, XendConfig
    23.1 --- a/tools/python/xen/xend/XendVDI.py	Fri Aug 31 11:31:18 2007 +0100
    23.2 +++ b/tools/python/xen/xend/XendVDI.py	Fri Aug 31 11:37:20 2007 +0100
    23.3 @@ -23,7 +23,8 @@ import os
    23.4  
    23.5  from xen.util.xmlrpclib2 import stringify
    23.6  from xmlrpclib import dumps, loads
    23.7 -from xen.util import security, xsconstants
    23.8 +from xen.util import xsconstants
    23.9 +import xen.util.xsm.xsm as security
   23.10  from xen.xend.XendError import SecurityError
   23.11  
   23.12  KB = 1024
    24.1 --- a/tools/python/xen/xend/XendXSPolicy.py	Fri Aug 31 11:31:18 2007 +0100
    24.2 +++ b/tools/python/xen/xend/XendXSPolicy.py	Fri Aug 31 11:37:20 2007 +0100
    24.3 @@ -20,7 +20,8 @@ import logging
    24.4  from xen.xend.XendBase import XendBase
    24.5  from xen.xend.XendError import *
    24.6  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    24.7 -from xen.util import xsconstants, security
    24.8 +from xen.util import xsconstants
    24.9 +import xen.util.xsm.xsm as security
   24.10  import base64
   24.11  
   24.12  log = logging.getLogger("xend.XendXSPolicy")
    25.1 --- a/tools/python/xen/xend/XendXSPolicyAdmin.py	Fri Aug 31 11:31:18 2007 +0100
    25.2 +++ b/tools/python/xen/xend/XendXSPolicyAdmin.py	Fri Aug 31 11:37:20 2007 +0100
    25.3 @@ -22,7 +22,8 @@ from xml.dom import minidom, Node
    25.4  
    25.5  from xen.xend.XendLogging import log
    25.6  from xen.xend import uuid
    25.7 -from xen.util import security, xsconstants, dictio, bootloader
    25.8 +from xen.util import xsconstants, dictio, bootloader
    25.9 +import xen.util.xsm.acm.acm as security
   25.10  from xen.util.xspolicy import XSPolicy
   25.11  from xen.util.acmpolicy import ACMPolicy
   25.12  from xen.xend.XendError import SecurityError
    26.1 --- a/tools/python/xen/xend/server/blkif.py	Fri Aug 31 11:31:18 2007 +0100
    26.2 +++ b/tools/python/xen/xend/server/blkif.py	Fri Aug 31 11:37:20 2007 +0100
    26.3 @@ -20,7 +20,7 @@ import re
    26.4  import string
    26.5  
    26.6  from xen.util import blkif
    26.7 -from xen.util import security
    26.8 +import xen.util.xsm.xsm as security
    26.9  from xen.xend.XendError import VmError
   26.10  from xen.xend.server.DevController import DevController
   26.11  
    27.1 --- a/tools/python/xen/xend/server/netif.py	Fri Aug 31 11:31:18 2007 +0100
    27.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Aug 31 11:37:20 2007 +0100
    27.3 @@ -27,8 +27,8 @@ import re
    27.4  from xen.xend import XendOptions
    27.5  from xen.xend.server.DevController import DevController
    27.6  from xen.xend.XendError import VmError
    27.7 -from xen.util import security
    27.8  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
    27.9 +import xen.util.xsm.xsm as security
   27.10  
   27.11  from xen.xend.XendLogging import log
   27.12  
    28.1 --- a/tools/python/xen/xm/addlabel.py	Fri Aug 31 11:31:18 2007 +0100
    28.2 +++ b/tools/python/xen/xm/addlabel.py	Fri Aug 31 11:37:20 2007 +0100
    28.3 @@ -23,7 +23,7 @@ import os
    28.4  import sys
    28.5  
    28.6  from xen.util import dictio
    28.7 -from xen.util import security
    28.8 +import xen.util.xsm.xsm as security
    28.9  from xen.xm.opts import OptionError
   28.10  from xen.util import xsconstants
   28.11  from xen.xm import main as xm_main
    29.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Fri Aug 31 11:31:18 2007 +0100
    29.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Fri Aug 31 11:37:20 2007 +0100
    29.3 @@ -26,11 +26,11 @@ import os, stat
    29.4  import shutil
    29.5  import string
    29.6  import re
    29.7 -from xen.util.security import err
    29.8 -from xen.util.security import policy_dir_prefix, xen_title_re
    29.9 -from xen.util.security import boot_filename, altboot_filename
   29.10 -from xen.util.security import any_title_re, xen_kernel_re, any_module_re
   29.11 -from xen.util.security import empty_line_re, binary_name_re, policy_name_re
   29.12 +from xen.util.xsm.xsm import err
   29.13 +from xen.util.xsm.xsm import policy_dir_prefix, xen_title_re
   29.14 +from xen.util.xsm.xsm import boot_filename, altboot_filename
   29.15 +from xen.util.xsm.xsm import any_title_re, xen_kernel_re, any_module_re
   29.16 +from xen.util.xsm.xsm import empty_line_re, binary_name_re, policy_name_re
   29.17  from xen.util import xsconstants
   29.18  from xen.xm.opts import OptionError
   29.19  from xen.xm import main as xm_main
    30.1 --- a/tools/python/xen/xm/create.py	Fri Aug 31 11:31:18 2007 +0100
    30.2 +++ b/tools/python/xen/xm/create.py	Fri Aug 31 11:37:20 2007 +0100
    30.3 @@ -33,7 +33,7 @@ from xen.xend import osdep
    30.4  import xen.xend.XendClient
    30.5  from xen.xend.XendBootloader import bootloader
    30.6  from xen.util import blkif
    30.7 -from xen.util import security
    30.8 +import xen.util.xsm.xsm as security
    30.9  from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
   30.10  
   30.11  from xen.xm.opts import *
   30.12 @@ -1221,7 +1221,7 @@ def config_security_check(config, verbos
   30.13              if verbose:
   30.14                  print "   %s: PERMITTED" % (resource)
   30.15  
   30.16 -        except security.ACMError:
   30.17 +        except security.XSMError:
   30.18              print "   %s: DENIED" % (resource)
   30.19              (poltype, res_label, res_policy) = security.get_res_label(resource)
   30.20              if not res_label:
   30.21 @@ -1243,7 +1243,7 @@ def create_security_check(config):
   30.22                  passed = 1
   30.23          else:
   30.24              print "Checking resources: (skipped)"
   30.25 -    except security.ACMError:
   30.26 +    except security.XSMError:
   30.27          sys.exit(-1)
   30.28  
   30.29      return passed
   30.30 @@ -1300,7 +1300,7 @@ def main(argv):
   30.31          map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
   30.32      elif not opts.is_xml:
   30.33          if not create_security_check(config):
   30.34 -            raise security.ACMError(
   30.35 +            raise security.XSMError(
   30.36                  'Security Configuration prevents domain from starting')
   30.37          dom = make_domain(opts, config)
   30.38          
    31.1 --- a/tools/python/xen/xm/dry-run.py	Fri Aug 31 11:31:18 2007 +0100
    31.2 +++ b/tools/python/xen/xm/dry-run.py	Fri Aug 31 11:37:20 2007 +0100
    31.3 @@ -19,7 +19,7 @@
    31.4  """Tests the security settings for a domain and its resources.
    31.5  """
    31.6  import sys
    31.7 -from xen.util import security
    31.8 +import xen.util.xsm.xsm as security
    31.9  from xen.xm import create
   31.10  from xen.xend import sxp
   31.11  from xen.xm.opts import OptionError
    32.1 --- a/tools/python/xen/xm/dumppolicy.py	Fri Aug 31 11:31:18 2007 +0100
    32.2 +++ b/tools/python/xen/xm/dumppolicy.py	Fri Aug 31 11:37:20 2007 +0100
    32.3 @@ -18,7 +18,7 @@
    32.4  """Display currently enforced policy (low-level hypervisor representation).
    32.5  """
    32.6  import sys
    32.7 -from xen.util.security import ACMError, err, dump_policy
    32.8 +from xen.util.xsm.xsm import XSMError, err, dump_policy
    32.9  from xen.xm.opts import OptionError
   32.10  
   32.11  def help():
    33.1 --- a/tools/python/xen/xm/getlabel.py	Fri Aug 31 11:31:18 2007 +0100
    33.2 +++ b/tools/python/xen/xm/getlabel.py	Fri Aug 31 11:37:20 2007 +0100
    33.3 @@ -20,7 +20,7 @@
    33.4  """
    33.5  import sys, os, re
    33.6  from xen.util import dictio
    33.7 -from xen.util import security
    33.8 +import xen.util.xsm.xsm as security
    33.9  from xen.util import xsconstants
   33.10  from xen.xm.opts import OptionError
   33.11  from xen.xm import main as xm_main
   33.12 @@ -62,7 +62,7 @@ def get_resource_label(resource):
   33.13                                      "Please relabel the resource.")
   33.14          print policytype+":"+policy+":"+label
   33.15      else:
   33.16 -        raise security.ACMError("Resource not labeled")
   33.17 +        raise security.XSMError("Resource not labeled")
   33.18  
   33.19  
   33.20  def get_domain_label(configfile):
   33.21 @@ -95,7 +95,7 @@ def get_domain_label(configfile):
   33.22  
   33.23      # send error message if we didn't find anything
   33.24      if acline == "":
   33.25 -        raise security.ACMError("Domain not labeled")
   33.26 +        raise security.XSMError("Domain not labeled")
   33.27  
   33.28      # print out the label
   33.29      (title, data) = acline.split("=", 1)
    34.1 --- a/tools/python/xen/xm/labels.py	Fri Aug 31 11:31:18 2007 +0100
    34.2 +++ b/tools/python/xen/xm/labels.py	Fri Aug 31 11:37:20 2007 +0100
    34.3 @@ -21,8 +21,8 @@
    34.4  import sys
    34.5  import traceback
    34.6  import string
    34.7 -from xen.util.security import ACMError, err, list_labels, active_policy
    34.8 -from xen.util.security import vm_label_re, res_label_re, all_label_re
    34.9 +from xen.util.xsm.xsm import XSMError, err, list_labels, active_policy
   34.10 +from xen.util.xsm.xsm import vm_label_re, res_label_re, all_label_re
   34.11  from xen.xm.opts import OptionError
   34.12  from xen.util.acmpolicy import ACMPolicy
   34.13  from xen.util import xsconstants
   34.14 @@ -78,7 +78,7 @@ def labels(policy, ptype):
   34.15          for label in labels:
   34.16              print label
   34.17  
   34.18 -    except ACMError:
   34.19 +    except XSMError:
   34.20          sys.exit(-1)
   34.21      except:
   34.22          traceback.print_exc(limit = 1)
    35.1 --- a/tools/python/xen/xm/loadpolicy.py	Fri Aug 31 11:31:18 2007 +0100
    35.2 +++ b/tools/python/xen/xm/loadpolicy.py	Fri Aug 31 11:37:20 2007 +0100
    35.3 @@ -20,7 +20,7 @@
    35.4  """
    35.5  import sys
    35.6  import traceback
    35.7 -from xen.util.security import ACMError, err, load_policy
    35.8 +from xen.util.xsm.xsm import XSMError, err, load_policy
    35.9  from xen.xm.opts import OptionError
   35.10  from xen.xm import main as xm_main
   35.11  from xen.util import xsconstants
    36.1 --- a/tools/python/xen/xm/main.py	Fri Aug 31 11:31:18 2007 +0100
    36.2 +++ b/tools/python/xen/xm/main.py	Fri Aug 31 11:37:20 2007 +0100
    36.3 @@ -49,7 +49,8 @@ from xen.xend.XendConstants import *
    36.4  from xen.xm.opts import OptionError, Opts, wrap, set_true
    36.5  from xen.xm import console
    36.6  from xen.util.xmlrpcclient import ServerProxy
    36.7 -from xen.util.security import ACMError
    36.8 +import xen.util.xsm.xsm as security
    36.9 +from xen.util.xsm.xsm import XSMError
   36.10  from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
   36.11  
   36.12  import XenAPI
   36.13 @@ -872,12 +873,7 @@ def parse_doms_info(info):
   36.14          }
   36.15  
   36.16      security_label = get_info('security_label', str, '')
   36.17 -    tmp = security_label.split(":")
   36.18 -    if len(tmp) != 3:
   36.19 -        seclabel = ""
   36.20 -    else:
   36.21 -        seclabel = security_label
   36.22 -    parsed_info['seclabel'] = seclabel
   36.23 +    parsed_info['seclabel'] = security.parse_security_label(security_label)
   36.24  
   36.25      if serverType == SERVER_XEN_API:
   36.26          parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
   36.27 @@ -935,14 +931,14 @@ def xm_brief_list(doms):
   36.28          print format % d
   36.29  
   36.30  def xm_label_list(doms):
   36.31 -    print '%-32s %5s %5s %5s %10s %9s %-8s' % \
   36.32 +    print '%-40s %3s %5s %5s %10s %9s %-10s' % \
   36.33            ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
   36.34 -    
   36.35 +
   36.36      output = []
   36.37 -    format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
   36.38 -             '%(cpu_time)8.1f %(seclabel)9s'
   36.39 +    format = '%(name)-40s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
   36.40 +             '%(cpu_time)8.1f %(seclabel)10s'
   36.41  
   36.42 -    from xen.util import security
   36.43 +    import xen.util.xsm.xsm as security
   36.44          
   36.45      for dom in doms:
   36.46          d = parse_doms_info(dom)
   36.47 @@ -2580,12 +2576,12 @@ def _run_cmd(cmd, cmd_name, args):
   36.48          print e.usage
   36.49      except XenAPIUnsupportedException, e:
   36.50          err(str(e))
   36.51 -    except ACMError, e:
   36.52 +    except XSMError, e:
   36.53          err(str(e))
   36.54      except Exception, e:
   36.55          if serverType != SERVER_XEN_API:
   36.56 -           from xen.util import security
   36.57 -           if isinstance(e, security.ACMError):
   36.58 +           import xen.util.xsm.xsm as security
   36.59 +           if isinstance(e, security.XSMError):
   36.60                 err(str(e))
   36.61                 return False, 1
   36.62          print "Unexpected error:", sys.exc_info()[0]
    37.1 --- a/tools/python/xen/xm/makepolicy.py	Fri Aug 31 11:31:18 2007 +0100
    37.2 +++ b/tools/python/xen/xm/makepolicy.py	Fri Aug 31 11:37:20 2007 +0100
    37.3 @@ -19,7 +19,7 @@
    37.4  """
    37.5  import sys
    37.6  import traceback
    37.7 -from xen.util.security import ACMError, err, make_policy
    37.8 +from xen.util.xsm.xsm import ACMError, err, make_policy
    37.9  from xen.util import xsconstants
   37.10  from xen.xm.opts import OptionError
   37.11  from xen.xm import main as xm_main
    38.1 --- a/tools/python/xen/xm/resources.py	Fri Aug 31 11:31:18 2007 +0100
    38.2 +++ b/tools/python/xen/xm/resources.py	Fri Aug 31 11:37:20 2007 +0100
    38.3 @@ -20,7 +20,7 @@
    38.4  """
    38.5  import sys
    38.6  from xen.util import dictio
    38.7 -from xen.util import security
    38.8 +import xen.util.xsm.xsm as security
    38.9  from xen.util import xsconstants
   38.10  from xen.xm.opts import OptionError
   38.11  from xen.xm import main as xm_main
    39.1 --- a/tools/python/xen/xm/rmlabel.py	Fri Aug 31 11:31:18 2007 +0100
    39.2 +++ b/tools/python/xen/xm/rmlabel.py	Fri Aug 31 11:37:20 2007 +0100
    39.3 @@ -20,7 +20,7 @@
    39.4  """
    39.5  import sys, os, re
    39.6  from xen.util import dictio
    39.7 -from xen.util import security
    39.8 +import xen.util.xsm.xsm as security
    39.9  from xen.xm.opts import OptionError
   39.10  from xen.xm import main as xm_main
   39.11  from xen.xm.main import server
   39.12 @@ -108,7 +108,7 @@ def rm_domain_label(configfile):
   39.13  
   39.14      # send error message if we didn't find anything to remove
   39.15      if not removed:
   39.16 -        raise security.ACMError('Domain not labeled')
   39.17 +        raise security.XSMError('Domain not labeled')
   39.18  
   39.19      # write the data back out to the file
   39.20      fd = open(fil, "wb")
    40.1 --- a/tools/python/xen/xm/setpolicy.py	Fri Aug 31 11:31:18 2007 +0100
    40.2 +++ b/tools/python/xen/xm/setpolicy.py	Fri Aug 31 11:37:20 2007 +0100
    40.3 @@ -26,7 +26,7 @@ import string
    40.4  from xen.util import xsconstants
    40.5  from xen.util.acmpolicy import ACMPolicy
    40.6  from xen.xm.opts import OptionError
    40.7 -from xen.util.security import policy_dir_prefix
    40.8 +from xen.util.xsm.acm.acm import policy_dir_prefix
    40.9  from xen.xm import main as xm_main
   40.10  from xen.xm.main import server
   40.11