diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index a7286c4..66d247b 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -34,6 +34,8 @@ #define PKG "xen.lowlevel.xc" #define CLS "xc" +#define FLASK_CTX_LEN 1024 + static PyObject *xc_error_obj, *zero; typedef struct { @@ -2077,6 +2079,202 @@ static PyObject *pyxc_cpupool_freeinfo(XcObject *self) return cpumap_to_cpulist(cpumap); } +static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *ctx; + char *buf; + uint32_t len; + uint32_t sid; + int ret; + + static char *kwd_list[] = { "context", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, + &ctx) ) + return NULL; + + len = strlen(ctx); + + buf = malloc(len); + if (!buf) { + errno = -ENOMEM; + PyErr_SetFromErrno(xc_error_obj); + } + + memcpy(buf, ctx, len); + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + free(buf); + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid); + + xc_interface_close(xc_handle); + + free(buf); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return PyInt_FromLong(sid); +} + +static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + uint32_t sid; + char ctx[FLASK_CTX_LEN]; + uint32_t ctx_len = FLASK_CTX_LEN; + int ret; + + static char *kwd_list[] = { "sid", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &sid) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_sid_to_context(xc_handle, sid, ctx, ctx_len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("s", ctx, ctx_len); +} + +static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds) +{ + xc_interface *xc_handle; + char *policy; + uint32_t len; + int ret; + + static char *kwd_list[] = { "policy", NULL }; + + if( !PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwd_list, &policy, &len) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_load(xc_handle, policy, len); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_getenforce(PyObject *self) +{ + xc_interface *xc_handle; + int ret; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_getenforce(xc_handle); + + xc_interface_close(xc_handle); + + if ( ret < 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_setenforce(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + int mode; + int ret; + + static char *kwd_list[] = { "mode", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, + &mode) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_setenforce(xc_handle, mode); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i", ret); +} + +static PyObject *pyflask_access(PyObject *self, PyObject *args, + PyObject *kwds) +{ + xc_interface *xc_handle; + char *tcon, *scon; + uint16_t tclass; + uint32_t req, allowed, decided, auditallow, auditdeny, seqno; + int ret; + + static char *kwd_list[] = { "src_context", "tar_context", + "tar_class", "req_permissions", + "decided", "auditallow","auditdeny", + "seqno", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ssil|llll", kwd_list, + &scon, &tcon, &tclass, &req, &decided, + &auditallow, &auditdeny, &seqno) ) + return NULL; + + xc_handle = xc_interface_open(0,0,0); + if (!xc_handle) { + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_flask_access(xc_handle, scon, tcon, tclass, req, &allowed, &decided, + &auditallow, &auditdeny, &seqno); + + xc_interface_close(xc_handle); + + if ( ret != 0 ) { + errno = -ret; + return PyErr_SetFromErrno(xc_error_obj); + } + + return Py_BuildValue("i",ret); +} + static PyMethodDef pyxc_methods[] = { { "domain_create", (PyCFunction)pyxc_domain_create, @@ -2676,6 +2874,59 @@ static PyMethodDef pyxc_methods[] = { "Get info about cpus not in any cpupool.\n" "Returns: [list]: List of CPUs\n" }, + { "flask_context_to_sid", + (PyCFunction)pyflask_context_to_sid, + METH_KEYWORDS, "\n" + "Convert a context string to a dynamic SID.\n" + " context [str]: String specifying context to be converted\n" + "Returns: [int]: Numeric SID on success; -1 on error.\n" }, + + { "flask_sid_to_context", + (PyCFunction)pyflask_sid_to_context, + METH_KEYWORDS, "\n" + "Convert a dynamic SID to context string.\n" + " context [int]: SID to be converted\n" + "Returns: [str]: Numeric SID on success; -1 on error.\n" }, + + { "flask_load", + (PyCFunction)pyflask_load, + METH_KEYWORDS, "\n" + "Loads a policy into the hypervisor.\n" + " policy [str]: policy to be load\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_getenforce", + (PyCFunction)pyflask_getenforce, + METH_NOARGS, "\n" + "Returns the current mode of the Flask XSM module.\n" + "Returns: [int]: 0 for permissive; 1 for enforcing; -1 on failure.\n" }, + + { "flask_setenforce", + (PyCFunction)pyflask_setenforce, + METH_KEYWORDS, "\n" + "Modifies the current mode for the Flask XSM module.\n" + " mode [int]: mode to change to\n" + "Returns: [int]: 0 on success; -1 on failure.\n" }, + + { "flask_access", + (PyCFunction)pyflask_access, + METH_KEYWORDS, "\n" + "Returns whether a source context has access to target context based on \ + class and permissions requested.\n" + " scon [str]: source context\n" + " tcon [str]: target context\n" + " tclass [int]: target security class\n" + " req [int] requested permissions\n" + " allowed [int] permissions allow for the target class between the source \ + and target context\n" + " decided [int] the permissions that were returned in the allowed \ + parameter\n" + " auditallow [int] permissions set to audit on allow\n" + " auditdeny [int] permissions set to audit on deny\n" + " seqno [int] not used\n" + "Returns: [int]: 0 on all permission granted; -1 if any permissions are \ + denied\n" }, + { NULL, NULL, 0, NULL } };