2 * Copyright (C) 2005 International Business Machines Corporation
3 * Copyright (c) 2005 by Trusted Computer Solutions, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
34 #include <sys/types.h>
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>
51 #include "isakmp_var.h"
53 #include "ipsec_doi.h"
60 * Get the security context information from SA.
63 get_security_context(sa
, p
)
65 struct policyindex
*p
;
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
;
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
);
87 bp
= (caddr_t
)(sab
+ 1); /* here bp points to first proposal payload */
88 len
= sa
->l
- sizeof(*sab
);
90 pbuf
= isakmp_parsewoh(ISAKMP_NPTYPE_P
, (struct isakmp_gen
*)bp
, len
);
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
);
104 plog(LLV_ERROR
, LOCATION
, NULL
,
105 "invalid proposal with length %d\n", pa
->len
);
110 /* our first proposal */
111 prop
= (struct isakmp_pl_p
*)pa
->ptr
;
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
);
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
);
128 trns
= (struct isakmp_pl_t
*)ta
->ptr
;
130 len
= ntohs(trns
->h
.len
) - sizeof(struct isakmp_pl_t
);
131 d
= (struct isakmp_data
*)((caddr_t
)trns
+ sizeof(struct isakmp_pl_t
));
134 type
= ntohs(d
->type
) & ~ISAKMP_GEN_MASK
;
135 flag
= ntohs(d
->type
) & ISAKMP_GEN_MASK
;
136 lorv
= ntohs(d
->lorv
);
138 if (type
!= IPSECDOI_ATTR_SECCTX
) {
141 d
= (struct isakmp_data
*)((char *)d
144 len
-= (sizeof(*d
) + lorv
);
145 d
= (struct isakmp_data
*)((caddr_t
)d
146 + sizeof(*d
) + lorv
);
149 flag
= ntohs(d
->type
& ISAKMP_GEN_MASK
);
151 plog(LLV_ERROR
, LOCATION
, NULL
,
152 "SECCTX must be in TLV.\n");
155 memcpy(&p
->sec_ctx
, d
+ 1, lorv
);
156 p
->sec_ctx
.ctx_strlen
= ntohs(p
->sec_ctx
.ctx_strlen
);
164 set_secctx_in_proposal(iph2
, spidx
)
165 struct ph2handle
*iph2
;
166 struct policyindex spidx
;
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
);
178 * description: function performs the steps necessary to initialize the
181 * return: 0 if avc was successfully initialized
182 * 1 if the avc could not be initialized
185 static int mls_ready
= 0;
190 if (!is_selinux_mls_enabled()) {
191 plog(LLV_ERROR
, LOCATION
, NULL
, "racoon: MLS support is not"
196 if (avc_init("racoon", NULL
, NULL
, NULL
, NULL
) == 0)
199 plog(LLV_ERROR
, LOCATION
, NULL
,
200 "racoon: could not initialize avc.\n");
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
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
215 within_range(security_context_t sl
, security_context_t range
)
219 security_id_t rangesid
;
220 struct av_decision avd
;
221 security_class_t tclass
;
224 if (!*range
) /* This policy doesn't have security context */
227 if (!mls_ready
) /* mls may not be enabled */
231 * Get the sids for the sl and range contexts
233 rtn
= avc_context_to_sid(sl
, &slsid
);
235 plog(LLV_ERROR
, LOCATION
, NULL
,
236 "within_range: Unable to retrieve "
237 "sid for sl context (%s).\n", sl
);
240 rtn
= avc_context_to_sid(range
, &rangesid
);
242 plog(LLV_ERROR
, LOCATION
, NULL
,
243 "within_range: Unable to retrieve "
244 "sid for range context (%s).\n", range
);
250 * Straight up test between sl and range
252 tclass
= SECCLASS_ASSOCIATION
;
253 av
= ASSOCIATION__POLMATCH
;
254 rtn
= avc_has_perm(slsid
, rangesid
, tclass
, av
, NULL
, &avd
);
256 plog(LLV_INFO
, LOCATION
, NULL
,
257 "within_range: The sl is not within range\n");
262 plog(LLV_DEBUG
, LOCATION
, NULL
,
263 "within_range: The sl (%s) is within range (%s)\n", sl
, range
);