blob: 74c9c73d6076c5f879f1353d4d27923b1415f903 [file] [log] [blame]
dcashman2e00e632016-10-12 14:58:09 -07001/*
2 * version_policy.c - Takes the given public platform policy, a private policy
3 * and a version number to produced a combined "versioned" policy file.
4 */
5#include <errno.h>
6#include <getopt.h>
7#include <stdbool.h>
8#include <stdio.h>
9#include <sys/stat.h>
10#include <cil/android.h>
11#include <cil/cil.h>
12#include <cil/cil_write_ast.h>
13
14void __attribute__ ((noreturn)) static usage(char *prog) {
15 printf("Usage: %s [OPTION]...\n", prog);
16 printf("\n");
17 printf("Options:\n");
18 printf(" -b, --base=<file> (req'd) base policy for versioning.\n");
19 printf(" -m, --mapping generate cil version mapping from base policy\n");
20 printf(" -n, --number (req'd) version number to use.\n");
21 printf(" -o, --output=<file> write cil policy to <file>\n");
22 printf(" -t, --tgt_policy policy to be versioned according to base policy\n");
23 printf(" -h, --help display usage information\n");
24 exit(1);
25}
26
27/*
28 * read_cil_file - Initialize db and parse CIL input file.
29 */
30static int read_cil_file(struct cil_db **db, char *path) {
31 int rc = SEPOL_ERR;
32 FILE *file;
33 struct stat filedata;
34 uint32_t file_size;
35 char *buff = NULL;
36
37 cil_db_init(db);
38 file = fopen(path, "re");
39 if (!file) {
40 fprintf(stderr, "Could not open file: %s\n", path);
41 goto file_err;
42 }
43 rc = stat(path, &filedata);
44 if (rc == -1) {
45 fprintf(stderr, "Could not stat file: %s - %s\n", path, strerror(errno));
46 goto err;
47 }
48 file_size = filedata.st_size;
49 buff = malloc(file_size);
50 if (buff == NULL) {
51 fprintf(stderr, "OOM!\n");
52 rc = SEPOL_ERR;
53 goto err;
54 }
55 rc = fread(buff, file_size, 1, file);
56 if (rc != 1) {
57 fprintf(stderr, "Failure reading file: %s\n", path);
58 rc = SEPOL_ERR;
59 goto err;
60 }
61 fclose(file);
62 file = NULL;
63
64 /* creates parse_tree */
65 rc = cil_add_file(*db, path, buff, file_size);
66 if (rc != SEPOL_OK) {
67 fprintf(stderr, "Failure adding %s to parse tree\n", path);
68 goto err;
69 }
70 free(buff);
71
72 return SEPOL_OK;
73err:
74 free(buff);
75 fclose(file);
76file_err:
77 cil_db_destroy(db);
78 return rc;
79}
80
81int main(int argc, char *argv[])
82{
83 int opt_char;
84 int opt_index = 0;
85 int rc = SEPOL_ERR;
86 bool mapping = false;
87 char *base = NULL;
88 char *tgt_policy = NULL;
89 char *num = NULL;
90 char *output = NULL;
91 struct cil_db *base_db = NULL;
92 struct cil_db *out_db = NULL;
93
94 static struct option long_opts[] = {
95 {"help", no_argument, 0, 'h'},
96 {"base", required_argument, 0, 'b'},
97 {"mapping", no_argument, 0, 'm'},
98 {"number", required_argument, 0, 'n'},
99 {"output", required_argument, 0, 'o'},
100 {"tgt_policy", required_argument, 0, 't'},
101 {0, 0, 0, 0}
102 };
103
104 while (1) {
105 opt_char = getopt_long(argc, argv, "b:mn:o:t:h", long_opts, &opt_index);
106 if (opt_char == -1) {
107 break;
108 }
109 switch (opt_char) {
110 case 'b':
111 base = strdup(optarg);
112 break;
113 case 'm':
114 mapping = true;
115 break;
116 case 'n':
117 num = strdup(optarg);
118 break;
119 case 'o':
120 output = strdup(optarg);
121 break;
122 case 't':
123 tgt_policy = strdup(optarg);
124 break;
125 case 'h':
126 usage(argv[0]);
127 default:
128 fprintf(stderr, "Unsupported option: %s\n", optarg);
129 usage(argv[0]);
130 }
131 }
132 if (optind < argc) {
133 fprintf(stderr, "Unknown arguments supplied\n");
134 usage(argv[0]);
135 }
136 if (num == NULL || base == NULL || (mapping == false && tgt_policy == NULL)) {
137 fprintf(stderr, "Please specify required arguments\n");
138 usage(argv[0]);
139 }
140
141 if (mapping && tgt_policy) {
142 fprintf(stderr, "Please select only one mode between --mapping and --tgt_policy\n");
143 usage(argv[0]);
144 }
145
146 /* gimme all the details */
147 cil_set_log_level(CIL_INFO);
148
149 /* read platform policy */
150 rc = read_cil_file(&base_db, base);
151 if (rc != SEPOL_OK) {
152 goto exit;
153 }
154
155 if (mapping) {
156 rc = cil_android_attrib_mapping(&out_db, base_db, num);
157 if (rc != SEPOL_OK)
158 goto exit;
159 } else {
160 /* read target policy, ready for manipulation */
161 rc = read_cil_file(&out_db, tgt_policy);
162 if (rc != SEPOL_OK) {
163 goto exit;
164 }
165 /* attributize the target policy */
166 rc = cil_android_attributize(out_db, base_db, num);
167 if (rc != SEPOL_OK) {
168 goto exit;
169 }
170 }
171 rc = cil_write_ast(out_db, output);
172 if (rc != SEPOL_OK) {
173 goto exit;
174 }
175
176exit:
177 free(base);
178 free(tgt_policy);
179 free(num);
180 free(output);
181 cil_db_destroy(&base_db);
182 cil_db_destroy(&out_db);
183 return rc;
184}