1 /* Authors: Christopher Ashworth <cashworth@tresys.com>
2 *
3 * Copyright (C) 2006 Tresys Technology, LLC
4 * Copyright (C) 2019 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /* The purpose of this file is to provide some functions commonly needed
22 * by our unit tests.
23 */
24
25 #include "utilities.h"
26
27 int test_store_enabled = 0;
28
29 semanage_handle_t *sh = NULL;
30
31 /* Silence any error output caused by our tests
32 * by using this dummy function to catch messages.
33 */
test_msg_handler(void * varg,semanage_handle_t * handle,const char * fmt,...)34 void test_msg_handler(void *varg, semanage_handle_t *handle, const char *fmt,
35 ...)
36 {
37 }
38
create_test_store()39 int create_test_store() {
40 FILE *fptr;
41
42 if (mkdir("test-policy", 0700) < 0)
43 return -1;
44
45 if (mkdir("test-policy/store", 0700) < 0)
46 return -1;
47
48 if (mkdir("test-policy/store/active", 0700) < 0)
49 return -1;
50
51 if (mkdir("test-policy/store/active/modules", 0700) < 0)
52 return -1;
53
54 if (mkdir("test-policy/etc", 0700) < 0)
55 return -1;
56
57 if (mkdir("test-policy/etc/selinux", 0700) < 0)
58 return -1;
59
60 fptr = fopen("test-policy/etc/selinux/semanage.conf", "w+");
61
62 if (!fptr)
63 return -1;
64
65 fclose(fptr);
66
67 enable_test_store();
68 return 0;
69 }
70
disable_test_store(void)71 void disable_test_store(void) {
72 test_store_enabled = 0;
73 }
74
enable_test_store(void)75 void enable_test_store(void) {
76 test_store_enabled = 1;
77 }
78
write_test_policy(char * data,size_t data_len)79 int write_test_policy(char *data, size_t data_len) {
80 FILE *fptr = fopen("test-policy/store/active/policy.kern", "wb+");
81
82 if (!fptr) {
83 perror("fopen");
84 return -1;
85 }
86
87 if (fwrite(data, data_len, 1, fptr) != 1) {
88 perror("fwrite");
89 fclose(fptr);
90 return -1;
91 }
92
93 fclose(fptr);
94
95 return 0;
96 }
97
write_test_policy_from_file(const char * filename)98 int write_test_policy_from_file(const char *filename) {
99 char *buf = NULL;
100 size_t len = 0;
101 FILE *fptr = fopen(filename, "rb");
102
103 if (!fptr) {
104 perror("fopen");
105 return -1;
106 }
107
108 fseek(fptr, 0, SEEK_END);
109 len = ftell(fptr);
110 fseek(fptr, 0, SEEK_SET);
111
112 buf = (char *) malloc(len);
113
114 if (!buf) {
115 perror("malloc");
116 fclose(fptr);
117 return -1;
118 }
119
120 fread(buf, len, 1, fptr);
121 fclose(fptr);
122
123 return write_test_policy(buf, len);
124 }
125
write_test_policy_src(unsigned char * data,unsigned int data_len)126 int write_test_policy_src(unsigned char *data, unsigned int data_len) {
127 if (mkdir("test-policy/store/active/modules/100", 0700) < 0)
128 return -1;
129
130 if (mkdir("test-policy/store/active/modules/100/base", 0700) < 0)
131 return -1;
132
133 FILE *fptr = fopen("test-policy/store/active/modules/100/base/cil",
134 "w+");
135
136 if (!fptr) {
137 perror("fopen");
138 return -1;
139 }
140
141 if (fwrite(data, data_len, 1, fptr) != 1) {
142 perror("fwrite");
143 fclose(fptr);
144 return -1;
145 }
146
147 fclose(fptr);
148
149 fptr = fopen("test-policy/store/active/modules/100/base/lang_ext",
150 "w+");
151
152 if (!fptr) {
153 perror("fopen");
154 return -1;
155 }
156
157 if (fwrite("cil", sizeof("cil"), 1, fptr) != 1) {
158 perror("fwrite");
159 fclose(fptr);
160 return -1;
161 }
162
163 fclose(fptr);
164
165 return 0;
166 }
167
destroy_test_store()168 int destroy_test_store() {
169 FTS *ftsp = NULL;
170 FTSENT *curr = NULL;
171 int ret = 0;
172
173 disable_test_store();
174
175 char *files[] = { (char *) "test-policy", NULL };
176
177 ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
178
179 if (!ftsp)
180 return -1;
181
182 while ((curr = fts_read(ftsp)))
183 switch (curr->fts_info) {
184 case FTS_DP:
185 case FTS_F:
186 case FTS_SL:
187 case FTS_SLNONE:
188 case FTS_DEFAULT:
189 if (remove(curr->fts_accpath) < 0)
190 ret = -1;
191 default:
192 break;
193 }
194
195 fts_close(ftsp);
196
197 return ret;
198 }
199
helper_handle_create(void)200 void helper_handle_create(void) {
201 if (test_store_enabled)
202 semanage_set_root("test-policy");
203
204 sh = semanage_handle_create();
205 CU_ASSERT_PTR_NOT_NULL(sh);
206
207 semanage_msg_set_callback(sh, test_msg_handler, NULL);
208
209 if (test_store_enabled) {
210 semanage_set_create_store(sh, 1);
211 semanage_set_reload(sh, 0);
212 semanage_set_store_root(sh, "");
213 semanage_select_store(sh, (char *) "store",
214 SEMANAGE_CON_DIRECT);
215 }
216 }
217
helper_handle_destroy(void)218 void helper_handle_destroy(void) {
219 semanage_handle_destroy(sh);
220 }
221
helper_connect(void)222 void helper_connect(void) {
223 CU_ASSERT(semanage_connect(sh) >= 0);
224 }
225
helper_disconnect(void)226 void helper_disconnect(void) {
227 CU_ASSERT(semanage_disconnect(sh) >= 0);
228 }
229
helper_begin_transaction(void)230 void helper_begin_transaction(void) {
231 CU_ASSERT(semanage_begin_transaction(sh) >= 0);
232 }
233
helper_commit(void)234 void helper_commit(void) {
235 CU_ASSERT(semanage_commit(sh) >= 0);
236 }
237
setup_handle(level_t level)238 void setup_handle(level_t level) {
239 if (level >= SH_NULL)
240 sh = NULL;
241
242 if (level >= SH_HANDLE)
243 helper_handle_create();
244
245 if (level >= SH_CONNECT)
246 helper_connect();
247
248 if (level >= SH_TRANS)
249 helper_begin_transaction();
250 }
251
cleanup_handle(level_t level)252 void cleanup_handle(level_t level) {
253 if (level >= SH_TRANS)
254 helper_commit();
255
256 if (level >= SH_CONNECT)
257 helper_disconnect();
258
259 if (level >= SH_HANDLE)
260 helper_handle_destroy();
261
262 if (level >= SH_NULL)
263 sh = NULL;
264 }
265
setup_handle_invalid_store(level_t level)266 void setup_handle_invalid_store(level_t level) {
267 CU_ASSERT(level >= SH_HANDLE);
268
269 helper_handle_create();
270
271 semanage_select_store(sh, (char *) "", SEMANAGE_CON_INVALID);
272
273 if (level >= SH_CONNECT)
274 helper_connect();
275
276 if (level >= SH_TRANS)
277 helper_begin_transaction();
278 }
279