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