Merged audit2why python binding from Dan Walsh.

This commit is contained in:
Daniel J Walsh 2008-01-23 21:52:01 +00:00
parent c633d69a56
commit e4623197a5
4 changed files with 12 additions and 534 deletions

View File

@ -139,3 +139,4 @@ libselinux-2.0.45.tgz
libselinux-2.0.46.tgz
libselinux-2.0.47.tgz
libselinux-2.0.48.tgz
libselinux-2.0.49.tgz

View File

@ -1,6 +1,6 @@
diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/av_permissions.h libselinux-2.0.47/include/selinux/av_permissions.h
diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/av_permissions.h libselinux-2.0.48/include/selinux/av_permissions.h
--- nsalibselinux/include/selinux/av_permissions.h 2007-11-15 15:52:46.000000000 -0500
+++ libselinux-2.0.47/include/selinux/av_permissions.h 2008-01-11 10:55:14.000000000 -0500
+++ libselinux-2.0.48/include/selinux/av_permissions.h 2008-01-23 14:39:58.000000000 -0500
@@ -900,6 +900,8 @@
#define PACKET__SEND 0x00000001UL
#define PACKET__RECV 0x00000002UL
@ -10,535 +10,9 @@ diff --exclude-from=exclude -N -u -r nsalibselinux/include/selinux/av_permission
#define KEY__VIEW 0x00000001UL
#define KEY__READ 0x00000002UL
#define KEY__WRITE 0x00000004UL
diff --exclude-from=exclude -N -u -r nsalibselinux/src/audit2why.c libselinux-2.0.47/src/audit2why.c
--- nsalibselinux/src/audit2why.c 1969-12-31 19:00:00.000000000 -0500
+++ libselinux-2.0.47/src/audit2why.c 2008-01-22 16:23:59.000000000 -0500
@@ -0,0 +1,460 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <sepol/sepol.h>
+#include <sepol/policydb/services.h>
+#include <Python.h>
+#include <selinux/selinux.h>
+
+#define UNKNOWN -1
+#define BADSCON -2
+#define BADTCON -3
+#define BADTCLASS -4
+#define BADPERM -5
+#define BADCOMPUTE -6
+#define NOPOLICY -7
+#define ALLOW 0
+#define DONTAUDIT 1
+#define TERULE 2
+#define BOOLEAN 3
+#define CONSTRAINT 4
+#define RBAC 5
+
+struct boolean_t {
+ char *name;
+ int active;
+};
+
+static struct boolean_t **boollist = NULL;
+static int boolcnt = 0;
+
+struct avc_t {
+ sepol_handle_t *handle;
+ policydb_t policydb;
+ sepol_security_id_t ssid;
+ sepol_security_id_t tsid;
+ sepol_security_class_t tclass;
+ sepol_access_vector_t av;
+};
+
+static struct avc_t *avc = NULL;
+
+static sidtab_t sidtab;
+
+static int load_booleans(const sepol_bool_t * boolean,
+ void *arg __attribute__ ((__unused__)))
+{
+ boollist[boolcnt] =
+ (struct boolean_t *)malloc(sizeof(struct boolean_t));
+ boollist[boolcnt]->name = strdup(sepol_bool_get_name(boolean));
+ boollist[boolcnt]->active = sepol_bool_get_value(boolean);
+ boolcnt++;
+ return 0;
+}
+
+static int check_booleans(struct avc_t *avc, struct boolean_t ***bools)
+{
+ char errormsg[PATH_MAX];
+ struct sepol_av_decision avd;
+ unsigned int reason;
+ int rc;
+ int i;
+ sepol_bool_key_t *key = NULL;
+ sepol_bool_t *boolean = NULL;
+ int fcnt = 0;
+ int *foundlist = calloc(boolcnt, sizeof(int));
+ if (!foundlist) {
+ PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
+ return fcnt;
+ }
+ for (i = 0; i < boolcnt; i++) {
+ char *name = boollist[i]->name;
+ int active = boollist[i]->active;
+ rc = sepol_bool_key_create(avc->handle, name, &key);
+ if (rc < 0) {
+ PyErr_SetString( PyExc_RuntimeError,
+ "Could not create boolean key.\n");
+ break;
+ }
+ rc = sepol_bool_query(avc->handle,
+ (sepol_policydb_t *) & avc->policydb,
+ key, &boolean);
+
+ if (rc < 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Could not find boolean %s.\n", name);
+ PyErr_SetString( PyExc_RuntimeError, errormsg);
+ break;
+ }
+
+ sepol_bool_set_value(boolean, !active);
+
+ rc = sepol_bool_set(avc->handle,
+ (sepol_policydb_t *) & avc->policydb,
+ key, boolean);
+ if (rc < 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Could not set boolean data %s.\n", name);
+ PyErr_SetString( PyExc_RuntimeError, errormsg);
+ break;
+ }
+
+ /* Reproduce the computation. */
+ rc = sepol_compute_av_reason(avc->ssid, avc->tsid, avc->tclass,
+ avc->av, &avd, &reason);
+ if (rc < 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Error during access vector computation, skipping...");
+ PyErr_SetString( PyExc_RuntimeError, errormsg);
+
+ sepol_bool_free(boolean);
+ break;
+ } else {
+ if (!reason) {
+ foundlist[fcnt] = i;
+ fcnt++;
+ }
+ sepol_bool_set_value((sepol_bool_t *) boolean, active);
+ rc = sepol_bool_set(avc->handle,
+ (sepol_policydb_t *) & avc->
+ policydb, key,
+ (sepol_bool_t *) boolean);
+ if (rc < 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Could not set boolean data %s.\n",
+ name);
+
+ PyErr_SetString( PyExc_RuntimeError, errormsg);
+ break;
+ }
+ }
+ sepol_bool_free(boolean);
+ sepol_bool_key_free(key);
+ key = NULL;
+ boolean = NULL;
+ }
+ if (key)
+ sepol_bool_key_free(key);
+
+ if (boolean)
+ sepol_bool_free(boolean);
+
+ if (fcnt > 0) {
+ *bools = (struct boolean_t **)
+ calloc(sizeof(struct boolean_t), fcnt + 1);
+ struct boolean_t *b = (struct boolean_t *) *bools;
+ for (i = 0; i < fcnt; i++) {
+ int ctr = foundlist[i];
+ b[i].name = strdup(boollist[ctr]->name);
+ b[i].active = !boollist[ctr]->active;
+ }
+ }
+ free(foundlist);
+ return fcnt;
+}
+
+static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args) {
+ PyObject *result = 0;
+
+ if (PyArg_ParseTuple(args,(char *)":finish")) {
+ int i = 0;
+ for (i = 0; i < boolcnt; i++) {
+ free(boollist[i]->name);
+ free(boollist[i]);
+ }
+ free(boollist);
+ sepol_sidtab_shutdown(&sidtab);
+ sepol_sidtab_destroy(&sidtab);
+ policydb_destroy(&avc->policydb);
+ sepol_handle_destroy(avc->handle);
+ free(avc);
+ avc = NULL;
+ boollist = NULL;
+ boolcnt = 0;
+
+ /* Boilerplate to return "None" */
+ Py_RETURN_NONE;
+ }
+ return result;
+}
+
+
+static int __policy_init(const char *init_path)
+{
+ FILE *fp;
+ int vers = 0;
+ char path[PATH_MAX];
+ char errormsg[PATH_MAX];
+ struct policy_file pf;
+ int rc;
+ unsigned int cnt;
+
+ if (init_path) {
+ strncpy(path, init_path, PATH_MAX);
+ fp = fopen(path, "r");
+ if (!fp) {
+ snprintf(errormsg, sizeof(errormsg),
+ "unable to open %s: %s\n",
+ path, strerror(errno));
+ PyErr_SetString( PyExc_ValueError, errormsg);
+ return 0; // trigger exception
+ }
+ } else {
+ vers = security_policyvers();
+ if (vers < 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Could not get policy version: %s\n",
+ strerror(errno));
+ PyErr_SetString( PyExc_ValueError, errormsg);
+ return 1;
+ }
+ snprintf(path, PATH_MAX, "%s.%d",
+ selinux_binary_policy_path(), vers);
+ fp = fopen(path, "r");
+ while (!fp && errno == ENOENT && --vers) {
+ snprintf(path, PATH_MAX, "%s.%d",
+ selinux_binary_policy_path(), vers);
+ fp = fopen(path, "r");
+ }
+ if (!fp) {
+ snprintf(errormsg, sizeof(errormsg),
+ "unable to open %s.%d: %s\n",
+ selinux_binary_policy_path(),
+ security_policyvers(), strerror(errno));
+ PyErr_SetString( PyExc_ValueError, errormsg);
+ return 1;
+ }
+ }
+
+ avc = calloc(sizeof(struct avc_t), 1);
+ if (!avc) {
+ PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
+ return 1;
+ }
+
+ /* Set up a policydb directly so that we can mutate it later
+ for booleans and user settings. Otherwise we would just use
+ sepol_set_policydb_from_file() here. */
+ pf.fp = fp;
+ pf.type = PF_USE_STDIO;
+ if (policydb_init(&avc->policydb)) {
+ snprintf(errormsg, sizeof(errormsg),
+ "policydb_init failed: %s\n", strerror(errno));
+ PyErr_SetString( PyExc_RuntimeError, errormsg);
+ fclose(fp);
+ return 1;
+ }
+ if (policydb_read(&avc->policydb, &pf, 0)) {
+ snprintf(errormsg, sizeof(errormsg),
+ "invalid binary policy %s\n", path);
+ PyErr_SetString( PyExc_ValueError, errormsg);
+ fclose(fp);
+ return 1;
+ }
+ fclose(fp);
+ sepol_set_policydb(&avc->policydb);
+ if (!init_path) {
+ /* If they didn't specify a full path of a binary policy file,
+ then also try loading any boolean settings and user
+ definitions from the active locations. Otherwise,
+ they can use genpolbools and genpolusers to build a
+ binary policy file that includes any desired settings
+ and then apply audit2why -p to the resulting file.
+ Errors are non-fatal as such settings are optional. */
+ sepol_debug(0);
+ (void)sepol_genbools_policydb(&avc->policydb,
+ selinux_booleans_path());
+ (void)sepol_genusers_policydb(&avc->policydb,
+ selinux_users_path());
+ }
+ avc->handle = sepol_handle_create();
+
+ rc = sepol_bool_count(avc->handle,
+ (sepol_policydb_t *) & avc->policydb, &cnt);
+ if (rc < 0) {
+ PyErr_SetString( PyExc_RuntimeError, "unable to get bool count\n");
+ return 1;
+ }
+
+ boollist = calloc(cnt, sizeof(struct boolean_t));
+ if (!boollist) {
+ PyErr_SetString( PyExc_MemoryError, "Out of memory\n");
+ return 1;
+ }
+
+ sepol_bool_iterate(avc->handle,
+ (const sepol_policydb_t *)&avc->policydb,
+ load_booleans, (void *)NULL);
+
+ /* Initialize the sidtab for subsequent use by sepol_context_to_sid
+ and sepol_compute_av_reason. */
+ rc = sepol_sidtab_init(&sidtab);
+ if (rc < 0) {
+ PyErr_SetString( PyExc_RuntimeError, "unable to init sidtab\n");
+ free(boollist);
+ return 1;
+ }
+ sepol_set_sidtab(&sidtab);
+ return 0;
+}
+
+static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) {
+ int result;
+ char *init_path=NULL;
+ if (PyArg_ParseTuple(args,(char *)"|s:policy_init",&init_path))
+ result = __policy_init(init_path);
+ return Py_BuildValue("i", result);
+}
+
+#define RETURN(X) \
+ PyTuple_SetItem(result, 0, Py_BuildValue("i", X)); \
+ return result;
+
+static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) {
+ security_context_t scon;
+ security_context_t tcon;
+ char *tclassstr;
+ PyObject *listObj;
+ PyObject *strObj;
+ int numlines;
+ struct boolean_t **bools;
+ unsigned int reason;
+ sepol_security_id_t ssid, tsid;
+ sepol_security_class_t tclass;
+ sepol_access_vector_t perm, av;
+ struct sepol_av_decision avd;
+ int rc;
+ int i=0;
+ PyObject *result = PyTuple_New(2);
+ if (!result) return NULL;
+ Py_INCREF(Py_None);
+ PyTuple_SetItem(result, 1, Py_None);
+
+ if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj))
+ return NULL;
+
+ /* get the number of lines passed to us */
+ numlines = PyList_Size(listObj);
+
+ /* should raise an error here. */
+ if (numlines < 0) return NULL; /* Not a list */
+
+ if (!avc) {
+ RETURN(NOPOLICY)
+ }
+
+ rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid);
+ if (rc < 0) {
+ RETURN(BADSCON)
+ }
+ rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
+ if (rc < 0) {
+ RETURN(BADTCON)
+ }
+ tclass = string_to_security_class(tclassstr);
+ if (!tclass) {
+ RETURN(BADTCLASS)
+ }
+ /* Convert the permission list to an AV. */
+ av = 0;
+
+ /* iterate over items of the list, grabbing strings, and parsing
+ for numbers */
+ for (i=0; i<numlines; i++){
+ char *permstr;
+
+ /* grab the string object from the next element of the list */
+ strObj = PyList_GetItem(listObj, i); /* Can't fail */
+
+ /* make it a string */
+ permstr = PyString_AsString( strObj );
+
+ perm = string_to_av_perm(tclass, permstr);
+ if (!perm) {
+ RETURN(BADPERM)
+ }
+ av |= perm;
+ }
+
+ /* Reproduce the computation. */
+ rc = sepol_compute_av_reason(ssid, tsid, tclass, av, &avd, &reason);
+ if (rc < 0) {
+ RETURN(BADCOMPUTE)
+ }
+
+ if (!reason) {
+ RETURN(ALLOW)
+ }
+ if (reason & SEPOL_COMPUTEAV_TE) {
+ avc->ssid = ssid;
+ avc->tsid = tsid;
+ avc->tclass = tclass;
+ avc->av = av;
+ if (check_booleans(avc, &bools) == 0) {
+ if (av & ~avd.auditdeny) {
+ RETURN(DONTAUDIT)
+ } else {
+ RETURN(TERULE)
+ }
+ } else {
+ PyTuple_SetItem(result, 0, Py_BuildValue("i", BOOLEAN));
+ struct boolean_t *b=(struct boolean_t *) bools;
+ int len=0;
+ while (b->name) {
+ len++; b++;
+ }
+ b = (struct boolean_t *) bools;
+ PyObject *boollist = PyTuple_New(len);
+ len=0;
+ while(b->name) {
+ PyObject *bool = Py_BuildValue("(si)", b->name, b->active);
+ PyTuple_SetItem(boollist, len++, bool);
+ b++;
+ }
+ free(bools);
+ PyTuple_SetItem(result, 1, boollist);
+ return result;
+ }
+ }
+
+ if (reason & SEPOL_COMPUTEAV_CONS) {
+ RETURN(CONSTRAINT);
+ }
+
+ if (reason & SEPOL_COMPUTEAV_RBAC) {
+ RETURN(RBAC)
+ }
+ RETURN(BADCOMPUTE)
+}
+
+static PyMethodDef audit2whyMethods[] = {
+ {"init", init, METH_VARARGS,
+ "Initialize policy database."},
+ {"analyze", analyze, METH_VARARGS,
+ "Analyze AVC."},
+ {"finish", finish, METH_VARARGS,
+ "Finish using policy, free memory."},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC
+initaudit2why(void)
+{
+ PyObject *m = Py_InitModule("audit2why", audit2whyMethods);
+ PyModule_AddIntConstant(m,"UNKNOWN", UNKNOWN);
+ PyModule_AddIntConstant(m,"BADSCON", BADSCON);
+ PyModule_AddIntConstant(m,"BADTCON", BADTCON);
+ PyModule_AddIntConstant(m,"BADTCLASS", BADTCLASS);
+ PyModule_AddIntConstant(m,"BADPERM", BADPERM);
+ PyModule_AddIntConstant(m,"BADCOMPUTE", BADCOMPUTE);
+ PyModule_AddIntConstant(m,"NOPOLICY", NOPOLICY);
+ PyModule_AddIntConstant(m,"ALLOW", ALLOW);
+ PyModule_AddIntConstant(m,"DONTAUDIT", DONTAUDIT);
+ PyModule_AddIntConstant(m,"TERULE", TERULE);
+ PyModule_AddIntConstant(m,"BOOLEAN", BOOLEAN);
+ PyModule_AddIntConstant(m,"CONSTRAINT", CONSTRAINT);
+ PyModule_AddIntConstant(m,"RBAC", RBAC);
+}
diff --exclude-from=exclude -N -u -r nsalibselinux/src/Makefile libselinux-2.0.47/src/Makefile
--- nsalibselinux/src/Makefile 2008-01-11 10:52:37.000000000 -0500
+++ libselinux-2.0.47/src/Makefile 2008-01-23 14:19:11.000000000 -0500
@@ -18,6 +18,7 @@
SWIGSO=_selinux.so
SWIGFILES=$(SWIGSO) selinux.py
LIBSO=$(TARGET).$(LIBVERSION)
+AUDIT2WHYSO=audit2why.so
ifeq ($(DISABLE_AVC),y)
UNUSED_SRCS+=avc.c avc_internal.c avc_sidtab.c mapping.c stringrep.c checkAccess.c
@@ -28,7 +29,7 @@
ifeq ($(DISABLE_RPM),y)
UNUSED_SRCS+=rpm.c
endif
-SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out $(SWIGCOUT),$(wildcard *.c)))
+SRCS= $(filter-out $(UNUSED_SRCS), $(filter-out audit2why.c $(SWIGCOUT),$(wildcard *.c)))
OBJS= $(patsubst %.c,%.o,$(SRCS))
LOBJS= $(patsubst %.c,%.lo,$(SRCS))
@@ -47,7 +48,7 @@
all: $(LIBA) $(LIBSO)
-pywrap: all $(SWIGSO)
+pywrap: all $(SWIGSO) $(AUDIT2WHYSO)
$(LIBA): $(OBJS)
$(AR) rcs $@ $^
@@ -63,6 +64,12 @@
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -ldl -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
ln -sf $@ $(TARGET)
+audit2why.lo: audit2why.c
+ $(CC) $(CFLAGS) -I$(PYINC) -fPIC -DSHARED -c -o $@ $<
+
+$(AUDIT2WHYSO): audit2why.lo
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -L. -lselinux ${LIBDIR}/libsepol.a -L$(LIBDIR) -Wl,-soname,$@
+
%.o: %.c policy.h
$(CC) $(CFLAGS) $(TLSFLAGS) -c -o $@ $<
@@ -83,14 +90,16 @@
cd $(LIBDIR) && ln -sf ../../`basename $(SHLIBDIR)`/$(LIBSO) $(TARGET)
install-pywrap: pywrap
- test -d $(PYTHONLIBDIR)/site-packages || install -m 755 -d $(PYTHONLIBDIR)/site-packages
- install -m 755 $(SWIGFILES) $(PYTHONLIBDIR)/site-packages
+ test -d $(PYTHONLIBDIR)/site-packages/selinux || install -m 755 -d $(PYTHONLIBDIR)/site-packages/selinux
+ install -m 755 $(SWIGSO) $(PYTHONLIBDIR)/site-packages/selinux
+ install -m 755 $(AUDIT2WHYSO) $(PYTHONLIBDIR)/site-packages/selinux
+ install -m 644 selinux.py $(PYTHONLIBDIR)/site-packages/selinux/__init__.py
relabel:
/sbin/restorecon $(SHLIBDIR)/$(LIBSO)
clean:
- -rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET)
+ -rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) $(AUDIT2WHYSO) *.o *.lo *~
distclean: clean
rm -f $(SWIGCOUT) $(SWIGFILES)
diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-2.0.47/src/matchpathcon.c
diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux-2.0.48/src/matchpathcon.c
--- nsalibselinux/src/matchpathcon.c 2007-09-28 09:48:58.000000000 -0400
+++ libselinux-2.0.47/src/matchpathcon.c 2008-01-11 10:55:14.000000000 -0500
+++ libselinux-2.0.48/src/matchpathcon.c 2008-01-23 14:39:58.000000000 -0500
@@ -2,6 +2,7 @@
#include <string.h>
#include <errno.h>
@ -556,9 +30,9 @@ diff --exclude-from=exclude -N -u -r nsalibselinux/src/matchpathcon.c libselinux
va_end(ap);
}
diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig.i libselinux-2.0.47/src/selinuxswig.i
diff --exclude-from=exclude -N -u -r nsalibselinux/src/selinuxswig.i libselinux-2.0.48/src/selinuxswig.i
--- nsalibselinux/src/selinuxswig.i 2008-01-23 14:36:29.000000000 -0500
+++ libselinux-2.0.47/src/selinuxswig.i 2008-01-11 10:55:14.000000000 -0500
+++ libselinux-2.0.48/src/selinuxswig.i 2008-01-23 14:39:58.000000000 -0500
@@ -14,6 +14,7 @@
%typedef unsigned mode_t;

View File

@ -3,7 +3,7 @@
Summary: SELinux library and simple utilities
Name: libselinux
Version: 2.0.48
Version: 2.0.49
Release: 1%{?dist}
License: Public Domain
Group: System Environment/Libraries
@ -137,6 +137,9 @@ exit 0
%{python_sitearch}/selinux/*
%changelog
* Wed Jan 23 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.49-1
* Merged audit2why python binding from Dan Walsh.
* Wed Jan 23 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.48-1
* Merged updated swig bindings from Dan Walsh, including typemap for pid_t.

View File

@ -1 +1 @@
d2909d07d752287a219155a604e2d175 libselinux-2.0.48.tgz
3095b464e36ad44f559b7540385972ed libselinux-2.0.49.tgz