diff options
Diffstat (limited to 'libapol/tests')
-rw-r--r-- | libapol/tests/Makefile.am | 23 | ||||
-rw-r--r-- | libapol/tests/avrule-tests.c | 161 | ||||
-rw-r--r-- | libapol/tests/avrule-tests.h | 35 | ||||
-rw-r--r-- | libapol/tests/constrain-tests.c | 523 | ||||
-rw-r--r-- | libapol/tests/constrain-tests.h | 33 | ||||
-rw-r--r-- | libapol/tests/dta-tests.c | 529 | ||||
-rw-r--r-- | libapol/tests/dta-tests.h | 35 | ||||
-rw-r--r-- | libapol/tests/infoflow-tests.c | 127 | ||||
-rw-r--r-- | libapol/tests/infoflow-tests.h | 36 | ||||
-rw-r--r-- | libapol/tests/libapol-tests.c | 64 | ||||
-rw-r--r-- | libapol/tests/policy-21-tests.c | 181 | ||||
-rw-r--r-- | libapol/tests/policy-21-tests.h | 35 | ||||
-rw-r--r-- | libapol/tests/role-tests.c | 154 | ||||
-rw-r--r-- | libapol/tests/role-tests.h | 35 | ||||
-rw-r--r-- | libapol/tests/terule-tests.c | 130 | ||||
-rw-r--r-- | libapol/tests/terule-tests.h | 35 | ||||
-rw-r--r-- | libapol/tests/user-tests.c | 159 | ||||
-rw-r--r-- | libapol/tests/user-tests.h | 35 |
18 files changed, 2330 insertions, 0 deletions
diff --git a/libapol/tests/Makefile.am b/libapol/tests/Makefile.am new file mode 100644 index 0000000..ed5005e --- /dev/null +++ b/libapol/tests/Makefile.am @@ -0,0 +1,23 @@ +TESTS = libapol-tests +check_PROGRAMS = libapol-tests + +libapol_tests_SOURCES = \ + avrule-tests.c avrule-tests.h \ + dta-tests.c dta-tests.h \ + infoflow-tests.c infoflow-tests.h \ + policy-21-tests.c policy-21-tests.h \ + role-tests.c role-tests.h \ + terule-tests.c terule-tests.h \ + user-tests.c user-tests.h \ + constrain-tests.c constrain-tests.h \ + ../../libqpol/src/queue.c ../../libqpol/src/queue.h \ + libapol-tests.c + +AM_CFLAGS = @DEBUGCFLAGS@ @WARNCFLAGS@ @PROFILECFLAGS@ @SELINUX_CFLAGS@ \ + @QPOL_CFLAGS@ @APOL_CFLAGS@ -DTOP_SRCDIR="\"$(top_srcdir)\"" + +AM_LDFLAGS = @DEBUGLDFLAGS@ @WARNLDFLAGS@ @PROFILELDFLAGS@ + +LDADD = @SELINUX_LIB_FLAG@ @APOL_LIB_FLAG@ @QPOL_LIB_FLAG@ @CUNIT_LIB_FLAG@ + +libapol_tests_DEPENDENCIES = ../src/libapol.so diff --git a/libapol/tests/avrule-tests.c b/libapol/tests/avrule-tests.c new file mode 100644 index 0000000..f86bbe2 --- /dev/null +++ b/libapol/tests/avrule-tests.c @@ -0,0 +1,161 @@ +/** + * @file + * + * Test the AV rule queries, both semantic and syntactic searches. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/avrule-query.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <qpol/policy_extend.h> +#include <stdbool.h> + +#define BIN_POLICY TEST_POLICIES "/setools-3.3/rules/rules-mls.21" +#define SOURCE_POLICY TEST_POLICIES "/setools-3.3/rules/rules-mls.conf" + +static apol_policy_t *bp = NULL; +static apol_policy_t *sp = NULL; + +static void avrule_basic_syn(void) +{ + apol_avrule_query_t *aq = apol_avrule_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(aq); + + int retval; + retval = apol_avrule_query_set_rules(sp, aq, QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_syn_avrule_get_by_query(sp, aq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + + size_t num_auditallows = 0, num_dontaudits = 0; + + qpol_policy_t *q = apol_policy_get_qpol(sp); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const qpol_syn_avrule_t *syn = (const qpol_syn_avrule_t *)apol_vector_get_element(v, i); + uint32_t rule_type; + retval = qpol_syn_avrule_get_rule_type(q, syn, &rule_type); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + CU_ASSERT(rule_type == QPOL_RULE_AUDITALLOW || rule_type == QPOL_RULE_DONTAUDIT); + if (rule_type == QPOL_RULE_AUDITALLOW) { + num_auditallows++; + } else if (rule_type == QPOL_RULE_DONTAUDIT) { + num_dontaudits++; + } + } + CU_ASSERT(num_auditallows == 4 && num_dontaudits == 1); + apol_vector_destroy(&v); + + retval = apol_avrule_query_append_class(sp, aq, "unknown class"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + retval = apol_syn_avrule_get_by_query(sp, aq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + apol_avrule_query_destroy(&aq); +} + +static void avrule_default(void) +{ + apol_avrule_query_t *aq = apol_avrule_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(aq); + + int retval; + qpol_policy_t *sq = apol_policy_get_qpol(sp); + + apol_vector_t *v = NULL; + + retval = apol_avrule_get_by_query(sp, aq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) == 396); + apol_vector_destroy(&v); + + qpol_policy_rebuild(sq, QPOL_POLICY_OPTION_NO_NEVERALLOWS); + retval = apol_avrule_get_by_query(sp, aq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) == 21); + apol_vector_destroy(&v); + + retval = apol_avrule_get_by_query(bp, aq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) == 21); + apol_vector_destroy(&v); + + apol_avrule_query_destroy(&aq); +} + +CU_TestInfo avrule_tests[] = { + {"basic syntactic search", avrule_basic_syn} + , + {"default query", avrule_default} + , + CU_TEST_INFO_NULL +}; + +int avrule_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, BIN_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((bp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, SOURCE_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((sp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(sp)) != 0) { + return 1; + } + + return 0; +} + +int avrule_cleanup() +{ + apol_policy_destroy(&bp); + apol_policy_destroy(&sp); + return 0; +} diff --git a/libapol/tests/avrule-tests.h b/libapol/tests/avrule-tests.h new file mode 100644 index 0000000..f56ab25 --- /dev/null +++ b/libapol/tests/avrule-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol avrule query tests. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVRULE_TESTS_H +#define AVRULE_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo avrule_tests[]; +extern int avrule_init(); +extern int avrule_cleanup(); + +#endif diff --git a/libapol/tests/constrain-tests.c b/libapol/tests/constrain-tests.c new file mode 100644 index 0000000..3133b5d --- /dev/null +++ b/libapol/tests/constrain-tests.c @@ -0,0 +1,523 @@ +/** + * @file + * + * Test the information flow analysis code. + * + * + * Copyright (C) 2010 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdio.h> +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/perm-map.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <stdbool.h> +#include <string.h> +#include <apol/constraint-query.h> +#include <sepol/policydb/policydb.h> +#include <sepol/policydb/constraint.h> +#include <libqpol/src/queue.h> + +#define CONSTR_SOURCE TEST_POLICIES "/setools-3.3/apol/constrain_test_policy.conf" +#define CONSTR_BINARY TEST_POLICIES "/setools-3.3/apol/constrain_test_policy.21" +// Glob won't work, but this gives the idea of where we are trying to go +#define CONSTR_MODULAR TEST_POLICIES "/setools-3.1/modules/*.pp" + +//#define DEBUGTRACE 1 + + +/* General concepts: The constraints are stored in the policy by class, + * that is, the list of classes stored in the policy has attached to it + * whatever constraints affect that class. + * The "policy_iter" iterator is a structure which contains a pointer to the + * list of classes from the loaded policy, and another pointer to the list of + * constraints associated with the current class. This latter pointer is + * traversed to its end, at which point the class pointer is updated, and the + * new class' list of constraints is put in its place. The switch from one + * class to the next is done behind the scenes by the iterator. Thus each time + * a new item is retrieved from policy_iter, it needs to have all info (class, + * permissions, expression) extracted from it. + * + * The input file must be a known file. The class and permissions are used as + * a key by this test routine to determine what the expected expression will + * be. Thus, if the input file is modified, this test becomes invalid. The file + * (defined above) resides in the 'testing-policies' repository. + * + * The statements validatetrans and mlsvalidatetrans, although similar to + * constrain and mlsconstrain, are not considered here. + * + */ + +// Define data for expected policy. This is a hack, but what I could think of +// on short notice. + +// Similar to struct constraint_expr from sepol/policydb/constraint.h +// but want char * list of names, not internal representations. +typedef struct local_expr { + uint32_t expr_type; + uint32_t attr; + uint32_t op; + size_t name_count; + char **namelist; +} local_expr_t; + +typedef struct constrain_test_list { + char **class; + char **permissions; // Must end with NULL + int test_found; + int expr_count; + local_expr_t **expr_list; +} constrain_test_list_t; + +// TODO Clean up memory leaks -- all iterators need to be destroyed, check other stuff + + +char *class0 = "file"; +char *perm0[] = { "create", "relabelto", NULL }; +local_expr_t expr00 = { CEXPR_ATTR, CEXPR_L2H2, CEXPR_EQ, 0, NULL }; +local_expr_t *expr0[] = { &expr00, NULL }; + +char *class1 = "lnk_file"; +char *perm1[10] = { "create", "relabelto", NULL }; +local_expr_t expr10 = { CEXPR_ATTR, CEXPR_L2H2, CEXPR_NEQ, 0, NULL }; +local_expr_t *expr1[] = { &expr10, NULL }; + +// This test (test 2) is not expected to be matched +char *class2 = "fifo_file"; +char *perm2[] = { "create", "relabelto", NULL }; +local_expr_t expr20 = { CEXPR_ATTR, CEXPR_L2H2, CEXPR_DOM, 0, NULL }; +local_expr_t *expr2[] = { &expr20, NULL }; + +char *class3 = "node"; +char *perm3[] = { "udp_send", NULL }; +local_expr_t expr30 = { CEXPR_ATTR, CEXPR_L1L2, CEXPR_DOM, 0, NULL }; +local_expr_t expr31 = { CEXPR_ATTR, CEXPR_L1H2, CEXPR_DOMBY, 0, NULL }; +local_expr_t expr32 = { CEXPR_AND, 0, 0, 0, NULL }; +local_expr_t *expr3[] = { &expr30, &expr31, &expr32, NULL }; + +char *class4 = "netif"; +char *perm4[] = { "tcp_send", NULL }; +local_expr_t expr40 = { CEXPR_ATTR, CEXPR_L1L2, CEXPR_DOM, 0, NULL }; +local_expr_t expr41 = { CEXPR_ATTR, CEXPR_L1H2, CEXPR_DOMBY, 0, NULL }; +local_expr_t expr42 = { CEXPR_OR, 0, 0, 0, NULL }; +local_expr_t *expr4[] = { &expr40, &expr41, &expr42, NULL }; + +char *class5 = "dir"; +char *perm5[] = { "read", NULL }; +char *name50[] = { "sysadm_t", "secadm_t", NULL }; +local_expr_t expr50 = { CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ, 2, name50 }; +local_expr_t *expr5[] = { &expr50, NULL }; + +constrain_test_list_t test_list[] = { + { &class0, perm0, 0, 1, expr0 }, + { &class1, perm1, 0, 1, expr1 }, + { &class2, perm2, 0, 1, expr2 }, + { &class3, perm3, 0, 3, expr3 }, + { &class4, perm4, 0, 3, expr4 }, + { &class5, perm5, 0, 3, expr5 } +}; + +typedef struct compare_perm_str { + int list_length; + int list_found; + int q_elements_compared; + char **list; +} compare_perm_str_t; + +typedef struct compare_expr_str { + int list_length; + int list_found; + local_expr_t **list; +} compare_expr_str_t; + + +static apol_policy_t *ps = NULL; // Source policy +static apol_policy_t *pb = NULL; // Binary policy +static apol_policy_t *pm = NULL; // Modular policy + + +// Prototypes if needed +static int compare_item_to_list(void *e, void *v); + + + + +static int doprintstr (queue_element_t e, void *p) +{ + char *s = (char *)e; + // Second arg is not used + + printf ("%s ", s); + return 0; +} + +static int compare_expr_list(qpol_policy_t *q, qpol_iterator_t *expr_iter, int expr_count, local_expr_t **le) +{ + const qpol_constraint_expr_node_t *expr; + int sym_type; + int op; + int expr_type; + int i; + int err; + + for (i=0; qpol_iterator_end(expr_iter) == 0; i++, qpol_iterator_next(expr_iter)) + { + expr_type = op = sym_type = 0; + if (i >= expr_count) // Hit the end of the list + return 1; // Not the right list + + err = qpol_iterator_get_item(expr_iter, (void **)&expr); + CU_ASSERT_EQUAL_FATAL(err, 0); + + err = qpol_constraint_expr_node_get_sym_type(q, expr, &sym_type); + CU_ASSERT_EQUAL_FATAL(err, 0); + + err = qpol_constraint_expr_node_get_op(q, expr, &op); + CU_ASSERT_EQUAL_FATAL(err, 0); + + err = qpol_constraint_expr_node_get_expr_type(q, expr, &expr_type); + CU_ASSERT_EQUAL_FATAL(err, 0); + +#ifdef DEBUGTRACE + printf ("Expr compare: Policy:attr:%d, op:%d, expr_type:%d\n", sym_type, op, expr_type); + printf ("Expr compare: Test:attr:%d, op:%d, expr_type:%d\n", le[i]->attr, le[i]->op, le[i]->expr_type); +#endif + if (sym_type != le[i]->attr) + { + return 1; + } + if (op != le[i]->op) + { + return 1; + } + if (expr_type != le[i]->expr_type) + { + return 1; + } + + if (expr_type == CEXPR_NAMES) // Need compare name lists + { + qpol_iterator_t *names_iter=NULL; + size_t name_size=0; + compare_perm_str_t x; + +#ifdef DEBUGTRACE + printf ("Found CEXPR_NAMES expression\n"); +#endif + x.list_length = le[i]->name_count; + x.list = le[i]->namelist; + x.list_found = 0; + x.q_elements_compared = 0; + + err = qpol_constraint_expr_node_get_names_iter (q, expr, &names_iter); + CU_ASSERT_EQUAL_FATAL(err, 0); + + err = qpol_iterator_get_size(names_iter, &name_size); + CU_ASSERT_EQUAL_FATAL(err, 0); + CU_ASSERT_TRUE_FATAL(name_size > 0); + + if (name_size != x.list_length) // Want exact match, + { + qpol_iterator_destroy(&names_iter); + return 1; + } + + for (; qpol_iterator_end(names_iter) == 0; qpol_iterator_next(names_iter)) + { + char *lname = NULL; + + err = qpol_iterator_get_item (names_iter, (void **)&lname); + CU_ASSERT_EQUAL_FATAL(err, 0); + + compare_item_to_list (lname, &x); + free (lname); + } + +#ifdef DEBUGTRACE + printf ("name list length=%d, list_found=%d, q_elements_compared=%d\n", x.list_length, x.list_found, x.q_elements_compared); +#endif + if ((x.list_length != x.list_found) || (x.list_length != x.q_elements_compared)) + return 1; + } + } + return 0; +} + +static int compare_item_to_list(void *e, void *v) +{ + char *pe = (char *)e; + compare_perm_str_t *x = (compare_perm_str_t *)v; + char **permlist = x->list; + char *perm; + + CU_ASSERT_PTR_NOT_NULL(permlist); + CU_ASSERT_PTR_NOT_NULL(pe); + + while ((perm=*permlist++) != NULL) + { +#ifdef DEBUGTRACE + printf ("pe = %s\n", pe); + printf ("perm = %s\n", perm); +#endif + if (strcmp(pe, perm) == 0) + x->list_found++; + } + x->q_elements_compared++; + return 0; +} + +static int compare_perm_list(queue_t perm_q, char **permissions) +{ + compare_perm_str_t x; + + x.list_length = 0; + x.list_found = 0; + x.q_elements_compared = 0; + x.list = permissions; + + while (*permissions++ != NULL) + x.list_length++; + +#ifdef DEBUGTRACE + printf ("list_length = %d\n", x.list_length); +#endif + if (queue_map(perm_q, compare_item_to_list, &x) != 0) + return 1; + +#ifdef DEBUGTRACE + printf ("list length=%d, list_found=%d, q_elements_compared=%d\n", x.list_length, x.list_found, x.q_elements_compared); +#endif + if ((x.list_length != x.list_found) || (x.list_length != x.q_elements_compared)) + return 1; + + return 0; +} + +static void constrain_test(apol_policy_t *ap) +{ + int i; + int err=0; + const char *class_name = NULL; + const char *constrain_type = "?constrain"; + char *perm_list = "No Perms Extracted"; + const qpol_constraint_expr_node_t *expr = NULL; + qpol_iterator_t *policy_iter = NULL; // Iterates over all constraints in a policy + qpol_iterator_t *perm_iter = NULL; // Iterates over permissions in a constraint + qpol_iterator_t *expr_iter = NULL; // Iterates over expression in a constraint + qpol_policy_t *q = apol_policy_get_qpol(ap); + qpol_constraint_t *constraint = NULL; + const qpol_class_t *class; + size_t n_constraints = 0; + size_t counted_constraints = 0; + size_t tests_not_found = 0; + int test_count = sizeof(test_list) / sizeof(constrain_test_list_t); + int tests_matched = 0; + int constrains_matched = 0; + + queue_t perm_q; // holds list of permissions, in case more than one + + err = qpol_policy_get_constraint_iter(q, &policy_iter); + if (err != 0) + { + CU_FAIL("Policy iterator not accessible"); + goto cleanup; + } + err = qpol_iterator_get_size(policy_iter, &n_constraints); + if (err != 0) + { + CU_FAIL("Policy size computation failed"); + goto cleanup; + } + + CU_ASSERT_EQUAL(n_constraints, 7); // Count of constraints split among all classes + + counted_constraints=0; + for (i=0; i<test_count; i++) + { + test_list[i].test_found = 0; + } + + // Iterate through constraints + for (; qpol_iterator_end(policy_iter) == 0; qpol_iterator_next(policy_iter)) + { + counted_constraints++; + /* The qpol_constraint_t that is returned below consists of + * struct qpol_constraint <<<from constraint_query.c + * { + * const qpol_class_t *obj_class; + * constraint_node_t *constr; + * }; + * the qpol_class_t is a pseudonym for class_datum_t from policydb.h + * constraint_node_t is defined in sepol/policydb/constraint.h + */ + err = qpol_iterator_get_item(policy_iter, (void **)&constraint); + CU_ASSERT_EQUAL_FATAL(err, 0); // Should never happen + + err = qpol_constraint_get_class(q, constraint, &class); + CU_ASSERT_EQUAL_FATAL(err, 0); // Should never happen + err = qpol_class_get_name(q, class, &class_name); + CU_ASSERT_EQUAL_FATAL(err, 0); // Should never happen + +#ifdef DEBUGTRACE + printf ("Found class %s\n", class_name); +#endif + // get permission(s) + err = qpol_constraint_get_perm_iter (q, constraint, &perm_iter); + CU_ASSERT_EQUAL_FATAL(err, 0); + + perm_q = queue_create(); + for (; qpol_iterator_end(perm_iter) == 0; qpol_iterator_next(perm_iter)) + { + err = qpol_iterator_get_item(perm_iter, (void **)&perm_list); + CU_ASSERT_EQUAL_FATAL(err,0) + + err = queue_insert (perm_q, perm_list); + CU_ASSERT_EQUAL_FATAL(err,0) + } +#ifdef DEBUGTRACE + printf ("perms: "); + queue_map(perm_q, doprintstr, NULL); + printf ("\n"); +#endif + + // get RPN expressions + err = qpol_constraint_get_expr_iter (q, constraint, &expr_iter); + CU_ASSERT_EQUAL_FATAL(err, 0); + + // At this point, the class, permission list, and expression list (in + // the iterator) have been identified. Based on expected class/permission + // combinations, find one which matches, and note that it was found. + // If not found, count that too. + for (i=0; i<test_count; i++) + { + if (strcmp(*(test_list[i].class), class_name) == 0) + { + if (compare_perm_list(perm_q, test_list[i].permissions) == 0) + { + if (compare_expr_list(q, expr_iter, test_list[i].expr_count, test_list[i].expr_list) == 0) + { + test_list[i].test_found = 1; + constrains_matched++; + break; + } +#ifdef DEBUGTRACE + else + { + printf ("Mismatch comparing expression list\n"); + } +#endif + } +#ifdef DEBUGTRACE + else + { + printf ("Mismatch comparing permission list\n"); + } +#endif + } +#ifdef DEBUGTRACE + else + { + printf ("Mismatch comparing classes %s,%s\n", *(test_list[i].class),class_name); + } +#endif + } + queue_destroy(perm_q); + } + for (i=0; i<test_count; i++) + { + if (test_list[i].test_found == 0) + { + CU_ASSERT_EQUAL(i, 2); + } + else + tests_matched++; + } +#ifdef DEBUGTRACE + printf ("tests_matched: %d, constrains_matched: %d, counted_constraints: %d, n_constraints: %d\n", tests_matched, constrains_matched, counted_constraints, n_constraints); +#endif + CU_ASSERT_EQUAL(tests_matched, 5); + CU_ASSERT_EQUAL(constrains_matched, 5); + CU_ASSERT_EQUAL(counted_constraints, 7); + CU_ASSERT_EQUAL(n_constraints, 7); + + CU_PASS(); + +cleanup: + return; + // close and destroy iterators/policy pointers +} + +static void constrain_source(void) +{ + constrain_test(ps); +} + +static void constrain_binary(void) +{ + constrain_test(pb); +// CU_PASS("Not yet implemented") +} + + +static void constrain_modular(void) +{ + CU_PASS("Not yet implemented") +} + +CU_TestInfo constrain_tests[] = { + {"constrain from source policy", constrain_source}, + {"constrain from binary policy", constrain_binary}, +// {"constrain from modular policy", constrain_modular}, + CU_TEST_INFO_NULL +}; + +int constrain_init() +{ + // Probably should move this to individual tests, just fstat policy to see if it is there! + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, CONSTR_SOURCE, NULL); + if (ppath == NULL) { + return 1; + } + + if ((ps = apol_policy_create_from_policy_path(ppath, QPOL_POLICY_OPTION_NO_NEVERALLOWS, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, CONSTR_BINARY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((pb = apol_policy_create_from_policy_path(ppath, QPOL_POLICY_OPTION_NO_NEVERALLOWS, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + return 0; +} + +int constrain_cleanup() +{ + apol_policy_destroy(&ps); + return 0; +} diff --git a/libapol/tests/constrain-tests.h b/libapol/tests/constrain-tests.h new file mode 100644 index 0000000..e87c020 --- /dev/null +++ b/libapol/tests/constrain-tests.h @@ -0,0 +1,33 @@ +/** + * @file + * + * Declarations for libapol constraint tests. + * + * + * Copyright (C) 2010 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONSTRAIN_TESTS_H +#define CONSTRAIN_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo constrain_tests[]; +extern int constrain_init(); +extern int constrain_cleanup(); + +#endif diff --git a/libapol/tests/dta-tests.c b/libapol/tests/dta-tests.c new file mode 100644 index 0000000..d25fd82 --- /dev/null +++ b/libapol/tests/dta-tests.c @@ -0,0 +1,529 @@ +/** + * @file + * + * Test the new domain transition analysis code introduced in SETools + * 3.3. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/avrule-query.h> +#include <apol/domain-trans-analysis.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <stdbool.h> +#include <string.h> + +#define POLICY TEST_POLICIES "/setools-3.3/apol/dta_test.policy.conf" + +static apol_policy_t *p = NULL; + +static void dta_forward(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_FORWARD); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_start_type(p, d, "tuna_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + apol_domain_trans_analysis_destroy(&d); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + + qpol_policy_t *q = apol_policy_get_qpol(p); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name, *ep_name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "tuna_t"); + + qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(name, "boat_t") == 0 || strcmp(name, "sand_t") == 0); + + qt = apol_domain_trans_result_get_entrypoint_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &ep_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + if (strcmp(name, "boat_t") == 0) { + CU_ASSERT_STRING_EQUAL(ep_name, "net_t"); + } else if (strcmp(name, "sand_t") == 0) { + CU_ASSERT(strcmp(ep_name, "reel_t") == 0 || strcmp(ep_name, "wave_t") == 0); + } + } + + apol_vector_destroy(&v); +} + +static void dta_forward_multi_end(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_FORWARD); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_start_type(p, d, "shark_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + apol_domain_trans_analysis_destroy(&d); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) == 2); + + qpol_policy_t *q = apol_policy_get_qpol(p); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name, *ep_name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "shark_t"); + + qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(name, "surf_t") == 0 || strcmp(name, "sand_t") == 0); + + qt = apol_domain_trans_result_get_entrypoint_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &ep_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + CU_ASSERT_STRING_EQUAL(ep_name, "wave_t"); + } + + apol_vector_destroy(&v); +} + +static void dta_forward_access(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_FORWARD); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_start_type(p, d, "tuna_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_access_type(p, d, "boat_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_access_type(p, d, "sand_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_access_type(p, d, "wave_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_class(p, d, "file"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_perm(p, d, "write"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + + qpol_policy_t *q = apol_policy_get_qpol(p); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "tuna_t"); + + qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "boat_t"); + + const apol_vector_t *rules_v = apol_domain_trans_result_get_access_rules(dtr); + CU_ASSERT_FATAL(rules_v != NULL && apol_vector_get_size(rules_v) > 0); + size_t j; + for (j = 0; j < apol_vector_get_size(rules_v); j++) { + const qpol_avrule_t *qa = (const qpol_avrule_t *)apol_vector_get_element(rules_v, j); + char *render = apol_avrule_render(p, qa); + CU_ASSERT_PTR_NOT_NULL_FATAL(render); + CU_ASSERT_STRING_EQUAL(render, "allow boat_t wave_t : file { write getattr execute } ;"); + free(render); + } + } + + apol_vector_destroy(&v); + + retval = apol_domain_trans_analysis_set_start_type(p, d, "boat_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_access_type(p, d, NULL); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_class(p, d, NULL); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_append_perm(p, d, NULL); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_policy_reset_domain_trans_table(p); + retval = apol_domain_trans_analysis_do(p, d, &v); + apol_domain_trans_analysis_destroy(&d); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "boat_t"); + + qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(name, "sand_t") == 0 || strcmp(name, "dock_t") == 0); + } + apol_vector_destroy(&v); +} + +static void dta_reverse(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval; + retval = apol_domain_trans_analysis_set_start_type(p, d, "sand_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_REVERSE); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + apol_domain_trans_analysis_destroy(&d); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + + qpol_policy_t *q = apol_policy_get_qpol(p); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "sand_t"); + + qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(name, "boat_t") == 0 || strcmp(name, "grouper_t") == 0 || strcmp(name, "shark_t") == 0 || + strcmp(name, "tuna_t") == 0); + } + + apol_vector_destroy(&v); +} + +static void dta_reverse_regexp(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval; + retval = apol_domain_trans_analysis_set_start_type(p, d, "sand_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_REVERSE); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_result_regex(p, d, "u"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + apol_domain_trans_analysis_destroy(&d); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + + qpol_policy_t *q = apol_policy_get_qpol(p); + size_t i; + bool found_tuna_wave = false, found_grouper_reel = false, found_grouper_wave = false; + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name, *ep_name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(name, "sand_t"); + + qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(name, "tuna_t") == 0 || strcmp(name, "grouper_t") == 0); + + qt = apol_domain_trans_result_get_entrypoint_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &ep_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + if (strcmp(name, "tuna_t") == 0) { + if (strcmp(ep_name, "wave_t") == 0) { + found_tuna_wave = true; + } + } else if (strcmp(name, "grouper_t") == 0) { + if (strcmp(ep_name, "reel_t") == 0) { + found_grouper_reel = true; + } else if (strcmp(ep_name, "wave_t") == 0) { + found_grouper_wave = true; + } + } + } + CU_ASSERT(found_tuna_wave && found_grouper_reel && found_grouper_wave); + + apol_vector_destroy(&v); +} + +static void dta_reflexive(void) +{ + apol_policy_reset_domain_trans_table(p); + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_FORWARD); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_start_type(p, d, "sand_t"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_domain_trans_analysis_do(p, d, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + + retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_REVERSE); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + retval = apol_domain_trans_analysis_do(p, d, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + size_t i; + qpol_policy_t *q = apol_policy_get_qpol(p); + for (i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + const char *name; + retval = qpol_type_get_name(q, qt, &name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_NOT_EQUAL(name, "sand_t"); + } + apol_vector_destroy(&v); + + apol_domain_trans_analysis_destroy(&d); +} + +struct dta_invalid_item +{ + const char *start_type; + const char *end_type; + const char *entrypoint_type; + const bool missing_proc_trans; + const bool missing_entrypoint; + const bool missing_exec; + const bool missing_setexec; + const bool missing_type_trans; + bool used; +}; + +static void dta_invalid(void) +{ + struct dta_invalid_item items[] = { + {"boat_t", "dock_t", "net_t", false, false, true, false, false, false}, + {"boat_t", "sand_t", "reel_t", false, false, true, false, false, false}, + {"crab_t", "dock_t", "net_t", false, false, false, true, false, false}, + {"crab_t", "dock_t", "rope_t", false, false, true, true, false, false}, + {"crab_t", "dock_t", "wave_t", false, true, true, false, false, false}, + {"gull_t", "dock_t", "net_t", false, false, false, true, true, false}, + {"gull_t", "dock_t", "rope_t", false, false, true, true, true, false}, + {"gull_t", "sand_t", "net_t", true, true, false, false, false, false}, + {"marlin_t", "boat_t", "line_t", false, false, true, false, false, false}, + {"marlin_t", "boat_t", "net_t", false, false, true, false, false, false}, + {"ray_t", "boat_t", "line_t", true, false, true, false, false, false}, + {"ray_t", "sand_t", "wave_t", true, false, false, false, false, false}, + {"shark_t", "sand_t", "reel_t", false, false, true, false, false, false}, + {"tuna_t", "boat_t", "line_t", false, false, true, false, false, false}, + {"tuna_t", "boat_t", "reel_t", false, true, false, false, false, false}, + {NULL, NULL, NULL, false, false, false, false, false, false} + }; + const char *start_types[] = { + "boat_t", "crab_t", "gull_t", "marlin_t", "ray_t", "shark_t", "tuna_t", NULL + }; + apol_domain_trans_analysis_t *d = apol_domain_trans_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(d); + int retval = apol_domain_trans_analysis_set_direction(p, d, APOL_DOMAIN_TRANS_DIRECTION_FORWARD); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_domain_trans_analysis_set_valid(p, d, APOL_DOMAIN_TRANS_SEARCH_INVALID); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + qpol_policy_t *q = apol_policy_get_qpol(p); + apol_vector_t *v = NULL; + struct dta_invalid_item *item; + for (const char **start = start_types; *start != NULL; start++) { + apol_policy_reset_domain_trans_table(p); + retval = apol_domain_trans_analysis_set_start_type(p, d, *start); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + retval = apol_domain_trans_analysis_do(p, d, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) > 0); + + for (size_t i = 0; i < apol_vector_get_size(v); i++) { + const apol_domain_trans_result_t *dtr = (const apol_domain_trans_result_t *)apol_vector_get_element(v, i); + + const char *result_start, *result_end, *result_entry; + + const qpol_type_t *qt = apol_domain_trans_result_get_start_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &result_start); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(result_start, *start); + + qt = apol_domain_trans_result_get_end_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &result_end); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + qt = apol_domain_trans_result_get_entrypoint_type(dtr); + CU_ASSERT_PTR_NOT_NULL(qt); + retval = qpol_type_get_name(q, qt, &result_entry); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + CU_ASSERT(apol_domain_trans_result_is_trans_valid(dtr) == 0); + + for (item = items + 0; item->start_type != NULL; item++) { + if (strcmp(result_start, item->start_type) == 0 && + strcmp(result_end, item->end_type) == 0 && + strcmp(result_entry, item->entrypoint_type) == 0 && !item->used) { + item->used = true; + + const apol_vector_t *cv; + if (item->missing_proc_trans) { + cv = apol_domain_trans_result_get_proc_trans_rules(dtr); + CU_ASSERT(cv != NULL && apol_vector_get_size(cv) == 0); + } + if (item->missing_entrypoint) { + cv = apol_domain_trans_result_get_entrypoint_rules(dtr); + CU_ASSERT(cv != NULL && apol_vector_get_size(cv) == 0); + } + if (item->missing_exec) { + cv = apol_domain_trans_result_get_exec_rules(dtr); + CU_ASSERT(cv != NULL && apol_vector_get_size(cv) == 0); + } + if (item->missing_setexec) { + cv = apol_domain_trans_result_get_setexec_rules(dtr); + CU_ASSERT(cv != NULL && apol_vector_get_size(cv) == 0); + } + if (item->missing_type_trans) { + cv = apol_domain_trans_result_get_type_trans_rules(dtr); + CU_ASSERT(cv != NULL && apol_vector_get_size(cv) == 0); + } + break; + } + } + if (item->start_type == NULL) { + CU_FAIL(); + } + } + apol_vector_destroy(&v); + } + + for (item = items + 0; item->start_type != NULL; item++) { + CU_ASSERT(item->used); + } + apol_domain_trans_analysis_destroy(&d); +} + +CU_TestInfo dta_tests[] = { + {"dta forward", dta_forward} + , + {"dta forward + access", dta_forward_access} + , + {"dta forward with multiple endpoints for same entrypoint", dta_forward_multi_end} + , + {"dta reverse", dta_reverse} + , + {"dta reverse + regexp", dta_reverse_regexp} + , + {"dta reflexive", dta_reflexive} + , + {"dta invalid transitions", dta_invalid} + , + CU_TEST_INFO_NULL +}; + +int dta_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((p = apol_policy_create_from_policy_path(ppath, QPOL_POLICY_OPTION_NO_NEVERALLOWS, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + int retval = apol_policy_build_domain_trans_table(p); + if (retval != 0) { + return 1; + } + return 0; +} + +int dta_cleanup() +{ + apol_policy_destroy(&p); + return 0; +} diff --git a/libapol/tests/dta-tests.h b/libapol/tests/dta-tests.h new file mode 100644 index 0000000..820b8d2 --- /dev/null +++ b/libapol/tests/dta-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol domain transition analysis tests. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DTA_TESTS_H +#define DTA_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo dta_tests[]; +extern int dta_init(); +extern int dta_cleanup(); + +#endif diff --git a/libapol/tests/infoflow-tests.c b/libapol/tests/infoflow-tests.c new file mode 100644 index 0000000..6a74ba6 --- /dev/null +++ b/libapol/tests/infoflow-tests.c @@ -0,0 +1,127 @@ +/** + * @file + * + * Test the information flow analysis code. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/infoflow-analysis.h> +#include <apol/perm-map.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <stdbool.h> +#include <string.h> + +#define BIG_POLICY TEST_POLICIES "/snapshots/fc4_targeted.policy.conf" +#define PERMMAP TOP_SRCDIR "/apol/perm_maps/apol_perm_mapping_ver19" + +static apol_policy_t *p = NULL; + +static void infoflow_direct_overview(void) +{ + apol_infoflow_analysis_t *ia = apol_infoflow_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(ia); + int retval; + retval = apol_infoflow_analysis_set_mode(p, ia, APOL_INFOFLOW_MODE_DIRECT); + CU_ASSERT(retval == 0); + retval = apol_infoflow_analysis_set_dir(p, ia, APOL_INFOFLOW_IN); + CU_ASSERT(retval == 0); + retval = apol_infoflow_analysis_set_type(p, ia, "agp_device_t"); + CU_ASSERT(retval == 0); + + apol_vector_t *v = NULL; + apol_infoflow_graph_t *g = NULL; + // no permmap loaded, so analysis run will abort with error + retval = apol_infoflow_analysis_do(p, ia, &v, &g); + CU_ASSERT(retval < 0); + + retval = apol_policy_open_permmap(p, PERMMAP); + CU_ASSERT(retval == 0); + + retval = apol_infoflow_analysis_do(p, ia, &v, &g); + CU_ASSERT(retval == 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) > 0); + CU_ASSERT_PTR_NOT_NULL(g); + + apol_infoflow_analysis_destroy(&ia); + apol_vector_destroy(&v); + apol_infoflow_graph_destroy(&g); +} + +static void infoflow_trans_overview(void) +{ + apol_infoflow_analysis_t *ia = apol_infoflow_analysis_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(ia); + int retval; + retval = apol_infoflow_analysis_set_mode(p, ia, APOL_INFOFLOW_MODE_DIRECT); + CU_ASSERT(retval == 0); + retval = apol_infoflow_analysis_set_dir(p, ia, APOL_INFOFLOW_IN); + CU_ASSERT(retval == 0); + retval = apol_infoflow_analysis_set_type(p, ia, "local_login_t"); + CU_ASSERT(retval == 0); + + apol_vector_t *v = NULL; + apol_infoflow_graph_t *g = NULL; + // permmap was loaded by infoflow_direct_overview() + retval = apol_infoflow_analysis_do(p, ia, &v, &g); + CU_ASSERT(retval == 0); + CU_ASSERT_PTR_NOT_NULL(v); + CU_ASSERT(apol_vector_get_size(v) > 0); + CU_ASSERT_PTR_NOT_NULL(g); + + apol_infoflow_analysis_destroy(&ia); + apol_vector_destroy(&v); + apol_infoflow_graph_destroy(&g); +} + +CU_TestInfo infoflow_tests[] = { + {"infoflow direct overview", infoflow_direct_overview} + , + {"infoflow trans overview", infoflow_trans_overview} + , + CU_TEST_INFO_NULL +}; + +int infoflow_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, BIG_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((p = apol_policy_create_from_policy_path(ppath, QPOL_POLICY_OPTION_NO_NEVERALLOWS, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + return 0; +} + +int infoflow_cleanup() +{ + apol_policy_destroy(&p); + return 0; +} diff --git a/libapol/tests/infoflow-tests.h b/libapol/tests/infoflow-tests.h new file mode 100644 index 0000000..840f3b1 --- /dev/null +++ b/libapol/tests/infoflow-tests.h @@ -0,0 +1,36 @@ +/** + * @file + * + * Declarations for libapol infomation flow analysis tests, both + * direct and transitive. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef INFOFLOW_TESTS_H +#define INFOFLOW_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo infoflow_tests[]; +extern int infoflow_init(); +extern int infoflow_cleanup(); + +#endif diff --git a/libapol/tests/libapol-tests.c b/libapol/tests/libapol-tests.c new file mode 100644 index 0000000..9b83235 --- /dev/null +++ b/libapol/tests/libapol-tests.c @@ -0,0 +1,64 @@ +/** + * @file + * + * CUnit testing framework for libapol. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <CUnit/Basic.h> + +#include "avrule-tests.h" +#include "dta-tests.h" +#include "infoflow-tests.h" +#include "policy-21-tests.h" +#include "role-tests.h" +#include "terule-tests.h" +#include "constrain-tests.h" +#include "user-tests.h" + +int main(void) +{ + if (CU_initialize_registry() != CUE_SUCCESS) { + return CU_get_error(); + } + + CU_SuiteInfo suites[] = { + {"Policy Version 21", policy_21_init, policy_21_cleanup, policy_21_tests}, + {"AV Rule Query", avrule_init, avrule_cleanup, avrule_tests}, + {"Domain Transition Analysis", dta_init, dta_cleanup, dta_tests}, + {"Infoflow Analysis", infoflow_init, infoflow_cleanup, infoflow_tests}, + {"Role Query", role_init, role_cleanup, role_tests}, + {"TE Rule Query", terule_init, terule_cleanup, terule_tests}, + {"User Query", user_init, user_cleanup, user_tests}, + {"Constrain query", constrain_init, constrain_cleanup, constrain_tests}, + CU_SUITE_INFO_NULL + }; + + CU_register_suites(suites); + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + unsigned int num_failures = CU_get_number_of_failure_records(); + CU_cleanup_registry(); + return (int)num_failures; +} diff --git a/libapol/tests/policy-21-tests.c b/libapol/tests/policy-21-tests.c new file mode 100644 index 0000000..ea07da1 --- /dev/null +++ b/libapol/tests/policy-21-tests.c @@ -0,0 +1,181 @@ +/** + * @file + * + * Test features of policy version 21, that were introduced in + * SETools 3.2. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <apol/range_trans-query.h> + +#define POLICY TEST_POLICIES "/setools-3.2/apol/rangetrans_testing_policy.conf" + +static apol_policy_t *p = NULL; + +static void policy_21_range_trans_all(void) +{ + apol_range_trans_query_t *rt = apol_range_trans_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(rt); + + apol_vector_t *v = NULL; + int retval = apol_range_trans_get_by_query(p, rt, &v); + apol_range_trans_query_destroy(&rt); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 17); + apol_vector_destroy(&v); +} + +static void policy_21_range_trans_process(void) +{ + apol_range_trans_query_t *rt = apol_range_trans_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(rt); + int retval; + retval = apol_range_trans_query_append_class(p, rt, "process"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_range_trans_get_by_query(p, rt, &v); + apol_range_trans_query_destroy(&rt); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 10); + size_t i; + qpol_policy_t *q = apol_policy_get_qpol(p); + for (i = 0; i < apol_vector_get_size(v); i++) { + const qpol_range_trans_t *qrt = (const qpol_range_trans_t *)apol_vector_get_element(v, i); + const qpol_class_t *c; + retval = qpol_range_trans_get_target_class(q, qrt, &c); + CU_ASSERT_EQUAL_FATAL(retval, 0); + const char *class_name; + retval = qpol_class_get_name(q, c, &class_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(class_name, "process"); + } + apol_vector_destroy(&v); +} + +static void policy_21_range_trans_lnk_file(void) +{ + apol_range_trans_query_t *rt = apol_range_trans_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(rt); + int retval; + retval = apol_range_trans_query_append_class(p, rt, "lnk_file"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_range_trans_get_by_query(p, rt, &v); + apol_range_trans_query_destroy(&rt); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 2); + size_t i; + qpol_policy_t *q = apol_policy_get_qpol(p); + for (i = 0; i < apol_vector_get_size(v); i++) { + const qpol_range_trans_t *qrt = (const qpol_range_trans_t *)apol_vector_get_element(v, i); + const qpol_class_t *c; + retval = qpol_range_trans_get_target_class(q, qrt, &c); + CU_ASSERT_EQUAL_FATAL(retval, 0); + const char *class_name; + retval = qpol_class_get_name(q, c, &class_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_STRING_EQUAL(class_name, "lnk_file"); + } + apol_vector_destroy(&v); +} + +static void policy_21_range_trans_either(void) +{ + apol_range_trans_query_t *rt = apol_range_trans_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(rt); + int retval; + retval = apol_range_trans_query_append_class(p, rt, "process"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + retval = apol_range_trans_query_append_class(p, rt, "lnk_file"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_range_trans_get_by_query(p, rt, &v); + apol_range_trans_query_destroy(&rt); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 12); + size_t i; + qpol_policy_t *q = apol_policy_get_qpol(p); + for (i = 0; i < apol_vector_get_size(v); i++) { + const qpol_range_trans_t *qrt = (const qpol_range_trans_t *)apol_vector_get_element(v, i); + const qpol_class_t *c; + retval = qpol_range_trans_get_target_class(q, qrt, &c); + CU_ASSERT_EQUAL_FATAL(retval, 0); + const char *class_name; + retval = qpol_class_get_name(q, c, &class_name); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(strcmp(class_name, "process") == 0 || strcmp(class_name, "lnk_file") == 0); + } + apol_vector_destroy(&v); +} + +static void policy_21_range_trans_socket(void) +{ + apol_range_trans_query_t *rt = apol_range_trans_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(rt); + int retval; + retval = apol_range_trans_query_append_class(p, rt, "socket"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_range_trans_get_by_query(p, rt, &v); + apol_range_trans_query_destroy(&rt); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); +} + +CU_TestInfo policy_21_tests[] = { + {"range_trans all", policy_21_range_trans_all}, + {"range_trans process", policy_21_range_trans_process}, + {"range_trans lnk_file", policy_21_range_trans_lnk_file}, + {"range_trans process or lnk_file", policy_21_range_trans_either}, + {"range_trans socket", policy_21_range_trans_socket}, + CU_TEST_INFO_NULL +}; + +int policy_21_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((p = apol_policy_create_from_policy_path(ppath, QPOL_POLICY_OPTION_NO_RULES, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + return 0; +} + +int policy_21_cleanup() +{ + apol_policy_destroy(&p); + return 0; +} diff --git a/libapol/tests/policy-21-tests.h b/libapol/tests/policy-21-tests.h new file mode 100644 index 0000000..dd427ba --- /dev/null +++ b/libapol/tests/policy-21-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol version 21 policy support. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef POLICY_21_TESTS_H +#define POLICY_21_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo policy_21_tests[]; +extern int policy_21_init(); +extern int policy_21_cleanup(); + +#endif diff --git a/libapol/tests/role-tests.c b/libapol/tests/role-tests.c new file mode 100644 index 0000000..3aee323 --- /dev/null +++ b/libapol/tests/role-tests.c @@ -0,0 +1,154 @@ +/** + * @file + * + * Test the role queries. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/role-query.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <stdbool.h> + +#define SOURCE_POLICY TEST_POLICIES "/setools/apol/role_dom.conf" + +static apol_policy_t *sp = NULL; +static qpol_policy_t *qp = NULL; + +static void role_basic(void) +{ + apol_role_query_t *q = apol_role_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(q); + + apol_vector_t *v = NULL; + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 26); + apol_vector_destroy(&v); + + apol_role_query_set_role(sp, q, "sh"); + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + + apol_role_query_set_role(sp, q, NULL); + apol_role_query_set_type(sp, q, "silly_t"); + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 2); + bool found_silly = false, found_object = false; + for (size_t i = 0; i < apol_vector_get_size(v); i++) { + qpol_role_t *r = (qpol_role_t *) apol_vector_get_element(v, i); + const char *name; + qpol_role_get_name(qp, r, &name); + if (strcmp(name, "silly_r") == 0) { + found_silly = true; + } else if (strcmp(name, "object_r") == 0) { + found_object = true; + } else { + CU_ASSERT(0); + } + } + CU_ASSERT(found_silly && found_object); + apol_vector_destroy(&v); + + apol_role_query_set_type(sp, q, "not_in_the_policy_t"); + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + + apol_role_query_destroy(&q); +} + +static void role_regex(void) +{ + apol_role_query_t *q = apol_role_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(q); + apol_role_query_set_regex(sp, q, 1); + + apol_role_query_set_role(sp, q, "*"); + apol_vector_t *v = NULL; + CU_ASSERT(apol_role_get_by_query(sp, q, &v) < 0 && v == NULL); + + apol_role_query_set_role(sp, q, "^sh"); + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 2); + bool found_shirt = false, found_shoe = false; + for (size_t i = 0; i < apol_vector_get_size(v); i++) { + qpol_role_t *r = (qpol_role_t *) apol_vector_get_element(v, i); + const char *name; + qpol_role_get_name(qp, r, &name); + if (strcmp(name, "shirt_r") == 0) { + found_shirt = true; + } else if (strcmp(name, "shoe_r") == 0) { + found_shoe = true; + } else { + CU_ASSERT(0); + } + } + CU_ASSERT(found_shirt && found_shoe); + apol_vector_destroy(&v); + + apol_role_query_set_role(sp, q, NULL); + apol_role_query_set_type(sp, q, "file"); + CU_ASSERT(apol_role_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 1); + qpol_role_t *r = (qpol_role_t *) apol_vector_get_element(v, 0); + const char *name; + qpol_role_get_name(qp, r, &name); + CU_ASSERT_STRING_EQUAL(name, "object_r"); + apol_vector_destroy(&v); + + apol_role_query_destroy(&q); +} + +CU_TestInfo role_tests[] = { + {"basic query", role_basic} + , + {"regex query", role_regex} + , + CU_TEST_INFO_NULL +}; + +int role_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, SOURCE_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((sp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + qp = apol_policy_get_qpol(sp); + + return 0; +} + +int role_cleanup() +{ + apol_policy_destroy(&sp); + return 0; +} diff --git a/libapol/tests/role-tests.h b/libapol/tests/role-tests.h new file mode 100644 index 0000000..0663f9e --- /dev/null +++ b/libapol/tests/role-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol role query tests. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ROLE_TESTS_H +#define ROLE_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo role_tests[]; +extern int role_init(); +extern int role_cleanup(); + +#endif diff --git a/libapol/tests/terule-tests.c b/libapol/tests/terule-tests.c new file mode 100644 index 0000000..f635e02 --- /dev/null +++ b/libapol/tests/terule-tests.c @@ -0,0 +1,130 @@ +/** + * @file + * + * Test the TE rule queries, both semantic and syntactic searches. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <apol/terule-query.h> +#include <qpol/policy_extend.h> +#include <stdbool.h> + +#define BIN_POLICY TEST_POLICIES "/setools-3.3/rules/rules-mls.21" +#define SOURCE_POLICY TEST_POLICIES "/setools-3.3/rules/rules-mls.conf" + +static apol_policy_t *bp = NULL; +static apol_policy_t *sp = NULL; + +static void terule_basic_syn(void) +{ + apol_terule_query_t *tq = apol_terule_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(tq); + + int retval; + retval = apol_terule_query_set_rules(sp, tq, QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + apol_vector_t *v = NULL; + retval = apol_syn_terule_get_by_query(sp, tq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT_PTR_NOT_NULL(v); + + size_t num_trans = 0, num_changes = 0, num_members = 0; + + qpol_policy_t *q = apol_policy_get_qpol(sp); + size_t i; + for (i = 0; i < apol_vector_get_size(v); i++) { + const qpol_syn_terule_t *syn = (const qpol_syn_terule_t *)apol_vector_get_element(v, i); + uint32_t rule_type; + retval = qpol_syn_terule_get_rule_type(q, syn, &rule_type); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(rule_type == QPOL_RULE_TYPE_TRANS || rule_type == QPOL_RULE_TYPE_CHANGE || + rule_type == QPOL_RULE_TYPE_MEMBER); + + if (rule_type == QPOL_RULE_TYPE_TRANS) { + num_trans++; + } else if (rule_type == QPOL_RULE_TYPE_CHANGE) { + num_changes++; + } else if (rule_type == QPOL_RULE_TYPE_MEMBER) { + num_members++; + } + } + CU_ASSERT(num_trans == 6 && num_changes == 3 && num_members == 4); + apol_vector_destroy(&v); + + retval = apol_terule_query_append_class(sp, tq, "cursor"); + CU_ASSERT_EQUAL_FATAL(retval, 0); + + retval = apol_syn_terule_get_by_query(sp, tq, &v); + CU_ASSERT_EQUAL_FATAL(retval, 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + apol_terule_query_destroy(&tq); +} + +CU_TestInfo terule_tests[] = { + {"basic syntactic search", terule_basic_syn} + , + CU_TEST_INFO_NULL +}; + +int terule_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, BIN_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((bp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, SOURCE_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((sp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(sp)) != 0) { + return 1; + } + + return 0; +} + +int terule_cleanup() +{ + apol_policy_destroy(&bp); + apol_policy_destroy(&sp); + return 0; +} diff --git a/libapol/tests/terule-tests.h b/libapol/tests/terule-tests.h new file mode 100644 index 0000000..fff497a --- /dev/null +++ b/libapol/tests/terule-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol terule query tests. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TERULE_TESTS_H +#define TERULE_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo terule_tests[]; +extern int terule_init(); +extern int terule_cleanup(); + +#endif diff --git a/libapol/tests/user-tests.c b/libapol/tests/user-tests.c new file mode 100644 index 0000000..2d912c0 --- /dev/null +++ b/libapol/tests/user-tests.c @@ -0,0 +1,159 @@ +/** + * @file + * + * Test the user queries. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include <CUnit/CUnit.h> +#include <apol/user-query.h> +#include <apol/policy.h> +#include <apol/policy-path.h> +#include <stdbool.h> + +#define SOURCE_POLICY TEST_POLICIES "/setools/apol/user_mls_testing_policy.conf" + +static apol_policy_t *sp = NULL; +static qpol_policy_t *qp = NULL; + +static void user_basic(void) +{ + apol_user_query_t *q = apol_user_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(q); + + apol_vector_t *v = NULL; + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 10); + apol_vector_destroy(&v); + + apol_user_query_set_role(sp, q, "object_r"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 10); + apol_vector_destroy(&v); + + apol_user_query_set_user(sp, q, "sys"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + + apol_user_query_set_user(sp, q, NULL); + apol_user_query_set_role(sp, q, "staff_r"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 3); + bool found_staff = false, found_rick = false, found_simple = false; + for (size_t i = 0; i < apol_vector_get_size(v); i++) { + qpol_user_t *u = (qpol_user_t *) apol_vector_get_element(v, i); + const char *name; + qpol_user_get_name(qp, u, &name); + if (strcmp(name, "staff_u") == 0) { + found_staff = true; + } else if (strcmp(name, "rick_u") == 0) { + found_rick = true; + } else if (strcmp(name, "simple_u") == 0) { + found_simple = true; + } else { + CU_ASSERT(0); + } + } + CU_ASSERT(found_staff && found_rick && found_simple); + apol_vector_destroy(&v); + + apol_user_query_set_role(sp, q, "not_in_the_policy_r"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 0); + apol_vector_destroy(&v); + + apol_user_query_destroy(&q); +} + +static void user_regex(void) +{ + apol_user_query_t *q = apol_user_query_create(); + CU_ASSERT_PTR_NOT_NULL_FATAL(q); + apol_user_query_set_regex(sp, q, 1); + + apol_user_query_set_user(sp, q, "*"); + apol_vector_t *v = NULL; + CU_ASSERT(apol_user_get_by_query(sp, q, &v) < 0 && v == NULL); + + apol_user_query_set_user(sp, q, "st"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 3); + bool found_staff = false, found_system = false, found_guest = false; + for (size_t i = 0; i < apol_vector_get_size(v); i++) { + qpol_user_t *u = (qpol_user_t *) apol_vector_get_element(v, i); + const char *name; + qpol_user_get_name(qp, u, &name); + if (strcmp(name, "staff_u") == 0) { + found_staff = true; + } else if (strcmp(name, "system_u") == 0) { + found_system = true; + } else if (strcmp(name, "guest_u") == 0) { + found_guest = true; + } else { + CU_ASSERT(0); + } + } + CU_ASSERT(found_staff && found_system && found_guest); + apol_vector_destroy(&v); + + apol_user_query_set_user(sp, q, NULL); + apol_user_query_set_role(sp, q, "user_r"); + CU_ASSERT(apol_user_get_by_query(sp, q, &v) == 0); + CU_ASSERT(v != NULL && apol_vector_get_size(v) == 3); + apol_vector_destroy(&v); + + apol_user_query_destroy(&q); +} + +CU_TestInfo user_tests[] = { + {"basic query", user_basic} + , + {"regex query", user_regex} + , + CU_TEST_INFO_NULL +}; + +int user_init() +{ + apol_policy_path_t *ppath = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, SOURCE_POLICY, NULL); + if (ppath == NULL) { + return 1; + } + + if ((sp = apol_policy_create_from_policy_path(ppath, 0, NULL, NULL)) == NULL) { + apol_policy_path_destroy(&ppath); + return 1; + } + apol_policy_path_destroy(&ppath); + + qp = apol_policy_get_qpol(sp); + + return 0; +} + +int user_cleanup() +{ + apol_policy_destroy(&sp); + return 0; +} diff --git a/libapol/tests/user-tests.h b/libapol/tests/user-tests.h new file mode 100644 index 0000000..d725db4 --- /dev/null +++ b/libapol/tests/user-tests.h @@ -0,0 +1,35 @@ +/** + * @file + * + * Declarations for libapol user query tests. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef USER_TESTS_H +#define USER_TESTS_H + +#include <CUnit/CUnit.h> + +extern CU_TestInfo user_tests[]; +extern int user_init(); +extern int user_cleanup(); + +#endif |