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>