1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <stdint.h> 33 #include <string.h> 34 #include <getopt.h> 35 #include <sys/stat.h> 36 37 #ifdef ANDROID 38 #include <cil/cil.h> 39 #else 40 #include <sepol/cil/cil.h> 41 #endif 42 #include <sepol/policydb.h> 43 44 static __attribute__((__noreturn__)) void usage(const char *prog) 45 { 46 printf("Usage: %s [OPTION]... FILE...\n", prog); 47 printf("\n"); 48 printf("Options:\n"); 49 printf(" -o, --output=<file> write policy.conf to <file>\n"); 50 printf(" (default: policy.conf)\n"); 51 printf(" -M, --mls true|false write an mls policy. Must be true or false.\n"); 52 printf(" This will override the (mls boolean) statement\n"); 53 printf(" if present in the policy\n"); 54 printf(" -P, --preserve-tunables treat tunables as booleans\n"); 55 printf(" -v, --verbose increment verbosity level\n"); 56 printf(" -h, --help display usage information\n"); 57 exit(1); 58 } 59 60 int main(int argc, char *argv[]) 61 { 62 int rc = SEPOL_ERR; 63 FILE *file = NULL; 64 char *buffer = NULL; 65 struct stat filedata; 66 uint32_t file_size; 67 char *output = NULL; 68 struct cil_db *db = NULL; 69 int mls = -1; 70 int preserve_tunables = 0; 71 int opt_char; 72 int opt_index = 0; 73 enum cil_log_level log_level = CIL_ERR; 74 static struct option long_opts[] = { 75 {"help", no_argument, 0, 'h'}, 76 {"verbose", no_argument, 0, 'v'}, 77 {"mls", required_argument, 0, 'M'}, 78 {"preserve-tunables", no_argument, 0, 'P'}, 79 {"output", required_argument, 0, 'o'}, 80 {0, 0, 0, 0} 81 }; 82 int i; 83 84 while (1) { 85 opt_char = getopt_long(argc, argv, "o:hvM:P", long_opts, &opt_index); 86 if (opt_char == -1) { 87 break; 88 } 89 switch (opt_char) { 90 case 'v': 91 log_level++; 92 break; 93 case 'M': 94 if (!strcasecmp(optarg, "true") || !strcasecmp(optarg, "1")) { 95 mls = 1; 96 } else if (!strcasecmp(optarg, "false") || !strcasecmp(optarg, "0")) { 97 mls = 0; 98 } else { 99 usage(argv[0]); 100 } 101 break; 102 case 'P': 103 preserve_tunables = 1; 104 break; 105 case 'o': 106 output = strdup(optarg); 107 break; 108 case 'h': 109 usage(argv[0]); 110 case '?': 111 break; 112 default: 113 fprintf(stderr, "Unsupported option: %s\n", optarg); 114 usage(argv[0]); 115 } 116 } 117 if (optind >= argc) { 118 fprintf(stderr, "No cil files specified\n"); 119 usage(argv[0]); 120 } 121 122 cil_set_log_level(log_level); 123 124 cil_db_init(&db); 125 cil_set_preserve_tunables(db, preserve_tunables); 126 cil_set_mls(db, mls); 127 cil_set_attrs_expand_generated(db, 0); 128 cil_set_attrs_expand_size(db, 0); 129 130 for (i = optind; i < argc; i++) { 131 file = fopen(argv[i], "r"); 132 if (!file) { 133 fprintf(stderr, "Could not open file: %s\n", argv[i]); 134 rc = SEPOL_ERR; 135 goto exit; 136 } 137 rc = stat(argv[i], &filedata); 138 if (rc == -1) { 139 fprintf(stderr, "Could not stat file: %s\n", argv[i]); 140 goto exit; 141 } 142 file_size = filedata.st_size; 143 144 buffer = malloc(file_size); 145 rc = fread(buffer, file_size, 1, file); 146 if (rc != 1) { 147 fprintf(stderr, "Failure reading file: %s\n", argv[i]); 148 goto exit; 149 } 150 fclose(file); 151 file = NULL; 152 153 rc = cil_add_file(db, argv[i], buffer, file_size); 154 if (rc != SEPOL_OK) { 155 fprintf(stderr, "Failure adding %s\n", argv[i]); 156 goto exit; 157 } 158 159 free(buffer); 160 buffer = NULL; 161 } 162 163 rc = cil_compile(db); 164 if (rc != SEPOL_OK) { 165 fprintf(stderr, "Failed to compile cildb: %d\n", rc); 166 goto exit; 167 } 168 169 if (output == NULL) { 170 file = fopen("policy.conf", "w"); 171 } else { 172 file = fopen(output, "w"); 173 } 174 if (file == NULL) { 175 fprintf(stderr, "Failure opening policy.conf file for writing\n"); 176 rc = SEPOL_ERR; 177 goto exit; 178 } 179 180 cil_write_policy_conf(file, db); 181 182 fclose(file); 183 file = NULL; 184 rc = SEPOL_OK; 185 186 exit: 187 if (file != NULL) { 188 fclose(file); 189 } 190 free(buffer); 191 free(output); 192 cil_db_destroy(&db); 193 return rc; 194 } 195