/*
 * Copyright (C) 2005 International Business Machines Corporation
 * Copyright (c) 2005 by Trusted Computer Solutions, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */


#include "config.h"

#include <sys/types.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <selinux/selinux.h>
#include <selinux/flask.h>
#include <selinux/av_permissions.h>
#include <selinux/avc.h>
#include <selinux/context.h>

#include "var.h"
#include "vmbuf.h"
#include "misc.h"
#include "plog.h"

#include "isakmp_var.h"
#include "isakmp.h"
#include "ipsec_doi.h"
#include "policy.h"
#include "proposal.h"
#include "strnames.h"
#include "handler.h"

/* 
 * Get the security context information from SA.
 */
int
get_security_context(sa, p)
	vchar_t *sa;
	struct policyindex *p;
{
	int len = 0;
	int flag, type = 0;
	u_int16_t lorv;
	caddr_t bp;
	vchar_t *pbuf = NULL;
	vchar_t *tbuf = NULL;
	struct isakmp_parse_t *pa;
	struct isakmp_parse_t *ta;
	struct isakmp_pl_p *prop;
	struct isakmp_pl_t *trns;
	struct isakmp_data *d;
	struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v;
	
	/* check SA payload size */
	if (sa->l < sizeof(*sab)) {
		plog(LLV_ERROR, LOCATION, NULL,
			"Invalid SA length = %zu.\n", sa->l);
		return -1;
	}

	bp = (caddr_t)(sab + 1); /* here bp points to first proposal payload */
	len = sa->l - sizeof(*sab);

	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, len);
	if (pbuf == NULL)
		return -1;

	pa = (struct isakmp_parse_t *)pbuf->v; 
        /* check the value of next payload */
	if (pa->type != ISAKMP_NPTYPE_P) {
		plog(LLV_ERROR, LOCATION, NULL,
			"Invalid payload type=%u\n", pa->type);
		vfree(pbuf);
		return -1;
	}

	if (pa->len == 0) {
		plog(LLV_ERROR, LOCATION, NULL,
		"invalid proposal with length %d\n", pa->len);
		vfree(pbuf);
		return -1;
	}

	/* our first proposal */
	prop = (struct isakmp_pl_p *)pa->ptr;

	/* now get transform */
	bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size;
	len = ntohs(prop->h.len) - 
		(sizeof(struct isakmp_pl_p) + prop->spi_size);
	tbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, len);
	if (tbuf == NULL)
		return -1;

	ta = (struct isakmp_parse_t *)tbuf->v;
	if (ta->type != ISAKMP_NPTYPE_T) {
		plog(LLV_ERROR, LOCATION, NULL,
		     "Invalid payload type=%u\n", ta->type);
		return -1;
	}
	
	trns = (struct isakmp_pl_t *)ta->ptr;

	len = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));

	while (len > 0) {
		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
		lorv = ntohs(d->lorv);

		if (type != IPSECDOI_ATTR_SECCTX) {
			if (flag) {
				len -= sizeof(*d);
				d = (struct isakmp_data *)((char *)d 
				     + sizeof(*d));
			} else {
				len -= (sizeof(*d) + lorv);
				d = (struct isakmp_data *)((caddr_t)d
				     + sizeof(*d) + lorv);
			}
		} else {
			flag = ntohs(d->type & ISAKMP_GEN_MASK);
			if (flag) {
				plog(LLV_ERROR, LOCATION, NULL,
				     "SECCTX must be in TLV.\n");
				return -1;
			}
			memcpy(&p->sec_ctx, d + 1, lorv);
			p->sec_ctx.ctx_strlen = ntohs(p->sec_ctx.ctx_strlen);
			return 0;
		}
	}
	return 0;
}

void
set_secctx_in_proposal(iph2, spidx)
	struct ph2handle *iph2;
	struct policyindex spidx;
{
	iph2->proposal->sctx.ctx_doi = spidx.sec_ctx.ctx_doi;
	iph2->proposal->sctx.ctx_alg = spidx.sec_ctx.ctx_alg;
	iph2->proposal->sctx.ctx_strlen = spidx.sec_ctx.ctx_strlen;
		memcpy(iph2->proposal->sctx.ctx_str, spidx.sec_ctx.ctx_str,
			spidx.sec_ctx.ctx_strlen);
}


/*
 * function: 	init_avc
 * description:	function performs the steps necessary to initialize the
 *		userspace avc.
 * input:	void
 * return:	0	if avc was successfully initialized
 * 		1	if the avc could not be initialized
 */

static int mls_ready = 0;

void
init_avc(void)
{
	if (!is_selinux_mls_enabled()) {
		plog(LLV_ERROR, LOCATION, NULL, "racoon: MLS support is not"
				" enabled.\n");
		return;
	}

	if (avc_init("racoon", NULL, NULL, NULL, NULL) == 0)
		mls_ready = 1;
	else
		plog(LLV_ERROR, LOCATION, NULL, 
		     "racoon: could not initialize avc.\n");
}

/*
 * function: 	within_range
 * description:	function determines if the specified sl is within the
 * 		configured range for a policy rule.
 * input:	security_context *sl		SL
 * 		char *range		Range
 * return:	1	if the sl is within the range
 * 		0	if the sl is not within the range or an error
 * 			occurred which prevented the determination
 */

int
within_range(security_context_t sl, security_context_t range)
{
	int rtn = 1;
	security_id_t slsid;
	security_id_t rangesid;
	struct av_decision avd;
	security_class_t tclass;
	access_vector_t av;

	if (!*range)	/* This policy doesn't have security context */
		return 1;

	if (!mls_ready)  /* mls may not be enabled */
		return 0;

	/*
	 * Get the sids for the sl and range contexts
	 */
	rtn = avc_context_to_sid(sl, &slsid);
	if (rtn != 0) {
		plog(LLV_ERROR, LOCATION, NULL, 
				"within_range: Unable to retrieve "
				"sid for sl context (%s).\n", sl);
		return 0;
	}
	rtn = avc_context_to_sid(range, &rangesid);
	if (rtn != 0) {
		plog(LLV_ERROR, LOCATION, NULL, 
				"within_range: Unable to retrieve "
				"sid for range context (%s).\n", range);
		sidput(slsid);
		return 0;
	}

	/* 
	 * Straight up test between sl and range
	 */
	tclass = SECCLASS_ASSOCIATION;
	av = ASSOCIATION__POLMATCH;
	rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd);
	if (rtn != 0) {
		plog(LLV_INFO, LOCATION, NULL, 
			"within_range: The sl is not within range\n");
		sidput(slsid);
		sidput(rangesid);
		return 0;
	}
	plog(LLV_DEBUG, LOCATION, NULL, 
		"within_range: The sl (%s) is within range (%s)\n", sl, range);
		return 1;
}
