
/* 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/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(const 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 if (key->specified & AVTAB_XPERMS) {
		if (key->specified & AVTAB_XPERMS_ALLOWED)
			fprintf(fp, "allowxperm ");
		else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
			fprintf(fp, "auditallowxperm ");
		else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
			fprintf(fp, "dontauditxperm ");
		render_key(key, p, fp);
		fprintf(fp, "%s;\n", sepol_extended_perms_to_string(datum->xperms));
	} 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)
{
	unsigned int i;
	avtab_ptr_t cur;

	/* hmm...should have used avtab_map. */
	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur; cur = cur->next) {
			render_av_rule(&cur->key, &cur->datum, what, p, fp);
		}
	}
	fprintf(fp, "\n");
	return 0;
}

int display_bools(policydb_t * p, FILE * fp)
{
	unsigned 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;

	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 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];
	unsigned 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, const char *prefix)
{
	const 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;
	unsigned 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_role_trans(policydb_t *p, FILE *fp)
{
	role_trans_t *rt;

	fprintf(fp, "role_trans rules:\n");
	for (rt = p->role_tr; rt; rt = rt->next) {
		display_id(p, fp, SYM_ROLES, rt->role - 1, "");
		display_id(p, fp, SYM_TYPES, rt->type - 1, "");
		display_id(p, fp, SYM_CLASSES, rt->tclass - 1, ":");
		display_id(p, fp, SYM_ROLES, rt->new_role - 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) {
		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, " %s\n", ft->name);
	}
}

int menu(void)
{
	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("8)  display role transitions\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):  ");
		if (fgets(ans, sizeof(ans), stdin) == NULL) {
			fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
					strerror(errno));
			continue;
		}
		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? ");
			if (fgets(ans, sizeof(ans), stdin) == NULL) {
				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
						strerror(errno));
				break;
			}
			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? ");
			if (fgets(ans, sizeof(ans), stdin) == NULL) {
				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
						strerror(errno));
				break;
			}
			ans[strlen(ans) - 1] = 0;

			if (atoi(ans))
				state = 1;
			else
				state = 0;

			change_bool(name, state, &policydb, out_fp);
			free(name);
			break;
		case '8':
			display_role_trans(&policydb, out_fp);
			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): ");
			if (fgets(OutfileName, sizeof(OutfileName), stdin) == NULL) {
				fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,
						strerror(errno));
				break;
			}
			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 */
