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>