File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / security.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /*
    2:  * Copyright (C) 2005 International Business Machines Corporation
    3:  * Copyright (c) 2005 by Trusted Computer Solutions, Inc.
    4:  * All rights reserved.
    5:  *
    6:  * Redistribution and use in source and binary forms, with or without
    7:  * modification, are permitted provided that the following conditions
    8:  * are met:
    9:  * 1. Redistributions of source code must retain the above copyright
   10:  *    notice, this list of conditions and the following disclaimer.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  * 3. Neither the name of the project nor the names of its contributors
   15:  *    may be used to endorse or promote products derived from this software
   16:  *    without specific prior written permission.
   17:  *
   18:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   22:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28:  * SUCH DAMAGE.
   29:  */
   30: 
   31: 
   32: #include "config.h"
   33: 
   34: #include <sys/types.h>
   35: 
   36: #include <stdlib.h>
   37: #include <stdio.h>
   38: #include <string.h>
   39: 
   40: #include <selinux/selinux.h>
   41: #include <selinux/flask.h>
   42: #include <selinux/av_permissions.h>
   43: #include <selinux/avc.h>
   44: #include <selinux/context.h>
   45: 
   46: #include "var.h"
   47: #include "vmbuf.h"
   48: #include "misc.h"
   49: #include "plog.h"
   50: 
   51: #include "isakmp_var.h"
   52: #include "isakmp.h"
   53: #include "ipsec_doi.h"
   54: #include "policy.h"
   55: #include "proposal.h"
   56: #include "strnames.h"
   57: #include "handler.h"
   58: 
   59: /* 
   60:  * Get the security context information from SA.
   61:  */
   62: int
   63: get_security_context(sa, p)
   64: 	vchar_t *sa;
   65: 	struct policyindex *p;
   66: {
   67: 	int len = 0;
   68: 	int flag, type = 0;
   69: 	u_int16_t lorv;
   70: 	caddr_t bp;
   71: 	vchar_t *pbuf = NULL;
   72: 	vchar_t *tbuf = NULL;
   73: 	struct isakmp_parse_t *pa;
   74: 	struct isakmp_parse_t *ta;
   75: 	struct isakmp_pl_p *prop;
   76: 	struct isakmp_pl_t *trns;
   77: 	struct isakmp_data *d;
   78: 	struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v;
   79: 	
   80: 	/* check SA payload size */
   81: 	if (sa->l < sizeof(*sab)) {
   82: 		plog(LLV_ERROR, LOCATION, NULL,
   83: 			"Invalid SA length = %zu.\n", sa->l);
   84: 		return -1;
   85: 	}
   86: 
   87: 	bp = (caddr_t)(sab + 1); /* here bp points to first proposal payload */
   88: 	len = sa->l - sizeof(*sab);
   89: 
   90: 	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, len);
   91: 	if (pbuf == NULL)
   92: 		return -1;
   93: 
   94: 	pa = (struct isakmp_parse_t *)pbuf->v; 
   95:         /* check the value of next payload */
   96: 	if (pa->type != ISAKMP_NPTYPE_P) {
   97: 		plog(LLV_ERROR, LOCATION, NULL,
   98: 			"Invalid payload type=%u\n", pa->type);
   99: 		vfree(pbuf);
  100: 		return -1;
  101: 	}
  102: 
  103: 	if (pa->len == 0) {
  104: 		plog(LLV_ERROR, LOCATION, NULL,
  105: 		"invalid proposal with length %d\n", pa->len);
  106: 		vfree(pbuf);
  107: 		return -1;
  108: 	}
  109: 
  110: 	/* our first proposal */
  111: 	prop = (struct isakmp_pl_p *)pa->ptr;
  112: 
  113: 	/* now get transform */
  114: 	bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size;
  115: 	len = ntohs(prop->h.len) - 
  116: 		(sizeof(struct isakmp_pl_p) + prop->spi_size);
  117: 	tbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, len);
  118: 	if (tbuf == NULL)
  119: 		return -1;
  120: 
  121: 	ta = (struct isakmp_parse_t *)tbuf->v;
  122: 	if (ta->type != ISAKMP_NPTYPE_T) {
  123: 		plog(LLV_ERROR, LOCATION, NULL,
  124: 		     "Invalid payload type=%u\n", ta->type);
  125: 		return -1;
  126: 	}
  127: 	
  128: 	trns = (struct isakmp_pl_t *)ta->ptr;
  129: 
  130: 	len = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
  131: 	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
  132: 
  133: 	while (len > 0) {
  134: 		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
  135: 		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
  136: 		lorv = ntohs(d->lorv);
  137: 
  138: 		if (type != IPSECDOI_ATTR_SECCTX) {
  139: 			if (flag) {
  140: 				len -= sizeof(*d);
  141: 				d = (struct isakmp_data *)((char *)d 
  142: 				     + sizeof(*d));
  143: 			} else {
  144: 				len -= (sizeof(*d) + lorv);
  145: 				d = (struct isakmp_data *)((caddr_t)d
  146: 				     + sizeof(*d) + lorv);
  147: 			}
  148: 		} else {
  149: 			flag = ntohs(d->type & ISAKMP_GEN_MASK);
  150: 			if (flag) {
  151: 				plog(LLV_ERROR, LOCATION, NULL,
  152: 				     "SECCTX must be in TLV.\n");
  153: 				return -1;
  154: 			}
  155: 			memcpy(&p->sec_ctx, d + 1, lorv);
  156: 			p->sec_ctx.ctx_strlen = ntohs(p->sec_ctx.ctx_strlen);
  157: 			return 0;
  158: 		}
  159: 	}
  160: 	return 0;
  161: }
  162: 
  163: void
  164: set_secctx_in_proposal(iph2, spidx)
  165: 	struct ph2handle *iph2;
  166: 	struct policyindex spidx;
  167: {
  168: 	iph2->proposal->sctx.ctx_doi = spidx.sec_ctx.ctx_doi;
  169: 	iph2->proposal->sctx.ctx_alg = spidx.sec_ctx.ctx_alg;
  170: 	iph2->proposal->sctx.ctx_strlen = spidx.sec_ctx.ctx_strlen;
  171: 		memcpy(iph2->proposal->sctx.ctx_str, spidx.sec_ctx.ctx_str,
  172: 			spidx.sec_ctx.ctx_strlen);
  173: }
  174: 
  175: 
  176: /*
  177:  * function: 	init_avc
  178:  * description:	function performs the steps necessary to initialize the
  179:  *		userspace avc.
  180:  * input:	void
  181:  * return:	0	if avc was successfully initialized
  182:  * 		1	if the avc could not be initialized
  183:  */
  184: 
  185: static int mls_ready = 0;
  186: 
  187: void
  188: init_avc(void)
  189: {
  190: 	if (!is_selinux_mls_enabled()) {
  191: 		plog(LLV_ERROR, LOCATION, NULL, "racoon: MLS support is not"
  192: 				" enabled.\n");
  193: 		return;
  194: 	}
  195: 
  196: 	if (avc_init("racoon", NULL, NULL, NULL, NULL) == 0)
  197: 		mls_ready = 1;
  198: 	else
  199: 		plog(LLV_ERROR, LOCATION, NULL, 
  200: 		     "racoon: could not initialize avc.\n");
  201: }
  202: 
  203: /*
  204:  * function: 	within_range
  205:  * description:	function determines if the specified sl is within the
  206:  * 		configured range for a policy rule.
  207:  * input:	security_context *sl		SL
  208:  * 		char *range		Range
  209:  * return:	1	if the sl is within the range
  210:  * 		0	if the sl is not within the range or an error
  211:  * 			occurred which prevented the determination
  212:  */
  213: 
  214: int
  215: within_range(security_context_t sl, security_context_t range)
  216: {
  217: 	int rtn = 1;
  218: 	security_id_t slsid;
  219: 	security_id_t rangesid;
  220: 	struct av_decision avd;
  221: 	security_class_t tclass;
  222: 	access_vector_t av;
  223: 
  224: 	if (!*range)	/* This policy doesn't have security context */
  225: 		return 1;
  226: 
  227: 	if (!mls_ready)  /* mls may not be enabled */
  228: 		return 0;
  229: 
  230: 	/*
  231: 	 * Get the sids for the sl and range contexts
  232: 	 */
  233: 	rtn = avc_context_to_sid(sl, &slsid);
  234: 	if (rtn != 0) {
  235: 		plog(LLV_ERROR, LOCATION, NULL, 
  236: 				"within_range: Unable to retrieve "
  237: 				"sid for sl context (%s).\n", sl);
  238: 		return 0;
  239: 	}
  240: 	rtn = avc_context_to_sid(range, &rangesid);
  241: 	if (rtn != 0) {
  242: 		plog(LLV_ERROR, LOCATION, NULL, 
  243: 				"within_range: Unable to retrieve "
  244: 				"sid for range context (%s).\n", range);
  245: 		sidput(slsid);
  246: 		return 0;
  247: 	}
  248: 
  249: 	/* 
  250: 	 * Straight up test between sl and range
  251: 	 */
  252: 	tclass = SECCLASS_ASSOCIATION;
  253: 	av = ASSOCIATION__POLMATCH;
  254: 	rtn = avc_has_perm(slsid, rangesid, tclass, av, NULL, &avd);
  255: 	if (rtn != 0) {
  256: 		plog(LLV_INFO, LOCATION, NULL, 
  257: 			"within_range: The sl is not within range\n");
  258: 		sidput(slsid);
  259: 		sidput(rangesid);
  260: 		return 0;
  261: 	}
  262: 	plog(LLV_DEBUG, LOCATION, NULL, 
  263: 		"within_range: The sl (%s) is within range (%s)\n", sl, range);
  264: 		return 1;
  265: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>