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