#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <search.h>
#include <stdbool.h>
#include <sepol/sepol.h>
#include <sepol/policydb/policydb.h>
#include <pcre2.h>

#define TABLE_SIZE 1024
#define KVP_NUM_OF_RULES (sizeof(rules) / sizeof(key_map))
#define log_set_verbose() do { logging_verbose = 1; log_info("Enabling verbose\n"); } while(0)
#define log_error(fmt, ...) log_msg(stderr, "Error: ", fmt, ##__VA_ARGS__)
#define log_warn(fmt, ...) log_msg(stderr, "Warning: ", fmt, ##__VA_ARGS__)
#define log_info(fmt, ...) if (logging_verbose ) { log_msg(stdout, "Info: ", fmt, ##__VA_ARGS__); }

#define APP_DATA_REQUIRED_ATTRIB "app_data_file_type"

/**
 * Initializes an empty, static list.
 */
#define list_init(free_fn) { .head = NULL, .tail = NULL, .freefn = (free_fn) }

/**
 * given an item in the list, finds the offset for the container
 * it was stored in.
 *
 * @element The element from the list
 * @type The container type ie what you allocated that has the list_element structure in it.
 * @name The name of the field that is the list_element
 *
 */
#define list_entry(element, type, name) \
		(type *)(((uint8_t *)(element)) - (uint8_t *)&(((type *)NULL)->name))

/**
 * Iterates over the list, do not free elements from the list when using this.
 * @list The list head to walk
 * @var The variable name for the cursor
 */
#define list_for_each(list, var) \
	for(var = (list)->head; var != NULL; var = var->next) /*NOLINT*/


typedef struct hash_entry hash_entry;
typedef enum key_dir key_dir;
typedef enum data_type data_type;
typedef enum rule_map_switch rule_map_switch;
typedef enum map_match map_match;
typedef struct key_map key_map;
typedef struct kvp kvp;
typedef struct rule_map rule_map;
typedef struct policy_info policy_info;
typedef struct list_element list_element;
typedef struct list list;
typedef struct key_map_regex key_map_regex;
typedef struct file_info file_info;

enum map_match {
	map_no_matches,
	map_input_matched,
	map_matched
};

const char *map_match_str[] = {
	"do not match",
	"match on all inputs",
	"match on everything"
};

/**
 * Whether or not the "key" from a key vaue pair is considered an
 * input or an output.
 */
enum key_dir {
	dir_in, dir_out
};

struct list_element {
	list_element *next;
};

struct list {
	list_element *head;
	list_element *tail;
	void (*freefn)(list_element *e);
};

struct key_map_regex {
	pcre2_code *compiled;
	pcre2_match_data *match_data;
};

/**
 * The workhorse of the logic. This struct maps key value pairs to
 * an associated set of meta data maintained in rule_map_new()
 */
struct key_map {
	char *name;
	key_dir dir;
	char *data;
	key_map_regex regex;
	bool (*fn_validate)(char *value, char **errmsg);
};

/**
 * Key value pair struct, this represents the raw kvp values coming
 * from the rules files.
 */
struct kvp {
	char *key;
	char *value;
};

/**
 * Rules are made up of meta data and an associated set of kvp stored in a
 * key_map array.
 */
struct rule_map {
	bool is_never_allow;
	list violations;
	list_element listify;
	char *key; /** key value before hashing */
	size_t length; /** length of the key map */
	int lineno; /** Line number rule was encounter on */
	char *filename; /** File it was found in */
	key_map m[]; /** key value mapping */
};

struct hash_entry {
	list_element listify;
	rule_map *r; /** The rule map to store at that location */
};

/**
 * Data associated for a policy file
 */
struct policy_info {

	char *policy_file_name; /** policy file path name */
	FILE *policy_file;      /** file handle to the policy file */
	sepol_policydb_t *db;
	sepol_policy_file_t *pf;
	sepol_handle_t *handle;
	sepol_context_t *con;
};

struct file_info {
	FILE *file; /** file itself */
	const char *name; /** name of file. do not free, these are not alloc'd */
	list_element listify;
};

static void input_file_list_freefn(list_element *e);
static void line_order_list_freefn(list_element *e);
static void rule_map_free(rule_map *rm, bool is_in_htable);

/** Set to !0 to enable verbose logging */
static int logging_verbose = 0;

/** file handle to the output file */
static file_info out_file;

static list input_file_list = list_init(input_file_list_freefn);

