Return to security.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
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: }