This source file includes following definitions.
- pfkeyv2_parsemessage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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 extern int encdebug;
87
88 #ifdef ENCDEBUG
89 #define DPRINTF(x) if (encdebug) printf x
90 #else
91 #define DPRINTF(x)
92 #endif
93
94 #define BITMAP_SA (1LL << SADB_EXT_SA)
95 #define BITMAP_LIFETIME_CURRENT (1LL << SADB_EXT_LIFETIME_CURRENT)
96 #define BITMAP_LIFETIME_HARD (1LL << SADB_EXT_LIFETIME_HARD)
97 #define BITMAP_LIFETIME_SOFT (1LL << SADB_EXT_LIFETIME_SOFT)
98 #define BITMAP_ADDRESS_SRC (1LL << SADB_EXT_ADDRESS_SRC)
99 #define BITMAP_ADDRESS_DST (1LL << SADB_EXT_ADDRESS_DST)
100 #define BITMAP_ADDRESS_PROXY (1LL << SADB_EXT_ADDRESS_PROXY)
101 #define BITMAP_KEY_AUTH (1LL << SADB_EXT_KEY_AUTH)
102 #define BITMAP_KEY_ENCRYPT (1LL << SADB_EXT_KEY_ENCRYPT)
103 #define BITMAP_IDENTITY_SRC (1LL << SADB_EXT_IDENTITY_SRC)
104 #define BITMAP_IDENTITY_DST (1LL << SADB_EXT_IDENTITY_DST)
105 #define BITMAP_SENSITIVITY (1LL << SADB_EXT_SENSITIVITY)
106 #define BITMAP_PROPOSAL (1LL << SADB_EXT_PROPOSAL)
107 #define BITMAP_SUPPORTED_AUTH (1LL << SADB_EXT_SUPPORTED_AUTH)
108 #define BITMAP_SUPPORTED_ENCRYPT (1LL << SADB_EXT_SUPPORTED_ENCRYPT)
109 #define BITMAP_SPIRANGE (1LL << SADB_EXT_SPIRANGE)
110 #define BITMAP_LIFETIME (BITMAP_LIFETIME_CURRENT | BITMAP_LIFETIME_HARD | BITMAP_LIFETIME_SOFT)
111 #define BITMAP_ADDRESS (BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_ADDRESS_PROXY)
112 #define BITMAP_KEY (BITMAP_KEY_AUTH | BITMAP_KEY_ENCRYPT)
113 #define BITMAP_IDENTITY (BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST)
114 #define BITMAP_MSG 1
115 #define BITMAP_X_SRC_MASK (1LL << SADB_X_EXT_SRC_MASK)
116 #define BITMAP_X_DST_MASK (1LL << SADB_X_EXT_DST_MASK)
117 #define BITMAP_X_PROTOCOL (1LL << SADB_X_EXT_PROTOCOL)
118 #define BITMAP_X_SRC_FLOW (1LL << SADB_X_EXT_SRC_FLOW)
119 #define BITMAP_X_DST_FLOW (1LL << SADB_X_EXT_DST_FLOW)
120 #define BITMAP_X_FLOW_TYPE (1LL << SADB_X_EXT_FLOW_TYPE)
121 #define BITMAP_X_SA2 (1LL << SADB_X_EXT_SA2)
122 #define BITMAP_X_DST2 (1LL << SADB_X_EXT_DST2)
123 #define BITMAP_X_POLICY (1LL << SADB_X_EXT_POLICY)
124 #define BITMAP_X_LOCAL_CREDENTIALS (1LL << SADB_X_EXT_LOCAL_CREDENTIALS)
125 #define BITMAP_X_REMOTE_CREDENTIALS (1LL << SADB_X_EXT_REMOTE_CREDENTIALS)
126 #define BITMAP_X_LOCAL_AUTH (1LL << SADB_X_EXT_LOCAL_AUTH)
127 #define BITMAP_X_REMOTE_AUTH (1LL << SADB_X_EXT_REMOTE_AUTH)
128 #define BITMAP_X_CREDENTIALS (BITMAP_X_LOCAL_CREDENTIALS | BITMAP_X_REMOTE_CREDENTIALS | BITMAP_X_LOCAL_AUTH | BITMAP_X_REMOTE_AUTH)
129 #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)
130 #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP)
131 #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP)
132 #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE)
133 #define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG)
134
135 uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
136 {
137
138 ~0,
139
140 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
141
142 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
143
144 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG,
145
146 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
147
148 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
149
150 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL | BITMAP_X_CREDENTIALS,
151
152 0,
153
154 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
155
156 0,
157
158 0,
159
160 0,
161
162 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_FLOW,
163
164 BITMAP_X_FLOW,
165
166 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
167
168 BITMAP_X_POLICY,
169 };
170
171 uint64_t sadb_exts_required_in[SADB_MAX+1] =
172 {
173
174 0,
175
176 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE,
177
178 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
179
180 BITMAP_SA | BITMAP_ADDRESS_DST,
181
182 BITMAP_SA | BITMAP_ADDRESS_DST,
183
184 BITMAP_SA | BITMAP_ADDRESS_DST,
185
186 0,
187
188 0,
189
190 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
191
192 0,
193
194 0,
195
196 0,
197
198 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
199
200 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
201
202 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
203
204 BITMAP_X_POLICY,
205 };
206
207 uint64_t sadb_exts_allowed_out[SADB_MAX+1] =
208 {
209
210 ~0,
211
212 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
213
214 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
215
216 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG,
217
218 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST,
219
220 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | 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,
221
222 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL | BITMAP_X_CREDENTIALS,
223
224 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
225
226 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS,
227
228 0,
229
230 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY,
231
232 0,
233
234 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,
235
236 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
237
238 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
239
240 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY,
241 };
242
243 uint64_t sadb_exts_required_out[SADB_MAX+1] =
244 {
245
246 0,
247
248 BITMAP_SA | BITMAP_ADDRESS_DST,
249
250 BITMAP_SA | BITMAP_ADDRESS_DST,
251
252 BITMAP_SA | BITMAP_ADDRESS_DST,
253
254 BITMAP_SA | BITMAP_ADDRESS_DST,
255
256 BITMAP_SA | BITMAP_LIFETIME_CURRENT | BITMAP_ADDRESS_DST,
257
258 0,
259
260 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP,
261
262 BITMAP_SA | BITMAP_ADDRESS_DST,
263
264 0,
265
266 0,
267
268 0,
269
270 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
271
272 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
273
274 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL,
275
276 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE,
277 };
278
279 int pfkeyv2_parsemessage(void *, int, void **);
280
281 #define RETURN_EINVAL(line) goto einval;
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(("pfkeyv2_parsemessage: message too short\n"));
295 return (EINVAL);
296 }
297
298 headers[0] = p;
299
300 if (sadb_msg->sadb_msg_len * sizeof(uint64_t) != left) {
301 DPRINTF(("pfkeyv2_parsemessage: length not a multiple of 64\n"));
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(("pfkeyv2_parsemessage: message header reserved "
310 "field set\n"));
311 return (EINVAL);
312 }
313
314 if (sadb_msg->sadb_msg_type > SADB_MAX) {
315 DPRINTF(("pfkeyv2_parsemessage: message type > %d\n",
316 SADB_MAX));
317 return (EINVAL);
318 }
319
320 if (!sadb_msg->sadb_msg_type) {
321 DPRINTF(("pfkeyv2_parsemessage: message type unset\n"));
322 return (EINVAL);
323 }
324
325 if (sadb_msg->sadb_msg_pid != curproc->p_pid) {
326 DPRINTF(("pfkeyv2_parsemessage: bad PID value\n"));
327 return (EINVAL);
328 }
329
330 if (sadb_msg->sadb_msg_errno) {
331 if (left) {
332 DPRINTF(("pfkeyv2_parsemessage: too-large error message\n"));
333 return (EINVAL);
334 }
335 return (0);
336 }
337
338 if (sadb_msg->sadb_msg_type == SADB_X_PROMISC) {
339 DPRINTF(("pfkeyv2_parsemessage: message type promiscuous\n"));
340 return (0);
341 }
342
343 allow = sadb_exts_allowed_in[sadb_msg->sadb_msg_type];
344
345 while (left > 0) {
346 sadb_ext = (struct sadb_ext *)p;
347 if (left < sizeof(struct sadb_ext)) {
348 DPRINTF(("pfkeyv2_parsemessage: extension header too "
349 "short\n"));
350 return (EINVAL);
351 }
352
353 i = sadb_ext->sadb_ext_len * sizeof(uint64_t);
354 if (left < i) {
355 DPRINTF(("pfkeyv2_parsemessage: extension header "
356 "exceeds message length\n"));
357 return (EINVAL);
358 }
359
360 if (sadb_ext->sadb_ext_type > SADB_EXT_MAX) {
361 DPRINTF(("pfkeyv2_parsemessage: unknown extension "
362 "header %d\n", sadb_ext->sadb_ext_type));
363 return (EINVAL);
364 }
365
366 if (!sadb_ext->sadb_ext_type) {
367 DPRINTF(("pfkeyv2_parsemessage: unset extension "
368 "header\n"));
369 return (EINVAL);
370 }
371
372 if (!(allow & (1LL << sadb_ext->sadb_ext_type))) {
373 DPRINTF(("pfkeyv2_parsemessage: extension header %d "
374 "not permitted on message type %d\n",
375 sadb_ext->sadb_ext_type, sadb_msg->sadb_msg_type));
376 return (EINVAL);
377 }
378
379 if (headers[sadb_ext->sadb_ext_type]) {
380 DPRINTF(("pfkeyv2_parsemessage: duplicate extension "
381 "header %d\n", sadb_ext->sadb_ext_type));
382 return (EINVAL);
383 }
384
385 seen |= (1LL << sadb_ext->sadb_ext_type);
386
387 switch (sadb_ext->sadb_ext_type) {
388 case SADB_EXT_SA:
389 case SADB_X_EXT_SA2:
390 {
391 struct sadb_sa *sadb_sa = (struct sadb_sa *)p;
392
393 if (i != sizeof(struct sadb_sa)) {
394 DPRINTF(("pfkeyv2_parsemessage: bad header "
395 "length for SA extension header %d\n",
396 sadb_ext->sadb_ext_type));
397 return (EINVAL);
398 }
399
400 if (sadb_sa->sadb_sa_state > SADB_SASTATE_MAX) {
401 DPRINTF(("pfkeyv2_parsemessage: unknown SA "
402 "state %d in SA extension header %d\n",
403 sadb_sa->sadb_sa_state,
404 sadb_ext->sadb_ext_type));
405 return (EINVAL);
406 }
407
408 if (sadb_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
409 DPRINTF(("pfkeyv2_parsemessage: cannot set SA "
410 "state to dead, SA extension header %d\n",
411 sadb_ext->sadb_ext_type));
412 return (EINVAL);
413 }
414
415 if (sadb_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
416 DPRINTF(("pfkeyv2_parsemessage: unknown "
417 "encryption algorithm %d in SA extension "
418 "header %d\n", sadb_sa->sadb_sa_encrypt,
419 sadb_ext->sadb_ext_type));
420 return (EINVAL);
421 }
422
423 if (sadb_sa->sadb_sa_auth > SADB_AALG_MAX) {
424 DPRINTF(("pfkeyv2_parsemessage: unknown "
425 "authentication algorithm %d in SA "
426 "extension header %d\n",
427 sadb_sa->sadb_sa_auth,
428 sadb_ext->sadb_ext_type));
429 return (EINVAL);
430 }
431
432 if (sadb_sa->sadb_sa_replay > 32) {
433 DPRINTF(("pfkeyv2_parsemessage: unsupported "
434 "replay window size %d in SA extension "
435 "header %d\n", sadb_sa->sadb_sa_replay,
436 sadb_ext->sadb_ext_type));
437 return (EINVAL);
438 }
439 }
440 break;
441 case SADB_X_EXT_PROTOCOL:
442 case SADB_X_EXT_FLOW_TYPE:
443 if (i != sizeof(struct sadb_protocol)) {
444 DPRINTF(("pfkeyv2_parsemessage: bad "
445 "PROTOCOL/FLOW header length in extension "
446 "header %d\n", sadb_ext->sadb_ext_type));
447 return (EINVAL);
448 }
449 break;
450 case SADB_X_EXT_POLICY:
451 if (i != sizeof(struct sadb_x_policy)) {
452 DPRINTF(("pfkeyv2_parsemessage: bad POLICY "
453 "header length\n"));
454 return (EINVAL);
455 }
456 break;
457 case SADB_EXT_LIFETIME_CURRENT:
458 case SADB_EXT_LIFETIME_HARD:
459 case SADB_EXT_LIFETIME_SOFT:
460 case SADB_X_EXT_LIFETIME_LASTUSE:
461 if (i != sizeof(struct sadb_lifetime)) {
462 DPRINTF(("pfkeyv2_parsemessage: bad header "
463 "length for LIFETIME extension header "
464 "%d\n", sadb_ext->sadb_ext_type));
465 return (EINVAL);
466 }
467 break;
468 case SADB_EXT_ADDRESS_SRC:
469 case SADB_EXT_ADDRESS_DST:
470 case SADB_X_EXT_SRC_MASK:
471 case SADB_X_EXT_DST_MASK:
472 case SADB_X_EXT_SRC_FLOW:
473 case SADB_X_EXT_DST_FLOW:
474 case SADB_X_EXT_DST2:
475 case SADB_EXT_ADDRESS_PROXY:
476 {
477 struct sadb_address *sadb_address =
478 (struct sadb_address *)p;
479 struct sockaddr *sa = (struct sockaddr *)(p +
480 sizeof(struct sadb_address));
481
482 if (i < sizeof(struct sadb_address) +
483 sizeof(struct sockaddr)) {
484 DPRINTF(("pfkeyv2_parsemessage: bad ADDRESS "
485 "extension header %d length\n",
486 sadb_ext->sadb_ext_type));
487 return (EINVAL);
488 }
489
490 if (sadb_address->sadb_address_reserved) {
491 DPRINTF(("pfkeyv2_parsemessage: ADDRESS "
492 "extension header %d reserved field set\n",
493 sadb_ext->sadb_ext_type));
494 return (EINVAL);
495 }
496 if (sa->sa_len &&
497 (i != sizeof(struct sadb_address) +
498 PADUP(sa->sa_len))) {
499 DPRINTF(("pfkeyv2_parsemessage: bad sockaddr "
500 "length field in ADDRESS extension "
501 "header %d\n", sadb_ext->sadb_ext_type));
502 return (EINVAL);
503 }
504
505 switch (sa->sa_family) {
506 case AF_INET:
507 if (sizeof(struct sadb_address) +
508 PADUP(sizeof(struct sockaddr_in)) != i) {
509 DPRINTF(("pfkeyv2_parsemessage: "
510 "invalid ADDRESS extension header "
511 "%d length\n",
512 sadb_ext->sadb_ext_type));
513 return (EINVAL);
514 }
515
516 if (sa->sa_len != sizeof(struct sockaddr_in)) {
517 DPRINTF(("pfkeyv2_parsemessage: bad "
518 "sockaddr_in length in ADDRESS "
519 "extension header %d\n",
520 sadb_ext->sadb_ext_type));
521 return (EINVAL);
522 }
523
524
525 switch (sadb_ext->sadb_ext_type)
526 {
527 case SADB_X_EXT_SRC_MASK:
528 case SADB_X_EXT_DST_MASK:
529 case SADB_X_EXT_SRC_FLOW:
530 case SADB_X_EXT_DST_FLOW:
531 break;
532
533 default:
534 if (((struct sockaddr_in *)sa)->sin_port) {
535 DPRINTF(("pfkeyv2_parsemessage"
536 ": port field set in "
537 "sockaddr_in of ADDRESS "
538 "extension header %d\n",
539 sadb_ext->sadb_ext_type));
540 return (EINVAL);
541 }
542 break;
543 }
544
545 {
546 char zero[sizeof(((struct sockaddr_in *)sa)->sin_zero)];
547 bzero(zero, sizeof(zero));
548
549 if (bcmp(&((struct sockaddr_in *)sa)->sin_zero, zero, sizeof(zero))) {
550 DPRINTF(("pfkeyv2_parsemessage"
551 ": reserved sockaddr_in "
552 "field non-zero'ed in "
553 "ADDRESS extension header "
554 "%d\n",
555 sadb_ext->sadb_ext_type));
556 return (EINVAL);
557 }
558 }
559 break;
560 #if INET6
561 case AF_INET6:
562 if (i != sizeof(struct sadb_address) +
563 PADUP(sizeof(struct sockaddr_in6))) {
564 DPRINTF(("pfkeyv2_parsemessage: "
565 "invalid sockaddr_in6 length in "
566 "ADDRESS extension header %d\n",
567 sadb_ext->sadb_ext_type));
568 return (EINVAL);
569 }
570
571 if (sa->sa_len !=
572 sizeof(struct sockaddr_in6)) {
573 DPRINTF(("pfkeyv2_parsemessage: bad "
574 "sockaddr_in6 length in ADDRESS "
575 "extension header %d\n",
576 sadb_ext->sadb_ext_type));
577 return (EINVAL);
578 }
579
580 if (((struct sockaddr_in6 *)sa)->sin6_flowinfo) {
581 DPRINTF(("pfkeyv2_parsemessage: "
582 "flowinfo field set in "
583 "sockaddr_in6 of ADDRESS "
584 "extension header %d\n",
585 sadb_ext->sadb_ext_type));
586 return (EINVAL);
587 }
588
589
590 switch (sadb_ext->sadb_ext_type)
591 {
592 case SADB_X_EXT_SRC_MASK:
593 case SADB_X_EXT_DST_MASK:
594 case SADB_X_EXT_SRC_FLOW:
595 case SADB_X_EXT_DST_FLOW:
596 break;
597
598 default:
599 if (((struct sockaddr_in6 *)sa)->sin6_port) {
600 DPRINTF(("pfkeyv2_parsemessage"
601 ": port field set in "
602 "sockaddr_in6 of ADDRESS "
603 "extension header %d\n",
604 sadb_ext->sadb_ext_type));
605 return (EINVAL);
606 }
607 break;
608 }
609 break;
610 #endif
611 default:
612 if (sadb_msg->sadb_msg_satype ==
613 SADB_X_SATYPE_TCPSIGNATURE &&
614 sa->sa_family == 0)
615 break;
616 DPRINTF(("pfkeyv2_parsemessage: unknown "
617 "address family %d in ADDRESS extension "
618 "header %d\n",
619 sa->sa_family, sadb_ext->sadb_ext_type));
620 return (EINVAL);
621 }
622 }
623 break;
624 case SADB_EXT_KEY_AUTH:
625 case SADB_EXT_KEY_ENCRYPT:
626 {
627 struct sadb_key *sadb_key = (struct sadb_key *)p;
628
629 if (i < sizeof(struct sadb_key)) {
630 DPRINTF(("pfkeyv2_parsemessage: bad header "
631 "length in KEY extension header %d\n",
632 sadb_ext->sadb_ext_type));
633 return (EINVAL);
634 }
635
636 if (!sadb_key->sadb_key_bits) {
637 DPRINTF(("pfkeyv2_parsemessage: key length "
638 "unset in KEY extension header %d\n",
639 sadb_ext->sadb_ext_type));
640 return (EINVAL);
641 }
642
643 if (((sadb_key->sadb_key_bits + 63) / 64) * sizeof(uint64_t) != i - sizeof(struct sadb_key)) {
644 DPRINTF(("pfkeyv2_parsemessage: invalid key "
645 "length in KEY extension header %d\n",
646 sadb_ext->sadb_ext_type));
647 return (EINVAL);
648 }
649
650 if (sadb_key->sadb_key_reserved) {
651 DPRINTF(("pfkeyv2_parsemessage: reserved field"
652 " set in KEY extension header %d\n",
653 sadb_ext->sadb_ext_type));
654 return (EINVAL);
655 }
656 }
657 break;
658 case SADB_X_EXT_LOCAL_AUTH:
659 case SADB_X_EXT_REMOTE_AUTH:
660 {
661 struct sadb_x_cred *sadb_cred =
662 (struct sadb_x_cred *)p;
663
664 if (i < sizeof(struct sadb_x_cred)) {
665 DPRINTF(("pfkeyv2_parsemessage: bad header "
666 "length for AUTH extension header %d\n",
667 sadb_ext->sadb_ext_type));
668 return (EINVAL);
669 }
670
671 if (sadb_cred->sadb_x_cred_type > SADB_X_AUTHTYPE_MAX) {
672 DPRINTF(("pfkeyv2_parsemessage: unknown auth "
673 "type %d in AUTH extension header %d\n",
674 sadb_cred->sadb_x_cred_type,
675 sadb_ext->sadb_ext_type));
676 return (EINVAL);
677 }
678
679 if (sadb_cred->sadb_x_cred_reserved) {
680 DPRINTF(("pfkeyv2_parsemessage: reserved field"
681 " set in AUTH extension header %d\n",
682 sadb_ext->sadb_ext_type));
683 return (EINVAL);
684 }
685 }
686 break;
687 case SADB_X_EXT_LOCAL_CREDENTIALS:
688 case SADB_X_EXT_REMOTE_CREDENTIALS:
689 {
690 struct sadb_x_cred *sadb_cred =
691 (struct sadb_x_cred *)p;
692
693 if (i < sizeof(struct sadb_x_cred)) {
694 DPRINTF(("pfkeyv2_parsemessage: bad header "
695 "length of CREDENTIALS extension header "
696 "%d\n", sadb_ext->sadb_ext_type));
697 return (EINVAL);
698 }
699
700 if (sadb_cred->sadb_x_cred_type > SADB_X_CREDTYPE_MAX) {
701 DPRINTF(("pfkeyv2_parsemessage: unknown "
702 "credential type %d in CREDENTIALS "
703 "extension header %d\n",
704 sadb_cred->sadb_x_cred_type,
705 sadb_ext->sadb_ext_type));
706 return (EINVAL);
707 }
708
709 if (sadb_cred->sadb_x_cred_reserved) {
710 DPRINTF(("pfkeyv2_parsemessage: reserved "
711 "field set in CREDENTIALS extension "
712 "header %d\n", sadb_ext->sadb_ext_type));
713 return (EINVAL);
714 }
715 }
716 break;
717 case SADB_EXT_IDENTITY_SRC:
718 case SADB_EXT_IDENTITY_DST:
719 {
720 struct sadb_ident *sadb_ident = (struct sadb_ident *)p;
721
722 if (i < sizeof(struct sadb_ident)) {
723 DPRINTF(("pfkeyv2_parsemessage: bad header "
724 "length of IDENTITY extension header %d\n",
725 sadb_ext->sadb_ext_type));
726 return (EINVAL);
727 }
728
729 if (sadb_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
730 DPRINTF(("pfkeyv2_parsemessage: unknown "
731 "identity type %d in IDENTITY extension "
732 "header %d\n",
733 sadb_ident->sadb_ident_type,
734 sadb_ext->sadb_ext_type));
735 return (EINVAL);
736 }
737
738 if (sadb_ident->sadb_ident_reserved) {
739 DPRINTF(("pfkeyv2_parsemessage: reserved "
740 "field set in IDENTITY extension header "
741 "%d\n", sadb_ext->sadb_ext_type));
742 return (EINVAL);
743 }
744
745 if (i > sizeof(struct sadb_ident)) {
746 char *c =
747 (char *)(p + sizeof(struct sadb_ident));
748 int j;
749
750 if (*(char *)(p + i - 1)) {
751 DPRINTF(("pfkeyv2_parsemessage: non "
752 "NUL-terminated identity in "
753 "IDENTITY extension header %d\n",
754 sadb_ext->sadb_ext_type));
755 return (EINVAL);
756 }
757
758 j = PADUP(strlen(c) + 1) +
759 sizeof(struct sadb_ident);
760
761 if (i != j) {
762 DPRINTF(("pfkeyv2_parsemessage: actual"
763 " identity length does not match "
764 "expected length in identity "
765 "extension header %d\n",
766 sadb_ext->sadb_ext_type));
767 return (EINVAL);
768 }
769 }
770 }
771 break;
772 case SADB_EXT_SENSITIVITY:
773 {
774 struct sadb_sens *sadb_sens = (struct sadb_sens *)p;
775
776 if (i < sizeof(struct sadb_sens)) {
777 DPRINTF(("pfkeyv2_parsemessage: bad header "
778 "length for SENSITIVITY extension "
779 "header\n"));
780 return (EINVAL);
781 }
782
783 if (i != (sadb_sens->sadb_sens_sens_len +
784 sadb_sens->sadb_sens_integ_len) *
785 sizeof(uint64_t) +
786 sizeof(struct sadb_sens)) {
787 DPRINTF(("pfkeyv2_parsemessage: bad payload "
788 "length for SENSITIVITY extension "
789 "header\n"));
790 return (EINVAL);
791 }
792 }
793 break;
794 case SADB_EXT_PROPOSAL:
795 {
796 struct sadb_prop *sadb_prop = (struct sadb_prop *)p;
797
798 if (i < sizeof(struct sadb_prop)) {
799 DPRINTF(("pfkeyv2_parsemessage: bad PROPOSAL "
800 "header length\n"));
801 return (EINVAL);
802 }
803
804 if (sadb_prop->sadb_prop_reserved) {
805 DPRINTF(("pfkeyv2_parsemessage: reserved field"
806 "set in PROPOSAL extension header\n"));
807 return (EINVAL);
808 }
809
810 if ((i - sizeof(struct sadb_prop)) %
811 sizeof(struct sadb_comb)) {
812 DPRINTF(("pfkeyv2_parsemessage: bad proposal "
813 "length\n"));
814 return (EINVAL);
815 }
816
817 {
818 struct sadb_comb *sadb_comb =
819 (struct sadb_comb *)(p +
820 sizeof(struct sadb_prop));
821 int j;
822
823 for (j = 0;
824 j < (i - sizeof(struct sadb_prop))/
825 sizeof(struct sadb_comb);
826 j++) {
827 if (sadb_comb->sadb_comb_auth >
828 SADB_AALG_MAX) {
829 DPRINTF(("pfkeyv2_parsemessage"
830 ": unknown authentication "
831 "algorithm %d in "
832 "PROPOSAL\n",
833 sadb_comb->sadb_comb_auth));
834 return (EINVAL);
835 }
836
837 if (sadb_comb->sadb_comb_encrypt >
838 SADB_EALG_MAX) {
839 DPRINTF(("pfkeyv2_parsemessage"
840 ": unknown encryption "
841 "algorithm %d in "
842 "PROPOSAL\n",
843 sadb_comb->sadb_comb_encrypt));
844 return (EINVAL);
845 }
846
847 if (sadb_comb->sadb_comb_reserved) {
848 DPRINTF(("pfkeyv2_parsemessage"
849 ": reserved field set in "
850 "COMB header\n"));
851 return (EINVAL);
852 }
853 }
854 }
855 }
856 break;
857 case SADB_EXT_SUPPORTED_AUTH:
858 case SADB_EXT_SUPPORTED_ENCRYPT:
859 case SADB_X_EXT_SUPPORTED_COMP:
860 {
861 struct sadb_supported *sadb_supported =
862 (struct sadb_supported *)p;
863 int j;
864
865 if (i < sizeof(struct sadb_supported)) {
866 DPRINTF(("pfkeyv2_parsemessage: bad header "
867 "length for SUPPORTED extension header "
868 "%d\n", sadb_ext->sadb_ext_type));
869 return (EINVAL);
870 }
871
872 if (sadb_supported->sadb_supported_reserved) {
873 DPRINTF(("pfkeyv2_parsemessage: reserved "
874 "field set in SUPPORTED extension "
875 "header %d\n", sadb_ext->sadb_ext_type));
876 return (EINVAL);
877 }
878
879 {
880 struct sadb_alg *sadb_alg =
881 (struct sadb_alg *)(p +
882 sizeof(struct sadb_supported));
883 int max_alg;
884
885 max_alg = sadb_ext->sadb_ext_type ==
886 SADB_EXT_SUPPORTED_AUTH ?
887 SADB_AALG_MAX : SADB_EXT_SUPPORTED_ENCRYPT ?
888 SADB_EALG_MAX : SADB_X_CALG_MAX;
889
890 for (j = 0;
891 j < sadb_supported->sadb_supported_len - 1;
892 j++) {
893 if (sadb_alg->sadb_alg_id > max_alg) {
894 DPRINTF(("pfkeyv2_parsemessage"
895 ": unknown algorithm %d "
896 "in SUPPORTED extension "
897 "header %d\n",
898 sadb_alg->sadb_alg_id,
899 sadb_ext->sadb_ext_type));
900 return (EINVAL);
901 }
902
903 if (sadb_alg->sadb_alg_reserved) {
904 DPRINTF(("pfkeyv2_parsemessage"
905 ": reserved field set in "
906 "supported algorithms "
907 "header inside SUPPORTED "
908 "extension header %d\n",
909 sadb_ext->sadb_ext_type));
910 return (EINVAL);
911 }
912
913 sadb_alg++;
914 }
915 }
916 }
917 break;
918 case SADB_EXT_SPIRANGE:
919 {
920 struct sadb_spirange *sadb_spirange =
921 (struct sadb_spirange *)p;
922
923 if (i != sizeof(struct sadb_spirange)) {
924 DPRINTF(("pfkeyv2_parsemessage: bad header "
925 "length of SPIRANGE extension header\n"));
926 return (EINVAL);
927 }
928
929 if (sadb_spirange->sadb_spirange_min >
930 sadb_spirange->sadb_spirange_max) {
931 DPRINTF(("pfkeyv2_parsemessage: bad SPI "
932 "range\n"));
933 return (EINVAL);
934 }
935 }
936 break;
937 case SADB_X_EXT_UDPENCAP:
938 if (i != sizeof(struct sadb_x_udpencap)) {
939 DPRINTF(("pfkeyv2_parsemessage: bad UDPENCAP "
940 "header length\n"));
941 return (EINVAL);
942 }
943 break;
944 #if NPF > 0
945 case SADB_X_EXT_TAG:
946 if (i < sizeof(struct sadb_x_tag)) {
947 DPRINTF(("pfkeyv2_parsemessage: "
948 "TAG extension header too small"));
949 return (EINVAL);
950 }
951 if (i > (sizeof(struct sadb_x_tag) +
952 PF_TAG_NAME_SIZE)) {
953 DPRINTF(("pfkeyv2_parsemessage: "
954 "TAG extension header too long"));
955 return (EINVAL);
956 }
957 break;
958 #endif
959 default:
960 DPRINTF(("pfkeyv2_parsemessage: unknown extension "
961 "header type %d\n",
962 sadb_ext->sadb_ext_type));
963 return (EINVAL);
964 }
965
966 headers[sadb_ext->sadb_ext_type] = p;
967 p += i;
968 left -= i;
969 }
970
971 if (left) {
972 DPRINTF(("pfkeyv2_parsemessage: message too long\n"));
973 return (EINVAL);
974 }
975
976 {
977 uint64_t required;
978
979 required = sadb_exts_required_in[sadb_msg->sadb_msg_type];
980
981 if ((seen & required) != required) {
982 DPRINTF(("pfkeyv2_parsemessage: required fields "
983 "missing\n"));
984 return (EINVAL);
985 }
986 }
987
988 switch (((struct sadb_msg *)headers[0])->sadb_msg_type) {
989 case SADB_UPDATE:
990 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
991 SADB_SASTATE_MATURE) {
992 DPRINTF(("pfkeyv2_parsemessage: updating non-mature "
993 "SA prohibited\n"));
994 return (EINVAL);
995 }
996 break;
997 case SADB_ADD:
998 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state !=
999 SADB_SASTATE_MATURE) {
1000 DPRINTF(("pfkeyv2_parsemessage: adding non-mature "
1001 "SA prohibited\n"));
1002 return (EINVAL);
1003 }
1004 break;
1005 }
1006
1007 return (0);
1008 }