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