summaryrefslogtreecommitdiffstats
path: root/libapol/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libapol/tests')
-rw-r--r--libapol/tests/Makefile.am23
-rw-r--r--libapol/tests/avrule-tests.c161
-rw-r--r--libapol/tests/avrule-tests.h35
-rw-r--r--libapol/tests/constrain-tests.c523
-rw-r--r--libapol/tests/constrain-tests.h33
-rw-r--r--libapol/tests/dta-tests.c529
-rw-r--r--libapol/tests/dta-tests.h35
-rw-r--r--libapol/tests/infoflow-tests.c127
-rw-r--r--libapol/tests/infoflow-tests.h36
-rw-r--r--libapol/tests/libapol-tests.c64
-rw-r--r--libapol/tests/policy-21-tests.c181
-rw-r--r--libapol/tests/policy-21-tests.h35
-rw-r--r--libapol/tests/role-tests.c154
-rw-r--r--libapol/tests/role-tests.h35
-rw-r--r--libapol/tests/terule-tests.c130
-rw-r--r--libapol/tests/terule-tests.h35
-rw-r--r--libapol/tests/user-tests.c159
-rw-r--r--libapol/tests/user-tests.h35
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