1 /* $OpenBSD: pfkeyv2_parsemessage.c,v 1.60 2021/07/14 22:39:26 tobhe Exp $ */
2
3 /*
4 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
5 *
6 * NRL grants permission for redistribution and use in source and binary
7 * forms, with or without modification, of the software and documentation
8 * created at NRL provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgements:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * This product includes software developed at the Information
20 * Technology Division, US Naval Research Laboratory.
21 * 4. Neither the name of the NRL nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
26 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * The views and conclusions contained in the software and documentation
38 * are those of the authors and should not be interpreted as representing
39 * official policies, either expressed or implied, of the US Naval
40 * Research Laboratory (NRL).
41 */
42
43 /*
44 * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. Neither the name of the author nor the names of any contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 */
70
71 #include "pf.h"
72
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/socket.h>
76 #include <sys/mbuf.h>
77 #include <sys/proc.h>
78 #include <netinet/ip_ipsp.h>
79 #include <net/pfkeyv2.h>
80
81 #if NPF > 0
82 #include <net/if.h>
83 #include <net/pfvar.h>
84 #endif
85
86 #ifdef ENCDEBUG
87 #define DPRINTF(fmt, args...) \
88 do { \
89 if (encdebug) \
90 printf("%s: " fmt "\n", __func__, ## args); \
91 } while (0)
92 #else
93 #define DPRINTF(fmt, args...) \
94 do { } while (0)
95 #endif
96
97 #define BITMAP_SA (1LL << SADB_EXT_SA)
98 #define BITMAP_LIFETIME_CURRENT (1LL << SADB_EXT_LIFETIME_CURRENT)
99 #define BITMAP_LIFETIME_HARD (1LL << SADB_EXT_LIFETIME_HARD)
100 #define BITMAP_LIFETIME_SOFT (1LL << SADB_EXT_LIFETIME_SOFT)
101 #define BITMAP_ADDRESS_SRC (1LL << SADB_EXT_ADDRESS_SRC)
102 #define BITMAP_ADDRESS_DST (1LL << SADB_EXT_ADDRESS_DST)
103 #define BITMAP_ADDRESS_PROXY (1LL << SADB_EXT_ADDRESS_PROXY)
104 #define BITMAP_KEY_AUTH (1LL << SADB_EXT_KEY_AUTH)
105 #define BITMAP_KEY_ENCRYPT (1LL << SADB_EXT_KEY_ENCRYPT)
106 #define BITMAP_IDENTITY_SRC (1LL << SADB_EXT_IDENTITY_SRC)
107 #define BITMAP_IDENTITY_DST (1LL << SADB_EXT_IDENTITY_DST)
108 #define BITMAP_SENSITIVITY (1LL << SADB_EXT_SENSITIVITY)
109 #define BITMAP_PROPOSAL (1LL << SADB_EXT_PROPOSAL)
110 #define BITMAP_SUPPORTED_AUTH (1LL << SADB_EXT_SUPPORTED_AUTH)
111 #define BITMAP_SUPPORTED_ENCRYPT (1LL << SADB_EXT_SUPPORTED_ENCRYPT)
112 #define BITMAP_SPIRANGE (1LL << SADB_EXT_SPIRANGE)
113 #define BITMAP_LIFETIME (BITMAP_LIFETIME_CURRENT | BITMAP_LIFETIME_HARD | BITMAP_LIFETIME_SOFT)
114 #define BITMAP_ADDRESS (BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST)
115 #define BITMAP_KEY (BITMAP_KEY_AUTH | BITMAP_KEY_ENCRYPT)
116 #define BITMAP_IDENTITY (BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST)
117 #define BITMAP_MSG 1
118 #define BITMAP_X_SRC_MASK (1LL << SADB_X_EXT_SRC_MASK)
119 #define BITMAP_X_DST_MASK (1LL << SADB_X_EXT_DST_MASK)
120 #define BITMAP_X_PROTOCOL (1LL << SADB_X_EXT_PROTOCOL)
121 #define BITMAP_X_SRC_FLOW (1LL << SADB_X_EXT_SRC_FLOW)
122 #define BITMAP_X_DST_FLOW (1LL << SADB_X_EXT_DST_FLOW)
123 #define BITMAP_X_FLOW_TYPE (1LL << SADB_X_EXT_FLOW_TYPE)
124 #define BITMAP_X_SA2 (1LL << SADB_X_EXT_SA2)
125 #define BITMAP_X_DST2 (1LL << SADB_X_EXT_DST2)
126 #define BITMAP_X_POLICY (1LL << SADB_X_EXT_POLICY)
127 #define BITMAP_X_FLOW (BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE)
128 #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP)
129 #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP)
130 #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE)
131 #define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG)
132 #define BITMAP_X_TAP (1LL << SADB_X_EXT_TAP)
133 #define BITMAP_X_SATYPE2 (1LL << SADB_X_EXT_SATYPE2)
134 #define BITMAP_X_RDOMAIN (1LL << SADB_X_EXT_RDOMAIN)
135 #define BITMAP_X_COUNTER (1LL << SADB_X_EXT_COUNTER)
136 #define BITMAP_X_MTU (1LL << SADB_X_EXT_MTU)
137 #define BITMAP_X_REPLAY (1LL << SADB_X_EXT_REPLAY)
138
139 uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
140 {
141 /* RESERVED */
142 ~0,
143 /* GETSPI */
144 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
145 /* UPDATE */
146 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
147 /* ADD */
148 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
149 /* DELETE */
150 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN,
151 /* GET */
152 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN,
153 /* ACQUIRE */
154 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL,
155 /* REGISTER */
156 0,
157 /* EXPIRE */
158 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
159 /* FLUSH */
160 0,
161 /* DUMP */
162 0,
163 /* X_PROMISC */
164 0,
165 /* X_ADDFLOW */
166 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_FLOW | BITMAP_X_RDOMAIN,
167 /* X_DELFLOW */
168 BITMAP_X_FLOW | BITMAP_X_RDOMAIN,
169 /* X_GRPSPIS */
170 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2 | BITMAP_X_RDOMAIN,
171 /* X_ASKPOLICY */
172 BITMAP_X_POLICY,
173 };
174
175 uint64_t sadb_exts_required_in[SADB_MAX+1] =
176 {
177 /* RESERVED */
178 0,
179 /* GETSPI */
180 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
181 /* UPDATE */
182 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
183 /* ADD */
184 BITMAP_SA | BITMAP_ADDRESS_DST,
185 /* DELETE */
186 BITMAP_SA | BITMAP_ADDRESS_DST,
187 /* GET */
188 BITMAP_SA | BITMAP_ADDRESS_DST,
189 /* ACQUIRE */
190 0,
191 /* REGISTER */
192 0,
193 /* EXPIRE */
194 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
195 /* FLUSH */
196 0,
197 /* DUMP */
198 0,
199 /* X_PROMISC */
200 0,
201 /* X_ADDFLOW */
202 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
203 /* X_DELFLOW */
204 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
205 /* X_GRPSPIS */
206 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2,
207 /* X_ASKPOLICY */
208 BITMAP_X_POLICY,
209 };
210
211 const uint64_t sadb_exts_allowed_out[SADB_MAX+1] =
212 {
213 /* RESERVED */
214 ~0,
215 /* GETSPI */
216 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
217 /* UPDATE */
218 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
219 /* ADD */
220 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN,
221 /* DELETE */
222 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN,
223 /* GET */
224 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_COUNTER | BITMAP_X_RDOMAIN | BITMAP_X_MTU | BITMAP_X_REPLAY,
225 /* ACQUIRE */
226 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL,
227 /* REGISTER */
228 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
229 /* EXPIRE */
230 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS,
231 /* FLUSH */
232 0,
233 /* DUMP */
234 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY,
235 /* X_PROMISC */
236 0,
237 /* X_ADDFLOW */
238 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_RDOMAIN,
239 /* X_DELFLOW */
240 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE | BITMAP_X_RDOMAIN,
241 /* X_GRPSPIS */
242 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2 | BITMAP_X_RDOMAIN,
243 /* X_ASKPOLICY */
244 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY,
245 };
246
247 const uint64_t sadb_exts_required_out[SADB_MAX+1] =
248 {
249 /* RESERVED */
250 0,
251 /* GETSPI */
252 BITMAP_SA | BITMAP_ADDRESS_DST,
253 /* UPDATE */
254 BITMAP_SA | BITMAP_ADDRESS_DST,
255 /* ADD */
256 BITMAP_SA | BITMAP_ADDRESS_DST,
257 /* DELETE */
258 BITMAP_SA | BITMAP_ADDRESS_DST,
259 /* GET */
260 BITMAP_SA | BITMAP_LIFETIME_CURRENT | BITMAP_ADDRESS_DST,
261 /* ACQUIRE */
262 0,
263 /* REGISTER */
264 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
265 /* EXPIRE */
266 BITMAP_SA | BITMAP_ADDRESS_DST,
267 /* FLUSH */
268 0,
269 /* DUMP */
270 0,
271 /* X_PROMISC */
272 0,
273 /* X_ADDFLOW */
274 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
275 /* X_DELFLOW */
276 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
277 /* X_GRPSPIS */
278 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2,
279 /* X_REPPOLICY */
280 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE,
281 };
282
283 int
284 pfkeyv2_parsemessage(void *p, int len, void **headers)
285 {
286 struct sadb_ext *sadb_ext;
287 int i, left = len;
288 uint64_t allow, seen = 1;
289 struct sadb_msg *sadb_msg = (struct sadb_msg *) p;
290
291 bzero(headers, (SADB_EXT_MAX + 1) * sizeof(void *));
292
293 if (left < sizeof(struct sadb_msg)) {
294 DPRINTF("message too short");
295 return (EINVAL);
296 }
297
298 headers[0] = p;
299
300 if (sadb_msg->sadb_msg_len * sizeof(uint64_t) != left) {
301 DPRINTF("length not a multiple of 64");
302 return (EINVAL);
303 }
304
305 p += sizeof(struct sadb_msg);
306 left -= sizeof(struct sadb_msg);
307
308 if (sadb_msg->sadb_msg_reserved) {
309 DPRINTF("message header reserved field set");
310 return (EINVAL);
311 }
312
313 if (sadb_msg->sadb_msg_type > SADB_MAX) {
314 DPRINTF("message type > %d", SADB_MAX);
315 return (EINVAL);
316 }
317
318 if (!sadb_msg->sadb_msg_type) {
319 DPRINTF("message type unset");
320 return (EINVAL);
321 }
322
323 if (sadb_msg->sadb_msg_pid != curproc->p_p->ps_pid) {
324 DPRINTF("bad PID value");
325 return (EINVAL);
326 }
327
328 if (sadb_msg->sadb_msg_errno) {
329 if (left) {
330 DPRINTF("too-large error message");
331 return (EINVAL);
332 }
333 return (0);
334 }
335
336 if (sadb_msg->sadb_msg_type == SADB_X_PROMISC) {
337 DPRINTF("message type promiscuous");
338 return (0);
339 }
340
341 allow = sadb_exts_allowed_in[sadb_msg->sadb_msg_type];
342
343 while (left > 0) {
344 sadb_ext = (struct sadb_ext *)p;
345 if (left < sizeof(struct sadb_ext)) {
346 DPRINTF("extension header too short");
347 return (EINVAL);
348 }
349
350 i = sadb_ext->sadb_ext_len * sizeof(uint64_t);
351 if (left < i) {
352 DPRINTF("extension header exceeds message length");
353 return (EINVAL);
354 }
355
356 if (sadb_ext->sadb_ext_type > SADB_EXT_MAX) {
357 DPRINTF("unknown extension header %d",
358 sadb_ext->sadb_ext_type);
359 return (EINVAL);
360 }
361
362 if (!sadb_ext->sadb_ext_type) {
363 DPRINTF("unset extension header");
364 return (EINVAL);
365 }
366
367 if (!(allow & (1LL << sadb_ext->sadb_ext_type))) {
368 DPRINTF("extension header %d not permitted on message "
369 "type %d",
370 sadb_ext->sadb_ext_type, sadb_msg->sadb_msg_type);
371 return (EINVAL);
372 }
373
374 if (headers[sadb_ext->sadb_ext_type]) {
375 DPRINTF("duplicate extension header %d",
376 sadb_ext->sadb_ext_type);
377 return (EINVAL);
378 }
379
380 seen |= (1LL << sadb_ext->sadb_ext_type);
381
382 switch (sadb_ext->sadb_ext_type) {
383 case SADB_EXT_SA:
384 case SADB_X_EXT_SA2:
385 {
386 struct sadb_sa *sadb_sa = (struct sadb_sa *)p;
387
388 if (i != sizeof(struct sadb_sa)) {
389 DPRINTF("bad header length for SA extension "
390 "header %d",
391 sadb_ext->sadb_ext_type);
392 return (EINVAL);
393 }
394
395 if (sadb_sa->sadb_sa_state > SADB_SASTATE_MAX) {
396 DPRINTF("unknown SA state %d in SA extension "
397 "header %d",
398 sadb_sa->sadb_sa_state,
399 sadb_ext->sadb_ext_type);
400 return (EINVAL);
401 }
402
403 if (sadb_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
404 DPRINTF("cannot set SA state to dead, "
405 "SA extension header %d",
406 sadb_ext->sadb_ext_type);
407 return (EINVAL);
408 }
409
410 if (sadb_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
411 DPRINTF("unknown encryption algorithm %d "
412 "in SA extension header %d",
413 sadb_sa->sadb_sa_encrypt,
414 sadb_ext->sadb_ext_type);
415 return (EINVAL);
416 }
417
418 if (sadb_sa->sadb_sa_auth > SADB_AALG_MAX) {
419 DPRINTF("unknown authentication algorithm %d "
420 "in SA extension header %d",
421 sadb_sa->sadb_sa_auth,
422 sadb_ext->sadb_ext_type);
423 return (EINVAL);
424 }
425
426 if (sadb_sa->sadb_sa_replay > 64) {
427 DPRINTF("unsupported replay window size %d "
428 "in SA extension header %d",
429 sadb_sa->sadb_sa_replay,
430 sadb_ext->sadb_ext_type);
431 return (EINVAL);
432 }
433 }
434 break;
435 case SADB_X_EXT_PROTOCOL:
436 case SADB_X_EXT_FLOW_TYPE:
437 case SADB_X_EXT_SATYPE2:
438 if (i != sizeof(struct sadb_protocol)) {
439 DPRINTF("bad PROTOCOL/FLOW/SATYPE2 header "
440 "length in extension header %d",
441 sadb_ext->sadb_ext_type);
442 return (EINVAL);
443 }
444 break;
445 case SADB_X_EXT_POLICY:
446 if (i != sizeof(struct sadb_x_policy)) {
447 DPRINTF("bad POLICY header length");
448 return (EINVAL);
449 }
450 break;
451 case SADB_EXT_LIFETIME_CURRENT:
452 case SADB_EXT_LIFETIME_HARD:
453 case SADB_EXT_LIFETIME_SOFT:
454 case SADB_X_EXT_LIFETIME_LASTUSE:
455 if (i != sizeof(struct sadb_lifetime)) {
456 DPRINTF("bad header length for LIFETIME "
457 "extension header %d",
458 sadb_ext->sadb_ext_type);
459 return (EINVAL);
460 }
461 break;
462 case SADB_EXT_ADDRESS_SRC:
463 case SADB_EXT_ADDRESS_DST:
464 case SADB_EXT_ADDRESS_PROXY:
465 case SADB_X_EXT_SRC_MASK:
466 case SADB_X_EXT_DST_MASK:
467 case SADB_X_EXT_SRC_FLOW:
468 case SADB_X_EXT_DST_FLOW:
469 case SADB_X_EXT_DST2:
470 {
471 struct sadb_address *sadb_address =
472 (struct sadb_address *)p;
473 struct sockaddr *sa = (struct sockaddr *)(p +
474 sizeof(struct sadb_address));
475
476 if (i < sizeof(struct sadb_address) +
477 sizeof(struct sockaddr)) {
478 DPRINTF("bad ADDRESS extension header %d "
479 "length",
480 sadb_ext->sadb_ext_type);
481 return (EINVAL);
482 }
483
484 if (sadb_address->sadb_address_reserved) {
485 DPRINTF("ADDRESS extension header %d reserved "
486 "field set",
487 sadb_ext->sadb_ext_type);
488 return (EINVAL);
489 }
490 if (sa->sa_len &&
491 (i != sizeof(struct sadb_address) +
492 PADUP(sa->sa_len))) {
493 DPRINTF("bad sockaddr length field in ADDRESS "
494 "extension header %d",
495 sadb_ext->sadb_ext_type);
496 return (EINVAL);
497 }
498
499 switch (sa->sa_family) {
500 case AF_INET:
501 if (sizeof(struct sadb_address) +
502 PADUP(sizeof(struct sockaddr_in)) != i) {
503 DPRINTF("invalid ADDRESS extension "
504 "header %d length",
505 sadb_ext->sadb_ext_type);
506 return (EINVAL);
507 }
508
509 if (sa->sa_len != sizeof(struct sockaddr_in)) {
510 DPRINTF("bad sockaddr_in length in "
511 "ADDRESS extension header %d",
512 sadb_ext->sadb_ext_type);
513 return (EINVAL);
514 }
515
516 /* Only check the right pieces */
517 switch (sadb_ext->sadb_ext_type)
518 {
519 case SADB_X_EXT_SRC_MASK:
520 case SADB_X_EXT_DST_MASK:
521 case SADB_X_EXT_SRC_FLOW:
522 case SADB_X_EXT_DST_FLOW:
523 break;
524
525 default:
526 if (((struct sockaddr_in *)sa)->sin_port) {
527 DPRINTF("port field set in "
528 "sockaddr_in of ADDRESS "
529 "extension header %d",
530 sadb_ext->sadb_ext_type);
531 return (EINVAL);
532 }
533 break;
534 }
535
536 {
537 char zero[sizeof(((struct sockaddr_in *)sa)->sin_zero)];
538 bzero(zero, sizeof(zero));
539
540 if (bcmp(&((struct sockaddr_in *)sa)->sin_zero, zero, sizeof(zero))) {
541 DPRINTF("reserved sockaddr_in "
542 "field non-zero'ed in "
543 "ADDRESS extension header "
544 "%d",
545 sadb_ext->sadb_ext_type);
546 return (EINVAL);
547 }
548 }
549 break;
550 #ifdef INET6
551 case AF_INET6:
552 if (i != sizeof(struct sadb_address) +
553 PADUP(sizeof(struct sockaddr_in6))) {
554 DPRINTF("invalid sockaddr_in6 length "
555 "in ADDRESS extension header %d",
556 sadb_ext->sadb_ext_type);
557 return (EINVAL);
558 }
559
560 if (sa->sa_len !=
561 sizeof(struct sockaddr_in6)) {
562 DPRINTF("bad sockaddr_in6 length in "
563 "ADDRESS extension header %d",
564 sadb_ext->sadb_ext_type);
565 return (EINVAL);
566 }
567
568 if (((struct sockaddr_in6 *)sa)->sin6_flowinfo) {
569 DPRINTF("flowinfo field set in "
570 "sockaddr_in6 of ADDRESS "
571 "extension header %d",
572 sadb_ext->sadb_ext_type);
573 return (EINVAL);
574 }
575
576 /* Only check the right pieces */
577 switch (sadb_ext->sadb_ext_type)
578 {
579 case SADB_X_EXT_SRC_MASK:
580 case SADB_X_EXT_DST_MASK:
581 case SADB_X_EXT_SRC_FLOW:
582 case SADB_X_EXT_DST_FLOW:
583 break;
584
585 default:
586 if (((struct sockaddr_in6 *)sa)->sin6_port) {
587 DPRINTF("port field set in "
588 "sockaddr_in6 of ADDRESS "
589 "extension header %d",
590 sadb_ext->sadb_ext_type);
591 return (EINVAL);
592 }
593 break;
594 }
595 break;
596 #endif /* INET6 */
597 default:
598 if (sadb_msg->sadb_msg_satype ==
599 SADB_X_SATYPE_TCPSIGNATURE &&
600 sa->sa_family == 0)
601 break;
602 DPRINTF("unknown address family %d in ADDRESS "
603 "extension header %d",
604 sa->sa_family, sadb_ext->sadb_ext_type);
605 return (EINVAL);
606 }
607 }
608 break;
609 case SADB_EXT_KEY_AUTH:
610 case SADB_EXT_KEY_ENCRYPT:
611 {
612 struct sadb_key *sadb_key = (struct sadb_key *)p;
613
614 if (i < sizeof(struct sadb_key)) {
615 DPRINTF("bad header length in KEY extension "
616 "header %d",
617 sadb_ext->sadb_ext_type);
618 return (EINVAL);
619 }
620
621 if (!sadb_key->sadb_key_bits) {
622 DPRINTF("key length unset in KEY extension "
623 "header %d",
624 sadb_ext->sadb_ext_type);
625 return (EINVAL);
626 }
627
628 if (((sadb_key->sadb_key_bits + 63) / 64) * sizeof(uint64_t) != i - sizeof(struct sadb_key)) {
629 DPRINTF("invalid key length in KEY extension "
630 "header %d",
631 sadb_ext->sadb_ext_type);
632 return (EINVAL);
633 }
634
635 if (sadb_key->sadb_key_reserved) {
636 DPRINTF("reserved field set in KEY extension "
637 "header %d",
638 sadb_ext->sadb_ext_type);
639 return (EINVAL);
640 }
641 }
642 break;
643 case SADB_EXT_IDENTITY_SRC:
644 case SADB_EXT_IDENTITY_DST:
645 {
646 struct sadb_ident *sadb_ident = (struct sadb_ident *)p;
647
648 if (i < sizeof(struct sadb_ident)) {
649 DPRINTF("bad header length of IDENTITY "
650 "extension header %d",
651 sadb_ext->sadb_ext_type);
652 return (EINVAL);
653 }
654
655 if (sadb_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
656 DPRINTF("unknown identity type %d in IDENTITY "
657 "extension header %d",
658 sadb_ident->sadb_ident_type,
659 sadb_ext->sadb_ext_type);
660 return (EINVAL);
661 }
662
663 if (sadb_ident->sadb_ident_reserved) {
664 DPRINTF("reserved field set in IDENTITY "
665 "extension header %d",
666 sadb_ext->sadb_ext_type);
667 return (EINVAL);
668 }
669
670 if (i > sizeof(struct sadb_ident)) {
671 char *c =
672 (char *)(p + sizeof(struct sadb_ident));
673 int j;
674
675 if (*(char *)(p + i - 1)) {
676 DPRINTF("non NUL-terminated identity "
677 "in IDENTITY extension header %d",
678 sadb_ext->sadb_ext_type);
679 return (EINVAL);
680 }
681
682 j = PADUP(strlen(c) + 1) +
683 sizeof(struct sadb_ident);
684
685 if (i != j) {
686 DPRINTF("actual identity length does "
687 "not match expected length in "
688 "identity extension header %d",
689 sadb_ext->sadb_ext_type);
690 return (EINVAL);
691 }
692 }
693 }
694 break;
695 case SADB_EXT_SENSITIVITY:
696 {
697 struct sadb_sens *sadb_sens = (struct sadb_sens *)p;
698
699 if (i < sizeof(struct sadb_sens)) {
700 DPRINTF("bad header length for SENSITIVITY "
701 "extension header");
702 return (EINVAL);
703 }
704
705 if (i != (sadb_sens->sadb_sens_sens_len +
706 sadb_sens->sadb_sens_integ_len) *
707 sizeof(uint64_t) +
708 sizeof(struct sadb_sens)) {
709 DPRINTF("bad payload length for SENSITIVITY "
710 "extension header");
711 return (EINVAL);
712 }
713 }
714 break;
715 case SADB_EXT_PROPOSAL:
716 {
717 struct sadb_prop *sadb_prop = (struct sadb_prop *)p;
718
719 if (i < sizeof(struct sadb_prop)) {
720 DPRINTF("bad PROPOSAL header length");
721 return (EINVAL);
722 }
723
724 if (sadb_prop->sadb_prop_reserved) {
725 DPRINTF("reserved fieldset in PROPOSAL "
726 "extension header");
727 return (EINVAL);
728 }
729
730 if ((i - sizeof(struct sadb_prop)) %
731 sizeof(struct sadb_comb)) {
732 DPRINTF("bad proposal length");
733 return (EINVAL);
734 }
735
736 {
737 struct sadb_comb *sadb_comb =
738 (struct sadb_comb *)(p +
739 sizeof(struct sadb_prop));
740 int j;
741
742 for (j = 0;
743 j < (i - sizeof(struct sadb_prop))/
744 sizeof(struct sadb_comb);
745 j++) {
746 if (sadb_comb->sadb_comb_auth >
747 SADB_AALG_MAX) {
748 DPRINTF("unknown "
749 "authentication algorithm "
750 "%d in PROPOSAL",
751 sadb_comb->sadb_comb_auth);
752 return (EINVAL);
753 }
754
755 if (sadb_comb->sadb_comb_encrypt >
756 SADB_EALG_MAX) {
757 DPRINTF("unknown encryption "
758 "algorithm %d in PROPOSAL",
759 sadb_comb->
760 sadb_comb_encrypt);
761 return (EINVAL);
762 }
763
764 if (sadb_comb->sadb_comb_reserved) {
765 DPRINTF("reserved field set "
766 "in COMB header");
767 return (EINVAL);
768 }
769 }
770 }
771 }
772 break;
773 case SADB_EXT_SUPPORTED_AUTH:
774 case SADB_EXT_SUPPORTED_ENCRYPT:
775 case SADB_X_EXT_SUPPORTED_COMP:
776 {
777 struct sadb_supported *sadb_supported =
778 (struct sadb_supported *)p;
779 int j;
780
781 if (i < sizeof(struct sadb_supported)) {
782 DPRINTF("bad header length for SUPPORTED " "extension header %d",
783 sadb_ext->sadb_ext_type);
784 return (EINVAL);
785 }
786
787 if (sadb_supported->sadb_supported_reserved) {
788 DPRINTF("reserved field set in SUPPORTED "
789 "extension header %d",
790 sadb_ext->sadb_ext_type);
791 return (EINVAL);
792 }
793
794 {
795 struct sadb_alg *sadb_alg =
796 (struct sadb_alg *)(p +
797 sizeof(struct sadb_supported));
798 int max_alg;
799
800 max_alg = sadb_ext->sadb_ext_type ==
801 SADB_EXT_SUPPORTED_AUTH ?
802 SADB_AALG_MAX : SADB_EXT_SUPPORTED_ENCRYPT ?
803 SADB_EALG_MAX : SADB_X_CALG_MAX;
804
805 for (j = 0;
806 j < sadb_supported->sadb_supported_len - 1;
807 j++) {
808 if (sadb_alg->sadb_alg_id > max_alg) {
809 DPRINTF("unknown algorithm %d "
810 "in SUPPORTED extension "
811 "header %d",
812 sadb_alg->sadb_alg_id,
813 sadb_ext->sadb_ext_type);
814 return (EINVAL);
815 }
816
817 if (sadb_alg->sadb_alg_reserved) {
818 DPRINTF("reserved field set "
819 "in supported algorithms "
820 "header inside SUPPORTED "
821 "extension header %d",
822 sadb_ext->sadb_ext_type);
823 return (EINVAL);
824 }
825
826 sadb_alg++;
827 }
828 }
829 }
830 break;
831 case SADB_EXT_SPIRANGE:
832 {
833 struct sadb_spirange *sadb_spirange =
834 (struct sadb_spirange *)p;
835
836 if (i != sizeof(struct sadb_spirange)) {
837 DPRINTF("bad header length of SPIRANGE "
838 "extension header");
839 return (EINVAL);
840 }
841
842 if (sadb_spirange->sadb_spirange_min >
843 sadb_spirange->sadb_spirange_max) {
844 DPRINTF("bad SPI range");
845 return (EINVAL);
846 }
847 }
848 break;
849 case SADB_X_EXT_UDPENCAP:
850 if (i != sizeof(struct sadb_x_udpencap)) {
851 DPRINTF("bad UDPENCAP header length");
852 return (EINVAL);
853 }
854 break;
855 case SADB_X_EXT_RDOMAIN:
856 if (i != sizeof(struct sadb_x_rdomain)) {
857 DPRINTF("bad RDOMAIN header length");
858 return (EINVAL);
859 }
860 break;
861 #if NPF > 0
862 case SADB_X_EXT_TAG:
863 if (i < sizeof(struct sadb_x_tag)) {
864 DPRINTF("TAG extension header too small");
865 return (EINVAL);
866 }
867 if (i > (sizeof(struct sadb_x_tag) +
868 PF_TAG_NAME_SIZE)) {
869 DPRINTF("TAG extension header too long");
870 return (EINVAL);
871 }
872 break;
873 case SADB_X_EXT_TAP:
874 if (i < sizeof(struct sadb_x_tap)) {
875 DPRINTF("TAP extension header too small");
876 return (EINVAL);
877 }
878 if (i > sizeof(struct sadb_x_tap)) {
879 DPRINTF("TAP extension header too long");
880 return (EINVAL);
881 }
882 break;
883 #endif
884 default:
885 DPRINTF("unknown extension header type %d",
886 sadb_ext->sadb_ext_type);
887 return (EINVAL);
888 }
889
890 headers[sadb_ext->sadb_ext_type] = p;
891 p += i;
892 left -= i;
893 }
894
895 if (left) {
896 DPRINTF("message too long");
897 return (EINVAL);
898 }
899
900 {
901 uint64_t required;
902
903 required = sadb_exts_required_in[sadb_msg->sadb_msg_type];
904
905 if ((seen & required) != required) {
906 DPRINTF("required fields missing");
907 return (EINVAL);
908 }
909 }
910
911 switch (((struct sadb_msg *)headers[0])->sadb_msg_type) {
912 case SADB_UPDATE:
913 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
914 SADB_SASTATE_MATURE) {
915 DPRINTF("updating non-mature SA prohibited");
916 return (EINVAL);
917 }
918 break;
919 case SADB_ADD:
920 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
921 SADB_SASTATE_MATURE) {
922 DPRINTF("adding non-mature SA prohibited");
923 return (EINVAL);
924 }
925 break;
926 }
927
928 return (0);
929 }
Cache object: bb8097d9ca3386b1ef788ed5d073c627
|