/* Authors: Christopher Ashworth * * Copyright (C) 2006 Tresys Technology, LLC * Copyright (C) 2019 Red Hat, Inc. * * 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 */ /* The purpose of this file is to provide some functions commonly needed * by our unit tests. */ #include "utilities.h" int test_store_enabled = 0; semanage_handle_t *sh = NULL; /* Silence any error output caused by our tests * by using this dummy function to catch messages. */ void test_msg_handler(void *varg, semanage_handle_t *handle, const char *fmt, ...) { } int create_test_store(void) { FILE *fptr; if (mkdir("test-policy", 0700) < 0) return -1; if (mkdir("test-policy/store", 0700) < 0) return -1; if (mkdir("test-policy/store/active", 0700) < 0) return -1; if (mkdir("test-policy/store/active/modules", 0700) < 0) return -1; if (mkdir("test-policy/etc", 0700) < 0) return -1; if (mkdir("test-policy/etc/selinux", 0700) < 0) return -1; fptr = fopen("test-policy/etc/selinux/semanage.conf", "w+"); if (!fptr) return -1; fclose(fptr); enable_test_store(); return 0; } void disable_test_store(void) { test_store_enabled = 0; } void enable_test_store(void) { test_store_enabled = 1; } static int write_test_policy(char *data, size_t data_len) { FILE *fptr = fopen("test-policy/store/active/policy.kern", "wb+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite(data, data_len, 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); return 0; } int write_test_policy_from_file(const char *filename) { char *buf = NULL; size_t len = 0; FILE *fptr = fopen(filename, "rb"); int rc; if (!fptr) { perror("fopen"); return -1; } fseek(fptr, 0, SEEK_END); len = ftell(fptr); fseek(fptr, 0, SEEK_SET); buf = (char *) malloc(len); if (!buf) { perror("malloc"); fclose(fptr); return -1; } fread(buf, len, 1, fptr); fclose(fptr); rc = write_test_policy(buf, len); free(buf); return rc; } int write_test_policy_src(unsigned char *data, unsigned int data_len) { if (mkdir("test-policy/store/active/modules/100", 0700) < 0) return -1; if (mkdir("test-policy/store/active/modules/100/base", 0700) < 0) return -1; FILE *fptr = fopen("test-policy/store/active/modules/100/base/cil", "w+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite(data, data_len, 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); fptr = fopen("test-policy/store/active/modules/100/base/lang_ext", "w+"); if (!fptr) { perror("fopen"); return -1; } if (fwrite("cil", sizeof("cil"), 1, fptr) != 1) { perror("fwrite"); fclose(fptr); return -1; } fclose(fptr); return 0; } int destroy_test_store(void) { FTS *ftsp = NULL; FTSENT *curr = NULL; int ret = 0; disable_test_store(); char *files[] = { (char *) "test-policy", NULL }; ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL); if (!ftsp) return -1; while ((curr = fts_read(ftsp))) switch (curr->fts_info) { case FTS_DP: case FTS_F: case FTS_SL: case FTS_SLNONE: case FTS_DEFAULT: if (remove(curr->fts_accpath) < 0) ret = -1; default: break; } fts_close(ftsp); return ret; } void helper_handle_create(void) { if (test_store_enabled) semanage_set_root("test-policy"); sh = semanage_handle_create(); CU_ASSERT_PTR_NOT_NULL(sh); semanage_msg_set_callback(sh, test_msg_handler, NULL); if (test_store_enabled) { semanage_set_create_store(sh, 1); semanage_set_reload(sh, 0); semanage_set_store_root(sh, ""); semanage_select_store(sh, (char *) "store", SEMANAGE_CON_DIRECT); } } void helper_handle_destroy(void) { semanage_handle_destroy(sh); } void helper_connect(void) { CU_ASSERT(semanage_connect(sh) >= 0); } void helper_disconnect(void) { CU_ASSERT(semanage_disconnect(sh) >= 0); } void helper_begin_transaction(void) { CU_ASSERT(semanage_begin_transaction(sh) >= 0); } void helper_commit(void) { CU_ASSERT(semanage_commit(sh) >= 0); } void setup_handle(level_t level) { if (level >= SH_NULL) sh = NULL; if (level >= SH_HANDLE) helper_handle_create(); if (level >= SH_CONNECT) helper_connect(); if (level >= SH_TRANS) helper_begin_transaction(); } void cleanup_handle(level_t level) { if (level >= SH_TRANS) helper_commit(); if (level >= SH_CONNECT) helper_disconnect(); if (level >= SH_HANDLE) helper_handle_destroy(); if (level >= SH_NULL) sh = NULL; } void setup_handle_invalid_store(level_t level) { CU_ASSERT(level >= SH_HANDLE); helper_handle_create(); semanage_select_store(sh, (char *) "", SEMANAGE_CON_INVALID); if (level >= SH_CONNECT) helper_connect(); if (level >= SH_TRANS) helper_begin_transaction(); }