summaryrefslogtreecommitdiff
path: root/test/dispol.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/dispol.c')
-rw-r--r--test/dispol.c531
1 files changed, 531 insertions, 0 deletions
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 */