mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-01 22:58:12 +00:00
Implement MLS level lookup.
This commit is contained in:
parent
880582fe73
commit
2dd517b4b3
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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):
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user