static policy_info pol = {
	.policy_file_name = NULL,
	.policy_file = NULL,
	.db = NULL,
	.pf = NULL,
	.handle = NULL,
	.con = NULL
};

/**
 * Head pointer to a linked list of
 * rule map table entries (hash_entry), used for
 * preserving the order of entries
 * based on "first encounter"
 */
static list line_order_list = list_init(line_order_list_freefn);

/*
 * List of hash_entrys for never allow rules.
 */
static list nallow_list = list_init(line_order_list_freefn);

/* validation call backs */
static bool validate_bool(char *value, char **errmsg);
static bool validate_levelFrom(char *value, char **errmsg);
static bool validate_domain(char *value, char **errmsg);
static bool validate_type(char *value, char **errmsg);
static bool validate_selinux_level(char *value, char **errmsg);
static bool validate_uint(char *value, char **errmsg);

/**
 * The heart of the mapping process, this must be updated if a new key value pair is added
 * to a rule.
 */
key_map rules[] = {
                /*Inputs*/
                { .name = "isSystemServer", .dir = dir_in, .fn_validate = validate_bool },
                { .name = "isEphemeralApp",  .dir = dir_in, .fn_validate = validate_bool },
                { .name = "isOwner",        .dir = dir_in, .fn_validate = validate_bool },
                { .name = "user",           .dir = dir_in,                              },
                { .name = "seinfo",         .dir = dir_in,                              },
                { .name = "name",           .dir = dir_in,                              },
                { .name = "path",           .dir = dir_in,                              },
                { .name = "isPrivApp",      .dir = dir_in, .fn_validate = validate_bool },
                { .name = "minTargetSdkVersion", .dir = dir_in, .fn_validate = validate_uint },
                { .name = "fromRunAs",       .dir = dir_in, .fn_validate = validate_bool },
                /*Outputs*/
                { .name = "domain",         .dir = dir_out, .fn_validate = validate_domain  },
                { .name = "type",           .dir = dir_out, .fn_validate = validate_type  },
                { .name = "levelFromUid",   .dir = dir_out, .fn_validate = validate_bool          },
                { .name = "levelFrom",      .dir = dir_out, .fn_validate = validate_levelFrom     },
                { .name = "level",          .dir = dir_out, .fn_validate = validate_selinux_level },
};

/**
 * Appends to the end of the list.
 * @list The list to append to
 * @e the element to append
 */
void list_append(list *list, list_element *e) {

	memset(e, 0, sizeof(*e));

	if (list->head == NULL ) {
		list->head = list->tail = e;
		return;
	}

	list->tail->next = e;
	list->tail = e;
	return;
}

/**
 * Free's all the elements in the specified list.
 * @list The list to free
 */
static void list_free(list *list) {

	list_element *tmp;
	list_element *cursor = list->head;

	while (cursor) {
		tmp = cursor;
		cursor = cursor->next;
		if (list->freefn) {
			list->freefn(tmp);
		}
	}
}

/*
 * called when the lists are freed
 */
static void line_order_list_freefn(list_element *e) {
	hash_entry *h = list_entry(e, typeof(*h), listify);
	rule_map_free(h->r, true);
	free(h);
}

static void input_file_list_freefn(list_element *e) {
	file_info *f = list_entry(e, typeof(*f), listify);

	if (f->file) {
		fclose(f->file);
	}
	free(f);
}

/**
 * Send a logging message to a file
 * @param out
 * 	Output file to send message too
 * @param prefix
 * 	A special prefix to write to the file, such as "Error:"
 * @param fmt
 * 	The printf style formatter to use, such as "%d"
 */
static void __attribute__ ((format(printf, 3, 4)))
log_msg(FILE *out, const char *prefix, const char *fmt, ...) {

	fprintf(out, "%s", prefix);
	va_list args;
	va_start(args, fmt);
	vfprintf(out, fmt, args);
	va_end(args);
}

/**
 * Look up a type in the policy.
 * @param db
 * 	The policy db to search
 * @param type
 * 	The type to search for
 * @param flavor
 * 	The expected flavor of type
 * @return
 * 	Pointer to the type's datum if it exists in the policy with the expected
 * 	flavor, NULL otherwise.
 * @warning
 * 	This function should not be called if libsepol is not linked statically
 * 	to this executable and LINK_SEPOL_STATIC is not defined.
 */
static type_datum_t *find_type(sepol_policydb_t *db, char *type, uint32_t flavor) {

	policydb_t *d = &db->p;
	hashtab_datum_t dat = hashtab_search(d->p_types.table, type);
        if (!dat) {
            return NULL;
        }
        type_datum_t *type_dat = (type_datum_t *) dat;
        if (type_dat->flavor != flavor) {
            return NULL;
        }
        return type_dat;
}

