⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acm.c

📁 xen 3.2.2 源码
💻 C
字号:
/**************************************************************** * acm.c * * Copyright (C) 2006,2007 IBM Corporation * * Authors: * Reiner Sailer <sailer@watson.ibm.com> * Stefan Berger <stefanb@us.ibm.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the * License. * * ACM low-level code that allows Python control code to leverage * the ACM hypercall interface to retrieve real-time information * from the Xen hypervisor security module. * * indent -i4 -kr -nut */#include <Python.h>#include <stdio.h>#include <fcntl.h>#include <sys/mman.h>#include <sys/types.h>#include <stdlib.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <xen/xsm/acm.h>#include <xen/xsm/acm_ops.h>#include <xenctrl.h>#define PERROR(_m, _a...) \fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,    \    errno, strerror(errno))static PyObject *acm_error_obj;/* generic shared function */void * __getssid(int domid, uint32_t *buflen){    struct acm_getssid getssid;    int xc_handle;    #define SSID_BUFFER_SIZE    4096    void *buf = NULL;    if ((xc_handle = xc_interface_open()) < 0) {        goto out1;    }    if ((buf = malloc(SSID_BUFFER_SIZE)) == NULL) {        PERROR("acm.policytype: Could not allocate ssid buffer!\n");        goto out2;    }    memset(buf, 0, SSID_BUFFER_SIZE);    set_xen_guest_handle(getssid.ssidbuf, buf);    getssid.ssidbuf_size = SSID_BUFFER_SIZE;    getssid.get_ssid_by = ACM_GETBY_domainid;    getssid.id.domainid = domid;    if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) {        if (errno == EACCES)            PERROR("ACM operation failed.");        free(buf);        buf = NULL;        goto out2;    } else {        *buflen = SSID_BUFFER_SIZE;        goto out2;    } out2:    xc_interface_close(xc_handle); out1:    return buf;}/* retrieve the policytype indirectly by retrieving the * ssidref for domain 0 (always exists) */static PyObject *policy(PyObject * self, PyObject * args){    /* out */    char *policyreference;    PyObject *ret;    void *ssid_buffer;    uint32_t buf_len;    if (!PyArg_ParseTuple(args, "", NULL)) {        return NULL;    }    ssid_buffer =  __getssid(0, &buf_len);    if (ssid_buffer == NULL || buf_len < sizeof(struct acm_ssid_buffer)) {        free(ssid_buffer);        return PyErr_SetFromErrno(acm_error_obj);    }    else {        struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)ssid_buffer;        policyreference = (char *)(ssid_buffer + ssid->policy_reference_offset                       + sizeof (struct acm_policy_reference_buffer));        ret = Py_BuildValue("s", policyreference);        free(ssid_buffer);        return ret;    }}/* retrieve ssid info for a domain domid*/static PyObject *getssid(PyObject * self, PyObject * args){    /* in */    uint32_t    domid;    /* out */    char *policytype, *policyreference;    uint32_t    ssidref;    void *ssid_buffer;    uint32_t buf_len;    if (!PyArg_ParseTuple(args, "i", &domid)) {        return NULL;    }    ssid_buffer =  __getssid(domid, &buf_len);    if (ssid_buffer == NULL) {        return NULL;    } else if (buf_len < sizeof(struct acm_ssid_buffer)) {        free(ssid_buffer);        return NULL;    } else {        struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *) ssid_buffer;        policytype = ACM_POLICY_NAME(ssid->secondary_policy_code << 4 |                     ssid->primary_policy_code);        ssidref = ssid->ssidref;        policyreference = (char *)(ssid_buffer + ssid->policy_reference_offset                       + sizeof (struct acm_policy_reference_buffer));    }    free(ssid_buffer);    return Py_BuildValue("{s:s,s:s,s:i}",             "policyreference",   policyreference,             "policytype",        policytype,             "ssidref",           ssidref);}/* retrieve access decision based on domain ids or ssidrefs */static PyObject *getdecision(PyObject * self, PyObject * args){    char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;    struct acm_getdecision getdecision;    int xc_handle, rc;    uint32_t hooktype;    if (!PyArg_ParseTuple(args, "ssssi", &arg1_name,                          &arg1, &arg2_name, &arg2, &hooktype)) {        return NULL;    }    if ((xc_handle = xc_interface_open()) <= 0) {        PERROR("Could not open xen privcmd device!\n");        return NULL;    }    if ((strcmp(arg1_name, "domid") && strcmp(arg1_name, "ssidref")) ||    (strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))        return NULL;    getdecision.hook = hooktype;    if (!strcmp(arg1_name, "domid")) {        getdecision.get_decision_by1 = ACM_GETBY_domainid;        getdecision.id1.domainid = atoi(arg1);    } else {        getdecision.get_decision_by1 = ACM_GETBY_ssidref;        getdecision.id1.ssidref = atol(arg1);    }    if (!strcmp(arg2_name, "domid")) {        getdecision.get_decision_by2 = ACM_GETBY_domainid;        getdecision.id2.domainid = atoi(arg2);    } else {        getdecision.get_decision_by2 = ACM_GETBY_ssidref;        getdecision.id2.ssidref = atol(arg2);    }    rc = xc_acm_op(xc_handle, ACMOP_getdecision,                   &getdecision, sizeof(getdecision));    xc_interface_close(xc_handle);    if (rc < 0) {        if (errno == EACCES)            PERROR("ACM operation failed.");        return NULL;    }    if (getdecision.acm_decision == ACM_ACCESS_PERMITTED)        decision = "PERMITTED";    else if (getdecision.acm_decision == ACM_ACCESS_DENIED)        decision = "DENIED";    return Py_BuildValue("s", decision);}/* error messages for exceptions */const char bad_arg[] = "Bad function argument.";const char ctrlif_op[] = "Could not open control interface.";const char hv_op_err[] = "Error from hypervisor operation.";static PyObject *chgpolicy(PyObject *self, PyObject *args){    struct acm_change_policy chgpolicy;    int xc_handle, rc;    char *bin_pol = NULL, *del_arr = NULL, *chg_arr = NULL;    int bin_pol_len = 0, del_arr_len = 0, chg_arr_len = 0;    uint errarray_mbrs = 20 * 2;    uint32_t error_array[errarray_mbrs];    PyObject *result;    uint len;    memset(&chgpolicy, 0x0, sizeof(chgpolicy));    if (!PyArg_ParseTuple(args, "s#s#s#" ,&bin_pol, &bin_pol_len,                                          &del_arr, &del_arr_len,                                          &chg_arr, &chg_arr_len)) {        PyErr_SetString(PyExc_TypeError, bad_arg);        return NULL;    }    chgpolicy.policy_pushcache_size = bin_pol_len;    chgpolicy.delarray_size = del_arr_len;    chgpolicy.chgarray_size = chg_arr_len;    chgpolicy.errarray_size = sizeof(error_array);    set_xen_guest_handle(chgpolicy.policy_pushcache, bin_pol);    set_xen_guest_handle(chgpolicy.del_array, del_arr);    set_xen_guest_handle(chgpolicy.chg_array, chg_arr);    set_xen_guest_handle(chgpolicy.err_array, error_array);    if ((xc_handle = xc_interface_open()) <= 0) {        PyErr_SetString(PyExc_IOError, ctrlif_op);        return NULL;    }    rc = xc_acm_op(xc_handle, ACMOP_chgpolicy, &chgpolicy, sizeof(chgpolicy));    xc_interface_close(xc_handle);    /* only pass the filled error codes */    for (len = 0; (len + 1) < errarray_mbrs; len += 2) {        if (error_array[len] == 0) {            len *= sizeof(error_array[0]);            break;        }    }    result = Py_BuildValue("is#", rc, error_array, len);    return result;}static PyObject *getpolicy(PyObject *self, PyObject *args){    struct acm_getpolicy getpolicy;    int xc_handle, rc;    uint8_t pull_buffer[8192];    PyObject *result;    uint32_t len = sizeof(pull_buffer);    memset(&getpolicy, 0x0, sizeof(getpolicy));    set_xen_guest_handle(getpolicy.pullcache, pull_buffer);    getpolicy.pullcache_size = sizeof(pull_buffer);    if ((xc_handle = xc_interface_open()) <= 0) {        PyErr_SetString(PyExc_IOError, ctrlif_op);        return NULL;    }    rc = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));    xc_interface_close(xc_handle);    if (rc == 0) {        struct acm_policy_buffer *header =                       (struct acm_policy_buffer *)pull_buffer;        if (ntohl(header->len) < sizeof(pull_buffer))            len = ntohl(header->len);    } else {        len = 0;    }    result = Py_BuildValue("is#", rc, pull_buffer, len);    return result;}static PyObject *relabel_domains(PyObject *self, PyObject *args){    struct acm_relabel_doms reldoms;    int xc_handle, rc;    char *relabel_rules = NULL;    int rel_rules_len = 0;    uint errarray_mbrs = 20 * 2;    uint32_t error_array[errarray_mbrs];    PyObject *result;    uint len;    memset(&reldoms, 0x0, sizeof(reldoms));    if (!PyArg_ParseTuple(args, "s#" ,&relabel_rules, &rel_rules_len)) {        PyErr_SetString(PyExc_TypeError, bad_arg);        return NULL;    }    reldoms.relabel_map_size = rel_rules_len;    reldoms.errarray_size = sizeof(error_array);    set_xen_guest_handle(reldoms.relabel_map, relabel_rules);    set_xen_guest_handle(reldoms.err_array, error_array);    if ((xc_handle = xc_interface_open()) <= 0) {        PyErr_SetString(PyExc_IOError, ctrlif_op);        return NULL;    }    rc = xc_acm_op(xc_handle, ACMOP_relabeldoms, &reldoms, sizeof(reldoms));    xc_interface_close(xc_handle);    /* only pass the filled error codes */    for (len = 0; (len + 1) < errarray_mbrs; len += 2) {        if (error_array[len] == 0) {            len *= sizeof(error_array[0]);            break;        }    }    result = Py_BuildValue("is#", rc, error_array, len);    return result;}/*=================General Python Extension Declarations=================*//* methods */static PyMethodDef acmMethods[] = {    {"policy",      policy,      METH_VARARGS, "Retrieve Active ACM Policy Reference Name"},    {"getssid",     getssid,     METH_VARARGS, "Retrieve label information and ssidref for a domain"},    {"getdecision", getdecision, METH_VARARGS, "Retrieve ACM access control decision"},    {"chgpolicy",   chgpolicy,   METH_VARARGS, "Change the policy in one step"},    {"getpolicy",   getpolicy,   METH_NOARGS , "Get the binary policy from the hypervisor"},    {"relabel_domains", relabel_domains, METH_VARARGS, "Relabel domains"},    /* end of list (extend list above this line) */    {NULL, NULL, 0, NULL}};/* inits */PyMODINIT_FUNC initacm(void){    PyObject *m = Py_InitModule("acm", acmMethods);    acm_error_obj = PyErr_NewException("acm.Error", PyExc_RuntimeError, NULL);    Py_INCREF(acm_error_obj);    PyModule_AddObject(m, "Error", acm_error_obj);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -