source: rtems-libbsd/ipsec-tools/src/racoon/security.c @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

  • Property mode set to 100644
File size: 7.0 KB
Line 
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 */
62int
63get_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
163void
164set_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
185static int mls_ready = 0;
186
187void
188init_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
214int
215within_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}
Note: See TracBrowser for help on using the repository browser.