Annotation of embedaddon/ipsec-tools/src/racoon/security.c, revision 1.1
1.1 ! misho 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>