No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / ipsec-tools / src / racoon / pfkey.c
blob7010c434bf6659d3bc4c32f6dbceaa6326bbf6e9
1 /* $NetBSD: pfkey.c,v 1.50 2009/08/10 08:22:13 tteras Exp $ */
3 /* $Id: pfkey.c,v 1.51 2009/09/03 09:29:07 tteras Exp $ */
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "config.h"
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <netdb.h>
40 #include <errno.h>
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
48 #ifdef ENABLE_NATT
49 # ifdef __linux__
50 # include <linux/udp.h>
51 # endif
52 # if defined(__NetBSD__) || defined(__FreeBSD__) || \
53 (defined(__APPLE__) && defined(__MACH__))
54 # include <netinet/udp.h>
55 # endif
56 #endif
58 #include <sys/types.h>
59 #include <sys/param.h>
60 #include <sys/socket.h>
61 #include <sys/queue.h>
62 #include <sys/sysctl.h>
64 #include <net/route.h>
65 #include <net/pfkeyv2.h>
67 #include <netinet/in.h>
68 #include PATH_IPSEC_H
69 #include <fcntl.h>
71 #include "libpfkey.h"
73 #include "var.h"
74 #include "misc.h"
75 #include "vmbuf.h"
76 #include "plog.h"
77 #include "sockmisc.h"
78 #include "session.h"
79 #include "debug.h"
81 #include "schedule.h"
82 #include "localconf.h"
83 #include "remoteconf.h"
84 #include "handler.h"
85 #include "policy.h"
86 #include "proposal.h"
87 #include "isakmp_var.h"
88 #include "isakmp.h"
89 #include "isakmp_inf.h"
90 #include "ipsec_doi.h"
91 #include "oakley.h"
92 #include "pfkey.h"
93 #include "algorithm.h"
94 #include "sainfo.h"
95 #include "admin.h"
96 #include "evt.h"
97 #include "privsep.h"
98 #include "strnames.h"
99 #include "backupsa.h"
100 #include "gcmalloc.h"
101 #include "nattraversal.h"
102 #include "crypto_openssl.h"
103 #include "grabmyaddr.h"
105 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
106 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
107 #endif
109 /* prototype */
110 static u_int ipsecdoi2pfkey_aalg __P((u_int));
111 static u_int ipsecdoi2pfkey_ealg __P((u_int));
112 static u_int ipsecdoi2pfkey_calg __P((u_int));
113 static u_int ipsecdoi2pfkey_alg __P((u_int, u_int));
114 static u_int keylen_aalg __P((u_int));
115 static u_int keylen_ealg __P((u_int, int));
117 static int pk_recvgetspi __P((caddr_t *));
118 static int pk_recvupdate __P((caddr_t *));
119 static int pk_recvadd __P((caddr_t *));
120 static int pk_recvdelete __P((caddr_t *));
121 static int pk_recvacquire __P((caddr_t *));
122 static int pk_recvexpire __P((caddr_t *));
123 static int pk_recvflush __P((caddr_t *));
124 static int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *));
125 static int pk_recvspdupdate __P((caddr_t *));
126 static int pk_recvspdadd __P((caddr_t *));
127 static int pk_recvspddelete __P((caddr_t *));
128 static int pk_recvspdexpire __P((caddr_t *));
129 static int pk_recvspdget __P((caddr_t *));
130 static int pk_recvspddump __P((caddr_t *));
131 static int pk_recvspdflush __P((caddr_t *));
132 #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
133 static int pk_recvmigrate __P((caddr_t *));
134 #endif
135 static struct sadb_msg *pk_recv __P((int, int *));
137 static int (*pkrecvf[]) __P((caddr_t *)) = {
138 NULL,
139 pk_recvgetspi,
140 pk_recvupdate,
141 pk_recvadd,
142 pk_recvdelete,
143 NULL, /* SADB_GET */
144 pk_recvacquire,
145 NULL, /* SABD_REGISTER */
146 pk_recvexpire,
147 pk_recvflush,
148 NULL, /* SADB_DUMP */
149 NULL, /* SADB_X_PROMISC */
150 NULL, /* SADB_X_PCHANGE */
151 pk_recvspdupdate,
152 pk_recvspdadd,
153 pk_recvspddelete,
154 pk_recvspdget,
155 NULL, /* SADB_X_SPDACQUIRE */
156 pk_recvspddump,
157 pk_recvspdflush,
158 NULL, /* SADB_X_SPDSETIDX */
159 pk_recvspdexpire,
160 NULL, /* SADB_X_SPDDELETE2 */
161 NULL, /* SADB_X_NAT_T_NEW_MAPPING */
162 #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
163 pk_recvmigrate,
164 #else
165 NULL, /* SADB_X_MIGRATE */
166 #endif
167 #if (SADB_MAX > 24)
168 #error "SADB extra message?"
169 #endif
172 static int addnewsp __P((caddr_t *, struct sockaddr *, struct sockaddr *));
174 /* cope with old kame headers - ugly */
175 #ifndef SADB_X_AALG_MD5
176 #define SADB_X_AALG_MD5 SADB_AALG_MD5
177 #endif
178 #ifndef SADB_X_AALG_SHA
179 #define SADB_X_AALG_SHA SADB_AALG_SHA
180 #endif
181 #ifndef SADB_X_AALG_NULL
182 #define SADB_X_AALG_NULL SADB_AALG_NULL
183 #endif
185 #ifndef SADB_X_EALG_BLOWFISHCBC
186 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
187 #endif
188 #ifndef SADB_X_EALG_CAST128CBC
189 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
190 #endif
191 #ifndef SADB_X_EALG_RC5CBC
192 #ifdef SADB_EALG_RC5CBC
193 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
194 #endif
195 #endif
198 * PF_KEY packet handler
199 * 0: success
200 * -1: fail
202 static int
203 pfkey_handler(ctx, fd)
204 void *ctx;
205 int fd;
207 struct sadb_msg *msg;
208 int len;
209 caddr_t mhp[SADB_EXT_MAX + 1];
210 int error = -1;
212 /* receive pfkey message. */
213 len = 0;
214 msg = (struct sadb_msg *) pk_recv(fd, &len);
215 if (msg == NULL) {
216 if (len < 0) {
217 /* do not report EAGAIN as error; well get
218 * called from main loop later. and it's normal
219 * when spd dump is received during reload and
220 * this function is called in loop. */
221 if (errno == EAGAIN)
222 goto end;
224 plog(LLV_ERROR, LOCATION, NULL,
225 "failed to recv from pfkey (%s)\n",
226 strerror(errno));
227 goto end;
228 } else {
229 /* short message - msg not ready */
230 return 0;
234 plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
235 s_pfkey_type(msg->sadb_msg_type));
236 plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
238 /* validity check */
239 if (msg->sadb_msg_errno) {
240 int pri;
242 /* when SPD is empty, treat the state as no error. */
243 if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
244 msg->sadb_msg_errno == ENOENT)
245 pri = LLV_DEBUG;
246 else
247 pri = LLV_ERROR;
249 plog(pri, LOCATION, NULL,
250 "pfkey %s failed: %s\n",
251 s_pfkey_type(msg->sadb_msg_type),
252 strerror(msg->sadb_msg_errno));
254 goto end;
257 /* check pfkey message. */
258 if (pfkey_align(msg, mhp)) {
259 plog(LLV_ERROR, LOCATION, NULL,
260 "libipsec failed pfkey align (%s)\n",
261 ipsec_strerror());
262 goto end;
264 if (pfkey_check(mhp)) {
265 plog(LLV_ERROR, LOCATION, NULL,
266 "libipsec failed pfkey check (%s)\n",
267 ipsec_strerror());
268 goto end;
270 msg = (struct sadb_msg *)mhp[0];
272 /* safety check */
273 if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
274 plog(LLV_ERROR, LOCATION, NULL,
275 "unknown PF_KEY message type=%u\n",
276 msg->sadb_msg_type);
277 goto end;
280 if (pkrecvf[msg->sadb_msg_type] == NULL) {
281 plog(LLV_INFO, LOCATION, NULL,
282 "unsupported PF_KEY message %s\n",
283 s_pfkey_type(msg->sadb_msg_type));
284 goto end;
287 if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
288 goto end;
290 error = 1;
291 end:
292 if (msg)
293 racoon_free(msg);
294 return(error);
298 * dump SADB
300 vchar_t *
301 pfkey_dump_sadb(satype)
302 int satype;
304 int s;
305 vchar_t *buf = NULL;
306 pid_t pid = getpid();
307 struct sadb_msg *msg = NULL;
308 size_t bl, ml;
309 int len;
310 int bufsiz;
312 if ((s = privsep_socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
313 plog(LLV_ERROR, LOCATION, NULL,
314 "libipsec failed pfkey open: %s\n",
315 ipsec_strerror());
316 return NULL;
319 if ((bufsiz = pfkey_set_buffer_size(s, lcconf->pfkey_buffer_size)) < 0) {
320 plog(LLV_ERROR, LOCATION, NULL,
321 "libipsec failed pfkey set buffer size to %d: %s\n",
322 lcconf->pfkey_buffer_size, ipsec_strerror());
323 return NULL;
324 } else if (bufsiz < lcconf->pfkey_buffer_size) {
325 plog(LLV_WARNING, LOCATION, NULL,
326 "pfkey socket receive buffer set to %dKB, instead of %d\n",
327 bufsiz, lcconf->pfkey_buffer_size);
330 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
331 if (pfkey_send_dump(s, satype) < 0) {
332 plog(LLV_ERROR, LOCATION, NULL,
333 "libipsec failed dump: %s\n", ipsec_strerror());
334 goto fail;
337 while (1) {
338 if (msg)
339 racoon_free(msg);
340 msg = pk_recv(s, &len);
341 if (msg == NULL) {
342 if (len < 0)
343 goto done;
344 else
345 continue;
348 if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid)
350 plog(LLV_DEBUG, LOCATION, NULL,
351 "discarding non-sadb dump msg %p, our pid=%i\n", msg, pid);
352 plog(LLV_DEBUG, LOCATION, NULL,
353 "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid);
354 continue;
358 ml = msg->sadb_msg_len << 3;
359 bl = buf ? buf->l : 0;
360 buf = vrealloc(buf, bl + ml);
361 if (buf == NULL) {
362 plog(LLV_ERROR, LOCATION, NULL,
363 "failed to reallocate buffer to dump.\n");
364 goto fail;
366 memcpy(buf->v + bl, msg, ml);
368 if (msg->sadb_msg_seq == 0)
369 break;
371 goto done;
373 fail:
374 if (buf)
375 vfree(buf);
376 buf = NULL;
377 done:
378 if (msg)
379 racoon_free(msg);
380 close(s);
381 return buf;
384 #ifdef ENABLE_ADMINPORT
386 * flush SADB
388 void
389 pfkey_flush_sadb(proto)
390 u_int proto;
392 int satype;
394 /* convert to SADB_SATYPE */
395 if ((satype = admin2pfkey_proto(proto)) < 0)
396 return;
398 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
399 if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
400 plog(LLV_ERROR, LOCATION, NULL,
401 "libipsec failed send flush (%s)\n", ipsec_strerror());
402 return;
405 return;
407 #endif
410 * These are the SATYPEs that we manage. We register to get
411 * PF_KEY messages related to these SATYPEs, and we also use
412 * this list to determine which SATYPEs to delete SAs for when
413 * we receive an INITIAL-CONTACT.
415 const struct pfkey_satype pfkey_satypes[] = {
416 { SADB_SATYPE_AH, "AH" },
417 { SADB_SATYPE_ESP, "ESP" },
418 { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
420 const int pfkey_nsatypes =
421 sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
424 * PF_KEY initialization
427 pfkey_init()
429 int i, reg_fail;
430 int bufsiz;
432 if ((lcconf->sock_pfkey = pfkey_open()) < 0) {
433 plog(LLV_ERROR, LOCATION, NULL,
434 "libipsec failed pfkey open (%s)\n", ipsec_strerror());
435 return -1;
437 if ((bufsiz = pfkey_set_buffer_size(lcconf->sock_pfkey,
438 lcconf->pfkey_buffer_size)) < 0) {
439 plog(LLV_ERROR, LOCATION, NULL,
440 "libipsec failed to set pfkey buffer size to %d (%s)\n",
441 lcconf->pfkey_buffer_size, ipsec_strerror());
442 return -1;
443 } else if (bufsiz < lcconf->pfkey_buffer_size) {
444 plog(LLV_WARNING, LOCATION, NULL,
445 "pfkey socket receive buffer set to %dKB, instead of %d\n",
446 bufsiz, lcconf->pfkey_buffer_size);
449 if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1)
450 plog(LLV_WARNING, LOCATION, NULL,
451 "failed to set the pfkey socket to NONBLOCK\n");
453 for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
454 plog(LLV_DEBUG, LOCATION, NULL,
455 "call pfkey_send_register for %s\n",
456 pfkey_satypes[i].ps_name);
457 if (pfkey_send_register(lcconf->sock_pfkey,
458 pfkey_satypes[i].ps_satype) < 0 ||
459 pfkey_recv_register(lcconf->sock_pfkey) < 0) {
460 plog(LLV_WARNING, LOCATION, NULL,
461 "failed to register %s (%s)\n",
462 pfkey_satypes[i].ps_name,
463 ipsec_strerror());
464 reg_fail++;
468 if (reg_fail == pfkey_nsatypes) {
469 plog(LLV_ERROR, LOCATION, NULL,
470 "failed to regist any protocol.\n");
471 pfkey_close(lcconf->sock_pfkey);
472 return -1;
475 initsp();
477 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
478 plog(LLV_ERROR, LOCATION, NULL,
479 "libipsec sending spddump failed: %s\n",
480 ipsec_strerror());
481 pfkey_close(lcconf->sock_pfkey);
482 return -1;
484 #if 0
485 if (pfkey_promisc_toggle(1) < 0) {
486 pfkey_close(lcconf->sock_pfkey);
487 return -1;
489 #endif
490 monitor_fd(lcconf->sock_pfkey, pfkey_handler, NULL);
491 return 0;
495 pfkey_reload()
497 flushsp();
499 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
500 plog(LLV_ERROR, LOCATION, NULL,
501 "libipsec sending spddump failed: %s\n",
502 ipsec_strerror());
503 return -1;
506 while (pfkey_handler(NULL, lcconf->sock_pfkey) > 0)
507 continue;
509 return 0;
512 /* %%% for conversion */
513 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
514 static u_int
515 ipsecdoi2pfkey_aalg(hashtype)
516 u_int hashtype;
518 switch (hashtype) {
519 case IPSECDOI_ATTR_AUTH_HMAC_MD5:
520 return SADB_AALG_MD5HMAC;
521 case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
522 return SADB_AALG_SHA1HMAC;
523 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
524 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
525 return SADB_X_AALG_SHA2_256;
526 #else
527 return SADB_X_AALG_SHA2_256HMAC;
528 #endif
529 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
530 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
531 return SADB_X_AALG_SHA2_384;
532 #else
533 return SADB_X_AALG_SHA2_384HMAC;
534 #endif
535 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
536 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
537 return SADB_X_AALG_SHA2_512;
538 #else
539 return SADB_X_AALG_SHA2_512HMAC;
540 #endif
541 case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */
542 return SADB_AALG_NONE;
544 /* not supported */
545 case IPSECDOI_ATTR_AUTH_DES_MAC:
546 plog(LLV_ERROR, LOCATION, NULL,
547 "Not supported hash type: %u\n", hashtype);
548 return ~0;
550 case 0: /* reserved */
551 default:
552 return SADB_AALG_NONE;
554 plog(LLV_ERROR, LOCATION, NULL,
555 "Invalid hash type: %u\n", hashtype);
556 return ~0;
558 /*NOTREACHED*/
561 /* IPSECDOI_ESP -> SADB_EALG */
562 static u_int
563 ipsecdoi2pfkey_ealg(t_id)
564 u_int t_id;
566 switch (t_id) {
567 case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */
568 return SADB_EALG_DESCBC;
569 case IPSECDOI_ESP_DES:
570 return SADB_EALG_DESCBC;
571 case IPSECDOI_ESP_3DES:
572 return SADB_EALG_3DESCBC;
573 #ifdef SADB_X_EALG_RC5CBC
574 case IPSECDOI_ESP_RC5:
575 return SADB_X_EALG_RC5CBC;
576 #endif
577 case IPSECDOI_ESP_CAST:
578 return SADB_X_EALG_CAST128CBC;
579 case IPSECDOI_ESP_BLOWFISH:
580 return SADB_X_EALG_BLOWFISHCBC;
581 case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD|
582 SADB_X_EXT_IV4B)*/
583 return SADB_EALG_DESCBC;
584 case IPSECDOI_ESP_NULL:
585 return SADB_EALG_NULL;
586 #ifdef SADB_X_EALG_AESCBC
587 case IPSECDOI_ESP_AES:
588 return SADB_X_EALG_AESCBC;
589 #endif
590 #ifdef SADB_X_EALG_TWOFISHCBC
591 case IPSECDOI_ESP_TWOFISH:
592 return SADB_X_EALG_TWOFISHCBC;
593 #endif
594 #ifdef SADB_X_EALG_CAMELLIACBC
595 case IPSECDOI_ESP_CAMELLIA:
596 return SADB_X_EALG_CAMELLIACBC;
597 #endif
599 /* not supported */
600 case IPSECDOI_ESP_3IDEA:
601 case IPSECDOI_ESP_IDEA:
602 case IPSECDOI_ESP_RC4:
603 plog(LLV_ERROR, LOCATION, NULL,
604 "Not supported transform: %u\n", t_id);
605 return ~0;
607 case 0: /* reserved */
608 default:
609 plog(LLV_ERROR, LOCATION, NULL,
610 "Invalid transform id: %u\n", t_id);
611 return ~0;
613 /*NOTREACHED*/
616 /* IPCOMP -> SADB_CALG */
617 static u_int
618 ipsecdoi2pfkey_calg(t_id)
619 u_int t_id;
621 switch (t_id) {
622 case IPSECDOI_IPCOMP_OUI:
623 return SADB_X_CALG_OUI;
624 case IPSECDOI_IPCOMP_DEFLATE:
625 return SADB_X_CALG_DEFLATE;
626 case IPSECDOI_IPCOMP_LZS:
627 return SADB_X_CALG_LZS;
629 case 0: /* reserved */
630 default:
631 plog(LLV_ERROR, LOCATION, NULL,
632 "Invalid transform id: %u\n", t_id);
633 return ~0;
635 /*NOTREACHED*/
638 /* IPSECDOI_PROTO -> SADB_SATYPE */
639 u_int
640 ipsecdoi2pfkey_proto(proto)
641 u_int proto;
643 switch (proto) {
644 case IPSECDOI_PROTO_IPSEC_AH:
645 return SADB_SATYPE_AH;
646 case IPSECDOI_PROTO_IPSEC_ESP:
647 return SADB_SATYPE_ESP;
648 case IPSECDOI_PROTO_IPCOMP:
649 return SADB_X_SATYPE_IPCOMP;
651 default:
652 plog(LLV_ERROR, LOCATION, NULL,
653 "Invalid ipsec_doi proto: %u\n", proto);
654 return ~0;
656 /*NOTREACHED*/
659 static u_int
660 ipsecdoi2pfkey_alg(algclass, type)
661 u_int algclass, type;
663 switch (algclass) {
664 case IPSECDOI_ATTR_AUTH:
665 return ipsecdoi2pfkey_aalg(type);
666 case IPSECDOI_PROTO_IPSEC_ESP:
667 return ipsecdoi2pfkey_ealg(type);
668 case IPSECDOI_PROTO_IPCOMP:
669 return ipsecdoi2pfkey_calg(type);
670 default:
671 plog(LLV_ERROR, LOCATION, NULL,
672 "Invalid ipsec_doi algclass: %u\n", algclass);
673 return ~0;
675 /*NOTREACHED*/
678 /* SADB_SATYPE -> IPSECDOI_PROTO */
679 u_int
680 pfkey2ipsecdoi_proto(satype)
681 u_int satype;
683 switch (satype) {
684 case SADB_SATYPE_AH:
685 return IPSECDOI_PROTO_IPSEC_AH;
686 case SADB_SATYPE_ESP:
687 return IPSECDOI_PROTO_IPSEC_ESP;
688 case SADB_X_SATYPE_IPCOMP:
689 return IPSECDOI_PROTO_IPCOMP;
691 default:
692 plog(LLV_ERROR, LOCATION, NULL,
693 "Invalid pfkey proto: %u\n", satype);
694 return ~0;
696 /*NOTREACHED*/
699 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
700 u_int
701 ipsecdoi2pfkey_mode(mode)
702 u_int mode;
704 switch (mode) {
705 case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
706 #ifdef ENABLE_NATT
707 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
708 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
709 #endif
710 return IPSEC_MODE_TUNNEL;
711 case IPSECDOI_ATTR_ENC_MODE_TRNS:
712 #ifdef ENABLE_NATT
713 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
714 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
715 #endif
716 return IPSEC_MODE_TRANSPORT;
717 default:
718 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
719 return ~0;
721 /*NOTREACHED*/
724 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
725 u_int
726 pfkey2ipsecdoi_mode(mode)
727 u_int mode;
729 switch (mode) {
730 case IPSEC_MODE_TUNNEL:
731 return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
732 case IPSEC_MODE_TRANSPORT:
733 return IPSECDOI_ATTR_ENC_MODE_TRNS;
734 case IPSEC_MODE_ANY:
735 return IPSECDOI_ATTR_ENC_MODE_ANY;
736 default:
737 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
738 return ~0;
740 /*NOTREACHED*/
743 /* default key length for encryption algorithm */
744 static u_int
745 keylen_aalg(hashtype)
746 u_int hashtype;
748 int res;
750 if (hashtype == 0)
751 return SADB_AALG_NONE;
753 res = alg_ipsec_hmacdef_hashlen(hashtype);
754 if (res == -1) {
755 plog(LLV_ERROR, LOCATION, NULL,
756 "invalid hmac algorithm %u.\n", hashtype);
757 return ~0;
759 return res;
762 /* default key length for encryption algorithm */
763 static u_int
764 keylen_ealg(enctype, encklen)
765 u_int enctype;
766 int encklen;
768 int res;
770 res = alg_ipsec_encdef_keylen(enctype, encklen);
771 if (res == -1) {
772 plog(LLV_ERROR, LOCATION, NULL,
773 "invalid encryption algorithm %u.\n", enctype);
774 return ~0;
776 return res;
779 void
780 pk_fixup_sa_addresses(mhp)
781 caddr_t *mhp;
783 struct sockaddr *src, *dst;
785 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
786 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
787 set_port(src, PORT_ISAKMP);
788 set_port(dst, PORT_ISAKMP);
790 #ifdef ENABLE_NATT
791 if (PFKEY_ADDR_X_NATTYPE(mhp[SADB_X_EXT_NAT_T_TYPE])) {
792 /* NAT-T is enabled for this SADB entry; copy
793 * the ports from NAT-T extensions */
794 if(mhp[SADB_X_EXT_NAT_T_SPORT] != NULL)
795 set_port(src, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_SPORT]));
796 if(mhp[SADB_X_EXT_NAT_T_DPORT] != NULL)
797 set_port(dst, PFKEY_ADDR_X_PORT(mhp[SADB_X_EXT_NAT_T_DPORT]));
799 #endif
803 pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
804 e_type, e_keylen, a_type, a_keylen, flags)
805 u_int proto_id;
806 u_int t_id;
807 u_int hashtype;
808 u_int *e_type;
809 u_int *e_keylen;
810 u_int *a_type;
811 u_int *a_keylen;
812 u_int *flags;
814 *flags = 0;
815 switch (proto_id) {
816 case IPSECDOI_PROTO_IPSEC_ESP:
817 if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
818 goto bad;
819 if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
820 goto bad;
821 *e_keylen >>= 3;
823 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
824 goto bad;
825 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
826 goto bad;
827 *a_keylen >>= 3;
829 if (*e_type == SADB_EALG_NONE) {
830 plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
831 goto bad;
833 break;
835 case IPSECDOI_PROTO_IPSEC_AH:
836 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
837 goto bad;
838 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
839 goto bad;
840 *a_keylen >>= 3;
842 if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
843 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
844 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
845 *a_type = SADB_X_AALG_MD5;
846 *flags |= SADB_X_EXT_OLD;
848 *e_type = SADB_EALG_NONE;
849 *e_keylen = 0;
850 if (*a_type == SADB_AALG_NONE) {
851 plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
852 goto bad;
854 break;
856 case IPSECDOI_PROTO_IPCOMP:
857 if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
858 goto bad;
859 *e_keylen = 0;
861 *flags = SADB_X_EXT_RAWCPI;
863 *a_type = SADB_AALG_NONE;
864 *a_keylen = 0;
865 if (*e_type == SADB_X_CALG_NONE) {
866 plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
867 goto bad;
869 break;
871 default:
872 plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
873 goto bad;
876 return 0;
878 bad:
879 errno = EINVAL;
880 return -1;
883 /*%%%*/
884 /* send getspi message per ipsec protocol per remote address */
886 * the local address and remote address in ph1handle are dealed
887 * with destination address and source address respectively.
888 * Because SPI is decided by responder.
891 pk_sendgetspi(iph2)
892 struct ph2handle *iph2;
894 struct sockaddr *src = NULL, *dst = NULL;
895 u_int satype, mode;
896 struct saprop *pp;
897 struct saproto *pr;
898 u_int32_t minspi, maxspi;
899 u_int8_t natt_type = 0;
900 u_int16_t sport = 0, dport = 0;
902 if (iph2->side == INITIATOR)
903 pp = iph2->proposal;
904 else
905 pp = iph2->approval;
907 if (iph2->sa_src && iph2->sa_dst) {
908 /* MIPv6: Use SA addresses, not IKE ones */
909 src = dupsaddr(iph2->sa_src);
910 dst = dupsaddr(iph2->sa_dst);
911 } else {
912 /* Common case: SA addresses and IKE ones are the same */
913 src = dupsaddr(iph2->src);
914 dst = dupsaddr(iph2->dst);
917 if (src == NULL || dst == NULL) {
918 racoon_free(src);
919 racoon_free(dst);
920 return -1;
923 for (pr = pp->head; pr != NULL; pr = pr->next) {
925 /* validity check */
926 satype = ipsecdoi2pfkey_proto(pr->proto_id);
927 if (satype == ~0) {
928 plog(LLV_ERROR, LOCATION, NULL,
929 "invalid proto_id %d\n", pr->proto_id);
930 racoon_free(src);
931 racoon_free(dst);
932 return -1;
934 /* this works around a bug in Linux kernel where it allocates 4 byte
935 spi's for IPCOMP */
936 else if (satype == SADB_X_SATYPE_IPCOMP) {
937 minspi = 0x100;
938 maxspi = 0xffff;
940 else {
941 minspi = 0;
942 maxspi = 0;
944 mode = ipsecdoi2pfkey_mode(pr->encmode);
945 if (mode == ~0) {
946 plog(LLV_ERROR, LOCATION, NULL,
947 "invalid encmode %d\n", pr->encmode);
948 racoon_free(src);
949 racoon_free(dst);
950 return -1;
953 #ifdef ENABLE_NATT
954 if (pr->udp_encap) {
955 natt_type = iph2->ph1->natt_options->encaps_type;
956 sport=extract_port(src);
957 dport=extract_port(dst);
959 #endif
961 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
962 if (pfkey_send_getspi_nat(
963 lcconf->sock_pfkey,
964 satype,
965 mode,
966 dst, /* src of SA */
967 src, /* dst of SA */
968 natt_type,
969 dport,
970 sport,
971 minspi, maxspi,
972 pr->reqid_in, iph2->seq) < 0) {
973 plog(LLV_ERROR, LOCATION, NULL,
974 "ipseclib failed send getspi (%s)\n",
975 ipsec_strerror());
976 racoon_free(src);
977 racoon_free(dst);
978 return -1;
980 plog(LLV_DEBUG, LOCATION, NULL,
981 "pfkey GETSPI sent: %s\n",
982 sadbsecas2str(dst, src, satype, 0, mode));
985 racoon_free(src);
986 racoon_free(dst);
987 return 0;
991 * receive GETSPI from kernel.
993 static int
994 pk_recvgetspi(mhp)
995 caddr_t *mhp;
997 struct sadb_msg *msg;
998 struct sadb_sa *sa;
999 struct ph2handle *iph2;
1000 struct sockaddr *src, *dst;
1001 int proto_id;
1002 int allspiok, notfound;
1003 struct saprop *pp;
1004 struct saproto *pr;
1006 /* validity check */
1007 if (mhp[SADB_EXT_SA] == NULL
1008 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1009 || mhp[SADB_EXT_ADDRESS_SRC] == NULL) {
1010 plog(LLV_ERROR, LOCATION, NULL,
1011 "inappropriate sadb getspi message passed.\n");
1012 return -1;
1014 msg = (struct sadb_msg *)mhp[0];
1015 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1016 pk_fixup_sa_addresses(mhp);
1017 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
1018 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1020 /* the message has to be processed or not ? */
1021 if (msg->sadb_msg_pid != getpid()) {
1022 plog(LLV_DEBUG, LOCATION, NULL,
1023 "%s message is not interesting "
1024 "because pid %d is not mine.\n",
1025 s_pfkey_type(msg->sadb_msg_type),
1026 msg->sadb_msg_pid);
1027 return -1;
1030 iph2 = getph2byseq(msg->sadb_msg_seq);
1031 if (iph2 == NULL) {
1032 plog(LLV_DEBUG, LOCATION, NULL,
1033 "seq %d of %s message not interesting.\n",
1034 msg->sadb_msg_seq,
1035 s_pfkey_type(msg->sadb_msg_type));
1036 return -1;
1039 if (iph2->status != PHASE2ST_GETSPISENT) {
1040 plog(LLV_ERROR, LOCATION, NULL,
1041 "status mismatch (db:%d msg:%d)\n",
1042 iph2->status, PHASE2ST_GETSPISENT);
1043 return -1;
1046 /* set SPI, and check to get all spi whether or not */
1047 allspiok = 1;
1048 notfound = 1;
1049 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1050 pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
1052 for (pr = pp->head; pr != NULL; pr = pr->next) {
1053 if (pr->proto_id == proto_id && pr->spi == 0) {
1054 pr->spi = sa->sadb_sa_spi;
1055 notfound = 0;
1056 plog(LLV_DEBUG, LOCATION, NULL,
1057 "pfkey GETSPI succeeded: %s\n",
1058 sadbsecas2str(dst, src,
1059 msg->sadb_msg_satype,
1060 sa->sadb_sa_spi,
1061 ipsecdoi2pfkey_mode(pr->encmode)));
1063 if (pr->spi == 0)
1064 allspiok = 0; /* not get all spi */
1067 if (notfound) {
1068 plog(LLV_ERROR, LOCATION, NULL,
1069 "get spi for unknown address %s\n",
1070 saddrwop2str(dst));
1071 return -1;
1074 if (allspiok) {
1075 /* update status */
1076 iph2->status = PHASE2ST_GETSPIDONE;
1077 if (isakmp_post_getspi(iph2) < 0) {
1078 plog(LLV_ERROR, LOCATION, NULL,
1079 "failed to start post getspi.\n");
1080 remph2(iph2);
1081 delph2(iph2);
1082 iph2 = NULL;
1083 return -1;
1087 return 0;
1091 * set inbound SA
1094 pk_sendupdate(iph2)
1095 struct ph2handle *iph2;
1097 struct saproto *pr;
1098 struct pfkey_send_sa_args sa_args;
1100 /* sanity check */
1101 if (iph2->approval == NULL) {
1102 plog(LLV_ERROR, LOCATION, NULL,
1103 "no approvaled SAs found.\n");
1104 return -1;
1107 /* fill in some needed for pfkey_send_update2 */
1108 memset (&sa_args, 0, sizeof (sa_args));
1109 sa_args.so = lcconf->sock_pfkey;
1110 if (iph2->lifetime_secs)
1111 sa_args.l_addtime = iph2->lifetime_secs;
1112 else
1113 sa_args.l_addtime = iph2->approval->lifetime;
1114 sa_args.seq = iph2->seq;
1115 sa_args.wsize = 4;
1117 if (iph2->sa_src && iph2->sa_dst) {
1118 /* MIPv6: Use SA addresses, not IKE ones */
1119 sa_args.dst = dupsaddr(iph2->sa_src);
1120 sa_args.src = dupsaddr(iph2->sa_dst);
1121 } else {
1122 /* Common case: SA addresses and IKE ones are the same */
1123 sa_args.dst = dupsaddr(iph2->src);
1124 sa_args.src = dupsaddr(iph2->dst);
1127 if (sa_args.src == NULL || sa_args.dst == NULL) {
1128 racoon_free(sa_args.src);
1129 racoon_free(sa_args.dst);
1130 return -1;
1133 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1134 /* validity check */
1135 sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1136 if (sa_args.satype == ~0) {
1137 plog(LLV_ERROR, LOCATION, NULL,
1138 "invalid proto_id %d\n", pr->proto_id);
1139 racoon_free(sa_args.src);
1140 racoon_free(sa_args.dst);
1141 return -1;
1143 else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1144 /* IPCOMP has no replay window */
1145 sa_args.wsize = 0;
1147 #ifdef ENABLE_SAMODE_UNSPECIFIED
1148 sa_args.mode = IPSEC_MODE_ANY;
1149 #else
1150 sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1151 if (sa_args.mode == ~0) {
1152 plog(LLV_ERROR, LOCATION, NULL,
1153 "invalid encmode %d\n", pr->encmode);
1154 racoon_free(sa_args.src);
1155 racoon_free(sa_args.dst);
1156 return -1;
1158 #endif
1159 /* set algorithm type and key length */
1160 sa_args.e_keylen = pr->head->encklen;
1161 if (pfkey_convertfromipsecdoi(
1162 pr->proto_id,
1163 pr->head->trns_id,
1164 pr->head->authtype,
1165 &sa_args.e_type, &sa_args.e_keylen,
1166 &sa_args.a_type, &sa_args.a_keylen,
1167 &sa_args.flags) < 0){
1168 racoon_free(sa_args.src);
1169 racoon_free(sa_args.dst);
1170 return -1;
1173 #if 0
1174 sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1175 #else
1176 sa_args.l_bytes = 0;
1177 #endif
1179 #ifdef HAVE_SECCTX
1180 if (*iph2->approval->sctx.ctx_str) {
1181 sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1182 sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1183 sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1184 sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1186 #endif /* HAVE_SECCTX */
1188 #ifdef ENABLE_NATT
1189 if (pr->udp_encap) {
1190 sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
1191 sa_args.l_natt_sport = extract_port(iph2->ph1->remote);
1192 sa_args.l_natt_dport = extract_port(iph2->ph1->local);
1193 sa_args.l_natt_oa = iph2->natoa_src;
1194 #ifdef SADB_X_EXT_NAT_T_FRAG
1195 sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1196 #endif
1198 #endif
1200 /* more info to fill in */
1201 sa_args.spi = pr->spi;
1202 sa_args.reqid = pr->reqid_in;
1203 sa_args.keymat = pr->keymat->v;
1205 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n");
1206 if (pfkey_send_update2(&sa_args) < 0) {
1207 plog(LLV_ERROR, LOCATION, NULL,
1208 "libipsec failed send update (%s)\n",
1209 ipsec_strerror());
1210 racoon_free(sa_args.src);
1211 racoon_free(sa_args.dst);
1212 return -1;
1215 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1216 continue;
1219 * It maybe good idea to call backupsa_to_file() after
1220 * racoon will receive the sadb_update messages.
1221 * But it is impossible because there is not key in the
1222 * information from the kernel.
1225 /* change some things before backing up */
1226 sa_args.wsize = 4;
1227 sa_args.l_bytes = iph2->approval->lifebyte * 1024;
1229 if (backupsa_to_file(&sa_args) < 0) {
1230 plog(LLV_ERROR, LOCATION, NULL,
1231 "backuped SA failed: %s\n",
1232 sadbsecas2str(sa_args.src, sa_args.dst,
1233 sa_args.satype, sa_args.spi, sa_args.mode));
1235 plog(LLV_DEBUG, LOCATION, NULL,
1236 "backuped SA: %s\n",
1237 sadbsecas2str(sa_args.src, sa_args.dst,
1238 sa_args.satype, sa_args.spi, sa_args.mode));
1241 racoon_free(sa_args.src);
1242 racoon_free(sa_args.dst);
1243 return 0;
1246 static int
1247 pk_recvupdate(mhp)
1248 caddr_t *mhp;
1250 struct sadb_msg *msg;
1251 struct sadb_sa *sa;
1252 struct sockaddr *src, *dst;
1253 struct ph2handle *iph2;
1254 u_int proto_id, encmode, sa_mode;
1255 int incomplete = 0;
1256 struct saproto *pr;
1258 /* ignore this message because of local test mode. */
1259 if (f_local)
1260 return 0;
1262 /* sanity check */
1263 if (mhp[0] == NULL
1264 || mhp[SADB_EXT_SA] == NULL
1265 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1266 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1267 plog(LLV_ERROR, LOCATION, NULL,
1268 "inappropriate sadb update message passed.\n");
1269 return -1;
1271 msg = (struct sadb_msg *)mhp[0];
1272 pk_fixup_sa_addresses(mhp);
1273 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1274 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1275 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1277 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1278 ? IPSEC_MODE_ANY
1279 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1281 /* the message has to be processed or not ? */
1282 if (msg->sadb_msg_pid != getpid()) {
1283 plog(LLV_DEBUG, LOCATION, NULL,
1284 "%s message is not interesting "
1285 "because pid %d is not mine.\n",
1286 s_pfkey_type(msg->sadb_msg_type),
1287 msg->sadb_msg_pid);
1288 return -1;
1291 iph2 = getph2byseq(msg->sadb_msg_seq);
1292 if (iph2 == NULL) {
1293 plog(LLV_DEBUG, LOCATION, NULL,
1294 "seq %d of %s message not interesting.\n",
1295 msg->sadb_msg_seq,
1296 s_pfkey_type(msg->sadb_msg_type));
1297 return -1;
1300 if (iph2->status != PHASE2ST_ADDSA) {
1301 plog(LLV_ERROR, LOCATION, NULL,
1302 "status mismatch (db:%d msg:%d)\n",
1303 iph2->status, PHASE2ST_ADDSA);
1304 return -1;
1307 /* check to complete all keys ? */
1308 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1309 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1310 if (proto_id == ~0) {
1311 plog(LLV_ERROR, LOCATION, NULL,
1312 "invalid proto_id %d\n", msg->sadb_msg_satype);
1313 return -1;
1315 encmode = pfkey2ipsecdoi_mode(sa_mode);
1316 if (encmode == ~0) {
1317 plog(LLV_ERROR, LOCATION, NULL,
1318 "invalid encmode %d\n", sa_mode);
1319 return -1;
1322 if (pr->proto_id == proto_id
1323 && pr->spi == sa->sadb_sa_spi) {
1324 pr->ok = 1;
1325 plog(LLV_DEBUG, LOCATION, NULL,
1326 "pfkey UPDATE succeeded: %s\n",
1327 sadbsecas2str(dst, src,
1328 msg->sadb_msg_satype,
1329 sa->sadb_sa_spi,
1330 sa_mode));
1332 plog(LLV_INFO, LOCATION, NULL,
1333 "IPsec-SA established: %s\n",
1334 sadbsecas2str(dst, src,
1335 msg->sadb_msg_satype, sa->sadb_sa_spi,
1336 sa_mode));
1339 if (pr->ok == 0)
1340 incomplete = 1;
1343 if (incomplete)
1344 return 0;
1346 /* turn off the timer for calling pfkey_timeover() */
1347 sched_cancel(&iph2->sce);
1349 /* update status */
1350 iph2->status = PHASE2ST_ESTABLISHED;
1351 evt_phase2(iph2, EVT_PHASE2_UP, NULL);
1353 #ifdef ENABLE_STATS
1354 gettimeofday(&iph2->end, NULL);
1355 syslog(LOG_NOTICE, "%s(%s): %8.6f",
1356 "phase2", "quick", timedelta(&iph2->start, &iph2->end));
1357 #endif
1359 /* turn off schedule */
1360 sched_cancel(&iph2->scr);
1363 * since we are going to reuse the phase2 handler, we need to
1364 * remain it and refresh all the references between ph1 and ph2 to use.
1366 sched_schedule(&iph2->sce, iph2->approval->lifetime,
1367 isakmp_ph2expire_stub);
1369 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1370 return 0;
1374 * set outbound SA
1377 pk_sendadd(iph2)
1378 struct ph2handle *iph2;
1380 struct saproto *pr;
1381 struct pfkey_send_sa_args sa_args;
1383 /* sanity check */
1384 if (iph2->approval == NULL) {
1385 plog(LLV_ERROR, LOCATION, NULL,
1386 "no approvaled SAs found.\n");
1387 return -1;
1390 /* fill in some needed for pfkey_send_update2 */
1391 memset (&sa_args, 0, sizeof (sa_args));
1392 sa_args.so = lcconf->sock_pfkey;
1393 if (iph2->lifetime_secs)
1394 sa_args.l_addtime = iph2->lifetime_secs;
1395 else
1396 sa_args.l_addtime = iph2->approval->lifetime;
1397 sa_args.seq = iph2->seq;
1398 sa_args.wsize = 4;
1400 if (iph2->sa_src && iph2->sa_dst) {
1401 /* MIPv6: Use SA addresses, not IKE ones */
1402 sa_args.src = dupsaddr(iph2->sa_src);
1403 sa_args.dst = dupsaddr(iph2->sa_dst);
1404 } else {
1405 /* Common case: SA addresses and IKE ones are the same */
1406 sa_args.src = dupsaddr(iph2->src);
1407 sa_args.dst = dupsaddr(iph2->dst);
1410 if (sa_args.src == NULL || sa_args.dst == NULL) {
1411 racoon_free(sa_args.src);
1412 racoon_free(sa_args.dst);
1413 return -1;
1416 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1417 /* validity check */
1418 sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1419 if (sa_args.satype == ~0) {
1420 plog(LLV_ERROR, LOCATION, NULL,
1421 "invalid proto_id %d\n", pr->proto_id);
1422 racoon_free(sa_args.src);
1423 racoon_free(sa_args.dst);
1424 return -1;
1426 else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1427 /* no replay window for IPCOMP */
1428 sa_args.wsize = 0;
1430 #ifdef ENABLE_SAMODE_UNSPECIFIED
1431 sa_args.mode = IPSEC_MODE_ANY;
1432 #else
1433 sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1434 if (sa_args.mode == ~0) {
1435 plog(LLV_ERROR, LOCATION, NULL,
1436 "invalid encmode %d\n", pr->encmode);
1437 racoon_free(sa_args.src);
1438 racoon_free(sa_args.dst);
1439 return -1;
1441 #endif
1443 /* set algorithm type and key length */
1444 sa_args.e_keylen = pr->head->encklen;
1445 if (pfkey_convertfromipsecdoi(
1446 pr->proto_id,
1447 pr->head->trns_id,
1448 pr->head->authtype,
1449 &sa_args.e_type, &sa_args.e_keylen,
1450 &sa_args.a_type, &sa_args.a_keylen,
1451 &sa_args.flags) < 0){
1452 racoon_free(sa_args.src);
1453 racoon_free(sa_args.dst);
1454 return -1;
1457 #if 0
1458 sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1459 #else
1460 sa_args.l_bytes = 0;
1461 #endif
1463 #ifdef HAVE_SECCTX
1464 if (*iph2->approval->sctx.ctx_str) {
1465 sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1466 sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1467 sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1468 sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1470 #endif /* HAVE_SECCTX */
1472 #ifdef ENABLE_NATT
1473 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
1474 "(NAT flavor)\n");
1476 if (pr->udp_encap) {
1477 sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
1478 sa_args.l_natt_sport = extract_port(iph2->ph1->local);
1479 sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
1480 sa_args.l_natt_oa = iph2->natoa_dst;
1481 #ifdef SADB_X_EXT_NAT_T_FRAG
1482 sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1483 #endif
1485 #endif
1486 /* more info to fill in */
1487 sa_args.spi = pr->spi_p;
1488 sa_args.reqid = pr->reqid_out;
1489 sa_args.keymat = pr->keymat_p->v;
1491 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
1492 if (pfkey_send_add2(&sa_args) < 0) {
1493 plog(LLV_ERROR, LOCATION, NULL,
1494 "libipsec failed send add (%s)\n",
1495 ipsec_strerror());
1496 racoon_free(sa_args.src);
1497 racoon_free(sa_args.dst);
1498 return -1;
1501 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1502 continue;
1505 * It maybe good idea to call backupsa_to_file() after
1506 * racoon will receive the sadb_update messages.
1507 * But it is impossible because there is not key in the
1508 * information from the kernel.
1510 if (backupsa_to_file(&sa_args) < 0) {
1511 plog(LLV_ERROR, LOCATION, NULL,
1512 "backuped SA failed: %s\n",
1513 sadbsecas2str(sa_args.src, sa_args.dst,
1514 sa_args.satype, sa_args.spi, sa_args.mode));
1516 plog(LLV_DEBUG, LOCATION, NULL,
1517 "backuped SA: %s\n",
1518 sadbsecas2str(sa_args.src, sa_args.dst,
1519 sa_args.satype, sa_args.spi, sa_args.mode));
1521 racoon_free(sa_args.src);
1522 racoon_free(sa_args.dst);
1523 return 0;
1526 static int
1527 pk_recvadd(mhp)
1528 caddr_t *mhp;
1530 struct sadb_msg *msg;
1531 struct sadb_sa *sa;
1532 struct sockaddr *src, *dst;
1533 struct ph2handle *iph2;
1534 u_int sa_mode;
1536 /* ignore this message because of local test mode. */
1537 if (f_local)
1538 return 0;
1540 /* sanity check */
1541 if (mhp[0] == NULL
1542 || mhp[SADB_EXT_SA] == NULL
1543 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1544 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1545 plog(LLV_ERROR, LOCATION, NULL,
1546 "inappropriate sadb add message passed.\n");
1547 return -1;
1549 msg = (struct sadb_msg *)mhp[0];
1550 pk_fixup_sa_addresses(mhp);
1551 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1552 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1553 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1555 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1556 ? IPSEC_MODE_ANY
1557 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1559 /* the message has to be processed or not ? */
1560 if (msg->sadb_msg_pid != getpid()) {
1561 plog(LLV_DEBUG, LOCATION, NULL,
1562 "%s message is not interesting "
1563 "because pid %d is not mine.\n",
1564 s_pfkey_type(msg->sadb_msg_type),
1565 msg->sadb_msg_pid);
1566 return -1;
1569 iph2 = getph2byseq(msg->sadb_msg_seq);
1570 if (iph2 == NULL) {
1571 plog(LLV_DEBUG, LOCATION, NULL,
1572 "seq %d of %s message not interesting.\n",
1573 msg->sadb_msg_seq,
1574 s_pfkey_type(msg->sadb_msg_type));
1575 return -1;
1579 * NOTE don't update any status of phase2 handle
1580 * because they must be updated by SADB_UPDATE message
1583 plog(LLV_INFO, LOCATION, NULL,
1584 "IPsec-SA established: %s\n",
1585 sadbsecas2str(src, dst,
1586 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1588 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1589 return 0;
1592 static int
1593 pk_recvexpire(mhp)
1594 caddr_t *mhp;
1596 struct sadb_msg *msg;
1597 struct sadb_sa *sa;
1598 struct sockaddr *src, *dst;
1599 struct ph2handle *iph2;
1600 u_int proto_id, sa_mode;
1602 /* sanity check */
1603 if (mhp[0] == NULL
1604 || mhp[SADB_EXT_SA] == NULL
1605 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1606 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1607 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1608 && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1609 plog(LLV_ERROR, LOCATION, NULL,
1610 "inappropriate sadb expire message passed.\n");
1611 return -1;
1613 msg = (struct sadb_msg *)mhp[0];
1614 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1615 pk_fixup_sa_addresses(mhp);
1616 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1617 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1619 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1620 ? IPSEC_MODE_ANY
1621 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1623 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1624 if (proto_id == ~0) {
1625 plog(LLV_ERROR, LOCATION, NULL,
1626 "invalid proto_id %d\n", msg->sadb_msg_satype);
1627 return -1;
1630 plog(LLV_INFO, LOCATION, NULL,
1631 "IPsec-SA expired: %s\n",
1632 sadbsecas2str(src, dst,
1633 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1635 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1636 if (iph2 == NULL) {
1638 * Ignore it because two expire messages are come up.
1639 * phase2 handler has been deleted already when 2nd message
1640 * is received.
1642 plog(LLV_DEBUG, LOCATION, NULL,
1643 "no such a SA found: %s\n",
1644 sadbsecas2str(src, dst,
1645 msg->sadb_msg_satype, sa->sadb_sa_spi,
1646 sa_mode));
1647 return 0;
1650 /* resent expiry message? */
1651 if (iph2->status > PHASE2ST_ESTABLISHED)
1652 return 0;
1654 /* still negotiating? */
1655 if (iph2->status < PHASE2ST_ESTABLISHED) {
1656 /* not a hard timeout? */
1657 if (mhp[SADB_EXT_LIFETIME_HARD] == NULL)
1658 return 0;
1661 * We were negotiating for that SA (w/o much success
1662 * from current status) and kernel has decided our time
1663 * is over trying (xfrm_larval_drop controls that and
1664 * is enabled by default on Linux >= 2.6.28 kernels).
1666 plog(LLV_WARNING, LOCATION, NULL,
1667 "PF_KEY EXPIRE message received from kernel for SA"
1668 " being negotiated. Stopping negotiation.\n");
1671 /* turn off the timer for calling isakmp_ph2expire() */
1672 sched_cancel(&iph2->sce);
1674 if (iph2->status == PHASE2ST_ESTABLISHED &&
1675 iph2->side == INITIATOR) {
1676 struct ph1handle *iph1hint;
1678 * Active phase 2 expired and we were initiator.
1679 * Begin new phase 2 exchange, so we can keep on sending
1680 * traffic.
1683 /* update status for re-use */
1684 iph1hint = iph2->ph1;
1685 initph2(iph2);
1686 iph2->status = PHASE2ST_STATUS2;
1688 /* start quick exchange */
1689 if (isakmp_post_acquire(iph2, iph1hint) < 0) {
1690 plog(LLV_ERROR, LOCATION, iph2->dst,
1691 "failed to begin ipsec sa "
1692 "re-negotication.\n");
1693 remph2(iph2);
1694 delph2(iph2);
1695 return -1;
1698 return 0;
1702 * We are responder or the phase 2 was not established.
1703 * Just remove the ph2handle to reflect SADB.
1705 iph2->status = PHASE2ST_EXPIRED;
1706 remph2(iph2);
1707 delph2(iph2);
1709 return 0;
1712 static int
1713 pk_recvacquire(mhp)
1714 caddr_t *mhp;
1716 struct sadb_msg *msg;
1717 struct sadb_x_policy *xpl;
1718 struct secpolicy *sp_out = NULL, *sp_in = NULL;
1719 struct ph2handle *iph2;
1720 struct sockaddr *src, *dst; /* IKE addresses (for exchanges) */
1721 struct sockaddr *sp_src, *sp_dst; /* SP addresses (selectors). */
1722 struct sockaddr *sa_src = NULL, *sa_dst = NULL ; /* SA addresses */
1723 #ifdef HAVE_SECCTX
1724 struct sadb_x_sec_ctx *m_sec_ctx;
1725 #endif /* HAVE_SECCTX */
1726 struct policyindex spidx;
1728 /* ignore this message because of local test mode. */
1729 if (f_local)
1730 return 0;
1732 /* sanity check */
1733 if (mhp[0] == NULL
1734 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1735 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1736 || mhp[SADB_X_EXT_POLICY] == NULL) {
1737 plog(LLV_ERROR, LOCATION, NULL,
1738 "inappropriate sadb acquire message passed.\n");
1739 return -1;
1741 msg = (struct sadb_msg *)mhp[0];
1742 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1743 /* acquire does not have nat-t ports; so do not bother setting
1744 * the default port 500; just use the port zero for wildcard
1745 * matching the get a valid natted destination */
1746 sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1747 sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1749 #ifdef HAVE_SECCTX
1750 m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
1752 if (m_sec_ctx != NULL) {
1753 plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
1754 m_sec_ctx->sadb_x_ctx_doi);
1755 plog(LLV_INFO, LOCATION, NULL,
1756 "security context algorithm: %u\n",
1757 m_sec_ctx->sadb_x_ctx_alg);
1758 plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
1759 m_sec_ctx->sadb_x_ctx_len);
1760 plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
1761 ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
1763 #endif /* HAVE_SECCTX */
1765 /* ignore if type is not IPSEC_POLICY_IPSEC */
1766 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1767 plog(LLV_DEBUG, LOCATION, NULL,
1768 "ignore ACQUIRE message. type is not IPsec.\n");
1769 return 0;
1772 /* ignore it if src or dst are multicast addresses. */
1773 if ((sp_dst->sa_family == AF_INET
1774 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_dst)->sin_addr.s_addr)))
1775 #ifdef INET6
1776 || (sp_dst->sa_family == AF_INET6
1777 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_dst)->sin6_addr))
1778 #endif
1780 plog(LLV_DEBUG, LOCATION, NULL,
1781 "ignore due to multicast destination address: %s.\n",
1782 saddrwop2str(sp_dst));
1783 return 0;
1786 if ((sp_src->sa_family == AF_INET
1787 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_src)->sin_addr.s_addr)))
1788 #ifdef INET6
1789 || (sp_src->sa_family == AF_INET6
1790 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_src)->sin6_addr))
1791 #endif
1793 plog(LLV_DEBUG, LOCATION, NULL,
1794 "ignore due to multicast source address: %s.\n",
1795 saddrwop2str(sp_src));
1796 return 0;
1799 /* search for proper policyindex */
1800 sp_out = getspbyspid(xpl->sadb_x_policy_id);
1801 if (sp_out == NULL) {
1802 plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1803 xpl->sadb_x_policy_id);
1804 return -1;
1806 plog(LLV_DEBUG, LOCATION, NULL,
1807 "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1809 /* Before going further, let first get the source and destination
1810 * address that would be used for IKE negotiation. The logic is:
1811 * - if SP from SPD image contains local and remote hints, we
1812 * use them (provided by MIGRATE).
1813 * - otherwise, we use the ones from the ipsecrequest, which means:
1814 * - the addresses from the request for transport mode
1815 * - the endpoints addresses for tunnel mode
1817 * Note that:
1818 * 1) racoon does not support negotiation of bundles which
1819 * simplifies the lookup for the addresses in the ipsecrequest
1820 * list, as we expect only one.
1821 * 2) We do source and destination parts all together and do not
1822 * accept semi-defined information. This is just a decision,
1823 * there might be needs.
1825 * --arno
1827 if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) {
1828 /* For Tunnel mode, SA addresses are the endpoints */
1829 src = (struct sockaddr *) &sp_out->req->saidx.src;
1830 dst = (struct sockaddr *) &sp_out->req->saidx.dst;
1831 } else {
1832 /* Otherwise use requested addresses.
1834 * We need to explicitly setup sa_src and sa_dst too,
1835 * since the SA ports are different from IKE port. And
1836 * src/dst ports will be overwritten when the matching
1837 * phase1 is found. */
1838 src = sa_src = sp_src;
1839 dst = sa_dst = sp_dst;
1841 if (sp_out->local && sp_out->remote) {
1842 /* hints available, let's use them */
1843 sa_src = src;
1844 sa_dst = dst;
1845 src = (struct sockaddr *) sp_out->local;
1846 dst = (struct sockaddr *) sp_out->remote;
1850 * If there is a phase 2 handler against the policy identifier in
1851 * the acquire message, and if
1852 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1853 * should ignore such a acquire message because the phase 2
1854 * is just negotiating.
1855 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1856 * has to prcesss such a acquire message because racoon may
1857 * lost the expire message.
1859 iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id);
1860 if (iph2 != NULL) {
1861 if (iph2->status < PHASE2ST_ESTABLISHED) {
1862 plog(LLV_DEBUG, LOCATION, NULL,
1863 "ignore the acquire because ph2 found\n");
1864 return -1;
1866 if (iph2->status == PHASE2ST_EXPIRED)
1867 iph2 = NULL;
1868 /*FALLTHROUGH*/
1871 /* Check we are listening on source address. If not, ignore. */
1872 if (myaddr_getsport(src) == -1) {
1873 plog(LLV_DEBUG, LOCATION, NULL,
1874 "Not listening on source address %s. Ignoring ACQUIRE.\n",
1875 saddrwop2str(src));
1876 return 0;
1879 /* get inbound policy */
1882 memset(&spidx, 0, sizeof(spidx));
1883 spidx.dir = IPSEC_DIR_INBOUND;
1884 memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1885 memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1886 spidx.prefs = sp_out->spidx.prefd;
1887 spidx.prefd = sp_out->spidx.prefs;
1888 spidx.ul_proto = sp_out->spidx.ul_proto;
1890 #ifdef HAVE_SECCTX
1891 if (m_sec_ctx) {
1892 spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
1893 spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
1894 spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
1895 memcpy(spidx.sec_ctx.ctx_str,
1896 ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
1897 spidx.sec_ctx.ctx_strlen);
1899 #endif /* HAVE_SECCTX */
1901 sp_in = getsp(&spidx);
1902 if (sp_in) {
1903 plog(LLV_DEBUG, LOCATION, NULL,
1904 "suitable inbound SP found: %s.\n",
1905 spidx2str(&sp_in->spidx));
1906 } else {
1907 plog(LLV_NOTIFY, LOCATION, NULL,
1908 "no in-bound policy found: %s\n",
1909 spidx2str(&spidx));
1913 /* allocate a phase 2 */
1914 iph2 = newph2();
1915 if (iph2 == NULL) {
1916 plog(LLV_ERROR, LOCATION, NULL,
1917 "failed to allocate phase2 entry.\n");
1918 return -1;
1920 iph2->side = INITIATOR;
1921 iph2->spid = xpl->sadb_x_policy_id;
1922 iph2->satype = msg->sadb_msg_satype;
1923 iph2->seq = msg->sadb_msg_seq;
1924 iph2->status = PHASE2ST_STATUS2;
1926 /* set address used by IKE for the negotiation (might differ from
1927 * SA address, i.e. might not be tunnel endpoints or addresses
1928 * of transport mode SA) */
1929 iph2->dst = dupsaddr(dst);
1930 if (iph2->dst == NULL) {
1931 delph2(iph2);
1932 return -1;
1934 iph2->src = dupsaddr(src);
1935 if (iph2->src == NULL) {
1936 delph2(iph2);
1937 return -1;
1940 /* If sa_src and sa_dst have been set, this mean we have to
1941 * set iph2->sa_src and iph2->sa_dst to provide the addresses
1942 * of the SA because iph2->src and iph2->dst are only the ones
1943 * used for the IKE exchanges. Those that need these addresses
1944 * are for instance pk_sendupdate() or pk_sendgetspi() */
1945 if (sa_src) {
1946 iph2->sa_src = dupsaddr(sa_src);
1947 iph2->sa_dst = dupsaddr(sa_dst);
1950 if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
1951 delph2(iph2);
1952 return -1;
1955 #ifdef HAVE_SECCTX
1956 if (m_sec_ctx) {
1957 set_secctx_in_proposal(iph2, spidx);
1959 #endif /* HAVE_SECCTX */
1961 insph2(iph2);
1963 /* start isakmp initiation by using ident exchange */
1964 /* XXX should be looped if there are multiple phase 2 handler. */
1965 if (isakmp_post_acquire(iph2, NULL) < 0) {
1966 plog(LLV_ERROR, LOCATION, NULL,
1967 "failed to begin ipsec sa negotication.\n");
1968 remph2(iph2);
1969 delph2(iph2);
1970 return -1;
1973 return 0;
1976 static int
1977 pk_recvdelete(mhp)
1978 caddr_t *mhp;
1980 struct sadb_msg *msg;
1981 struct sadb_sa *sa;
1982 struct sockaddr *src, *dst;
1983 struct ph2handle *iph2 = NULL;
1984 u_int proto_id;
1986 /* ignore this message because of local test mode. */
1987 if (f_local)
1988 return 0;
1990 /* sanity check */
1991 if (mhp[0] == NULL
1992 || mhp[SADB_EXT_SA] == NULL
1993 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1994 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1995 plog(LLV_ERROR, LOCATION, NULL,
1996 "inappropriate sadb delete message passed.\n");
1997 return -1;
1999 msg = (struct sadb_msg *)mhp[0];
2000 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
2001 pk_fixup_sa_addresses(mhp);
2002 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
2003 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
2005 /* the message has to be processed or not ? */
2006 if (msg->sadb_msg_pid == getpid()) {
2007 plog(LLV_DEBUG, LOCATION, NULL,
2008 "%s message is not interesting "
2009 "because the message was originated by me.\n",
2010 s_pfkey_type(msg->sadb_msg_type));
2011 return -1;
2014 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
2015 if (proto_id == ~0) {
2016 plog(LLV_ERROR, LOCATION, NULL,
2017 "invalid proto_id %d\n", msg->sadb_msg_satype);
2018 return -1;
2021 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
2022 if (iph2 == NULL) {
2023 /* ignore */
2024 plog(LLV_ERROR, LOCATION, NULL,
2025 "no iph2 found: %s\n",
2026 sadbsecas2str(src, dst, msg->sadb_msg_satype,
2027 sa->sadb_sa_spi, IPSEC_MODE_ANY));
2028 return 0;
2031 plog(LLV_ERROR, LOCATION, NULL,
2032 "pfkey DELETE received: %s\n",
2033 sadbsecas2str(src, dst,
2034 msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
2036 /* send delete information */
2037 if (iph2->status == PHASE2ST_ESTABLISHED)
2038 isakmp_info_send_d2(iph2);
2040 remph2(iph2);
2041 delph2(iph2);
2043 return 0;
2046 static int
2047 pk_recvflush(mhp)
2048 caddr_t *mhp;
2050 /* ignore this message because of local test mode. */
2051 if (f_local)
2052 return 0;
2054 /* sanity check */
2055 if (mhp[0] == NULL) {
2056 plog(LLV_ERROR, LOCATION, NULL,
2057 "inappropriate sadb flush message passed.\n");
2058 return -1;
2061 flushph2();
2063 return 0;
2066 static int
2067 getsadbpolicy(policy0, policylen0, type, iph2)
2068 caddr_t *policy0;
2069 int *policylen0, type;
2070 struct ph2handle *iph2;
2072 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2073 struct sockaddr *src = NULL, *dst = NULL;
2074 struct sadb_x_policy *xpl;
2075 struct sadb_x_ipsecrequest *xisr;
2076 struct saproto *pr;
2077 struct saproto **pr_rlist;
2078 int rlist_len = 0;
2079 caddr_t policy, p;
2080 int policylen;
2081 int xisrlen;
2082 u_int satype, mode;
2083 int len = 0;
2084 #ifdef HAVE_SECCTX
2085 int ctxlen = 0;
2086 #endif /* HAVE_SECCTX */
2089 /* get policy buffer size */
2090 policylen = sizeof(struct sadb_x_policy);
2091 if (type != SADB_X_SPDDELETE) {
2092 if (iph2->sa_src && iph2->sa_dst) {
2093 src = iph2->sa_src; /* MIPv6: Use SA addresses, */
2094 dst = iph2->sa_dst; /* not IKE ones */
2095 } else {
2096 src = iph2->src; /* Common case: SA addresses */
2097 dst = iph2->dst; /* and IKE ones are the same */
2100 for (pr = iph2->approval->head; pr; pr = pr->next) {
2101 xisrlen = sizeof(*xisr);
2102 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2103 xisrlen += (sysdep_sa_len(src) +
2104 sysdep_sa_len(dst));
2107 policylen += PFKEY_ALIGN8(xisrlen);
2111 #ifdef HAVE_SECCTX
2112 if (*spidx->sec_ctx.ctx_str) {
2113 ctxlen = sizeof(struct sadb_x_sec_ctx)
2114 + PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
2115 policylen += ctxlen;
2117 #endif /* HAVE_SECCTX */
2119 /* make policy structure */
2120 policy = racoon_malloc(policylen);
2121 memset((void*)policy, 0xcd, policylen);
2122 if (!policy) {
2123 plog(LLV_ERROR, LOCATION, NULL,
2124 "buffer allocation failed.\n");
2125 return -1;
2128 xpl = (struct sadb_x_policy *)policy;
2129 xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2130 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2131 xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2132 xpl->sadb_x_policy_dir = spidx->dir;
2133 xpl->sadb_x_policy_id = 0;
2134 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2135 xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2136 #endif
2137 len++;
2139 #ifdef HAVE_SECCTX
2140 if (*spidx->sec_ctx.ctx_str) {
2141 struct sadb_x_sec_ctx *p;
2143 p = (struct sadb_x_sec_ctx *)(xpl + len);
2144 memset(p, 0, ctxlen);
2145 p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
2146 p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2147 p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
2148 p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
2149 p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
2151 memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
2152 len += ctxlen;
2154 #endif /* HAVE_SECCTX */
2156 /* no need to append policy information any more if type is SPDDELETE */
2157 if (type == SADB_X_SPDDELETE)
2158 goto end;
2160 xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
2162 /* The order of things is reversed for use in add policy messages */
2163 for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
2164 pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
2165 if (!pr_rlist) {
2166 plog(LLV_ERROR, LOCATION, NULL,
2167 "buffer allocation failed.\n");
2168 return -1;
2170 pr_rlist[rlist_len--] = NULL;
2171 for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
2172 rlist_len = 0;
2174 for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
2176 satype = doi2ipproto(pr->proto_id);
2177 if (satype == ~0) {
2178 plog(LLV_ERROR, LOCATION, NULL,
2179 "invalid proto_id %d\n", pr->proto_id);
2180 goto err;
2182 mode = ipsecdoi2pfkey_mode(pr->encmode);
2183 if (mode == ~0) {
2184 plog(LLV_ERROR, LOCATION, NULL,
2185 "invalid encmode %d\n", pr->encmode);
2186 goto err;
2190 * the policy level cannot be unique because the policy
2191 * is defined later than SA, so req_id cannot be bound to SA.
2193 xisr->sadb_x_ipsecrequest_proto = satype;
2194 xisr->sadb_x_ipsecrequest_mode = mode;
2195 if(iph2->proposal->head->reqid_in > 0){
2196 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
2197 xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
2198 }else{
2199 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2200 xisr->sadb_x_ipsecrequest_reqid = 0;
2202 p = (caddr_t)(xisr + 1);
2204 xisrlen = sizeof(*xisr);
2206 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2207 int src_len, dst_len;
2209 src_len = sysdep_sa_len(src);
2210 dst_len = sysdep_sa_len(dst);
2211 xisrlen += src_len + dst_len;
2213 memcpy(p, src, src_len);
2214 p += src_len;
2216 memcpy(p, dst, dst_len);
2217 p += dst_len;
2220 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2221 xisr = (struct sadb_x_ipsecrequest *)p;
2224 racoon_free(pr_rlist);
2226 end:
2227 *policy0 = policy;
2228 *policylen0 = policylen;
2230 return 0;
2232 err:
2233 if (policy)
2234 racoon_free(policy);
2235 if (pr_rlist) racoon_free(pr_rlist);
2237 return -1;
2241 pk_sendspdupdate2(iph2)
2242 struct ph2handle *iph2;
2244 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2245 caddr_t policy = NULL;
2246 int policylen = 0;
2247 u_int64_t ltime, vtime;
2249 ltime = iph2->approval->lifetime;
2250 vtime = 0;
2252 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2253 plog(LLV_ERROR, LOCATION, NULL,
2254 "getting sadb policy failed.\n");
2255 return -1;
2258 if (pfkey_send_spdupdate2(
2259 lcconf->sock_pfkey,
2260 (struct sockaddr *)&spidx->src,
2261 spidx->prefs,
2262 (struct sockaddr *)&spidx->dst,
2263 spidx->prefd,
2264 spidx->ul_proto,
2265 ltime, vtime,
2266 policy, policylen, 0) < 0) {
2267 plog(LLV_ERROR, LOCATION, NULL,
2268 "libipsec failed send spdupdate2 (%s)\n",
2269 ipsec_strerror());
2270 goto end;
2272 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
2274 end:
2275 if (policy)
2276 racoon_free(policy);
2278 return 0;
2281 static int
2282 pk_recvspdupdate(mhp)
2283 caddr_t *mhp;
2285 struct sadb_address *saddr, *daddr;
2286 struct sadb_x_policy *xpl;
2287 struct sadb_lifetime *lt;
2288 struct policyindex spidx;
2289 struct secpolicy *sp;
2290 struct sockaddr *local=NULL, *remote=NULL;
2291 u_int64_t created;
2292 int ret;
2294 /* sanity check */
2295 if (mhp[0] == NULL
2296 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2297 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2298 || mhp[SADB_X_EXT_POLICY] == NULL) {
2299 plog(LLV_ERROR, LOCATION, NULL,
2300 "inappropriate sadb spdupdate message passed.\n");
2301 return -1;
2303 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2304 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2305 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2306 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2307 if(lt != NULL)
2308 created = lt->sadb_lifetime_addtime;
2309 else
2310 created = 0;
2312 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2313 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2314 saddr + 1,
2315 daddr + 1,
2316 saddr->sadb_address_prefixlen,
2317 daddr->sadb_address_prefixlen,
2318 saddr->sadb_address_proto,
2319 xpl->sadb_x_policy_priority,
2320 created,
2321 &spidx);
2322 #else
2323 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2324 saddr + 1,
2325 daddr + 1,
2326 saddr->sadb_address_prefixlen,
2327 daddr->sadb_address_prefixlen,
2328 saddr->sadb_address_proto,
2329 created,
2330 &spidx);
2331 #endif
2333 #ifdef HAVE_SECCTX
2334 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2335 struct sadb_x_sec_ctx *ctx;
2337 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2338 spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2339 spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2340 spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2341 memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2343 #endif /* HAVE_SECCTX */
2345 sp = getsp(&spidx);
2346 if (sp == NULL) {
2347 plog(LLV_ERROR, LOCATION, NULL,
2348 "such policy does not already exist: \"%s\"\n",
2349 spidx2str(&spidx));
2350 } else {
2351 /* preserve hints before deleting the SP */
2352 local = sp->local;
2353 remote = sp->remote;
2354 sp->local = NULL;
2355 sp->remote = NULL;
2357 remsp(sp);
2358 delsp(sp);
2361 /* Add new SP (with old hints) */
2362 ret = addnewsp(mhp, local, remote);
2364 if (local != NULL)
2365 racoon_free(local);
2366 if (remote != NULL)
2367 racoon_free(remote);
2369 if (ret < 0)
2370 return -1;
2372 return 0;
2376 * this function has to be used by responder side.
2379 pk_sendspdadd2(iph2)
2380 struct ph2handle *iph2;
2382 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2383 caddr_t policy = NULL;
2384 int policylen = 0;
2385 u_int64_t ltime, vtime;
2387 ltime = iph2->approval->lifetime;
2388 vtime = 0;
2390 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2391 plog(LLV_ERROR, LOCATION, NULL,
2392 "getting sadb policy failed.\n");
2393 return -1;
2396 if (pfkey_send_spdadd2(
2397 lcconf->sock_pfkey,
2398 (struct sockaddr *)&spidx->src,
2399 spidx->prefs,
2400 (struct sockaddr *)&spidx->dst,
2401 spidx->prefd,
2402 spidx->ul_proto,
2403 ltime, vtime,
2404 policy, policylen, 0) < 0) {
2405 plog(LLV_ERROR, LOCATION, NULL,
2406 "libipsec failed send spdadd2 (%s)\n",
2407 ipsec_strerror());
2408 goto end;
2410 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
2412 end:
2413 if (policy)
2414 racoon_free(policy);
2416 return 0;
2419 static int
2420 pk_recvspdadd(mhp)
2421 caddr_t *mhp;
2423 struct sadb_address *saddr, *daddr;
2424 struct sadb_x_policy *xpl;
2425 struct sadb_lifetime *lt;
2426 struct policyindex spidx;
2427 struct secpolicy *sp;
2428 struct sockaddr *local = NULL, *remote = NULL;
2429 u_int64_t created;
2430 int ret;
2432 /* sanity check */
2433 if (mhp[0] == NULL
2434 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2435 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2436 || mhp[SADB_X_EXT_POLICY] == NULL) {
2437 plog(LLV_ERROR, LOCATION, NULL,
2438 "inappropriate sadb spdadd message passed.\n");
2439 return -1;
2441 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2442 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2443 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2444 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2445 if(lt != NULL)
2446 created = lt->sadb_lifetime_addtime;
2447 else
2448 created = 0;
2450 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2451 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2452 saddr + 1,
2453 daddr + 1,
2454 saddr->sadb_address_prefixlen,
2455 daddr->sadb_address_prefixlen,
2456 saddr->sadb_address_proto,
2457 xpl->sadb_x_policy_priority,
2458 created,
2459 &spidx);
2460 #else
2461 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2462 saddr + 1,
2463 daddr + 1,
2464 saddr->sadb_address_prefixlen,
2465 daddr->sadb_address_prefixlen,
2466 saddr->sadb_address_proto,
2467 created,
2468 &spidx);
2469 #endif
2471 #ifdef HAVE_SECCTX
2472 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2473 struct sadb_x_sec_ctx *ctx;
2475 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2476 spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2477 spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2478 spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2479 memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2481 #endif /* HAVE_SECCTX */
2483 sp = getsp(&spidx);
2484 if (sp != NULL) {
2485 plog(LLV_ERROR, LOCATION, NULL,
2486 "such policy already exists. "
2487 "anyway replace it: %s\n",
2488 spidx2str(&spidx));
2490 /* preserve hints before deleting the SP */
2491 local = sp->local;
2492 remote = sp->remote;
2493 sp->local = NULL;
2494 sp->remote = NULL;
2496 remsp(sp);
2497 delsp(sp);
2500 /* Add new SP (with old hints) */
2501 ret = addnewsp(mhp, local, remote);
2503 if (local != NULL)
2504 racoon_free(local);
2505 if (remote != NULL)
2506 racoon_free(remote);
2508 if (ret < 0)
2509 return -1;
2511 return 0;
2515 * this function has to be used by responder side.
2518 pk_sendspddelete(iph2)
2519 struct ph2handle *iph2;
2521 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2522 caddr_t policy = NULL;
2523 int policylen;
2525 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2526 plog(LLV_ERROR, LOCATION, NULL,
2527 "getting sadb policy failed.\n");
2528 return -1;
2531 if (pfkey_send_spddelete(
2532 lcconf->sock_pfkey,
2533 (struct sockaddr *)&spidx->src,
2534 spidx->prefs,
2535 (struct sockaddr *)&spidx->dst,
2536 spidx->prefd,
2537 spidx->ul_proto,
2538 policy, policylen, 0) < 0) {
2539 plog(LLV_ERROR, LOCATION, NULL,
2540 "libipsec failed send spddelete (%s)\n",
2541 ipsec_strerror());
2542 goto end;
2544 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2546 end:
2547 if (policy)
2548 racoon_free(policy);
2550 return 0;
2553 static int
2554 pk_recvspddelete(mhp)
2555 caddr_t *mhp;
2557 struct sadb_address *saddr, *daddr;
2558 struct sadb_x_policy *xpl;
2559 struct sadb_lifetime *lt;
2560 struct policyindex spidx;
2561 struct secpolicy *sp;
2562 u_int64_t created;
2564 /* sanity check */
2565 if (mhp[0] == NULL
2566 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2567 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2568 || mhp[SADB_X_EXT_POLICY] == NULL) {
2569 plog(LLV_ERROR, LOCATION, NULL,
2570 "inappropriate sadb spddelete message passed.\n");
2571 return -1;
2573 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2574 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2575 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2576 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2577 if(lt != NULL)
2578 created = lt->sadb_lifetime_addtime;
2579 else
2580 created = 0;
2582 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2583 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2584 saddr + 1,
2585 daddr + 1,
2586 saddr->sadb_address_prefixlen,
2587 daddr->sadb_address_prefixlen,
2588 saddr->sadb_address_proto,
2589 xpl->sadb_x_policy_priority,
2590 created,
2591 &spidx);
2592 #else
2593 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2594 saddr + 1,
2595 daddr + 1,
2596 saddr->sadb_address_prefixlen,
2597 daddr->sadb_address_prefixlen,
2598 saddr->sadb_address_proto,
2599 created,
2600 &spidx);
2601 #endif
2603 #ifdef HAVE_SECCTX
2604 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2605 struct sadb_x_sec_ctx *ctx;
2607 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2608 spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2609 spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2610 spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2611 memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2613 #endif /* HAVE_SECCTX */
2615 sp = getsp(&spidx);
2616 if (sp == NULL) {
2617 plog(LLV_ERROR, LOCATION, NULL,
2618 "no policy found: %s\n",
2619 spidx2str(&spidx));
2620 return -1;
2623 remsp(sp);
2624 delsp(sp);
2626 return 0;
2629 static int
2630 pk_recvspdexpire(mhp)
2631 caddr_t *mhp;
2633 struct sadb_address *saddr, *daddr;
2634 struct sadb_x_policy *xpl;
2635 struct sadb_lifetime *lt;
2636 struct policyindex spidx;
2637 struct secpolicy *sp;
2638 u_int64_t created;
2640 /* sanity check */
2641 if (mhp[0] == NULL
2642 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2643 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2644 || mhp[SADB_X_EXT_POLICY] == NULL) {
2645 plog(LLV_ERROR, LOCATION, NULL,
2646 "inappropriate sadb spdexpire message passed.\n");
2647 return -1;
2649 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2650 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2651 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2652 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2653 if(lt != NULL)
2654 created = lt->sadb_lifetime_addtime;
2655 else
2656 created = 0;
2658 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2659 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2660 saddr + 1,
2661 daddr + 1,
2662 saddr->sadb_address_prefixlen,
2663 daddr->sadb_address_prefixlen,
2664 saddr->sadb_address_proto,
2665 xpl->sadb_x_policy_priority,
2666 created,
2667 &spidx);
2668 #else
2669 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2670 saddr + 1,
2671 daddr + 1,
2672 saddr->sadb_address_prefixlen,
2673 daddr->sadb_address_prefixlen,
2674 saddr->sadb_address_proto,
2675 created,
2676 &spidx);
2677 #endif
2679 #ifdef HAVE_SECCTX
2680 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2681 struct sadb_x_sec_ctx *ctx;
2683 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2684 spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2685 spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2686 spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2687 memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2689 #endif /* HAVE_SECCTX */
2691 sp = getsp(&spidx);
2692 if (sp == NULL) {
2693 plog(LLV_ERROR, LOCATION, NULL,
2694 "no policy found: %s\n",
2695 spidx2str(&spidx));
2696 return -1;
2699 remsp(sp);
2700 delsp(sp);
2702 return 0;
2705 static int
2706 pk_recvspdget(mhp)
2707 caddr_t *mhp;
2709 /* sanity check */
2710 if (mhp[0] == NULL) {
2711 plog(LLV_ERROR, LOCATION, NULL,
2712 "inappropriate sadb spdget message passed.\n");
2713 return -1;
2716 return 0;
2719 static int
2720 pk_recvspddump(mhp)
2721 caddr_t *mhp;
2723 struct sadb_msg *msg;
2724 struct sadb_address *saddr, *daddr;
2725 struct sadb_x_policy *xpl;
2726 struct sadb_lifetime *lt;
2727 struct policyindex spidx;
2728 struct secpolicy *sp;
2729 struct sockaddr *local=NULL, *remote=NULL;
2730 u_int64_t created;
2731 int ret;
2733 /* sanity check */
2734 if (mhp[0] == NULL) {
2735 plog(LLV_ERROR, LOCATION, NULL,
2736 "inappropriate sadb spddump message passed.\n");
2737 return -1;
2739 msg = (struct sadb_msg *)mhp[0];
2740 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2741 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2742 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2743 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2744 if(lt != NULL)
2745 created = lt->sadb_lifetime_addtime;
2746 else
2747 created = 0;
2749 if (saddr == NULL || daddr == NULL || xpl == NULL) {
2750 plog(LLV_ERROR, LOCATION, NULL,
2751 "inappropriate sadb spddump message passed.\n");
2752 return -1;
2755 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2756 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2757 saddr + 1,
2758 daddr + 1,
2759 saddr->sadb_address_prefixlen,
2760 daddr->sadb_address_prefixlen,
2761 saddr->sadb_address_proto,
2762 xpl->sadb_x_policy_priority,
2763 created,
2764 &spidx);
2765 #else
2766 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2767 saddr + 1,
2768 daddr + 1,
2769 saddr->sadb_address_prefixlen,
2770 daddr->sadb_address_prefixlen,
2771 saddr->sadb_address_proto,
2772 created,
2773 &spidx);
2774 #endif
2776 #ifdef HAVE_SECCTX
2777 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2778 struct sadb_x_sec_ctx *ctx;
2780 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2781 spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2782 spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2783 spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2784 memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2786 #endif /* HAVE_SECCTX */
2788 sp = getsp(&spidx);
2789 if (sp != NULL) {
2790 plog(LLV_ERROR, LOCATION, NULL,
2791 "such policy already exists. "
2792 "anyway replace it: %s\n",
2793 spidx2str(&spidx));
2795 /* preserve hints before deleting the SP */
2796 local = sp->local;
2797 remote = sp->remote;
2798 sp->local = NULL;
2799 sp->remote = NULL;
2801 remsp(sp);
2802 delsp(sp);
2805 /* Add new SP (with old hints) */
2806 ret = addnewsp(mhp, local, remote);
2808 if (local != NULL)
2809 racoon_free(local);
2810 if (remote != NULL)
2811 racoon_free(remote);
2813 if (ret < 0)
2814 return -1;
2816 return 0;
2819 static int
2820 pk_recvspdflush(mhp)
2821 caddr_t *mhp;
2823 /* sanity check */
2824 if (mhp[0] == NULL) {
2825 plog(LLV_ERROR, LOCATION, NULL,
2826 "inappropriate sadb spdflush message passed.\n");
2827 return -1;
2830 flushsp();
2832 return 0;
2835 #if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
2837 /* MIGRATE support (pk_recvmigrate() is the handler of MIGRATE message).
2839 * pk_recvmigrate()
2840 * 1) some preprocessing and checks
2841 * 2) parsing of sadb_x_kmaddress extension
2842 * 3) SP lookup using selectors and content of policy extension from MIGRATE
2843 * 4) resolution of current local and remote IKE addresses
2844 * 5) Use of addresses to get Phase 1 handler if any
2845 * 6) Update of IKE addresses in Phase 1 (iph1->local and iph1->remote)
2846 * 7) Update of IKE addresses in Phase 2 (iph2->src and iph2->dst)
2847 * 8) Update of IKE addresses in SP (sp->local and sp->remote)
2848 * 9) Loop on sadb_x_ipsecrequests pairs from MIGRATE
2849 * - update of associated ipsecrequests entries in sp->req (should be
2850 * only one as racoon does not support bundles), i.e. update of
2851 * tunnel endpoints when required.
2852 * - If tunnel mode endpoints have been updated, lookup of associated
2853 * Phase 2 handle to also update sa_src and sa_dst entries
2855 * XXX Note that we do not support yet the update of SA addresses for transport
2856 * mode, but only the update of SA addresses for tunnel mode (endpoints).
2857 * Reasons are:
2858 * - there is no initial need for MIPv6
2859 * - racoon does not support bundles
2860 * - this would imply more work to deal with sainfo update (if feasible).
2863 /* Generic argument structure for migration callbacks */
2864 struct migrate_args {
2865 struct sockaddr *local;
2866 struct sockaddr *remote;
2870 * Update local and remote addresses of given Phase 1. Schedule removal
2871 * if negotiation was going on and restart a one from updated address.
2873 * -1 is returned on error. 0 if everything went right.
2875 static int
2876 migrate_ph1_ike_addresses(iph1, arg)
2877 struct ph1handle *iph1;
2878 void *arg;
2880 struct migrate_args *ma = (struct migrate_args *) arg;
2881 struct remoteconf *rmconf;
2882 u_int16_t port;
2884 /* Already up-to-date? */
2885 if (cmpsaddr(iph1->local, ma->local) == 0 &&
2886 cmpsaddr(iph1->remote, ma->remote) == 0)
2887 return 0;
2889 if (iph1->status < PHASE1ST_ESTABLISHED) {
2890 /* Bad luck! We received a MIGRATE *while* negotiating
2891 * Phase 1 (i.e. it was not established yet). If we act as
2892 * initiator we need to restart the negotiation. As
2893 * responder, our best bet is to update our addresses
2894 * and wait for the initiator to do something */
2895 plog(LLV_WARNING, LOCATION, NULL, "MIGRATE received *during* "
2896 "Phase 1 negotiation (%s).\n",
2897 saddr2str_fromto("%s => %s", ma->local, ma->remote));
2899 /* If we are not acting as initiator, let's just leave and
2900 * let the remote peer handle the restart */
2901 rmconf = getrmconf(ma->remote, 0);
2902 if (rmconf == NULL || !rmconf->passive) {
2903 iph1->status = PHASE1ST_EXPIRED;
2904 sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub);
2906 /* This is unlikely, but let's just check if a Phase 1
2907 * for the new addresses already exist */
2908 if (getph1byaddr(ma->local, ma->remote, 0)) {
2909 plog(LLV_WARNING, LOCATION, NULL, "No need "
2910 "to start a new Phase 1 negotiation. One "
2911 "already exists.\n");
2912 return 0;
2915 plog(LLV_WARNING, LOCATION, NULL, "As initiator, "
2916 "restarting it.\n");
2917 /* Note that the insertion of the new Phase 1 will not
2918 * interfere with the fact we are called from enumph1,
2919 * because it is inserted as first element. --arno */
2920 isakmp_ph1begin_i(rmconf, ma->local, ma->remote);
2922 return 0;
2926 if (iph1->local != NULL) {
2927 plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 local "
2928 "address from %s\n",
2929 saddr2str_fromto("%s to %s", iph1->local, ma->local));
2930 port = extract_port(iph1->local);
2931 racoon_free(iph1->local);
2932 } else
2933 port = 0;
2935 iph1->local = dupsaddr(ma->local);
2936 if (iph1->local == NULL) {
2937 plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2938 "Phase 1 local address.\n");
2939 return -1;
2941 set_port(iph1->local, port);
2943 if (iph1->remote != NULL) {
2944 plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 remote "
2945 "address from %s\n",
2946 saddr2str_fromto("%s to %s", iph1->remote, ma->remote));
2947 port = extract_port(iph1->remote);
2948 racoon_free(iph1->remote);
2949 } else
2950 port = 0;
2952 iph1->remote = dupsaddr(ma->remote);
2953 if (iph1->remote == NULL) {
2954 plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2955 "Phase 1 remote address.\n");
2956 return -1;
2958 set_port(iph1->remote, port);
2960 return 0;
2963 /* Update src and dst of all current Phase 2 handles.
2964 * with provided local and remote addresses.
2965 * Our intent is NOT to modify IPsec SA endpoints but IKE
2966 * addresses so we need to take care to separate those if
2967 * they are different. -1 is returned on error. 0 if everything
2968 * went right.
2970 * Note: we do not maintain port information as it is not
2971 * expected to be meaningful --arno
2973 static int
2974 migrate_ph2_ike_addresses(iph2, arg)
2975 struct ph2handle *iph2;
2976 void *arg;
2978 struct migrate_args *ma = (struct migrate_args *) arg;
2979 struct ph1handle *iph1;
2981 /* If Phase 2 has an associated Phase 1, migrate addresses */
2982 if (iph2->ph1)
2983 migrate_ph1_ike_addresses(iph2->ph1, arg);
2985 /* Already up-to-date? */
2986 if (cmpsaddr(iph2->src, ma->local) == 0 &&
2987 cmpsaddr(iph2->dst, ma->remote) == 0)
2988 return 0;
2990 /* save src/dst as sa_src/sa_dst before rewriting */
2991 if (iph2->sa_src == NULL && iph2->sa_dst == NULL) {
2992 iph2->sa_src = iph2->src;
2993 iph2->sa_dst = iph2->dst;
2994 iph2->src = NULL;
2995 iph2->dst = NULL;
2998 if (iph2->src != NULL)
2999 racoon_free(iph2->src);
3000 iph2->src = dupsaddr(ma->local);
3001 if (iph2->src == NULL) {
3002 plog(LLV_ERROR, LOCATION, NULL,
3003 "unable to allocate Phase 2 src address.\n");
3004 return -1;
3007 if (iph2->dst != NULL)
3008 racoon_free(iph2->dst);
3009 iph2->dst = dupsaddr(ma->remote);
3010 if (iph2->dst == NULL) {
3011 plog(LLV_ERROR, LOCATION, NULL,
3012 "unable to allocate Phase 2 dst address.\n");
3013 return -1;
3016 return 0;
3019 /* Consider existing Phase 2 handles with given spid and update their source
3020 * and destination addresses for SA. As racoon does not support bundles, if
3021 * we modify multiple occurrences, this probably imply rekeying has happened.
3023 * Both addresses passed to the function are expected not to be NULL and of
3024 * same family. -1 is returned on error. 0 if everything went right.
3026 * Specific care is needed to support Phase 2 for which negotiation has
3027 * already started but are which not yet established.
3029 static int
3030 migrate_ph2_sa_addresses(iph2, args)
3031 struct ph2handle *iph2;
3032 void *args;
3034 struct migrate_args *ma = (struct migrate_args *) args;
3036 if (iph2->sa_src != NULL) {
3037 racoon_free(iph2->sa_src);
3038 iph2->sa_src = NULL;
3041 if (iph2->sa_dst != NULL) {
3042 racoon_free(iph2->sa_dst);
3043 iph2->sa_dst = NULL;
3046 iph2->sa_src = dupsaddr(ma->local);
3047 if (iph2->sa_src == NULL) {
3048 plog(LLV_ERROR, LOCATION, NULL,
3049 "unable to allocate Phase 2 sa_src address.\n");
3050 return -1;
3053 iph2->sa_dst = dupsaddr(ma->remote);
3054 if (iph2->sa_dst == NULL) {
3055 plog(LLV_ERROR, LOCATION, NULL,
3056 "unable to allocate Phase 2 sa_dst address.\n");
3057 return -1;
3060 if (iph2->status < PHASE2ST_ESTABLISHED) {
3061 struct remoteconf *rmconf;
3062 /* We were negotiating for that SA when we received the MIGRATE.
3063 * We cannot simply update the addresses and let the exchange
3064 * go on. We have to restart the whole negotiation if we are
3065 * the initiator. Otherwise (acting as responder), we just need
3066 * to delete our ph2handle and wait for the initiator to start
3067 * a new negotiation. */
3069 if (iph2->ph1 && iph2->ph1->rmconf)
3070 rmconf = iph2->ph1->rmconf;
3071 else
3072 rmconf = getrmconf(iph2->dst, 0);
3074 if (rmconf && !rmconf->passive) {
3075 struct ph1handle *iph1hint;
3077 plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3078 "*during* IPsec SA negotiation. As initiator, "
3079 "restarting it.\n");
3081 /* Turn off expiration timer ...*/
3082 sched_cancel(&iph2->sce);
3083 iph2->status = PHASE2ST_EXPIRED;
3085 /* ... clean Phase 2 handle ... */
3086 iph1hint = iph2->ph1;
3087 initph2(iph2);
3088 iph2->status = PHASE2ST_STATUS2;
3090 /* and start a new negotiation */
3091 if (isakmp_post_acquire(iph2, iph1hint) < 0) {
3092 plog(LLV_ERROR, LOCATION, iph2->dst, "failed "
3093 "to begin IPsec SA renegotiation after "
3094 "MIGRATE reception.\n");
3095 remph2(iph2);
3096 delph2(iph2);
3097 return -1;
3099 } else {
3100 plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3101 "*during* IPsec SA negotiation. As responder, let's"
3102 "wait for the initiator to act.\n");
3104 /* Simply schedule deletion */
3105 isakmp_ph2expire(iph2);
3109 return 0;
3112 /* Update SP hints (local and remote addresses) for future IKE
3113 * negotiations of SA associated with that SP. -1 is returned
3114 * on error. 0 if everything went right.
3116 * Note: we do not maintain port information as it is not
3117 * expected to be meaningful --arno
3119 static int
3120 migrate_sp_ike_addresses(sp, local, remote)
3121 struct secpolicy *sp;
3122 struct sockaddr *local, *remote;
3124 if (sp == NULL || local == NULL || remote == NULL)
3125 return -1;
3127 if (sp->local != NULL)
3128 racoon_free(sp->local);
3130 sp->local = dupsaddr(local);
3131 if (sp->local == NULL) {
3132 plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3133 "local hint for SP.\n");
3134 return -1;
3137 if (sp->remote != NULL)
3138 racoon_free(sp->remote);
3140 sp->remote = dupsaddr(remote);
3141 if (sp->remote == NULL) {
3142 plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3143 "remote hint for SP.\n");
3144 return -1;
3147 return 0;
3150 /* Given current ipsecrequest (isr_cur) to be migrated in considered
3151 tree, the function first checks that it matches the expected one
3152 (xisr_old) provided in MIGRATE message and then updates the addresses
3153 if it is tunnel mode (with content of xisr_new). Various other checks
3154 are performed. For transport mode, structures are not modified, only
3155 the checks are done. -1 is returned on error. */
3156 static int
3157 migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new)
3158 u_int32_t spid;
3159 struct ipsecrequest *isr_cur;
3160 struct sadb_x_ipsecrequest *xisr_old, *xisr_new;
3162 struct secasindex *saidx = &isr_cur->saidx;
3163 struct sockaddr *osaddr, *odaddr, *nsaddr, *ndaddr;
3164 struct ph2selector ph2sel;
3165 struct migrate_args ma;
3167 /* First, check that mode and proto do match */
3168 if (xisr_old->sadb_x_ipsecrequest_proto != saidx->proto ||
3169 xisr_old->sadb_x_ipsecrequest_mode != saidx->mode ||
3170 xisr_new->sadb_x_ipsecrequest_proto != saidx->proto ||
3171 xisr_new->sadb_x_ipsecrequest_mode != saidx->mode)
3172 return -1;
3174 /* Then, verify reqid if necessary */
3175 if (isr_cur->saidx.reqid &&
3176 (xisr_old->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3177 xisr_new->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3178 isr_cur->saidx.reqid != xisr_old->sadb_x_ipsecrequest_reqid ||
3179 isr_cur->saidx.reqid != xisr_new->sadb_x_ipsecrequest_reqid))
3180 return -1;
3182 /* If not tunnel mode, our work is over */
3183 if (saidx->mode != IPSEC_MODE_TUNNEL) {
3184 plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3185 "non tunnel mode isr, skipping SA address migration.\n");
3186 return 0;
3189 /* Tunnel mode: let's check addresses do match and then update them. */
3190 osaddr = (struct sockaddr *)(xisr_old + 1);
3191 odaddr = (struct sockaddr *)(((u_int8_t *)osaddr) + sysdep_sa_len(osaddr));
3192 nsaddr = (struct sockaddr *)(xisr_new + 1);
3193 ndaddr = (struct sockaddr *)(((u_int8_t *)nsaddr) + sysdep_sa_len(nsaddr));
3195 /* Check family does match */
3196 if (osaddr->sa_family != odaddr->sa_family ||
3197 nsaddr->sa_family != ndaddr->sa_family)
3198 return -1;
3200 /* Check family does match */
3201 if (saidx->src.ss_family != osaddr->sa_family)
3202 return -1;
3204 /* We log IPv4 to IPv6 and IPv6 to IPv4 switches */
3205 if (nsaddr->sa_family != osaddr->sa_family)
3206 plog(LLV_INFO, LOCATION, NULL, "SADB_X_MIGRATE: "
3207 "changing address families (%d to %d) for endpoints.\n",
3208 osaddr->sa_family, nsaddr->sa_family);
3210 if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) ||
3211 cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst)) {
3212 plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3213 "mismatch of addresses in saidx and xisr.\n");
3214 return -1;
3217 /* Excellent. Let's grab associated Phase 2 handle (if any)
3218 * and update its sa_src and sa_dst entries. Note that we
3219 * make the assumption that racoon does not support bundles
3220 * and make the lookup using spid: we blindly update
3221 * sa_src and sa_dst for _all_ found Phase 2 handles */
3222 memset(&ph2sel, 0, sizeof(ph2sel));
3223 ph2sel.spid = spid;
3225 memset(&ma, 0, sizeof(ma));
3226 ma.local = nsaddr;
3227 ma.remote = ndaddr;
3229 if (enumph2(&ph2sel, migrate_ph2_sa_addresses, &ma) < 0)
3230 return -1;
3232 /* Now we can do the update of endpoints in secasindex */
3233 memcpy(&saidx->src, nsaddr, sysdep_sa_len(nsaddr));
3234 memcpy(&saidx->dst, ndaddr, sysdep_sa_len(ndaddr));
3236 return 0;
3239 /* Process the raw (unparsed yet) list of sadb_x_ipsecrequests of MIGRATE
3240 * message. For each sadb_x_ipsecrequest pair (old followed by new),
3241 * the corresponding ipsecrequest entry in the SP is updated. Associated
3242 * existing Phase 2 handle is also updated (if any) */
3243 static int
3244 migrate_sp_isr_list(sp, xisr_list, xisr_list_len)
3245 struct secpolicy *sp;
3246 struct sadb_x_ipsecrequest *xisr_list;
3247 int xisr_list_len;
3249 struct sadb_x_ipsecrequest *xisr_new, *xisr_old = xisr_list;
3250 int xisr_old_len, xisr_new_len;
3251 struct ipsecrequest *isr_cur;
3253 isr_cur = sp->req; /* ipsecrequest list from from sp */
3255 while (xisr_list_len > 0 && isr_cur != NULL) {
3256 /* Get old xisr (length field is in bytes) */
3257 xisr_old_len = xisr_old->sadb_x_ipsecrequest_len;
3258 if (xisr_old_len < sizeof(*xisr_old) ||
3259 xisr_old_len + sizeof(*xisr_new) > xisr_list_len) {
3260 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3261 "invalid ipsecrequest length. Exiting.\n");
3262 return -1;
3265 /* Get new xisr with updated info */
3266 xisr_new = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_old) + xisr_old_len);
3267 xisr_new_len = xisr_new->sadb_x_ipsecrequest_len;
3268 if (xisr_new_len < sizeof(*xisr_new) ||
3269 xisr_new_len + xisr_old_len > xisr_list_len) {
3270 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3271 "invalid ipsecrequest length. Exiting.\n");
3272 return -1;
3275 /* Start by migrating current ipsecrequest from SP */
3276 if (migrate_ph2_one_isr(sp->id, isr_cur, xisr_old, xisr_new) == -1) {
3277 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3278 "Unable to match and migrate isr. Exiting.\n");
3279 return -1;
3282 /* Update pointers for next round */
3283 xisr_list_len -= xisr_old_len + xisr_new_len;
3284 xisr_old = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_new) +
3285 xisr_new_len);
3287 isr_cur = isr_cur->next; /* Get next ipsecrequest from SP */
3290 /* Check we had the same amount of pairs in the MIGRATE
3291 as the number of ipsecrequests in the SP */
3292 if ((xisr_list_len != 0) || isr_cur != NULL) {
3293 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3294 "number of ipsecrequest does not match the one in SP.\n");
3295 return -1;
3298 return 0;
3301 /* Parse sadb_x_kmaddress extension and make local and remote
3302 * parameters point to the new addresses (zero copy). -1 is
3303 * returned on error, meaning that addresses are not usable */
3304 static int
3305 parse_kmaddress(kmaddr, local, remote)
3306 struct sadb_x_kmaddress *kmaddr;
3307 struct sockaddr **local, **remote;
3309 int addrslen, local_len=0;
3310 struct ph1handle *iph1;
3312 if (kmaddr == NULL)
3313 return -1;
3315 /* Grab addresses in sadb_x_kmaddress extension */
3316 addrslen = PFKEY_EXTLEN(kmaddr) - sizeof(*kmaddr);
3317 if (addrslen < sizeof(struct sockaddr))
3318 return -1;
3320 *local = (struct sockaddr *)(kmaddr + 1);
3322 switch ((*local)->sa_family) {
3323 case AF_INET:
3324 local_len = sizeof(struct sockaddr_in);
3325 break;
3326 #ifdef INET6
3327 case AF_INET6:
3328 local_len = sizeof(struct sockaddr_in6);
3329 break;
3330 #endif
3331 default:
3332 return -1;
3335 if (addrslen != PFKEY_ALIGN8(2*local_len))
3336 return -1;
3338 *remote = (struct sockaddr *)(((u_int8_t *)(*local)) + local_len);
3340 if ((*local)->sa_family != (*remote)->sa_family)
3341 return -1;
3343 return 0;
3346 /* Handler of PF_KEY MIGRATE message. Helpers are above */
3347 static int
3348 pk_recvmigrate(mhp)
3349 caddr_t *mhp;
3351 struct sadb_address *saddr, *daddr;
3352 struct sockaddr *old_saddr, *new_saddr;
3353 struct sockaddr *old_daddr, *new_daddr;
3354 struct sockaddr *old_local, *old_remote;
3355 struct sockaddr *local, *remote;
3356 struct sadb_x_kmaddress *kmaddr;
3357 struct sadb_x_policy *xpl;
3358 struct sadb_x_ipsecrequest *xisr_list;
3359 struct sadb_lifetime *lt;
3360 struct policyindex spidx;
3361 struct secpolicy *sp;
3362 struct ipsecrequest *isr_cur;
3363 struct secasindex *oldsaidx;
3364 struct ph2handle *iph2;
3365 struct ph1handle *iph1;
3366 struct ph2selector ph2sel;
3367 struct ph1selector ph1sel;
3368 u_int32_t spid;
3369 u_int64_t created;
3370 int xisr_list_len;
3371 int ulproto;
3372 struct migrate_args ma;
3374 /* Some sanity checks */
3376 if (mhp[0] == NULL
3377 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
3378 || mhp[SADB_EXT_ADDRESS_DST] == NULL
3379 || mhp[SADB_X_EXT_KMADDRESS] == NULL
3380 || mhp[SADB_X_EXT_POLICY] == NULL) {
3381 plog(LLV_ERROR, LOCATION, NULL,
3382 "SADB_X_MIGRATE: invalid MIGRATE message received.\n");
3383 return -1;
3385 kmaddr = (struct sadb_x_kmaddress *)mhp[SADB_X_EXT_KMADDRESS];
3386 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3387 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3388 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3389 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3390 if (lt != NULL)
3391 created = lt->sadb_lifetime_addtime;
3392 else
3393 created = 0;
3395 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
3396 plog(LLV_WARNING, LOCATION, NULL,"SADB_X_MIGRATE: "
3397 "found non IPsec policy in MIGRATE message. Exiting.\n");
3398 return -1;
3401 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3402 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3403 "invalid size for sadb_x_policy. Exiting.\n");
3404 return -1;
3407 /* Some logging to help debbugging */
3408 if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
3409 plog(LLV_DEBUG, LOCATION, NULL,
3410 "SADB_X_MIGRATE: Outbound SA being migrated.\n");
3411 else
3412 plog(LLV_DEBUG, LOCATION, NULL,
3413 "SADB_X_MIGRATE: Inbound SA being migrated.\n");
3415 /* validity check */
3416 xisr_list = (struct sadb_x_ipsecrequest *)(xpl + 1);
3417 xisr_list_len = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3418 if (xisr_list_len < sizeof(*xisr_list)) {
3419 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3420 "invalid sadb_x_policy message length. Exiting.\n");
3421 return -1;
3424 if (parse_kmaddress(kmaddr, &local, &remote) == -1) {
3425 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3426 "invalid sadb_x_kmaddress extension. Exiting.\n");
3427 return -1;
3430 /* 0 means ANY */
3431 if (saddr->sadb_address_proto == 0)
3432 ulproto = IPSEC_ULPROTO_ANY;
3433 else
3434 ulproto = saddr->sadb_address_proto;
3436 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3437 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3438 saddr + 1,
3439 daddr + 1,
3440 saddr->sadb_address_prefixlen,
3441 daddr->sadb_address_prefixlen,
3442 ulproto,
3443 xpl->sadb_x_policy_priority,
3444 created,
3445 &spidx);
3446 #else
3447 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3448 saddr + 1,
3449 daddr + 1,
3450 saddr->sadb_address_prefixlen,
3451 daddr->sadb_address_prefixlen,
3452 ulproto,
3453 created,
3454 &spidx);
3455 #endif
3457 /* Everything seems ok, let's get the SP.
3459 * XXX We could also do the lookup using the spid from xpl.
3460 * I don't know which one is better. --arno */
3461 sp = getsp(&spidx);
3462 if (sp == NULL) {
3463 plog(LLV_ERROR, LOCATION, NULL,
3464 "SADB_X_MIGRATE: Passed policy does not exist: %s\n",
3465 spidx2str(&spidx));
3466 return -1;
3469 /* Get the best source and destination addresses used for IKE
3470 * negotiation, to find and migrate existing Phase 1 */
3471 if (sp->local && sp->remote) {
3472 /* hints available, let's use them */
3473 old_local = (struct sockaddr *)sp->local;
3474 old_remote = (struct sockaddr *)sp->remote;
3475 } else if (sp->req && sp->req->saidx.mode == IPSEC_MODE_TUNNEL) {
3476 /* Tunnel mode and no hint, use endpoints */
3477 old_local = (struct sockaddr *)&sp->req->saidx.src;
3478 old_remote = (struct sockaddr *)&sp->req->saidx.dst;
3479 } else {
3480 /* default, use selectors as fallback */
3481 old_local = (struct sockaddr *)&sp->spidx.src;
3482 old_remote = (struct sockaddr *)&sp->spidx.dst;
3485 /* We migrate all Phase 1 that match our old local and remote
3486 * addresses (no matter their state).
3488 * XXX In fact, we should probably havea special treatment for
3489 * Phase 1 that are being established when we receive a MIGRATE.
3490 * This can happen if a movement occurs during the initial IKE
3491 * negotiation. In that case, I wonder if should restart the
3492 * negotiation from the new address or just update things like
3493 * we do it now.
3495 * XXX while looking at getph1byaddr(), the comment at the
3496 * beginning of the function expects comparison to happen
3497 * without ports considerations but it uses CMPSADDR() which
3498 * relies either on cmpsaddrstrict() or cmpsaddrwop() based
3499 * on NAT-T support being activated. That make me wonder if I
3500 * should force ports to 0 (ANY) in local and remote values
3501 * used below.
3503 * -- arno */
3505 /* Apply callback data ...*/
3506 memset(&ma, 0, sizeof(ma));
3507 ma.local = local;
3508 ma.remote = remote;
3510 /* Fill phase1 match criteria ... */
3511 memset(&ph1sel, 0, sizeof(ph1sel));
3512 ph1sel.local = old_local;
3513 ph1sel.remote = old_remote;
3516 /* Have matching Phase 1 found and addresses updated. As this is a
3517 * time consuming task on a busy responder, and MIGRATE messages
3518 * are always sent for *both* inbound and outbound (and possibly
3519 * forward), we only do that for outbound SP. */
3520 if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND &&
3521 enumph1(&ph1sel, migrate_ph1_ike_addresses, &ma) < 0) {
3522 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3523 "to migrate Phase 1 addresses.\n");
3524 return -1;
3527 /* We can now update IKE addresses in Phase 2 handle. */
3528 memset(&ph2sel, 0, sizeof(ph2sel));
3529 ph2sel.spid = sp->id;
3530 if (enumph2(&ph2sel, migrate_ph2_ike_addresses, &ma) < 0) {
3531 plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3532 "to migrate Phase 2 IKE addresses.\n");
3533 return -1;
3536 /* and _then_ in SP. */
3537 if (migrate_sp_ike_addresses(sp, local, remote) < 0) {
3538 plog(LLV_ERROR, LOCATION, NULL,
3539 "SADB_X_MIGRATE: Unable to migrate SP IKE addresses.\n");
3540 return -1;
3543 /* Loop on sadb_x_ipsecrequest list to possibly update sp->req
3544 * entries and associated live Phase 2 handles (their sa_src
3545 * and sa_dst) */
3546 if (migrate_sp_isr_list(sp, xisr_list, xisr_list_len) < 0) {
3547 plog(LLV_ERROR, LOCATION, NULL,
3548 "SADB_X_MIGRATE: Unable to migrate isr list.\n");
3549 return -1;
3552 return 0;
3554 #endif
3557 * send error against acquire message to kenrel.
3560 pk_sendeacquire(iph2)
3561 struct ph2handle *iph2;
3563 struct sadb_msg *newmsg;
3564 int len;
3566 len = sizeof(struct sadb_msg);
3567 newmsg = racoon_calloc(1, len);
3568 if (newmsg == NULL) {
3569 plog(LLV_ERROR, LOCATION, NULL,
3570 "failed to get buffer to send acquire.\n");
3571 return -1;
3574 memset(newmsg, 0, len);
3575 newmsg->sadb_msg_version = PF_KEY_V2;
3576 newmsg->sadb_msg_type = SADB_ACQUIRE;
3577 newmsg->sadb_msg_errno = ENOENT; /* XXX */
3578 newmsg->sadb_msg_satype = iph2->satype;
3579 newmsg->sadb_msg_len = PFKEY_UNIT64(len);
3580 newmsg->sadb_msg_reserved = 0;
3581 newmsg->sadb_msg_seq = iph2->seq;
3582 newmsg->sadb_msg_pid = (u_int32_t)getpid();
3584 /* send message */
3585 len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
3587 racoon_free(newmsg);
3589 return 0;
3593 * check if the algorithm is supported or not.
3594 * OUT 0: ok
3595 * -1: ng
3598 pk_checkalg(class, calg, keylen)
3599 int class, calg, keylen;
3601 int sup, error;
3602 u_int alg;
3603 struct sadb_alg alg0;
3605 switch (algclass2doi(class)) {
3606 case IPSECDOI_PROTO_IPSEC_ESP:
3607 sup = SADB_EXT_SUPPORTED_ENCRYPT;
3608 break;
3609 case IPSECDOI_ATTR_AUTH:
3610 sup = SADB_EXT_SUPPORTED_AUTH;
3611 break;
3612 case IPSECDOI_PROTO_IPCOMP:
3613 plog(LLV_DEBUG, LOCATION, NULL,
3614 "compression algorithm can not be checked "
3615 "because sadb message doesn't support it.\n");
3616 return 0;
3617 default:
3618 plog(LLV_ERROR, LOCATION, NULL,
3619 "invalid algorithm class.\n");
3620 return -1;
3622 alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
3623 if (alg == ~0)
3624 return -1;
3626 if (keylen == 0) {
3627 if (ipsec_get_keylen(sup, alg, &alg0)) {
3628 plog(LLV_ERROR, LOCATION, NULL,
3629 "%s.\n", ipsec_strerror());
3630 return -1;
3632 keylen = alg0.sadb_alg_minbits;
3635 error = ipsec_check_keylen(sup, alg, keylen);
3636 if (error)
3637 plog(LLV_ERROR, LOCATION, NULL,
3638 "%s.\n", ipsec_strerror());
3640 return error;
3644 * differences with pfkey_recv() in libipsec/pfkey.c:
3645 * - never performs busy wait loop.
3646 * - returns NULL and set *lenp to negative on fatal failures
3647 * - returns NULL and set *lenp to non-negative on non-fatal failures
3648 * - returns non-NULL on success
3650 static struct sadb_msg *
3651 pk_recv(so, lenp)
3652 int so;
3653 int *lenp;
3655 struct sadb_msg buf, *newmsg;
3656 int reallen;
3657 int retry = 0;
3659 *lenp = -1;
3662 plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
3663 *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
3664 retry++;
3666 while (*lenp < 0 && errno == EAGAIN && retry < 3);
3668 if (*lenp < 0)
3669 return NULL; /*fatal*/
3671 else if (*lenp < sizeof(buf))
3672 return NULL;
3674 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
3675 if (reallen < sizeof(buf)) {
3676 *lenp = -1;
3677 errno = EIO;
3678 return NULL; /*fatal*/
3680 if ((newmsg = racoon_calloc(1, reallen)) == NULL)
3681 return NULL;
3683 *lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
3684 if (*lenp < 0) {
3685 racoon_free(newmsg);
3686 return NULL; /*fatal*/
3687 } else if (*lenp != reallen) {
3688 racoon_free(newmsg);
3689 return NULL;
3692 *lenp = recv(so, (caddr_t)newmsg, reallen, 0);
3693 if (*lenp < 0) {
3694 racoon_free(newmsg);
3695 return NULL; /*fatal*/
3696 } else if (*lenp != reallen) {
3697 racoon_free(newmsg);
3698 return NULL;
3701 return newmsg;
3704 /* see handler.h */
3705 u_int32_t
3706 pk_getseq()
3708 return eay_random();
3711 static int
3712 addnewsp(mhp, local, remote)
3713 caddr_t *mhp;
3714 struct sockaddr *local, *remote;
3716 struct secpolicy *new = NULL;
3717 struct sadb_address *saddr, *daddr;
3718 struct sadb_x_policy *xpl;
3719 struct sadb_lifetime *lt;
3720 u_int64_t created;
3722 /* sanity check */
3723 if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
3724 || mhp[SADB_EXT_ADDRESS_DST] == NULL
3725 || mhp[SADB_X_EXT_POLICY] == NULL) {
3726 plog(LLV_ERROR, LOCATION, NULL,
3727 "inappropriate sadb spd management message passed.\n");
3728 goto bad;
3731 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3732 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3733 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3734 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3735 if(lt != NULL)
3736 created = lt->sadb_lifetime_addtime;
3737 else
3738 created = 0;
3739 lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3740 if(lt != NULL)
3741 created = lt->sadb_lifetime_addtime;
3742 else
3743 created = 0;
3745 #ifdef __linux__
3746 /* bsd skips over per-socket policies because there will be no
3747 * src and dst extensions in spddump messages. On Linux the only
3748 * way to achieve the same is check for policy id.
3750 if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
3751 #endif
3753 new = newsp();
3754 if (new == NULL) {
3755 plog(LLV_ERROR, LOCATION, NULL,
3756 "failed to allocate buffer\n");
3757 goto bad;
3760 new->spidx.dir = xpl->sadb_x_policy_dir;
3761 new->id = xpl->sadb_x_policy_id;
3762 new->policy = xpl->sadb_x_policy_type;
3763 new->req = NULL;
3765 /* check policy */
3766 switch (xpl->sadb_x_policy_type) {
3767 case IPSEC_POLICY_DISCARD:
3768 case IPSEC_POLICY_NONE:
3769 case IPSEC_POLICY_ENTRUST:
3770 case IPSEC_POLICY_BYPASS:
3771 break;
3773 case IPSEC_POLICY_IPSEC:
3775 int tlen;
3776 struct sadb_x_ipsecrequest *xisr;
3777 struct ipsecrequest **p_isr = &new->req;
3779 /* validity check */
3780 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3781 plog(LLV_ERROR, LOCATION, NULL,
3782 "invalid msg length.\n");
3783 goto bad;
3786 tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3787 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
3789 while (tlen > 0) {
3791 /* length check */
3792 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
3793 plog(LLV_ERROR, LOCATION, NULL,
3794 "invalid msg length.\n");
3795 goto bad;
3798 /* allocate request buffer */
3799 *p_isr = newipsecreq();
3800 if (*p_isr == NULL) {
3801 plog(LLV_ERROR, LOCATION, NULL,
3802 "failed to get new ipsecreq.\n");
3803 goto bad;
3806 /* set values */
3807 (*p_isr)->next = NULL;
3809 switch (xisr->sadb_x_ipsecrequest_proto) {
3810 case IPPROTO_ESP:
3811 case IPPROTO_AH:
3812 case IPPROTO_IPCOMP:
3813 break;
3814 default:
3815 plog(LLV_ERROR, LOCATION, NULL,
3816 "invalid proto type: %u\n",
3817 xisr->sadb_x_ipsecrequest_proto);
3818 goto bad;
3820 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
3822 switch (xisr->sadb_x_ipsecrequest_mode) {
3823 case IPSEC_MODE_TRANSPORT:
3824 case IPSEC_MODE_TUNNEL:
3825 break;
3826 case IPSEC_MODE_ANY:
3827 default:
3828 plog(LLV_ERROR, LOCATION, NULL,
3829 "invalid mode: %u\n",
3830 xisr->sadb_x_ipsecrequest_mode);
3831 goto bad;
3833 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
3835 switch (xisr->sadb_x_ipsecrequest_level) {
3836 case IPSEC_LEVEL_DEFAULT:
3837 case IPSEC_LEVEL_USE:
3838 case IPSEC_LEVEL_REQUIRE:
3839 break;
3840 case IPSEC_LEVEL_UNIQUE:
3841 (*p_isr)->saidx.reqid =
3842 xisr->sadb_x_ipsecrequest_reqid;
3843 break;
3845 default:
3846 plog(LLV_ERROR, LOCATION, NULL,
3847 "invalid level: %u\n",
3848 xisr->sadb_x_ipsecrequest_level);
3849 goto bad;
3851 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
3853 /* set IP addresses if there */
3854 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
3855 struct sockaddr *paddr;
3857 paddr = (struct sockaddr *)(xisr + 1);
3858 bcopy(paddr, &(*p_isr)->saidx.src,
3859 sysdep_sa_len(paddr));
3861 paddr = (struct sockaddr *)((caddr_t)paddr
3862 + sysdep_sa_len(paddr));
3863 bcopy(paddr, &(*p_isr)->saidx.dst,
3864 sysdep_sa_len(paddr));
3867 (*p_isr)->sp = new;
3869 /* initialization for the next. */
3870 p_isr = &(*p_isr)->next;
3871 tlen -= xisr->sadb_x_ipsecrequest_len;
3873 /* validity check */
3874 if (tlen < 0) {
3875 plog(LLV_ERROR, LOCATION, NULL,
3876 "becoming tlen < 0\n");
3879 xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
3880 + xisr->sadb_x_ipsecrequest_len);
3883 break;
3884 default:
3885 plog(LLV_ERROR, LOCATION, NULL,
3886 "invalid policy type.\n");
3887 goto bad;
3890 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3891 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3892 saddr + 1,
3893 daddr + 1,
3894 saddr->sadb_address_prefixlen,
3895 daddr->sadb_address_prefixlen,
3896 saddr->sadb_address_proto,
3897 xpl->sadb_x_policy_priority,
3898 created,
3899 &new->spidx);
3900 #else
3901 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3902 saddr + 1,
3903 daddr + 1,
3904 saddr->sadb_address_prefixlen,
3905 daddr->sadb_address_prefixlen,
3906 saddr->sadb_address_proto,
3907 created,
3908 &new->spidx);
3909 #endif
3911 #ifdef HAVE_SECCTX
3912 if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
3913 struct sadb_x_sec_ctx *ctx;
3915 ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
3916 new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
3917 new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
3918 new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
3919 memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
3921 #endif /* HAVE_SECCTX */
3923 /* Set local and remote hints for that SP, if available */
3924 if (local && remote) {
3925 new->local = dupsaddr(local);
3926 new->remote = dupsaddr(remote);
3929 inssp(new);
3931 return 0;
3932 bad:
3933 if (new != NULL) {
3934 if (new->req != NULL)
3935 racoon_free(new->req);
3936 racoon_free(new);
3938 return -1;
3941 /* proto/mode/src->dst spi */
3942 const char *
3943 sadbsecas2str(src, dst, proto, spi, mode)
3944 struct sockaddr *src, *dst;
3945 int proto;
3946 u_int32_t spi;
3947 int mode;
3949 static char buf[256];
3950 u_int doi_proto, doi_mode = 0;
3951 char *p;
3952 int blen, i;
3954 doi_proto = pfkey2ipsecdoi_proto(proto);
3955 if (doi_proto == ~0)
3956 return NULL;
3957 if (mode) {
3958 doi_mode = pfkey2ipsecdoi_mode(mode);
3959 if (doi_mode == ~0)
3960 return NULL;
3963 blen = sizeof(buf) - 1;
3964 p = buf;
3966 i = snprintf(p, blen, "%s%s%s ",
3967 s_ipsecdoi_proto(doi_proto),
3968 mode ? "/" : "",
3969 mode ? s_ipsecdoi_encmode(doi_mode) : "");
3970 if (i < 0 || i >= blen)
3971 return NULL;
3972 p += i;
3973 blen -= i;
3975 i = snprintf(p, blen, "%s->", saddr2str(src));
3976 if (i < 0 || i >= blen)
3977 return NULL;
3978 p += i;
3979 blen -= i;
3981 i = snprintf(p, blen, "%s ", saddr2str(dst));
3982 if (i < 0 || i >= blen)
3983 return NULL;
3984 p += i;
3985 blen -= i;
3987 if (spi) {
3988 snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3989 (unsigned long)ntohl(spi));
3992 return buf;