Implement MLS level lookup.

This commit is contained in:
Chris PeBenito 2015-02-21 15:09:52 -05:00
parent 880582fe73
commit 2dd517b4b3
4 changed files with 229 additions and 9 deletions
libqpol
setools/policyrep

View File

@ -38,6 +38,7 @@ extern "C"
typedef struct qpol_cat qpol_cat_t; typedef struct qpol_cat qpol_cat_t;
typedef struct qpol_mls_range qpol_mls_range_t; typedef struct qpol_mls_range qpol_mls_range_t;
typedef struct qpol_mls_level qpol_mls_level_t; typedef struct qpol_mls_level qpol_mls_level_t;
typedef struct qpol_semantic_level qpol_semantic_level_t;
#include <qpol/iterator.h> #include <qpol/iterator.h>
#include <qpol/policy.h> #include <qpol/policy.h>
@ -253,6 +254,11 @@ extern "C"
extern int qpol_mls_level_get_cat_iter(const qpol_policy_t * policy, const qpol_mls_level_t * level, extern int qpol_mls_level_get_cat_iter(const qpol_policy_t * policy, const qpol_mls_level_t * level,
qpol_iterator_t ** cats); qpol_iterator_t ** cats);
/* semantic levels */
extern int qpol_policy_get_semantic_level_by_name(const qpol_policy_t * policy, const char *name, const qpol_semantic_level_t ** datum);
extern int qpol_semantic_level_add_cats_by_name(const qpol_policy_t * policy, const qpol_semantic_level_t * level, const char *low, const char *high);
extern int qpol_mls_level_from_semantic_level(const qpol_policy_t * policy, const qpol_semantic_level_t * src, qpol_mls_level_t **dest);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -6,7 +6,7 @@
* @author Jeremy A. Mowery jmowery@tresys.com * @author Jeremy A. Mowery jmowery@tresys.com
* @author Jason Tang jtang@tresys.com * @author Jason Tang jtang@tresys.com
* *
* Copyright (C) 2006-2007 Tresys Technology, LLC * Copyright (C) 2006-2007. 2015 Tresys Technology, LLC
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -637,3 +637,139 @@ int qpol_mls_level_get_cat_iter(const qpol_policy_t * policy, const qpol_mls_lev
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
int qpol_mls_level_from_semantic_level(const qpol_policy_t * policy, const qpol_semantic_level_t * src, qpol_mls_level_t **dest)
{
policydb_t *db = NULL;
mls_semantic_level_t *internal_semantic = NULL;
mls_level_t *internal_level = NULL;
if (policy == NULL || src == NULL || dest == NULL) {
ERR(policy, "%s", strerror(EINVAL));
errno = EINVAL;
*dest = NULL;
return STATUS_ERR;
}
internal_semantic = (mls_semantic_level_t*) src;
db = &policy->p->p;
internal_level = malloc(sizeof(mls_level_t));
if (!internal_level) {
return STATUS_ERR;
}
mls_level_init(internal_level);
if(mls_semantic_level_expand(internal_semantic, internal_level, db, policy->sh) < 0) {
mls_level_destroy(internal_level);
free(internal_level);
errno = EINVAL;
*dest = NULL;
return STATUS_ERR;
}
*dest = (qpol_mls_level_t*) internal_level;
return STATUS_SUCCESS;
}
/* semantic level */
int qpol_policy_get_semantic_level_by_name(const qpol_policy_t * policy, const char *name, const qpol_semantic_level_t ** datum)
{
policydb_t *db = NULL;
hashtab_datum_t internal_datum = NULL;
mls_semantic_level_t *internal_semantic = NULL;
if (policy == NULL || name == NULL || datum == NULL) {
if (datum != NULL)
*datum = NULL;
ERR(policy, "%s", strerror(EINVAL));
errno = EINVAL;
return STATUS_ERR;
}
internal_semantic = malloc(sizeof(mls_semantic_level_t));
if (!internal_semantic) {
return STATUS_ERR;
}
mls_semantic_level_init(internal_semantic);
db = &policy->p->p;
internal_datum = hashtab_search(db->p_levels.table, (hashtab_key_t)name);
if (internal_datum == NULL) {
mls_semantic_level_destroy(internal_semantic);
free(internal_semantic);
*datum = NULL;
ERR(policy, "could not find datum for level %s", name);
errno = ENOENT;
return STATUS_ERR;
}
internal_semantic->sens = ((level_datum_t*)internal_datum)->level->sens;
*datum = (qpol_semantic_level_t *) internal_semantic;
return STATUS_SUCCESS;
}
int qpol_semantic_level_add_cats_by_name(const qpol_policy_t * policy, const qpol_semantic_level_t * level, const char *low, const char *high)
{
hashtab_datum_t internal_datum;
policydb_t *db = NULL;
mls_semantic_level_t *internal_level = NULL;
mls_semantic_cat_t *internal_cat = NULL;
if (policy == NULL || level == NULL || low == NULL || high == NULL) {
ERR(policy, "%s", strerror(EINVAL));
errno = EINVAL;
return STATUS_ERR;
}
internal_cat = malloc(sizeof(mls_semantic_cat_t));
if (!internal_cat) {
return STATUS_ERR;
}
mls_semantic_cat_init(internal_cat);
db = &policy->p->p;
internal_level = (mls_semantic_level_t*) level;
internal_datum = hashtab_search(db->p_cats.table, (hashtab_key_t)low);
if (internal_datum == NULL) {
ERR(policy, "could not find datum for cat %s", low);
goto err;
}
internal_cat->low = ((cat_datum_t*)internal_datum)->s.value;
internal_datum = hashtab_search(db->p_cats.table, (hashtab_key_t)high);
if (internal_datum == NULL) {
ERR(policy, "could not find datum for cat %s", high);
goto err;
}
internal_cat->high = ((cat_datum_t*)internal_datum)->s.value;
if (internal_cat->low > internal_cat->high) {
ERR(policy, "invalid semantic category range: %s.%s", low, high);
goto err;
}
if (!(internal_level->cat)) {
internal_level->cat = internal_cat;
} else {
mls_semantic_cat_t *curr = internal_level->cat;
while(curr->next) {
curr = curr->next;
}
curr->next = internal_cat;
}
return STATUS_SUCCESS;
err:
mls_semantic_cat_destroy(internal_cat);
free(internal_cat);
errno = ENOENT;
return STATUS_ERR;
}

View File

@ -84,10 +84,47 @@ def level_factory(policy, symbol):
Factory function for creating MLS level objects (e.g. levels used Factory function for creating MLS level objects (e.g. levels used
in contexts of labeling statements) in contexts of labeling statements)
""" """
if not isinstance(symbol, qpol.qpol_mls_level_t): if isinstance(symbol, qpol.qpol_mls_level_t):
raise TypeError("MLS levels cannot be looked-up.") return MLSLevel(policy, symbol)
return MLSLevel(policy, symbol) # parse the level string and construct a semantic representation
sens_split = symbol.split(":")
sens = sens_split[0]
try:
semantic_level = qpol.qpol_semantic_level_t(policy, sens)
except ValueError:
raise InvalidLevel("{0} is not a valid sensitivity".format(sens))
try:
cats = sens_split[1]
except IndexError:
pass
else:
for group in cats.split(","):
catrange = group.split(".")
if len(catrange) == 2:
try:
semantic_level.add_cats(policy, catrange[0], catrange[1])
except ValueError:
raise InvalidLevel("{0} is not a valid category range".format(group))
elif len(catrange) == 1:
try:
semantic_level.add_cats(policy, catrange[0], catrange[0])
except ValueError:
raise InvalidLevel("{0} is not a valid category".format(group))
else:
# may not be possible to get here
raise InvalidLevel("{0} is not a valid category range".format(group))
# convert to level object
try:
policy_level = qpol.qpol_mls_level_t(policy, semantic_level)
except ValueError:
raise InvalidLevel("{0} is not a valid level".format(symbol))
return MLSLevel(policy, policy_level)
def level_decl_factory(policy, symbol): def level_decl_factory(policy, symbol):

View File

@ -1561,16 +1561,57 @@ typedef struct qpol_mls_range {} qpol_mls_range_t;
}; };
%} %}
/* qpol semantic mls level */
typedef struct qpol_semantic_level {} qpol_semantic_level_t;
%extend qpol_semantic_level {
%exception qpol_semantic_level {
$action
if (!result) {
PyErr_SetString(PyExc_ValueError, "Invalid sensitivity name.");
return NULL;
}
}
qpol_semantic_level(qpol_policy_t *p, const char *name) {
const qpol_semantic_level_t *l;
qpol_policy_get_semantic_level_by_name(p, name, &l);
return (qpol_semantic_level_t*)l;
};
~qpol_semantic_level() {
/* mls_semantic_level_destroy(self); */
return;
};
%exception add_cats {
$action
if (result) {
PyErr_SetString(PyExc_ValueError, "Invalid category name or category range.");
return NULL;
}
}
int add_cats(qpol_policy_t *p, const char *low, const char *high) {
return qpol_semantic_level_add_cats_by_name(p, self, low, high);
}
};
/* qpol mls level */ /* qpol mls level */
typedef struct qpol_mls_level {} qpol_mls_level_t; typedef struct qpol_mls_level {} qpol_mls_level_t;
%extend qpol_mls_level { %extend qpol_mls_level {
qpol_mls_level() { %exception qpol_mls_level {
BEGIN_EXCEPTION $action
SWIG_exception(SWIG_RuntimeError, "Cannot directly create qpol_mls_level_t objects"); if (!result) {
END_EXCEPTION PyErr_SetString(PyExc_ValueError, "Invalid level.");
fail:
return NULL; return NULL;
}
} }
qpol_mls_level(qpol_policy_t *p, qpol_semantic_level_t *l) {
qpol_mls_level_t *level;
qpol_mls_level_from_semantic_level(p, l, &level);
return level;
}
~qpol_mls_level() { ~qpol_mls_level() {
/* no op */ /* no op */
return; return;