1/*
2 * Author: Joshua Brindle <jbrindle@tresys.com>
3 *         Chad Sellers <csellers@tresys.com>
4 *         Chris PeBenito <cpebenito@tresys.com>
5 *
6 * Copyright (C) 2006 Tresys Technology, LLC
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU Lesser General Public
10 *  License as published by the Free Software Foundation; either
11 *  version 2.1 of the License, or (at your option) any later version.
12 *
13 *  This library is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *  Lesser General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Lesser General Public
19 *  License along with this library; if not, write to the Free Software
20 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 */
22
23/* This has tests that are common between test suites*/
24
25#include <sepol/policydb/avrule_block.h>
26
27#include <CUnit/Basic.h>
28
29void test_sym_presence(policydb_t * p, char *id, int sym_type, unsigned int scope_type, unsigned int *decls, unsigned int len)
30{
31	scope_datum_t *scope;
32	int found;
33	unsigned int i, j;
34	/* make sure it is in global symtab */
35	if (!hashtab_search(p->symtab[sym_type].table, id)) {
36		fprintf(stderr, "symbol %s not found in table %d\n", id, sym_type);
37		CU_FAIL_FATAL();
38	}
39	/* make sure its scope is correct */
40	scope = hashtab_search(p->scope[sym_type].table, id);
41	CU_ASSERT_FATAL(scope != NULL);
42	CU_ASSERT(scope->scope == scope_type);
43	CU_ASSERT(scope->decl_ids_len == len);
44	if (scope->decl_ids_len != len)
45		fprintf(stderr, "sym %s has %d decls, %d expected\n", id, scope->decl_ids_len, len);
46	for (i = 0; i < len; i++) {
47		found = 0;
48		for (j = 0; j < len; j++) {
49			if (decls[i] == scope->decl_ids[j])
50				found++;
51		}
52		CU_ASSERT(found == 1);
53	}
54
55}
56
57static int common_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
58{
59	common_datum_t *d = (common_datum_t *) datum;
60	policydb_t *p = (policydb_t *) data;
61
62	CU_ASSERT(p->sym_val_to_name[SYM_COMMONS][d->s.value - 1] == (char *)key);
63	return 0;
64}
65
66static int class_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
67{
68	class_datum_t *d = (class_datum_t *) datum;
69	policydb_t *p = (policydb_t *) data;
70
71	CU_ASSERT(p->sym_val_to_name[SYM_CLASSES][d->s.value - 1] == (char *)key);
72	CU_ASSERT(p->class_val_to_struct[d->s.value - 1] == d);
73	return 0;
74}
75
76static int role_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
77{
78	role_datum_t *d = (role_datum_t *) datum;
79	policydb_t *p = (policydb_t *) data;
80
81	CU_ASSERT(p->sym_val_to_name[SYM_ROLES][d->s.value - 1] == (char *)key);
82	CU_ASSERT(p->role_val_to_struct[d->s.value - 1] == d);
83	return 0;
84}
85
86static int type_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
87{
88	type_datum_t *d = (type_datum_t *) datum;
89	policydb_t *p = (policydb_t *) data;
90
91	if (!d->primary)
92		return 0;
93
94	CU_ASSERT(p->sym_val_to_name[SYM_TYPES][d->s.value - 1] == (char *)key);
95	CU_ASSERT(p->type_val_to_struct[d->s.value - 1] == d);
96
97	return 0;
98}
99
100static int user_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
101{
102	user_datum_t *d = (user_datum_t *) datum;
103	policydb_t *p = (policydb_t *) data;
104
105	CU_ASSERT(p->sym_val_to_name[SYM_USERS][d->s.value - 1] == (char *)key);
106	CU_ASSERT(p->user_val_to_struct[d->s.value - 1] == d);
107	return 0;
108}
109
110static int cond_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
111{
112	cond_bool_datum_t *d = (cond_bool_datum_t *) datum;
113	policydb_t *p = (policydb_t *) data;
114
115	CU_ASSERT(p->sym_val_to_name[SYM_BOOLS][d->s.value - 1] == (char *)key);
116	CU_ASSERT(p->bool_val_to_struct[d->s.value - 1] == d);
117	return 0;
118}
119
120static int level_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
121{
122	level_datum_t *d = (level_datum_t *) datum;
123	policydb_t *p = (policydb_t *) data;
124
125	CU_ASSERT(p->sym_val_to_name[SYM_LEVELS][d->level->sens - 1] == (char *)key);
126	return 0;
127}
128
129static int cat_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data)
130{
131	cat_datum_t *d = (cat_datum_t *) datum;
132	policydb_t *p = (policydb_t *) data;
133
134	CU_ASSERT(p->sym_val_to_name[SYM_CATS][d->s.value - 1] == (char *)key);
135	return 0;
136}
137
138static int (*test_index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, void *p) = {
139common_test_index, class_test_index, role_test_index, type_test_index, user_test_index, cond_test_index, level_test_index, cat_test_index,};
140
141void test_policydb_indexes(policydb_t * p)
142{
143	int i;
144
145	for (i = 0; i < SYM_NUM; i++) {
146		hashtab_map(p->symtab[i].table, test_index_f[i], p);
147	}
148}
149
150void test_alias_datum(policydb_t * p, char *id, char *primary_id, char mode, unsigned int flavor)
151{
152	type_datum_t *type, *primary;
153	unsigned int my_primary, my_flavor, my_value;
154
155	type = hashtab_search(p->p_types.table, id);
156	primary = hashtab_search(p->p_types.table, primary_id);
157
158	CU_ASSERT_PTR_NOT_NULL(type);
159	CU_ASSERT_PTR_NOT_NULL(primary);
160
161	if (type && primary) {
162		if (mode) {
163			my_flavor = type->flavor;
164		} else {
165			my_flavor = flavor;
166		}
167
168		if (my_flavor == TYPE_TYPE) {
169			my_primary = 0;
170			my_value = primary->s.value;
171		} else if (my_flavor == TYPE_ALIAS) {
172			my_primary = primary->s.value;
173			CU_ASSERT_NOT_EQUAL(type->s.value, primary->s.value);
174			my_value = type->s.value;
175		} else {
176			CU_FAIL("not an alias");
177		}
178
179		CU_ASSERT(type->primary == my_primary);
180		CU_ASSERT(type->flavor == my_flavor);
181		CU_ASSERT(type->s.value == my_value);
182	}
183}
184
185role_datum_t *test_role_type_set(policydb_t * p, char *id, avrule_decl_t * decl, char **types, unsigned int len, unsigned int flags)
186{
187	ebitmap_node_t *tnode;
188	unsigned int i, j, new, found = 0;
189	role_datum_t *role;
190
191	if (decl)
192		role = hashtab_search(decl->p_roles.table, id);
193	else
194		role = hashtab_search(p->p_roles.table, id);
195
196	if (!role)
197		printf("role %s can't be found! \n", id);
198
199	CU_ASSERT_FATAL(role != NULL);
200
201	ebitmap_for_each_bit(&role->types.types, tnode, i) {
202		if (ebitmap_node_get_bit(tnode, i)) {
203			new = 0;
204			for (j = 0; j < len; j++) {
205				if (strcmp(p->sym_val_to_name[SYM_TYPES][i], types[j]) == 0) {
206					found++;
207					new = 1;
208				}
209			}
210			if (new == 0) {
211				printf("\nRole %s had type %s not in types array\n", id, p->sym_val_to_name[SYM_TYPES][i]);
212			}
213			CU_ASSERT(new == 1);
214		}
215	}
216	CU_ASSERT(found == len);
217	if (found != len)
218		printf("\nrole %s has %d types, %d expected\n", p->sym_val_to_name[SYM_ROLES][role->s.value - 1], found, len);
219	/* roles should never have anything in the negset */
220	CU_ASSERT(role->types.negset.highbit == 0);
221	CU_ASSERT(role->types.flags == flags);
222
223	return role;
224}
225
226void test_attr_types(policydb_t * p, char *id, avrule_decl_t * decl, char **types, int len)
227{
228	ebitmap_node_t *tnode;
229	int j, new, found = 0;
230	unsigned int i;
231	type_datum_t *attr;
232
233	if (decl)
234		attr = hashtab_search(decl->p_types.table, id);
235	else
236		attr = hashtab_search(p->p_types.table, id);
237
238	if (attr == NULL)
239		printf("could not find attr %s in decl %d\n", id, decl->decl_id);
240	CU_ASSERT_FATAL(attr != NULL);
241	CU_ASSERT(attr->flavor == TYPE_ATTRIB);
242	CU_ASSERT(attr->primary == 1);
243
244	ebitmap_for_each_bit(&attr->types, tnode, i) {
245		if (ebitmap_node_get_bit(tnode, i)) {
246			new = 0;
247			for (j = 0; j < len; j++) {
248				if (strcmp(p->sym_val_to_name[SYM_TYPES][i], types[j]) == 0) {
249					found++;
250					new = 1;
251				}
252			}
253			if (new == 0) {
254				printf("\nattr %s had type %s not in types array\n", id, p->sym_val_to_name[SYM_TYPES][i]);
255			}
256			CU_ASSERT(new == 1);
257		}
258	}
259	CU_ASSERT(found == len);
260	if (found != len)
261		printf("\nattr %s has %d types, %d expected\n", id, found, len);
262}
263