static bool type_has_attribute(sepol_policydb_t *db, type_datum_t *type_dat,
                               type_datum_t *attrib_dat) {
    policydb_t *d = &db->p;
    ebitmap_t *attr_bits = &d->type_attr_map[type_dat->s.value - 1];
    return ebitmap_get_bit(attr_bits, attrib_dat->s.value - 1) != 0;
}

static bool match_regex(key_map *assert, const key_map *check) {

	char *tomatch = check->data;

	int ret = pcre2_match(assert->regex.compiled, (PCRE2_SPTR) tomatch,
				PCRE2_ZERO_TERMINATED, 0, 0,
				assert->regex.match_data, NULL);

	/* ret > 0 from pcre2_match means matched */
	return ret > 0;
}

static bool compile_regex(key_map *km, int *errcode, PCRE2_SIZE *erroff) {

	size_t size;
	char *anchored;

	/*
	 * Explicitly anchor all regex's
	 * The size is the length of the string to anchor (km->data), the anchor
	 * characters ^ and $ and the null byte. Hence strlen(km->data) + 3
	 */
	size = strlen(km->data) + 3;
	anchored = alloca(size);
	sprintf(anchored, "^%s$", km->data);

	km->regex.compiled = pcre2_compile((PCRE2_SPTR) anchored,
						PCRE2_ZERO_TERMINATED,
						PCRE2_DOTALL,
						errcode, erroff,
						NULL);
	if (!km->regex.compiled) {
		return false;
	}

	km->regex.match_data = pcre2_match_data_create_from_pattern(
			km->regex.compiled, NULL);
	if (!km->regex.match_data) {
		pcre2_code_free(km->regex.compiled);
		return false;
	}
	return true;
}

static bool validate_bool(char *value, char **errmsg) {

	if (!strcmp("true", value) || !strcmp("false", value)) {
		return true;
	}

	*errmsg = "Expecting \"true\" or \"false\"";
	return false;
}

static bool validate_levelFrom(char *value, char **errmsg) {

	if (strcasecmp(value, "none") && strcasecmp(value, "all") &&
		strcasecmp(value, "app") && strcasecmp(value, "user")) {
		*errmsg = "Expecting one of: \"none\", \"all\", \"app\" or \"user\"";
		return false;
	}
	return true;
}

static bool validate_domain(char *value, char **errmsg) {

#if defined(LINK_SEPOL_STATIC)
	/*
	 * No policy file present means we cannot check
	 * SE Linux types
	 */
	if (!pol.policy_file) {
		return true;
	}

	if (!find_type(pol.db, value, TYPE_TYPE)) {
		*errmsg = "Expecting a valid SELinux type";
		return false;
	}
#endif

	return true;
}

static bool validate_type(char *value, char **errmsg) {

#if defined(LINK_SEPOL_STATIC)
	/*
	 * No policy file present means we cannot check
	 * SE Linux types
	 */
	if (!pol.policy_file) {
		return true;
	}

        type_datum_t *type_dat = find_type(pol.db, value, TYPE_TYPE);
	if (!type_dat) {
		*errmsg = "Expecting a valid SELinux type";
		return false;
	}

        type_datum_t *attrib_dat = find_type(pol.db, APP_DATA_REQUIRED_ATTRIB,
                                              TYPE_ATTRIB);
	if (!attrib_dat) {
            /* If the policy doesn't contain the attribute, we can't check it */
            return true;
        }

        if (!type_has_attribute(pol.db, type_dat, attrib_dat)) {
            *errmsg = "Missing required attribute " APP_DATA_REQUIRED_ATTRIB;
            return false;
        }

#endif

	return true;
}

static bool validate_selinux_level(char *value, char **errmsg) {

	/*
	 * No policy file present means we cannot check
	 * SE Linux MLS
	 */
	if (!pol.policy_file) {
		return true;
	}

	int ret = sepol_mls_check(pol.handle, pol.db, value);
	if (ret < 0) {
		*errmsg = "Expecting a valid SELinux MLS value";
		return false;
	}

	return true;
}

static bool validate_uint(char *value, char **errmsg) {

	char *endptr;
	long longvalue;
	longvalue = strtol(value, &endptr, 10);
	if (('\0' != *endptr) || (longvalue < 0) || (longvalue > INT32_MAX)) {
		*errmsg = "Expecting a valid unsigned integer";
		return false;
	}

	return true;
}

