#ifndef _SELABEL_FILE_H_
#define _SELABEL_FILE_H_

#include <errno.h>
#include <pthread.h>
#include <string.h>

#include <sys/stat.h>
#include <sys/xattr.h>

/*
 * regex.h/c were introduced to hold all dependencies on the regular
 * expression back-end when we started supporting PCRE2. regex.h defines a
 * minimal interface required by libselinux, so that the remaining code
 * can be agnostic about the underlying implementation.
 */
#include "regex.h"

#include "callbacks.h"
#include "label_internal.h"
#include "selinux_internal.h"

#define SELINUX_MAGIC_COMPILED_FCONTEXT	0xf97cff8a

/* Version specific changes */
#define SELINUX_COMPILED_FCONTEXT_NOPCRE_VERS	1
#define SELINUX_COMPILED_FCONTEXT_PCRE_VERS	2
#define SELINUX_COMPILED_FCONTEXT_MODE		3
#define SELINUX_COMPILED_FCONTEXT_PREFIX_LEN	4
#define SELINUX_COMPILED_FCONTEXT_REGEX_ARCH	5

#define SELINUX_COMPILED_FCONTEXT_MAX_VERS \
	SELINUX_COMPILED_FCONTEXT_REGEX_ARCH

/* Required selinux_restorecon and selabel_get_digests_all_partial_matches() */
#define RESTORECON_PARTIAL_MATCH_DIGEST  "security.sehash"

struct selabel_sub {
	char *src;
	int slen;
	char *dst;
	struct selabel_sub *next;
};

/* A file security context specification. */
struct spec {
	struct selabel_lookup_rec lr;	/* holds contexts for lookup result */
	char *regex_str;	/* regular expression string for diagnostics */
	char *type_str;		/* type string for diagnostic messages */
	struct regex_data * regex; /* backend dependent regular expression data */
	bool regex_compiled; /* bool to indicate if the regex is compiled */
	pthread_mutex_t regex_lock; /* lock for lazy compilation of regex */
	mode_t mode;		/* mode format value */
	int matches;		/* number of matching pathnames */
	int stem_id;		/* indicates which stem-compression item */
	char hasMetaChars;	/* regular expression has meta-chars */
	char from_mmap;		/* this spec is from an mmap of the data */
	size_t prefix_len;      /* length of fixed path prefix */
};

/* A regular expression stem */
struct stem {
	char *buf;
	int len;
	char from_mmap;
};

/* Where we map the file in during selabel_open() */
struct mmap_area {
	void *addr;	/* Start addr + len used to release memory at close */
	size_t len;
	void *next_addr;	/* Incremented by next_entry() */
	size_t next_len;	/* Decremented by next_entry() */
	struct mmap_area *next;
};

/* Our stored configuration */
struct saved_data {
	/*
	 * The array of specifications, initially in the same order as in
	 * the specification file. Sorting occurs based on hasMetaChars.
	 */
	struct spec *spec_arr;
	unsigned int nspec;
	unsigned int alloc_specs;

	/*
	 * The array of regular expression stems.
	 */
	struct stem *stem_arr;
	int num_stems;
	int alloc_stems;
	struct mmap_area *mmap_areas;

	/* substitution support */
	struct selabel_sub *dist_subs;
	struct selabel_sub *subs;
};

static inline mode_t string_to_mode(char *mode)
{
	size_t len;

	if (!mode)
		return 0;
	len = strlen(mode);
	if (mode[0] != '-' || len != 2)
		return -1;
	switch (mode[1]) {
	case 'b':
		return S_IFBLK;
	case 'c':
		return S_IFCHR;
	case 'd':
		return S_IFDIR;
	case 'p':
		return S_IFIFO;
	case 'l':
		return S_IFLNK;
	case 's':
		return S_IFSOCK;
	case '-':
		return S_IFREG;
	default:
		return -1;
	}
	/* impossible to get here */
	return 0;
}

static inline int grow_specs(struct saved_data *data)
{
	struct spec *specs;
	size_t new_specs, total_specs;

	if (data->nspec < data->alloc_specs)
		return 0;

	new_specs = data->nspec + 16;
	total_specs = data->nspec + new_specs;

	specs = realloc(data->spec_arr, total_specs * sizeof(*specs));
	if (!specs) {
		perror("realloc");
		return -1;
	}

	/* blank the new entries */
	memset(&specs[data->nspec], 0, new_specs * sizeof(*specs));

	data->spec_arr = specs;
	data->alloc_specs = total_specs;
	return 0;
}

/* Determine if the regular expression specification has any meta characters. */
static inline void spec_hasMetaChars(struct spec *spec)
{
	char *c;
	int len;
	char *end;

	c = spec->regex_str;
	len = strlen(spec->regex_str);
	end = c + len;

	spec->hasMetaChars = 0;
	spec->prefix_len = len;

	/* Look at each character in the RE specification string for a
	 * meta character. Return when any meta character reached. */
	while (c < end) {
		switch (*c) {
		case '.':
		case '^':
		case '$':
		case '?':
		case '*':
		case '+':
		case '|':
		case '[':
		case '(':
		case '{':
			spec->hasMetaChars = 1;
			spec->prefix_len = c - spec->regex_str;
			return;
		case '\\':	/* skip the next character */
			c++;
			break;
		default:
			break;

		}
		c++;
	}
}

