#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <ctype.h>
#include <alloca.h>
#include <fnmatch.h>
#include <syslog.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include "mcstrans.h"

/* Define data structures */
typedef struct secolor {
	uint32_t fg;
	uint32_t bg;
} secolor_t;

typedef struct semnemonic {
	char *name;
	uint32_t color;
	struct semnemonic *next;
} semnemonic_t;

typedef struct setab {
	char *pattern;
	secolor_t color;
	struct setab *next;
} setab_t;

#define COLOR_USER	0
#define COLOR_ROLE	1
#define COLOR_TYPE	2
#define COLOR_RANGE	3
#define N_COLOR		4

#define AUX_RULE_COLOR "color"
static char *rules[] = { "user", "role", "type", "range" };

static setab_t *clist[N_COLOR];
static setab_t *cend[N_COLOR];
static semnemonic_t *mnemonics;

static security_context_t my_context;

void finish_context_colors(void) {
	setab_t *cur, *next;
	semnemonic_t *ptr;
	unsigned i;

	for (i = 0; i < N_COLOR; i++) {
		cur = clist[i];
		while(cur) {
			next = cur->next;
			free(cur->pattern);
			free(cur);
			cur = next;
		}
		clist[i] = cend[i] = NULL;
	}

	ptr = mnemonics;
	while (ptr) {
		mnemonics = ptr->next;
		free(ptr->name);
		free(ptr);
		ptr = mnemonics;
	}
	mnemonics = NULL;

	freecon(my_context);
	my_context = NULL;
}

static int check_dominance(const char *pattern, const char *raw) {
	security_context_t ctx;
	context_t con;
	struct av_decision avd;
	int rc = -1;
	context_t my_tmp;
	const char *raw_range;
	security_class_t context_class = string_to_security_class("context");
	access_vector_t context_contains_perm = string_to_av_perm(context_class, "contains");

	con = context_new(raw);
	if (!con)
		return -1;
	raw_range = context_range_get(con);

	my_tmp = context_new(my_context);
	if (!my_tmp) {
		context_free(con);
		return -1;
	}

	ctx = NULL;
	if (context_range_set(my_tmp, pattern))
		goto out;
	ctx = strdup(context_str(my_tmp));
	if (!ctx)
		goto out;

	if (context_range_set(my_tmp, raw_range))
		goto out;
	raw = context_str(my_tmp);
	if (!raw)
		goto out;

	rc = security_compute_av_raw(ctx, (security_context_t)raw, context_class, context_contains_perm, &avd);
	if (rc)
		goto out;

	rc = (context_contains_perm & avd.allowed) != context_contains_perm;
out:
	free(ctx);
	context_free(my_tmp);
	context_free(con);
	return rc;
}

static const secolor_t *find_color(int idx, const char *component,
				   const char *raw) {
	setab_t *ptr = clist[idx];

	if (idx == COLOR_RANGE) {
		if (!raw) {
			return NULL;
		}
	} else if (!component) {
		return NULL;
	}

	while (ptr) {
		if (fnmatch(ptr->pattern, component, 0) == 0) {
			if (idx == COLOR_RANGE) {
			    if (check_dominance(ptr->pattern, raw) == 0)
					return &ptr->color;
			} else 
				return &ptr->color;
		}
		ptr = ptr->next;
	}

	return NULL;
}

static int add_secolor(int idx, char *pattern, uint32_t fg, uint32_t bg) {
	setab_t *cptr;

	cptr = calloc(1, sizeof(setab_t));
	if (!cptr) return -1;

	cptr->pattern = strdup(pattern);
	if (!cptr->pattern) {
		free(cptr);
		return -1;
	}

	cptr->color.fg = fg & 0xffffff;
	cptr->color.bg = bg & 0xffffff;

	if (cend[idx]) {
		cend[idx]->next = cptr;
		cend[idx] = cptr;
	} else {
		clist[idx] = cptr;
		cend[idx] = cptr;
	}
	return 0;
}

static int find_mnemonic(const char *name, uint32_t *retval)
{
	semnemonic_t *ptr;

	if (*name == '#')
		return sscanf(name, "#%x", retval) == 1 ? 0 : -1;

	ptr = mnemonics;
	while (ptr) {
		if (!strcmp(ptr->name, name)) {
			*retval = ptr->color;
			return 0;
		}
		ptr = ptr->next;
	}

	return -1;
}