/**
 * Validates a key_map against a set of enforcement rules, this
 * function exits the application on a type that cannot be properly
 * checked
 *
 * @param m
 * 	The key map to check
 * @param lineno
 * 	The line number in the source file for the corresponding key map
 * @return
 * 	true if valid, false if invalid
 */
static bool key_map_validate(key_map *m, const char *filename, int lineno,
		bool is_neverallow) {

	PCRE2_SIZE erroff;
	int errcode;
	bool rc = true;
	char *key = m->name;
	char *value = m->data;
	char *errmsg = NULL;
	char errstr[256];

	log_info("Validating %s=%s\n", key, value);

	/*
	 * Neverallows are completely skipped from validity checking so you can match
	 * un-unspecified inputs.
	 */
	if (is_neverallow) {
		if (!m->regex.compiled) {
			rc = compile_regex(m, &errcode, &erroff);
			if (!rc) {
				pcre2_get_error_message(errcode,
							(PCRE2_UCHAR*) errstr,
							sizeof(errstr));
				log_error("Invalid regex on line %d : %s PCRE error: %s at offset %lu",
						lineno, value, errstr, erroff);
			}
		}
		goto out;
	}

	/* If the key has a validation routine, call it */
	if (m->fn_validate) {
		rc = m->fn_validate(value, &errmsg);

		if (!rc) {
			log_error("Could not validate key \"%s\" for value \"%s\" on line: %d in file: \"%s\": %s\n", key, value,
			lineno, filename, errmsg);
		}
	}

out:
	log_info("Key map validate returning: %d\n", rc);
	return rc;
}

/**
 * Prints a rule map back to a file
 * @param fp
 * 	The file handle to print too
 * @param r
 * 	The rule map to print
 */
static void rule_map_print(FILE *fp, rule_map *r) {

	size_t i;
	key_map *m;

	for (i = 0; i < r->length; i++) {
		m = &(r->m[i]);
		if (i < r->length - 1)
			fprintf(fp, "%s=%s ", m->name, m->data);
		else
			fprintf(fp, "%s=%s", m->name, m->data);
	}
}

/**
 * Compare two rule maps for equality
 * @param rmA
 * 	a rule map to check
 * @param rmB
 * 	a rule map to check
 * @return
 *  a map_match enum indicating the result
 */
static map_match rule_map_cmp(rule_map *rmA, rule_map *rmB) {

	size_t i;
	size_t j;
	int inputs_found = 0;
	int num_of_matched_inputs = 0;
	int input_mode = 0;
	size_t matches = 0;
	key_map *mA;
	key_map *mB;

	for (i = 0; i < rmA->length; i++) {
		mA = &(rmA->m[i]);

		for (j = 0; j < rmB->length; j++) {
			mB = &(rmB->m[j]);
			input_mode = 0;

			if (strcmp(mA->name, mB->name))
				continue;

			if (strcmp(mA->data, mB->data))
				continue;

			if (mB->dir != mA->dir)
				continue;
			else if (mB->dir == dir_in) {
				input_mode = 1;
				inputs_found++;
			}

			if (input_mode) {
				log_info("Matched input lines: name=%s data=%s\n", mA->name, mA->data);
				num_of_matched_inputs++;
			}

			/* Match found, move on */
			log_info("Matched lines: name=%s data=%s", mA->name, mA->data);
			matches++;
			break;
		}
	}

	/* If they all matched*/
	if (matches == rmA->length) {
		log_info("Rule map cmp MATCH\n");
		return map_matched;
	}

	/* They didn't all match but the input's did */
	else if (num_of_matched_inputs == inputs_found) {
		log_info("Rule map cmp INPUT MATCH\n");
		return map_input_matched;
	}

	/* They didn't all match, and the inputs didn't match, ie it didn't
	 * match */
	else {
		log_info("Rule map cmp NO MATCH\n");
		return map_no_matches;
	}
}

/**
 * Frees a rule map
 * @param rm
 * 	rule map to be freed.
 * @is_in_htable
 * 	True if the rule map has been added to the hash table, false
 * 	otherwise.
 */
