Home | History | Annotate | Download | only in tests
      1 /* Authors: Christopher Ashworth <cashworth (at) tresys.com>
      2  *          Caleb Case <ccase (at) tresys.com>
      3  *          Chris PeBenito <cpebenito (at) tresys.com>
      4  *
      5  * Copyright (C) 2006 Tresys Technology, LLC
      6  *
      7  *  This library is free software; you can redistribute it and/or
      8  *  modify it under the terms of the GNU Lesser General Public
      9  *  License as published by the Free Software Foundation; either
     10  *  version 2.1 of the License, or (at your option) any later version.
     11  *
     12  *  This library is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  *  Lesser General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU Lesser General Public
     18  *  License along with this library; if not, write to the Free Software
     19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20  */
     21 
     22 /*  The purpose of this file is to provide unit tests of the functions in:
     23  *
     24  *  libsemanage/src/semanage_store.c
     25  *
     26  */
     27 
     28 #include "handle.h"
     29 #include "semanage_store.h"
     30 
     31 #include "utilities.h"
     32 #include "test_semanage_store.h"
     33 
     34 #include <libgen.h>
     35 #include <limits.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <sys/mman.h>
     40 #include <sys/types.h>
     41 #include <sys/stat.h>
     42 #include <fcntl.h>
     43 #include <unistd.h>
     44 #include <CUnit/Basic.h>
     45 
     46 semanage_handle_t *sh = NULL;
     47 const char *rootpath = "./test-policy";
     48 const char *polpath = "./test-policy/store/";
     49 const char *readlockpath = "./test-policy/store/semanage.read.LOCK";
     50 const char *translockpath = "./test-policy/store/semanage.trans.LOCK";
     51 const char *actpath = "./test-policy/store/active";
     52 const char *modpath = "./test-policy/store/active/modules";
     53 
     54 /* The suite initialization function.
     55  * Returns zero on success, non-zero otherwise.
     56  */
     57 int semanage_store_test_init(void)
     58 {
     59 	int err;
     60 
     61 	/* create directories */
     62 	err = mkdir(rootpath, S_IRUSR | S_IWUSR | S_IXUSR);
     63 	if (err != 0)
     64 		return -1;
     65 
     66 	err = mkdir(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
     67 	if (err != 0)
     68 		return -1;
     69 
     70 	err = mkdir(actpath, S_IRUSR | S_IWUSR | S_IXUSR);
     71 	if (err != 0)
     72 		return -1;
     73 
     74 	err = mkdir(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
     75 	if (err != 0)
     76 		return -1;
     77 
     78 	/* initialize the handle */
     79 	sh = semanage_handle_create();
     80 	if (sh == NULL)
     81 		return -1;
     82 
     83 	/* hide error messages */
     84 	sh->msg_callback = test_msg_handler;
     85 
     86 	/* use our own policy store */
     87 	free(sh->conf->store_path);
     88 	sh->conf->store_path = strdup("store");
     89 
     90 	/* initialize paths */
     91 	err = semanage_check_init(sh, rootpath);
     92 	if (err != 0)
     93 		return -1;
     94 
     95 	return 0;
     96 }
     97 
     98 /* The suite cleanup function.
     99  * Returns zero on success, non-zero otherwise.
    100  */
    101 int semanage_store_test_cleanup(void)
    102 {
    103 	int err;
    104 
    105 	/* remove the test policy directories */
    106 	err = rmdir(modpath);
    107 	if (err != 0)
    108 		return -1;
    109 
    110 	err = rmdir(actpath);
    111 	if (err != 0)
    112 		return -1;
    113 
    114 	err = rmdir(polpath);
    115 	if (err != 0)
    116 		return -1;
    117 
    118 	err = rmdir(rootpath);
    119 	if (err != 0)
    120 		return -1;
    121 
    122 	/* cleanup the handle */
    123 	semanage_handle_destroy(sh);
    124 	return 0;
    125 }
    126 
    127 /* Adds all the tests needed for this suite.
    128  */
    129 int semanage_store_add_tests(CU_pSuite suite)
    130 {
    131 	if (NULL ==
    132 	    CU_add_test(suite, "semanage_store_access_check",
    133 			test_semanage_store_access_check)) {
    134 		CU_cleanup_registry();
    135 		return CU_get_error();
    136 	}
    137 
    138 	if (NULL ==
    139 	    CU_add_test(suite, "semanage_get_lock", test_semanage_get_lock)) {
    140 		CU_cleanup_registry();
    141 		return CU_get_error();
    142 	}
    143 
    144 	if (NULL ==
    145 	    CU_add_test(suite, "semanage_nc_sort", test_semanage_nc_sort)) {
    146 		CU_cleanup_registry();
    147 		return CU_get_error();
    148 	}
    149 
    150 	return 0;
    151 }
    152 
    153 /* Tests the semanage_store_access_check function in semanage_store.c
    154  */
    155 void test_semanage_store_access_check(void)
    156 {
    157 	int err;
    158 
    159 	/* create lock file */
    160 	err = mknod(readlockpath, S_IRUSR | S_IWUSR, S_IFREG);
    161 
    162 	/* check with permissions 000 */
    163 	err = chmod(modpath, 0);
    164 	CU_ASSERT(err == 0);
    165 	err = chmod(readlockpath, 0);
    166 	CU_ASSERT(err == 0);
    167 	err = chmod(polpath, 0);
    168 	CU_ASSERT(err == 0);
    169 
    170 	err = semanage_store_access_check();
    171 	CU_ASSERT(err == -1);
    172 
    173 	/* check with permissions 500 */
    174 	err = chmod(polpath, S_IRUSR | S_IXUSR);
    175 	CU_ASSERT(err == 0);
    176 	err = chmod(readlockpath, S_IRUSR);
    177 	CU_ASSERT(err == 0);
    178 	err = chmod(modpath, S_IRUSR | S_IXUSR);
    179 	CU_ASSERT(err == 0);
    180 
    181 	err = semanage_store_access_check();
    182 	CU_ASSERT(err == SEMANAGE_CAN_READ);
    183 
    184 	/* check with permissions 700 */
    185 	err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
    186 	CU_ASSERT(err == 0);
    187 	err = chmod(readlockpath, S_IRUSR | S_IWUSR);
    188 	CU_ASSERT(err == 0);
    189 	err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
    190 	CU_ASSERT(err == 0);
    191 
    192 	err = semanage_store_access_check();
    193 	CU_ASSERT(err == SEMANAGE_CAN_WRITE);
    194 
    195 	/* check with lock file 000 and others 500 */
    196 	err = chmod(polpath, S_IRUSR | S_IXUSR);
    197 	CU_ASSERT(err == 0);
    198 	err = chmod(readlockpath, 0);
    199 	CU_ASSERT(err == 0);
    200 	err = chmod(modpath, S_IRUSR | S_IXUSR);
    201 	CU_ASSERT(err == 0);
    202 
    203 	err = semanage_store_access_check();
    204 	CU_ASSERT(err == 0);
    205 
    206 	/* check with lock file 000 and others 700 */
    207 	err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
    208 	CU_ASSERT(err == 0);
    209 	err = chmod(readlockpath, 0);
    210 	CU_ASSERT(err == 0);
    211 	err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
    212 	CU_ASSERT(err == 0);
    213 
    214 	err = semanage_store_access_check();
    215 	CU_ASSERT(err == 0);
    216 
    217 	/* remove lock file */
    218 	err = remove(readlockpath);
    219 	CU_ASSERT(err == 0);
    220 
    221 	/* check with no lock file and 000 */
    222 	err = chmod(modpath, 0);
    223 	CU_ASSERT(err == 0);
    224 	err = chmod(polpath, 0);
    225 	CU_ASSERT(err == 0);
    226 
    227 	err = semanage_store_access_check();
    228 	CU_ASSERT(err == -1);
    229 
    230 	/* check with no lock file and 500 */
    231 	err = chmod(polpath, S_IRUSR | S_IXUSR);
    232 	CU_ASSERT(err == 0);
    233 	err = chmod(modpath, S_IRUSR | S_IXUSR);
    234 	CU_ASSERT(err == 0);
    235 
    236 	err = semanage_store_access_check();
    237 	CU_ASSERT(err == 0);
    238 
    239 	/* check with no lock file but write in polpath */
    240 	err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
    241 	CU_ASSERT(err == 0);
    242 
    243 	err = semanage_store_access_check();
    244 	CU_ASSERT(err == SEMANAGE_CAN_READ);
    245 
    246 	/* check with no lock file and 700 */
    247 	err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
    248 	CU_ASSERT(err == 0);
    249 	err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
    250 	CU_ASSERT(err == 0);
    251 
    252 	err = semanage_store_access_check();
    253 	CU_ASSERT(err == SEMANAGE_CAN_WRITE);
    254 }
    255 
    256 /* Tests the semanage_get_lock functions in semanage_store.c
    257  */
    258 void test_semanage_get_lock(void)
    259 {
    260 	int err;
    261 
    262 	/* attempt to get an active lock */
    263 	err = semanage_get_active_lock(sh);
    264 	CU_ASSERT(err == 0);
    265 
    266 	/* attempt to get the lock again */
    267 	err = semanage_get_active_lock(sh);
    268 	CU_ASSERT(err == 0);
    269 
    270 	/* attempt to release the active lock */
    271 	semanage_release_active_lock(sh);
    272 
    273 	/* attempt to get an active lock */
    274 	err = semanage_get_active_lock(sh);
    275 	CU_ASSERT(err == 0);
    276 
    277 	/* attempt to release the active lock */
    278 	semanage_release_active_lock(sh);
    279 
    280 	/* attempt to get a trans lock */
    281 	err = semanage_get_trans_lock(sh);
    282 	CU_ASSERT(err == 0);
    283 
    284 	/* attempt to get the lock again */
    285 	err = semanage_get_trans_lock(sh);
    286 	CU_ASSERT(err == 0);
    287 
    288 	/* attempt to release the trans lock */
    289 	semanage_release_trans_lock(sh);
    290 
    291 	/* attempt to get a trans lock */
    292 	err = semanage_get_trans_lock(sh);
    293 	CU_ASSERT(err == 0);
    294 
    295 	/* attempt to release the trans lock */
    296 	semanage_release_trans_lock(sh);
    297 
    298 	/* remove the lock files */
    299 	err = remove(readlockpath);
    300 	CU_ASSERT(err == 0);
    301 	err = remove(translockpath);
    302 	CU_ASSERT(err == 0);
    303 }
    304 
    305 /* Tests the semanage_nc_sort function in semanage_store.c
    306  */
    307 void test_semanage_nc_sort(void)
    308 {
    309 	char *source_buf, *sorted_buf = NULL, *good_buf, *bad_buf;
    310 	size_t source_buf_len, sorted_buf_len, good_buf_len, bad_buf_len;
    311 	int sourcefd, goodfd, badfd, err;
    312 	struct stat sb;
    313 
    314 	/* open source file */
    315 	sourcefd = open("nc_sort_unsorted", O_RDONLY);
    316 	if (sourcefd < 0) {
    317 		CU_FAIL("Missing nc_sort_unsorted test file.");
    318 		return;
    319 	}
    320 	fstat(sourcefd, &sb);
    321 	source_buf_len = sb.st_size;
    322 	source_buf =
    323 	    (char *)mmap(NULL, source_buf_len, PROT_READ, MAP_PRIVATE, sourcefd,
    324 			 0);
    325 
    326 	/* open good result file */
    327 	goodfd = open("nc_sort_sorted", O_RDONLY);
    328 	if (goodfd < 0) {
    329 		CU_FAIL("Missing nc_sort_sorted test file.");
    330 		goto out2;
    331 	}
    332 	fstat(goodfd, &sb);
    333 	good_buf_len = sb.st_size;
    334 	good_buf =
    335 	    (char *)mmap(NULL, good_buf_len, PROT_READ, MAP_PRIVATE, goodfd, 0);
    336 
    337 	/* open malformed source file (missing priorities) */
    338 	badfd = open("nc_sort_malformed", O_RDONLY);
    339 	if (badfd < 0) {
    340 		CU_FAIL("Missing nc_sort_malformed test file.");
    341 		goto out1;
    342 	}
    343 	fstat(badfd, &sb);
    344 	bad_buf_len = sb.st_size;
    345 	bad_buf =
    346 	    (char *)mmap(NULL, bad_buf_len, PROT_READ, MAP_PRIVATE, badfd, 0);
    347 
    348 	/* sort test file */
    349 	err =
    350 	    semanage_nc_sort(sh, source_buf, source_buf_len, &sorted_buf,
    351 			     &sorted_buf_len);
    352 	CU_ASSERT_FALSE(err);
    353 	CU_ASSERT_STRING_EQUAL(sorted_buf, good_buf);
    354 
    355 	/* reset for reuse in next test */
    356 	free(sorted_buf);
    357 	sorted_buf = NULL;
    358 
    359 	/* sort malformed source file */
    360 	err =
    361 	    semanage_nc_sort(sh, bad_buf, bad_buf_len, &sorted_buf,
    362 			     &sorted_buf_len);
    363 	CU_ASSERT_EQUAL(err, -1);
    364 
    365 	free(sorted_buf);
    366 
    367 	munmap(bad_buf, bad_buf_len);
    368 	close(badfd);
    369       out1:
    370 	munmap(good_buf, good_buf_len);
    371 	close(goodfd);
    372       out2:
    373 	munmap(source_buf, source_buf_len);
    374 	close(sourcefd);
    375 }
    376