16cd6a6acSopenharmony_ci/* 26cd6a6acSopenharmony_ci * Copyright 2011 Tresys Technology, LLC. All rights reserved. 36cd6a6acSopenharmony_ci * 46cd6a6acSopenharmony_ci * Redistribution and use in source and binary forms, with or without 56cd6a6acSopenharmony_ci * modification, are permitted provided that the following conditions are met: 66cd6a6acSopenharmony_ci * 76cd6a6acSopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, 86cd6a6acSopenharmony_ci * this list of conditions and the following disclaimer. 96cd6a6acSopenharmony_ci * 106cd6a6acSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, 116cd6a6acSopenharmony_ci * this list of conditions and the following disclaimer in the documentation 126cd6a6acSopenharmony_ci * and/or other materials provided with the distribution. 136cd6a6acSopenharmony_ci * 146cd6a6acSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 156cd6a6acSopenharmony_ci * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 166cd6a6acSopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 176cd6a6acSopenharmony_ci * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 186cd6a6acSopenharmony_ci * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 196cd6a6acSopenharmony_ci * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 206cd6a6acSopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 216cd6a6acSopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 226cd6a6acSopenharmony_ci * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 236cd6a6acSopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 246cd6a6acSopenharmony_ci * 256cd6a6acSopenharmony_ci * The views and conclusions contained in the software and documentation are those 266cd6a6acSopenharmony_ci * of the authors and should not be interpreted as representing official policies, 276cd6a6acSopenharmony_ci * either expressed or implied, of Tresys Technology, LLC. 286cd6a6acSopenharmony_ci */ 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci#include <stdlib.h> 316cd6a6acSopenharmony_ci#include <stdio.h> 326cd6a6acSopenharmony_ci#include <stdint.h> 336cd6a6acSopenharmony_ci#include <string.h> 346cd6a6acSopenharmony_ci#include <getopt.h> 356cd6a6acSopenharmony_ci#include <sys/stat.h> 366cd6a6acSopenharmony_ci 376cd6a6acSopenharmony_ci#ifdef ANDROID 386cd6a6acSopenharmony_ci#include <cil/cil.h> 396cd6a6acSopenharmony_ci#else 406cd6a6acSopenharmony_ci#include <sepol/cil/cil.h> 416cd6a6acSopenharmony_ci#endif 426cd6a6acSopenharmony_ci#include <sepol/policydb.h> 436cd6a6acSopenharmony_ci 446cd6a6acSopenharmony_cistatic __attribute__((__noreturn__)) void usage(const char *prog) 456cd6a6acSopenharmony_ci{ 466cd6a6acSopenharmony_ci printf("Usage: %s [OPTION]... FILE...\n", prog); 476cd6a6acSopenharmony_ci printf("\n"); 486cd6a6acSopenharmony_ci printf("Options:\n"); 496cd6a6acSopenharmony_ci printf(" -o, --output=<file> write policy.conf to <file>\n"); 506cd6a6acSopenharmony_ci printf(" (default: policy.conf)\n"); 516cd6a6acSopenharmony_ci printf(" -M, --mls true|false write an mls policy. Must be true or false.\n"); 526cd6a6acSopenharmony_ci printf(" This will override the (mls boolean) statement\n"); 536cd6a6acSopenharmony_ci printf(" if present in the policy\n"); 546cd6a6acSopenharmony_ci printf(" -P, --preserve-tunables treat tunables as booleans\n"); 556cd6a6acSopenharmony_ci printf(" -Q, --qualified-names Allow names containing dots (qualified names).\n"); 566cd6a6acSopenharmony_ci printf(" Blocks, blockinherits, blockabstracts, and\n"); 576cd6a6acSopenharmony_ci printf(" in-statements will not be allowed.\n"); 586cd6a6acSopenharmony_ci printf(" -v, --verbose increment verbosity level\n"); 596cd6a6acSopenharmony_ci printf(" -h, --help display usage information\n"); 606cd6a6acSopenharmony_ci exit(1); 616cd6a6acSopenharmony_ci} 626cd6a6acSopenharmony_ci 636cd6a6acSopenharmony_ciint main(int argc, char *argv[]) 646cd6a6acSopenharmony_ci{ 656cd6a6acSopenharmony_ci int rc = SEPOL_ERR; 666cd6a6acSopenharmony_ci FILE *file = NULL; 676cd6a6acSopenharmony_ci char *buffer = NULL; 686cd6a6acSopenharmony_ci struct stat filedata; 696cd6a6acSopenharmony_ci uint32_t file_size; 706cd6a6acSopenharmony_ci char *output = NULL; 716cd6a6acSopenharmony_ci struct cil_db *db = NULL; 726cd6a6acSopenharmony_ci int mls = -1; 736cd6a6acSopenharmony_ci int preserve_tunables = 0; 746cd6a6acSopenharmony_ci int qualified_names = 0; 756cd6a6acSopenharmony_ci int opt_char; 766cd6a6acSopenharmony_ci int opt_index = 0; 776cd6a6acSopenharmony_ci enum cil_log_level log_level = CIL_ERR; 786cd6a6acSopenharmony_ci static struct option long_opts[] = { 796cd6a6acSopenharmony_ci {"help", no_argument, 0, 'h'}, 806cd6a6acSopenharmony_ci {"verbose", no_argument, 0, 'v'}, 816cd6a6acSopenharmony_ci {"mls", required_argument, 0, 'M'}, 826cd6a6acSopenharmony_ci {"preserve-tunables", no_argument, 0, 'P'}, 836cd6a6acSopenharmony_ci {"qualified-names", no_argument, 0, 'Q'}, 846cd6a6acSopenharmony_ci {"output", required_argument, 0, 'o'}, 856cd6a6acSopenharmony_ci {0, 0, 0, 0} 866cd6a6acSopenharmony_ci }; 876cd6a6acSopenharmony_ci int i; 886cd6a6acSopenharmony_ci 896cd6a6acSopenharmony_ci while (1) { 906cd6a6acSopenharmony_ci opt_char = getopt_long(argc, argv, "o:hvM:PQ", long_opts, &opt_index); 916cd6a6acSopenharmony_ci if (opt_char == -1) { 926cd6a6acSopenharmony_ci break; 936cd6a6acSopenharmony_ci } 946cd6a6acSopenharmony_ci switch (opt_char) { 956cd6a6acSopenharmony_ci case 'v': 966cd6a6acSopenharmony_ci log_level++; 976cd6a6acSopenharmony_ci break; 986cd6a6acSopenharmony_ci case 'M': 996cd6a6acSopenharmony_ci if (!strcasecmp(optarg, "true") || !strcasecmp(optarg, "1")) { 1006cd6a6acSopenharmony_ci mls = 1; 1016cd6a6acSopenharmony_ci } else if (!strcasecmp(optarg, "false") || !strcasecmp(optarg, "0")) { 1026cd6a6acSopenharmony_ci mls = 0; 1036cd6a6acSopenharmony_ci } else { 1046cd6a6acSopenharmony_ci usage(argv[0]); 1056cd6a6acSopenharmony_ci } 1066cd6a6acSopenharmony_ci break; 1076cd6a6acSopenharmony_ci case 'P': 1086cd6a6acSopenharmony_ci preserve_tunables = 1; 1096cd6a6acSopenharmony_ci break; 1106cd6a6acSopenharmony_ci case 'Q': 1116cd6a6acSopenharmony_ci qualified_names = 1; 1126cd6a6acSopenharmony_ci break; 1136cd6a6acSopenharmony_ci case 'o': 1146cd6a6acSopenharmony_ci free(output); 1156cd6a6acSopenharmony_ci output = strdup(optarg); 1166cd6a6acSopenharmony_ci break; 1176cd6a6acSopenharmony_ci case 'h': 1186cd6a6acSopenharmony_ci usage(argv[0]); 1196cd6a6acSopenharmony_ci case '?': 1206cd6a6acSopenharmony_ci break; 1216cd6a6acSopenharmony_ci default: 1226cd6a6acSopenharmony_ci fprintf(stderr, "Unsupported option: %s\n", optarg); 1236cd6a6acSopenharmony_ci usage(argv[0]); 1246cd6a6acSopenharmony_ci } 1256cd6a6acSopenharmony_ci } 1266cd6a6acSopenharmony_ci if (optind >= argc) { 1276cd6a6acSopenharmony_ci fprintf(stderr, "No cil files specified\n"); 1286cd6a6acSopenharmony_ci usage(argv[0]); 1296cd6a6acSopenharmony_ci } 1306cd6a6acSopenharmony_ci 1316cd6a6acSopenharmony_ci cil_set_log_level(log_level); 1326cd6a6acSopenharmony_ci 1336cd6a6acSopenharmony_ci cil_db_init(&db); 1346cd6a6acSopenharmony_ci cil_set_preserve_tunables(db, preserve_tunables); 1356cd6a6acSopenharmony_ci cil_set_qualified_names(db, qualified_names); 1366cd6a6acSopenharmony_ci cil_set_mls(db, mls); 1376cd6a6acSopenharmony_ci cil_set_attrs_expand_generated(db, 0); 1386cd6a6acSopenharmony_ci cil_set_attrs_expand_size(db, 0); 1396cd6a6acSopenharmony_ci 1406cd6a6acSopenharmony_ci for (i = optind; i < argc; i++) { 1416cd6a6acSopenharmony_ci file = fopen(argv[i], "r"); 1426cd6a6acSopenharmony_ci if (!file) { 1436cd6a6acSopenharmony_ci fprintf(stderr, "Could not open file: %s\n", argv[i]); 1446cd6a6acSopenharmony_ci rc = SEPOL_ERR; 1456cd6a6acSopenharmony_ci goto exit; 1466cd6a6acSopenharmony_ci } 1476cd6a6acSopenharmony_ci rc = stat(argv[i], &filedata); 1486cd6a6acSopenharmony_ci if (rc == -1) { 1496cd6a6acSopenharmony_ci fprintf(stderr, "Could not stat file: %s\n", argv[i]); 1506cd6a6acSopenharmony_ci goto exit; 1516cd6a6acSopenharmony_ci } 1526cd6a6acSopenharmony_ci file_size = filedata.st_size; 1536cd6a6acSopenharmony_ci 1546cd6a6acSopenharmony_ci buffer = malloc(file_size); 1556cd6a6acSopenharmony_ci rc = fread(buffer, file_size, 1, file); 1566cd6a6acSopenharmony_ci if (rc != 1) { 1576cd6a6acSopenharmony_ci fprintf(stderr, "Failure reading file: %s\n", argv[i]); 1586cd6a6acSopenharmony_ci goto exit; 1596cd6a6acSopenharmony_ci } 1606cd6a6acSopenharmony_ci fclose(file); 1616cd6a6acSopenharmony_ci file = NULL; 1626cd6a6acSopenharmony_ci 1636cd6a6acSopenharmony_ci rc = cil_add_file(db, argv[i], buffer, file_size); 1646cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 1656cd6a6acSopenharmony_ci fprintf(stderr, "Failure adding %s\n", argv[i]); 1666cd6a6acSopenharmony_ci goto exit; 1676cd6a6acSopenharmony_ci } 1686cd6a6acSopenharmony_ci 1696cd6a6acSopenharmony_ci free(buffer); 1706cd6a6acSopenharmony_ci buffer = NULL; 1716cd6a6acSopenharmony_ci } 1726cd6a6acSopenharmony_ci 1736cd6a6acSopenharmony_ci rc = cil_compile(db); 1746cd6a6acSopenharmony_ci if (rc != SEPOL_OK) { 1756cd6a6acSopenharmony_ci fprintf(stderr, "Failed to compile cildb: %d\n", rc); 1766cd6a6acSopenharmony_ci goto exit; 1776cd6a6acSopenharmony_ci } 1786cd6a6acSopenharmony_ci 1796cd6a6acSopenharmony_ci if (output == NULL) { 1806cd6a6acSopenharmony_ci file = fopen("policy.conf", "w"); 1816cd6a6acSopenharmony_ci } else { 1826cd6a6acSopenharmony_ci file = fopen(output, "w"); 1836cd6a6acSopenharmony_ci } 1846cd6a6acSopenharmony_ci if (file == NULL) { 1856cd6a6acSopenharmony_ci fprintf(stderr, "Failure opening policy.conf file for writing\n"); 1866cd6a6acSopenharmony_ci rc = SEPOL_ERR; 1876cd6a6acSopenharmony_ci goto exit; 1886cd6a6acSopenharmony_ci } 1896cd6a6acSopenharmony_ci 1906cd6a6acSopenharmony_ci cil_write_policy_conf(file, db); 1916cd6a6acSopenharmony_ci 1926cd6a6acSopenharmony_ci fclose(file); 1936cd6a6acSopenharmony_ci file = NULL; 1946cd6a6acSopenharmony_ci rc = SEPOL_OK; 1956cd6a6acSopenharmony_ci 1966cd6a6acSopenharmony_ciexit: 1976cd6a6acSopenharmony_ci if (file != NULL) { 1986cd6a6acSopenharmony_ci fclose(file); 1996cd6a6acSopenharmony_ci } 2006cd6a6acSopenharmony_ci free(buffer); 2016cd6a6acSopenharmony_ci free(output); 2026cd6a6acSopenharmony_ci cil_db_destroy(&db); 2036cd6a6acSopenharmony_ci return rc; 2046cd6a6acSopenharmony_ci} 205