]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/pfkey_racoon.c
efa1f6cebe2024a7216f612cb16331e3820f6a93
[apple/ipsec.git] / ipsec-tools / racoon / pfkey_racoon.c
1 /* $Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #include "racoon_types.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <netdb.h>
39 #include <errno.h>
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 #include <netdb.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46
47 #ifdef ENABLE_NATT
48 #include <netinet/udp.h>
49 #endif
50
51 #include <sys/types.h>
52 #include <sys/param.h>
53 #include <sys/socket.h>
54 #include <sys/queue.h>
55 #include <sys/sysctl.h>
56
57 #include <net/route.h>
58 #include <net/pfkeyv2.h>
59
60 #include <netinet/in.h>
61 #ifndef HAVE_NETINET6_IPSEC
62 #include <netinet/ipsec.h>
63 #else
64 #include <netinet6/ipsec.h>
65 #endif
66
67 #include "libpfkey.h"
68
69 #include "var.h"
70 #include "misc.h"
71 #include "vmbuf.h"
72 #include "plog.h"
73 #include "sockmisc.h"
74 #include "debug.h"
75 #include "fsm.h"
76 #include "ike_session.h"
77
78 #include "schedule.h"
79 #include "localconf.h"
80 #include "remoteconf.h"
81 #include "isakmp_var.h"
82 #include "isakmp.h"
83 #include "isakmp_inf.h"
84 #include "ipsec_doi.h"
85 #include "oakley.h"
86 #include "pfkey.h"
87 #include "handler.h"
88 #include "policy.h"
89 #include "algorithm.h"
90 #include "sainfo.h"
91 #include "proposal.h"
92 #include "strnames.h"
93 #include "gcmalloc.h"
94 #include "nattraversal.h"
95 #include "crypto_openssl.h"
96 #include "grabmyaddr.h"
97 #include "vpn_control.h"
98 #include "vpn_control_var.h"
99 #include "ike_session.h"
100 #include "ipsecSessionTracer.h"
101 #include "ipsecMessageTracer.h"
102 #include "power_mgmt.h"
103 #include "session.h"
104
105 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
106 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
107 #endif
108
109 /* prototype */
110 static u_int ipsecdoi2pfkey_aalg (u_int);
111 static u_int ipsecdoi2pfkey_ealg (u_int);
112 static u_int ipsecdoi2pfkey_calg (u_int);
113 static u_int ipsecdoi2pfkey_alg (u_int, u_int);
114 static u_int keylen_aalg (u_int);
115 static u_int keylen_ealg (u_int, int);
116
117 static int pk_recvgetspi (caddr_t *);
118 static int pk_recvupdate (caddr_t *);
119 static int pk_recvadd (caddr_t *);
120 static int pk_recvdelete (caddr_t *);
121 static int pk_recvacquire (caddr_t *);
122 static int pk_recvexpire (caddr_t *);
123 static int pk_recvflush (caddr_t *);
124 static int getsadbpolicy (caddr_t *, int *, int, phase2_handle_t *);
125 static int pk_recvspdupdate (caddr_t *);
126 static int pk_recvspdadd (caddr_t *);
127 static int pk_recvspddelete (caddr_t *);
128 static int pk_recvspdexpire (caddr_t *);
129 static int pk_recvspdget (caddr_t *);
130 static int pk_recvspddump (caddr_t *);
131 static int pk_recvspdflush (caddr_t *);
132 static int pk_recvgetsastat (caddr_t *);
133 static struct sadb_msg *pk_recv (int, ssize_t *);
134
135 static int (*pkrecvf[]) (caddr_t *) = {
136 NULL,
137 pk_recvgetspi,
138 pk_recvupdate,
139 pk_recvadd,
140 pk_recvdelete,
141 NULL, /* SADB_GET */
142 pk_recvacquire,
143 NULL, /* SABD_REGISTER */
144 pk_recvexpire,
145 pk_recvflush,
146 NULL, /* SADB_DUMP */
147 NULL, /* SADB_X_PROMISC */
148 NULL, /* SADB_X_PCHANGE */
149 pk_recvspdupdate,
150 pk_recvspdadd,
151 pk_recvspddelete,
152 pk_recvspdget,
153 NULL, /* SADB_X_SPDACQUIRE */
154 pk_recvspddump,
155 pk_recvspdflush,
156 NULL, /* SADB_X_SPDSETIDX */
157 pk_recvspdexpire,
158 NULL, /* SADB_X_SPDDELETE2 */
159 pk_recvgetsastat, /* SADB_GETSASTAT */
160 NULL, /* SADB_X_SPDENABLE */
161 NULL, /* SADB_X_SPDDISNABLE */
162 NULL, /* SADB_MIGRATE */
163 #if (SADB_MAX > 26)
164 #warning "SADB extra message?"
165 #endif
166 };
167
168 static int addnewsp (caddr_t *);
169
170 /* cope with old kame headers - ugly */
171 #ifndef SADB_X_AALG_MD5
172 #define SADB_X_AALG_MD5 SADB_AALG_MD5
173 #endif
174 #ifndef SADB_X_AALG_SHA
175 #define SADB_X_AALG_SHA SADB_AALG_SHA
176 #endif
177 #ifndef SADB_X_AALG_NULL
178 #define SADB_X_AALG_NULL SADB_AALG_NULL
179 #endif
180
181 #ifndef SADB_X_EALG_BLOWFISHCBC
182 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
183 #endif
184 #ifndef SADB_X_EALG_CAST128CBC
185 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
186 #endif
187 #ifndef SADB_X_EALG_RC5CBC
188 #ifdef SADB_EALG_RC5CBC
189 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
190 #endif
191 #endif
192
193 int
194 pfkey_process(msg)
195 struct sadb_msg *msg;
196 {
197 caddr_t mhp[SADB_EXT_MAX + 1];
198 int error = -1;
199
200 // Special debug use only - creates large logs
201 // plogdump(ASL_LEVEL_DEBUG, msg, msg->sadb_msg_len << 3, "get pfkey %s message\n",
202 // s_pfkey_type(msg->sadb_msg_type));
203
204 /* validity check */
205 /* check pfkey message. */
206 if (pfkey_align(msg, mhp)) {
207 plog(ASL_LEVEL_ERR,
208 "libipsec failed pfkey align (%s)\n",
209 ipsec_strerror());
210 goto end;
211 }
212 if (pfkey_check(mhp)) {
213 plog(ASL_LEVEL_ERR,
214 "libipsec failed pfkey check (%s)\n",
215 ipsec_strerror());
216 goto end;
217 }
218 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
219
220 if (msg->sadb_msg_errno) {
221 int pri;
222
223 /* when SPD is empty, treat the state as no error. */
224 if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
225 msg->sadb_msg_errno == ENOENT)
226 pri = ASL_LEVEL_NOTICE;
227 else
228 pri = ASL_LEVEL_ERR;
229
230 plog(pri,
231 "pfkey %s failed: %s\n",
232 s_pfkey_type(msg->sadb_msg_type),
233 strerror(msg->sadb_msg_errno));
234 goto end;
235 }
236
237 /* safety check */
238 if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
239 plog(ASL_LEVEL_ERR,
240 "unknown PF_KEY message type=%u\n",
241 msg->sadb_msg_type);
242 goto end;
243 }
244
245 if (pkrecvf[msg->sadb_msg_type] == NULL) {
246 plog(ASL_LEVEL_NOTICE,
247 "unsupported PF_KEY message %s\n",
248 s_pfkey_type(msg->sadb_msg_type));
249 goto end;
250 }
251
252 if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
253 goto end;
254
255 error = 0;
256 end:
257 if (msg)
258 racoon_free(msg);
259 return(error);
260 }
261
262 /*
263 * PF_KEY packet handler
264 * 0: success
265 * -1: fail
266 */
267
268 //%%%%%%%%%%%%%%%%%% need to handle errors encountered here - this no longer returns a result
269 void
270 pfkey_handler(void *unused)
271 {
272 struct sadb_msg *msg;
273 ssize_t len;
274
275 if (slept_at || woke_at) {
276 plog(ASL_LEVEL_DEBUG,
277 "ignoring pfkey port until power-mgmt event is handled.\n");
278 return;
279 }
280
281 /* receive pfkey message. */
282 len = 0;
283 msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
284
285 if (msg == NULL) {
286 if (len < 0) {
287 plog(ASL_LEVEL_ERR,
288 "failed to recv from pfkey (%s)\n",
289 strerror(errno));
290 return;
291 } else {
292 /* short message - msg not ready */
293 plog(ASL_LEVEL_NOTICE, "recv short message from pfkey\n");
294 return;
295 }
296 }
297 pfkey_process(msg);
298 }
299
300 void
301 pfkey_post_handler()
302 {
303 struct saved_msg_elem *elem;
304 struct saved_msg_elem *elem_tmp = NULL;
305
306 if (slept_at || woke_at) {
307 plog(ASL_LEVEL_NOTICE,
308 "ignoring (saved) pfkey messages until power-mgmt event is handled.\n");
309 return;
310 }
311
312 TAILQ_FOREACH_SAFE(elem, &lcconf->saved_msg_queue, chain, elem_tmp) {
313 pfkey_process((struct sadb_msg *)elem->msg);
314 TAILQ_REMOVE(&lcconf->saved_msg_queue, elem, chain);
315 racoon_free(elem);
316
317 }
318 }
319
320 int
321 pfkey_save_msg(msg)
322 struct sadb_msg *msg;
323 {
324 struct saved_msg_elem *elem;
325
326 elem = (struct saved_msg_elem *)racoon_calloc(sizeof(struct saved_msg_elem), 1);
327 if (elem == NULL)
328 return -1;
329 elem->msg = msg;
330 TAILQ_INSERT_TAIL(&lcconf->saved_msg_queue, elem, chain);
331 return 0;
332 }
333
334 /*
335 * dump SADB
336 */
337 vchar_t *
338 pfkey_dump_sadb(satype)
339 int satype;
340 {
341 int s = -1;
342 vchar_t *buf = NULL;
343 pid_t pid = getpid();
344 struct sadb_msg *msg = NULL;
345 size_t bl, ml;
346 ssize_t len;
347
348 if ((s = pfkey_open()) < 0) {
349 plog(ASL_LEVEL_ERR,
350 "libipsec failed pfkey open: %s\n",
351 ipsec_strerror());
352 return NULL;
353 }
354
355 plog(ASL_LEVEL_DEBUG, "call pfkey_send_dump\n");
356 if (pfkey_send_dump(s, satype) < 0) {
357 plog(ASL_LEVEL_ERR,
358 "libipsec failed dump: %s\n", ipsec_strerror());
359 goto fail;
360 }
361
362 while (1) {
363 if (msg)
364 racoon_free(msg);
365 msg = pk_recv(s, &len);
366 if (msg == NULL) {
367 if (len < 0)
368 goto done;
369 else
370 continue;
371 }
372
373 /*
374 * for multi-processor system this had to be added because the messages can
375 * be interleaved - they won't all be dump messages
376 */
377 if (msg->sadb_msg_type != SADB_DUMP) { /* save for later processing */
378 pfkey_save_msg(msg);
379 msg = NULL;
380 continue;
381 }
382
383 // ignore dump messages that aren't racoon's
384 if (msg->sadb_msg_pid != pid)
385 continue;
386
387 ml = msg->sadb_msg_len << 3;
388 bl = buf ? buf->l : 0;
389 buf = vrealloc(buf, bl + ml);
390 if (buf == NULL) {
391 plog(ASL_LEVEL_ERR,
392 "failed to reallocate buffer to dump.\n");
393 goto fail;
394 }
395 memcpy(buf->v + bl, msg, ml);
396
397 if (msg->sadb_msg_seq == 0)
398 break;
399 }
400 goto done;
401
402 fail:
403 if (buf)
404 vfree(buf);
405 buf = NULL;
406 done:
407 if (msg)
408 racoon_free(msg);
409 if (s >= 0)
410 pfkey_close_sock(s);
411 return buf;
412 }
413
414
415 /*
416 * These are the SATYPEs that we manage. We register to get
417 * PF_KEY messages related to these SATYPEs, and we also use
418 * this list to determine which SATYPEs to delete SAs for when
419 * we receive an INITIAL-CONTACT.
420 */
421 const struct pfkey_satype pfkey_satypes[] = {
422 { SADB_SATYPE_AH, "AH" },
423 { SADB_SATYPE_ESP, "ESP" },
424 { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
425 };
426 const int pfkey_nsatypes =
427 sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
428
429 /*
430 * PF_KEY initialization
431 */
432 int
433 pfkey_init(void)
434 {
435 int i, reg_fail, sock;
436
437 if ((lcconf->sock_pfkey = pfkey_open()) < 0) {
438 plog(ASL_LEVEL_ERR,
439 "libipsec failed pfkey open (%s)\n", ipsec_strerror());
440 return -1;
441 }
442
443 for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
444 plog(ASL_LEVEL_DEBUG,
445 "call pfkey_send_register for %s\n",
446 pfkey_satypes[i].ps_name);
447 if (pfkey_send_register(lcconf->sock_pfkey,
448 pfkey_satypes[i].ps_satype) < 0 ||
449 pfkey_recv_register(lcconf->sock_pfkey) < 0) {
450 plog(ASL_LEVEL_WARNING,
451 "failed to register %s (%s)\n",
452 pfkey_satypes[i].ps_name,
453 ipsec_strerror());
454 reg_fail++;
455 }
456 }
457
458 if (reg_fail == pfkey_nsatypes) {
459 plog(ASL_LEVEL_ERR,
460 "failed to regist any protocol.\n");
461 close(lcconf->sock_pfkey);
462 return -1;
463 }
464 initsp();
465
466 lcconf->pfkey_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, lcconf->sock_pfkey, 0, dispatch_get_main_queue());
467 if (lcconf->pfkey_source == NULL) {
468 plog(ASL_LEVEL_ERR, "could not create pfkey socket source.");
469 return -1;
470 }
471 dispatch_source_set_event_handler_f(lcconf->pfkey_source, pfkey_handler);
472 sock = lcconf->sock_pfkey;
473 dispatch_source_set_cancel_handler(lcconf->pfkey_source,
474 ^{
475 pfkey_close_sock(sock);
476 });
477 dispatch_resume(lcconf->pfkey_source);
478
479 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
480 plog(ASL_LEVEL_ERR,
481 "libipsec sending spddump failed: %s\n",
482 ipsec_strerror());
483 pfkey_close();
484 return -1;
485 }
486 #if 0
487 if (pfkey_promisc_toggle(1) < 0) {
488 pfkey_close();
489 return -1;
490 }
491 #endif
492
493 return 0;
494 }
495
496 void
497 pfkey_close(void)
498 {
499 dispatch_source_cancel(lcconf->pfkey_source);
500 lcconf->pfkey_source = NULL;
501 }
502
503 /* %%% for conversion */
504 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
505 static u_int
506 ipsecdoi2pfkey_aalg(hashtype)
507 u_int hashtype;
508 {
509 switch (hashtype) {
510 case IPSECDOI_ATTR_AUTH_HMAC_MD5:
511 case IPSECDOI_ATTR_AUTH_HMAC_MD5_96:
512 return SADB_AALG_MD5HMAC;
513 case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
514 case IPSECDOI_ATTR_AUTH_HMAC_SHA1_96:
515 return SADB_AALG_SHA1HMAC;
516 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
517 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
518 return SADB_X_AALG_SHA2_256;
519 #else
520 return SADB_X_AALG_SHA2_256HMAC;
521 #endif
522 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
523 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
524 return SADB_X_AALG_SHA2_384;
525 #else
526 return SADB_X_AALG_SHA2_384HMAC;
527 #endif
528 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
529 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
530 return SADB_X_AALG_SHA2_512;
531 #else
532 return SADB_X_AALG_SHA2_512HMAC;
533 #endif
534 case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */
535 return SADB_AALG_NONE;
536
537 /* not supported */
538 case IPSECDOI_ATTR_AUTH_DES_MAC:
539 plog(ASL_LEVEL_ERR,
540 "Not supported hash type: %u\n", hashtype);
541 return ~0;
542
543 case 0: /* reserved */
544 default:
545 return SADB_AALG_NONE;
546
547 plog(ASL_LEVEL_ERR,
548 "Invalid hash type: %u\n", hashtype);
549 return ~0;
550 }
551 /*NOTREACHED*/
552 }
553
554 /* IPSECDOI_ESP -> SADB_EALG */
555 static u_int
556 ipsecdoi2pfkey_ealg(t_id)
557 u_int t_id;
558 {
559 switch (t_id) {
560 case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */
561 return SADB_EALG_DESCBC;
562 case IPSECDOI_ESP_DES:
563 return SADB_EALG_DESCBC;
564 case IPSECDOI_ESP_3DES:
565 return SADB_EALG_3DESCBC;
566 #ifdef SADB_X_EALG_RC5CBC
567 case IPSECDOI_ESP_RC5:
568 return SADB_X_EALG_RC5CBC;
569 #endif
570 case IPSECDOI_ESP_CAST:
571 return SADB_X_EALG_CAST128CBC;
572 case IPSECDOI_ESP_BLOWFISH:
573 return SADB_X_EALG_BLOWFISHCBC;
574 case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD|
575 SADB_X_EXT_IV4B)*/
576 return SADB_EALG_DESCBC;
577 case IPSECDOI_ESP_NULL:
578 return SADB_EALG_NULL;
579 #ifdef SADB_X_EALG_AESCBC
580 case IPSECDOI_ESP_AES:
581 return SADB_X_EALG_AESCBC;
582 #endif
583 #ifdef SADB_X_EALG_TWOFISHCBC
584 case IPSECDOI_ESP_TWOFISH:
585 return SADB_X_EALG_TWOFISHCBC;
586 #endif
587
588 /* not supported */
589 case IPSECDOI_ESP_3IDEA:
590 case IPSECDOI_ESP_IDEA:
591 case IPSECDOI_ESP_RC4:
592 plog(ASL_LEVEL_ERR,
593 "Not supported transform: %u\n", t_id);
594 return ~0;
595
596 case 0: /* reserved */
597 default:
598 plog(ASL_LEVEL_ERR,
599 "Invalid transform id: %u\n", t_id);
600 return ~0;
601 }
602 /*NOTREACHED*/
603 }
604
605 /* IPCOMP -> SADB_CALG */
606 static u_int
607 ipsecdoi2pfkey_calg(t_id)
608 u_int t_id;
609 {
610 switch (t_id) {
611 case IPSECDOI_IPCOMP_OUI:
612 return SADB_X_CALG_OUI;
613 case IPSECDOI_IPCOMP_DEFLATE:
614 return SADB_X_CALG_DEFLATE;
615 case IPSECDOI_IPCOMP_LZS:
616 return SADB_X_CALG_LZS;
617
618 case 0: /* reserved */
619 default:
620 plog(ASL_LEVEL_ERR,
621 "Invalid transform id: %u\n", t_id);
622 return ~0;
623 }
624 /*NOTREACHED*/
625 }
626
627 /* IPSECDOI_PROTO -> SADB_SATYPE */
628 u_int
629 ipsecdoi2pfkey_proto(proto)
630 u_int proto;
631 {
632 switch (proto) {
633 case IPSECDOI_PROTO_IPSEC_AH:
634 return SADB_SATYPE_AH;
635 case IPSECDOI_PROTO_IPSEC_ESP:
636 return SADB_SATYPE_ESP;
637 case IPSECDOI_PROTO_IPCOMP:
638 return SADB_X_SATYPE_IPCOMP;
639
640 default:
641 plog(ASL_LEVEL_ERR,
642 "Invalid ipsec_doi proto: %u\n", proto);
643 return ~0;
644 }
645 /*NOTREACHED*/
646 }
647
648 static u_int
649 ipsecdoi2pfkey_alg(algclass, type)
650 u_int algclass, type;
651 {
652 switch (algclass) {
653 case IPSECDOI_ATTR_AUTH:
654 return ipsecdoi2pfkey_aalg(type);
655 case IPSECDOI_PROTO_IPSEC_ESP:
656 return ipsecdoi2pfkey_ealg(type);
657 case IPSECDOI_PROTO_IPCOMP:
658 return ipsecdoi2pfkey_calg(type);
659 default:
660 plog(ASL_LEVEL_ERR,
661 "Invalid ipsec_doi algclass: %u\n", algclass);
662 return ~0;
663 }
664 /*NOTREACHED*/
665 }
666
667 /* SADB_SATYPE -> IPSECDOI_PROTO */
668 u_int
669 pfkey2ipsecdoi_proto(satype)
670 u_int satype;
671 {
672 switch (satype) {
673 case SADB_SATYPE_AH:
674 return IPSECDOI_PROTO_IPSEC_AH;
675 case SADB_SATYPE_ESP:
676 return IPSECDOI_PROTO_IPSEC_ESP;
677 case SADB_X_SATYPE_IPCOMP:
678 return IPSECDOI_PROTO_IPCOMP;
679
680 default:
681 plog(ASL_LEVEL_ERR,
682 "Invalid pfkey proto: %u\n", satype);
683 return ~0;
684 }
685 /*NOTREACHED*/
686 }
687
688 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
689 u_int
690 ipsecdoi2pfkey_mode(mode)
691 u_int mode;
692 {
693 switch (mode) {
694 case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
695 #ifdef ENABLE_NATT
696 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
697 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
698 #endif
699 return IPSEC_MODE_TUNNEL;
700 case IPSECDOI_ATTR_ENC_MODE_TRNS:
701 #ifdef ENABLE_NATT
702 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
703 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
704 #endif
705 return IPSEC_MODE_TRANSPORT;
706 default:
707 plog(ASL_LEVEL_ERR, "Invalid mode type: %u\n", mode);
708 return ~0;
709 }
710 /*NOTREACHED*/
711 }
712
713 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
714 u_int
715 pfkey2ipsecdoi_mode(mode)
716 u_int mode;
717 {
718 switch (mode) {
719 case IPSEC_MODE_TUNNEL:
720 return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
721 case IPSEC_MODE_TRANSPORT:
722 return IPSECDOI_ATTR_ENC_MODE_TRNS;
723 case IPSEC_MODE_ANY:
724 return IPSECDOI_ATTR_ENC_MODE_ANY;
725 default:
726 plog(ASL_LEVEL_ERR, "Invalid mode type: %u\n", mode);
727 return ~0;
728 }
729 /*NOTREACHED*/
730 }
731
732 /* default key length for encryption algorithm */
733 static u_int
734 keylen_aalg(hashtype)
735 u_int hashtype;
736 {
737 int res;
738
739 if (hashtype == 0)
740 return SADB_AALG_NONE;
741
742 res = alg_ipsec_hmacdef_hashlen(hashtype);
743 if (res == -1) {
744 plog(ASL_LEVEL_ERR,
745 "invalid hmac algorithm %u.\n", hashtype);
746 return ~0;
747 }
748 return res;
749 }
750
751 /* default key length for encryption algorithm */
752 static u_int
753 keylen_ealg(enctype, encklen)
754 u_int enctype;
755 int encklen;
756 {
757 int res;
758
759 res = alg_ipsec_encdef_keylen(enctype, encklen);
760 if (res == -1) {
761 plog(ASL_LEVEL_ERR,
762 "invalid encryption algorithm %u.\n", enctype);
763 return ~0;
764 }
765 return res;
766 }
767
768 int
769 pfkey_convertfromipsecdoi(iph2, proto_id, t_id, hashtype,
770 e_type, e_keylen, a_type, a_keylen, flags)
771 phase2_handle_t *iph2;
772 u_int proto_id;
773 u_int t_id;
774 u_int hashtype;
775 u_int *e_type;
776 u_int *e_keylen;
777 u_int *a_type;
778 u_int *a_keylen;
779 u_int *flags;
780 {
781 *flags = 0;
782 switch (proto_id) {
783 case IPSECDOI_PROTO_IPSEC_ESP:
784 if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
785 goto bad;
786 if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
787 goto bad;
788 *e_keylen >>= 3;
789
790 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
791 goto bad;
792 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
793 goto bad;
794 *a_keylen >>= 3;
795
796 if (*e_type == SADB_EALG_NONE) {
797 plog(ASL_LEVEL_ERR, "no ESP algorithm.\n");
798 goto bad;
799 }
800 break;
801
802 case IPSECDOI_PROTO_IPSEC_AH:
803 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
804 goto bad;
805 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
806 goto bad;
807 *a_keylen >>= 3;
808
809 if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
810 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
811 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
812 *a_type = SADB_X_AALG_MD5;
813 *flags |= SADB_X_EXT_OLD;
814 }
815 *e_type = SADB_EALG_NONE;
816 *e_keylen = 0;
817 if (*a_type == SADB_AALG_NONE) {
818 plog(ASL_LEVEL_ERR, "no AH algorithm.\n");
819 goto bad;
820 }
821 break;
822
823 case IPSECDOI_PROTO_IPCOMP:
824 if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
825 goto bad;
826 *e_keylen = 0;
827
828 *flags = SADB_X_EXT_RAWCPI;
829
830 *a_type = SADB_AALG_NONE;
831 *a_keylen = 0;
832 if (*e_type == SADB_X_CALG_NONE) {
833 plog(ASL_LEVEL_ERR, "no IPCOMP algorithm.\n");
834 goto bad;
835 }
836 break;
837
838 default:
839 plog(ASL_LEVEL_ERR, "unknown IPsec protocol.\n");
840 goto bad;
841 }
842
843 return 0;
844
845 bad:
846 errno = EINVAL;
847 return -1;
848 }
849
850 /* called from scheduler */
851 void
852 pfkey_timeover_stub(p)
853 void *p;
854 {
855
856 pfkey_timeover((phase2_handle_t *)p);
857 }
858
859 void
860 pfkey_timeover(iph2)
861 phase2_handle_t *iph2;
862 {
863 plog(ASL_LEVEL_ERR,
864 "%s give up to get IPsec-SA due to time up to wait.\n",
865 saddrwop2str((struct sockaddr *)iph2->dst));
866 SCHED_KILL(iph2->sce);
867
868 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
869 if (iph2->side == INITIATOR)
870 pk_sendeacquire(iph2);
871
872 ike_session_unlink_phase2(iph2);
873
874 return;
875 }
876
877 /*%%%*/
878 /* send getspi message per ipsec protocol per remote address */
879 /*
880 * the local address and remote address in ph1handle are dealed
881 * with destination address and source address respectively.
882 * Because SPI is decided by responder.
883 */
884 int
885 pk_sendgetspi(iph2)
886 phase2_handle_t *iph2;
887 {
888 struct sockaddr_storage *src = NULL, *dst = NULL;
889 u_int satype, mode;
890 struct saprop *pp;
891 struct saproto *pr;
892 u_int32_t minspi, maxspi;
893 int proxy = 0;
894
895 if (iph2->side == INITIATOR) {
896 pp = iph2->proposal;
897 proxy = iph2->ph1->rmconf->support_proxy;
898 } else {
899 pp = iph2->approval;
900 if (iph2->sainfo && iph2->sainfo->id_i)
901 proxy = 1;
902 }
903
904 /* for mobile IPv6 */
905 if (proxy && iph2->src_id && iph2->dst_id &&
906 ipsecdoi_transportmode(pp)) {
907 src = iph2->src_id;
908 dst = iph2->dst_id;
909 } else {
910 src = iph2->src;
911 dst = iph2->dst;
912 }
913
914 for (pr = pp->head; pr != NULL; pr = pr->next) {
915
916 /* validity check */
917 satype = ipsecdoi2pfkey_proto(pr->proto_id);
918 if (satype == ~0) {
919 plog(ASL_LEVEL_ERR,
920 "invalid proto_id %d\n", pr->proto_id);
921 return -1;
922 }
923 /* this works around a bug in Linux kernel where it allocates 4 byte
924 spi's for IPCOMP */
925 else if (satype == SADB_X_SATYPE_IPCOMP) {
926 minspi = 0x100;
927 maxspi = 0xffff;
928 }
929 else {
930 minspi = 0;
931 maxspi = 0;
932 }
933 mode = ipsecdoi2pfkey_mode(pr->encmode);
934 if (mode == ~0) {
935 plog(ASL_LEVEL_ERR,
936 "invalid encmode %d\n", pr->encmode);
937 return -1;
938 }
939
940 plog(ASL_LEVEL_DEBUG, "call pfkey_send_getspi\n");
941 if (pfkey_send_getspi(
942 lcconf->sock_pfkey,
943 satype,
944 mode,
945 dst, /* src of SA */
946 src, /* dst of SA */
947 minspi, maxspi,
948 pr->reqid_in, 0, 0, iph2->seq, 0) < 0) {
949 plog(ASL_LEVEL_ERR,
950 "ipseclib failed send getspi (%s)\n",
951 ipsec_strerror());
952 return -1;
953 }
954
955 plog(ASL_LEVEL_DEBUG,
956 "pfkey GETSPI sent: %s\n",
957 sadbsecas2str(dst, src, satype, 0, mode));
958 }
959
960 return 0;
961 }
962
963 /*
964 * receive GETSPI from kernel.
965 */
966 static int
967 pk_recvgetspi(mhp)
968 caddr_t *mhp;
969 {
970 struct sadb_msg *msg;
971 struct sadb_sa *sa;
972 phase2_handle_t *iph2;
973 struct sockaddr_storage *dst;
974 int proto_id;
975 int allspiok, notfound;
976 struct saprop *pp;
977 struct saproto *pr;
978
979 /* validity check */
980 if (mhp[SADB_EXT_SA] == NULL
981 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
982 plog(ASL_LEVEL_ERR,
983 "Inappropriate sadb getspi message passed.\n");
984 return -1;
985 }
986 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
987 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
988 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
989
990 /* the message has to be processed or not ? */
991 if (msg->sadb_msg_pid != getpid()) {
992 plog(ASL_LEVEL_DEBUG,
993 "%s message is not interesting "
994 "because pid %d is not mine.\n",
995 s_pfkey_type(msg->sadb_msg_type),
996 msg->sadb_msg_pid);
997 return -1;
998 }
999
1000 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq);
1001 if (iph2 == NULL) {
1002 plog(ASL_LEVEL_DEBUG,
1003 "Seq %d of %s message not interesting.\n",
1004 msg->sadb_msg_seq,
1005 s_pfkey_type(msg->sadb_msg_type));
1006 return -1;
1007 }
1008
1009 if (iph2->is_dying) {
1010 plog(ASL_LEVEL_ERR,
1011 "Status mismatch Phase 2 dying (db:%d)\n",
1012 iph2->status);
1013 return -1;
1014 }
1015
1016 switch (iph2->version) {
1017 case ISAKMP_VERSION_NUMBER_IKEV1:
1018 if (iph2->status != IKEV1_STATE_QUICK_I_GETSPISENT &&
1019 iph2->status != IKEV1_STATE_QUICK_R_GETSPISENT) {
1020 plog(ASL_LEVEL_ERR, "Status mismatch (db:%d)\n", iph2->status);
1021 return -1;
1022 }
1023 // check the underlying iph2->ph1
1024 if (!iph2->ph1) {
1025 if (!ike_session_update_ph2_ph1bind(iph2)) {
1026 plog(ASL_LEVEL_ERR,
1027 "Can't proceed with getspi for %s. no suitable ISAKMP-SA found \n",
1028 saddrwop2str((struct sockaddr *)iph2->dst));
1029 ike_session_unlink_phase2(iph2);
1030 return -1;
1031 }
1032 }
1033 break;
1034 default:
1035 plog(ASL_LEVEL_ERR, "Internal error: invalid IKE major version %d\n", iph2->version);
1036 return -1;
1037 }
1038
1039 /* set SPI, and check to get all spi whether or not */
1040 allspiok = 1;
1041 notfound = 1;
1042 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1043 pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
1044
1045 for (pr = pp->head; pr != NULL; pr = pr->next) {
1046 if (pr->proto_id == proto_id && pr->spi == 0) {
1047 pr->spi = sa->sadb_sa_spi;
1048 notfound = 0;
1049 plog(ASL_LEVEL_DEBUG,
1050 "pfkey GETSPI succeeded: %s\n",
1051 sadbsecas2str(iph2->dst, iph2->src,
1052 msg->sadb_msg_satype,
1053 sa->sadb_sa_spi,
1054 ipsecdoi2pfkey_mode(pr->encmode)));
1055 }
1056 if (pr->spi == 0)
1057 allspiok = 0; /* not get all spi */
1058 }
1059
1060 if (notfound) {
1061 plog(ASL_LEVEL_ERR,
1062 "Get spi for unknown address %s\n",
1063 saddrwop2str((struct sockaddr *)iph2->dst));
1064 ike_session_unlink_phase2(iph2);
1065 return -1;
1066 }
1067
1068 if (allspiok) {
1069 switch (iph2->version) {
1070 case ISAKMP_VERSION_NUMBER_IKEV1:
1071 if (isakmp_post_getspi(iph2) < 0) {
1072 plog(ASL_LEVEL_ERR, "IKEv1 post getspi failed.\n");
1073 ike_session_unlink_phase2(iph2);
1074 iph2 = NULL;
1075 return -1;
1076 }
1077 break;
1078 }
1079 }
1080 return 0;
1081 }
1082
1083 /*
1084 * set inbound SA
1085 */
1086 int
1087 pk_sendupdate(iph2)
1088 phase2_handle_t *iph2;
1089 {
1090 struct saproto *pr;
1091 struct sockaddr_storage *src = NULL, *dst = NULL;
1092 u_int e_type, e_keylen, a_type, a_keylen, flags;
1093 u_int satype, mode;
1094 u_int64_t lifebyte = 0;
1095 u_int wsize = 4; /* XXX static size of window */
1096 int proxy = 0;
1097 struct ph2natt natt;
1098 int authtype;
1099
1100 /* sanity check */
1101 if (iph2->approval == NULL) {
1102 plog(ASL_LEVEL_ERR,
1103 "No approved SAs found.\n");
1104 }
1105
1106 if (iph2->side == INITIATOR)
1107 proxy = iph2->ph1->rmconf->support_proxy;
1108 else if (iph2->sainfo && iph2->sainfo->id_i)
1109 proxy = 1;
1110
1111 /* for mobile IPv6 */
1112 if (proxy && iph2->src_id && iph2->dst_id &&
1113 ipsecdoi_transportmode(iph2->approval)) {
1114 src = iph2->src_id;
1115 dst = iph2->dst_id;
1116 } else {
1117 src = iph2->src;
1118 dst = iph2->dst;
1119 }
1120
1121 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1122 /* validity check */
1123 satype = ipsecdoi2pfkey_proto(pr->proto_id);
1124 if (satype == ~0) {
1125 plog(ASL_LEVEL_ERR,
1126 "Invalid proto_id %d\n", pr->proto_id);
1127 return -1;
1128 }
1129 else if (satype == SADB_X_SATYPE_IPCOMP) {
1130 /* IPCOMP has no replay window */
1131 wsize = 0;
1132 }
1133 #ifdef ENABLE_SAMODE_UNSPECIFIED
1134 mode = IPSEC_MODE_ANY;
1135 #else
1136 mode = ipsecdoi2pfkey_mode(pr->encmode);
1137 if (mode == ~0) {
1138 plog(ASL_LEVEL_ERR,
1139 "Invalid encmode %d\n", pr->encmode);
1140 return -1;
1141 }
1142 #endif
1143
1144 /* set algorithm type and key length */
1145 e_keylen = pr->head->encklen;
1146 authtype = pr->head->authtype;
1147 a_keylen = 0;
1148 if (pfkey_convertfromipsecdoi(
1149 iph2,
1150 pr->proto_id,
1151 pr->head->trns_id,
1152 authtype,
1153 &e_type, &e_keylen,
1154 &a_type, &a_keylen, &flags) < 0)
1155 return -1;
1156
1157 #if 0
1158 lifebyte = iph2->approval->lifebyte * 1024,
1159 #else
1160 lifebyte = 0;
1161 #endif
1162
1163 #ifdef ENABLE_NATT
1164 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_update\n");
1165 plog(ASL_LEVEL_DEBUG, "call pfkey_send_update: e_type %d, e_klen %d, a_type %d, a_klen %d\n",
1166 e_type, e_keylen, a_type, a_keylen);
1167 if (pr->udp_encap) {
1168 memset (&natt, 0, sizeof (natt));
1169 natt.sport = extract_port (iph2->ph1->remote);
1170 flags |= SADB_X_EXT_NATT;
1171 if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
1172 mode == IPSEC_MODE_TRANSPORT &&
1173 src->ss_family == AF_INET) {
1174 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
1175 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1176 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1177 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1178 }
1179 } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
1180 if (iph2->ph1->rmconf->natt_keepalive == TRUE)
1181 flags |= SADB_X_EXT_NATT_KEEPALIVE;
1182 } else {
1183 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1184 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1185 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1186 }
1187 }
1188 } else {
1189 memset (&natt, 0, sizeof (natt));
1190 }
1191
1192 if (pfkey_send_update(
1193 lcconf->sock_pfkey,
1194 satype,
1195 mode,
1196 dst,
1197 src,
1198 pr->spi,
1199 pr->reqid_in,
1200 wsize,
1201 pr->keymat->v,
1202 e_type, e_keylen, a_type, a_keylen, flags,
1203 0, lifebyte, iph2->approval->lifetime, 0,
1204 iph2->seq, natt.sport, 0) < 0) {
1205 plog(ASL_LEVEL_ERR,
1206 "libipsec failed send update (%s)\n",
1207 ipsec_strerror());
1208 return -1;
1209 }
1210 #else
1211 plog(ASL_LEVEL_DEBUG, "call pfkey_send_update\n");
1212 if (pfkey_send_update(
1213 lcconf->sock_pfkey,
1214 satype,
1215 mode,
1216 dst,
1217 src,
1218 pr->spi,
1219 pr->reqid_in,
1220 wsize,
1221 pr->keymat->v,
1222 e_type, e_keylen, a_type, a_keylen, flags,
1223 0, lifebyte, iph2->approval->lifetime, 0,
1224 iph2->seq, 0, 0) < 0) {
1225 plog(ASL_LEVEL_ERR,
1226 "libipsec failed send update (%s)\n",
1227 ipsec_strerror());
1228 return -1;
1229 }
1230 #endif /* ENABLE_NATT */
1231
1232
1233 }
1234
1235 return 0;
1236 }
1237
1238 static int
1239 pk_recvupdate(mhp)
1240 caddr_t *mhp;
1241 {
1242 struct sadb_msg *msg;
1243 struct sadb_sa *sa;
1244 struct sockaddr_storage *src, *dst;
1245 phase2_handle_t *iph2;
1246 u_int proto_id, encmode, sa_mode;
1247 int incomplete = 0;
1248 struct saproto *pr;
1249
1250 /* ignore this message because of local test mode. */
1251 if (f_local)
1252 return 0;
1253
1254 /* sanity check */
1255 if (mhp[0] == NULL
1256 || mhp[SADB_EXT_SA] == NULL
1257 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1258 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1259 plog(ASL_LEVEL_ERR,
1260 "inappropriate sadb update message passed.\n");
1261 return -1;
1262 }
1263 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1264 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1265 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1266 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1267
1268 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1269 ? IPSEC_MODE_ANY
1270 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1271
1272 /* the message has to be processed or not ? */
1273 if (msg->sadb_msg_pid != getpid()) {
1274 plog(ASL_LEVEL_DEBUG,
1275 "%s message is not interesting "
1276 "because pid %d is not mine.\n",
1277 s_pfkey_type(msg->sadb_msg_type),
1278 msg->sadb_msg_pid);
1279 return -1;
1280 }
1281
1282 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq);
1283 if (iph2 == NULL) {
1284 plog(ASL_LEVEL_DEBUG,
1285 "Seq %d of %s message not interesting.\n",
1286 msg->sadb_msg_seq,
1287 s_pfkey_type(msg->sadb_msg_type));
1288 return -1;
1289 }
1290
1291 if (iph2->is_dying) {
1292 plog(ASL_LEVEL_ERR,
1293 "Status mismatch Phase 2 dying (db:%d)\n",
1294 iph2->status);
1295 return -1;
1296 }
1297 if (iph2->status != IKEV1_STATE_QUICK_I_ADDSA &&
1298 iph2->status != IKEV1_STATE_QUICK_R_ADDSA) {
1299 plog(ASL_LEVEL_ERR,
1300 "Status mismatch (db:%d)\n",
1301 iph2->status);
1302 return -1;
1303 }
1304
1305 /* check to complete all keys ? */
1306 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1307 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1308 if (proto_id == ~0) {
1309 plog(ASL_LEVEL_ERR,
1310 "invalid proto_id %d\n", msg->sadb_msg_satype);
1311 return -1;
1312 }
1313 encmode = pfkey2ipsecdoi_mode(sa_mode);
1314 if (encmode == ~0) {
1315 plog(ASL_LEVEL_ERR,
1316 "invalid encmode %d\n", sa_mode);
1317 return -1;
1318 }
1319
1320 if (pr->proto_id == proto_id
1321 && pr->spi == sa->sadb_sa_spi) {
1322 pr->ok = 1;
1323 plog(ASL_LEVEL_DEBUG,
1324 "pfkey UPDATE succeeded: %s\n",
1325 sadbsecas2str(iph2->dst, iph2->src,
1326 msg->sadb_msg_satype,
1327 sa->sadb_sa_spi,
1328 sa_mode));
1329
1330 plog(ASL_LEVEL_NOTICE,
1331 "IPsec-SA established (update): satype=%u spi=%#x mode=%u\n",
1332 msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
1333 plog(ASL_LEVEL_DEBUG,
1334 "IPsec-SA established (update): %s\n",
1335 sadbsecas2str(iph2->dst, iph2->src,
1336 msg->sadb_msg_satype, sa->sadb_sa_spi,
1337 sa_mode));
1338 }
1339
1340 if (pr->ok == 0)
1341 incomplete = 1;
1342 }
1343
1344 if (incomplete)
1345 return 0;
1346
1347 /* turn off the timer for calling pfkey_timeover() */
1348 SCHED_KILL(iph2->sce);
1349
1350 /* update status */
1351 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_ESTABLISHED);
1352
1353 if (iph2->side == INITIATOR) {
1354 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1355 IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC,
1356 CONSTSTR("Initiator, Quick-Mode"),
1357 CONSTSTR(NULL));
1358 } else {
1359 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1360 IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC,
1361 CONSTSTR("Responder, Quick-Mode"),
1362 CONSTSTR(NULL));
1363 }
1364
1365 ike_session_ph2_established(iph2);
1366
1367 IPSECLOGASLMSG("IPSec Phase 2 established (Initiated by %s).\n",
1368 (iph2->side == INITIATOR)? "me" : "peer");
1369
1370 #ifdef ENABLE_STATS
1371 gettimeofday(&iph2->end, NULL);
1372 plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f",
1373 "Phase 2", "quick", timedelta(&iph2->start, &iph2->end));
1374 #endif
1375
1376 /* count up */
1377 if (iph2->ph1)
1378 iph2->ph1->ph2cnt++;
1379
1380 /* turn off schedule */
1381 if (iph2->scr)
1382 SCHED_KILL(iph2->scr);
1383
1384 /*
1385 * since we are going to reuse the phase2 handler, we need to
1386 * remain it and refresh all the references between ph1 and ph2 to use.
1387 */
1388 ike_session_unbindph12(iph2); //%%%%% fix this
1389
1390 iph2->sce = sched_new(iph2->approval->lifetime,
1391 isakmp_ph2expire_stub, iph2);
1392
1393 plog(ASL_LEVEL_DEBUG, "===\n");
1394 return 0;
1395 }
1396
1397 /*
1398 * set outbound SA
1399 */
1400 int
1401 pk_sendadd(iph2)
1402 phase2_handle_t *iph2;
1403 {
1404 struct saproto *pr;
1405 struct sockaddr_storage *src = NULL, *dst = NULL;
1406 u_int e_type, e_keylen, a_type, a_keylen, flags;
1407 u_int satype, mode;
1408 u_int64_t lifebyte = 0;
1409 u_int wsize = 4; /* XXX static size of window */
1410 int proxy = 0;
1411 struct ph2natt natt;
1412 int authtype;
1413
1414 /* sanity check */
1415 if (iph2->approval == NULL) {
1416 plog(ASL_LEVEL_ERR,
1417 "no approvaled SAs found.\n");
1418 }
1419
1420 if (iph2->side == INITIATOR)
1421 proxy = iph2->ph1->rmconf->support_proxy;
1422 else if (iph2->sainfo && iph2->sainfo->id_i)
1423 proxy = 1;
1424
1425 /* for mobile IPv6 */
1426 if (proxy && iph2->src_id && iph2->dst_id &&
1427 ipsecdoi_transportmode(iph2->approval)) {
1428 src = iph2->src_id;
1429 dst = iph2->dst_id;
1430 } else {
1431 src = iph2->src;
1432 dst = iph2->dst;
1433 }
1434
1435 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1436 /* validity check */
1437 satype = ipsecdoi2pfkey_proto(pr->proto_id);
1438 if (satype == ~0) {
1439 plog(ASL_LEVEL_ERR,
1440 "invalid proto_id %d\n", pr->proto_id);
1441 return -1;
1442 }
1443 else if (satype == SADB_X_SATYPE_IPCOMP) {
1444 /* no replay window for IPCOMP */
1445 wsize = 0;
1446 }
1447 #ifdef ENABLE_SAMODE_UNSPECIFIED
1448 mode = IPSEC_MODE_ANY;
1449 #else
1450 mode = ipsecdoi2pfkey_mode(pr->encmode);
1451 if (mode == ~0) {
1452 plog(ASL_LEVEL_ERR,
1453 "invalid encmode %d\n", pr->encmode);
1454 return -1;
1455 }
1456 #endif
1457
1458 /* set algorithm type and key length */
1459 e_keylen = pr->head->encklen;
1460 authtype = pr->head->authtype;
1461 a_keylen = 0;
1462 if (pfkey_convertfromipsecdoi(
1463 iph2,
1464 pr->proto_id,
1465 pr->head->trns_id,
1466 authtype,
1467 &e_type, &e_keylen,
1468 &a_type, &a_keylen, &flags) < 0)
1469 return -1;
1470
1471 #if 0
1472 lifebyte = iph2->approval->lifebyte * 1024,
1473 #else
1474 lifebyte = 0;
1475 #endif
1476
1477 #ifdef ENABLE_NATT
1478 //plog(ASL_LEVEL_DEBUG, "call pfkey_send_add\n");
1479 plog(ASL_LEVEL_DEBUG, "call pfkey_send_add: e_type %d, e_klen %d, a_type %d, a_klen %d\n",
1480 e_type, e_keylen, a_type, a_keylen);
1481
1482 if (pr->udp_encap) {
1483 memset (&natt, 0, sizeof (natt));
1484 natt.dport = extract_port (iph2->ph1->remote);
1485 flags |= SADB_X_EXT_NATT;
1486 if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
1487 mode == IPSEC_MODE_TRANSPORT &&
1488 src->ss_family == AF_INET) {
1489 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
1490 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1491 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1492 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1493 }
1494 } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
1495 if (iph2->ph1->rmconf->natt_keepalive == TRUE)
1496 flags |= SADB_X_EXT_NATT_KEEPALIVE;
1497 } else {
1498 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1499 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1500 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1501 }
1502 }
1503 } else {
1504 memset (&natt, 0, sizeof (natt));
1505
1506 /* Remove port information, that SA doesn't use it */
1507 //set_port(src, 0);
1508 //set_port(dst, 0);
1509 }
1510
1511 if (pfkey_send_add(
1512 lcconf->sock_pfkey,
1513 satype,
1514 mode,
1515 src,
1516 dst,
1517 pr->spi_p,
1518 pr->reqid_out,
1519 wsize,
1520 pr->keymat_p->v,
1521 e_type, e_keylen, a_type, a_keylen, flags,
1522 0, lifebyte, iph2->approval->lifetime, 0,
1523 iph2->seq,natt.dport, 0) < 0) {
1524 plog(ASL_LEVEL_ERR,
1525 "libipsec failed send add (%s)\n",
1526 ipsec_strerror());
1527 return -1;
1528 }
1529 #else
1530 plog(ASL_LEVEL_DEBUG, "call pfkey_send_add\n");
1531
1532 /* Remove port information, it is not used without NAT-T */
1533 //set_port(src, 0);
1534 //set_port(dst, 0);
1535
1536 if (pfkey_send_add(
1537 lcconf->sock_pfkey,
1538 satype,
1539 mode,
1540 src,
1541 dst,
1542 pr->spi_p,
1543 pr->reqid_out,
1544 wsize,
1545 pr->keymat_p->v,
1546 e_type, e_keylen, a_type, a_keylen, flags,
1547 0, lifebyte, iph2->approval->lifetime, 0,
1548 iph2->seq, 0, 0) < 0) {
1549 plog(ASL_LEVEL_ERR,
1550 "libipsec failed send add (%s)\n",
1551 ipsec_strerror());
1552 return -1;
1553 }
1554 #endif /* ENABLE_NATT */
1555 }
1556
1557 return 0;
1558 }
1559
1560 static int
1561 pk_recvadd(mhp)
1562 caddr_t *mhp;
1563 {
1564 struct sadb_msg *msg;
1565 struct sadb_sa *sa;
1566 struct sockaddr_storage *src, *dst;
1567 phase2_handle_t *iph2;
1568 u_int sa_mode;
1569
1570 /* ignore this message because of local test mode. */
1571 if (f_local)
1572 return 0;
1573
1574 /* sanity check */
1575 if (mhp[0] == NULL
1576 || mhp[SADB_EXT_SA] == NULL
1577 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1578 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1579 plog(ASL_LEVEL_ERR,
1580 "inappropriate sadb add message passed.\n");
1581 return -1;
1582 }
1583 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1584 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1585 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1586 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1587
1588 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1589 ? IPSEC_MODE_ANY
1590 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1591
1592 /* the message has to be processed or not ? */
1593 if (msg->sadb_msg_pid != getpid()) {
1594 plog(ASL_LEVEL_DEBUG,
1595 "%s message is not interesting "
1596 "because pid %d is not mine.\n",
1597 s_pfkey_type(msg->sadb_msg_type),
1598 msg->sadb_msg_pid);
1599 return -1;
1600 }
1601
1602 iph2 = ike_session_getph2byseq(msg->sadb_msg_seq);
1603 if (iph2 == NULL) {
1604 plog(ASL_LEVEL_DEBUG,
1605 "seq %d of %s message not interesting.\n",
1606 msg->sadb_msg_seq,
1607 s_pfkey_type(msg->sadb_msg_type));
1608 return -1;
1609 }
1610 /*
1611 * NOTE don't update any status of phase2 handle
1612 * because they must be updated by SADB_UPDATE message
1613 */
1614
1615 plog(ASL_LEVEL_NOTICE,
1616 "IPsec-SA established (add): satype=%u spi=%#x mode=%u\n",
1617 msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
1618 plog(ASL_LEVEL_DEBUG,
1619 "IPsec-SA established (add): %s\n",
1620 sadbsecas2str(iph2->src, iph2->dst,
1621 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1622
1623 ike_session_cleanup_other_established_ph2s(iph2->parent_session, iph2);
1624
1625 #ifdef ENABLE_VPNCONTROL_PORT
1626 {
1627 vpncontrol_notify_phase_change(0, FROM_LOCAL, NULL, iph2);
1628 }
1629 #endif
1630
1631 plog(ASL_LEVEL_DEBUG, "===\n");
1632 return 0;
1633 }
1634
1635 static int
1636 pk_recvexpire(mhp)
1637 caddr_t *mhp;
1638 {
1639 struct sadb_msg *msg;
1640 struct sadb_sa *sa;
1641 struct sockaddr_storage *src, *dst;
1642 phase2_handle_t *iph2;
1643 u_int proto_id, sa_mode;
1644
1645 /* sanity check */
1646 if (mhp[0] == NULL
1647 || mhp[SADB_EXT_SA] == NULL
1648 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1649 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1650 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1651 && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1652 plog(ASL_LEVEL_ERR,
1653 "inappropriate sadb expire message passed.\n");
1654 return -1;
1655 }
1656 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1657 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1658 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1659 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1660
1661 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1662 ? IPSEC_MODE_ANY
1663 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1664
1665 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1666 if (proto_id == ~0) {
1667 plog(ASL_LEVEL_ERR,
1668 "invalid proto_id %d\n", msg->sadb_msg_satype);
1669 return -1;
1670 }
1671
1672 plog(ASL_LEVEL_NOTICE,
1673 "IPsec-SA expired: satype=%u spi=%#x mode=%u\n",
1674 msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
1675 plog(ASL_LEVEL_DEBUG,
1676 "IPsec-SA expired: %s\n",
1677 sadbsecas2str(src, dst,
1678 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1679
1680 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1681 if (iph2 == NULL) {
1682 /*
1683 * Ignore it because two expire messages are come up.
1684 * phase2 handler has been deleted already when 2nd message
1685 * is received.
1686 */
1687 plog(ASL_LEVEL_DEBUG,
1688 "no such a SA found: %s\n",
1689 sadbsecas2str(src, dst,
1690 msg->sadb_msg_satype, sa->sadb_sa_spi,
1691 sa_mode));
1692 return 0;
1693 }
1694 if (iph2->is_dying || !FSM_STATE_IS_ESTABLISHED(iph2->status)) {
1695 /*
1696 * If the status is not equal to PHASE2ST_ESTABLISHED,
1697 * racoon ignores this expire message. There are two reason.
1698 * One is that the phase 2 probably starts because there is
1699 * a potential that racoon receives the acquire message
1700 * without receiving a expire message. Another is that racoon
1701 * may receive the multiple expire messages from the kernel.
1702 */
1703 plog(ASL_LEVEL_WARNING,
1704 "The expire message is received but the handler %s (status = 0x%x).\n",
1705 iph2->is_dying ? "is dying" : "has not been established", iph2->status);
1706 return 0;
1707 }
1708
1709 /* turn off the timer for calling isakmp_ph2expire() */
1710 SCHED_KILL(iph2->sce);
1711
1712 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
1713
1714 /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
1715 /* allocate buffer for status management of pfkey message */
1716 if (iph2->side == INITIATOR &&
1717 !ike_session_has_other_established_ph2(iph2->parent_session, iph2) &&
1718 !ike_session_drop_rekey(iph2->parent_session, IKE_SESSION_REKEY_TYPE_PH2)) {
1719
1720 ike_session_initph2(iph2);
1721
1722 /* start isakmp initiation by using ident exchange */
1723 if (isakmp_post_acquire(iph2) < 0) {
1724 plog(ASL_LEVEL_ERR,
1725 "failed to begin ipsec sa "
1726 "re-negotiation.\n");
1727 ike_session_unlink_phase2(iph2);
1728 return -1;
1729 }
1730
1731 return 0;
1732 /*NOTREACHED*/
1733 }
1734
1735
1736 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1737 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't
1738 * manage IPsec SA, so delete the list */
1739 ike_session_unlink_phase2(iph2);
1740
1741 return 0;
1742 }
1743
1744 static int
1745 pk_recvacquire(mhp)
1746 caddr_t *mhp;
1747 {
1748 struct sadb_msg *msg;
1749 struct sadb_x_policy *xpl;
1750 struct secpolicy *sp_out = NULL, *sp_in = NULL;
1751 phase2_handle_t *iph2;
1752 struct sockaddr_storage *src, *dst;
1753 ike_session_t *session = NULL;
1754 struct remoteconf *rmconf;
1755
1756 /* ignore this message because of local test mode. */
1757 if (f_local)
1758 return 0;
1759
1760 /* sanity check */
1761 if (mhp[0] == NULL
1762 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1763 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1764 || mhp[SADB_X_EXT_POLICY] == NULL) {
1765 plog(ASL_LEVEL_ERR,
1766 "inappropriate sadb acquire message passed.\n");
1767 return -1;
1768 }
1769 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1770 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1771 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1772 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1773
1774 /* ignore if type is not IPSEC_POLICY_IPSEC */
1775 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1776 plog(ASL_LEVEL_DEBUG,
1777 "ignore ACQUIRE message. type is not IPsec.\n");
1778 return 0;
1779 }
1780
1781 /* ignore it if src is multicast address */
1782 {
1783 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1784
1785 if ((sa->ss_family == AF_INET
1786 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
1787 #ifdef INET6
1788 || (sa->ss_family == AF_INET6
1789 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
1790 #endif
1791 ) {
1792 plog(ASL_LEVEL_DEBUG,
1793 "ignore due to multicast address: %s.\n",
1794 saddrwop2str((struct sockaddr *)sa));
1795 return 0;
1796 }
1797 }
1798
1799 /* ignore, if we do not listen on source address */
1800 {
1801 /* reasons behind:
1802 * - if we'll contact peer from address we do not listen -
1803 * we will be unable to complete negotiation;
1804 * - if we'll negotiate using address we're listening -
1805 * remote peer will send packets to address different
1806 * than one in the policy, so kernel will drop them;
1807 * => therefore this acquire is not for us! --Aidas
1808 */
1809 // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1810 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1811 struct myaddrs *p;
1812 int do_listen = 0;
1813 char * str;
1814 for (p = lcconf->myaddrs; p; p = p->next) {
1815 str = saddr2str((struct sockaddr *)p->addr);
1816 plog(ASL_LEVEL_DEBUG,
1817 "checking listen addrs: %s", str);
1818
1819 if (!cmpsaddrwop(p->addr, sa)) {
1820 do_listen = 1;
1821 break;
1822 }
1823 }
1824
1825 if (!do_listen) {
1826 plog(ASL_LEVEL_DEBUG,
1827 "ignore because do not listen on source address : %s.\n",
1828 saddrwop2str((struct sockaddr *)sa));
1829 return 0;
1830 }
1831 }
1832
1833 /*
1834 * If there is a phase 2 handler against the policy identifier in
1835 * the acquire message, and if
1836 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1837 * should ignore such a acquire message because the phase 2
1838 * is just negotiating.
1839 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1840 * has to process such a acquire message because racoon may
1841 * have lost the expire message.
1842 */
1843 iph2 = ike_session_getph2byid(src, dst, xpl->sadb_x_policy_id);
1844 if (iph2 != NULL) {
1845 session = iph2->parent_session;
1846 if (!FSM_STATE_IS_ESTABLISHED(iph2->status)) {
1847 plog(ASL_LEVEL_DEBUG,
1848 "ignore the acquire because ph2 found\n");
1849 return -1;
1850 }
1851 if (FSM_STATE_IS_EXPIRED(iph2->status))
1852 iph2 = NULL;
1853 /*FALLTHROUGH*/
1854 }
1855
1856 /* search for proper policyindex */
1857 sp_out = getspbyspid(xpl->sadb_x_policy_id);
1858 if (sp_out == NULL) {
1859 plog(ASL_LEVEL_ERR, "no policy found: id:%d.\n",
1860 xpl->sadb_x_policy_id);
1861 return -1;
1862 }
1863 plog(ASL_LEVEL_DEBUG,
1864 "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1865
1866 /* get inbound policy */
1867 {
1868 struct policyindex spidx;
1869
1870 spidx.dir = IPSEC_DIR_INBOUND;
1871 memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1872 memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1873 spidx.prefs = sp_out->spidx.prefd;
1874 spidx.prefd = sp_out->spidx.prefs;
1875 spidx.ul_proto = sp_out->spidx.ul_proto;
1876
1877 sp_in = getsp(&spidx);
1878 if (sp_in) {
1879 plog(ASL_LEVEL_DEBUG,
1880 "Suitable inbound SP found: %s.\n",
1881 spidx2str(&sp_in->spidx));
1882 } else {
1883 plog(ASL_LEVEL_NOTICE,
1884 "No in-bound policy found: %s\n",
1885 spidx2str(&spidx));
1886 }
1887 }
1888
1889 /* allocate a phase 2 */
1890 rmconf = getrmconf(dst);
1891 if (rmconf == NULL) {
1892 plog(ASL_LEVEL_ERR, "No configuration found for %s.\n",
1893 saddrwop2str((struct sockaddr *)dst));
1894 return -1;
1895 }
1896
1897 iph2 = ike_session_newph2(rmconf->ike_version, PHASE2_TYPE_SA);
1898 if (iph2 == NULL) {
1899 plog(ASL_LEVEL_ERR,
1900 "Failed to allocate Phase 2 entry.\n");
1901 return -1;
1902 }
1903 plog(ASL_LEVEL_DEBUG, "Got new Phase 2 version %d\n", iph2->version);
1904 iph2->version = rmconf->ike_version;
1905 iph2->side = INITIATOR;
1906 iph2->spid = xpl->sadb_x_policy_id;
1907
1908 iph2->satype = msg->sadb_msg_satype;
1909 iph2->seq = msg->sadb_msg_seq;
1910 vpncontrol_set_nat64_prefix(&iph2->nat64_prefix);
1911 /* set end addresses of SA */
1912 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1913 iph2->src = dupsaddr(ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
1914 if (iph2->src == NULL) {
1915 ike_session_delph2(iph2);
1916 return -1;
1917 }
1918 iph2->dst = dupsaddr(ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
1919 if (iph2->dst == NULL) {
1920 ike_session_delph2(iph2);
1921 return -1;
1922 }
1923
1924 if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1) {
1925 fsm_set_state(&iph2->status, IKEV1_STATE_QUICK_I_START);
1926 }
1927
1928 plog(ASL_LEVEL_DEBUG,
1929 "new acquire %s\n", spidx2str(&sp_out->spidx));
1930
1931 /* get sainfo */
1932 {
1933 vchar_t *idsrc, *iddst;
1934
1935 idsrc = ipsecdoi_sockaddr2id(&sp_out->spidx.src,
1936 sp_out->spidx.prefs, sp_out->spidx.ul_proto);
1937 if (idsrc == NULL) {
1938 plog(ASL_LEVEL_ERR,
1939 "failed to get ID for %s\n",
1940 spidx2str(&sp_out->spidx));
1941 ike_session_delph2(iph2);
1942 return -1;
1943 }
1944 iddst = ipsecdoi_sockaddr2id(&sp_out->spidx.dst,
1945 sp_out->spidx.prefd, sp_out->spidx.ul_proto);
1946 if (iddst == NULL) {
1947 plog(ASL_LEVEL_ERR,
1948 "failed to get ID for %s\n",
1949 spidx2str(&sp_out->spidx));
1950 vfree(idsrc);
1951 ike_session_delph2(iph2);
1952 return -1;
1953 }
1954 iph2->sainfo = getsainfo(idsrc, iddst, NULL, 0);
1955 vfree(idsrc);
1956 vfree(iddst);
1957 if (iph2->sainfo == NULL) {
1958 plog(ASL_LEVEL_ERR,
1959 "failed to get sainfo.\n");
1960 ike_session_delph2(iph2);
1961 return -1;
1962 /* XXX should use the algorithm list from register message */
1963 }
1964 }
1965 retain_sainfo(iph2->sainfo);
1966
1967 if (set_proposal_from_policy(iph2, sp_out, sp_in) < 0) {
1968 plog(ASL_LEVEL_ERR,
1969 "failed to create saprop.\n");
1970 ike_session_delph2(iph2);
1971 return -1;
1972 }
1973
1974 if (session == NULL)
1975 session = ike_session_get_session(iph2->src, iph2->dst, 1, NULL);
1976 if (session == NULL)
1977 fatal_error(-1);
1978
1979 if (ike_session_link_phase2(session, iph2))
1980 fatal_error(-1); //????? fix ???
1981
1982 /* start isakmp initiation by using ident exchange */
1983 /* XXX should be looped if there are multiple phase 2 handler. */
1984 if (isakmp_post_acquire(iph2) < 0) {
1985 plog(ASL_LEVEL_ERR,
1986 "failed to begin ipsec sa negotiation.\n");
1987 goto err;
1988 }
1989
1990 #if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1991 if ( lcconf->vt == NULL){
1992 if (!(lcconf->vt = vproc_transaction_begin(NULL)))
1993 plog(ASL_LEVEL_ERR,
1994 "vproc_transaction_begin returns NULL.\n");
1995 }
1996 #endif // !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1997
1998
1999 return 0;
2000
2001 err:
2002 ike_session_unlink_phase2(iph2);
2003 return -1;
2004 }
2005
2006 static int
2007 pk_recvdelete(mhp)
2008 caddr_t *mhp;
2009 {
2010 struct sadb_msg *msg;
2011 struct sadb_sa *sa;
2012 struct sockaddr_storage *src, *dst;
2013 phase2_handle_t *iph2 = NULL;
2014 u_int proto_id;
2015
2016 /* ignore this message because of local test mode. */
2017 if (f_local)
2018 return 0;
2019
2020 /* sanity check */
2021 if (mhp[0] == NULL
2022 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2023 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
2024 plog(ASL_LEVEL_ERR,
2025 "inappropriate sadb delete message passed.\n");
2026 return -1;
2027 }
2028 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2029 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
2030 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
2031 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
2032
2033 /* the message has to be processed or not ? */
2034 if (msg->sadb_msg_pid == getpid()) {
2035 plog(ASL_LEVEL_DEBUG,
2036 "%s message is not interesting "
2037 "because the message was originated by me.\n",
2038 s_pfkey_type(msg->sadb_msg_type));
2039 return -1;
2040 }
2041
2042 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
2043 if (proto_id == ~0) {
2044 plog(ASL_LEVEL_ERR,
2045 "invalid proto_id %d\n", msg->sadb_msg_satype);
2046 return -1;
2047 }
2048
2049 plog(ASL_LEVEL_DEBUG, "SADB delete message: proto-id %d\n", proto_id);
2050 plog(ASL_LEVEL_DEBUG, "src: %s\n", saddr2str((struct sockaddr *)src));
2051 plog(ASL_LEVEL_DEBUG, "dst: %s\n", saddr2str((struct sockaddr *)dst));
2052
2053 if (!sa) {
2054 ike_session_deleteallph2(src, dst, proto_id);
2055 ike_session_deleteallph1(src, dst);
2056 return 0;
2057 }
2058
2059 iph2 = ike_session_getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
2060 if (iph2 == NULL) {
2061 /* ignore */
2062 plog(ASL_LEVEL_ERR,
2063 "no iph2 found: %s\n",
2064 sadbsecas2str(src, dst, msg->sadb_msg_satype,
2065 sa->sadb_sa_spi, IPSEC_MODE_ANY));
2066 return 0;
2067 }
2068
2069 plog(ASL_LEVEL_ERR,
2070 "pfkey DELETE received: %s\n",
2071 sadbsecas2str(iph2->src, iph2->dst,
2072 msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
2073
2074 /* send delete information */
2075
2076 /* TODO: Look into handling this properly. Currently, if we get here, we can end up sending delete messages to the server for their own SAs, which is rejected. */
2077 /*if (FSM_STATE_IS_ESTABLISHED(iph2->status))
2078 isakmp_info_send_d2(iph2);
2079
2080 ike_session_cleanup_ph1s_by_ph2(iph2);
2081 ike_session_unlink_phase2(iph2);*/
2082
2083 return 0;
2084 }
2085
2086 static int
2087 pk_recvflush(mhp)
2088 caddr_t *mhp;
2089 {
2090 /* sanity check */
2091 if (mhp[0] == NULL) {
2092 plog(ASL_LEVEL_ERR,
2093 "inappropriate sadb flush message passed.\n");
2094 return -1;
2095 }
2096
2097 ike_session_flush_all_phase2(false);
2098 ike_session_flush_all_phase1(false);
2099
2100 return 0;
2101 }
2102
2103 static int
2104 getsadbpolicy(policy0, policylen0, type, iph2)
2105 caddr_t *policy0;
2106 int *policylen0, type;
2107 phase2_handle_t *iph2;
2108 {
2109 struct policyindex *spidx = iph2->spidx_gen;
2110 struct sadb_x_policy *xpl;
2111 struct sadb_x_ipsecrequest *xisr;
2112 struct saproto *pr;
2113 caddr_t policy, p;
2114 int policylen;
2115 int xisrlen;
2116 u_int satype, mode;
2117
2118 /* get policy buffer size */
2119 policylen = sizeof(struct sadb_x_policy);
2120 if (type != SADB_X_SPDDELETE) {
2121 for (pr = iph2->approval->head; pr; pr = pr->next) {
2122 xisrlen = sizeof(*xisr);
2123 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2124 xisrlen += (sysdep_sa_len((struct sockaddr *)iph2->src)
2125 + sysdep_sa_len((struct sockaddr *)iph2->dst));
2126 }
2127
2128 policylen += PFKEY_ALIGN8(xisrlen);
2129 }
2130 }
2131
2132 /* make policy structure */
2133 policy = racoon_malloc(policylen);
2134 if (!policy) {
2135 plog(ASL_LEVEL_ERR,
2136 "buffer allocation failed.\n");
2137 return -1;
2138 }
2139
2140 xpl = ALIGNED_CAST(struct sadb_x_policy *)policy;
2141 xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2142 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2143 xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2144 xpl->sadb_x_policy_dir = spidx->dir;
2145 xpl->sadb_x_policy_id = 0;
2146 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2147 xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2148 #endif
2149
2150 /* no need to append policy information any more if type is SPDDELETE */
2151 if (type == SADB_X_SPDDELETE)
2152 goto end;
2153
2154 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
2155
2156 for (pr = iph2->approval->head; pr; pr = pr->next) {
2157
2158 satype = doi2ipproto(pr->proto_id);
2159 if (satype == ~0) {
2160 plog(ASL_LEVEL_ERR,
2161 "invalid proto_id %d\n", pr->proto_id);
2162 goto err;
2163 }
2164 mode = ipsecdoi2pfkey_mode(pr->encmode);
2165 if (mode == ~0) {
2166 plog(ASL_LEVEL_ERR,
2167 "invalid encmode %d\n", pr->encmode);
2168 goto err;
2169 }
2170
2171 /*
2172 * the policy level cannot be unique because the policy
2173 * is defined later than SA, so req_id cannot be bound to SA.
2174 */
2175 xisr->sadb_x_ipsecrequest_proto = satype;
2176 xisr->sadb_x_ipsecrequest_mode = mode;
2177 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2178 xisr->sadb_x_ipsecrequest_reqid = 0;
2179 p = (caddr_t)(xisr + 1);
2180
2181 xisrlen = sizeof(*xisr);
2182
2183 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2184 int src_len, dst_len;
2185
2186 src_len = sysdep_sa_len((struct sockaddr *)iph2->src);
2187 dst_len = sysdep_sa_len((struct sockaddr *)iph2->dst);
2188 xisrlen += src_len + dst_len;
2189
2190 memcpy(p, iph2->src, src_len);
2191 p += src_len;
2192
2193 memcpy(p, iph2->dst, dst_len);
2194 p += dst_len;
2195 }
2196
2197 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2198 }
2199
2200 end:
2201 *policy0 = policy;
2202 *policylen0 = policylen;
2203
2204 return 0;
2205
2206 err:
2207 if (policy)
2208 racoon_free(policy);
2209
2210 return -1;
2211 }
2212
2213 int
2214 pk_sendspdupdate2(iph2)
2215 phase2_handle_t *iph2;
2216 {
2217 struct policyindex *spidx = iph2->spidx_gen;
2218 caddr_t policy = NULL;
2219 int policylen = 0;
2220 u_int64_t ltime, vtime;
2221
2222 ltime = iph2->approval->lifetime;
2223 vtime = 0;
2224
2225 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2226 plog(ASL_LEVEL_ERR,
2227 "getting sadb policy failed.\n");
2228 return -1;
2229 }
2230
2231 if (pfkey_send_spdupdate2(
2232 lcconf->sock_pfkey,
2233 &spidx->src,
2234 spidx->prefs,
2235 &spidx->dst,
2236 spidx->prefd,
2237 spidx->ul_proto,
2238 ltime, vtime,
2239 policy, policylen, 0) < 0) {
2240 plog(ASL_LEVEL_ERR,
2241 "libipsec failed send spdupdate2 (%s)\n",
2242 ipsec_strerror());
2243 goto end;
2244 }
2245 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spdupdate2\n");
2246
2247 end:
2248 if (policy)
2249 racoon_free(policy);
2250
2251 return 0;
2252 }
2253
2254 static int
2255 pk_recvspdupdate(mhp)
2256 caddr_t *mhp;
2257 {
2258 struct sadb_address *saddr, *daddr;
2259 struct sadb_x_policy *xpl;
2260 struct policyindex spidx;
2261 struct secpolicy *sp;
2262
2263 /* sanity check */
2264 if (mhp[0] == NULL
2265 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2266 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2267 || mhp[SADB_X_EXT_POLICY] == NULL) {
2268 plog(ASL_LEVEL_ERR,
2269 "inappropriate sadb spdupdate message passed.\n");
2270 return -1;
2271 }
2272 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2273 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2274 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2275
2276 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2277 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2278 saddr + 1,
2279 daddr + 1,
2280 saddr->sadb_address_prefixlen,
2281 daddr->sadb_address_prefixlen,
2282 saddr->sadb_address_proto,
2283 xpl->sadb_x_policy_priority,
2284 &spidx);
2285 #else
2286 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2287 saddr + 1,
2288 daddr + 1,
2289 saddr->sadb_address_prefixlen,
2290 daddr->sadb_address_prefixlen,
2291 saddr->sadb_address_proto,
2292 &spidx);
2293 #endif
2294
2295 sp = getsp(&spidx);
2296 if (sp == NULL) {
2297 plog(ASL_LEVEL_ERR,
2298 "such policy does not already exist: \"%s\"\n",
2299 spidx2str(&spidx));
2300 } else {
2301 remsp(sp);
2302 delsp(sp);
2303 }
2304
2305 if (addnewsp(mhp) < 0)
2306 return -1;
2307
2308 return 0;
2309 }
2310
2311 /*
2312 * this function has to be used by responder side.
2313 */
2314 int
2315 pk_sendspdadd2(iph2)
2316 phase2_handle_t *iph2;
2317 {
2318 struct policyindex *spidx = iph2->spidx_gen;
2319 caddr_t policy = NULL;
2320 int policylen = 0;
2321 u_int64_t ltime, vtime;
2322
2323 ltime = iph2->approval->lifetime;
2324 vtime = 0;
2325
2326 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2327 plog(ASL_LEVEL_ERR,
2328 "getting sadb policy failed.\n");
2329 return -1;
2330 }
2331
2332 if (pfkey_send_spdadd2(
2333 lcconf->sock_pfkey,
2334 &spidx->src,
2335 spidx->prefs,
2336 &spidx->dst,
2337 spidx->prefd,
2338 spidx->ul_proto,
2339 ltime, vtime,
2340 policy, policylen, 0) < 0) {
2341 plog(ASL_LEVEL_ERR,
2342 "libipsec failed send spdadd2 (%s)\n",
2343 ipsec_strerror());
2344 goto end;
2345 }
2346 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spdadd2\n");
2347
2348 end:
2349 if (policy)
2350 racoon_free(policy);
2351
2352 return 0;
2353 }
2354
2355 static int
2356 pk_recvspdadd(mhp)
2357 caddr_t *mhp;
2358 {
2359 struct sadb_address *saddr, *daddr;
2360 struct sadb_x_policy *xpl;
2361 struct policyindex spidx;
2362 struct secpolicy *sp;
2363
2364 /* sanity check */
2365 if (mhp[0] == NULL
2366 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2367 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2368 || mhp[SADB_X_EXT_POLICY] == NULL) {
2369 plog(ASL_LEVEL_ERR,
2370 "inappropriate sadb spdadd message passed.\n");
2371 return -1;
2372 }
2373 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2374 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2375 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2376
2377 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2378 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2379 saddr + 1,
2380 daddr + 1,
2381 saddr->sadb_address_prefixlen,
2382 daddr->sadb_address_prefixlen,
2383 saddr->sadb_address_proto,
2384 xpl->sadb_x_policy_priority,
2385 &spidx);
2386 #else
2387 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2388 saddr + 1,
2389 daddr + 1,
2390 saddr->sadb_address_prefixlen,
2391 daddr->sadb_address_prefixlen,
2392 saddr->sadb_address_proto,
2393 &spidx);
2394 #endif
2395
2396 sp = getsp(&spidx);
2397 if (sp != NULL) {
2398 plog(ASL_LEVEL_ERR,
2399 "such policy already exists. "
2400 "anyway replace it: %s\n",
2401 spidx2str(&spidx));
2402 remsp(sp);
2403 delsp(sp);
2404 }
2405
2406 if (addnewsp(mhp) < 0)
2407 return -1;
2408
2409 return 0;
2410 }
2411
2412 /*
2413 * this function has to be used by responder side.
2414 */
2415 int
2416 pk_sendspddelete(iph2)
2417 phase2_handle_t *iph2;
2418 {
2419 struct policyindex *spidx = iph2->spidx_gen;
2420 caddr_t policy = NULL;
2421 int policylen;
2422
2423 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2424 plog(ASL_LEVEL_ERR,
2425 "getting sadb policy failed.\n");
2426 return -1;
2427 }
2428
2429 if (pfkey_send_spddelete(
2430 lcconf->sock_pfkey,
2431 &spidx->src,
2432 spidx->prefs,
2433 &spidx->dst,
2434 spidx->prefd,
2435 spidx->ul_proto,
2436 policy, policylen, 0) < 0) {
2437 plog(ASL_LEVEL_ERR,
2438 "libipsec failed send spddelete (%s)\n",
2439 ipsec_strerror());
2440 goto end;
2441 }
2442 plog(ASL_LEVEL_DEBUG, "call pfkey_send_spddelete\n");
2443
2444 end:
2445 if (policy)
2446 racoon_free(policy);
2447
2448 return 0;
2449 }
2450
2451 static int
2452 pk_recvspddelete(mhp)
2453 caddr_t *mhp;
2454 {
2455 struct sadb_address *saddr, *daddr;
2456 struct sadb_x_policy *xpl;
2457 struct policyindex spidx;
2458 struct secpolicy *sp;
2459
2460 /* sanity check */
2461 if (mhp[0] == NULL
2462 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2463 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2464 || mhp[SADB_X_EXT_POLICY] == NULL) {
2465 plog(ASL_LEVEL_ERR,
2466 "inappropriate sadb spddelete message passed.\n");
2467 return -1;
2468 }
2469 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2470 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2471 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2472
2473 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2474 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2475 saddr + 1,
2476 daddr + 1,
2477 saddr->sadb_address_prefixlen,
2478 daddr->sadb_address_prefixlen,
2479 saddr->sadb_address_proto,
2480 xpl->sadb_x_policy_priority,
2481 &spidx);
2482 #else
2483 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2484 saddr + 1,
2485 daddr + 1,
2486 saddr->sadb_address_prefixlen,
2487 daddr->sadb_address_prefixlen,
2488 saddr->sadb_address_proto,
2489 &spidx);
2490 #endif
2491
2492 sp = getsp(&spidx);
2493 if (sp == NULL) {
2494 plog(ASL_LEVEL_ERR,
2495 "no policy found: %s\n",
2496 spidx2str(&spidx));
2497 return -1;
2498 }
2499
2500 ike_session_purgephXbyspid(xpl->sadb_x_policy_id, true);
2501
2502 remsp(sp);
2503 delsp(sp);
2504
2505 return 0;
2506 }
2507
2508 static int
2509 pk_recvspdexpire(mhp)
2510 caddr_t *mhp;
2511 {
2512 struct sadb_address *saddr, *daddr;
2513 struct sadb_x_policy *xpl;
2514 struct policyindex spidx;
2515 struct secpolicy *sp;
2516
2517 /* sanity check */
2518 if (mhp[0] == NULL
2519 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2520 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2521 || mhp[SADB_X_EXT_POLICY] == NULL) {
2522 plog(ASL_LEVEL_ERR,
2523 "inappropriate sadb spdexpire message passed.\n");
2524 return -1;
2525 }
2526 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2527 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2528 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2529
2530 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2531 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2532 saddr + 1,
2533 daddr + 1,
2534 saddr->sadb_address_prefixlen,
2535 daddr->sadb_address_prefixlen,
2536 saddr->sadb_address_proto,
2537 xpl->sadb_x_policy_priority,
2538 &spidx);
2539 #else
2540 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2541 saddr + 1,
2542 daddr + 1,
2543 saddr->sadb_address_prefixlen,
2544 daddr->sadb_address_prefixlen,
2545 saddr->sadb_address_proto,
2546 &spidx);
2547 #endif
2548
2549 sp = getsp(&spidx);
2550 if (sp == NULL) {
2551 plog(ASL_LEVEL_ERR,
2552 "no policy found: %s\n",
2553 spidx2str(&spidx));
2554 return -1;
2555 }
2556
2557 ike_session_purgephXbyspid(xpl->sadb_x_policy_id, false);
2558
2559 remsp(sp);
2560 delsp(sp);
2561
2562 return 0;
2563 }
2564
2565 static int
2566 pk_recvspdget(mhp)
2567 caddr_t *mhp;
2568 {
2569 /* sanity check */
2570 if (mhp[0] == NULL) {
2571 plog(ASL_LEVEL_ERR,
2572 "inappropriate sadb spdget message passed.\n");
2573 return -1;
2574 }
2575
2576 return 0;
2577 }
2578
2579 static int
2580 pk_recvspddump(mhp)
2581 caddr_t *mhp;
2582 {
2583 struct sadb_msg *msg;
2584 struct sadb_address *saddr, *daddr;
2585 struct sadb_x_policy *xpl;
2586 struct policyindex spidx;
2587 struct secpolicy *sp;
2588
2589 /* sanity check */
2590 if (mhp[0] == NULL) {
2591 plog(ASL_LEVEL_ERR,
2592 "inappropriate sadb spddump message passed.\n");
2593 return -1;
2594 }
2595 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2596
2597 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2598 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2599 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2600
2601 if (saddr == NULL || daddr == NULL || xpl == NULL) {
2602 plog(ASL_LEVEL_ERR,
2603 "inappropriate sadb spddump message passed.\n");
2604 return -1;
2605 }
2606
2607 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2608 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2609 saddr + 1,
2610 daddr + 1,
2611 saddr->sadb_address_prefixlen,
2612 daddr->sadb_address_prefixlen,
2613 saddr->sadb_address_proto,
2614 xpl->sadb_x_policy_priority,
2615 &spidx);
2616 #else
2617 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2618 saddr + 1,
2619 daddr + 1,
2620 saddr->sadb_address_prefixlen,
2621 daddr->sadb_address_prefixlen,
2622 saddr->sadb_address_proto,
2623 &spidx);
2624 #endif
2625
2626 sp = getsp(&spidx);
2627 if (sp != NULL) {
2628 plog(ASL_LEVEL_ERR,
2629 "such policy already exists. "
2630 "anyway replace it: %s\n",
2631 spidx2str(&spidx));
2632 remsp(sp);
2633 delsp(sp);
2634 }
2635
2636 if (addnewsp(mhp) < 0)
2637 return -1;
2638
2639 return 0;
2640 }
2641
2642 static int
2643 pk_recvspdflush(mhp)
2644 caddr_t *mhp;
2645 {
2646 /* sanity check */
2647 if (mhp[0] == NULL) {
2648 plog(ASL_LEVEL_ERR,
2649 "inappropriate sadb spdflush message passed.\n");
2650 return -1;
2651 }
2652
2653 ike_session_flush_all_phase2(false);
2654 ike_session_flush_all_phase1(false);
2655 flushsp();
2656
2657 return 0;
2658 }
2659
2660 /*
2661 * send error against acquire message to kenrel.
2662 */
2663 int
2664 pk_sendeacquire(iph2)
2665 phase2_handle_t *iph2;
2666 {
2667 struct sadb_msg *newmsg;
2668 int len;
2669
2670 len = sizeof(struct sadb_msg);
2671 newmsg = racoon_calloc(1, len);
2672 if (newmsg == NULL) {
2673 plog(ASL_LEVEL_ERR,
2674 "failed to get buffer to send acquire.\n");
2675 return -1;
2676 }
2677
2678 memset(newmsg, 0, len);
2679 newmsg->sadb_msg_version = PF_KEY_V2;
2680 newmsg->sadb_msg_type = SADB_ACQUIRE;
2681 newmsg->sadb_msg_errno = ENOENT; /* XXX */
2682 newmsg->sadb_msg_satype = iph2->satype;
2683 newmsg->sadb_msg_len = PFKEY_UNIT64(len);
2684 newmsg->sadb_msg_reserved = 0;
2685 newmsg->sadb_msg_seq = iph2->seq;
2686 newmsg->sadb_msg_pid = (u_int32_t)getpid();
2687
2688 /* send message */
2689 len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
2690
2691 racoon_free(newmsg);
2692
2693 return 0;
2694 }
2695
2696 int
2697 pk_sendget_inbound_sastats(ike_session_t *session)
2698 {
2699 u_int32_t max_stats;
2700 u_int32_t seq;
2701
2702 if (!session) {
2703 plog(ASL_LEVEL_DEBUG, "invalid args in %s \n", __FUNCTION__);
2704 return -1;
2705 }
2706
2707 session->traffic_monitor.num_in_curr_req = 0;
2708 bzero(session->traffic_monitor.in_curr_req, sizeof(session->traffic_monitor.in_curr_req));
2709 max_stats = (sizeof(session->traffic_monitor.in_curr_req) / sizeof(session->traffic_monitor.in_curr_req[0]));
2710
2711 // get list of SAs
2712 if ((session->traffic_monitor.num_in_curr_req = ike_session_get_sas_for_stats(session,
2713 IPSEC_DIR_INBOUND,
2714 &seq,
2715 session->traffic_monitor.in_curr_req,
2716 max_stats))) {
2717 u_int64_t session_ids[] = {(u_int64_t)session, 0};
2718
2719 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__);
2720
2721 if (pfkey_send_getsastats(lcconf->sock_pfkey,
2722 seq,
2723 session_ids,
2724 1,
2725 IPSEC_DIR_INBOUND,
2726 session->traffic_monitor.in_curr_req,
2727 session->traffic_monitor.num_in_curr_req) < 0) {
2728 return -1;
2729 }
2730 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__);
2731
2732 return session->traffic_monitor.num_in_curr_req;
2733 }
2734 return 0;
2735 }
2736
2737 int
2738 pk_sendget_outbound_sastats(ike_session_t *session)
2739 {
2740 u_int32_t max_stats;
2741 u_int32_t seq;
2742
2743 if (!session) {
2744 plog(ASL_LEVEL_DEBUG, "invalid args in %s \n", __FUNCTION__);
2745 return -1;
2746 }
2747
2748 session->traffic_monitor.num_out_curr_req = 0;
2749 bzero(session->traffic_monitor.out_curr_req, sizeof(session->traffic_monitor.out_curr_req));
2750 max_stats = (sizeof(session->traffic_monitor.out_curr_req) / sizeof(session->traffic_monitor.out_curr_req[0]));
2751
2752 // get list of SAs
2753 if ((session->traffic_monitor.num_out_curr_req = ike_session_get_sas_for_stats(session,
2754 IPSEC_DIR_OUTBOUND,
2755 &seq,
2756 session->traffic_monitor.out_curr_req,
2757 max_stats))) {
2758 u_int64_t session_ids[] = {(u_int64_t)session, 0};
2759
2760 //plog(ASL_LEVEL_DEBUG, "about to call %s\n", __FUNCTION__);
2761
2762 if (pfkey_send_getsastats(lcconf->sock_pfkey,
2763 seq,
2764 session_ids,
2765 1,
2766 IPSEC_DIR_OUTBOUND,
2767 session->traffic_monitor.out_curr_req,
2768 session->traffic_monitor.num_out_curr_req) < 0) {
2769 return -1;
2770 }
2771 //plog(ASL_LEVEL_DEBUG, "%s successful\n", __FUNCTION__);
2772
2773 return session->traffic_monitor.num_out_curr_req;
2774 }
2775 return 0;
2776 }
2777
2778 /*
2779 * receive GETSPDSTAT from kernel.
2780 */
2781 static int
2782 pk_recvgetsastat(mhp)
2783 caddr_t *mhp;
2784 {
2785 struct sadb_msg *msg;
2786 struct sadb_session_id *session_id;
2787 struct sadb_sastat *stat_resp;
2788 ike_session_t *session;
2789
2790 /* validity check */
2791 if (mhp[0] == NULL ||
2792 mhp[SADB_EXT_SESSION_ID] == NULL ||
2793 mhp[SADB_EXT_SASTAT] == NULL) {
2794 plog(ASL_LEVEL_ERR,
2795 "inappropriate sadb getsastat response.\n");
2796 return -1;
2797 }
2798 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to structs in an aligned buffer
2799 session_id = ALIGNED_CAST(struct sadb_session_id *)mhp[SADB_EXT_SESSION_ID];
2800 stat_resp = ALIGNED_CAST(struct sadb_sastat *)mhp[SADB_EXT_SASTAT];
2801
2802 /* the message has to be processed or not ? */
2803 if (msg->sadb_msg_pid != getpid()) {
2804 plog(ASL_LEVEL_DEBUG,
2805 "%s message is not interesting "
2806 "because pid %d is not mine.\n",
2807 s_pfkey_type(msg->sadb_msg_type),
2808 msg->sadb_msg_pid);
2809 return -1;
2810 }
2811 if (!session_id->sadb_session_id_v[0]) {
2812 plog(ASL_LEVEL_DEBUG,
2813 "%s message is bad "
2814 "because session-id[0] is invalid.\n",
2815 s_pfkey_type(msg->sadb_msg_type));
2816 return -1;
2817 }
2818 session = ALIGNED_CAST(__typeof__(session))session_id->sadb_session_id_v[0];
2819
2820 if (!stat_resp->sadb_sastat_list_len) {
2821 plog(ASL_LEVEL_DEBUG,
2822 "%s message is bad "
2823 "because it has no sastats.\n",
2824 s_pfkey_type(msg->sadb_msg_type));
2825 return -1;
2826 }
2827
2828 ike_session_update_traffic_idle_status(session,
2829 stat_resp->sadb_sastat_dir,
2830 (struct sastat *)(stat_resp + 1),
2831 stat_resp->sadb_sastat_list_len);
2832 return 0;
2833 }
2834
2835 /*
2836 * check if the algorithm is supported or not.
2837 * OUT 0: ok
2838 * -1: ng
2839 */
2840 int
2841 pk_checkalg(class, calg, keylen)
2842 int class, calg, keylen;
2843 {
2844 int sup, error;
2845 u_int alg;
2846 struct sadb_alg alg0;
2847
2848 switch (algclass2doi(class)) {
2849 case IPSECDOI_PROTO_IPSEC_ESP:
2850 sup = SADB_EXT_SUPPORTED_ENCRYPT;
2851 break;
2852 case IPSECDOI_ATTR_AUTH:
2853 sup = SADB_EXT_SUPPORTED_AUTH;
2854 break;
2855 case IPSECDOI_PROTO_IPCOMP:
2856 return 0;
2857 default:
2858 plog(ASL_LEVEL_ERR,
2859 "invalid algorithm class.\n");
2860 return -1;
2861 }
2862 alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
2863 if (alg == ~0)
2864 return -1;
2865
2866 if (keylen == 0) {
2867 if (ipsec_get_keylen(sup, alg, &alg0)) {
2868 plog(ASL_LEVEL_ERR,
2869 "%s.\n", ipsec_strerror());
2870 return -1;
2871 }
2872 keylen = alg0.sadb_alg_minbits;
2873 }
2874
2875 error = ipsec_check_keylen(sup, alg, keylen);
2876 if (error)
2877 plog(ASL_LEVEL_ERR,
2878 "%s.\n", ipsec_strerror());
2879
2880 return error;
2881 }
2882
2883 /*
2884 * differences with pfkey_recv() in libipsec/pfkey.c:
2885 * - never performs busy wait loop.
2886 * - returns NULL and set *lenp to negative on fatal failures
2887 * - returns NULL and set *lenp to non-negative on non-fatal failures
2888 * - returns non-NULL on success
2889 */
2890 static struct sadb_msg *
2891 pk_recv(so, lenp)
2892 int so;
2893 ssize_t *lenp;
2894 {
2895 struct sadb_msg *newmsg;
2896 int reallen = 0;
2897 socklen_t optlen = sizeof(reallen);
2898
2899 if (getsockopt(so, SOL_SOCKET, SO_NREAD, &reallen, &optlen) < 0)
2900 return NULL; /*fatal*/
2901
2902 if (reallen == 0)
2903 return NULL;
2904
2905 if ((newmsg = racoon_calloc(1, reallen)) == NULL)
2906 return NULL;
2907
2908 while ((*lenp = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
2909 if (errno == EINTR)
2910 continue;
2911 plog(ASL_LEVEL_ERR, "failed to recv pfkey message: %s\n", strerror(errno));
2912 break;
2913 }
2914 if (*lenp < 0) {
2915 racoon_free(newmsg);
2916 return NULL; /*fatal*/
2917 } else if (*lenp != reallen || *lenp < sizeof(struct sadb_msg)) {
2918 racoon_free(newmsg);
2919 return NULL;
2920 }
2921
2922 return newmsg;
2923 }
2924
2925 /* see handler.h */
2926 u_int32_t
2927 pk_getseq()
2928 {
2929 return eay_random();
2930 }
2931
2932 static int
2933 addnewsp(mhp)
2934 caddr_t *mhp;
2935 {
2936 struct secpolicy *new;
2937 struct sadb_address *saddr, *daddr;
2938 struct sadb_x_policy *xpl;
2939
2940 /* sanity check */
2941 if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
2942 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2943 || mhp[SADB_X_EXT_POLICY] == NULL) {
2944 plog(ASL_LEVEL_ERR,
2945 "inappropriate sadb spd management message passed.\n");
2946 return -1;
2947 }
2948
2949 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2950 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2951 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2952
2953 new = newsp();
2954 if (new == NULL) {
2955 plog(ASL_LEVEL_ERR,
2956 "failed to allocate buffer\n");
2957 return -1;
2958 }
2959
2960 new->spidx.dir = xpl->sadb_x_policy_dir;
2961 new->id = xpl->sadb_x_policy_id;
2962 new->policy = xpl->sadb_x_policy_type;
2963 new->req = NULL;
2964
2965 /* check policy */
2966 switch (xpl->sadb_x_policy_type) {
2967 case IPSEC_POLICY_DISCARD:
2968 case IPSEC_POLICY_GENERATE:
2969 case IPSEC_POLICY_NONE:
2970 case IPSEC_POLICY_ENTRUST:
2971 case IPSEC_POLICY_BYPASS:
2972 break;
2973
2974 case IPSEC_POLICY_IPSEC:
2975 {
2976 int tlen;
2977 struct sadb_x_ipsecrequest *xisr;
2978 struct ipsecrequest **p_isr = &new->req;
2979
2980 /* validity check */
2981 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
2982 plog(ASL_LEVEL_ERR,
2983 "invalid msg length.\n");
2984 return -1;
2985 }
2986
2987 tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
2988 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
2989
2990 while (tlen > 0) {
2991
2992 /* length check */
2993 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
2994 plog(ASL_LEVEL_ERR,
2995 "invalid msg length.\n");
2996 return -1;
2997 }
2998
2999 /* allocate request buffer */
3000 *p_isr = newipsecreq();
3001 if (*p_isr == NULL) {
3002 plog(ASL_LEVEL_ERR,
3003 "failed to get new ipsecreq.\n");
3004 return -1;
3005 }
3006
3007 /* set values */
3008 (*p_isr)->next = NULL;
3009
3010 switch (xisr->sadb_x_ipsecrequest_proto) {
3011 case IPPROTO_ESP:
3012 case IPPROTO_AH:
3013 case IPPROTO_IPCOMP:
3014 break;
3015 default:
3016 plog(ASL_LEVEL_ERR,
3017 "invalid proto type: %u\n",
3018 xisr->sadb_x_ipsecrequest_proto);
3019 return -1;
3020 }
3021 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
3022
3023 switch (xisr->sadb_x_ipsecrequest_mode) {
3024 case IPSEC_MODE_TRANSPORT:
3025 case IPSEC_MODE_TUNNEL:
3026 break;
3027 case IPSEC_MODE_ANY:
3028 default:
3029 plog(ASL_LEVEL_ERR,
3030 "invalid mode: %u\n",
3031 xisr->sadb_x_ipsecrequest_mode);
3032 return -1;
3033 }
3034 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
3035
3036 switch (xisr->sadb_x_ipsecrequest_level) {
3037 case IPSEC_LEVEL_DEFAULT:
3038 case IPSEC_LEVEL_USE:
3039 case IPSEC_LEVEL_REQUIRE:
3040 break;
3041 case IPSEC_LEVEL_UNIQUE:
3042 (*p_isr)->saidx.reqid =
3043 xisr->sadb_x_ipsecrequest_reqid;
3044 break;
3045
3046 default:
3047 plog(ASL_LEVEL_ERR,
3048 "invalid level: %u\n",
3049 xisr->sadb_x_ipsecrequest_level);
3050 return -1;
3051 }
3052 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
3053
3054 /* set IP addresses if there */
3055 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
3056 struct sockaddr *paddr;
3057
3058 paddr = (struct sockaddr *)(xisr + 1);
3059 bcopy(paddr, &(*p_isr)->saidx.src,
3060 sysdep_sa_len(paddr));
3061
3062 paddr = (struct sockaddr *)((caddr_t)paddr
3063 + sysdep_sa_len(paddr));
3064 bcopy(paddr, &(*p_isr)->saidx.dst,
3065 sysdep_sa_len(paddr));
3066 }
3067
3068 (*p_isr)->sp = new;
3069
3070 /* initialization for the next. */
3071 p_isr = &(*p_isr)->next;
3072 tlen -= xisr->sadb_x_ipsecrequest_len;
3073
3074 /* validity check */
3075 if (tlen < 0) {
3076 plog(ASL_LEVEL_ERR,
3077 "becoming tlen < 0\n");
3078 }
3079
3080 xisr = ALIGNED_CAST(struct sadb_x_ipsecrequest *)((caddr_t)xisr
3081 + xisr->sadb_x_ipsecrequest_len);
3082 }
3083 }
3084 break;
3085 default:
3086 plog(ASL_LEVEL_ERR,
3087 "invalid policy type.\n");
3088 delsp(new);
3089 return -1;
3090 }
3091
3092 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3093 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3094 saddr + 1,
3095 daddr + 1,
3096 saddr->sadb_address_prefixlen,
3097 daddr->sadb_address_prefixlen,
3098 saddr->sadb_address_proto,
3099 xpl->sadb_x_policy_priority,
3100 &new->spidx);
3101 #else
3102 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3103 saddr + 1,
3104 daddr + 1,
3105 saddr->sadb_address_prefixlen,
3106 daddr->sadb_address_prefixlen,
3107 saddr->sadb_address_proto,
3108 &new->spidx);
3109 #endif
3110
3111 inssp(new);
3112
3113 return 0;
3114 }
3115
3116 /* proto/mode/src->dst spi */
3117 const char *
3118 sadbsecas2str(src, dst, proto, spi, mode)
3119 struct sockaddr_storage *src, *dst;
3120 int proto;
3121 u_int32_t spi;
3122 int mode;
3123 {
3124 static char buf[256];
3125 u_int doi_proto, doi_mode = 0;
3126 char *p;
3127 int blen, i;
3128
3129 doi_proto = pfkey2ipsecdoi_proto(proto);
3130 if (doi_proto == ~0)
3131 return NULL;
3132 if (mode) {
3133 doi_mode = pfkey2ipsecdoi_mode(mode);
3134 if (doi_mode == ~0)
3135 return NULL;
3136 }
3137
3138 blen = sizeof(buf) - 1;
3139 p = buf;
3140
3141 i = snprintf(p, blen, "%s%s%s ",
3142 s_ipsecdoi_proto(doi_proto),
3143 mode ? "/" : "",
3144 mode ? s_ipsecdoi_encmode(doi_mode) : "");
3145 if (i < 0 || i >= blen)
3146 return NULL;
3147 p += i;
3148 blen -= i;
3149
3150 i = snprintf(p, blen, "%s->", saddr2str((struct sockaddr *)src));
3151 if (i < 0 || i >= blen)
3152 return NULL;
3153 p += i;
3154 blen -= i;
3155
3156 i = snprintf(p, blen, "%s ", saddr2str((struct sockaddr *)dst));
3157 if (i < 0 || i >= blen)
3158 return NULL;
3159 p += i;
3160 blen -= i;
3161
3162 if (spi) {
3163 snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3164 (unsigned long)ntohl(spi));
3165 }
3166
3167 return buf;
3168 }