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