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

View File

@ -38,6 +38,7 @@ extern "C"
typedef struct qpol_cat qpol_cat_t;
typedef struct qpol_mls_range qpol_mls_range_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/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,
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
}
#endif

View File

@ -6,7 +6,7 @@
* @author Jeremy A. Mowery jmowery@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
* 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;
}
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
in contexts of labeling statements)
"""
if not isinstance(symbol, qpol.qpol_mls_level_t):
raise TypeError("MLS levels cannot be looked-up.")
if isinstance(symbol, qpol.qpol_mls_level_t):
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):

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 */
typedef struct qpol_mls_level {} qpol_mls_level_t;
%extend qpol_mls_level {
qpol_mls_level() {
BEGIN_EXCEPTION
SWIG_exception(SWIG_RuntimeError, "Cannot directly create qpol_mls_level_t objects");
END_EXCEPTION
fail:
%exception qpol_mls_level {
$action
if (!result) {
PyErr_SetString(PyExc_ValueError, "Invalid level.");
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() {
/* no op */
return;