00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <config.h>
00028
00029 #include "sediffx.h"
00030 #include "toplevel.h"
00031
00032 #include <errno.h>
00033 #include <getopt.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <glade/glade.h>
00037 #include <gtk/gtk.h>
00038
00039 struct sediffx
00040 {
00041 apol_policy_path_t *paths[SEDIFFX_POLICY_NUM];
00042 apol_policy_t *policies[SEDIFFX_POLICY_NUM];
00043 toplevel_t *top;
00044 poldiff_t *poldiff;
00045 uint32_t flags;
00046 };
00047
00048 static struct option const longopts[] = {
00049 {"run-diff", no_argument, NULL, 'd'},
00050 {"help", no_argument, NULL, 'h'},
00051 {"version", no_argument, NULL, 'V'},
00052 {NULL, 0, NULL, 0}
00053 };
00054
00055 void sediffx_set_policy(sediffx_t * s, sediffx_policy_e which, apol_policy_t * policy, apol_policy_path_t * path)
00056 {
00057 poldiff_destroy(&s->poldiff);
00058 if (policy != NULL) {
00059 apol_policy_destroy(&s->policies[which]);
00060 s->policies[which] = policy;
00061 if (path != s->paths[which]) {
00062 apol_policy_path_destroy(&s->paths[which]);
00063 }
00064 s->paths[which] = path;
00065 } else {
00066 apol_policy_destroy(&s->policies[which]);
00067 apol_policy_path_destroy(&s->paths[which]);
00068 }
00069 }
00070
00071 const apol_policy_path_t *sediffx_get_policy_path(sediffx_t * sediffx, const sediffx_policy_e which)
00072 {
00073 return sediffx->paths[which];
00074 }
00075
00076 poldiff_t *sediffx_get_poldiff(sediffx_t * s, poldiff_handle_fn_t fn, void *arg)
00077 {
00078 if (s->poldiff != NULL) {
00079 return s->poldiff;
00080 }
00081 if (s->policies[SEDIFFX_POLICY_ORIG] == NULL || s->policies[SEDIFFX_POLICY_MOD] == NULL) {
00082 return NULL;
00083 }
00084 s->poldiff = poldiff_create(s->policies[SEDIFFX_POLICY_ORIG], s->policies[SEDIFFX_POLICY_MOD], fn, arg);
00085 if (s->poldiff != NULL) {
00086
00087 s->policies[SEDIFFX_POLICY_ORIG] = NULL;
00088 s->policies[SEDIFFX_POLICY_MOD] = NULL;
00089 }
00090 return s->poldiff;
00091 }
00092
00093 void sediffx_set_poldiff_run_flags(sediffx_t * s, uint32_t flags)
00094 {
00095 s->flags = flags;
00096 }
00097
00098 uint32_t sediffx_get_poldiff_run_flags(sediffx_t * s)
00099 {
00100 return s->flags;
00101 }
00102
00103 static void print_version_info(void)
00104 {
00105 printf("sediffx %s\n%s\n", VERSION, COPYRIGHT_INFO);
00106 }
00107
00108 static void usage(const char *program_name, int brief)
00109 {
00110 printf("Usage: %s [-d] [ORIGINAL_POLICY ; MODIFIED_POLICY]\n\n", program_name);
00111 if (brief) {
00112 printf("\tTry %s --help for more help.\n\n", program_name);
00113 return;
00114 }
00115 printf("Semantically differentiate two policies. All supported policy elements\n");
00116 printf("are examined. The following options are available:\n");
00117 printf("\n");
00118 printf(" -d, --diff-now load policies and diff immediately\n");
00119 printf(" -h, --help print this help text and exit\n");
00120 printf(" -V, --version print version information and exit\n\n");
00121 }
00122
00123 struct delayed_main_data
00124 {
00125 apol_policy_path_t *orig_path, *mod_path;
00126 int run_diff;
00127 toplevel_t *top;
00128 };
00129
00130
00131
00132
00133
00134
00135
00136 static gboolean delayed_main(gpointer data)
00137 {
00138 struct delayed_main_data *dmd = (struct delayed_main_data *)data;
00139 if (toplevel_open_policies(dmd->top, dmd->orig_path, dmd->mod_path) == 0 && dmd->run_diff) {
00140 toplevel_run_diff(dmd->top);
00141 }
00142 return FALSE;
00143 }
00144
00145 static void sediffx_destroy(sediffx_t ** sediffx)
00146 {
00147 if (sediffx != NULL && *sediffx != NULL) {
00148 int i;
00149 for (i = SEDIFFX_POLICY_ORIG; i < SEDIFFX_POLICY_NUM; i++) {
00150 apol_policy_path_destroy(&((*sediffx)->paths[i]));
00151 apol_policy_destroy(&((*sediffx)->policies[i]));
00152 }
00153 poldiff_destroy(&((*sediffx)->poldiff));
00154 free(*sediffx);
00155 *sediffx = NULL;
00156 }
00157 }
00158
00159 static void sediffx_parse_command_line(int argc, char **argv, apol_policy_path_t ** orig_path, apol_policy_path_t ** mod_path,
00160 int *run_diff)
00161 {
00162 int optc;
00163 *orig_path = NULL;
00164 *mod_path = NULL;
00165 *run_diff = 0;
00166 while ((optc = getopt_long(argc, argv, "dhV", longopts, NULL)) != -1) {
00167 switch (optc) {
00168 case 0:
00169 break;
00170 case 'd':
00171 *run_diff = 1;
00172 break;
00173 case 'h':
00174 usage(argv[0], 0);
00175 exit(EXIT_SUCCESS);
00176 case 'V':
00177 print_version_info();
00178 exit(EXIT_SUCCESS);
00179 default:
00180 usage(argv[0], 1);
00181 exit(EXIT_FAILURE);
00182 }
00183 }
00184
00185 if (argc - optind == 0) {
00186
00187
00188 if (*run_diff) {
00189 usage(argv[0], 0);
00190 exit(EXIT_FAILURE);
00191 }
00192 return;
00193 } else if (argc - optind == 1) {
00194 usage(argv[0], 1);
00195 exit(EXIT_FAILURE);
00196 }
00197 if (argc - optind == 2) {
00198
00199 if (strcmp(argv[optind], ";") == 0 || strcmp(argv[optind + 1], ";") == 0) {
00200 usage(argv[0], 1);
00201 exit(EXIT_FAILURE);
00202 }
00203 *orig_path = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, argv[optind], NULL);
00204 *mod_path = apol_policy_path_create(APOL_POLICY_PATH_TYPE_MONOLITHIC, argv[optind + 1], NULL);
00205 if (*orig_path == NULL || *mod_path == NULL) {
00206 ERR(NULL, "%s", strerror(errno));
00207 exit(EXIT_FAILURE);
00208 }
00209 return;
00210 }
00211
00212
00213 char *orig_base_path = NULL;
00214 apol_vector_t *orig_module_paths = NULL;
00215 char *mod_base_path = NULL;
00216 apol_vector_t *mod_module_paths = NULL;
00217 apol_policy_path_type_e orig_path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC;
00218 apol_policy_path_type_e mod_path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC;
00219
00220 orig_base_path = argv[optind++];
00221 if (!(orig_module_paths = apol_vector_create(NULL))) {
00222 ERR(NULL, "%s", strerror(errno));
00223 goto err;
00224 }
00225 for (; argc - optind; optind++) {
00226 if (!strcmp(";", argv[optind])) {
00227 optind++;
00228 break;
00229 }
00230 if (apol_vector_append(orig_module_paths, (void *)argv[optind])) {
00231 ERR(NULL, "Error loading module %s", argv[optind]);
00232 goto err;
00233 }
00234 orig_path_type = APOL_POLICY_PATH_TYPE_MODULAR;
00235 }
00236 if (apol_file_is_policy_path_list(orig_base_path) > 0) {
00237 *orig_path = apol_policy_path_create_from_file(orig_base_path);
00238 if (*orig_path == NULL) {
00239 ERR(NULL, "%s", "invalid policy list");
00240 goto err;
00241 }
00242 } else {
00243 *orig_path = apol_policy_path_create(orig_path_type, orig_base_path, orig_module_paths);
00244 if (*orig_path == NULL) {
00245 ERR(NULL, "%s", strerror(errno));
00246 goto err;
00247 }
00248 }
00249 apol_vector_destroy(&orig_module_paths);
00250
00251 if (argc - optind == 0) {
00252 ERR(NULL, "%s", "Missing path to modified policy.");
00253 goto err;
00254 }
00255
00256 mod_base_path = argv[optind++];
00257 if (!(mod_module_paths = apol_vector_create(NULL))) {
00258 ERR(NULL, "%s", strerror(errno));
00259 goto err;
00260 }
00261 for (; argc - optind; optind++) {
00262 if (apol_vector_append(mod_module_paths, (void *)argv[optind])) {
00263 ERR(NULL, "Error loading module %s", argv[optind]);
00264 goto err;
00265 }
00266 mod_path_type = APOL_POLICY_PATH_TYPE_MODULAR;
00267 }
00268 if (apol_file_is_policy_path_list(mod_base_path) > 0) {
00269 *mod_path = apol_policy_path_create_from_file(mod_base_path);
00270 if (*mod_path == NULL) {
00271 ERR(NULL, "%s", "invalid policy list");
00272 goto err;
00273 }
00274 } else {
00275 *mod_path = apol_policy_path_create(mod_path_type, mod_base_path, mod_module_paths);
00276 if (*mod_path == NULL) {
00277 ERR(NULL, "%s", strerror(errno));
00278 goto err;
00279 }
00280 }
00281 apol_vector_destroy(&mod_module_paths);
00282 return;
00283 err:
00284 apol_policy_path_destroy(orig_path);
00285 apol_policy_path_destroy(mod_path);
00286 apol_vector_destroy(&orig_module_paths);
00287 apol_vector_destroy(&mod_module_paths);
00288 }
00289
00290 int main(int argc, char **argv)
00291 {
00292 sediffx_t *app;
00293 apol_policy_path_t *orig_path, *mod_path;
00294 int run_diff;
00295
00296 if (!g_thread_supported())
00297 g_thread_init(NULL);
00298
00299 gtk_init(&argc, &argv);
00300 sediffx_parse_command_line(argc, argv, &orig_path, &mod_path, &run_diff);
00301 glade_init();
00302 if (!g_thread_supported())
00303 g_thread_init(NULL);
00304 if ((app = calloc(1, sizeof(*app))) == NULL || (app->top = toplevel_create(app)) == NULL) {
00305 ERR(NULL, "%s", strerror(errno));
00306 sediffx_destroy(&app);
00307 exit(EXIT_FAILURE);
00308 }
00309 if (orig_path != NULL && mod_path != NULL) {
00310 struct delayed_main_data dmd = { orig_path, mod_path, run_diff, app->top };
00311 g_idle_add(&delayed_main, &dmd);
00312 }
00313 gtk_main();
00314
00315 sediffx_destroy(&app);
00316 exit(EXIT_SUCCESS);
00317 }