static void rule_map_free(rule_map *rm, bool is_in_htable) {

	size_t i;
	size_t len = rm->length;
	for (i = 0; i < len; i++) {
		key_map *m = &(rm->m[i]);
		free(m->data);

		if (m->regex.compiled) {
			pcre2_code_free(m->regex.compiled);
		}

		if (m->regex.match_data) {
			pcre2_match_data_free(m->regex.match_data);
		}
	}

	/*
	 * hdestroy() frees comparsion keys for non glibc
	 * on GLIBC we always free on NON-GLIBC we free if
	 * it is not in the htable.
	 */
	if (rm->key) {
#ifdef __GLIBC__
		/* silence unused warning */
		(void)is_in_htable;
		free(rm->key);
#else
		if (!is_in_htable) {
			free(rm->key);
		}
#endif
	}

	free(rm->filename);
	free(rm);
}

static void free_kvp(kvp *k) {
	free(k->key);
	free(k->value);
}

/**
 * Checks a rule_map for any variation of KVP's that shouldn't be allowed.
 * It builds an assertion failure list for each rule map.
 * Note that this function logs all errors.
 *
 * Current Checks:
 * 1. That a specified name entry should have a specified seinfo entry as well.
 * 2. That no rule violates a neverallow
 * @param rm
 *  The rule map to check for validity.
 */
static void rule_map_validate(rule_map *rm) {

	size_t i, j;
	const key_map *rule;
	key_map *nrule;
	hash_entry *e;
	rule_map *assert;
	list_element *cursor;

	list_for_each(&nallow_list, cursor) {
		e = list_entry(cursor, typeof(*e), listify);
		assert = e->r;

		size_t cnt = 0;

		for (j = 0; j < assert->length; j++) {
			nrule = &(assert->m[j]);

			// mark that nrule->name is for a null check
			bool is_null_check = !strcmp(nrule->data, "\"\"");

			for (i = 0; i < rm->length; i++) {
				rule = &(rm->m[i]);

				if (!strcmp(rule->name, nrule->name)) {

					/* the name was found, (data cannot be false) then it was specified */
					is_null_check = false;

					if (match_regex(nrule, rule)) {
						cnt++;
					}
				}
			}

			/*
			 * the nrule was marked in a null check and we never found a match on nrule, thus
			 * it matched and we update the cnt
			 */
			if (is_null_check) {
				cnt++;
			}
		}
		if (cnt == assert->length) {
			list_append(&rm->violations, &assert->listify);
		}
	}
}

/**
 * Given a set of key value pairs, this will construct a new rule map.
 * On error this function calls exit.
 * @param keys
 * 	Keys from a rule line to map
 * @param num_of_keys
 * 	The length of the keys array
 * @param lineno
 * 	The line number the keys were extracted from
 * @return
 * 	A rule map pointer.
 */
static rule_map *rule_map_new(kvp keys[], size_t num_of_keys, int lineno,
		const char *filename, bool is_never_allow) {

	size_t i = 0, j = 0;
	rule_map *new_map = NULL;
	kvp *k = NULL;
	key_map *r = NULL, *x = NULL;
	bool seen[KVP_NUM_OF_RULES];

	for (i = 0; i < KVP_NUM_OF_RULES; i++)
		seen[i] = false;

	new_map = calloc(1, (num_of_keys * sizeof(key_map)) + sizeof(rule_map));
	if (!new_map)
		goto oom;

	new_map->is_never_allow = is_never_allow;
	new_map->length = num_of_keys;
	new_map->lineno = lineno;
	new_map->filename = strdup(filename);
	if (!new_map->filename) {
		goto oom;
	}

	/* For all the keys in a rule line*/
	for (i = 0; i < num_of_keys; i++) {
		k = &(keys[i]);
		r = &(new_map->m[i]);

		for (j = 0; j < KVP_NUM_OF_RULES; j++) {
			x = &(rules[j]);

			/* Only assign key name to map name */
			if (strcasecmp(k->key, x->name)) {
				if (j == KVP_NUM_OF_RULES - 1) {
					log_error("No match for key: %s\n", k->key);
					goto err;
				}
				continue;
			}

			if (seen[j]) {
					log_error("Duplicated key: %s\n", k->key);
					goto err;
			}
			seen[j] = true;

			memcpy(r, x, sizeof(key_map));

			/* Assign rule map value to one from file */
			r->data = strdup(k->value);
			if (!r->data)
				goto oom;

			/* Enforce type check*/
			log_info("Validating keys!\n");
			if (!key_map_validate(r, filename, lineno, new_map->is_never_allow)) {
				log_error("Could not validate\n");
				goto err;
			}

			/*
			 * Only build key off of inputs with the exception of neverallows.
			 * Neverallows are keyed off of all key value pairs,
			 */
			if (r->dir == dir_in || new_map->is_never_allow) {
				char *tmp;
				int key_len = strlen(k->key);
				int val_len = strlen(k->value);
				int l = (new_map->key) ? strlen(new_map->key) : 0;
				l = l + key_len + val_len;
				l += 1;

				tmp = realloc(new_map->key, l);
				if (!tmp)
					goto oom;

				if (!new_map->key)
					memset(tmp, 0, l);

				new_map->key = tmp;

				strncat(new_map->key, k->key, key_len);
				strncat(new_map->key, k->value, val_len);
			}
			break;
		}
		free_kvp(k);
	}

	if (new_map->key == NULL) {
		log_error("Strange, no keys found, input file corrupt perhaps?\n");
		goto err;
	}

	return new_map;

oom:
	log_error("Out of memory!\n");
err:
	if (new_map) {
		rule_map_free(new_map, false);
		for (; i < num_of_keys; i++) {
			k = &(keys[i]);
			free_kvp(k);
		}
	}
	return NULL;
}