static int add_mnemonic(const char *name, uint32_t color)
{
	semnemonic_t *ptr = malloc(sizeof(semnemonic_t));
	if (!ptr)
		return -1;

	ptr->color = color;
	ptr->name = strdup(name);
	if (!ptr->name) {
		free(ptr);
		return -1;
	}

	ptr->next = mnemonics;
	mnemonics = ptr;
	return 0;
}


/* Process line from color file.
   May modify the data pointed to by the buffer paremeter */
static int process_color(char *buffer, int line) {
	char rule[10], pat[256], f[256], b[256];
	uint32_t i, fg, bg;
	int ret;

	while(isspace(*buffer))
		buffer++;
	if(buffer[0] == '#' || buffer[0] == '\0') return 0;

	ret = sscanf(buffer, "%8s %255s = %255s %255s", rule, pat, f, b);
	if (ret == 4) {
		if (find_mnemonic(f, &fg) == 0 && find_mnemonic(b, &bg) == 0)
			for (i = 0; i < N_COLOR; i++)
				if (!strcmp(rule, rules[i]))
					return add_secolor(i, pat, fg, bg);
	}
	else if (ret == 3) {
		if (!strcmp(rule, AUX_RULE_COLOR)) {
			if (sscanf(f, "#%x", &fg) == 1)
				return add_mnemonic(pat, fg);
		}
	}

	syslog(LOG_WARNING, "Line %d of secolors file is invalid.", line);
	return 0;
}

/* Read in color file.
 */
int init_colors(void) {
	FILE *cfg = NULL;
	size_t size = 0;
	char *buffer = NULL;
	int line = 0;

	getcon(&my_context);

	cfg = fopen(selinux_colors_path(), "r");
	if (!cfg) return 1;

	__fsetlocking(cfg, FSETLOCKING_BYCALLER);
	while (getline(&buffer, &size, cfg) > 0) {
		if( process_color(buffer, ++line) < 0 ) break;
	}
	free(buffer);

	fclose(cfg);
	return 0;
}

static const unsigned precedence[N_COLOR][N_COLOR - 1] = {
	{ COLOR_ROLE, COLOR_TYPE, COLOR_RANGE },
	{ COLOR_USER, COLOR_TYPE, COLOR_RANGE },
	{ COLOR_USER, COLOR_ROLE, COLOR_RANGE },
	{ COLOR_USER, COLOR_ROLE, COLOR_TYPE },
};

static const secolor_t default_color = { 0x000000, 0xffffff };

static int parse_components(context_t con, char **components) {
	components[COLOR_USER] = (char *)context_user_get(con);
	components[COLOR_ROLE] = (char *)context_role_get(con);
	components[COLOR_TYPE] = (char *)context_type_get(con);
	components[COLOR_RANGE] = (char *)context_range_get(con);

	return 0;
}

/* Look up colors.
 */
int raw_color(const security_context_t raw, char **color_str) {
#define CHARS_PER_COLOR 16
	context_t con;
	uint32_t i, j, mask = 0;
	const secolor_t *items[N_COLOR];
	char *result, *components[N_COLOR];
	char buf[CHARS_PER_COLOR + 1];
	int rc = -1;

	if (!color_str && !*color_str) {
		return -1;
	}

	/* parse context and allocate memory */
	con = context_new(raw);
	if (!con)
		return -1;
	if (parse_components(con, components) < 0)
		goto out;

	result = malloc((N_COLOR * CHARS_PER_COLOR) + 1);
	if (!result)
		goto out;
	result[0] = '\0';

	/* find colors for which we have a match */
	for (i = 0; i < N_COLOR; i++) {
		items[i] = find_color(i, components[i], raw);
		if (items[i])
			mask |= (1 << i);
	}
	if (mask == 0) {
		items[0] = &default_color;
		mask = 1;
	}

	/* propagate colors according to the precedence rules */
	for (i = 0; i < N_COLOR; i++)
		if (!(mask & (1 << i)))
			for (j = 0; j < N_COLOR - 1; j++)
				if (mask & (1 << precedence[i][j])) {
					items[i] = items[precedence[i][j]];
					break;
				}

	/* print results into a big long string */
	for (i = 0; i < N_COLOR; i++) {
		snprintf(buf, sizeof(buf), "#%06x #%06x ",
			 items[i]->fg, items[i]->bg);
		strncat(result, buf, sizeof(buf));
	}

	*color_str = result;
	rc = 0;
out:
	context_free(con);

	return rc;
}
