source: rtems-libbsd/ipsec-tools/src/racoon/pfkey.c @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

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