]> git.saurik.com Git - apple/network_cmds.git/blame - racoon.tproj/pfkey.c
network_cmds-115.tar.gz
[apple/network_cmds.git] / racoon.tproj / pfkey.c
CommitLineData
7ba0088d
A
1/* $KAME: pfkey.c,v 1.132 2001/10/19 05:31:22 sakane Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#define _PFKEY_C_
33
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37#include <sys/queue.h>
38
39#include <net/route.h>
40#include <net/pfkeyv2.h>
41#include <netkey/key_debug.h>
42
43#include <netinet/in.h>
44#ifdef IPV6_INRIA_VERSION
45#include <netinet/ipsec.h>
46#else
47#include <netinet6/ipsec.h>
48#endif
49
50#include <stdlib.h>
51#include <string.h>
52#include <stdio.h>
53#include <netdb.h>
54#include <errno.h>
55#ifdef HAVE_UNISTD_H
56#include <unistd.h>
57#endif
58#include <netdb.h>
59
60#include "libpfkey.h"
61
62#include "var.h"
63#include "misc.h"
64#include "vmbuf.h"
65#include "plog.h"
66#include "sockmisc.h"
67#include "debug.h"
68
69#include "schedule.h"
70#include "localconf.h"
71#include "remoteconf.h"
72#include "isakmp_var.h"
73#include "isakmp.h"
74#include "isakmp_inf.h"
75#include "ipsec_doi.h"
76#include "oakley.h"
77#include "pfkey.h"
78#include "handler.h"
79#include "policy.h"
80#include "algorithm.h"
81#include "sainfo.h"
82#include "proposal.h"
83#include "admin.h"
84#include "strnames.h"
85#include "backupsa.h"
86#include "gcmalloc.h"
87
88/* prototype */
89static u_int ipsecdoi2pfkey_aalg __P((u_int));
90static u_int ipsecdoi2pfkey_ealg __P((u_int));
91static u_int ipsecdoi2pfkey_calg __P((u_int));
92static u_int ipsecdoi2pfkey_alg __P((u_int, u_int));
93static u_int keylen_aalg __P((u_int));
94static u_int keylen_ealg __P((u_int, int));
95
96static int pk_recvgetspi __P((caddr_t *));
97static int pk_recvupdate __P((caddr_t *));
98static int pk_recvadd __P((caddr_t *));
99static int pk_recvdelete __P((caddr_t *));
100static int pk_recvacquire __P((caddr_t *));
101static int pk_recvexpire __P((caddr_t *));
102static int pk_recvflush __P((caddr_t *));
103static int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *));
104static int pk_recvspdupdate __P((caddr_t *));
105static int pk_recvspdadd __P((caddr_t *));
106static int pk_recvspddelete __P((caddr_t *));
107static int pk_recvspdexpire __P((caddr_t *));
108static int pk_recvspdget __P((caddr_t *));
109static int pk_recvspddump __P((caddr_t *));
110static int pk_recvspdflush __P((caddr_t *));
111static struct sadb_msg *pk_recv __P((int, int *));
112
113static int (*pkrecvf[]) __P((caddr_t *)) = {
114NULL,
115pk_recvgetspi,
116pk_recvupdate,
117pk_recvadd,
118pk_recvdelete,
119NULL, /* SADB_GET */
120pk_recvacquire,
121NULL, /* SABD_REGISTER */
122pk_recvexpire,
123pk_recvflush,
124NULL, /* SADB_DUMP */
125NULL, /* SADB_X_PROMISC */
126NULL, /* SADB_X_PCHANGE */
127pk_recvspdupdate,
128pk_recvspdadd,
129pk_recvspddelete,
130pk_recvspdget,
131NULL, /* SADB_X_SPDACQUIRE */
132pk_recvspddump,
133pk_recvspdflush,
134NULL, /* SADB_X_SPDSETIDX */
135pk_recvspdexpire,
136NULL, /* SADB_X_SPDDELETE2 */
137};
138
139static int addnewsp __P((caddr_t *));
140
141/* cope with old kame headers - ugly */
142#ifndef SADB_X_AALG_MD5
143#define SADB_X_AALG_MD5 SADB_AALG_MD5
144#endif
145#ifndef SADB_X_AALG_SHA
146#define SADB_X_AALG_SHA SADB_AALG_SHA
147#endif
148#ifndef SADB_X_AALG_NULL
149#define SADB_X_AALG_NULL SADB_AALG_NULL
150#endif
151
152#ifndef SADB_X_EALG_BLOWFISHCBC
153#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
154#endif
155#ifndef SADB_X_EALG_CAST128CBC
156#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
157#endif
158#ifndef SADB_X_EALG_RC5CBC
159#ifdef SADB_EALG_RC5CBC
160#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
161#endif
162#endif
163
164/*
165 * PF_KEY packet handler
166 * 0: success
167 * -1: fail
168 */
169int
170pfkey_handler()
171{
172 struct sadb_msg *msg;
173 int len;
174 caddr_t mhp[SADB_EXT_MAX + 1];
175 int error = -1;
176
177 /* receive pfkey message. */
178 len = 0;
179 msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
180 if (msg == NULL) {
181 if (len < 0) {
182 plog(LLV_ERROR, LOCATION, NULL,
183 "failed to recv from pfkey (%s)\n",
184 strerror(errno));
185 goto end;
186 } else {
187 /* short message - msg not ready */
188 return 0;
189 }
190 }
191
192 plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
193 s_pfkey_type(msg->sadb_msg_type));
194 plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
195
196 /* validity check */
197 if (msg->sadb_msg_errno) {
198 int pri;
199
200 /* when SPD is empty, treat the state as no error. */
201 if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
202 msg->sadb_msg_errno == ENOENT)
203 pri = LLV_DEBUG;
204 else
205 pri = LLV_ERROR;
206
207 plog(pri, LOCATION, NULL,
208 "pfkey %s failed: %s\n",
209 s_pfkey_type(msg->sadb_msg_type),
210 strerror(msg->sadb_msg_errno));
211
212 goto end;
213 }
214
215 /* check pfkey message. */
216 if (pfkey_align(msg, mhp)) {
217 plog(LLV_ERROR, LOCATION, NULL,
218 "libipsec failed pfkey align (%s)\n",
219 ipsec_strerror());
220 goto end;
221 }
222 if (pfkey_check(mhp)) {
223 plog(LLV_ERROR, LOCATION, NULL,
224 "libipsec failed pfkey check (%s)\n",
225 ipsec_strerror());
226 goto end;
227 }
228 msg = (struct sadb_msg *)mhp[0];
229
230 if (pkrecvf[msg->sadb_msg_type] == NULL) {
231 plog(LLV_DEBUG, LOCATION, NULL,
232 "not supported command %s\n",
233 s_pfkey_type(msg->sadb_msg_type));
234 goto end;
235 }
236
237 if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
238 goto end;
239
240 error = 0;
241end:
242 if (msg)
243 racoon_free(msg);
244 return(error);
245}
246
247/*
248 * dump SADB
249 */
250vchar_t *
251pfkey_dump_sadb(satype)
252 int satype;
253{
254 int s = -1;
255 vchar_t *buf = NULL;
256 pid_t pid = getpid();
257 struct sadb_msg *msg = NULL;
258 size_t bl, ml;
259 int len;
260
261 if ((s = pfkey_open()) < 0) {
262 plog(LLV_ERROR, LOCATION, NULL,
263 "libipsec failed pfkey open: %s\n",
264 ipsec_strerror());
265 return NULL;
266 }
267
268 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
269 if (pfkey_send_dump(s, satype) < 0) {
270 plog(LLV_ERROR, LOCATION, NULL,
271 "libipsec failed dump: %s\n", ipsec_strerror());
272 goto fail;
273 }
274
275 while (1) {
276 if (msg)
277 racoon_free(msg);
278 msg = pk_recv(s, &len);
279 if (msg == NULL) {
280 if (len < 0)
281 goto done;
282 else
283 continue;
284 }
285
286 if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid)
287 continue;
288
289 ml = msg->sadb_msg_len << 3;
290 bl = buf ? buf->l : 0;
291 buf = vrealloc(buf, bl + ml);
292 if (buf == NULL) {
293 plog(LLV_ERROR, LOCATION, NULL,
294 "failed to reallocate buffer to dump.\n");
295 goto fail;
296 }
297 memcpy(buf->v + bl, msg, ml);
298
299 if (msg->sadb_msg_seq == 0)
300 break;
301 }
302 goto done;
303
304fail:
305 if (buf)
306 vfree(buf);
307 buf = NULL;
308done:
309 if (msg)
310 racoon_free(msg);
311 if (s >= 0)
312 close(s);
313 return buf;
314}
315
316/*
317 * flush SADB
318 */
319void
320pfkey_flush_sadb(proto)
321 u_int proto;
322{
323 int satype;
324
325 /* convert to SADB_SATYPE */
326 if ((satype = admin2pfkey_proto(proto)) < 0)
327 return;
328
329 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
330 if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
331 plog(LLV_ERROR, LOCATION, NULL,
332 "libipsec failed send flush (%s)\n", ipsec_strerror());
333 return;
334 }
335
336 return;
337}
338
339/*
340 * These are the SATYPEs that we manage. We register to get
341 * PF_KEY messages related to these SATYPEs, and we also use
342 * this list to determine which SATYPEs to delete SAs for when
343 * we receive an INITIAL-CONTACT.
344 */
345const struct pfkey_satype pfkey_satypes[] = {
346 { SADB_SATYPE_AH, "AH" },
347 { SADB_SATYPE_ESP, "ESP" },
348 { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
349};
350const int pfkey_nsatypes =
351 sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
352
353/*
354 * PF_KEY initialization
355 */
356int
357pfkey_init()
358{
359 int i, reg_fail;
360
361 if ((lcconf->sock_pfkey = pfkey_open()) < 0) {
362 plog(LLV_ERROR, LOCATION, NULL,
363 "libipsec failed pfkey open (%s)", ipsec_strerror());
364 return -1;
365 }
366
367 for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
368 plog(LLV_DEBUG, LOCATION, NULL,
369 "call pfkey_send_register for %s\n",
370 pfkey_satypes[i].ps_name);
371 if (pfkey_send_register(lcconf->sock_pfkey,
372 pfkey_satypes[i].ps_satype) < 0 ||
373 pfkey_recv_register(lcconf->sock_pfkey) < 0) {
374 plog(LLV_WARNING, LOCATION, NULL,
375 "failed to register %s (%s)",
376 pfkey_satypes[i].ps_name,
377 ipsec_strerror());
378 reg_fail++;
379 }
380 }
381
382 if (reg_fail == pfkey_nsatypes) {
383 plog(LLV_ERROR, LOCATION, NULL,
384 "failed to regist any protocol.");
385 pfkey_close(lcconf->sock_pfkey);
386 return -1;
387 }
388
389 initsp();
390
391 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
392 plog(LLV_ERROR, LOCATION, NULL,
393 "libipsec sending spddump failed: %s",
394 ipsec_strerror());
395 pfkey_close(lcconf->sock_pfkey);
396 return -1;
397 }
398#if 0
399 if (pfkey_promisc_toggle(1) < 0) {
400 pfkey_close(lcconf->sock_pfkey);
401 return -1;
402 }
403#endif
404 return 0;
405}
406
407/* %%% for conversion */
408/* IPSECDOI_ATTR_AUTH -> SADB_AALG */
409static u_int
410ipsecdoi2pfkey_aalg(hashtype)
411 u_int hashtype;
412{
413 switch (hashtype) {
414 case IPSECDOI_ATTR_AUTH_HMAC_MD5:
415 return SADB_AALG_MD5HMAC;
416 case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
417 return SADB_AALG_SHA1HMAC;
418 case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */
419 return SADB_AALG_NONE;
420
421 /* not supported */
422 case IPSECDOI_ATTR_AUTH_DES_MAC:
423 plog(LLV_ERROR, LOCATION, NULL,
424 "Not supported hash type: %u\n", hashtype);
425 return ~0;
426
427 case 0: /* reserved */
428 default:
429 return SADB_AALG_NONE;
430
431 plog(LLV_ERROR, LOCATION, NULL,
432 "Invalid hash type: %u\n", hashtype);
433 return ~0;
434 }
435 /*NOTREACHED*/
436}
437
438/* IPSECDOI_ESP -> SADB_EALG */
439static u_int
440ipsecdoi2pfkey_ealg(t_id)
441 u_int t_id;
442{
443 switch (t_id) {
444 case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */
445 return SADB_EALG_DESCBC;
446 case IPSECDOI_ESP_DES:
447 return SADB_EALG_DESCBC;
448 case IPSECDOI_ESP_3DES:
449 return SADB_EALG_3DESCBC;
450#ifdef SADB_X_EALG_RC5CBC
451 case IPSECDOI_ESP_RC5:
452 return SADB_X_EALG_RC5CBC;
453#endif
454 case IPSECDOI_ESP_CAST:
455 return SADB_X_EALG_CAST128CBC;
456 case IPSECDOI_ESP_BLOWFISH:
457 return SADB_X_EALG_BLOWFISHCBC;
458 case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD|
459 SADB_X_EXT_IV4B)*/
460 return SADB_EALG_DESCBC;
461 case IPSECDOI_ESP_NULL:
462 return SADB_EALG_NULL;
463#ifdef SADB_X_EALG_RIJNDAELCBC
464 case IPSECDOI_ESP_RIJNDAEL:
465 return SADB_X_EALG_RIJNDAELCBC;
466#endif
467#ifdef SADB_X_EALG_TWOFISHCBC
468 case IPSECDOI_ESP_TWOFISH:
469 return SADB_X_EALG_TWOFISHCBC;
470#endif
471
472 /* not supported */
473 case IPSECDOI_ESP_3IDEA:
474 case IPSECDOI_ESP_IDEA:
475 case IPSECDOI_ESP_RC4:
476 plog(LLV_ERROR, LOCATION, NULL,
477 "Not supported transform: %u\n", t_id);
478 return ~0;
479
480 case 0: /* reserved */
481 default:
482 plog(LLV_ERROR, LOCATION, NULL,
483 "Invalid transform id: %u\n", t_id);
484 return ~0;
485 }
486 /*NOTREACHED*/
487}
488
489/* IPCOMP -> SADB_CALG */
490static u_int
491ipsecdoi2pfkey_calg(t_id)
492 u_int t_id;
493{
494 switch (t_id) {
495 case IPSECDOI_IPCOMP_OUI:
496 return SADB_X_CALG_OUI;
497 case IPSECDOI_IPCOMP_DEFLATE:
498 return SADB_X_CALG_DEFLATE;
499 case IPSECDOI_IPCOMP_LZS:
500 return SADB_X_CALG_LZS;
501
502 case 0: /* reserved */
503 default:
504 plog(LLV_ERROR, LOCATION, NULL,
505 "Invalid transform id: %u\n", t_id);
506 return ~0;
507 }
508 /*NOTREACHED*/
509}
510
511/* IPSECDOI_PROTO -> SADB_SATYPE */
512u_int
513ipsecdoi2pfkey_proto(proto)
514 u_int proto;
515{
516 switch (proto) {
517 case IPSECDOI_PROTO_IPSEC_AH:
518 return SADB_SATYPE_AH;
519 case IPSECDOI_PROTO_IPSEC_ESP:
520 return SADB_SATYPE_ESP;
521 case IPSECDOI_PROTO_IPCOMP:
522 return SADB_X_SATYPE_IPCOMP;
523
524 default:
525 plog(LLV_ERROR, LOCATION, NULL,
526 "Invalid ipsec_doi proto: %u\n", proto);
527 return ~0;
528 }
529 /*NOTREACHED*/
530}
531
532static u_int
533ipsecdoi2pfkey_alg(algclass, type)
534 u_int algclass, type;
535{
536 switch (algclass) {
537 case IPSECDOI_ATTR_AUTH:
538 return ipsecdoi2pfkey_aalg(type);
539 case IPSECDOI_PROTO_IPSEC_ESP:
540 return ipsecdoi2pfkey_ealg(type);
541 case IPSECDOI_PROTO_IPCOMP:
542 return ipsecdoi2pfkey_calg(type);
543 default:
544 plog(LLV_ERROR, LOCATION, NULL,
545 "Invalid ipsec_doi algclass: %u\n", algclass);
546 return ~0;
547 }
548 /*NOTREACHED*/
549}
550
551/* SADB_SATYPE -> IPSECDOI_PROTO */
552u_int
553pfkey2ipsecdoi_proto(satype)
554 u_int satype;
555{
556 switch (satype) {
557 case SADB_SATYPE_AH:
558 return IPSECDOI_PROTO_IPSEC_AH;
559 case SADB_SATYPE_ESP:
560 return IPSECDOI_PROTO_IPSEC_ESP;
561 case SADB_X_SATYPE_IPCOMP:
562 return IPSECDOI_PROTO_IPCOMP;
563
564 default:
565 plog(LLV_ERROR, LOCATION, NULL,
566 "Invalid pfkey proto: %u\n", satype);
567 return ~0;
568 }
569 /*NOTREACHED*/
570}
571
572/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
573u_int
574ipsecdoi2pfkey_mode(mode)
575 u_int mode;
576{
577 switch (mode) {
578 case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
579 return IPSEC_MODE_TUNNEL;
580 case IPSECDOI_ATTR_ENC_MODE_TRNS:
581 return IPSEC_MODE_TRANSPORT;
582 default:
583 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
584 return ~0;
585 }
586 /*NOTREACHED*/
587}
588
589/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
590u_int
591pfkey2ipsecdoi_mode(mode)
592 u_int mode;
593{
594 switch (mode) {
595 case IPSEC_MODE_TUNNEL:
596 return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
597 case IPSEC_MODE_TRANSPORT:
598 return IPSECDOI_ATTR_ENC_MODE_TRNS;
599 case IPSEC_MODE_ANY:
600 return IPSECDOI_ATTR_ENC_MODE_ANY;
601 default:
602 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
603 return ~0;
604 }
605 /*NOTREACHED*/
606}
607
608/* default key length for encryption algorithm */
609static u_int
610keylen_aalg(hashtype)
611 u_int hashtype;
612{
613 int res;
614
615 if (hashtype == 0)
616 return SADB_AALG_NONE;
617
618 res = alg_ipsec_hmacdef_hashlen(hashtype);
619 if (res == -1) {
620 plog(LLV_ERROR, LOCATION, NULL,
621 "invalid hmac algorithm %u.\n", hashtype);
622 return ~0;
623 }
624 return res;
625}
626
627/* default key length for encryption algorithm */
628static u_int
629keylen_ealg(enctype, encklen)
630 u_int enctype;
631 int encklen;
632{
633 int res;
634
635 res = alg_ipsec_encdef_keylen(enctype, encklen);
636 if (res == -1) {
637 plog(LLV_ERROR, LOCATION, NULL,
638 "invalid encryption algorithm %u.\n", enctype);
639 return ~0;
640 }
641 return res;
642}
643
644int
645pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
646 e_type, e_keylen, a_type, a_keylen, flags)
647 u_int proto_id;
648 u_int t_id;
649 u_int hashtype;
650 u_int *e_type;
651 u_int *e_keylen;
652 u_int *a_type;
653 u_int *a_keylen;
654 u_int *flags;
655{
656 *flags = 0;
657 switch (proto_id) {
658 case IPSECDOI_PROTO_IPSEC_ESP:
659 if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
660 goto bad;
661 if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
662 goto bad;
663 *e_keylen >>= 3;
664
665 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
666 goto bad;
667 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
668 goto bad;
669 *a_keylen >>= 3;
670
671 if (*e_type == SADB_EALG_NONE) {
672 plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
673 goto bad;
674 }
675 break;
676
677 case IPSECDOI_PROTO_IPSEC_AH:
678 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
679 goto bad;
680 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
681 goto bad;
682 *a_keylen >>= 3;
683
684 if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
685 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
686 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
687 *a_type = SADB_X_AALG_MD5;
688 *flags |= SADB_X_EXT_OLD;
689 }
690 *e_type = SADB_EALG_NONE;
691 *e_keylen = 0;
692 if (*a_type == SADB_AALG_NONE) {
693 plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
694 goto bad;
695 }
696 break;
697
698 case IPSECDOI_PROTO_IPCOMP:
699 if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
700 goto bad;
701 *e_keylen = 0;
702
703 *flags = SADB_X_EXT_RAWCPI;
704
705 *a_type = SADB_AALG_NONE;
706 *a_keylen = 0;
707 if (*e_type == SADB_X_CALG_NONE) {
708 plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
709 goto bad;
710 }
711 break;
712
713 default:
714 plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
715 goto bad;
716 }
717
718 return 0;
719
720 bad:
721 errno = EINVAL;
722 return -1;
723}
724
725/* called from scheduler */
726void
727pfkey_timeover_stub(p)
728 void *p;
729{
730
731 pfkey_timeover((struct ph2handle *)p);
732}
733
734void
735pfkey_timeover(iph2)
736 struct ph2handle *iph2;
737{
738 plog(LLV_ERROR, LOCATION, NULL,
739 "%s give up to get IPsec-SA due to time up to wait.\n",
740 saddrwop2str(iph2->dst));
741 SCHED_KILL(iph2->sce);
742
743 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
744 if (iph2->side == INITIATOR)
745 pk_sendeacquire(iph2);
746
747 unbindph12(iph2);
748 remph2(iph2);
749 delph2(iph2);
750
751 return;
752}
753
754/*%%%*/
755/* send getspi message per ipsec protocol per remote address */
756/*
757 * the local address and remote address in ph1handle are dealed
758 * with destination address and source address respectively.
759 * Because SPI is decided by responder.
760 */
761int
762pk_sendgetspi(iph2)
763 struct ph2handle *iph2;
764{
765 u_int satype, mode;
766 struct saprop *pp;
767 struct saproto *pr;
768
769 pp = iph2->side == INITIATOR
770 ? iph2->proposal
771 : iph2->approval;
772
773 for (pr = pp->head; pr != NULL; pr = pr->next) {
774
775 /* validity check */
776 satype = ipsecdoi2pfkey_proto(pr->proto_id);
777 if (satype == ~0) {
778 plog(LLV_ERROR, LOCATION, NULL,
779 "invalid proto_id %d\n", pr->proto_id);
780 return -1;
781 }
782 mode = ipsecdoi2pfkey_mode(pr->encmode);
783 if (mode == ~0) {
784 plog(LLV_ERROR, LOCATION, NULL,
785 "invalid encmode %d\n", pr->encmode);
786 return -1;
787 }
788
789 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
790 if (pfkey_send_getspi(
791 lcconf->sock_pfkey,
792 satype,
793 mode,
794 iph2->dst, /* src of SA */
795 iph2->src, /* dst of SA */
796 0, 0, pr->reqid_in, iph2->seq) < 0) {
797 plog(LLV_ERROR, LOCATION, NULL,
798 "ipseclib failed send getspi (%s)\n",
799 ipsec_strerror());
800 return -1;
801 }
802 plog(LLV_DEBUG, LOCATION, NULL,
803 "pfkey GETSPI sent: %s\n",
804 sadbsecas2str(iph2->dst, iph2->src, satype, 0, mode));
805 }
806
807 return 0;
808}
809
810/*
811 * receive GETSPI from kernel.
812 */
813static int
814pk_recvgetspi(mhp)
815 caddr_t *mhp;
816{
817 struct sadb_msg *msg;
818 struct sadb_sa *sa;
819 struct ph2handle *iph2;
820 struct sockaddr *dst;
821 int proto_id;
822 int allspiok, notfound;
823 struct saprop *pp;
824 struct saproto *pr;
825
826 /* validity check */
827 if (mhp[SADB_EXT_SA] == NULL
828 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
829 plog(LLV_ERROR, LOCATION, NULL,
830 "inappropriate sadb getspi message passed.\n");
831 return -1;
832 }
833 msg = (struct sadb_msg *)mhp[0];
834 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
835 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
836
837 /* the message has to be processed or not ? */
838 if (msg->sadb_msg_pid != getpid()) {
839 plog(LLV_DEBUG, LOCATION, NULL,
840 "%s message is not interesting "
841 "because pid %d is not mine.\n",
842 s_pfkey_type(msg->sadb_msg_type),
843 msg->sadb_msg_pid);
844 return -1;
845 }
846
847 iph2 = getph2byseq(msg->sadb_msg_seq);
848 if (iph2 == NULL) {
849 plog(LLV_DEBUG, LOCATION, NULL,
850 "seq %d of %s message not interesting.\n",
851 msg->sadb_msg_seq,
852 s_pfkey_type(msg->sadb_msg_type));
853 return -1;
854 }
855
856 if (iph2->status != PHASE2ST_GETSPISENT) {
857 plog(LLV_ERROR, LOCATION, NULL,
858 "status mismatch (db:%d msg:%d)\n",
859 iph2->status, PHASE2ST_GETSPISENT);
860 return -1;
861 }
862
863 /* set SPI, and check to get all spi whether or not */
864 allspiok = 1;
865 notfound = 1;
866 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
867 pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
868
869 for (pr = pp->head; pr != NULL; pr = pr->next) {
870 if (pr->proto_id == proto_id && pr->spi == 0) {
871 pr->spi = sa->sadb_sa_spi;
872 notfound = 0;
873 plog(LLV_DEBUG, LOCATION, NULL,
874 "pfkey GETSPI succeeded: %s\n",
875 sadbsecas2str(iph2->dst, iph2->src,
876 msg->sadb_msg_satype,
877 sa->sadb_sa_spi,
878 ipsecdoi2pfkey_mode(pr->encmode)));
879 }
880 if (pr->spi == 0)
881 allspiok = 0; /* not get all spi */
882 }
883
884 if (notfound) {
885 plog(LLV_ERROR, LOCATION, NULL,
886 "get spi for unknown address %s\n",
887 saddrwop2str(iph2->dst));
888 return -1;
889 }
890
891 if (allspiok) {
892 /* update status */
893 iph2->status = PHASE2ST_GETSPIDONE;
894 if (isakmp_post_getspi(iph2) < 0) {
895 plog(LLV_ERROR, LOCATION, NULL,
896 "failed to start post getspi.\n");
897 unbindph12(iph2);
898 remph2(iph2);
899 delph2(iph2);
900 iph2 = NULL;
901 return -1;
902 }
903 }
904
905 return 0;
906}
907
908/*
909 * set inbound SA
910 */
911int
912pk_sendupdate(iph2)
913 struct ph2handle *iph2;
914{
915 struct saproto *pr;
916 struct sockaddr *src = NULL, *dst = NULL;
917 int e_type, e_keylen, a_type, a_keylen, flags;
918 u_int satype, mode;
919 u_int64_t lifebyte = 0;
920
921 /* sanity check */
922 if (iph2->approval == NULL) {
923 plog(LLV_ERROR, LOCATION, NULL,
924 "no approvaled SAs found.\n");
925 }
926
927 /* for mobile IPv6 */
928 if (iph2->ph1->rmconf->support_mip6 && iph2->src_id && iph2->dst_id) {
929 src = iph2->src_id;
930 dst = iph2->dst_id;
931 } else {
932 src = iph2->src;
933 dst = iph2->dst;
934 }
935
936 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
937 /* validity check */
938 satype = ipsecdoi2pfkey_proto(pr->proto_id);
939 if (satype == ~0) {
940 plog(LLV_ERROR, LOCATION, NULL,
941 "invalid proto_id %d\n", pr->proto_id);
942 return -1;
943 }
944#ifdef ENABLE_SAMODE_UNSPECIFIED
945 mode = IPSEC_MODE_ANY;
946#else
947 mode = ipsecdoi2pfkey_mode(pr->encmode);
948 if (mode == ~0) {
949 plog(LLV_ERROR, LOCATION, NULL,
950 "invalid encmode %d\n", pr->encmode);
951 return -1;
952 }
953#endif
954
955 /* set algorithm type and key length */
956 e_keylen = pr->head->encklen;
957 if (pfkey_convertfromipsecdoi(
958 pr->proto_id,
959 pr->head->trns_id,
960 pr->head->authtype,
961 &e_type, &e_keylen,
962 &a_type, &a_keylen, &flags) < 0)
963 return -1;
964
965#if 0
966 lifebyte = iph2->approval->lifebyte * 1024,
967#else
968 lifebyte = 0;
969#endif
970
971 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update\n");
972
973 if (pfkey_send_update(
974 lcconf->sock_pfkey,
975 satype,
976 mode,
977 iph2->dst,
978 iph2->src,
979 pr->spi,
980 pr->reqid_in,
981 4, /* XXX static size of window */
982 pr->keymat->v,
983 e_type, e_keylen, a_type, a_keylen, flags,
984 0, lifebyte, iph2->approval->lifetime, 0,
985 iph2->seq) < 0) {
986 plog(LLV_ERROR, LOCATION, NULL,
987 "libipsec failed send update (%s)\n",
988 ipsec_strerror());
989 return -1;
990 }
991
992 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
993 continue;
994
995 /*
996 * It maybe good idea to call backupsa_to_file() after
997 * racoon will receive the sadb_update messages.
998 * But it is impossible because there is not key in the
999 * information from the kernel.
1000 */
1001 if (backupsa_to_file(satype, mode, iph2->dst, iph2->src,
1002 pr->spi, pr->reqid_in, 4,
1003 pr->keymat->v,
1004 e_type, e_keylen, a_type, a_keylen, flags,
1005 0, iph2->approval->lifebyte * 1024,
1006 iph2->approval->lifetime, 0,
1007 iph2->seq) < 0) {
1008 plog(LLV_ERROR, LOCATION, NULL,
1009 "backuped SA failed: %s\n",
1010 sadbsecas2str(iph2->dst, iph2->src,
1011 satype, pr->spi, mode));
1012 }
1013 plog(LLV_DEBUG, LOCATION, NULL,
1014 "backuped SA: %s\n",
1015 sadbsecas2str(iph2->dst, iph2->src,
1016 satype, pr->spi, mode));
1017 }
1018
1019 return 0;
1020}
1021
1022static int
1023pk_recvupdate(mhp)
1024 caddr_t *mhp;
1025{
1026 struct sadb_msg *msg;
1027 struct sadb_sa *sa;
1028 struct sockaddr *src, *dst;
1029 struct ph2handle *iph2;
1030 u_int proto_id, encmode, sa_mode;
1031 int incomplete = 0;
1032 struct saproto *pr;
1033
1034 /* ignore this message because of local test mode. */
1035 if (f_local)
1036 return 0;
1037
1038 /* sanity check */
1039 if (mhp[0] == NULL
1040 || mhp[SADB_EXT_SA] == NULL
1041 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1042 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1043 plog(LLV_ERROR, LOCATION, NULL,
1044 "inappropriate sadb update message passed.\n");
1045 return -1;
1046 }
1047 msg = (struct sadb_msg *)mhp[0];
1048 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1049 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1050 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1051
1052 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1053 ? IPSEC_MODE_ANY
1054 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1055
1056 /* the message has to be processed or not ? */
1057 if (msg->sadb_msg_pid != getpid()) {
1058 plog(LLV_DEBUG, LOCATION, NULL,
1059 "%s message is not interesting "
1060 "because pid %d is not mine.\n",
1061 s_pfkey_type(msg->sadb_msg_type),
1062 msg->sadb_msg_pid);
1063 return -1;
1064 }
1065
1066 iph2 = getph2byseq(msg->sadb_msg_seq);
1067 if (iph2 == NULL) {
1068 plog(LLV_DEBUG, LOCATION, NULL,
1069 "seq %d of %s message not interesting.\n",
1070 msg->sadb_msg_seq,
1071 s_pfkey_type(msg->sadb_msg_type));
1072 return -1;
1073 }
1074
1075 if (iph2->status != PHASE2ST_ADDSA) {
1076 plog(LLV_ERROR, LOCATION, NULL,
1077 "status mismatch (db:%d msg:%d)\n",
1078 iph2->status, PHASE2ST_ADDSA);
1079 return -1;
1080 }
1081
1082 /* check to complete all keys ? */
1083 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1084 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1085 if (proto_id == ~0) {
1086 plog(LLV_ERROR, LOCATION, NULL,
1087 "invalid proto_id %d\n", msg->sadb_msg_satype);
1088 return -1;
1089 }
1090 encmode = pfkey2ipsecdoi_mode(sa_mode);
1091 if (encmode == ~0) {
1092 plog(LLV_ERROR, LOCATION, NULL,
1093 "invalid encmode %d\n", sa_mode);
1094 return -1;
1095 }
1096
1097 if (pr->proto_id == proto_id
1098 && pr->spi == sa->sadb_sa_spi) {
1099 pr->ok = 1;
1100 plog(LLV_DEBUG, LOCATION, NULL,
1101 "pfkey UPDATE succeeded: %s\n",
1102 sadbsecas2str(iph2->dst, iph2->src,
1103 msg->sadb_msg_satype,
1104 sa->sadb_sa_spi,
1105 sa_mode));
1106
1107 plog(LLV_INFO, LOCATION, NULL,
1108 "IPsec-SA established: %s\n",
1109 sadbsecas2str(iph2->dst, iph2->src,
1110 msg->sadb_msg_satype, sa->sadb_sa_spi,
1111 sa_mode));
1112 }
1113
1114 if (pr->ok == 0)
1115 incomplete = 1;
1116 }
1117
1118 if (incomplete)
1119 return 0;
1120
1121 /* turn off the timer for calling pfkey_timeover() */
1122 SCHED_KILL(iph2->sce);
1123
1124 /* update status */
1125 iph2->status = PHASE2ST_ESTABLISHED;
1126
1127#ifdef ENABLE_STATS
1128 gettimeofday(&iph2->end, NULL);
1129 syslog(LOG_NOTICE, "%s(%s): %8.6f",
1130 "phase2", "quick", timedelta(&iph2->start, &iph2->end));
1131#endif
1132
1133 /* count up */
1134 iph2->ph1->ph2cnt++;
1135
1136 /*
1137 * since we are going to reuse the phase2 handler, we need to
1138 * remain it and refresh all the references between ph1 and ph2 to use.
1139 */
1140 unbindph12(iph2);
1141
1142 iph2->sce = sched_new(iph2->approval->lifetime,
1143 isakmp_ph2expire_stub, iph2);
1144
1145 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1146 return 0;
1147}
1148
1149/*
1150 * set outbound SA
1151 */
1152int
1153pk_sendadd(iph2)
1154 struct ph2handle *iph2;
1155{
1156 struct saproto *pr;
1157 struct sockaddr *src = NULL, *dst = NULL;
1158 int e_type, e_keylen, a_type, a_keylen, flags;
1159 u_int satype, mode;
1160 u_int64_t lifebyte = 0;
1161
1162 /* sanity check */
1163 if (iph2->approval == NULL) {
1164 plog(LLV_ERROR, LOCATION, NULL,
1165 "no approvaled SAs found.\n");
1166 }
1167
1168 /* for mobile IPv6 */
1169 if (iph2->ph1->rmconf->support_mip6 && iph2->src_id && iph2->dst_id) {
1170 src = iph2->src_id;
1171 dst = iph2->dst_id;
1172 } else {
1173 src = iph2->src;
1174 dst = iph2->dst;
1175 }
1176
1177 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1178 /* validity check */
1179 satype = ipsecdoi2pfkey_proto(pr->proto_id);
1180 if (satype == ~0) {
1181 plog(LLV_ERROR, LOCATION, NULL,
1182 "invalid proto_id %d\n", pr->proto_id);
1183 return -1;
1184 }
1185#ifdef ENABLE_SAMODE_UNSPECIFIED
1186 mode = IPSEC_MODE_ANY;
1187#else
1188 mode = ipsecdoi2pfkey_mode(pr->encmode);
1189 if (mode == ~0) {
1190 plog(LLV_ERROR, LOCATION, NULL,
1191 "invalid encmode %d\n", pr->encmode);
1192 return -1;
1193 }
1194#endif
1195
1196 /* set algorithm type and key length */
1197 e_keylen = pr->head->encklen;
1198 if (pfkey_convertfromipsecdoi(
1199 pr->proto_id,
1200 pr->head->trns_id,
1201 pr->head->authtype,
1202 &e_type, &e_keylen,
1203 &a_type, &a_keylen, &flags) < 0)
1204 return -1;
1205
1206#if 0
1207 lifebyte = iph2->approval->lifebyte * 1024,
1208#else
1209 lifebyte = 0;
1210#endif
1211
1212 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add\n");
1213
1214 if (pfkey_send_add(
1215 lcconf->sock_pfkey,
1216 satype,
1217 mode,
1218 iph2->src,
1219 iph2->dst,
1220 pr->spi_p,
1221 pr->reqid_out,
1222 4, /* XXX static size of window */
1223 pr->keymat_p->v,
1224 e_type, e_keylen, a_type, a_keylen, flags,
1225 0, lifebyte, iph2->approval->lifetime, 0,
1226 iph2->seq) < 0) {
1227 plog(LLV_ERROR, LOCATION, NULL,
1228 "libipsec failed send add (%s)\n",
1229 ipsec_strerror());
1230 return -1;
1231 }
1232
1233 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1234 continue;
1235
1236 /*
1237 * It maybe good idea to call backupsa_to_file() after
1238 * racoon will receive the sadb_update messages.
1239 * But it is impossible because there is not key in the
1240 * information from the kernel.
1241 */
1242 if (backupsa_to_file(satype, mode, iph2->src, iph2->dst,
1243 pr->spi_p, pr->reqid_out, 4,
1244 pr->keymat_p->v,
1245 e_type, e_keylen, a_type, a_keylen, flags,
1246 0, iph2->approval->lifebyte * 1024,
1247 iph2->approval->lifetime, 0,
1248 iph2->seq) < 0) {
1249 plog(LLV_ERROR, LOCATION, NULL,
1250 "backuped SA failed: %s\n",
1251 sadbsecas2str(iph2->src, iph2->dst,
1252 satype, pr->spi_p, mode));
1253 }
1254 plog(LLV_DEBUG, LOCATION, NULL,
1255 "backuped SA: %s\n",
1256 sadbsecas2str(iph2->src, iph2->dst,
1257 satype, pr->spi_p, mode));
1258 }
1259
1260 return 0;
1261}
1262
1263static int
1264pk_recvadd(mhp)
1265 caddr_t *mhp;
1266{
1267 struct sadb_msg *msg;
1268 struct sadb_sa *sa;
1269 struct sockaddr *src, *dst;
1270 struct ph2handle *iph2;
1271 u_int sa_mode;
1272
1273 /* ignore this message because of local test mode. */
1274 if (f_local)
1275 return 0;
1276
1277 /* sanity check */
1278 if (mhp[0] == NULL
1279 || mhp[SADB_EXT_SA] == NULL
1280 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1281 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1282 plog(LLV_ERROR, LOCATION, NULL,
1283 "inappropriate sadb add message passed.\n");
1284 return -1;
1285 }
1286 msg = (struct sadb_msg *)mhp[0];
1287 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1288 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1289 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1290
1291 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1292 ? IPSEC_MODE_ANY
1293 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1294
1295 /* the message has to be processed or not ? */
1296 if (msg->sadb_msg_pid != getpid()) {
1297 plog(LLV_DEBUG, LOCATION, NULL,
1298 "%s message is not interesting "
1299 "because pid %d is not mine.\n",
1300 s_pfkey_type(msg->sadb_msg_type),
1301 msg->sadb_msg_pid);
1302 return -1;
1303 }
1304
1305 iph2 = getph2byseq(msg->sadb_msg_seq);
1306 if (iph2 == NULL) {
1307 plog(LLV_DEBUG, LOCATION, NULL,
1308 "seq %d of %s message not interesting.\n",
1309 msg->sadb_msg_seq,
1310 s_pfkey_type(msg->sadb_msg_type));
1311 return -1;
1312 }
1313
1314 /*
1315 * NOTE don't update any status of phase2 handle
1316 * because they must be updated by SADB_UPDATE message
1317 */
1318
1319 plog(LLV_INFO, LOCATION, NULL,
1320 "IPsec-SA established: %s\n",
1321 sadbsecas2str(iph2->src, iph2->dst,
1322 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1323
1324 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1325 return 0;
1326}
1327
1328static int
1329pk_recvexpire(mhp)
1330 caddr_t *mhp;
1331{
1332 struct sadb_msg *msg;
1333 struct sadb_sa *sa;
1334 struct sockaddr *src, *dst;
1335 struct ph2handle *iph2;
1336 u_int proto_id, sa_mode;
1337
1338 /* sanity check */
1339 if (mhp[0] == NULL
1340 || mhp[SADB_EXT_SA] == NULL
1341 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1342 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1343 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1344 && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1345 plog(LLV_ERROR, LOCATION, NULL,
1346 "inappropriate sadb expire message passed.\n");
1347 return -1;
1348 }
1349 msg = (struct sadb_msg *)mhp[0];
1350 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1351 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1352 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1353
1354 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1355 ? IPSEC_MODE_ANY
1356 : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1357
1358 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1359 if (proto_id == ~0) {
1360 plog(LLV_ERROR, LOCATION, NULL,
1361 "invalid proto_id %d\n", msg->sadb_msg_satype);
1362 return -1;
1363 }
1364
1365 plog(LLV_INFO, LOCATION, NULL,
1366 "IPsec-SA expired: %s\n",
1367 sadbsecas2str(src, dst,
1368 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1369
1370 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1371 if (iph2 == NULL) {
1372 /*
1373 * Ignore it because two expire messages are come up.
1374 * phase2 handler has been deleted already when 2nd message
1375 * is received.
1376 */
1377 plog(LLV_DEBUG, LOCATION, NULL,
1378 "no such a SA found: %s\n",
1379 sadbsecas2str(src, dst,
1380 msg->sadb_msg_satype, sa->sadb_sa_spi,
1381 sa_mode));
1382 return 0;
1383 }
1384 if (iph2->status != PHASE2ST_ESTABLISHED) {
1385 /*
1386 * If the status is not equal to PHASE2ST_ESTABLISHED,
1387 * racoon ignores this expire message. There are two reason.
1388 * One is that the phase 2 probably starts becuase there is
1389 * a potential that racoon receives the acquire message
1390 * without receiving a expire message. Another is that racoon
1391 * may receive the multiple expire messages from the kernel.
1392 */
1393 plog(LLV_WARNING, LOCATION, NULL,
1394 "the expire message is received "
1395 "but the handler has not been established.\n");
1396 return 0;
1397 }
1398
1399 /* turn off the timer for calling isakmp_ph2expire() */
1400 SCHED_KILL(iph2->sce);
1401
1402 iph2->status = PHASE2ST_EXPIRED;
1403
1404 /* INITIATOR, begin phase 2 exchange. */
1405 /* allocate buffer for status management of pfkey message */
1406 if (iph2->side == INITIATOR) {
1407
1408 initph2(iph2);
1409
1410 /* update status for re-use */
1411 iph2->status = PHASE2ST_STATUS2;
1412
1413 /* start isakmp initiation by using ident exchange */
1414 if (isakmp_post_acquire(iph2) < 0) {
1415 plog(LLV_ERROR, LOCATION, iph2->dst,
1416 "failed to begin ipsec sa "
1417 "re-negotication.\n");
1418 unbindph12(iph2);
1419 remph2(iph2);
1420 delph2(iph2);
1421 return -1;
1422 }
1423
1424 return 0;
1425 /*NOTREACHED*/
1426 }
1427
1428 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1429 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't
1430 * manage IPsec SA, so delete the list */
1431 unbindph12(iph2);
1432 remph2(iph2);
1433 delph2(iph2);
1434
1435 return 0;
1436}
1437
1438static int
1439pk_recvacquire(mhp)
1440 caddr_t *mhp;
1441{
1442 struct sadb_msg *msg;
1443 struct sadb_x_policy *xpl;
1444 struct secpolicy *sp_out = NULL, *sp_in = NULL;
1445#define MAXNESTEDSA 5 /* XXX */
1446 struct ph2handle *iph2[MAXNESTEDSA];
1447 int n; /* # of phase 2 handler */
1448
1449 /* ignore this message because of local test mode. */
1450 if (f_local)
1451 return 0;
1452
1453 /* sanity check */
1454 if (mhp[0] == NULL
1455 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1456 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1457 || mhp[SADB_X_EXT_POLICY] == NULL) {
1458 plog(LLV_ERROR, LOCATION, NULL,
1459 "inappropriate sadb acquire message passed.\n");
1460 return -1;
1461 }
1462 msg = (struct sadb_msg *)mhp[0];
1463 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1464
1465 /* ignore if type is not IPSEC_POLICY_IPSEC */
1466 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1467 plog(LLV_DEBUG, LOCATION, NULL,
1468 "ignore SPDGET message. type is not IPsec.\n");
1469 return 0;
1470 }
1471
1472 /* ignore it if src is multicast address */
1473 {
1474 struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1475
1476 if ((sa->sa_family == AF_INET
1477 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
1478#ifdef INET6
1479 || (sa->sa_family == AF_INET6
1480 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
1481#endif
1482 ) {
1483 plog(LLV_DEBUG, LOCATION, NULL,
1484 "ignore due to multicast address: %s.\n",
1485 saddrwop2str(sa));
1486 return 0;
1487 }
1488 }
1489
1490 /*
1491 * If there is a phase 2 handler against the policy identifier in
1492 * the acquire message, and if
1493 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1494 * should ignore such a acquire message becuase the phase 2
1495 * is just negotiating.
1496 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1497 * has to prcesss such a acquire message becuase racoon may
1498 * lost the expire message.
1499 */
1500 iph2[0] = getph2byspid(xpl->sadb_x_policy_id);
1501 if (iph2[0] != NULL) {
1502 if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
1503 plog(LLV_DEBUG, LOCATION, NULL,
1504 "ignore the acquire becuase ph2 found\n");
1505 return -1;
1506 }
1507 if (iph2[0]->status == PHASE2ST_EXPIRED)
1508 iph2[0] = NULL;
1509 /*FALLTHROUGH*/
1510 }
1511
1512 /* search for proper policyindex */
1513 sp_out = getspbyspid(xpl->sadb_x_policy_id);
1514 if (sp_out == NULL) {
1515 plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1516 xpl->sadb_x_policy_id);
1517 return -1;
1518 }
1519 plog(LLV_DEBUG, LOCATION, NULL,
1520 "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1521
1522 /* get inbound policy */
1523 {
1524 struct policyindex spidx;
1525
1526 spidx.dir = IPSEC_DIR_INBOUND;
1527 memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1528 memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1529 spidx.prefs = sp_out->spidx.prefd;
1530 spidx.prefd = sp_out->spidx.prefs;
1531 spidx.ul_proto = sp_out->spidx.ul_proto;
1532
1533 sp_in = getsp(&spidx);
1534 if (sp_in) {
1535 plog(LLV_DEBUG, LOCATION, NULL,
1536 "suitable inbound SP found: %s.\n",
1537 spidx2str(&sp_in->spidx));
1538 } else {
1539 plog(LLV_NOTIFY, LOCATION, NULL,
1540 "no in-bound policy found: %s\n",
1541 spidx2str(&spidx));
1542 }
1543 }
1544
1545 memset(iph2, 0, MAXNESTEDSA);
1546
1547 n = 0;
1548
1549 /* allocate a phase 2 */
1550 iph2[n] = newph2();
1551 if (iph2[n] == NULL) {
1552 plog(LLV_ERROR, LOCATION, NULL,
1553 "failed to allocate phase2 entry.\n");
1554 return -1;
1555 }
1556 iph2[n]->side = INITIATOR;
1557 iph2[n]->spid = xpl->sadb_x_policy_id;
1558 iph2[n]->satype = msg->sadb_msg_satype;
1559 iph2[n]->seq = msg->sadb_msg_seq;
1560 iph2[n]->status = PHASE2ST_STATUS2;
1561
1562 /* set end addresses of SA */
1563 iph2[n]->dst = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
1564 if (iph2[n]->dst == NULL) {
1565 delph2(iph2[n]);
1566 return -1;
1567 }
1568 iph2[n]->src = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
1569 if (iph2[n]->src == NULL) {
1570 delph2(iph2[n]);
1571 return -1;
1572 }
1573
1574 plog(LLV_DEBUG, LOCATION, NULL,
1575 "new acquire %s\n", spidx2str(&sp_out->spidx));
1576
1577 /* get sainfo */
1578 {
1579 vchar_t *idsrc, *iddst;
1580
1581 idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
1582 sp_out->spidx.prefs, sp_out->spidx.ul_proto);
1583 if (idsrc == NULL) {
1584 plog(LLV_ERROR, LOCATION, NULL,
1585 "failed to get ID for %s\n",
1586 spidx2str(&sp_out->spidx));
1587 delph2(iph2[n]);
1588 return -1;
1589 }
1590 iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
1591 sp_out->spidx.prefd, sp_out->spidx.ul_proto);
1592 if (iddst == NULL) {
1593 plog(LLV_ERROR, LOCATION, NULL,
1594 "failed to get ID for %s\n",
1595 spidx2str(&sp_out->spidx));
1596 vfree(idsrc);
1597 delph2(iph2[n]);
1598 return -1;
1599 }
1600 iph2[n]->sainfo = getsainfo(idsrc, iddst);
1601 vfree(idsrc);
1602 vfree(iddst);
1603 if (iph2[n]->sainfo == NULL) {
1604 plog(LLV_ERROR, LOCATION, NULL,
1605 "failed to get sainfo.\n");
1606 delph2(iph2[n]);
1607 return -1;
1608 /* XXX should use the algorithm list from register message */
1609 }
1610 }
1611
1612 if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
1613 plog(LLV_ERROR, LOCATION, NULL,
1614 "failed to create saprop.\n");
1615 delph2(iph2[n]);
1616 return -1;
1617 }
1618 insph2(iph2[n]);
1619
1620 /* start isakmp initiation by using ident exchange */
1621 /* XXX should be looped if there are multiple phase 2 handler. */
1622 if (isakmp_post_acquire(iph2[n]) < 0) {
1623 plog(LLV_ERROR, LOCATION, NULL,
1624 "failed to begin ipsec sa negotication.\n");
1625 goto err;
1626 }
1627
1628 return 0;
1629
1630err:
1631 while (n >= 0) {
1632 unbindph12(iph2[n]);
1633 remph2(iph2[n]);
1634 delph2(iph2[n]);
1635 iph2[n] = NULL;
1636 n--;
1637 }
1638 return -1;
1639}
1640
1641static int
1642pk_recvdelete(mhp)
1643 caddr_t *mhp;
1644{
1645 struct sadb_msg *msg;
1646 struct sadb_sa *sa;
1647 struct sockaddr *src, *dst;
1648 struct ph2handle *iph2 = NULL;
1649 u_int proto_id;
1650
1651 /* ignore this message because of local test mode. */
1652 if (f_local)
1653 return 0;
1654
1655 /* sanity check */
1656 if (mhp[0] == NULL
1657 || mhp[SADB_EXT_SA] == NULL
1658 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1659 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1660 plog(LLV_ERROR, LOCATION, NULL,
1661 "inappropriate sadb acquire message passed.\n");
1662 return -1;
1663 }
1664 msg = (struct sadb_msg *)mhp[0];
1665 sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1666 src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1667 dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1668
1669 /* the message has to be processed or not ? */
1670 if (msg->sadb_msg_pid == getpid()) {
1671 plog(LLV_DEBUG, LOCATION, NULL,
1672 "%s message is not interesting "
1673 "because the message was originated by me.\n",
1674 s_pfkey_type(msg->sadb_msg_type),
1675 msg->sadb_msg_pid);
1676 return -1;
1677 }
1678
1679 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1680 if (proto_id == ~0) {
1681 plog(LLV_ERROR, LOCATION, NULL,
1682 "invalid proto_id %d\n", msg->sadb_msg_satype);
1683 return -1;
1684 }
1685
1686 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1687 if (iph2 == NULL) {
1688 /* ignore */
1689 plog(LLV_ERROR, LOCATION, NULL,
1690 "no iph2 found: %s\n",
1691 sadbsecas2str(src, dst, msg->sadb_msg_satype,
1692 sa->sadb_sa_spi, IPSEC_MODE_ANY));
1693 return 0;
1694 }
1695
1696 plog(LLV_ERROR, LOCATION, NULL,
1697 "pfkey DELETE received: %s\n",
1698 sadbsecas2str(iph2->src, iph2->dst,
1699 msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
1700
1701 /* send delete information */
1702 if (iph2->status == PHASE2ST_ESTABLISHED)
1703 isakmp_info_send_d2(iph2);
1704
1705 unbindph12(iph2);
1706 remph2(iph2);
1707 delph2(iph2);
1708
1709 return 0;
1710}
1711
1712static int
1713pk_recvflush(mhp)
1714 caddr_t *mhp;
1715{
1716 /* ignore this message because of local test mode. */
1717 if (f_local)
1718 return 0;
1719
1720 /* sanity check */
1721 if (mhp[0] == NULL) {
1722 plog(LLV_ERROR, LOCATION, NULL,
1723 "inappropriate sadb acquire message passed.\n");
1724 return -1;
1725 }
1726
1727 flushph2();
1728
1729 return 0;
1730}
1731
1732static int
1733getsadbpolicy(policy0, policylen0, type, iph2)
1734 caddr_t *policy0;
1735 int *policylen0, type;
1736 struct ph2handle *iph2;
1737{
1738 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
1739 struct sadb_x_policy *xpl;
1740 struct sadb_x_ipsecrequest *xisr;
1741 struct saproto *pr;
1742 caddr_t policy, p;
1743 int policylen;
1744 int xisrlen;
1745 u_int satype, mode;
1746
1747 /* get policy buffer size */
1748 policylen = sizeof(struct sadb_x_policy);
1749 if (type != SADB_X_SPDDELETE) {
1750 for (pr = iph2->approval->head; pr; pr = pr->next) {
1751 xisrlen = sizeof(*xisr);
1752 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
1753 xisrlen += (iph2->src->sa_len
1754 + iph2->dst->sa_len);
1755 }
1756
1757 policylen += PFKEY_ALIGN8(xisrlen);
1758 }
1759 }
1760
1761 /* make policy structure */
1762 policy = racoon_malloc(policylen);
1763 if (!policy) {
1764 plog(LLV_ERROR, LOCATION, NULL,
1765 "buffer allocation failed.\n");
1766 return -1;
1767 }
1768
1769 xpl = (struct sadb_x_policy *)policy;
1770 xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
1771 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1772 xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
1773 xpl->sadb_x_policy_dir = spidx->dir;
1774 xpl->sadb_x_policy_id = 0;
1775
1776 /* no need to append policy information any more if type is SPDDELETE */
1777 if (type == SADB_X_SPDDELETE)
1778 goto end;
1779
1780 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
1781
1782 for (pr = iph2->approval->head; pr; pr = pr->next) {
1783
1784 satype = doi2ipproto(pr->proto_id);
1785 if (satype == ~0) {
1786 plog(LLV_ERROR, LOCATION, NULL,
1787 "invalid proto_id %d\n", pr->proto_id);
1788 goto err;
1789 }
1790 mode = ipsecdoi2pfkey_mode(pr->encmode);
1791 if (mode == ~0) {
1792 plog(LLV_ERROR, LOCATION, NULL,
1793 "invalid encmode %d\n", pr->encmode);
1794 goto err;
1795 }
1796
1797 /*
1798 * the policy level cannot be unique because the policy
1799 * is defined later than SA, so req_id cannot be bound to SA.
1800 */
1801 xisr->sadb_x_ipsecrequest_proto = satype;
1802 xisr->sadb_x_ipsecrequest_mode = mode;
1803 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
1804 xisr->sadb_x_ipsecrequest_reqid = 0;
1805 p = (caddr_t)(xisr + 1);
1806
1807 xisrlen = sizeof(*xisr);
1808
1809 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
1810 xisrlen += (iph2->src->sa_len + iph2->dst->sa_len);
1811
1812 memcpy(p, iph2->src, iph2->src->sa_len);
1813 p += iph2->src->sa_len;
1814
1815 memcpy(p, iph2->dst, iph2->dst->sa_len);
1816 p += iph2->dst->sa_len;
1817 }
1818
1819 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
1820 }
1821
1822end:
1823 *policy0 = policy;
1824 *policylen0 = policylen;
1825
1826 return 0;
1827
1828err:
1829 if (policy)
1830 racoon_free(policy);
1831
1832 return -1;
1833}
1834
1835int
1836pk_sendspdupdate2(iph2)
1837 struct ph2handle *iph2;
1838{
1839 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
1840 caddr_t policy = NULL;
1841 int policylen = 0;
1842 u_int64_t ltime, vtime;
1843
1844 ltime = iph2->approval->lifetime;
1845 vtime = 0;
1846
1847 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
1848 plog(LLV_ERROR, LOCATION, NULL,
1849 "getting sadb policy failed.\n");
1850 return -1;
1851 }
1852
1853 if (pfkey_send_spdupdate2(
1854 lcconf->sock_pfkey,
1855 (struct sockaddr *)&spidx->src,
1856 spidx->prefs,
1857 (struct sockaddr *)&spidx->dst,
1858 spidx->prefd,
1859 spidx->ul_proto,
1860 ltime, vtime,
1861 policy, policylen, 0) < 0) {
1862 plog(LLV_ERROR, LOCATION, NULL,
1863 "libipsec failed send spdupdate2 (%s)\n",
1864 ipsec_strerror());
1865 goto end;
1866 }
1867 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
1868
1869end:
1870 if (policy)
1871 racoon_free(policy);
1872
1873 return 0;
1874}
1875
1876static int
1877pk_recvspdupdate(mhp)
1878 caddr_t *mhp;
1879{
1880 /* sanity check */
1881 if (mhp[0] == NULL) {
1882 plog(LLV_ERROR, LOCATION, NULL,
1883 "inappropriate sadb spdupdate message passed.\n");
1884 return -1;
1885 }
1886
1887 return 0;
1888}
1889
1890/*
1891 * this function has to be used by responder side.
1892 */
1893int
1894pk_sendspdadd2(iph2)
1895 struct ph2handle *iph2;
1896{
1897 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
1898 caddr_t policy = NULL;
1899 int policylen = 0;
1900 u_int64_t ltime, vtime;
1901
1902 ltime = iph2->approval->lifetime;
1903 vtime = 0;
1904
1905 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
1906 plog(LLV_ERROR, LOCATION, NULL,
1907 "getting sadb policy failed.\n");
1908 return -1;
1909 }
1910
1911 if (pfkey_send_spdadd2(
1912 lcconf->sock_pfkey,
1913 (struct sockaddr *)&spidx->src,
1914 spidx->prefs,
1915 (struct sockaddr *)&spidx->dst,
1916 spidx->prefd,
1917 spidx->ul_proto,
1918 ltime, vtime,
1919 policy, policylen, 0) < 0) {
1920 plog(LLV_ERROR, LOCATION, NULL,
1921 "libipsec failed send spdadd2 (%s)\n",
1922 ipsec_strerror());
1923 goto end;
1924 }
1925 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
1926
1927end:
1928 if (policy)
1929 racoon_free(policy);
1930
1931 return 0;
1932}
1933
1934static int
1935pk_recvspdadd(mhp)
1936 caddr_t *mhp;
1937{
1938 struct sadb_address *saddr, *daddr;
1939 struct sadb_x_policy *xpl;
1940 struct policyindex spidx;
1941 struct secpolicy *sp;
1942
1943 /* sanity check */
1944 if (mhp[0] == NULL
1945 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1946 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1947 || mhp[SADB_X_EXT_POLICY] == NULL) {
1948 plog(LLV_ERROR, LOCATION, NULL,
1949 "inappropriate sadb spdadd message passed.\n");
1950 return -1;
1951 }
1952 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
1953 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
1954 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1955
1956 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
1957 saddr + 1,
1958 daddr + 1,
1959 saddr->sadb_address_prefixlen,
1960 daddr->sadb_address_prefixlen,
1961 saddr->sadb_address_proto,
1962 &spidx);
1963
1964 sp = getsp(&spidx);
1965 if (sp != NULL) {
1966 plog(LLV_ERROR, LOCATION, NULL,
1967 "such policy already exists. "
1968 "anyway replace it: %s\n",
1969 spidx2str(&spidx));
1970 remsp(sp);
1971 delsp(sp);
1972 }
1973
1974 if (addnewsp(mhp) < 0)
1975 return -1;
1976
1977 return 0;
1978}
1979
1980/*
1981 * this function has to be used by responder side.
1982 */
1983int
1984pk_sendspddelete(iph2)
1985 struct ph2handle *iph2;
1986{
1987 struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
1988 caddr_t policy = NULL;
1989 int policylen;
1990
1991 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
1992 plog(LLV_ERROR, LOCATION, NULL,
1993 "getting sadb policy failed.\n");
1994 return -1;
1995 }
1996
1997 if (pfkey_send_spddelete(
1998 lcconf->sock_pfkey,
1999 (struct sockaddr *)&spidx->src,
2000 spidx->prefs,
2001 (struct sockaddr *)&spidx->dst,
2002 spidx->prefd,
2003 spidx->ul_proto,
2004 policy, policylen, 0) < 0) {
2005 plog(LLV_ERROR, LOCATION, NULL,
2006 "libipsec failed send spddelete (%s)\n",
2007 ipsec_strerror());
2008 goto end;
2009 }
2010 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2011
2012end:
2013 if (policy)
2014 racoon_free(policy);
2015
2016 return 0;
2017}
2018
2019static int
2020pk_recvspddelete(mhp)
2021 caddr_t *mhp;
2022{
2023 struct sadb_address *saddr, *daddr;
2024 struct sadb_x_policy *xpl;
2025 struct policyindex spidx;
2026 struct secpolicy *sp;
2027
2028 /* sanity check */
2029 if (mhp[0] == NULL
2030 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2031 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2032 || mhp[SADB_X_EXT_POLICY] == NULL) {
2033 plog(LLV_ERROR, LOCATION, NULL,
2034 "inappropriate sadb spddelete message passed.\n");
2035 return -1;
2036 }
2037 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2038 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2039 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2040
2041 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2042 saddr + 1,
2043 daddr + 1,
2044 saddr->sadb_address_prefixlen,
2045 daddr->sadb_address_prefixlen,
2046 saddr->sadb_address_proto,
2047 &spidx);
2048
2049 sp = getsp(&spidx);
2050 if (sp == NULL) {
2051 plog(LLV_ERROR, LOCATION, NULL,
2052 "no policy found: %s\n",
2053 spidx2str(&spidx));
2054 return -1;
2055 }
2056
2057 remsp(sp);
2058 delsp(sp);
2059
2060 return 0;
2061}
2062
2063static int
2064pk_recvspdexpire(mhp)
2065 caddr_t *mhp;
2066{
2067 struct sadb_address *saddr, *daddr;
2068 struct sadb_x_policy *xpl;
2069 struct policyindex spidx;
2070 struct secpolicy *sp;
2071
2072 /* sanity check */
2073 if (mhp[0] == NULL
2074 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2075 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2076 || mhp[SADB_X_EXT_POLICY] == NULL) {
2077 plog(LLV_ERROR, LOCATION, NULL,
2078 "inappropriate sadb spdexpire message passed.\n");
2079 return -1;
2080 }
2081 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2082 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2083 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2084
2085 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2086 saddr + 1,
2087 daddr + 1,
2088 saddr->sadb_address_prefixlen,
2089 daddr->sadb_address_prefixlen,
2090 saddr->sadb_address_proto,
2091 &spidx);
2092
2093 sp = getsp(&spidx);
2094 if (sp == NULL) {
2095 plog(LLV_ERROR, LOCATION, NULL,
2096 "no policy found: %s\n",
2097 spidx2str(&spidx));
2098 return -1;
2099 }
2100
2101 remsp(sp);
2102 delsp(sp);
2103
2104 return 0;
2105}
2106
2107static int
2108pk_recvspdget(mhp)
2109 caddr_t *mhp;
2110{
2111 /* sanity check */
2112 if (mhp[0] == NULL) {
2113 plog(LLV_ERROR, LOCATION, NULL,
2114 "inappropriate sadb spdget message passed.\n");
2115 return -1;
2116 }
2117
2118 return 0;
2119}
2120
2121static int
2122pk_recvspddump(mhp)
2123 caddr_t *mhp;
2124{
2125 struct sadb_msg *msg;
2126 struct sadb_address *saddr, *daddr;
2127 struct sadb_x_policy *xpl;
2128 struct policyindex spidx;
2129 struct secpolicy *sp;
2130
2131 /* sanity check */
2132 if (mhp[0] == NULL) {
2133 plog(LLV_ERROR, LOCATION, NULL,
2134 "inappropriate sadb spddump message passed.\n");
2135 return -1;
2136 }
2137 msg = (struct sadb_msg *)mhp[0];
2138
2139 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2140 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2141 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2142
2143 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2144 saddr + 1,
2145 daddr + 1,
2146 saddr->sadb_address_prefixlen,
2147 daddr->sadb_address_prefixlen,
2148 saddr->sadb_address_proto,
2149 &spidx);
2150
2151 sp = getsp(&spidx);
2152 if (sp != NULL) {
2153 plog(LLV_ERROR, LOCATION, NULL,
2154 "such policy already exists. "
2155 "anyway replace it: %s\n",
2156 spidx2str(&spidx));
2157 remsp(sp);
2158 delsp(sp);
2159 }
2160
2161 if (addnewsp(mhp) < 0)
2162 return -1;
2163
2164 return 0;
2165}
2166
2167static int
2168pk_recvspdflush(mhp)
2169 caddr_t *mhp;
2170{
2171 /* sanity check */
2172 if (mhp[0] == NULL) {
2173 plog(LLV_ERROR, LOCATION, NULL,
2174 "inappropriate sadb spdflush message passed.\n");
2175 return -1;
2176 }
2177
2178 flushsp();
2179
2180 return 0;
2181}
2182
2183/*
2184 * send error against acquire message to kenrel.
2185 */
2186int
2187pk_sendeacquire(iph2)
2188 struct ph2handle *iph2;
2189{
2190 struct sadb_msg *newmsg;
2191 int len;
2192
2193 len = sizeof(struct sadb_msg);
2194 newmsg = racoon_calloc(1, len);
2195 if (newmsg == NULL) {
2196 plog(LLV_ERROR, LOCATION, NULL,
2197 "failed to get buffer to send acquire.\n");
2198 return -1;
2199 }
2200
2201 memset(newmsg, 0, len);
2202 newmsg->sadb_msg_version = PF_KEY_V2;
2203 newmsg->sadb_msg_type = SADB_ACQUIRE;
2204 newmsg->sadb_msg_errno = ENOENT; /* XXX */
2205 newmsg->sadb_msg_satype = iph2->satype;
2206 newmsg->sadb_msg_len = PFKEY_UNIT64(len);
2207 newmsg->sadb_msg_reserved = 0;
2208 newmsg->sadb_msg_seq = iph2->seq;
2209 newmsg->sadb_msg_pid = (u_int32_t)getpid();
2210
2211 /* send message */
2212 len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
2213
2214 racoon_free(newmsg);
2215
2216 return 0;
2217}
2218
2219/*
2220 * check if the algorithm is supported or not.
2221 * OUT 0: ok
2222 * -1: ng
2223 */
2224int
2225pk_checkalg(class, calg, keylen)
2226 int class, calg, keylen;
2227{
2228 int sup, error;
2229 u_int alg;
2230 struct sadb_alg alg0;
2231
2232 switch (algclass2doi(class)) {
2233 case IPSECDOI_PROTO_IPSEC_ESP:
2234 sup = SADB_EXT_SUPPORTED_ENCRYPT;
2235 break;
2236 case IPSECDOI_ATTR_AUTH:
2237 sup = SADB_EXT_SUPPORTED_AUTH;
2238 break;
2239 case IPSECDOI_PROTO_IPCOMP:
2240 plog(LLV_DEBUG, LOCATION, NULL,
2241 "compression algorithm can not be checked "
2242 "because sadb message doesn't support it.\n");
2243 return 0;
2244 default:
2245 plog(LLV_ERROR, LOCATION, NULL,
2246 "invalid algorithm class.\n");
2247 return -1;
2248 }
2249 alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
2250 if (alg == ~0)
2251 return -1;
2252
2253 if (keylen == 0) {
2254 if (ipsec_get_keylen(sup, alg, &alg0)) {
2255 plog(LLV_ERROR, LOCATION, NULL,
2256 "%s.\n", ipsec_strerror());
2257 return -1;
2258 }
2259 keylen = alg0.sadb_alg_minbits;
2260 }
2261
2262 error = ipsec_check_keylen(sup, alg, keylen);
2263 if (error)
2264 plog(LLV_ERROR, LOCATION, NULL,
2265 "%s.\n", ipsec_strerror());
2266
2267 return error;
2268}
2269
2270/*
2271 * differences with pfkey_recv() in libipsec/pfkey.c:
2272 * - never performs busy wait loop.
2273 * - returns NULL and set *lenp to negative on fatal failures
2274 * - returns NULL and set *lenp to non-negative on non-fatal failures
2275 * - returns non-NULL on success
2276 */
2277static struct sadb_msg *
2278pk_recv(so, lenp)
2279 int so;
2280 int *lenp;
2281{
2282 struct sadb_msg buf, *newmsg;
2283 int reallen;
2284
2285 *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK);
2286 if (*lenp < 0)
2287 return NULL; /*fatal*/
2288 else if (*lenp < sizeof(buf))
2289 return NULL;
2290
2291 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
2292 if ((newmsg = racoon_calloc(1, reallen)) == NULL)
2293 return NULL;
2294
2295 *lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
2296 if (*lenp < 0) {
2297 racoon_free(newmsg);
2298 return NULL; /*fatal*/
2299 } else if (*lenp != reallen) {
2300 racoon_free(newmsg);
2301 return NULL;
2302 }
2303
2304 *lenp = recv(so, (caddr_t)newmsg, reallen, 0);
2305 if (*lenp < 0) {
2306 racoon_free(newmsg);
2307 return NULL; /*fatal*/
2308 } else if (*lenp != reallen) {
2309 racoon_free(newmsg);
2310 return NULL;
2311 }
2312
2313 return newmsg;
2314}
2315
2316/* see handler.h */
2317u_int32_t
2318pk_getseq()
2319{
2320 return (u_int32_t)random();
2321}
2322
2323static int
2324addnewsp(mhp)
2325 caddr_t *mhp;
2326{
2327 struct secpolicy *new;
2328 struct sadb_address *saddr, *daddr;
2329 struct sadb_x_policy *xpl;
2330
2331 /* sanity check */
2332 if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
2333 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2334 || mhp[SADB_X_EXT_POLICY] == NULL) {
2335 plog(LLV_ERROR, LOCATION, NULL,
2336 "inappropriate sadb spd management message passed.\n");
2337 return -1;
2338 }
2339
2340 saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2341 daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2342 xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2343
2344 new = newsp();
2345 if (new == NULL) {
2346 plog(LLV_ERROR, LOCATION, NULL,
2347 "failed to allocate buffer\n");
2348 return -1;
2349 }
2350
2351 new->spidx.dir = xpl->sadb_x_policy_dir;
2352 new->id = xpl->sadb_x_policy_id;
2353 new->policy = xpl->sadb_x_policy_type;
2354 new->req = NULL;
2355
2356 /* check policy */
2357 switch (xpl->sadb_x_policy_type) {
2358 case IPSEC_POLICY_DISCARD:
2359 case IPSEC_POLICY_NONE:
2360 case IPSEC_POLICY_ENTRUST:
2361 case IPSEC_POLICY_BYPASS:
2362 break;
2363
2364 case IPSEC_POLICY_IPSEC:
2365 {
2366 int tlen;
2367 struct sadb_x_ipsecrequest *xisr;
2368 struct ipsecrequest **p_isr = &new->req;
2369
2370 /* validity check */
2371 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
2372 plog(LLV_ERROR, LOCATION, NULL,
2373 "invalid msg length.\n");
2374 return -1;
2375 }
2376
2377 tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
2378 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
2379
2380 while (tlen > 0) {
2381
2382 /* length check */
2383 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
2384 plog(LLV_ERROR, LOCATION, NULL,
2385 "invalid msg length.\n");
2386 return -1;
2387 }
2388
2389 /* allocate request buffer */
2390 *p_isr = newipsecreq();
2391 if (*p_isr == NULL) {
2392 plog(LLV_ERROR, LOCATION, NULL,
2393 "failed to get new ipsecreq.\n");
2394 return -1;
2395 }
2396
2397 /* set values */
2398 (*p_isr)->next = NULL;
2399
2400 switch (xisr->sadb_x_ipsecrequest_proto) {
2401 case IPPROTO_ESP:
2402 case IPPROTO_AH:
2403 case IPPROTO_IPCOMP:
2404 break;
2405 default:
2406 plog(LLV_ERROR, LOCATION, NULL,
2407 "invalid proto type: %u\n",
2408 xisr->sadb_x_ipsecrequest_proto);
2409 return -1;
2410 }
2411 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
2412
2413 switch (xisr->sadb_x_ipsecrequest_mode) {
2414 case IPSEC_MODE_TRANSPORT:
2415 case IPSEC_MODE_TUNNEL:
2416 break;
2417 case IPSEC_MODE_ANY:
2418 default:
2419 plog(LLV_ERROR, LOCATION, NULL,
2420 "invalid mode: %u\n",
2421 xisr->sadb_x_ipsecrequest_mode);
2422 return -1;
2423 }
2424 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
2425
2426 switch (xisr->sadb_x_ipsecrequest_level) {
2427 case IPSEC_LEVEL_DEFAULT:
2428 case IPSEC_LEVEL_USE:
2429 case IPSEC_LEVEL_REQUIRE:
2430 break;
2431 case IPSEC_LEVEL_UNIQUE:
2432 (*p_isr)->saidx.reqid =
2433 xisr->sadb_x_ipsecrequest_reqid;
2434 break;
2435
2436 default:
2437 plog(LLV_ERROR, LOCATION, NULL,
2438 "invalid level: %u\n",
2439 xisr->sadb_x_ipsecrequest_level);
2440 return -1;
2441 }
2442 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
2443
2444 /* set IP addresses if there */
2445 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
2446 struct sockaddr *paddr;
2447
2448 paddr = (struct sockaddr *)(xisr + 1);
2449 bcopy(paddr, &(*p_isr)->saidx.src,
2450 paddr->sa_len);
2451
2452 paddr = (struct sockaddr *)((caddr_t)paddr
2453 + paddr->sa_len);
2454 bcopy(paddr, &(*p_isr)->saidx.dst,
2455 paddr->sa_len);
2456 }
2457
2458 (*p_isr)->sp = new;
2459
2460 /* initialization for the next. */
2461 p_isr = &(*p_isr)->next;
2462 tlen -= xisr->sadb_x_ipsecrequest_len;
2463
2464 /* validity check */
2465 if (tlen < 0) {
2466 plog(LLV_ERROR, LOCATION, NULL,
2467 "becoming tlen < 0\n");
2468 }
2469
2470 xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
2471 + xisr->sadb_x_ipsecrequest_len);
2472 }
2473 }
2474 break;
2475 default:
2476 plog(LLV_ERROR, LOCATION, NULL,
2477 "invalid policy type.\n");
2478 return -1;
2479 }
2480
2481 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2482 saddr + 1,
2483 daddr + 1,
2484 saddr->sadb_address_prefixlen,
2485 daddr->sadb_address_prefixlen,
2486 saddr->sadb_address_proto,
2487 &new->spidx);
2488
2489 inssp(new);
2490
2491 return 0;
2492}
2493
2494/* proto/mode/src->dst spi */
2495const char *
2496sadbsecas2str(src, dst, proto, spi, mode)
2497 struct sockaddr *src, *dst;
2498 int proto;
2499 u_int32_t spi;
2500 int mode;
2501{
2502 static char buf[256];
2503 u_int doi_proto, doi_mode = 0;
2504 char *p;
2505 int blen, i;
2506
2507 doi_proto = pfkey2ipsecdoi_proto(proto);
2508 if (doi_proto == ~0)
2509 return NULL;
2510 if (mode) {
2511 doi_mode = pfkey2ipsecdoi_mode(mode);
2512 if (doi_mode == ~0)
2513 return NULL;
2514 }
2515
2516 blen = sizeof(buf) - 1;
2517 p = buf;
2518
2519 i = snprintf(p, blen, "%s%s%s ",
2520 s_ipsecdoi_proto(doi_proto),
2521 mode ? "/" : "",
2522 mode ? s_ipsecdoi_encmode(doi_mode) : "");
2523 if (i < 0 || i >= blen)
2524 return NULL;
2525 p += i;
2526 blen -= i;
2527
2528 i = snprintf(p, blen, "%s->", saddrwop2str(src));
2529 if (i < 0 || i >= blen)
2530 return NULL;
2531 p += i;
2532 blen -= i;
2533
2534 i = snprintf(p, blen, "%s ", saddrwop2str(dst));
2535 if (i < 0 || i >= blen)
2536 return NULL;
2537 p += i;
2538 blen -= i;
2539
2540 if (spi) {
2541 snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
2542 (unsigned long)ntohl(spi));
2543 }
2544
2545 return buf;
2546}