/* Move exact pathname specifications to the end. */
static inline int sort_specs(struct saved_data *data)
{
	struct spec *spec_copy;
	struct spec spec;
	unsigned int i;
	int front, back;
	size_t len = sizeof(*spec_copy);

	spec_copy = malloc(len * data->nspec);
	if (!spec_copy)
		return -1;

	/* first move the exact pathnames to the back */
	front = 0;
	back = data->nspec - 1;
	for (i = 0; i < data->nspec; i++) {
		if (data->spec_arr[i].hasMetaChars)
			memcpy(&spec_copy[front++], &data->spec_arr[i], len);
		else
			memcpy(&spec_copy[back--], &data->spec_arr[i], len);
	}

	/*
	 * now the exact pathnames are at the end, but they are in the reverse
	 * order. Since 'front' is now the first of the 'exact' we can run
	 * that part of the array switching the front and back element.
	 */
	back = data->nspec - 1;
	while (front < back) {
		/* save the front */
		memcpy(&spec, &spec_copy[front], len);
		/* move the back to the front */
		memcpy(&spec_copy[front], &spec_copy[back], len);
		/* put the old front in the back */
		memcpy(&spec_copy[back], &spec, len);
		front++;
		back--;
	}

	free(data->spec_arr);
	data->spec_arr = spec_copy;

	return 0;
}

/* Return the length of the text that can be considered the stem, returns 0
 * if there is no identifiable stem */
static inline int get_stem_from_spec(const char *const buf)
{
	const char *tmp = strchr(buf + 1, '/');
	const char *ind;

	if (!tmp)
		return 0;

	for (ind = buf; ind < tmp; ind++) {
		if (strchr(".^$?*+|[({", (int)*ind))
			return 0;
	}
	return tmp - buf;
}

/*
 * return the stemid given a string and a length
 */
static inline int find_stem(struct saved_data *data, const char *buf,
						    int stem_len)
{
	int i;

	for (i = 0; i < data->num_stems; i++) {
		if (stem_len == data->stem_arr[i].len &&
		    !strncmp(buf, data->stem_arr[i].buf, stem_len))
			return i;
	}

	return -1;
}

/* returns the index of the new stored object */
static inline int store_stem(struct saved_data *data, char *buf, int stem_len)
{
	int num = data->num_stems;

	if (data->alloc_stems == num) {
		struct stem *tmp_arr;
		int alloc_stems = data->alloc_stems * 2 + 16;
		tmp_arr = realloc(data->stem_arr,
				  sizeof(*tmp_arr) * alloc_stems);
		if (!tmp_arr) {
			free(buf);
			return -1;
		}
		data->alloc_stems = alloc_stems;
		data->stem_arr = tmp_arr;
	}
	data->stem_arr[num].len = stem_len;
	data->stem_arr[num].buf = buf;
	data->stem_arr[num].from_mmap = 0;
	data->num_stems++;

	return num;
}

/* find the stem of a file spec, returns the index into stem_arr for a new
 * or existing stem, (or -1 if there is no possible stem - IE for a file in
 * the root directory or a regex that is too complex for us). */
static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
{
	int stem_len = get_stem_from_spec(buf);
	int stemid;
	char *stem;

	if (!stem_len)
		return -1;

	stemid = find_stem(data, buf, stem_len);
	if (stemid >= 0)
		return stemid;

	/* not found, allocate a new one */
	stem = strndup(buf, stem_len);
	if (!stem)
		return -1;

	return store_stem(data, stem, stem_len);
}

/* This will always check for buffer over-runs and either read the next entry
 * if buf != NULL or skip over the entry (as these areas are mapped in the
 * current buffer). */
static inline int next_entry(void *buf, struct mmap_area *fp, size_t bytes)
{
	if (bytes > fp->next_len)
		return -1;

	if (buf)
		memcpy(buf, fp->next_addr, bytes);

	fp->next_addr = (char *)fp->next_addr + bytes;
	fp->next_len -= bytes;
	return 0;
}

