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 static 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 int rc;
103
104 if (!fptr) {
105 perror("fopen");
106 return -1;
107 }
108
109 fseek(fptr, 0, SEEK_END);
110 len = ftell(fptr);
111 fseek(fptr, 0, SEEK_SET);
112
113 buf = (char *) malloc(len);
114
115 if (!buf) {
116 perror("malloc");
117 fclose(fptr);
118 return -1;
119 }
120
121 fread(buf, len, 1, fptr);
122 fclose(fptr);
123
124 rc = write_test_policy(buf, len);
125 free(buf);
126 return rc;
127 }
128
write_test_policy_src(unsigned char * data,unsigned int data_len)129 int write_test_policy_src(unsigned char *data, unsigned int data_len) {
130 if (mkdir("test-policy/store/active/modules/100", 0700) < 0)
131 return -1;
132
133 if (mkdir("test-policy/store/active/modules/100/base", 0700) < 0)
134 return -1;
135
136 FILE *fptr = fopen("test-policy/store/active/modules/100/base/cil",
137 "w+");
138
139 if (!fptr) {
140 perror("fopen");
141 return -1;
142 }
143
144 if (fwrite(data, data_len, 1, fptr) != 1) {
145 perror("fwrite");
146 fclose(fptr);
147 return -1;
148 }
149
150 fclose(fptr);
151
152 fptr = fopen("test-policy/store/active/modules/100/base/lang_ext",
153 "w+");
154
155 if (!fptr) {
156 perror("fopen");
157 return -1;
158 }
159
160 if (fwrite("cil", sizeof("cil"), 1, fptr) != 1) {
161 perror("fwrite");
162 fclose(fptr);
163 return -1;
164 }
165
166 fclose(fptr);
167
168 return 0;
169 }
170
destroy_test_store()171 int destroy_test_store() {
172 FTS *ftsp = NULL;
173 FTSENT *curr = NULL;
174 int ret = 0;
175
176 disable_test_store();
177
178 char *files[] = { (char *) "test-policy", NULL };
179
180 ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
181
182 if (!ftsp)
183 return -1;
184
185 while ((curr = fts_read(ftsp)))
186 switch (curr->fts_info) {
187 case FTS_DP:
188 case FTS_F:
189 case FTS_SL:
190 case FTS_SLNONE:
191 case FTS_DEFAULT:
192 if (remove(curr->fts_accpath) < 0)
193 ret = -1;
194 default:
195 break;
196 }
197
198 fts_close(ftsp);
199
200 return ret;
201 }
202
helper_handle_create(void)203 void helper_handle_create(void) {
204 if (test_store_enabled)
205 semanage_set_root("test-policy");
206
207 sh = semanage_handle_create();
208 CU_ASSERT_PTR_NOT_NULL(sh);
209
210 semanage_msg_set_callback(sh, test_msg_handler, NULL);
211
212 if (test_store_enabled) {
213 semanage_set_create_store(sh, 1);
214 semanage_set_reload(sh, 0);
215 semanage_set_store_root(sh, "");
216 semanage_select_store(sh, (char *) "store",
217 SEMANAGE_CON_DIRECT);
218 }
219 }
220
helper_handle_destroy(void)221 void helper_handle_destroy(void) {
222 semanage_handle_destroy(sh);
223 }
224
helper_connect(void)225 void helper_connect(void) {
226 CU_ASSERT(semanage_connect(sh) >= 0);
227 }
228
helper_disconnect(void)229 void helper_disconnect(void) {
230 CU_ASSERT(semanage_disconnect(sh) >= 0);
231 }
232
helper_begin_transaction(void)233 void helper_begin_transaction(void) {
234 CU_ASSERT(semanage_begin_transaction(sh) >= 0);
235 }
236
helper_commit(void)237 void helper_commit(void) {
238 CU_ASSERT(semanage_commit(sh) >= 0);
239 }
240
setup_handle(level_t level)241 void setup_handle(level_t level) {
242 if (level >= SH_NULL)
243 sh = NULL;
244
245 if (level >= SH_HANDLE)
246 helper_handle_create();
247
248 if (level >= SH_CONNECT)
249 helper_connect();
250
251 if (level >= SH_TRANS)
252 helper_begin_transaction();
253 }
254
cleanup_handle(level_t level)255 void cleanup_handle(level_t level) {
256 if (level >= SH_TRANS)
257 helper_commit();
258
259 if (level >= SH_CONNECT)
260 helper_disconnect();
261
262 if (level >= SH_HANDLE)
263 helper_handle_destroy();
264
265 if (level >= SH_NULL)
266 sh = NULL;
267 }
268
setup_handle_invalid_store(level_t level)269 void setup_handle_invalid_store(level_t level) {
270 CU_ASSERT(level >= SH_HANDLE);
271
272 helper_handle_create();
273
274 semanage_select_store(sh, (char *) "", SEMANAGE_CON_INVALID);
275
276 if (level >= SH_CONNECT)
277 helper_connect();
278
279 if (level >= SH_TRANS)
280 helper_begin_transaction();
281 }
282