summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSE Android <seandroid@taiga.selinuxproject.org>2012-01-24 05:27:18 -0800
committerSE Android <seandroid@taiga.selinuxproject.org>2012-01-24 05:27:18 -0800
commit8c48de15b1afeb1cd01a753195a29b1a7811dbfe (patch)
treee5ad1c3ac33510d3058e65de59874b3065593e5b /test
downloadcheckpolicy-8c48de15b1afeb1cd01a753195a29b1a7811dbfe.tar.gz
Import checkpolicy 2.1.0 (Release 2011-07-27).
Diffstat (limited to 'test')
-rw-r--r--test/Makefile21
-rw-r--r--test/dismod.c1017
-rw-r--r--test/dispol.c531
3 files changed, 1569 insertions, 0 deletions
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..fe1bf5d
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for building the dispol program
+#
+PREFIX ?= $(DESTDIR)/usr
+BINDIR=$(PREFIX)/bin
+LIBDIR=$(PREFIX)/lib
+INCLUDEDIR ?= $(PREFIX)/include
+
+CFLAGS ?= -g -Wall -O2 -pipe
+override CFLAGS += -I$(INCLUDEDIR)
+
+LDLIBS=-lfl -lsepol -lselinux $(LIBDIR)/libsepol.a -L$(LIBDIR)
+
+all: dispol dismod
+
+dispol: dispol.o
+
+dismod: dismod.o
+
+clean:
+ -rm -f dispol dismod *.o
diff --git a/test/dismod.c b/test/dismod.c
new file mode 100644
index 0000000..66f976f
--- /dev/null
+++ b/test/dismod.c
@@ -0,0 +1,1017 @@
+
+/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
+ *
+ * Copyright (C) 2003,2004,2005 Tresys Technology, LLC
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2.
+ */
+
+/*
+ * dismod.c
+ *
+ * Test program to the contents of a binary policy in text
+ * form.
+ *
+ * dismod binary_mod_file
+ */
+
+#include <getopt.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/conditional.h>
+#include <sepol/policydb/flask.h>
+#include <sepol/policydb/link.h>
+#include <sepol/policydb/module.h>
+#include <sepol/policydb/util.h>
+#include <sepol/policydb/polcaps.h>
+
+#include <byteswap.h>
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define le32_to_cpu(x) (x)
+#else
+#define le32_to_cpu(x) bswap_32(x)
+#endif
+
+#define DISPLAY_AVBLOCK_COND_AVTAB 0
+#define DISPLAY_AVBLOCK_UNCOND_AVTAB 1
+#define DISPLAY_AVBLOCK_ROLE_TYPE_NODE 2 /* unused? */
+#define DISPLAY_AVBLOCK_ROLE_TRANS 3
+#define DISPLAY_AVBLOCK_ROLE_ALLOW 4
+#define DISPLAY_AVBLOCK_REQUIRES 5
+#define DISPLAY_AVBLOCK_DECLARES 6
+#define DISPLAY_AVBLOCK_FILENAME_TRANS 7
+
+static policydb_t policydb;
+extern unsigned int ss_initialized;
+
+int policyvers = MOD_POLICYDB_VERSION_BASE;
+
+static const char *symbol_labels[9] = {
+ "commons",
+ "classes", "roles ", "types ", "users ", "bools ",
+ "levels ", "cats ", "attribs"
+};
+
+void usage(char *progname)
+{
+ printf("usage: %s binary_pol_file\n\n", progname);
+ exit(1);
+}
+
+static void render_access_mask(uint32_t mask, uint32_t class, policydb_t * p,
+ FILE * fp)
+{
+ char *perm;
+ fprintf(fp, "{");
+ perm = sepol_av_to_string(p, class, mask);
+ if (perm)
+ fprintf(fp, "%s ", perm);
+ fprintf(fp, "}");
+}
+
+static void render_access_bitmap(ebitmap_t * map, uint32_t class,
+ policydb_t * p, FILE * fp)
+{
+ unsigned int i;
+ char *perm;
+ fprintf(fp, "{");
+ for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) {
+ if (ebitmap_get_bit(map, i)) {
+ perm = sepol_av_to_string(p, class, 1 << i);
+ if (perm)
+ fprintf(fp, " %s", perm);
+ }
+ }
+ fprintf(fp, " }");
+}
+
+static void display_id(policydb_t * p, FILE * fp, uint32_t symbol_type,
+ uint32_t symbol_value, char *prefix)
+{
+ char *id = p->sym_val_to_name[symbol_type][symbol_value];
+ scope_datum_t *scope =
+ (scope_datum_t *) hashtab_search(p->scope[symbol_type].table, id);
+ assert(scope != NULL);
+ if (scope->scope == SCOPE_REQ) {
+ fprintf(fp, " [%s%s]", prefix, id);
+ } else {
+ fprintf(fp, " %s%s", prefix, id);
+ }
+}
+
+int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy,
+ FILE * fp)
+{
+ int i, num_types;
+
+ if (set->flags & TYPE_STAR) {
+ fprintf(fp, " * ");
+ return 0;
+ } else if (set->flags & TYPE_COMP) {
+ fprintf(fp, " ~");
+ }
+
+ num_types = 0;
+ if (flags & RULE_SELF) {
+ num_types++;
+ }
+
+ for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types);
+ i++) {
+ if (!ebitmap_get_bit(&set->types, i))
+ continue;
+ num_types++;
+ if (num_types > 1)
+ break;
+ }
+
+ if (num_types <= 1) {
+ for (i = ebitmap_startbit(&set->negset);
+ i < ebitmap_length(&set->negset); i++) {
+ if (!ebitmap_get_bit(&set->negset, i))
+ continue;
+ num_types++;
+ if (num_types > 1)
+ break;
+ }
+ }
+
+ if (num_types > 1)
+ fprintf(fp, "{");
+
+ for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types);
+ i++) {
+ if (!ebitmap_get_bit(&set->types, i))
+ continue;
+ display_id(policy, fp, SYM_TYPES, i, "");
+ }
+
+ for (i = ebitmap_startbit(&set->negset);
+ i < ebitmap_length(&set->negset); i++) {
+ if (!ebitmap_get_bit(&set->negset, i))
+ continue;
+ display_id(policy, fp, SYM_TYPES, i, "-");
+ }
+
+ if (flags & RULE_SELF) {
+ fprintf(fp, " self");
+ }
+
+ if (num_types > 1)
+ fprintf(fp, " }");
+
+ return 0;
+}
+
+int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp)
+{
+ int i, num = 0;
+
+ if (roles->flags & ROLE_STAR) {
+ fprintf(fp, " * ");
+ return 0;
+ } else if (roles->flags & ROLE_COMP) {
+ fprintf(fp, " ~");
+ }
+
+ for (i = ebitmap_startbit(&roles->roles);
+ i < ebitmap_length(&roles->roles); i++) {
+ if (!ebitmap_get_bit(&roles->roles, i))
+ continue;
+ num++;
+ if (num > 1) {
+ fprintf(fp, "{");
+ break;
+ }
+ }
+
+ for (i = ebitmap_startbit(&roles->roles);
+ i < ebitmap_length(&roles->roles); i++) {
+ if (ebitmap_get_bit(&roles->roles, i))
+ display_id(p, fp, SYM_ROLES, i, "");
+ }
+
+ if (num > 1)
+ fprintf(fp, " }");
+
+ return 0;
+
+}
+
+/* 'what' values for this function */
+#define RENDER_UNCONDITIONAL 0x0001 /* render all regardless of enabled state */
+#define RENDER_ENABLED 0x0002
+#define RENDER_DISABLED 0x0004
+#define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED)
+
+int display_avrule(avrule_t * avrule, uint32_t what, policydb_t * policy,
+ FILE * fp)
+{
+ class_perm_node_t *cur;
+ int num_classes;
+
+ if (avrule == NULL) {
+ fprintf(fp, " <empty>\n");
+ return 0;
+ }
+ if (avrule->specified & AVRULE_AV) {
+ if (avrule->specified & AVRULE_ALLOWED) {
+ fprintf(fp, " allow");
+ }
+ if (avrule->specified & AVRULE_AUDITALLOW) {
+ fprintf(fp, " auditallow ");
+ }
+ if (avrule->specified & AVRULE_DONTAUDIT) {
+ fprintf(fp, " dontaudit");
+ }
+ } else if (avrule->specified & AVRULE_TYPE) {
+ if (avrule->specified & AVRULE_TRANSITION) {
+ fprintf(fp, " type_transition");
+ }
+ if (avrule->specified & AVRULE_MEMBER) {
+ fprintf(fp, " type_member");
+ }
+ if (avrule->specified & AVRULE_CHANGE) {
+ fprintf(fp, " type_change");
+ }
+ } else if (avrule->specified & AVRULE_NEVERALLOW) {
+ fprintf(fp, " neverallow");
+ } else {
+ fprintf(fp, " ERROR: no valid rule type specified\n");
+ return -1;
+ }
+
+ if (display_type_set(&avrule->stypes, 0, policy, fp))
+ return -1;
+
+ if (display_type_set(&avrule->ttypes, avrule->flags, policy, fp))
+ return -1;
+
+ fprintf(fp, " :");
+ cur = avrule->perms;
+ num_classes = 0;
+ while (cur) {
+ num_classes++;
+ if (num_classes > 1)
+ break;
+ cur = cur->next;
+ }
+
+ if (num_classes > 1)
+ fprintf(fp, " {");
+
+ cur = avrule->perms;
+ while (cur) {
+ display_id(policy, fp, SYM_CLASSES, cur->class - 1, "");
+ cur = cur->next;
+ }
+
+ if (num_classes > 1)
+ fprintf(fp, " }");
+ fprintf(fp, " ");
+
+ if (avrule->specified & (AVRULE_AV | AVRULE_NEVERALLOW)) {
+ render_access_mask(avrule->perms->data, avrule->perms->class,
+ policy, fp);
+ } else if (avrule->specified & AVRULE_TYPE) {
+ display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, "");
+ }
+
+ fprintf(fp, ";\n");
+
+ return 0;
+}
+
+int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
+{
+ type_datum_t *type;
+ FILE *fp;
+ int i, first_attrib = 1;
+
+ type = (type_datum_t *) datum;
+ fp = (FILE *) data;
+
+ if (type->primary) {
+ display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, "");
+ fprintf(fp, " [%d]: ", type->s.value);
+ } else {
+ /* as that aliases have no value of their own and that
+ * they can never be required by a module, use this
+ * alternative way of displaying a name */
+ fprintf(fp, " %s [%d]: ", (char *)key, type->s.value);
+ }
+ if (type->flavor == TYPE_ATTRIB) {
+ fprintf(fp, "attribute for types");
+ for (i = ebitmap_startbit(&type->types);
+ i < ebitmap_length(&type->types); i++) {
+ if (!ebitmap_get_bit(&type->types, i))
+ continue;
+ if (first_attrib) {
+ first_attrib = 0;
+ } else {
+ fprintf(fp, ",");
+ }
+ display_id(&policydb, fp, SYM_TYPES, i, "");
+ }
+ } else if (type->primary) {
+ fprintf(fp, "type");
+ } else {
+ fprintf(fp, "alias for type");
+ display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, "");
+ }
+ fprintf(fp, " flags:%x\n", type->flags);
+
+ return 0;
+}
+
+int display_types(policydb_t * p, FILE * fp)
+{
+ if (hashtab_map(p->p_types.table, display_type_callback, fp))
+ return -1;
+ return 0;
+}
+
+int display_users(policydb_t * p, FILE * fp)
+{
+ int i, j;
+ ebitmap_t *bitmap;
+ for (i = 0; i < p->p_users.nprim; i++) {
+ display_id(p, fp, SYM_USERS, i, "");
+ fprintf(fp, ":");
+ bitmap = &(p->user_val_to_struct[i]->roles.roles);
+ for (j = ebitmap_startbit(bitmap); j < ebitmap_length(bitmap);
+ j++) {
+ if (ebitmap_get_bit(bitmap, j)) {
+ display_id(p, fp, SYM_ROLES, j, "");
+ }
+ }
+ fprintf(fp, "\n");
+ }
+ return 0;
+}
+
+int display_bools(policydb_t * p, FILE * fp)
+{
+ int i;
+
+ for (i = 0; i < p->p_bools.nprim; i++) {
+ display_id(p, fp, SYM_BOOLS, i, "");
+ fprintf(fp, " : %d\n", p->bool_val_to_struct[i]->state);
+ }
+ return 0;
+}
+
+void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
+{
+
+ cond_expr_t *cur;
+ for (cur = exp; cur != NULL; cur = cur->next) {
+ switch (cur->expr_type) {
+ case COND_BOOL:
+ fprintf(fp, "%s ",
+ p->p_bool_val_to_name[cur->bool - 1]);
+ break;
+ case COND_NOT:
+ fprintf(fp, "! ");
+ break;
+ case COND_OR:
+ fprintf(fp, "|| ");
+ break;
+ case COND_AND:
+ fprintf(fp, "&& ");
+ break;
+ case COND_XOR:
+ fprintf(fp, "^ ");
+ break;
+ case COND_EQ:
+ fprintf(fp, "== ");
+ break;
+ case COND_NEQ:
+ fprintf(fp, "!= ");
+ break;
+ default:
+ fprintf(fp, "error!");
+ break;
+ }
+ }
+}
+
+void display_policycon(policydb_t * p, FILE * fp)
+{
+#if 0
+ int i;
+ ocontext_t *cur;
+ char *name;
+
+ for (i = 0; i < POLICYCON_NUM; i++) {
+ fprintf(fp, "%s:", symbol_labels[i]);
+ for (cur = p->policycon[i].head; cur != NULL; cur = cur->next) {
+ if (*(cur->u.name) == '\0') {
+ name = "{default}";
+ } else {
+ name = cur->u.name;
+ }
+ fprintf(fp, "\n%16s - %s:%s:%s", name,
+ p->p_user_val_to_name[cur->context[0].user - 1],
+ p->p_role_val_to_name[cur->context[0].role - 1],
+ p->p_type_val_to_name[cur->context[0].type -
+ 1]);
+ }
+ fprintf(fp, "\n");
+ }
+#endif
+}
+
+void display_initial_sids(policydb_t * p, FILE * fp)
+{
+ ocontext_t *cur;
+ char *user, *role, *type;
+
+ fprintf(fp, "Initial SIDs:\n");
+ for (cur = p->ocontexts[OCON_ISID]; cur != NULL; cur = cur->next) {
+ user = p->p_user_val_to_name[cur->context[0].user - 1];
+ role = p->p_role_val_to_name[cur->context[0].role - 1];
+ type = p->p_type_val_to_name[cur->context[0].type - 1];
+ fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
+ cur->u.name, cur->sid[0], user, role, type);
+ }
+#if 0
+ fprintf(fp, "Policy Initial SIDs:\n");
+ for (cur = p->ocontexts[OCON_POLICYISID]; cur != NULL; cur = cur->next) {
+ user = p->p_user_val_to_name[cur->context[0].user - 1];
+ role = p->p_role_val_to_name[cur->context[0].role - 1];
+ type = p->p_type_val_to_name[cur->context[0].type - 1];
+ fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n",
+ cur->u.name, cur->sid[0], user, role, type);
+ }
+#endif
+}
+
+void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp)
+{
+ int i, num = 0;
+
+ for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) {
+ if (!ebitmap_get_bit(classes, i))
+ continue;
+ num++;
+ if (num > 1) {
+ fprintf(fp, "{");
+ break;
+ }
+ }
+
+ for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) {
+ if (ebitmap_get_bit(classes, i))
+ display_id(p, fp, SYM_CLASSES, i, "");
+ }
+
+ if (num > 1)
+ fprintf(fp, " }");
+}
+
+void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp)
+{
+ for (; tr; tr = tr->next) {
+ fprintf(fp, "role transition ");
+ display_mod_role_set(&tr->roles, p, fp);
+ display_type_set(&tr->types, 0, p, fp);
+ fprintf(fp, " :");
+ display_class_set(&tr->classes, p, fp);
+ display_id(p, fp, SYM_ROLES, tr->new_role - 1, "");
+ fprintf(fp, "\n");
+ }
+}
+
+void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp)
+{
+ for (; ra; ra = ra->next) {
+ fprintf(fp, "role allow ");
+ display_mod_role_set(&ra->roles, p, fp);
+ display_mod_role_set(&ra->new_roles, p, fp);
+ fprintf(fp, "\n");
+ }
+}
+
+void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, FILE * fp)
+{
+ for (; tr; tr = tr->next) {
+ fprintf(fp, "filename transition %s", tr->name);
+ display_type_set(&tr->stypes, 0, p, fp);
+ display_type_set(&tr->ttypes, 0, p, fp);
+ display_id(p, fp, SYM_CLASSES, tr->tclass - 1, ":");
+ display_id(p, fp, SYM_TYPES, tr->otype - 1, "");
+ fprintf(fp, "\n");
+ }
+}
+
+int role_display_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
+{
+ role_datum_t *role;
+ FILE *fp;
+
+ role = (role_datum_t *) datum;
+ fp = (FILE *) data;
+
+ fprintf(fp, "role:");
+ display_id(&policydb, fp, SYM_ROLES, role->s.value - 1, "");
+ fprintf(fp, " types: ");
+ display_type_set(&role->types, 0, &policydb, fp);
+ fprintf(fp, "\n");
+
+ return 0;
+}
+
+static int display_scope_index(scope_index_t * indices, policydb_t * p,
+ FILE * out_fp)
+{
+ int i;
+ for (i = 0; i < SYM_NUM; i++) {
+ int any_found = 0, j;
+ fprintf(out_fp, "%s:", symbol_labels[i]);
+ for (j = ebitmap_startbit(&indices->scope[i]);
+ j < ebitmap_length(&indices->scope[i]); j++) {
+ if (ebitmap_get_bit(&indices->scope[i], j)) {
+ any_found = 1;
+ fprintf(out_fp, " %s",
+ p->sym_val_to_name[i][j]);
+ if (i == SYM_CLASSES) {
+ if (j < indices->class_perms_len) {
+ render_access_bitmap(indices->
+ class_perms_map
+ + j, j + 1,
+ p, out_fp);
+ } else {
+ fprintf(out_fp,
+ "<no perms known>");
+ }
+ }
+ }
+ }
+ if (!any_found) {
+ fprintf(out_fp, " <empty>");
+ }
+ fprintf(out_fp, "\n");
+ }
+ return 0;
+}
+
+#if 0
+int display_cond_expressions(policydb_t * p, FILE * fp)
+{
+ cond_node_t *cur;
+ cond_av_list_t *av_cur;
+ for (cur = p->cond_list; cur != NULL; cur = cur->next) {
+ fprintf(fp, "expression: ");
+ display_expr(p, cur->expr, fp);
+ fprintf(fp, "current state: %d\n", cur->cur_state);
+ fprintf(fp, "True list:\n");
+ for (av_cur = cur->true_list; av_cur != NULL;
+ av_cur = av_cur->next) {
+ fprintf(fp, "\t");
+ render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+ RENDER_CONDITIONAL, p, fp);
+ }
+ fprintf(fp, "False list:\n");
+ for (av_cur = cur->false_list; av_cur != NULL;
+ av_cur = av_cur->next) {
+ fprintf(fp, "\t");
+ render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+ RENDER_CONDITIONAL, p, fp);
+ }
+ }
+ return 0;
+}
+
+int change_bool(char *name, int state, policydb_t * p, FILE * fp)
+{
+ cond_bool_datum_t *bool;
+
+ bool = hashtab_search(p->p_bools.table, name);
+ if (bool == NULL) {
+ fprintf(fp, "Could not find bool %s\n", name);
+ return -1;
+ }
+ bool->state = state;
+ evaluate_conds(p);
+ return 0;
+}
+#endif
+
+int display_avdecl(avrule_decl_t * decl, int field, uint32_t what,
+ policydb_t * policy, FILE * out_fp)
+{
+ fprintf(out_fp, "decl %u:%s\n", decl->decl_id,
+ (decl->enabled ? " [enabled]" : ""));
+ switch (field) {
+ case DISPLAY_AVBLOCK_COND_AVTAB:{
+ cond_list_t *cond = decl->cond_list;
+ avrule_t *avrule;
+ while (cond) {
+ fprintf(out_fp, "expression: ");
+ display_expr(&policydb, cond->expr, out_fp);
+ fprintf(out_fp, "current state: %d\n",
+ cond->cur_state);
+ fprintf(out_fp, "True list:\n");
+ avrule = cond->avtrue_list;
+ while (avrule) {
+ display_avrule(avrule,
+ RENDER_UNCONDITIONAL,
+ &policydb, out_fp);
+ avrule = avrule->next;
+ }
+ fprintf(out_fp, "False list:\n");
+ avrule = cond->avfalse_list;
+ while (avrule) {
+ display_avrule(avrule,
+ RENDER_UNCONDITIONAL,
+ &policydb, out_fp);
+ avrule = avrule->next;
+ }
+ cond = cond->next;
+ }
+ break;
+ }
+ case DISPLAY_AVBLOCK_UNCOND_AVTAB:{
+ avrule_t *avrule = decl->avrules;
+ if (avrule == NULL) {
+ fprintf(out_fp, " <empty>\n");
+ }
+ while (avrule != NULL) {
+ if (display_avrule
+ (avrule, what, policy, out_fp)) {
+ return -1;
+ }
+ avrule = avrule->next;
+ }
+ break;
+ }
+ case DISPLAY_AVBLOCK_ROLE_TYPE_NODE:{ /* role_type_node */
+ break;
+ }
+ case DISPLAY_AVBLOCK_ROLE_TRANS:{
+ display_role_trans(decl->role_tr_rules, policy, out_fp);
+ break;
+ }
+ case DISPLAY_AVBLOCK_ROLE_ALLOW:{
+ display_role_allow(decl->role_allow_rules, policy,
+ out_fp);
+ break;
+ }
+ case DISPLAY_AVBLOCK_REQUIRES:{
+ if (display_scope_index
+ (&decl->required, policy, out_fp)) {
+ return -1;
+ }
+ break;
+ }
+ case DISPLAY_AVBLOCK_DECLARES:{
+ if (display_scope_index
+ (&decl->declared, policy, out_fp)) {
+ return -1;
+ }
+ break;
+ }
+ case DISPLAY_AVBLOCK_FILENAME_TRANS:
+ display_filename_trans(decl->filename_trans_rules, policy,
+ out_fp);
+ return -1;
+ break;
+ default:{
+ assert(0);
+ }
+ }
+ return 0; /* should never get here */
+}
+
+int display_avblock(int field, uint32_t what, policydb_t * policy,
+ FILE * out_fp)
+{
+ avrule_block_t *block = policydb.global;
+ while (block != NULL) {
+ fprintf(out_fp, "--- begin avrule block ---\n");
+ avrule_decl_t *decl = block->branch_list;
+ while (decl != NULL) {
+ if (display_avdecl(decl, field, what, policy, out_fp)) {
+ return -1;
+ }
+ decl = decl->next;
+ }
+ block = block->next;
+ }
+ return 0;
+}
+
+int display_handle_unknown(policydb_t * p, FILE * out_fp)
+{
+ if (p->handle_unknown == ALLOW_UNKNOWN)
+ fprintf(out_fp, "Allow unknown classes and perms\n");
+ else if (p->handle_unknown == DENY_UNKNOWN)
+ fprintf(out_fp, "Deny unknown classes and perms\n");
+ else if (p->handle_unknown == REJECT_UNKNOWN)
+ fprintf(out_fp, "Reject unknown classes and perms\n");
+ return 0;
+}
+
+static int read_policy(char *filename, policydb_t * policy)
+{
+ FILE *in_fp;
+ struct policy_file f;
+ int retval;
+ uint32_t buf[1];
+
+ if ((in_fp = fopen(filename, "rb")) == NULL) {
+ fprintf(stderr, "Can't open '%s': %s\n",
+ filename, strerror(errno));
+ exit(1);
+ }
+ policy_file_init(&f);
+ f.type = PF_USE_STDIO;
+ f.fp = in_fp;
+
+ /* peek at the first byte. if they are indicative of a
+ package use the package reader, otherwise use the normal
+ policy reader */
+ if (fread(buf, sizeof(uint32_t), 1, in_fp) != 1) {
+ fprintf(stderr, "Could not read from policy.\n");
+ exit(1);
+ }
+ rewind(in_fp);
+ if (le32_to_cpu(buf[0]) == SEPOL_MODULE_PACKAGE_MAGIC) {
+ sepol_module_package_t *package;
+ if (sepol_module_package_create(&package)) {
+ fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__);
+ exit(1);
+ }
+ package->policy = (sepol_policydb_t *) policy;
+ package->file_contexts = NULL;
+ retval =
+ sepol_module_package_read(package,
+ (sepol_policy_file_t *) & f, 1);
+ free(package->file_contexts);
+ } else {
+ if (policydb_init(policy)) {
+ fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__);
+ exit(1);
+ }
+ retval = policydb_read(policy, &f, 1);
+ }
+ fclose(in_fp);
+ return retval;
+}
+
+static void link_module(policydb_t * base, FILE * out_fp)
+{
+ char module_name[80] = { 0 };
+ int ret;
+ policydb_t module, *mods = &module;
+
+ if (base->policy_type != POLICY_BASE) {
+ printf("Can only link if initial file was a base policy.\n");
+ return;
+ }
+ printf("\nModule filename: ");
+ fgets(module_name, sizeof(module_name), stdin);
+ module_name[strlen(module_name) - 1] = '\0'; /* remove LF */
+ if (module_name[0] == '\0') {
+ return;
+ }
+
+ /* read the binary policy */
+ fprintf(out_fp, "Reading module...\n");
+ if (read_policy(module_name, mods)) {
+ fprintf(stderr,
+ "%s: error(s) encountered while loading policy\n",
+ module_name);
+ exit(1);
+ }
+ if (module.policy_type != POLICY_MOD) {
+ fprintf(stderr, "This file is not a loadable policy module.\n");
+ exit(1);
+ }
+ if (policydb_index_classes(&module) ||
+ policydb_index_others(NULL, &module, 0)) {
+ fprintf(stderr, "Could not index module.\n");
+ exit(1);
+ }
+ ret = link_modules(NULL, base, &mods, 1, 0);
+ if (ret != 0) {
+ printf("Link failed (error %d)\n", ret);
+ printf("(You will probably need to restart dismod.)\n");
+ }
+ policydb_destroy(&module);
+ return;
+}
+
+static void display_policycaps(policydb_t * p, FILE * fp)
+{
+ ebitmap_node_t *node;
+ const char *capname;
+ char buf[64];
+ int i;
+
+ fprintf(fp, "policy capabilities:\n");
+ ebitmap_for_each_bit(&p->policycaps, node, i) {
+ if (ebitmap_node_get_bit(node, i)) {
+ capname = sepol_polcap_getname(i);
+ if (capname == NULL) {
+ snprintf(buf, sizeof(buf), "unknown (%d)", i);
+ capname = buf;
+ }
+ fprintf(fp, "\t%s\n", capname);
+ }
+ }
+}
+
+int menu()
+{
+ printf("\nSelect a command:\n");
+ printf("1) display unconditional AVTAB\n");
+ printf("2) display conditional AVTAB\n");
+ printf("3) display users\n");
+ printf("4) display bools\n");
+ printf("5) display roles\n");
+ printf("6) display types, attributes, and aliases\n");
+ printf("7) display role transitions\n");
+ printf("8) display role allows\n");
+ printf("9) Display policycon\n");
+ printf("0) Display initial SIDs\n");
+ printf("\n");
+ printf("a) Display avrule requirements\n");
+ printf("b) Display avrule declarations\n");
+ printf("c) Display policy capabilities\n");
+ printf("l) Link in a module\n");
+ printf("u) Display the unknown handling setting\n");
+ printf("F) Display filename_trans rules\n");
+ printf("\n");
+ printf("f) set output file\n");
+ printf("m) display menu\n");
+ printf("q) quit\n");
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *out_fp = stdout;
+ char ans[81], OutfileName[121];
+
+ if (argc != 2)
+ usage(argv[0]);
+
+ /* read the binary policy */
+ fprintf(out_fp, "Reading policy...\n");
+ policydb_init(&policydb);
+ if (read_policy(argv[1], &policydb)) {
+ fprintf(stderr,
+ "%s: error(s) encountered while loading policy\n",
+ argv[0]);
+ exit(1);
+ }
+
+ if (policydb.policy_type != POLICY_BASE &&
+ policydb.policy_type != POLICY_MOD) {
+ fprintf(stderr,
+ "This file is neither a base nor loadable policy module.\n");
+ exit(1);
+ }
+
+ if (policydb_index_classes(&policydb)) {
+ fprintf(stderr, "Error indexing classes\n");
+ exit(1);
+ }
+
+ if (policydb_index_others(NULL, &policydb, 1)) {
+ fprintf(stderr, "Error indexing others\n");
+ exit(1);
+ }
+
+ if (policydb.policy_type == POLICY_BASE) {
+ printf("Binary base policy file loaded.\n\n");
+ } else {
+ printf("Binary policy module file loaded.\n");
+ printf("Module name: %s\n", policydb.name);
+ printf("Module version: %s\n", policydb.version);
+ printf("\n");
+ }
+
+ menu();
+ for (;;) {
+ printf("\nCommand (\'m\' for menu): ");
+ fgets(ans, sizeof(ans), stdin);
+ switch (ans[0]) {
+
+ case '1':
+ fprintf(out_fp, "unconditional avtab:\n");
+ display_avblock(DISPLAY_AVBLOCK_UNCOND_AVTAB,
+ RENDER_UNCONDITIONAL, &policydb,
+ out_fp);
+ break;
+ case '2':
+ fprintf(out_fp, "conditional avtab:\n");
+ display_avblock(DISPLAY_AVBLOCK_COND_AVTAB,
+ RENDER_UNCONDITIONAL, &policydb,
+ out_fp);
+ break;
+ case '3':
+ display_users(&policydb, out_fp);
+ break;
+ case '4':
+ display_bools(&policydb, out_fp);
+ break;
+ case '5':
+ if (hashtab_map
+ (policydb.p_roles.table, role_display_callback,
+ out_fp))
+ exit(1);
+ break;
+ case '6':
+ if (display_types(&policydb, out_fp)) {
+ fprintf(stderr, "Error displaying types\n");
+ exit(1);
+ }
+ break;
+ case '7':
+ fprintf(out_fp, "role transitions:\n");
+ display_avblock(DISPLAY_AVBLOCK_ROLE_TRANS, 0,
+ &policydb, out_fp);
+ break;
+ case '8':
+ fprintf(out_fp, "role allows:\n");
+ display_avblock(DISPLAY_AVBLOCK_ROLE_ALLOW, 0,
+ &policydb, out_fp);
+ break;
+ case '9':
+ display_policycon(&policydb, out_fp);
+ break;
+ case '0':
+ display_initial_sids(&policydb, out_fp);
+ break;
+ case 'a':
+ fprintf(out_fp, "avrule block requirements:\n");
+ display_avblock(DISPLAY_AVBLOCK_REQUIRES, 0,
+ &policydb, out_fp);
+ break;
+ case 'b':
+ fprintf(out_fp, "avrule block declarations:\n");
+ display_avblock(DISPLAY_AVBLOCK_DECLARES, 0,
+ &policydb, out_fp);
+ break;
+ case 'c':
+ display_policycaps(&policydb, out_fp);
+ break;
+ case 'u':
+ case 'U':
+ display_handle_unknown(&policydb, out_fp);
+ break;
+ case 'f':
+ printf
+ ("\nFilename for output (<CR> for screen output): ");
+ fgets(OutfileName, sizeof(OutfileName), stdin);
+ OutfileName[strlen(OutfileName) - 1] = '\0'; /* fix_string (remove LF) */
+ if (strlen(OutfileName) == 0)
+ out_fp = stdout;
+ else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
+ fprintf(stderr, "Cannot open output file %s\n",
+ OutfileName);
+ out_fp = stdout;
+ }
+ if (out_fp != stdout)
+ printf("\nOutput to file: %s\n", OutfileName);
+ break;
+ case 'F':
+ fprintf(out_fp, "filename_trans rules:\n");
+ display_avblock(DISPLAY_AVBLOCK_FILENAME_TRANS,
+ 0, &policydb, out_fp);
+ break;
+ case 'l':
+ link_module(&policydb, out_fp);
+ break;
+ case 'q':
+ policydb_destroy(&policydb);
+ exit(0);
+ break;
+ case 'm':
+ menu();
+ break;
+ default:
+ printf("\nInvalid choice\n");
+ menu();
+ break;
+
+ }
+ }
+ exit(EXIT_SUCCESS);
+}
diff --git a/test/dispol.c b/test/dispol.c
new file mode 100644
index 0000000..ee2cf02
--- /dev/null
+++ b/test/dispol.c
@@ -0,0 +1,531 @@
+
+/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
+ *
+ * Copyright (C) 2003 Tresys Technology, LLC
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2.
+ */
+
+/*
+ * displaypol.c
+ *
+ * Test program to the contents of a binary policy in text
+ * form. This program currently only displays the
+ * avtab (including conditional avtab) rules.
+ *
+ * displaypol binary_pol_file
+ */
+
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/avtab.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/conditional.h>
+#include <sepol/policydb/expand.h>
+#include <sepol/policydb/util.h>
+#include <sepol/policydb/polcaps.h>
+#include <getopt.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+static policydb_t policydb;
+
+void usage(char *progname)
+{
+ printf("usage: %s binary_pol_file\n\n", progname);
+ exit(1);
+}
+
+int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
+ FILE * fp)
+{
+ char *perm;
+ fprintf(fp, "{");
+ perm = sepol_av_to_string(p, key->target_class, mask);
+ if (perm)
+ fprintf(fp, "%s ", perm);
+ fprintf(fp, "}");
+ return 0;
+}
+
+int render_type(uint32_t type, policydb_t * p, FILE * fp)
+{
+ fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
+ return 0;
+}
+
+int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
+{
+ char *stype, *ttype, *tclass;
+ stype = p->p_type_val_to_name[key->source_type - 1];
+ ttype = p->p_type_val_to_name[key->target_type - 1];
+ tclass = p->p_class_val_to_name[key->target_class - 1];
+ if (stype && ttype)
+ fprintf(fp, "%s %s : %s ", stype, ttype, tclass);
+ else if (stype)
+ fprintf(fp, "%s %u : %s ", stype, key->target_type, tclass);
+ else if (ttype)
+ fprintf(fp, "%u %s : %s ", key->source_type, ttype, tclass);
+ else
+ fprintf(fp, "%u %u : %s ", key->source_type, key->target_type,
+ tclass);
+ return 0;
+}
+
+/* 'what' values for this function */
+#define RENDER_UNCONDITIONAL 0x0001 /* render all regardless of enabled state */
+#define RENDER_ENABLED 0x0002
+#define RENDER_DISABLED 0x0004
+#define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED)
+
+int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
+ policydb_t * p, FILE * fp)
+{
+ if (!(what & RENDER_UNCONDITIONAL)) {
+ if (what != RENDER_CONDITIONAL && (((what & RENDER_ENABLED)
+ && !(key->
+ specified &
+ AVTAB_ENABLED))
+ || ((what & RENDER_DISABLED)
+ && (key->
+ specified &
+ AVTAB_ENABLED)))) {
+ return 0; /* doesn't match selection criteria */
+ }
+ }
+
+ if (!(what & RENDER_UNCONDITIONAL)) {
+ if (key->specified & AVTAB_ENABLED)
+ fprintf(fp, "[enabled] ");
+ else if (!(key->specified & AVTAB_ENABLED))
+ fprintf(fp, "[disabled] ");
+ }
+
+ if (key->specified & AVTAB_AV) {
+ if (key->specified & AVTAB_ALLOWED) {
+ fprintf(fp, "allow ");
+ render_key(key, p, fp);
+ render_access_mask(datum->data, key, p, fp);
+ fprintf(fp, ";\n");
+ }
+ if (key->specified & AVTAB_AUDITALLOW) {
+ fprintf(fp, "auditallow ");
+ render_key(key, p, fp);
+ render_access_mask(datum->data, key, p, fp);
+ fprintf(fp, ";\n");
+ }
+ if (key->specified & AVTAB_AUDITDENY) {
+ fprintf(fp, "dontaudit ");
+ render_key(key, p, fp);
+ /* We inverse the mask for dontaudit since the mask is internally stored
+ * as a auditdeny mask */
+ render_access_mask(~datum->data, key, p, fp);
+ fprintf(fp, ";\n");
+ }
+ } else if (key->specified & AVTAB_TYPE) {
+ if (key->specified & AVTAB_TRANSITION) {
+ fprintf(fp, "type_transition ");
+ render_key(key, p, fp);
+ render_type(datum->data, p, fp);
+ fprintf(fp, ";\n");
+ }
+ if (key->specified & AVTAB_MEMBER) {
+ fprintf(fp, "type_member ");
+ render_key(key, p, fp);
+ render_type(datum->data, p, fp);
+ fprintf(fp, ";\n");
+ }
+ if (key->specified & AVTAB_CHANGE) {
+ fprintf(fp, "type_change ");
+ render_key(key, p, fp);
+ render_type(datum->data, p, fp);
+ fprintf(fp, ";\n");
+ }
+ } else {
+ fprintf(fp, " ERROR: no valid rule type specified\n");
+ return -1;
+ }
+ return 0;
+}
+
+int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
+{
+ int i;
+ avtab_ptr_t cur;
+ avtab_t expa;
+
+ if (avtab_init(&expa))
+ goto oom;
+ if (expand_avtab(p, a, &expa)) {
+ avtab_destroy(&expa);
+ goto oom;
+ }
+
+ /* hmm...should have used avtab_map. */
+ for (i = 0; i < expa.nslot; i++) {
+ for (cur = expa.htable[i]; cur; cur = cur->next) {
+ render_av_rule(&cur->key, &cur->datum, what, p, fp);
+ }
+ }
+ avtab_destroy(&expa);
+ fprintf(fp, "\n");
+ return 0;
+ oom:
+ fprintf(stderr, "out of memory\n");
+ return 1;
+}
+
+int display_bools(policydb_t * p, FILE * fp)
+{
+ int i;
+
+ for (i = 0; i < p->p_bools.nprim; i++) {
+ fprintf(fp, "%s : %d\n", p->p_bool_val_to_name[i],
+ p->bool_val_to_struct[i]->state);
+ }
+ return 0;
+}
+
+void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
+{
+
+ cond_expr_t *cur;
+ for (cur = exp; cur != NULL; cur = cur->next) {
+ switch (cur->expr_type) {
+ case COND_BOOL:
+ fprintf(fp, "%s ",
+ p->p_bool_val_to_name[cur->bool - 1]);
+ break;
+ case COND_NOT:
+ fprintf(fp, "! ");
+ break;
+ case COND_OR:
+ fprintf(fp, "|| ");
+ break;
+ case COND_AND:
+ fprintf(fp, "&& ");
+ break;
+ case COND_XOR:
+ fprintf(fp, "^ ");
+ break;
+ case COND_EQ:
+ fprintf(fp, "== ");
+ break;
+ case COND_NEQ:
+ fprintf(fp, "!= ");
+ break;
+ default:
+ fprintf(fp, "error!");
+ break;
+ }
+ }
+}
+
+int display_cond_expressions(policydb_t * p, FILE * fp)
+{
+ cond_node_t *cur;
+ cond_av_list_t *av_cur, *expl = NULL;
+ avtab_t expa;
+
+ for (cur = p->cond_list; cur != NULL; cur = cur->next) {
+ fprintf(fp, "expression: ");
+ display_expr(p, cur->expr, fp);
+ fprintf(fp, "current state: %d\n", cur->cur_state);
+ fprintf(fp, "True list:\n");
+ if (avtab_init(&expa))
+ goto oom;
+ if (expand_cond_av_list(p, cur->true_list, &expl, &expa)) {
+ avtab_destroy(&expa);
+ goto oom;
+ }
+ for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
+ fprintf(fp, "\t");
+ render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+ RENDER_CONDITIONAL, p, fp);
+ }
+ cond_av_list_destroy(expl);
+ avtab_destroy(&expa);
+ fprintf(fp, "False list:\n");
+ if (avtab_init(&expa))
+ goto oom;
+ if (expand_cond_av_list(p, cur->false_list, &expl, &expa)) {
+ avtab_destroy(&expa);
+ goto oom;
+ }
+ for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
+ fprintf(fp, "\t");
+ render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+ RENDER_CONDITIONAL, p, fp);
+ }
+ cond_av_list_destroy(expl);
+ avtab_destroy(&expa);
+ }
+ return 0;
+
+ oom:
+ fprintf(stderr, "out of memory\n");
+ return 1;
+}
+
+int display_handle_unknown(policydb_t * p, FILE * out_fp)
+{
+ if (p->handle_unknown == ALLOW_UNKNOWN)
+ fprintf(out_fp, "Allow unknown classes and permisions\n");
+ else if (p->handle_unknown == DENY_UNKNOWN)
+ fprintf(out_fp, "Deny unknown classes and permisions\n");
+ else if (p->handle_unknown == REJECT_UNKNOWN)
+ fprintf(out_fp, "Reject unknown classes and permisions\n");
+ return 0;
+}
+
+int change_bool(char *name, int state, policydb_t * p, FILE * fp)
+{
+ cond_bool_datum_t *bool;
+
+ bool = hashtab_search(p->p_bools.table, name);
+ if (bool == NULL) {
+ fprintf(fp, "Could not find bool %s\n", name);
+ return -1;
+ }
+ bool->state = state;
+ evaluate_conds(p);
+ return 0;
+}
+
+static void display_policycaps(policydb_t * p, FILE * fp)
+{
+ ebitmap_node_t *node;
+ const char *capname;
+ char buf[64];
+ int i;
+
+ fprintf(fp, "policy capabilities:\n");
+ ebitmap_for_each_bit(&p->policycaps, node, i) {
+ if (ebitmap_node_get_bit(node, i)) {
+ capname = sepol_polcap_getname(i);
+ if (capname == NULL) {
+ snprintf(buf, sizeof(buf), "unknown (%d)", i);
+ capname = buf;
+ }
+ fprintf(fp, "\t%s\n", capname);
+ }
+ }
+}
+
+static void display_id(policydb_t *p, FILE *fp, uint32_t symbol_type,
+ uint32_t symbol_value, char *prefix)
+{
+ char *id = p->sym_val_to_name[symbol_type][symbol_value];
+ fprintf(fp, " %s%s", prefix, id);
+}
+
+static void display_permissive(policydb_t *p, FILE *fp)
+{
+ ebitmap_node_t *node;
+ int i;
+
+ fprintf(fp, "permissive sids:\n");
+ ebitmap_for_each_bit(&p->permissive_map, node, i) {
+ if (ebitmap_node_get_bit(node, i)) {
+ fprintf(fp, "\t");
+ display_id(p, fp, SYM_TYPES, i - 1, "");
+ fprintf(fp, "\n");
+ }
+ }
+}
+
+static void display_filename_trans(policydb_t *p, FILE *fp)
+{
+ filename_trans_t *ft;
+
+ fprintf(fp, "filename_trans rules:\n");
+ for (ft = p->filename_trans; ft; ft = ft->next) {
+ fprintf(fp, "%s\n", ft->name);
+ display_id(p, fp, SYM_TYPES, ft->stype - 1, "");
+ display_id(p, fp, SYM_TYPES, ft->ttype - 1, "");
+ display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":");
+ display_id(p, fp, SYM_TYPES, ft->otype - 1, "");
+ fprintf(fp, "\n");
+ }
+}
+
+int menu()
+{
+ printf("\nSelect a command:\n");
+ printf("1) display unconditional AVTAB\n");
+ printf("2) display conditional AVTAB (entirely)\n");
+ printf("3) display conditional AVTAG (only ENABLED rules)\n");
+ printf("4) display conditional AVTAB (only DISABLED rules)\n");
+ printf("5) display conditional bools\n");
+ printf("6) display conditional expressions\n");
+ printf("7) change a boolean value\n");
+ printf("\n");
+ printf("c) display policy capabilities\n");
+ printf("p) display the list of permissive types\n");
+ printf("u) display unknown handling setting\n");
+ printf("F) display filename_trans rules\n");
+ printf("\n");
+ printf("f) set output file\n");
+ printf("m) display menu\n");
+ printf("q) quit\n");
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *out_fp = stdout;
+ char ans[81], OutfileName[121];
+ int fd, ret;
+ struct stat sb;
+ void *map;
+ char *name;
+ int state;
+ struct policy_file pf;
+
+ if (argc != 2)
+ usage(argv[0]);
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open '%s': %s\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+ if (fstat(fd, &sb) < 0) {
+ fprintf(stderr, "Can't stat '%s': %s\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+ map =
+ mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED) {
+ fprintf(stderr, "Can't map '%s': %s\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+
+ /* read the binary policy */
+ fprintf(out_fp, "Reading policy...\n");
+ policy_file_init(&pf);
+ pf.type = PF_USE_MEMORY;
+ pf.data = map;
+ pf.len = sb.st_size;
+ if (policydb_init(&policydb)) {
+ fprintf(stderr, "%s: Out of memory!\n", argv[0]);
+ exit(1);
+ }
+ ret = policydb_read(&policydb, &pf, 1);
+ if (ret) {
+ fprintf(stderr,
+ "%s: error(s) encountered while parsing configuration\n",
+ argv[0]);
+ exit(1);
+ }
+
+ fprintf(stdout, "binary policy file loaded\n\n");
+ close(fd);
+
+ menu();
+ for (;;) {
+ printf("\nCommand (\'m\' for menu): ");
+ fgets(ans, sizeof(ans), stdin);
+ switch (ans[0]) {
+
+ case '1':
+ display_avtab(&policydb.te_avtab, RENDER_UNCONDITIONAL,
+ &policydb, out_fp);
+ break;
+ case '2':
+ display_avtab(&policydb.te_cond_avtab,
+ RENDER_CONDITIONAL, &policydb, out_fp);
+ break;
+ case '3':
+ display_avtab(&policydb.te_cond_avtab, RENDER_ENABLED,
+ &policydb, out_fp);
+ break;
+ case '4':
+ display_avtab(&policydb.te_cond_avtab, RENDER_DISABLED,
+ &policydb, out_fp);
+ break;
+ case '5':
+ display_bools(&policydb, out_fp);
+ break;
+ case '6':
+ display_cond_expressions(&policydb, out_fp);
+ break;
+ case '7':
+ printf("name? ");
+ fgets(ans, sizeof(ans), stdin);
+ ans[strlen(ans) - 1] = 0;
+
+ name = malloc((strlen(ans) + 1) * sizeof(char));
+ if (name == NULL) {
+ fprintf(stderr, "couldn't malloc string.\n");
+ break;
+ }
+ strcpy(name, ans);
+
+ printf("state? ");
+ fgets(ans, sizeof(ans), stdin);
+ ans[strlen(ans) - 1] = 0;
+
+ if (atoi(ans))
+ state = 1;
+ else
+ state = 0;
+
+ change_bool(name, state, &policydb, out_fp);
+ free(name);
+ break;
+ case 'c':
+ display_policycaps(&policydb, out_fp);
+ break;
+ case 'p':
+ display_permissive(&policydb, out_fp);
+ break;
+ case 'u':
+ case 'U':
+ display_handle_unknown(&policydb, out_fp);
+ break;
+ case 'f':
+ printf
+ ("\nFilename for output (<CR> for screen output): ");
+ fgets(OutfileName, sizeof(OutfileName), stdin);
+ OutfileName[strlen(OutfileName) - 1] = '\0'; /* fix_string (remove LF) */
+ if (strlen(OutfileName) == 0)
+ out_fp = stdout;
+ else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
+ fprintf(stderr, "Cannot open output file %s\n",
+ OutfileName);
+ out_fp = stdout;
+ }
+ if (out_fp != stdout)
+ printf("\nOutput to file: %s\n", OutfileName);
+ break;
+ case 'F':
+ display_filename_trans(&policydb, out_fp);
+ break;
+ case 'q':
+ policydb_destroy(&policydb);
+ exit(0);
+ break;
+ case 'm':
+ menu();
+ break;
+ default:
+ printf("\nInvalid choice\n");
+ menu();
+ break;
+
+ }
+ }
+}
+
+/* FLASK */