/**
 * Print the usage of the program
 */
static void usage() {
	printf(
	        "checkseapp [options] <input file>\n"
		        "Processes an seapp_contexts file specified by argument <input file> (default stdin) "
		        "and allows later declarations to override previous ones on a match.\n"
		        "Options:\n"
		        "-h - print this help message\n"
		        "-v - enable verbose debugging informations\n"
		        "-p policy file - specify policy file for strict checking of output selectors against the policy\n"
		        "-o output file - specify output file or - for stdout. No argument runs in silent mode and outputs nothing\n");
}

static void init() {

	bool has_out_file;
	list_element *cursor;
	file_info *tmp;

	/* input files if the list is empty, use stdin */
	if (!input_file_list.head) {
		log_info("Using stdin for input\n");
		tmp = malloc(sizeof(*tmp));
		if (!tmp) {
			log_error("oom");
			exit(EXIT_FAILURE);
		}
		tmp->name = "stdin";
		tmp->file = stdin;
		list_append(&input_file_list, &(tmp->listify));
	}
	else {
		list_for_each(&input_file_list, cursor) {
			tmp = list_entry(cursor, typeof(*tmp), listify);

			log_info("Opening input file: \"%s\"\n", tmp->name);
			tmp->file = fopen(tmp->name, "r");
			if (!tmp->file) {
				log_error("Could not open file: %s error: %s\n", tmp->name,
						strerror(errno));
				exit(EXIT_FAILURE);
			}
		}
	}

	has_out_file = out_file.name != NULL;

	/* If output file is -, then use stdout, else open the path */
	if (has_out_file && !strcmp(out_file.name, "-")) {
		out_file.file = stdout;
		out_file.name = "stdout";
	}
	else if (has_out_file) {
		out_file.file = fopen(out_file.name, "w+");
	}

	if (has_out_file && !out_file.file) {
		log_error("Could not open file: \"%s\" error: \"%s\"\n", out_file.name,
				strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (pol.policy_file_name) {
		log_info("Opening policy file: %s\n", pol.policy_file_name);
		pol.policy_file = fopen(pol.policy_file_name, "rb");
		if (!pol.policy_file) {
			log_error("Could not open file: %s error: %s\n",
					pol.policy_file_name, strerror(errno));
			exit(EXIT_FAILURE);
		}

		pol.handle = sepol_handle_create();
		if (!pol.handle) {
			log_error("Could not create sepolicy handle: %s\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (sepol_policy_file_create(&pol.pf) < 0) {
			log_error("Could not create sepolicy file: %s!\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		sepol_policy_file_set_fp(pol.pf, pol.policy_file);
		sepol_policy_file_set_handle(pol.pf, pol.handle);

		if (sepol_policydb_create(&pol.db) < 0) {
			log_error("Could not create sepolicy db: %s!\n",
					strerror(errno));
			exit(EXIT_FAILURE);
		}

		if (sepol_policydb_read(pol.db, pol.pf) < 0) {
			log_error("Could not load policy file to db: invalid input file!\n");
			exit(EXIT_FAILURE);
		}
	}

	list_for_each(&input_file_list, cursor) {
		tmp = list_entry(cursor, typeof(*tmp), listify);
		log_info("Input file set to: \"%s\"\n", tmp->name);
	}

	log_info("Policy file set to: \"%s\"\n",
			(pol.policy_file_name == NULL) ? "None" : pol.policy_file_name);
	log_info("Output file set to: \"%s\"\n", out_file.name);

#if !defined(LINK_SEPOL_STATIC)
	log_warn("LINK_SEPOL_STATIC is not defined\n""Not checking types!");
#endif

}

/**
 * Handle parsing and setting the global flags for the command line
 * options. This function calls exit on failure.
 * @param argc
 * 	argument count
 * @param argv
 * 	argument list
 */
static void handle_options(int argc, char *argv[]) {

	int c;
	file_info *input_file;

	while ((c = getopt(argc, argv, "ho:p:v")) != -1) {
		switch (c) {
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
		case 'o':
			out_file.name = optarg;
			break;
		case 'p':
			pol.policy_file_name = optarg;
			break;
		case 'v':
			log_set_verbose();
			break;
		case '?':
			if (optopt == 'o' || optopt == 'p')
				log_error("Option -%c requires an argument.\n", optopt);
			else if (isprint (optopt))
				log_error("Unknown option `-%c'.\n", optopt);
			else {
				log_error(
						"Unknown option character `\\x%x'.\n",
						optopt);
			}
		default:
			exit(EXIT_FAILURE);
		}
	}

	for (c = optind; c < argc; c++) {

		input_file = calloc(1, sizeof(*input_file));
		if (!input_file) {
			log_error("oom");
			exit(EXIT_FAILURE);
		}
		input_file->name = argv[c];
		list_append(&input_file_list, &input_file->listify);
	}
}

/**
 * Adds a rule to the hash table and to the ordered list if needed.
 * @param rm
 * 	The rule map to add.
 */
static void rule_add(rule_map *rm) {

	map_match cmp;
	ENTRY e;
	ENTRY *f;
	hash_entry *entry;
	hash_entry *tmp;
	list *list_to_addto;

	e.key = rm->key;
	e.data = NULL;

	log_info("Searching for key: %s\n", e.key);
	/* Check to see if it has already been added*/
	f = hsearch(e, FIND);

	/*
	 * Since your only hashing on a partial key, the inputs we need to handle
	 * when you want to override the outputs for a given input set, as well as
	 * checking for duplicate entries.
	 */
	if (f) {
		log_info("Existing entry found!\n");
		tmp = (hash_entry *)f->data;
		cmp = rule_map_cmp(rm, tmp->r);
		log_error("Duplicate line detected in file: %s\n"
			  "Lines %d and %d %s!\n",
			  rm->filename, tmp->r->lineno, rm->lineno,
			  map_match_str[cmp]);
		rule_map_free(rm, false);
		goto err;
	}
	/* It wasn't found, just add the rule map to the table */
	else {

		entry = malloc(sizeof(hash_entry));
		if (!entry)
			goto oom;

		entry->r = rm;
		e.data = entry;

		f = hsearch(e, ENTER);
		if (f == NULL) {
			goto oom;
		}

		/* new entries must be added to the ordered list */
		entry->r = rm;
		list_to_addto = rm->is_never_allow ? &nallow_list : &line_order_list;
		list_append(list_to_addto, &entry->listify);
	}

	return;
oom:
	if (e.key)
		free(e.key);
	if (entry)
		free(entry);
	if (rm)
		free(rm);
	log_error("Out of memory in function: %s\n", __FUNCTION__);
err:
	exit(EXIT_FAILURE);
}

static void parse_file(file_info *in_file) {

	char *p;
	size_t len;
	char *token;
	char *saveptr;
	bool is_never_allow;
	bool found_whitespace;

	size_t lineno = 0;
	char *name = NULL;
	char *value = NULL;
	size_t token_cnt = 0;

	char line_buf[BUFSIZ];
	kvp keys[KVP_NUM_OF_RULES];

	while (fgets(line_buf, sizeof(line_buf) - 1, in_file->file)) {
		lineno++;
		is_never_allow = false;
		found_whitespace = false;
		log_info("Got line %zu\n", lineno);
		len = strlen(line_buf);
		if (line_buf[len - 1] == '\n')
			line_buf[len - 1] = '\0';
		p = line_buf;

		/* neverallow lines must start with neverallow (ie ^neverallow) */
		if (!strncasecmp(p, "neverallow", strlen("neverallow"))) {
			p += strlen("neverallow");
			is_never_allow = true;
		}

		/* strip trailing whitespace skip comments */
		while (isspace(*p)) {
			p++;
			found_whitespace = true;
		}
		if (*p == '#' || *p == '\0')
			continue;

		token = strtok_r(p, " \t", &saveptr);
		if (!token)
			goto err;

		token_cnt = 0;
		memset(keys, 0, sizeof(kvp) * KVP_NUM_OF_RULES);
		while (1) {

			name = token;
			value = strchr(name, '=');
			if (!value)
				goto err;
			*value++ = 0;

			keys[token_cnt].key = strdup(name);
			if (!keys[token_cnt].key)
				goto oom;

			keys[token_cnt].value = strdup(value);
			if (!keys[token_cnt].value)
				goto oom;

			token_cnt++;

			token = strtok_r(NULL, " \t", &saveptr);
			if (!token)
				break;

			if (token_cnt == KVP_NUM_OF_RULES)
				goto oob;

		} /*End token parsing */

		rule_map *r = rule_map_new(keys, token_cnt, lineno, in_file->name, is_never_allow);
		if (!r)
			goto err;
		rule_add(r);

	} /* End file parsing */
	return;

err:
	log_error("Reading file: \"%s\" line: %zu name: \"%s\" value: \"%s\"\n",
		in_file->name, lineno, name, value);
	if (found_whitespace && name && !strcasecmp(name, "neverallow")) {
		log_error("perhaps whitespace before neverallow\n");
	}
	exit(EXIT_FAILURE);
oom:
	log_error("In function %s:  Out of memory\n", __FUNCTION__);
	exit(EXIT_FAILURE);
oob:
	log_error("Reading file: \"%s\" line: %zu reason: the size of key pairs exceeds the MAX(%zu)\n",
		in_file->name, lineno, KVP_NUM_OF_RULES);
	exit(EXIT_FAILURE);
}

/**
 * Parses the seapp_contexts file and neverallow file
 * and adds them to the hash table and ordered list entries
 * when it encounters them.
 * Calls exit on failure.
 */
static void parse() {

	file_info *current;
	list_element *cursor;
	list_for_each(&input_file_list, cursor) {
		current = list_entry(cursor, typeof(*current), listify);
		parse_file(current);
	}
}

static void validate() {

	list_element *cursor, *v;
	bool found_issues = false;
	hash_entry *e;
	rule_map *r;
	list_for_each(&line_order_list, cursor) {
		e = list_entry(cursor, typeof(*e), listify);
		rule_map_validate(e->r);
	}

	list_for_each(&line_order_list, cursor) {
		e = list_entry(cursor, typeof(*e), listify);
		r = e->r;
		list_for_each(&r->violations, v) {
			found_issues = true;
			log_error("Rule in File \"%s\" on line %d: \"", e->r->filename, e->r->lineno);
			rule_map_print(stderr, e->r);
			r = list_entry(v, rule_map, listify);
			fprintf(stderr, "\" violates neverallow in File \"%s\" on line %d: \"", r->filename, r->lineno);
			rule_map_print(stderr, r);
			fprintf(stderr, "\"\n");
		}
	}

	if (found_issues) {
		exit(EXIT_FAILURE);
	}
}

/**
 * Should be called after parsing to cause the printing of the rule_maps
 * stored in the ordered list, head first, which preserves the "first encountered"
 * ordering.
 */
static void output() {

	hash_entry *e;
	list_element *cursor;

	if (!out_file.file) {
		log_info("No output file, not outputting.\n");
		return;
	}

	list_for_each(&line_order_list, cursor) {
		e = list_entry(cursor, hash_entry, listify);
		rule_map_print(out_file.file, e->r);
		fprintf(out_file.file, "\n");
	}
}

/**
 * This function is registered to the at exit handler and should clean up
 * the programs dynamic resources, such as memory and fd's.
 */
static void cleanup() {

	/* Only close this when it was opened by me and not the crt */
	if (out_file.name && strcmp(out_file.name, "stdout") && out_file.file) {
		log_info("Closing file: %s\n", out_file.name);
		fclose(out_file.file);
	}

	if (pol.policy_file) {

		log_info("Closing file: %s\n", pol.policy_file_name);
		fclose(pol.policy_file);

		if (pol.db)
			sepol_policydb_free(pol.db);

		if (pol.pf)
			sepol_policy_file_free(pol.pf);

		if (pol.handle)
			sepol_handle_destroy(pol.handle);
	}

	log_info("Freeing lists\n");
	list_free(&input_file_list);
	list_free(&line_order_list);
	list_free(&nallow_list);
	hdestroy();
}

int main(int argc, char *argv[]) {
	if (!hcreate(TABLE_SIZE)) {
		log_error("Could not create hash table: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	atexit(cleanup);
	handle_options(argc, argv);
	init();
	log_info("Starting to parse\n");
	parse();
	log_info("Parsing completed, generating output\n");
	validate();
	output();
	log_info("Success, generated output\n");
	exit(EXIT_SUCCESS);
}