static inline int compile_regex(struct spec *spec, const char **errbuf)
{
	char *reg_buf, *anchored_regex, *cp;
	struct regex_error_data error_data;
	static char regex_error_format_buffer[256];
	size_t len;
	int rc;
	bool regex_compiled;

	/* We really want pthread_once() here, but since its
	 * init_routine does not take a parameter, it's not possible
	 * to use, so we generate the same effect with atomics and a
	 * mutex */
#ifdef __ATOMIC_RELAXED
	regex_compiled =
		__atomic_load_n(&spec->regex_compiled, __ATOMIC_ACQUIRE);
#else
	/* GCC <4.7 */
	__sync_synchronize();
	regex_compiled = spec->regex_compiled;
#endif
	if (regex_compiled) {
		return 0; /* already done */
	}

	__pthread_mutex_lock(&spec->regex_lock);
	/* Check if another thread compiled the regex while we waited
	 * on the mutex */
#ifdef __ATOMIC_RELAXED
	regex_compiled =
		__atomic_load_n(&spec->regex_compiled, __ATOMIC_ACQUIRE);
#else
	/* GCC <4.7 */
	__sync_synchronize();
	regex_compiled = spec->regex_compiled;
#endif
	if (regex_compiled) {
		__pthread_mutex_unlock(&spec->regex_lock);
		return 0;
	}

	reg_buf = spec->regex_str;
	/* Anchor the regular expression. */
	len = strlen(reg_buf);
	cp = anchored_regex = malloc(len + 3);
	if (!anchored_regex) {
		if (errbuf)
			*errbuf = "out of memory";
		__pthread_mutex_unlock(&spec->regex_lock);
		return -1;
	}

	/* Create ^...$ regexp.  */
	*cp++ = '^';
	memcpy(cp, reg_buf, len);
	cp += len;
	*cp++ = '$';
	*cp = '\0';

	/* Compile the regular expression. */
	rc = regex_prepare_data(&spec->regex, anchored_regex, &error_data);
	free(anchored_regex);
	if (rc < 0) {
		if (errbuf) {
			regex_format_error(&error_data,
					regex_error_format_buffer,
					sizeof(regex_error_format_buffer));
			*errbuf = &regex_error_format_buffer[0];
		}
		__pthread_mutex_unlock(&spec->regex_lock);
		return -1;
	}

	/* Done. */
#ifdef __ATOMIC_RELAXED
	__atomic_store_n(&spec->regex_compiled, true, __ATOMIC_RELEASE);
#else
	/* GCC <4.7 */
	spec->regex_compiled = true;
	__sync_synchronize();
#endif
	__pthread_mutex_unlock(&spec->regex_lock);
	return 0;
}

/* This service is used by label_file.c process_file() and
 * utils/sefcontext_compile.c */
static inline int process_line(struct selabel_handle *rec,
			const char *path, const char *prefix,
			char *line_buf, unsigned lineno)
{
	int items, len, rc;
	char *regex = NULL, *type = NULL, *context = NULL;
	struct saved_data *data = (struct saved_data *)rec->data;
	struct spec *spec_arr;
	unsigned int nspec = data->nspec;
	const char *errbuf = NULL;

	items = read_spec_entries(line_buf, &errbuf, 3, &regex, &type, &context);
	if (items < 0) {
		rc = errno;
		selinux_log(SELINUX_ERROR,
			"%s:  line %u error due to: %s\n", path,
			lineno, errbuf ?: strerror(errno));
		errno = rc;
		return -1;
	}

	if (items == 0)
		return items;

	if (items < 2) {
		COMPAT_LOG(SELINUX_ERROR,
			    "%s:  line %u is missing fields\n", path,
			    lineno);
		if (items == 1)
			free(regex);
		errno = EINVAL;
		return -1;
	} else if (items == 2) {
		/* The type field is optional. */
		context = type;
		type = 0;
	}

	len = get_stem_from_spec(regex);
	if (len && prefix && strncmp(prefix, regex, len)) {
		/* Stem of regex does not match requested prefix, discard. */
		free(regex);
		free(type);
		free(context);
		return 0;
	}

	rc = grow_specs(data);
	if (rc)
		return rc;

	spec_arr = data->spec_arr;

	/* process and store the specification in spec. */
	spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
	spec_arr[nspec].regex_str = regex;
	__pthread_mutex_init(&spec_arr[nspec].regex_lock, NULL);
	spec_arr[nspec].regex_compiled = false;

	spec_arr[nspec].type_str = type;
	spec_arr[nspec].mode = 0;

	spec_arr[nspec].lr.ctx_raw = context;
	spec_arr[nspec].lr.lineno = lineno;

	/*
	 * bump data->nspecs to cause closef() to cover it in its free
	 * but do not bump nspec since it's used below.
	 */
	data->nspec++;

	if (rec->validating
			&& compile_regex(&spec_arr[nspec], &errbuf)) {
		COMPAT_LOG(SELINUX_ERROR,
			   "%s:  line %u has invalid regex %s:  %s\n",
			   path, lineno, regex, errbuf);
		errno = EINVAL;
		return -1;
	}

	if (type) {
		mode_t mode = string_to_mode(type);

		if (mode == (mode_t)-1) {
			COMPAT_LOG(SELINUX_ERROR,
				   "%s:  line %u has invalid file type %s\n",
				   path, lineno, type);
			errno = EINVAL;
			return -1;
		}
		spec_arr[nspec].mode = mode;
	}

	/* Determine if specification has
	 * any meta characters in the RE */
	spec_hasMetaChars(&spec_arr[nspec]);

	if (strcmp(context, "<<none>>") && rec->validating)
		return compat_validate(rec, &spec_arr[nspec].lr, path, lineno);

	return 0;
}

#endif /* _SELABEL_FILE_H_ */
