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

55-freebsd-126-freebsd-12
Last change on this file since 8645c9d7 was 8645c9d7, checked in by Christian Mauderer <christian.mauderer@…>, on 06/06/18 at 09:11:52

ipsec-tools: Apply patches from FreeBSD ports.

Source: https://svnweb.freebsd.org/ports/head/security/ipsec-tools/files/ revision 468617.

  • Property mode set to 100644
File size: 99.7 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                        /* if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) */
1194                                sa_args.l_natt_oai = iph2->natoa_dst;
1195                        /* if (iph2->ph1->natt_flags & NAT_DETECTED_ME) */
1196                                sa_args.l_natt_oar = iph2->natoa_src;
1197#ifdef SADB_X_EXT_NAT_T_FRAG
1198                        sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1199#endif
1200                }
1201#endif
1202
1203                /* more info to fill in */
1204                sa_args.spi = pr->spi;
1205                sa_args.reqid = pr->reqid_in;
1206                sa_args.keymat = pr->keymat->v;
1207
1208                plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n");
1209                if (pfkey_send_update2(&sa_args) < 0) {
1210                        plog(LLV_ERROR, LOCATION, NULL,
1211                                "libipsec failed send update (%s)\n",
1212                                ipsec_strerror());
1213                        racoon_free(sa_args.src);
1214                        racoon_free(sa_args.dst);
1215                        return -1;
1216                }
1217
1218                if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1219                        continue;
1220
1221                /*
1222                 * It maybe good idea to call backupsa_to_file() after
1223                 * racoon will receive the sadb_update messages.
1224                 * But it is impossible because there is not key in the
1225                 * information from the kernel.
1226                 */
1227
1228                /* change some things before backing up */
1229                sa_args.wsize = 4;
1230                sa_args.l_bytes = iph2->approval->lifebyte * 1024;
1231
1232                if (backupsa_to_file(&sa_args) < 0) {
1233                        plog(LLV_ERROR, LOCATION, NULL,
1234                                "backuped SA failed: %s\n",
1235                                sadbsecas2str(sa_args.src, sa_args.dst,
1236                                sa_args.satype, sa_args.spi, sa_args.mode));
1237                }
1238                plog(LLV_DEBUG, LOCATION, NULL,
1239                        "backuped SA: %s\n",
1240                        sadbsecas2str(sa_args.src, sa_args.dst,
1241                        sa_args.satype, sa_args.spi, sa_args.mode));
1242        }
1243
1244        racoon_free(sa_args.src);
1245        racoon_free(sa_args.dst);
1246        return 0;
1247}
1248
1249static int
1250pk_recvupdate(mhp)
1251        caddr_t *mhp;
1252{
1253        struct sadb_msg *msg;
1254        struct sadb_sa *sa;
1255        struct sockaddr *src, *dst;
1256        struct ph2handle *iph2;
1257        u_int proto_id, encmode, sa_mode;
1258        int incomplete = 0;
1259        struct saproto *pr;
1260
1261        /* ignore this message because of local test mode. */
1262        if (f_local)
1263                return 0;
1264
1265        /* sanity check */
1266        if (mhp[0] == NULL
1267         || mhp[SADB_EXT_SA] == NULL
1268         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1269         || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1270                plog(LLV_ERROR, LOCATION, NULL,
1271                        "inappropriate sadb update message passed.\n");
1272                return -1;
1273        }
1274        msg = (struct sadb_msg *)mhp[0];
1275        pk_fixup_sa_addresses(mhp);
1276        src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1277        dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1278        sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1279
1280        sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1281                ? IPSEC_MODE_ANY
1282                : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1283
1284        /* the message has to be processed or not ? */
1285        if (msg->sadb_msg_pid != getpid()) {
1286                plog(LLV_DEBUG, LOCATION, NULL,
1287                        "%s message is not interesting "
1288                        "because pid %d is not mine.\n",
1289                        s_pfkey_type(msg->sadb_msg_type),
1290                        msg->sadb_msg_pid);
1291                return -1;
1292        }
1293
1294        iph2 = getph2byseq(msg->sadb_msg_seq);
1295        if (iph2 == NULL) {
1296                plog(LLV_DEBUG, LOCATION, NULL,
1297                        "seq %d of %s message not interesting.\n",
1298                        msg->sadb_msg_seq,
1299                        s_pfkey_type(msg->sadb_msg_type));
1300                return -1;
1301        }
1302
1303        if (iph2->status != PHASE2ST_ADDSA) {
1304                plog(LLV_ERROR, LOCATION, NULL,
1305                        "status mismatch (db:%d msg:%d)\n",
1306                        iph2->status, PHASE2ST_ADDSA);
1307                return -1;
1308        }
1309
1310        /* check to complete all keys ? */
1311        for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1312                proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1313                if (proto_id == ~0) {
1314                        plog(LLV_ERROR, LOCATION, NULL,
1315                                "invalid proto_id %d\n", msg->sadb_msg_satype);
1316                        return -1;
1317                }
1318                encmode = pfkey2ipsecdoi_mode(sa_mode);
1319                if (encmode == ~0) {
1320                        plog(LLV_ERROR, LOCATION, NULL,
1321                                "invalid encmode %d\n", sa_mode);
1322                        return -1;
1323                }
1324
1325                if (pr->proto_id == proto_id
1326                 && pr->spi == sa->sadb_sa_spi) {
1327                        pr->ok = 1;
1328                        plog(LLV_DEBUG, LOCATION, NULL,
1329                                "pfkey UPDATE succeeded: %s\n",
1330                                sadbsecas2str(dst, src,
1331                                    msg->sadb_msg_satype,
1332                                    sa->sadb_sa_spi,
1333                                    sa_mode));
1334
1335                        plog(LLV_INFO, LOCATION, NULL,
1336                                "IPsec-SA established: %s\n",
1337                                sadbsecas2str(dst, src,
1338                                        msg->sadb_msg_satype, sa->sadb_sa_spi,
1339                                        sa_mode));
1340                }
1341
1342                if (pr->ok == 0)
1343                        incomplete = 1;
1344        }
1345
1346        if (incomplete)
1347                return 0;
1348
1349        /* turn off the timer for calling pfkey_timeover() */
1350        sched_cancel(&iph2->sce);
1351
1352        /* update status */
1353        iph2->status = PHASE2ST_ESTABLISHED;
1354        evt_phase2(iph2, EVT_PHASE2_UP, NULL);
1355
1356#ifdef ENABLE_STATS
1357        gettimeofday(&iph2->end, NULL);
1358        syslog(LOG_NOTICE, "%s(%s): %8.6f",
1359                "phase2", "quick", timedelta(&iph2->start, &iph2->end));
1360#endif
1361
1362        /* turn off schedule */
1363        sched_cancel(&iph2->scr);
1364
1365        /*
1366         * since we are going to reuse the phase2 handler, we need to
1367         * remain it and refresh all the references between ph1 and ph2 to use.
1368         */
1369        sched_schedule(&iph2->sce, iph2->approval->lifetime,
1370                       isakmp_ph2expire_stub);
1371
1372        plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1373        return 0;
1374}
1375
1376/*
1377 * set outbound SA
1378 */
1379int
1380pk_sendadd(iph2)
1381        struct ph2handle *iph2;
1382{
1383        struct saproto *pr;
1384        struct pfkey_send_sa_args sa_args;
1385
1386        /* sanity check */
1387        if (iph2->approval == NULL) {
1388                plog(LLV_ERROR, LOCATION, NULL,
1389                        "no approvaled SAs found.\n");
1390                return -1;
1391        }
1392
1393        /* fill in some needed for pfkey_send_update2 */
1394        memset (&sa_args, 0, sizeof (sa_args));
1395        sa_args.so = lcconf->sock_pfkey;
1396        if (iph2->lifetime_secs)
1397                sa_args.l_addtime = iph2->lifetime_secs;
1398        else
1399                sa_args.l_addtime = iph2->approval->lifetime;
1400        sa_args.seq = iph2->seq;
1401        sa_args.wsize = 4;
1402
1403        if (iph2->sa_src && iph2->sa_dst) {
1404                /* MIPv6: Use SA addresses, not IKE ones */
1405                sa_args.src = dupsaddr(iph2->sa_src);
1406                sa_args.dst = dupsaddr(iph2->sa_dst);
1407        } else {
1408                /* Common case: SA addresses and IKE ones are the same */
1409                sa_args.src = dupsaddr(iph2->src);
1410                sa_args.dst = dupsaddr(iph2->dst);
1411        }
1412
1413        if (sa_args.src == NULL || sa_args.dst == NULL) {
1414                racoon_free(sa_args.src);
1415                racoon_free(sa_args.dst);
1416                return -1;
1417        }
1418
1419        for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1420                /* validity check */
1421                sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1422                if (sa_args.satype == ~0) {
1423                        plog(LLV_ERROR, LOCATION, NULL,
1424                                "invalid proto_id %d\n", pr->proto_id);
1425                        racoon_free(sa_args.src);
1426                        racoon_free(sa_args.dst);
1427                        return -1;
1428                }
1429                else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1430                        /* no replay window for IPCOMP */
1431                        sa_args.wsize = 0;
1432                }
1433#ifdef ENABLE_SAMODE_UNSPECIFIED
1434                sa_args.mode = IPSEC_MODE_ANY;
1435#else
1436                sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1437                if (sa_args.mode == ~0) {
1438                        plog(LLV_ERROR, LOCATION, NULL,
1439                                "invalid encmode %d\n", pr->encmode);
1440                        racoon_free(sa_args.src);
1441                        racoon_free(sa_args.dst);
1442                        return -1;
1443                }
1444#endif
1445
1446                /* set algorithm type and key length */
1447                sa_args.e_keylen = pr->head->encklen;
1448                if (pfkey_convertfromipsecdoi(
1449                                pr->proto_id,
1450                                pr->head->trns_id,
1451                                pr->head->authtype,
1452                                &sa_args.e_type, &sa_args.e_keylen,
1453                                &sa_args.a_type, &sa_args.a_keylen,
1454                                &sa_args.flags) < 0){
1455                        racoon_free(sa_args.src);
1456                        racoon_free(sa_args.dst);
1457                        return -1;
1458                }
1459
1460#if 0
1461                sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1462#else
1463                sa_args.l_bytes = 0;
1464#endif
1465
1466#ifdef HAVE_SECCTX
1467                if (*iph2->approval->sctx.ctx_str) {
1468                        sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1469                        sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1470                        sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1471                        sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1472                }
1473#endif /* HAVE_SECCTX */
1474
1475#ifdef ENABLE_NATT
1476                plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
1477                    "(NAT flavor)\n");
1478
1479                if (pr->udp_encap) {
1480                        sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
1481                        sa_args.l_natt_sport = extract_port(iph2->ph1->local);
1482                        sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
1483#ifdef SADB_X_EXT_NAT_T_FRAG
1484                        sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1485#endif
1486                }
1487#endif
1488                /* more info to fill in */
1489                sa_args.spi = pr->spi_p;
1490                sa_args.reqid = pr->reqid_out;
1491                sa_args.keymat = pr->keymat_p->v;
1492
1493                plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
1494                if (pfkey_send_add2(&sa_args) < 0) {
1495                        plog(LLV_ERROR, LOCATION, NULL,
1496                                "libipsec failed send add (%s)\n",
1497                                ipsec_strerror());
1498                        racoon_free(sa_args.src);
1499                        racoon_free(sa_args.dst);
1500                        return -1;
1501                }
1502
1503                if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1504                        continue;
1505
1506                /*
1507                 * It maybe good idea to call backupsa_to_file() after
1508                 * racoon will receive the sadb_update messages.
1509                 * But it is impossible because there is not key in the
1510                 * information from the kernel.
1511                 */
1512                if (backupsa_to_file(&sa_args) < 0) {
1513                        plog(LLV_ERROR, LOCATION, NULL,
1514                                "backuped SA failed: %s\n",
1515                                sadbsecas2str(sa_args.src, sa_args.dst,
1516                                sa_args.satype, sa_args.spi, sa_args.mode));
1517                }
1518                plog(LLV_DEBUG, LOCATION, NULL,
1519                        "backuped SA: %s\n",
1520                        sadbsecas2str(sa_args.src, sa_args.dst,
1521                        sa_args.satype, sa_args.spi, sa_args.mode));
1522        }
1523        racoon_free(sa_args.src);
1524        racoon_free(sa_args.dst);
1525        return 0;
1526}
1527
1528static int
1529pk_recvadd(mhp)
1530        caddr_t *mhp;
1531{
1532        struct sadb_msg *msg;
1533        struct sadb_sa *sa;
1534        struct sockaddr *src, *dst;
1535        struct ph2handle *iph2;
1536        u_int sa_mode;
1537
1538        /* ignore this message because of local test mode. */
1539        if (f_local)
1540                return 0;
1541
1542        /* sanity check */
1543        if (mhp[0] == NULL
1544         || mhp[SADB_EXT_SA] == NULL
1545         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1546         || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1547                plog(LLV_ERROR, LOCATION, NULL,
1548                        "inappropriate sadb add message passed.\n");
1549                return -1;
1550        }
1551        msg = (struct sadb_msg *)mhp[0];
1552        pk_fixup_sa_addresses(mhp);
1553        src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1554        dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1555        sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1556
1557        sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1558                ? IPSEC_MODE_ANY
1559                : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1560
1561        /* the message has to be processed or not ? */
1562        if (msg->sadb_msg_pid != getpid()) {
1563                plog(LLV_DEBUG, LOCATION, NULL,
1564                        "%s message is not interesting "
1565                        "because pid %d is not mine.\n",
1566                        s_pfkey_type(msg->sadb_msg_type),
1567                        msg->sadb_msg_pid);
1568                return -1;
1569        }
1570
1571        iph2 = getph2byseq(msg->sadb_msg_seq);
1572        if (iph2 == NULL) {
1573                plog(LLV_DEBUG, LOCATION, NULL,
1574                        "seq %d of %s message not interesting.\n",
1575                        msg->sadb_msg_seq,
1576                        s_pfkey_type(msg->sadb_msg_type));
1577                return -1;
1578        }
1579
1580        /*
1581         * NOTE don't update any status of phase2 handle
1582         * because they must be updated by SADB_UPDATE message
1583         */
1584
1585        plog(LLV_INFO, LOCATION, NULL,
1586                "IPsec-SA established: %s\n",
1587                sadbsecas2str(src, dst,
1588                        msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1589
1590        plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1591        return 0;
1592}
1593
1594static int
1595pk_recvexpire(mhp)
1596        caddr_t *mhp;
1597{
1598        struct sadb_msg *msg;
1599        struct sadb_sa *sa;
1600        struct sockaddr *src, *dst;
1601        struct ph2handle *iph2;
1602        u_int proto_id, sa_mode;
1603
1604        /* sanity check */
1605        if (mhp[0] == NULL
1606         || mhp[SADB_EXT_SA] == NULL
1607         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1608         || mhp[SADB_EXT_ADDRESS_DST] == NULL
1609         || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1610          && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1611                plog(LLV_ERROR, LOCATION, NULL,
1612                        "inappropriate sadb expire message passed.\n");
1613                return -1;
1614        }
1615        msg = (struct sadb_msg *)mhp[0];
1616        sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1617        pk_fixup_sa_addresses(mhp);
1618        src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1619        dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1620
1621        sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1622                ? IPSEC_MODE_ANY
1623                : ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1624
1625        proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1626        if (proto_id == ~0) {
1627                plog(LLV_ERROR, LOCATION, NULL,
1628                        "invalid proto_id %d\n", msg->sadb_msg_satype);
1629                return -1;
1630        }
1631
1632        plog(LLV_INFO, LOCATION, NULL,
1633                "IPsec-SA expired: %s\n",
1634                sadbsecas2str(src, dst,
1635                        msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1636
1637        iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1638        if (iph2 == NULL) {
1639                /*
1640                 * Ignore it because two expire messages are come up.
1641                 * phase2 handler has been deleted already when 2nd message
1642                 * is received.
1643                 */
1644                plog(LLV_DEBUG, LOCATION, NULL,
1645                        "no such a SA found: %s\n",
1646                        sadbsecas2str(src, dst,
1647                            msg->sadb_msg_satype, sa->sadb_sa_spi,
1648                            sa_mode));
1649                return 0;
1650        }
1651
1652        /* resent expiry message? */
1653        if (iph2->status > PHASE2ST_ESTABLISHED)
1654                return 0;
1655
1656        /* still negotiating? */
1657        if (iph2->status < PHASE2ST_ESTABLISHED) {
1658                /* not a hard timeout? */
1659                if (mhp[SADB_EXT_LIFETIME_HARD] == NULL)
1660                        return 0;
1661
1662                /*
1663                 * We were negotiating for that SA (w/o much success
1664                 * from current status) and kernel has decided our time
1665                 * is over trying (xfrm_larval_drop controls that and
1666                 * is enabled by default on Linux >= 2.6.28 kernels).
1667                 */
1668                plog(LLV_WARNING, LOCATION, NULL,
1669                     "PF_KEY EXPIRE message received from kernel for SA"
1670                     " being negotiated. Stopping negotiation.\n");
1671        }
1672
1673        /* turn off the timer for calling isakmp_ph2expire() */
1674        sched_cancel(&iph2->sce);
1675
1676        if (iph2->status == PHASE2ST_ESTABLISHED &&
1677            iph2->side == INITIATOR) {
1678                struct ph1handle *iph1hint;
1679                /*
1680                 * Active phase 2 expired and we were initiator.
1681                 * Begin new phase 2 exchange, so we can keep on sending
1682                 * traffic.
1683                 */
1684
1685                /* update status for re-use */
1686                iph1hint = iph2->ph1;
1687                initph2(iph2);
1688                iph2->status = PHASE2ST_STATUS2;
1689
1690                /* start quick exchange */
1691                if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
1692                        plog(LLV_ERROR, LOCATION, iph2->dst,
1693                                "failed to begin ipsec sa "
1694                                "re-negotication.\n");
1695                        remph2(iph2);
1696                        delph2(iph2);
1697                        return -1;
1698                }
1699
1700                return 0;
1701        }
1702
1703        /*
1704         * We are responder or the phase 2 was not established.
1705         * Just remove the ph2handle to reflect SADB.
1706         */
1707        iph2->status = PHASE2ST_EXPIRED;
1708        remph2(iph2);
1709        delph2(iph2);
1710
1711        return 0;
1712}
1713
1714static int
1715pk_recvacquire(mhp)
1716        caddr_t *mhp;
1717{
1718        struct sadb_msg *msg;
1719        struct sadb_x_policy *xpl;
1720        struct secpolicy *sp_out = NULL, *sp_in = NULL;
1721        struct ph2handle *iph2;
1722        struct sockaddr *src, *dst;     /* IKE addresses (for exchanges) */
1723        struct sockaddr *sp_src, *sp_dst;   /* SP addresses (selectors). */
1724        struct sockaddr *sa_src = NULL, *sa_dst = NULL ; /* SA addresses */
1725#ifdef HAVE_SECCTX
1726        struct sadb_x_sec_ctx *m_sec_ctx;
1727#endif /* HAVE_SECCTX */
1728        struct policyindex spidx;
1729
1730        /* ignore this message because of local test mode. */
1731        if (f_local)
1732                return 0;
1733
1734        /* sanity check */
1735        if (mhp[0] == NULL
1736         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1737         || mhp[SADB_EXT_ADDRESS_DST] == NULL
1738         || mhp[SADB_X_EXT_POLICY] == NULL) {
1739                plog(LLV_ERROR, LOCATION, NULL,
1740                        "inappropriate sadb acquire message passed.\n");
1741                return -1;
1742        }
1743        msg = (struct sadb_msg *)mhp[0];
1744        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1745        /* acquire does not have nat-t ports; so do not bother setting
1746         * the default port 500; just use the port zero for wildcard
1747         * matching the get a valid natted destination */
1748        sp_src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1749        sp_dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1750
1751#ifdef HAVE_SECCTX
1752        m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
1753
1754        if (m_sec_ctx != NULL) {
1755                plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
1756                     m_sec_ctx->sadb_x_ctx_doi);
1757                plog(LLV_INFO, LOCATION, NULL,
1758                     "security context algorithm: %u\n",
1759                     m_sec_ctx->sadb_x_ctx_alg);
1760                plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
1761                     m_sec_ctx->sadb_x_ctx_len);
1762                plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
1763                     ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
1764        }
1765#endif /* HAVE_SECCTX */
1766
1767        /* ignore if type is not IPSEC_POLICY_IPSEC */
1768        if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1769                plog(LLV_DEBUG, LOCATION, NULL,
1770                        "ignore ACQUIRE message. type is not IPsec.\n");
1771                return 0;
1772        }
1773
1774        /* ignore it if src or dst are multicast addresses. */
1775        if ((sp_dst->sa_family == AF_INET
1776          && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_dst)->sin_addr.s_addr)))
1777#ifdef INET6
1778         || (sp_dst->sa_family == AF_INET6
1779          && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_dst)->sin6_addr))
1780#endif
1781        ) {
1782                plog(LLV_DEBUG, LOCATION, NULL,
1783                        "ignore due to multicast destination address: %s.\n",
1784                        saddrwop2str(sp_dst));
1785                return 0;
1786        }
1787
1788        if ((sp_src->sa_family == AF_INET
1789          && IN_MULTICAST(ntohl(((struct sockaddr_in *)sp_src)->sin_addr.s_addr)))
1790#ifdef INET6
1791         || (sp_src->sa_family == AF_INET6
1792          && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sp_src)->sin6_addr))
1793#endif
1794        ) {
1795                plog(LLV_DEBUG, LOCATION, NULL,
1796                        "ignore due to multicast source address: %s.\n",
1797                        saddrwop2str(sp_src));
1798                return 0;
1799        }
1800
1801        /* search for proper policyindex */
1802        sp_out = getspbyspid(xpl->sadb_x_policy_id);
1803        if (sp_out == NULL) {
1804                plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1805                        xpl->sadb_x_policy_id);
1806                return -1;
1807        }
1808        plog(LLV_DEBUG, LOCATION, NULL,
1809                "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1810
1811        /* Before going further, let first get the source and destination
1812         * address that would be used for IKE negotiation. The logic is:
1813         * - if SP from SPD image contains local and remote hints, we
1814         *   use them (provided by MIGRATE).
1815         * - otherwise, we use the ones from the ipsecrequest, which means:
1816         *   - the addresses from the request for transport mode
1817         *   - the endpoints addresses for tunnel mode
1818         *
1819         * Note that:
1820         * 1) racoon does not support negotiation of bundles which
1821         *    simplifies the lookup for the addresses in the ipsecrequest
1822         *    list, as we expect only one.
1823         * 2) We do source and destination parts all together and do not
1824         *    accept semi-defined information. This is just a decision,
1825         *    there might be needs.
1826         *
1827         * --arno
1828         */
1829        if (sp_out->req && sp_out->req->saidx.mode == IPSEC_MODE_TUNNEL) {
1830                /* For Tunnel mode, SA addresses are the endpoints */
1831                src = (struct sockaddr *) &sp_out->req->saidx.src;
1832                dst = (struct sockaddr *) &sp_out->req->saidx.dst;
1833        } else {
1834                /* Otherwise use requested addresses.
1835                 *
1836                 * We need to explicitly setup sa_src and sa_dst too,
1837                 * since the SA ports are different from IKE port. And
1838                 * src/dst ports will be overwritten when the matching
1839                 * phase1 is found. */
1840                src = sa_src = sp_src;
1841                dst = sa_dst = sp_dst;
1842        }
1843        if (sp_out->local && sp_out->remote) {
1844                /* hints available, let's use them */
1845                sa_src = src;
1846                sa_dst = dst;
1847                src = (struct sockaddr *) sp_out->local;
1848                dst = (struct sockaddr *) sp_out->remote;
1849        }
1850
1851        /*
1852         * If there is a phase 2 handler against the policy identifier in
1853         * the acquire message, and if
1854         *    1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1855         *       should ignore such a acquire message because the phase 2
1856         *       is just negotiating.
1857         *    2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1858         *       has to prcesss such a acquire message because racoon may
1859         *       lost the expire message.
1860         */
1861        iph2 = getph2byid(src, dst, xpl->sadb_x_policy_id);
1862        if (iph2 != NULL) {
1863                if (iph2->status < PHASE2ST_ESTABLISHED) {
1864                        plog(LLV_DEBUG, LOCATION, NULL,
1865                                "ignore the acquire because ph2 found\n");
1866                        return -1;
1867                }
1868                if (iph2->status == PHASE2ST_EXPIRED)
1869                        iph2 = NULL;
1870                /*FALLTHROUGH*/
1871        }
1872
1873        /* Check we are listening on source address. If not, ignore. */
1874        if (myaddr_getsport(src) == -1) {
1875                plog(LLV_DEBUG, LOCATION, NULL,
1876                     "Not listening on source address %s. Ignoring ACQUIRE.\n",
1877                     saddrwop2str(src));
1878                return 0;
1879        }
1880
1881        /* get inbound policy */
1882    {
1883
1884        memset(&spidx, 0, sizeof(spidx));
1885        spidx.dir = IPSEC_DIR_INBOUND;
1886        memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1887        memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1888        spidx.prefs = sp_out->spidx.prefd;
1889        spidx.prefd = sp_out->spidx.prefs;
1890        spidx.ul_proto = sp_out->spidx.ul_proto;
1891
1892#ifdef HAVE_SECCTX
1893        if (m_sec_ctx) {
1894                spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
1895                spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
1896                spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
1897                memcpy(spidx.sec_ctx.ctx_str,
1898                      ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
1899                      spidx.sec_ctx.ctx_strlen);
1900        }
1901#endif /* HAVE_SECCTX */
1902
1903        sp_in = getsp(&spidx);
1904        if (sp_in) {
1905                plog(LLV_DEBUG, LOCATION, NULL,
1906                        "suitable inbound SP found: %s.\n",
1907                        spidx2str(&sp_in->spidx));
1908        } else {
1909                plog(LLV_NOTIFY, LOCATION, NULL,
1910                        "no in-bound policy found: %s\n",
1911                        spidx2str(&spidx));
1912        }
1913    }
1914
1915        /* allocate a phase 2 */
1916        iph2 = newph2();
1917        if (iph2 == NULL) {
1918                plog(LLV_ERROR, LOCATION, NULL,
1919                        "failed to allocate phase2 entry.\n");
1920                return -1;
1921        }
1922        iph2->side = INITIATOR;
1923        iph2->spid = xpl->sadb_x_policy_id;
1924        iph2->satype = msg->sadb_msg_satype;
1925        iph2->seq = msg->sadb_msg_seq;
1926        iph2->status = PHASE2ST_STATUS2;
1927
1928        /* set address used by IKE for the negotiation (might differ from
1929         * SA address, i.e. might not be tunnel endpoints or addresses
1930         * of transport mode SA) */
1931        iph2->dst = dupsaddr(dst);
1932        if (iph2->dst == NULL) {
1933                delph2(iph2);
1934                return -1;
1935        }
1936        iph2->src = dupsaddr(src);
1937        if (iph2->src == NULL) {
1938                delph2(iph2);
1939                return -1;
1940        }
1941
1942        /* If sa_src and sa_dst have been set, this mean we have to
1943         * set iph2->sa_src and iph2->sa_dst to provide the addresses
1944         * of the SA because iph2->src and iph2->dst are only the ones
1945         * used for the IKE exchanges. Those that need these addresses
1946         * are for instance pk_sendupdate() or pk_sendgetspi() */
1947        if (sa_src) {
1948                iph2->sa_src = dupsaddr(sa_src);
1949                iph2->sa_dst = dupsaddr(sa_dst);
1950        }
1951
1952        if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
1953                delph2(iph2);
1954                return -1;
1955        }
1956
1957#ifdef HAVE_SECCTX
1958        if (m_sec_ctx) {
1959                set_secctx_in_proposal(iph2, spidx);
1960        }
1961#endif /* HAVE_SECCTX */
1962
1963        insph2(iph2);
1964
1965        /* start isakmp initiation by using ident exchange */
1966        /* XXX should be looped if there are multiple phase 2 handler. */
1967        if (isakmp_post_acquire(iph2, NULL, TRUE) < 0) {
1968                plog(LLV_ERROR, LOCATION, NULL,
1969                        "failed to begin ipsec sa negotication.\n");
1970                remph2(iph2);
1971                delph2(iph2);
1972                return -1;
1973        }
1974
1975        return 0;
1976}
1977
1978static int
1979pk_recvdelete(mhp)
1980        caddr_t *mhp;
1981{
1982        struct sadb_msg *msg;
1983        struct sadb_sa *sa;
1984        struct sockaddr *src, *dst;
1985        struct ph2handle *iph2 = NULL;
1986        u_int proto_id;
1987
1988        /* ignore this message because of local test mode. */
1989        if (f_local)
1990                return 0;
1991
1992        /* sanity check */
1993        if (mhp[0] == NULL
1994         || mhp[SADB_EXT_SA] == NULL
1995         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1996         || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1997                plog(LLV_ERROR, LOCATION, NULL,
1998                        "inappropriate sadb delete message passed.\n");
1999                return -1;
2000        }
2001        msg = (struct sadb_msg *)mhp[0];
2002        sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
2003        pk_fixup_sa_addresses(mhp);
2004        src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
2005        dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
2006
2007        /* the message has to be processed or not ? */
2008        if (msg->sadb_msg_pid == getpid()) {
2009                plog(LLV_DEBUG, LOCATION, NULL,
2010                        "%s message is not interesting "
2011                        "because the message was originated by me.\n",
2012                        s_pfkey_type(msg->sadb_msg_type));
2013                return -1;
2014        }
2015
2016        proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
2017        if (proto_id == ~0) {
2018                plog(LLV_ERROR, LOCATION, NULL,
2019                        "invalid proto_id %d\n", msg->sadb_msg_satype);
2020                return -1;
2021        }
2022
2023        iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
2024        if (iph2 == NULL) {
2025                /* ignore */
2026                plog(LLV_ERROR, LOCATION, NULL,
2027                        "no iph2 found: %s\n",
2028                        sadbsecas2str(src, dst, msg->sadb_msg_satype,
2029                                sa->sadb_sa_spi, IPSEC_MODE_ANY));
2030                return 0;
2031        }
2032
2033        plog(LLV_ERROR, LOCATION, NULL,
2034                "pfkey DELETE received: %s\n",
2035                sadbsecas2str(src, dst,
2036                        msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
2037
2038        /* send delete information */
2039        if (iph2->status == PHASE2ST_ESTABLISHED)
2040                isakmp_info_send_d2(iph2);
2041
2042        remph2(iph2);
2043        delph2(iph2);
2044
2045        return 0;
2046}
2047
2048static int
2049pk_recvflush(mhp)
2050        caddr_t *mhp;
2051{
2052        /* ignore this message because of local test mode. */
2053        if (f_local)
2054                return 0;
2055
2056        /* sanity check */
2057        if (mhp[0] == NULL) {
2058                plog(LLV_ERROR, LOCATION, NULL,
2059                        "inappropriate sadb flush message passed.\n");
2060                return -1;
2061        }
2062
2063        flushph2();
2064
2065        return 0;
2066}
2067
2068static int
2069getsadbpolicy(policy0, policylen0, type, iph2)
2070        caddr_t *policy0;
2071        int *policylen0, type;
2072        struct ph2handle *iph2;
2073{
2074        struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2075        struct sockaddr *src = NULL, *dst = NULL;
2076        struct sadb_x_policy *xpl;
2077        struct sadb_x_ipsecrequest *xisr;
2078        struct saproto *pr;
2079        struct saproto **pr_rlist;
2080        int rlist_len = 0;
2081        caddr_t policy, p;
2082        int policylen;
2083        int xisrlen;
2084        u_int satype, mode;
2085        int len = 0;
2086#ifdef HAVE_SECCTX
2087        int ctxlen = 0;
2088#endif /* HAVE_SECCTX */
2089
2090
2091        /* get policy buffer size */
2092        policylen = sizeof(struct sadb_x_policy);
2093        if (type != SADB_X_SPDDELETE) {
2094                if (iph2->sa_src && iph2->sa_dst) {
2095                        src = iph2->sa_src; /* MIPv6: Use SA addresses, */
2096                        dst = iph2->sa_dst; /* not IKE ones             */
2097                } else {
2098                        src = iph2->src; /* Common case: SA addresses */
2099                        dst = iph2->dst; /* and IKE ones are the same */
2100                }
2101
2102                for (pr = iph2->approval->head; pr; pr = pr->next) {
2103                        xisrlen = sizeof(*xisr);
2104                        if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2105                                xisrlen += (sysdep_sa_len(src) +
2106                                            sysdep_sa_len(dst));
2107                        }
2108
2109                        policylen += PFKEY_ALIGN8(xisrlen);
2110                }
2111        }
2112
2113#ifdef HAVE_SECCTX
2114        if (*spidx->sec_ctx.ctx_str) {
2115                ctxlen = sizeof(struct sadb_x_sec_ctx)
2116                                + PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
2117                policylen += ctxlen;
2118        }
2119#endif /* HAVE_SECCTX */
2120
2121        /* make policy structure */
2122        policy = racoon_malloc(policylen);
2123        memset((void*)policy, 0xcd, policylen);
2124        if (!policy) {
2125                plog(LLV_ERROR, LOCATION, NULL,
2126                        "buffer allocation failed.\n");
2127                return -1;
2128        }
2129
2130        xpl = (struct sadb_x_policy *)policy;
2131        xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2132        xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2133        xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2134        xpl->sadb_x_policy_dir = spidx->dir;
2135        xpl->sadb_x_policy_id = 0;
2136#ifdef HAVE_PFKEY_POLICY_PRIORITY
2137        xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2138#endif
2139        len++;
2140
2141#ifdef HAVE_SECCTX
2142        if (*spidx->sec_ctx.ctx_str) {
2143                struct sadb_x_sec_ctx *p;
2144
2145                p = (struct sadb_x_sec_ctx *)(xpl + len);
2146                memset(p, 0, ctxlen);
2147                p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
2148                p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2149                p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
2150                p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
2151                p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
2152
2153                memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
2154                len += ctxlen;
2155        }
2156#endif /* HAVE_SECCTX */
2157
2158        /* no need to append policy information any more if type is SPDDELETE */
2159        if (type == SADB_X_SPDDELETE)
2160                goto end;
2161
2162        xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
2163
2164        /* The order of things is reversed for use in add policy messages */
2165        for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
2166        pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
2167        if (!pr_rlist) {
2168                plog(LLV_ERROR, LOCATION, NULL,
2169                        "buffer allocation failed.\n");
2170                return -1;
2171        }
2172        pr_rlist[rlist_len--] = NULL;
2173        for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
2174        rlist_len = 0;
2175
2176        for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
2177
2178                satype = doi2ipproto(pr->proto_id);
2179                if (satype == ~0) {
2180                        plog(LLV_ERROR, LOCATION, NULL,
2181                                "invalid proto_id %d\n", pr->proto_id);
2182                        goto err;
2183                }
2184                mode = ipsecdoi2pfkey_mode(pr->encmode);
2185                if (mode == ~0) {
2186                        plog(LLV_ERROR, LOCATION, NULL,
2187                                "invalid encmode %d\n", pr->encmode);
2188                        goto err;
2189                }
2190
2191                /*
2192                 * the policy level cannot be unique because the policy
2193                 * is defined later than SA, so req_id cannot be bound to SA.
2194                 */
2195                xisr->sadb_x_ipsecrequest_proto = satype;
2196                xisr->sadb_x_ipsecrequest_mode = mode;
2197                if(iph2->proposal->head->reqid_in > 0){
2198                        xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
2199                        xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
2200                }else{
2201                        xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2202                        xisr->sadb_x_ipsecrequest_reqid = 0;
2203                }
2204                p = (caddr_t)(xisr + 1);
2205
2206                xisrlen = sizeof(*xisr);
2207
2208                if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2209                        int src_len, dst_len;
2210
2211                        src_len = sysdep_sa_len(src);
2212                        dst_len = sysdep_sa_len(dst);
2213                        xisrlen += src_len + dst_len;
2214
2215                        memcpy(p, src, src_len);
2216                        p += src_len;
2217
2218                        memcpy(p, dst, dst_len);
2219                        p += dst_len;
2220                }
2221
2222                xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2223                xisr = (struct sadb_x_ipsecrequest *)p;
2224
2225        }
2226        racoon_free(pr_rlist);
2227
2228end:
2229        *policy0 = policy;
2230        *policylen0 = policylen;
2231
2232        return 0;
2233
2234err:
2235        if (policy)
2236                racoon_free(policy);
2237        if (pr_rlist) racoon_free(pr_rlist);
2238
2239        return -1;
2240}
2241
2242int
2243pk_sendspdupdate2(iph2)
2244        struct ph2handle *iph2;
2245{
2246        struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2247        caddr_t policy = NULL;
2248        int policylen = 0;
2249        u_int64_t ltime, vtime;
2250
2251        ltime = iph2->approval->lifetime;
2252        vtime = 0;
2253
2254        if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2255                plog(LLV_ERROR, LOCATION, NULL,
2256                        "getting sadb policy failed.\n");
2257                return -1;
2258        }
2259
2260        if (pfkey_send_spdupdate2(
2261                        lcconf->sock_pfkey,
2262                        (struct sockaddr *)&spidx->src,
2263                        spidx->prefs,
2264                        (struct sockaddr *)&spidx->dst,
2265                        spidx->prefd,
2266                        spidx->ul_proto,
2267                        ltime, vtime,
2268                        policy, policylen, 0) < 0) {
2269                plog(LLV_ERROR, LOCATION, NULL,
2270                        "libipsec failed send spdupdate2 (%s)\n",
2271                        ipsec_strerror());
2272                goto end;
2273        }
2274        plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
2275
2276end:
2277        if (policy)
2278                racoon_free(policy);
2279
2280        return 0;
2281}
2282
2283static int
2284pk_recvspdupdate(mhp)
2285        caddr_t *mhp;
2286{
2287        struct sadb_address *saddr, *daddr;
2288        struct sadb_x_policy *xpl;
2289        struct sadb_lifetime *lt;
2290        struct policyindex spidx;
2291        struct secpolicy *sp;
2292        struct sockaddr *local=NULL, *remote=NULL;
2293        u_int64_t created;
2294        int ret;
2295
2296        /* sanity check */
2297        if (mhp[0] == NULL
2298         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2299         || mhp[SADB_EXT_ADDRESS_DST] == NULL
2300         || mhp[SADB_X_EXT_POLICY] == NULL) {
2301                plog(LLV_ERROR, LOCATION, NULL,
2302                        "inappropriate sadb spdupdate message passed.\n");
2303                return -1;
2304        }
2305        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2306        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2307        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2308        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2309        if(lt != NULL)
2310                created = lt->sadb_lifetime_addtime;
2311        else
2312                created = 0;
2313
2314#ifdef HAVE_PFKEY_POLICY_PRIORITY
2315        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2316                        saddr + 1,
2317                        daddr + 1,
2318                        saddr->sadb_address_prefixlen,
2319                        daddr->sadb_address_prefixlen,
2320                        saddr->sadb_address_proto,
2321                        xpl->sadb_x_policy_priority,
2322                        created,
2323                        &spidx);
2324#else
2325        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2326                        saddr + 1,
2327                        daddr + 1,
2328                        saddr->sadb_address_prefixlen,
2329                        daddr->sadb_address_prefixlen,
2330                        saddr->sadb_address_proto,
2331                        created,
2332                        &spidx);
2333#endif
2334
2335#ifdef HAVE_SECCTX
2336        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2337                struct sadb_x_sec_ctx *ctx;
2338
2339                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2340                spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2341                spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2342                spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2343                memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2344        }
2345#endif /* HAVE_SECCTX */
2346
2347        sp = getsp(&spidx);
2348        if (sp == NULL) {
2349                plog(LLV_DEBUG, LOCATION, NULL,
2350                        "this policy did not exist for removal: \"%s\"\n",
2351                        spidx2str(&spidx));
2352        } else {
2353                /* preserve hints before deleting the SP */
2354                local = sp->local;
2355                remote = sp->remote;
2356                sp->local = NULL;
2357                sp->remote = NULL;
2358
2359                remsp(sp);
2360                delsp(sp);
2361        }
2362
2363        /* Add new SP (with old hints) */
2364        ret = addnewsp(mhp, local, remote);
2365
2366        if (local != NULL)
2367                racoon_free(local);
2368        if (remote != NULL)
2369                racoon_free(remote);
2370
2371        if (ret < 0)
2372                return -1;
2373
2374        return 0;
2375}
2376
2377/*
2378 * this function has to be used by responder side.
2379 */
2380int
2381pk_sendspdadd2(iph2)
2382        struct ph2handle *iph2;
2383{
2384        struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2385        caddr_t policy = NULL;
2386        int policylen = 0;
2387        u_int64_t ltime, vtime;
2388
2389        ltime = iph2->approval->lifetime;
2390        vtime = 0;
2391
2392        if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2393                plog(LLV_ERROR, LOCATION, NULL,
2394                        "getting sadb policy failed.\n");
2395                return -1;
2396        }
2397
2398        if (pfkey_send_spdadd2(
2399                        lcconf->sock_pfkey,
2400                        (struct sockaddr *)&spidx->src,
2401                        spidx->prefs,
2402                        (struct sockaddr *)&spidx->dst,
2403                        spidx->prefd,
2404                        spidx->ul_proto,
2405                        ltime, vtime,
2406                        policy, policylen, 0) < 0) {
2407                plog(LLV_ERROR, LOCATION, NULL,
2408                        "libipsec failed send spdadd2 (%s)\n",
2409                        ipsec_strerror());
2410                goto end;
2411        }
2412        plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
2413
2414end:
2415        if (policy)
2416                racoon_free(policy);
2417
2418        return 0;
2419}
2420
2421static int
2422pk_recvspdadd(mhp)
2423        caddr_t *mhp;
2424{
2425        struct sadb_address *saddr, *daddr;
2426        struct sadb_x_policy *xpl;
2427        struct sadb_lifetime *lt;
2428        struct policyindex spidx;
2429        struct secpolicy *sp;
2430        struct sockaddr *local = NULL, *remote = NULL;
2431        u_int64_t created;
2432        int ret;
2433
2434        /* sanity check */
2435        if (mhp[0] == NULL
2436         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2437         || mhp[SADB_EXT_ADDRESS_DST] == NULL
2438         || mhp[SADB_X_EXT_POLICY] == NULL) {
2439                plog(LLV_ERROR, LOCATION, NULL,
2440                        "inappropriate sadb spdadd message passed.\n");
2441                return -1;
2442        }
2443        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2444        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2445        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2446        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2447        if(lt != NULL)
2448                created = lt->sadb_lifetime_addtime;
2449        else
2450                created = 0;
2451
2452#ifdef HAVE_PFKEY_POLICY_PRIORITY
2453        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2454                        saddr + 1,
2455                        daddr + 1,
2456                        saddr->sadb_address_prefixlen,
2457                        daddr->sadb_address_prefixlen,
2458                        saddr->sadb_address_proto,
2459                        xpl->sadb_x_policy_priority,
2460                        created,
2461                        &spidx);
2462#else
2463        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2464                        saddr + 1,
2465                        daddr + 1,
2466                        saddr->sadb_address_prefixlen,
2467                        daddr->sadb_address_prefixlen,
2468                        saddr->sadb_address_proto,
2469                        created,
2470                        &spidx);
2471#endif
2472
2473#ifdef HAVE_SECCTX
2474        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2475                struct sadb_x_sec_ctx *ctx;
2476
2477                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2478                spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2479                spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2480                spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2481                memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2482        }
2483#endif /* HAVE_SECCTX */
2484
2485        sp = getsp(&spidx);
2486        if (sp != NULL) {
2487                plog(LLV_ERROR, LOCATION, NULL,
2488                        "such policy already exists. "
2489                        "anyway replace it: %s\n",
2490                        spidx2str(&spidx));
2491
2492                /* preserve hints before deleting the SP */
2493                local = sp->local;
2494                remote = sp->remote;
2495                sp->local = NULL;
2496                sp->remote = NULL;
2497
2498                remsp(sp);
2499                delsp(sp);
2500        }
2501
2502        /* Add new SP (with old hints) */
2503        ret = addnewsp(mhp, local, remote);
2504
2505        if (local != NULL)
2506                racoon_free(local);
2507        if (remote != NULL)
2508                racoon_free(remote);
2509
2510        if (ret < 0)
2511                return -1;
2512
2513        return 0;
2514}
2515
2516/*
2517 * this function has to be used by responder side.
2518 */
2519int
2520pk_sendspddelete(iph2)
2521        struct ph2handle *iph2;
2522{
2523        struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2524        caddr_t policy = NULL;
2525        int policylen;
2526
2527        if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2528                plog(LLV_ERROR, LOCATION, NULL,
2529                        "getting sadb policy failed.\n");
2530                return -1;
2531        }
2532
2533        if (pfkey_send_spddelete(
2534                        lcconf->sock_pfkey,
2535                        (struct sockaddr *)&spidx->src,
2536                        spidx->prefs,
2537                        (struct sockaddr *)&spidx->dst,
2538                        spidx->prefd,
2539                        spidx->ul_proto,
2540                        policy, policylen, 0) < 0) {
2541                plog(LLV_ERROR, LOCATION, NULL,
2542                        "libipsec failed send spddelete (%s)\n",
2543                        ipsec_strerror());
2544                goto end;
2545        }
2546        plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2547
2548end:
2549        if (policy)
2550                racoon_free(policy);
2551
2552        return 0;
2553}
2554
2555static int
2556pk_recvspddelete(mhp)
2557        caddr_t *mhp;
2558{
2559        struct sadb_address *saddr, *daddr;
2560        struct sadb_x_policy *xpl;
2561        struct sadb_lifetime *lt;
2562        struct policyindex spidx;
2563        struct secpolicy *sp;
2564        u_int64_t created;
2565
2566        /* sanity check */
2567        if (mhp[0] == NULL
2568         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2569         || mhp[SADB_EXT_ADDRESS_DST] == NULL
2570         || mhp[SADB_X_EXT_POLICY] == NULL) {
2571                plog(LLV_ERROR, LOCATION, NULL,
2572                        "inappropriate sadb spddelete message passed.\n");
2573                return -1;
2574        }
2575        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2576        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2577        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2578        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2579        if(lt != NULL)
2580                created = lt->sadb_lifetime_addtime;
2581        else
2582                created = 0;
2583
2584#ifdef HAVE_PFKEY_POLICY_PRIORITY
2585        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2586                        saddr + 1,
2587                        daddr + 1,
2588                        saddr->sadb_address_prefixlen,
2589                        daddr->sadb_address_prefixlen,
2590                        saddr->sadb_address_proto,
2591                        xpl->sadb_x_policy_priority,
2592                        created,
2593                        &spidx);
2594#else
2595        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2596                        saddr + 1,
2597                        daddr + 1,
2598                        saddr->sadb_address_prefixlen,
2599                        daddr->sadb_address_prefixlen,
2600                        saddr->sadb_address_proto,
2601                        created,
2602                        &spidx);
2603#endif
2604
2605#ifdef HAVE_SECCTX
2606        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2607                struct sadb_x_sec_ctx *ctx;
2608
2609                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2610                spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2611                spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2612                spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2613                memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2614        }
2615#endif /* HAVE_SECCTX */
2616
2617        sp = getsp(&spidx);
2618        if (sp == NULL) {
2619                plog(LLV_ERROR, LOCATION, NULL,
2620                        "no policy found: %s\n",
2621                        spidx2str(&spidx));
2622                return -1;
2623        }
2624
2625        remsp(sp);
2626        delsp(sp);
2627
2628        return 0;
2629}
2630
2631static int
2632pk_recvspdexpire(mhp)
2633        caddr_t *mhp;
2634{
2635        struct sadb_address *saddr, *daddr;
2636        struct sadb_x_policy *xpl;
2637        struct sadb_lifetime *lt;
2638        struct policyindex spidx;
2639        struct secpolicy *sp;
2640        u_int64_t created;
2641
2642        /* sanity check */
2643        if (mhp[0] == NULL
2644         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2645         || mhp[SADB_EXT_ADDRESS_DST] == NULL
2646         || mhp[SADB_X_EXT_POLICY] == NULL) {
2647                plog(LLV_ERROR, LOCATION, NULL,
2648                        "inappropriate sadb spdexpire message passed.\n");
2649                return -1;
2650        }
2651        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2652        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2653        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2654        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2655        if(lt != NULL)
2656                created = lt->sadb_lifetime_addtime;
2657        else
2658                created = 0;
2659
2660#ifdef HAVE_PFKEY_POLICY_PRIORITY
2661        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2662                        saddr + 1,
2663                        daddr + 1,
2664                        saddr->sadb_address_prefixlen,
2665                        daddr->sadb_address_prefixlen,
2666                        saddr->sadb_address_proto,
2667                        xpl->sadb_x_policy_priority,
2668                        created,
2669                        &spidx);
2670#else
2671        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2672                        saddr + 1,
2673                        daddr + 1,
2674                        saddr->sadb_address_prefixlen,
2675                        daddr->sadb_address_prefixlen,
2676                        saddr->sadb_address_proto,
2677                        created,
2678                        &spidx);
2679#endif
2680
2681#ifdef HAVE_SECCTX
2682        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2683                struct sadb_x_sec_ctx *ctx;
2684
2685                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2686                spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2687                spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2688                spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2689                memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2690        }
2691#endif /* HAVE_SECCTX */
2692
2693        sp = getsp(&spidx);
2694        if (sp == NULL) {
2695                plog(LLV_ERROR, LOCATION, NULL,
2696                        "no policy found: %s\n",
2697                        spidx2str(&spidx));
2698                return -1;
2699        }
2700
2701        remsp(sp);
2702        delsp(sp);
2703
2704        return 0;
2705}
2706
2707static int
2708pk_recvspdget(mhp)
2709        caddr_t *mhp;
2710{
2711        /* sanity check */
2712        if (mhp[0] == NULL) {
2713                plog(LLV_ERROR, LOCATION, NULL,
2714                        "inappropriate sadb spdget message passed.\n");
2715                return -1;
2716        }
2717
2718        return 0;
2719}
2720
2721static int
2722pk_recvspddump(mhp)
2723        caddr_t *mhp;
2724{
2725        struct sadb_msg *msg;
2726        struct sadb_address *saddr, *daddr;
2727        struct sadb_x_policy *xpl;
2728        struct sadb_lifetime *lt;
2729        struct policyindex spidx;
2730        struct secpolicy *sp;
2731        struct sockaddr *local=NULL, *remote=NULL;
2732        u_int64_t created;
2733        int ret;
2734
2735        /* sanity check */
2736        if (mhp[0] == NULL) {
2737                plog(LLV_ERROR, LOCATION, NULL,
2738                        "inappropriate sadb spddump message passed.\n");
2739                return -1;
2740        }
2741        msg = (struct sadb_msg *)mhp[0];
2742        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2743        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2744        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2745        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2746        if(lt != NULL)
2747                created = lt->sadb_lifetime_addtime;
2748        else
2749                created = 0;
2750
2751        if (saddr == NULL || daddr == NULL || xpl == NULL) {
2752                plog(LLV_ERROR, LOCATION, NULL,
2753                        "inappropriate sadb spddump message passed.\n");
2754                return -1;
2755        }
2756
2757#ifdef HAVE_PFKEY_POLICY_PRIORITY
2758        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2759                        saddr + 1,
2760                        daddr + 1,
2761                        saddr->sadb_address_prefixlen,
2762                        daddr->sadb_address_prefixlen,
2763                        saddr->sadb_address_proto,
2764                        xpl->sadb_x_policy_priority,
2765                        created,
2766                        &spidx);
2767#else
2768        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2769                        saddr + 1,
2770                        daddr + 1,
2771                        saddr->sadb_address_prefixlen,
2772                        daddr->sadb_address_prefixlen,
2773                        saddr->sadb_address_proto,
2774                        created,
2775                        &spidx);
2776#endif
2777
2778#ifdef HAVE_SECCTX
2779        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2780                struct sadb_x_sec_ctx *ctx;
2781
2782                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2783                spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2784                spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2785                spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2786                memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2787        }
2788#endif /* HAVE_SECCTX */
2789
2790        sp = getsp(&spidx);
2791        if (sp != NULL) {
2792                plog(LLV_ERROR, LOCATION, NULL,
2793                        "such policy already exists. "
2794                        "anyway replace it: %s\n",
2795                        spidx2str(&spidx));
2796
2797                /* preserve hints before deleting the SP */
2798                local = sp->local;
2799                remote = sp->remote;
2800                sp->local = NULL;
2801                sp->remote = NULL;
2802
2803                remsp(sp);
2804                delsp(sp);
2805        }
2806
2807        /* Add new SP (with old hints) */
2808        ret = addnewsp(mhp, local, remote);
2809
2810        if (local != NULL)
2811                racoon_free(local);
2812        if (remote != NULL)
2813                racoon_free(remote);
2814
2815        if (ret < 0)
2816                return -1;
2817
2818        return 0;
2819}
2820
2821static int
2822pk_recvspdflush(mhp)
2823        caddr_t *mhp;
2824{
2825        /* sanity check */
2826        if (mhp[0] == NULL) {
2827                plog(LLV_ERROR, LOCATION, NULL,
2828                        "inappropriate sadb spdflush message passed.\n");
2829                return -1;
2830        }
2831
2832        flushsp();
2833
2834        return 0;
2835}
2836
2837#if defined(SADB_X_MIGRATE) && defined(SADB_X_EXT_KMADDRESS)
2838
2839/* MIGRATE support (pk_recvmigrate() is the handler of MIGRATE message).
2840 *
2841 * pk_recvmigrate()
2842 *   1) some preprocessing and checks
2843 *   2) parsing of sadb_x_kmaddress extension
2844 *   3) SP lookup using selectors and content of policy extension from MIGRATE
2845 *   4) resolution of current local and remote IKE addresses
2846 *   5) Use of addresses to get Phase 1 handler if any
2847 *   6) Update of IKE addresses in Phase 1 (iph1->local and iph1->remote)
2848 *   7) Update of IKE addresses in Phase 2 (iph2->src and iph2->dst)
2849 *   8) Update of IKE addresses in SP (sp->local and sp->remote)
2850 *   9) Loop on sadb_x_ipsecrequests pairs from MIGRATE
2851 *      - update of associated ipsecrequests entries in sp->req (should be
2852 *        only one as racoon does not support bundles), i.e. update of
2853 *        tunnel endpoints when required.
2854 *      - If tunnel mode endpoints have been updated, lookup of associated
2855 *        Phase 2 handle to also update sa_src and sa_dst entries
2856 *
2857 * XXX Note that we do not support yet the update of SA addresses for transport
2858 *     mode, but only the update of SA addresses for tunnel mode (endpoints).
2859 *     Reasons are:
2860 *      - there is no initial need for MIPv6
2861 *      - racoon does not support bundles
2862 *      - this would imply more work to deal with sainfo update (if feasible).
2863 */
2864
2865/* Generic argument structure for migration callbacks */
2866struct migrate_args {
2867        struct sockaddr *local;
2868        struct sockaddr *remote;
2869};
2870
2871/*
2872 * Update local and remote addresses of given Phase 1. Schedule removal
2873 * if negotiation was going on and restart a one from updated address.
2874 *
2875 * -1 is returned on error. 0 if everything went right.
2876 */
2877static int
2878migrate_ph1_ike_addresses(iph1, arg)
2879        struct ph1handle *iph1;
2880        void *arg;
2881{
2882        struct migrate_args *ma = (struct migrate_args *) arg;
2883        struct remoteconf *rmconf;
2884        u_int16_t port;
2885
2886        /* Already up-to-date? */
2887        if (cmpsaddr(iph1->local, ma->local) == CMPSADDR_MATCH &&
2888            cmpsaddr(iph1->remote, ma->remote) == CMPSADDR_MATCH)
2889                return 0;
2890
2891        if (iph1->status < PHASE1ST_ESTABLISHED) {
2892                /* Bad luck! We received a MIGRATE *while* negotiating
2893                 * Phase 1 (i.e. it was not established yet). If we act as
2894                 * initiator we need to restart the negotiation. As
2895                 * responder, our best bet is to update our addresses
2896                 * and wait for the initiator to do something */
2897                plog(LLV_WARNING, LOCATION, NULL, "MIGRATE received *during* "
2898                     "Phase 1 negotiation (%s).\n",
2899                     saddr2str_fromto("%s => %s", ma->local, ma->remote));
2900
2901                /* If we are not acting as initiator, let's just leave and
2902                 * let the remote peer handle the restart */
2903                rmconf = getrmconf(ma->remote, 0);
2904                if (rmconf == NULL || !rmconf->passive) {
2905                        iph1->status = PHASE1ST_EXPIRED;
2906                        isakmp_ph1delete(iph1);
2907
2908                        /* This is unlikely, but let's just check if a Phase 1
2909                         * for the new addresses already exist */
2910                        if (getph1byaddr(ma->local, ma->remote, 0)) {
2911                                plog(LLV_WARNING, LOCATION, NULL, "No need "
2912                                     "to start a new Phase 1 negotiation. One "
2913                                     "already exists.\n");
2914                                return 0;
2915                        }
2916
2917                        plog(LLV_WARNING, LOCATION, NULL, "As initiator, "
2918                             "restarting it.\n");
2919                         /* Note that the insertion of the new Phase 1 will not
2920                          * interfere with the fact we are called from enumph1,
2921                          * because it is inserted as first element. --arno */
2922                        isakmp_ph1begin_i(rmconf, ma->local, ma->remote);
2923
2924                        return 0;
2925                }
2926        }
2927
2928        if (iph1->local != NULL) {
2929                plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 local "
2930                     "address from %s\n",
2931                     saddr2str_fromto("%s to %s", iph1->local, ma->local));
2932                port = extract_port(iph1->local);
2933                racoon_free(iph1->local);
2934        } else
2935                port = 0;
2936
2937        iph1->local = dupsaddr(ma->local);
2938        if (iph1->local == NULL) {
2939                plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2940                     "Phase 1 local address.\n");
2941                return -1;
2942        }
2943        set_port(iph1->local, port);
2944
2945        if (iph1->remote != NULL) {
2946                plog(LLV_DEBUG, LOCATION, NULL, "Migrating Phase 1 remote "
2947                     "address from %s\n",
2948                     saddr2str_fromto("%s to %s", iph1->remote, ma->remote));
2949                port = extract_port(iph1->remote);
2950                racoon_free(iph1->remote);
2951        } else
2952                port = 0;
2953
2954        iph1->remote = dupsaddr(ma->remote);
2955        if (iph1->remote == NULL) {
2956                plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
2957                     "Phase 1 remote address.\n");
2958                return -1;
2959        }
2960        set_port(iph1->remote, port);
2961
2962        return 0;
2963}
2964
2965/* Update src and dst of all current Phase 2 handles.
2966 * with provided local and remote addresses.
2967 * Our intent is NOT to modify IPsec SA endpoints but IKE
2968 * addresses so we need to take care to separate those if
2969 * they are different. -1 is returned on error. 0 if everything
2970 * went right.
2971 *
2972 * Note: we do not maintain port information as it is not
2973 *       expected to be meaningful --arno
2974 */
2975static int
2976migrate_ph2_ike_addresses(iph2, arg)
2977        struct ph2handle *iph2;
2978        void *arg;
2979{
2980        struct migrate_args *ma = (struct migrate_args *) arg;
2981        struct ph1handle *iph1;
2982
2983        /* If Phase 2 has an associated Phase 1, migrate addresses */
2984        if (iph2->ph1)
2985                migrate_ph1_ike_addresses(iph2->ph1, arg);
2986
2987        /* Already up-to-date? */
2988        if (cmpsaddr(iph2->src, ma->local) == CMPSADDR_MATCH &&
2989            cmpsaddr(iph2->dst, ma->remote) == CMPSADDR_MATCH)
2990                return 0;
2991
2992        /* save src/dst as sa_src/sa_dst before rewriting */
2993        if (iph2->sa_src == NULL && iph2->sa_dst == NULL) {
2994                iph2->sa_src = iph2->src;
2995                iph2->sa_dst = iph2->dst;
2996                iph2->src = NULL;
2997                iph2->dst = NULL;
2998        }
2999
3000        if (iph2->src != NULL)
3001                racoon_free(iph2->src);
3002        iph2->src = dupsaddr(ma->local);
3003        if (iph2->src == NULL) {
3004                plog(LLV_ERROR, LOCATION, NULL,
3005                     "unable to allocate Phase 2 src address.\n");
3006                return -1;
3007        }
3008
3009        if (iph2->dst != NULL)
3010                racoon_free(iph2->dst);
3011        iph2->dst = dupsaddr(ma->remote);
3012        if (iph2->dst == NULL) {
3013                plog(LLV_ERROR, LOCATION, NULL,
3014                     "unable to allocate Phase 2 dst address.\n");
3015                return -1;
3016        }
3017
3018        return 0;
3019}
3020
3021/* Consider existing Phase 2 handles with given spid and update their source
3022 * and destination addresses for SA. As racoon does not support bundles, if
3023 * we modify multiple occurrences, this probably imply rekeying has happened.
3024 *
3025 * Both addresses passed to the function are expected not to be NULL and of
3026 * same family. -1 is returned on error. 0 if everything went right.
3027 *
3028 * Specific care is needed to support Phase 2 for which negotiation has
3029 * already started but are which not yet established.
3030 */
3031static int
3032migrate_ph2_sa_addresses(iph2, args)
3033        struct ph2handle *iph2;
3034        void *args;
3035{
3036        struct migrate_args *ma = (struct migrate_args *) args;
3037
3038        if (iph2->sa_src != NULL) {
3039                racoon_free(iph2->sa_src);
3040                iph2->sa_src = NULL;
3041        }
3042
3043        if (iph2->sa_dst != NULL) {
3044                racoon_free(iph2->sa_dst);
3045                iph2->sa_dst = NULL;
3046        }
3047
3048        iph2->sa_src = dupsaddr(ma->local);
3049        if (iph2->sa_src == NULL) {
3050                plog(LLV_ERROR, LOCATION, NULL,
3051                     "unable to allocate Phase 2 sa_src address.\n");
3052                return -1;
3053        }
3054
3055        iph2->sa_dst = dupsaddr(ma->remote);
3056        if (iph2->sa_dst == NULL) {
3057                plog(LLV_ERROR, LOCATION, NULL,
3058                     "unable to allocate Phase 2 sa_dst address.\n");
3059                return -1;
3060        }
3061
3062        if (iph2->status < PHASE2ST_ESTABLISHED) {
3063                struct remoteconf *rmconf;
3064                /* We were negotiating for that SA when we received the MIGRATE.
3065                 * We cannot simply update the addresses and let the exchange
3066                 * go on. We have to restart the whole negotiation if we are
3067                 * the initiator. Otherwise (acting as responder), we just need
3068                 * to delete our ph2handle and wait for the initiator to start
3069                 * a new negotiation. */
3070
3071                if (iph2->ph1 && iph2->ph1->rmconf)
3072                        rmconf = iph2->ph1->rmconf;
3073                else
3074                        rmconf = getrmconf(iph2->dst, 0);
3075
3076                if (rmconf && !rmconf->passive) {
3077                        struct ph1handle *iph1hint;
3078
3079                        plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3080                             "*during* IPsec SA negotiation. As initiator, "
3081                             "restarting it.\n");
3082
3083                        /* Turn off expiration timer ...*/
3084                        sched_cancel(&iph2->sce);
3085                        iph2->status = PHASE2ST_EXPIRED;
3086
3087                        /* ... clean Phase 2 handle ... */
3088                        iph1hint = iph2->ph1;
3089                        initph2(iph2);
3090                        iph2->status = PHASE2ST_STATUS2;
3091
3092                        /* and start a new negotiation */
3093                        if (isakmp_post_acquire(iph2, iph1hint, FALSE) < 0) {
3094                                plog(LLV_ERROR, LOCATION, iph2->dst, "failed "
3095                                     "to begin IPsec SA renegotiation after "
3096                                     "MIGRATE reception.\n");
3097                                remph2(iph2);
3098                                delph2(iph2);
3099                                return -1;
3100                        }
3101                } else {
3102                        plog(LLV_WARNING, LOCATION, iph2->dst, "MIGRATE received "
3103                             "*during* IPsec SA negotiation. As responder, let's"
3104                             "wait for the initiator to act.\n");
3105
3106                        /* Simply schedule deletion */
3107                        isakmp_ph2expire(iph2);
3108                }
3109        }
3110
3111        return 0;
3112}
3113
3114/* Update SP hints (local and remote addresses) for future IKE
3115 * negotiations of SA associated with that SP. -1 is returned
3116 * on error. 0 if everything went right.
3117 *
3118 * Note: we do not maintain port information as it is not
3119 *       expected to be meaningful --arno
3120 */
3121static int
3122migrate_sp_ike_addresses(sp, local, remote)
3123        struct secpolicy *sp;
3124        struct sockaddr *local, *remote;
3125{
3126        if (sp == NULL || local == NULL || remote == NULL)
3127                return -1;
3128
3129        if (sp->local != NULL)
3130                racoon_free(sp->local);
3131
3132        sp->local = dupsaddr(local);
3133        if (sp->local == NULL) {
3134                plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3135                     "local hint for SP.\n");
3136                return -1;
3137        }
3138
3139        if (sp->remote != NULL)
3140                racoon_free(sp->remote);
3141
3142        sp->remote = dupsaddr(remote);
3143        if (sp->remote == NULL) {
3144                plog(LLV_ERROR, LOCATION, NULL, "unable to allocate "
3145                     "remote hint for SP.\n");
3146                return -1;
3147        }
3148
3149        return 0;
3150}
3151
3152/* Given current ipsecrequest (isr_cur) to be migrated in considered
3153   tree, the function first checks that it matches the expected one
3154   (xisr_old) provided in MIGRATE message and then updates the addresses
3155   if it is tunnel mode (with content of xisr_new). Various other checks
3156   are performed. For transport mode, structures are not modified, only
3157   the checks are done. -1 is returned on error. */
3158static int
3159migrate_ph2_one_isr(spid, isr_cur, xisr_old, xisr_new)
3160        u_int32_t spid;
3161        struct ipsecrequest *isr_cur;
3162        struct sadb_x_ipsecrequest *xisr_old, *xisr_new;
3163{
3164        struct secasindex *saidx = &isr_cur->saidx;
3165        struct sockaddr *osaddr, *odaddr, *nsaddr, *ndaddr;
3166        struct ph2selector ph2sel;
3167        struct migrate_args ma;
3168
3169        /* First, check that mode and proto do match */
3170        if (xisr_old->sadb_x_ipsecrequest_proto != saidx->proto ||
3171            xisr_old->sadb_x_ipsecrequest_mode != saidx->mode ||
3172            xisr_new->sadb_x_ipsecrequest_proto != saidx->proto ||
3173            xisr_new->sadb_x_ipsecrequest_mode != saidx->mode)
3174                return -1;
3175
3176        /* Then, verify reqid if necessary */
3177        if (isr_cur->saidx.reqid &&
3178            (xisr_old->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3179             xisr_new->sadb_x_ipsecrequest_reqid != IPSEC_LEVEL_UNIQUE ||
3180             isr_cur->saidx.reqid != xisr_old->sadb_x_ipsecrequest_reqid ||
3181             isr_cur->saidx.reqid != xisr_new->sadb_x_ipsecrequest_reqid))
3182                return -1;
3183
3184        /* If not tunnel mode, our work is over */
3185        if (saidx->mode != IPSEC_MODE_TUNNEL) {
3186                plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3187                     "non tunnel mode isr, skipping SA address migration.\n");
3188                return 0;
3189        }
3190
3191        /* Tunnel mode: let's check addresses do match and then update them. */
3192        osaddr = (struct sockaddr *)(xisr_old + 1);
3193        odaddr = (struct sockaddr *)(((u_int8_t *)osaddr) + sysdep_sa_len(osaddr));
3194        nsaddr = (struct sockaddr *)(xisr_new + 1);
3195        ndaddr = (struct sockaddr *)(((u_int8_t *)nsaddr) + sysdep_sa_len(nsaddr));
3196
3197        /* Check family does match */
3198        if (osaddr->sa_family != odaddr->sa_family ||
3199            nsaddr->sa_family != ndaddr->sa_family)
3200                return -1;
3201
3202        /* Check family does match */
3203        if (saidx->src.ss_family != osaddr->sa_family)
3204                return -1;
3205
3206        /* We log IPv4 to IPv6 and IPv6 to IPv4 switches */
3207        if (nsaddr->sa_family != osaddr->sa_family)
3208                plog(LLV_INFO, LOCATION, NULL, "SADB_X_MIGRATE: "
3209                     "changing address families (%d to %d) for endpoints.\n",
3210                     osaddr->sa_family, nsaddr->sa_family);
3211
3212        if (cmpsaddr(osaddr, (struct sockaddr *) &saidx->src) != CMPSADDR_MATCH ||
3213            cmpsaddr(odaddr, (struct sockaddr *) &saidx->dst) != CMPSADDR_MATCH) {
3214                plog(LLV_DEBUG, LOCATION, NULL, "SADB_X_MIGRATE: "
3215                     "mismatch of addresses in saidx and xisr.\n");
3216                return -1;
3217        }
3218
3219        /* Excellent. Let's grab associated Phase 2 handle (if any)
3220         * and update its sa_src and sa_dst entries.  Note that we
3221         * make the assumption that racoon does not support bundles
3222         * and make the lookup using spid: we blindly update
3223         * sa_src and sa_dst for _all_ found Phase 2 handles */
3224        memset(&ph2sel, 0, sizeof(ph2sel));
3225        ph2sel.spid = spid;
3226
3227        memset(&ma, 0, sizeof(ma));
3228        ma.local = nsaddr;
3229        ma.remote = ndaddr;
3230
3231        if (enumph2(&ph2sel, migrate_ph2_sa_addresses, &ma) < 0)
3232                return -1;
3233
3234        /* Now we can do the update of endpoints in secasindex */
3235        memcpy(&saidx->src, nsaddr, sysdep_sa_len(nsaddr));
3236        memcpy(&saidx->dst, ndaddr, sysdep_sa_len(ndaddr));
3237
3238        return 0;
3239}
3240
3241/* Process the raw (unparsed yet) list of sadb_x_ipsecrequests of MIGRATE
3242 * message. For each sadb_x_ipsecrequest pair (old followed by new),
3243 * the corresponding ipsecrequest entry in the SP is updated. Associated
3244 * existing Phase 2 handle is also updated (if any) */
3245static int
3246migrate_sp_isr_list(sp, xisr_list, xisr_list_len)
3247        struct secpolicy *sp;
3248        struct sadb_x_ipsecrequest *xisr_list;
3249        int xisr_list_len;
3250{
3251        struct sadb_x_ipsecrequest *xisr_new, *xisr_old = xisr_list;
3252        int xisr_old_len, xisr_new_len;
3253        struct ipsecrequest *isr_cur;
3254
3255        isr_cur = sp->req; /* ipsecrequest list from from sp */
3256
3257        while (xisr_list_len > 0 && isr_cur != NULL) {
3258                /* Get old xisr (length field is in bytes) */
3259                xisr_old_len = xisr_old->sadb_x_ipsecrequest_len;
3260                if (xisr_old_len < sizeof(*xisr_old) ||
3261                    xisr_old_len + sizeof(*xisr_new) > xisr_list_len) {
3262                        plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3263                             "invalid ipsecrequest length. Exiting.\n");
3264                        return -1;
3265                }
3266
3267                /* Get new xisr with updated info */
3268                xisr_new = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_old) + xisr_old_len);
3269                xisr_new_len = xisr_new->sadb_x_ipsecrequest_len;
3270                if (xisr_new_len < sizeof(*xisr_new) ||
3271                    xisr_new_len + xisr_old_len > xisr_list_len) {
3272                        plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3273                             "invalid ipsecrequest length. Exiting.\n");
3274                        return -1;
3275                }
3276
3277                /* Start by migrating current ipsecrequest from SP */
3278                if (migrate_ph2_one_isr(sp->id, isr_cur, xisr_old, xisr_new) == -1) {
3279                        plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3280                             "Unable to match and migrate isr. Exiting.\n");
3281                        return -1;
3282                }
3283
3284                /* Update pointers for next round */
3285                xisr_list_len -= xisr_old_len + xisr_new_len;
3286                xisr_old = (struct sadb_x_ipsecrequest *)(((u_int8_t *)xisr_new) +
3287                                                          xisr_new_len);
3288
3289                isr_cur = isr_cur->next; /* Get next ipsecrequest from SP */
3290        }
3291
3292        /* Check we had the same amount of pairs in the MIGRATE
3293           as the number of ipsecrequests in the SP */
3294        if ((xisr_list_len != 0) || isr_cur != NULL) {
3295                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3296                     "number of ipsecrequest does not match the one in SP.\n");
3297                return -1;
3298        }
3299
3300        return 0;
3301}
3302
3303/* Parse sadb_x_kmaddress extension and make local and remote
3304 * parameters point to the new addresses (zero copy). -1 is
3305 * returned on error, meaning that addresses are not usable */
3306static int
3307parse_kmaddress(kmaddr, local, remote)
3308        struct sadb_x_kmaddress *kmaddr;
3309        struct sockaddr **local, **remote;
3310{
3311        int addrslen, local_len=0;
3312        struct ph1handle *iph1;
3313
3314        if (kmaddr == NULL)
3315                return -1;
3316
3317        /* Grab addresses in sadb_x_kmaddress extension */
3318        addrslen = PFKEY_EXTLEN(kmaddr) - sizeof(*kmaddr);
3319        if (addrslen < sizeof(struct sockaddr))
3320                return -1;
3321
3322        *local = (struct sockaddr *)(kmaddr + 1);
3323
3324        switch ((*local)->sa_family) {
3325        case AF_INET:
3326                local_len = sizeof(struct sockaddr_in);
3327                break;
3328#ifdef INET6
3329        case AF_INET6:
3330                local_len = sizeof(struct sockaddr_in6);
3331                break;
3332#endif
3333        default:
3334                return -1;
3335        }
3336
3337        if (addrslen != PFKEY_ALIGN8(2*local_len))
3338                return -1;
3339
3340        *remote = (struct sockaddr *)(((u_int8_t *)(*local)) + local_len);
3341
3342        if ((*local)->sa_family != (*remote)->sa_family)
3343                return -1;
3344
3345        return 0;
3346}
3347
3348/* Handler of PF_KEY MIGRATE message. Helpers are above */
3349static int
3350pk_recvmigrate(mhp)
3351        caddr_t *mhp;
3352{
3353        struct sadb_address *saddr, *daddr;
3354        struct sockaddr *old_saddr, *new_saddr;
3355        struct sockaddr *old_daddr, *new_daddr;
3356        struct sockaddr *old_local, *old_remote;
3357        struct sockaddr *local, *remote;
3358        struct sadb_x_kmaddress *kmaddr;
3359        struct sadb_x_policy *xpl;
3360        struct sadb_x_ipsecrequest *xisr_list;
3361        struct sadb_lifetime *lt;
3362        struct policyindex spidx;
3363        struct secpolicy *sp;
3364        struct ipsecrequest *isr_cur;
3365        struct secasindex *oldsaidx;
3366        struct ph2handle *iph2;
3367        struct ph1handle *iph1;
3368        struct ph2selector ph2sel;
3369        struct ph1selector ph1sel;
3370        u_int32_t spid;
3371        u_int64_t created;
3372        int xisr_list_len;
3373        int ulproto;
3374        struct migrate_args ma;
3375
3376        /* Some sanity checks */
3377
3378        if (mhp[0] == NULL
3379         || mhp[SADB_EXT_ADDRESS_SRC] == NULL
3380         || mhp[SADB_EXT_ADDRESS_DST] == NULL
3381         || mhp[SADB_X_EXT_KMADDRESS] == NULL
3382         || mhp[SADB_X_EXT_POLICY] == NULL) {
3383                plog(LLV_ERROR, LOCATION, NULL,
3384                        "SADB_X_MIGRATE: invalid MIGRATE message received.\n");
3385                return -1;
3386        }
3387        kmaddr = (struct sadb_x_kmaddress *)mhp[SADB_X_EXT_KMADDRESS];
3388        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3389        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3390        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3391        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3392        if (lt != NULL)
3393                created = lt->sadb_lifetime_addtime;
3394        else
3395                created = 0;
3396
3397        if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
3398                plog(LLV_WARNING, LOCATION, NULL,"SADB_X_MIGRATE: "
3399                     "found non IPsec policy in MIGRATE message. Exiting.\n");
3400                return -1;
3401        }
3402
3403        if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3404                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3405                     "invalid size for sadb_x_policy. Exiting.\n");
3406                return -1;
3407        }
3408
3409        /* Some logging to help debbugging */
3410        if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
3411                plog(LLV_DEBUG, LOCATION, NULL,
3412                     "SADB_X_MIGRATE: Outbound SA being migrated.\n");
3413        else
3414                plog(LLV_DEBUG, LOCATION, NULL,
3415                     "SADB_X_MIGRATE: Inbound SA being migrated.\n");
3416
3417        /* validity check */
3418        xisr_list = (struct sadb_x_ipsecrequest *)(xpl + 1);
3419        xisr_list_len = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3420        if (xisr_list_len < sizeof(*xisr_list)) {
3421                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3422                     "invalid sadb_x_policy message length. Exiting.\n");
3423                return -1;
3424        }
3425
3426        if (parse_kmaddress(kmaddr, &local, &remote) == -1) {
3427                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: "
3428                     "invalid sadb_x_kmaddress extension. Exiting.\n");
3429                return -1;
3430        }
3431
3432        /* 0 means ANY */
3433        if (saddr->sadb_address_proto == 0)
3434                ulproto = IPSEC_ULPROTO_ANY;
3435        else
3436                ulproto = saddr->sadb_address_proto;
3437
3438#ifdef HAVE_PFKEY_POLICY_PRIORITY
3439        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3440                        saddr + 1,
3441                        daddr + 1,
3442                        saddr->sadb_address_prefixlen,
3443                        daddr->sadb_address_prefixlen,
3444                        ulproto,
3445                        xpl->sadb_x_policy_priority,
3446                        created,
3447                        &spidx);
3448#else
3449        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3450                        saddr + 1,
3451                        daddr + 1,
3452                        saddr->sadb_address_prefixlen,
3453                        daddr->sadb_address_prefixlen,
3454                        ulproto,
3455                        created,
3456                        &spidx);
3457#endif
3458
3459        /* Everything seems ok, let's get the SP.
3460         *
3461         * XXX We could also do the lookup using the spid from xpl.
3462         *     I don't know which one is better.  --arno */
3463        sp = getsp(&spidx);
3464        if (sp == NULL) {
3465                plog(LLV_ERROR, LOCATION, NULL,
3466                        "SADB_X_MIGRATE: Passed policy does not exist: %s\n",
3467                        spidx2str(&spidx));
3468                return -1;
3469        }
3470
3471        /* Get the best source and destination addresses used for IKE
3472         * negotiation, to find and migrate existing Phase 1 */
3473        if (sp->local && sp->remote) {
3474                /* hints available, let's use them */
3475                old_local  = (struct sockaddr *)sp->local;
3476                old_remote = (struct sockaddr *)sp->remote;
3477        } else if (sp->req && sp->req->saidx.mode == IPSEC_MODE_TUNNEL) {
3478                /* Tunnel mode and no hint, use endpoints */
3479                old_local  = (struct sockaddr *)&sp->req->saidx.src;
3480                old_remote = (struct sockaddr *)&sp->req->saidx.dst;
3481        } else {
3482                /* default, use selectors as fallback */
3483                old_local  = (struct sockaddr *)&sp->spidx.src;
3484                old_remote = (struct sockaddr *)&sp->spidx.dst;
3485        }
3486
3487        /* We migrate all Phase 1 that match our old local and remote
3488         * addresses (no matter their state).
3489         *
3490         * XXX In fact, we should probably havea special treatment for
3491         * Phase 1 that are being established when we receive a MIGRATE.
3492         * This can happen if a movement occurs during the initial IKE
3493         * negotiation. In that case, I wonder if should restart the
3494         * negotiation from the new address or just update things like
3495         * we do it now.
3496         *
3497         * XXX while looking at getph1byaddr(), the comment at the
3498         * beginning of the function expects comparison to happen
3499         * without ports considerations but it uses CMPSADDR() which
3500         * relies either on cmpsaddrstrict() or cmpsaddrwop() based
3501         * on NAT-T support being activated. That make me wonder if I
3502         * should force ports to 0 (ANY) in local and remote values
3503         * used below.
3504         *
3505         * -- arno */
3506
3507        /* Apply callback data ...*/
3508        memset(&ma, 0, sizeof(ma));
3509        ma.local = local;
3510        ma.remote = remote;
3511
3512        /* Fill phase1 match criteria ... */
3513        memset(&ph1sel, 0, sizeof(ph1sel));
3514        ph1sel.local = old_local;
3515        ph1sel.remote = old_remote;
3516
3517
3518        /* Have matching Phase 1 found and addresses updated. As this is a
3519         * time consuming task on a busy responder, and MIGRATE messages
3520         * are always sent for *both* inbound and outbound (and possibly
3521         * forward), we only do that for outbound SP. */
3522        if (xpl->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND &&
3523            enumph1(&ph1sel, migrate_ph1_ike_addresses, &ma) < 0) {
3524                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3525                     "to migrate Phase 1 addresses.\n");
3526                return -1;
3527        }
3528
3529        /* We can now update IKE addresses in Phase 2 handle. */
3530        memset(&ph2sel, 0, sizeof(ph2sel));
3531        ph2sel.spid = sp->id;
3532        if (enumph2(&ph2sel, migrate_ph2_ike_addresses, &ma) < 0) {
3533                plog(LLV_ERROR, LOCATION, NULL, "SADB_X_MIGRATE: Unable "
3534                     "to migrate Phase 2 IKE addresses.\n");
3535                return -1;
3536        }
3537
3538        /* and _then_ in SP. */
3539        if (migrate_sp_ike_addresses(sp, local, remote) < 0) {
3540                plog(LLV_ERROR, LOCATION, NULL,
3541                     "SADB_X_MIGRATE: Unable to migrate SP IKE addresses.\n");
3542                return -1;
3543        }
3544
3545        /* Loop on sadb_x_ipsecrequest list to possibly update sp->req
3546         * entries and associated live Phase 2 handles (their sa_src
3547         * and sa_dst) */
3548        if (migrate_sp_isr_list(sp, xisr_list, xisr_list_len) < 0) {
3549                plog(LLV_ERROR, LOCATION, NULL,
3550                     "SADB_X_MIGRATE: Unable to migrate isr list.\n");
3551                return -1;
3552        }
3553
3554        return 0;
3555}
3556#endif
3557
3558/*
3559 * send error against acquire message to kernel.
3560 */
3561int
3562pk_sendeacquire(iph2)
3563        struct ph2handle *iph2;
3564{
3565        struct sadb_msg *newmsg;
3566        int len;
3567
3568        len = sizeof(struct sadb_msg);
3569        newmsg = racoon_calloc(1, len);
3570        if (newmsg == NULL) {
3571                plog(LLV_ERROR, LOCATION, NULL,
3572                        "failed to get buffer to send acquire.\n");
3573                return -1;
3574        }
3575
3576        memset(newmsg, 0, len);
3577        newmsg->sadb_msg_version = PF_KEY_V2;
3578        newmsg->sadb_msg_type = SADB_ACQUIRE;
3579        newmsg->sadb_msg_errno = ENOENT;        /* XXX */
3580        newmsg->sadb_msg_satype = iph2->satype;
3581        newmsg->sadb_msg_len = PFKEY_UNIT64(len);
3582        newmsg->sadb_msg_reserved = 0;
3583        newmsg->sadb_msg_seq = iph2->seq;
3584        newmsg->sadb_msg_pid = (u_int32_t)getpid();
3585
3586        /* send message */
3587        len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
3588
3589        racoon_free(newmsg);
3590
3591        return 0;
3592}
3593
3594/*
3595 * check if the algorithm is supported or not.
3596 * OUT   0: ok
3597 *      -1: ng
3598 */
3599int
3600pk_checkalg(class, calg, keylen)
3601        int class, calg, keylen;
3602{
3603        int sup, error;
3604        u_int alg;
3605        struct sadb_alg alg0;
3606
3607        switch (algclass2doi(class)) {
3608        case IPSECDOI_PROTO_IPSEC_ESP:
3609                sup = SADB_EXT_SUPPORTED_ENCRYPT;
3610                break;
3611        case IPSECDOI_ATTR_AUTH:
3612                sup = SADB_EXT_SUPPORTED_AUTH;
3613                break;
3614        case IPSECDOI_PROTO_IPCOMP:
3615                plog(LLV_DEBUG, LOCATION, NULL,
3616                        "no check of compression algorithm; "
3617                        "not supported in sadb message.\n");
3618                return 0;
3619        default:
3620                plog(LLV_ERROR, LOCATION, NULL,
3621                        "invalid algorithm class.\n");
3622                return -1;
3623        }
3624        alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
3625        if (alg == ~0)
3626                return -1;
3627
3628        if (keylen == 0) {
3629                if (ipsec_get_keylen(sup, alg, &alg0)) {
3630                        plog(LLV_ERROR, LOCATION, NULL,
3631                                "%s.\n", ipsec_strerror());
3632                        return -1;
3633                }
3634                keylen = alg0.sadb_alg_minbits;
3635        }
3636
3637        error = ipsec_check_keylen(sup, alg, keylen);
3638        if (error)
3639                plog(LLV_ERROR, LOCATION, NULL,
3640                        "%s.\n", ipsec_strerror());
3641
3642        return error;
3643}
3644
3645/*
3646 * differences with pfkey_recv() in libipsec/pfkey.c:
3647 * - never performs busy wait loop.
3648 * - returns NULL and set *lenp to negative on fatal failures
3649 * - returns NULL and set *lenp to non-negative on non-fatal failures
3650 * - returns non-NULL on success
3651 */
3652static struct sadb_msg *
3653pk_recv(so, lenp)
3654        int so;
3655        int *lenp;
3656{
3657        struct sadb_msg buf, *newmsg;
3658        int reallen;
3659        int retry = 0;
3660
3661        *lenp = -1;
3662        do
3663        {
3664            plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
3665            *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
3666            retry++;
3667        }
3668        while (*lenp < 0 && errno == EAGAIN && retry < 3);
3669
3670        if (*lenp < 0)
3671                return NULL;    /*fatal*/
3672
3673        else if (*lenp < sizeof(buf))
3674                return NULL;
3675
3676        reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
3677        if (reallen < sizeof(buf)) {
3678                *lenp = -1;
3679                errno = EIO;
3680                return NULL;    /*fatal*/
3681        }
3682        if ((newmsg = racoon_calloc(1, reallen)) == NULL)
3683                return NULL;
3684
3685        *lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
3686        if (*lenp < 0) {
3687                racoon_free(newmsg);
3688                return NULL;    /*fatal*/
3689        } else if (*lenp != reallen) {
3690                racoon_free(newmsg);
3691                return NULL;
3692        }
3693
3694        *lenp = recv(so, (caddr_t)newmsg, reallen, 0);
3695        if (*lenp < 0) {
3696                racoon_free(newmsg);
3697                return NULL;    /*fatal*/
3698        } else if (*lenp != reallen) {
3699                racoon_free(newmsg);
3700                return NULL;
3701        }
3702
3703        return newmsg;
3704}
3705
3706/* see handler.h */
3707u_int32_t
3708pk_getseq()
3709{
3710        return eay_random();
3711}
3712
3713static int
3714addnewsp(mhp, local, remote)
3715        caddr_t *mhp;
3716        struct sockaddr *local, *remote;
3717{
3718        struct secpolicy *new = NULL;
3719        struct sadb_address *saddr, *daddr;
3720        struct sadb_x_policy *xpl;
3721        struct sadb_lifetime *lt;
3722        u_int64_t created;
3723
3724        /* sanity check */
3725        if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
3726         || mhp[SADB_EXT_ADDRESS_DST] == NULL
3727         || mhp[SADB_X_EXT_POLICY] == NULL) {
3728                plog(LLV_ERROR, LOCATION, NULL,
3729                        "inappropriate sadb spd management message passed.\n");
3730                goto bad;
3731        }
3732
3733        saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3734        daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3735        xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3736        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3737        if(lt != NULL)
3738                created = lt->sadb_lifetime_addtime;
3739        else
3740                created = 0;
3741        lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
3742        if(lt != NULL)
3743                created = lt->sadb_lifetime_addtime;
3744        else
3745                created = 0;
3746
3747#ifdef __linux__
3748        /* bsd skips over per-socket policies because there will be no
3749         * src and dst extensions in spddump messages. On Linux the only
3750         * way to achieve the same is check for policy id.
3751         */
3752        if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
3753#endif
3754
3755        new = newsp();
3756        if (new == NULL) {
3757                plog(LLV_ERROR, LOCATION, NULL,
3758                        "failed to allocate buffer\n");
3759                goto bad;
3760        }
3761
3762        new->spidx.dir = xpl->sadb_x_policy_dir;
3763        new->id = xpl->sadb_x_policy_id;
3764        new->policy = xpl->sadb_x_policy_type;
3765        new->req = NULL;
3766
3767        /* check policy */
3768        switch (xpl->sadb_x_policy_type) {
3769        case IPSEC_POLICY_DISCARD:
3770        case IPSEC_POLICY_NONE:
3771        case IPSEC_POLICY_ENTRUST:
3772        case IPSEC_POLICY_BYPASS:
3773                break;
3774
3775        case IPSEC_POLICY_IPSEC:
3776            {
3777                int tlen;
3778                struct sadb_x_ipsecrequest *xisr;
3779                struct ipsecrequest **p_isr = &new->req;
3780
3781                /* validity check */
3782                if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3783                        plog(LLV_ERROR, LOCATION, NULL,
3784                                "invalid msg length.\n");
3785                        goto bad;
3786                }
3787
3788                tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3789                xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
3790
3791                while (tlen > 0) {
3792
3793                        /* length check */
3794                        if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
3795                                plog(LLV_ERROR, LOCATION, NULL,
3796                                        "invalid msg length.\n");
3797                                goto bad;
3798                        }
3799
3800                        /* allocate request buffer */
3801                        *p_isr = newipsecreq();
3802                        if (*p_isr == NULL) {
3803                                plog(LLV_ERROR, LOCATION, NULL,
3804                                        "failed to get new ipsecreq.\n");
3805                                goto bad;
3806                        }
3807
3808                        /* set values */
3809                        (*p_isr)->next = NULL;
3810
3811                        switch (xisr->sadb_x_ipsecrequest_proto) {
3812                        case IPPROTO_ESP:
3813                        case IPPROTO_AH:
3814                        case IPPROTO_IPCOMP:
3815                                break;
3816                        default:
3817                                plog(LLV_ERROR, LOCATION, NULL,
3818                                        "invalid proto type: %u\n",
3819                                        xisr->sadb_x_ipsecrequest_proto);
3820                                goto bad;
3821                        }
3822                        (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
3823
3824                        switch (xisr->sadb_x_ipsecrequest_mode) {
3825                        case IPSEC_MODE_TRANSPORT:
3826                        case IPSEC_MODE_TUNNEL:
3827                                break;
3828                        case IPSEC_MODE_ANY:
3829                        default:
3830                                plog(LLV_ERROR, LOCATION, NULL,
3831                                        "invalid mode: %u\n",
3832                                        xisr->sadb_x_ipsecrequest_mode);
3833                                goto bad;
3834                        }
3835                        (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
3836
3837                        switch (xisr->sadb_x_ipsecrequest_level) {
3838                        case IPSEC_LEVEL_DEFAULT:
3839                        case IPSEC_LEVEL_USE:
3840                        case IPSEC_LEVEL_REQUIRE:
3841                                break;
3842                        case IPSEC_LEVEL_UNIQUE:
3843                                (*p_isr)->saidx.reqid =
3844                                        xisr->sadb_x_ipsecrequest_reqid;
3845                                break;
3846
3847                        default:
3848                                plog(LLV_ERROR, LOCATION, NULL,
3849                                        "invalid level: %u\n",
3850                                        xisr->sadb_x_ipsecrequest_level);
3851                                goto bad;
3852                        }
3853                        (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
3854
3855                        /* set IP addresses if there */
3856                        if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
3857                                struct sockaddr *paddr;
3858
3859                                paddr = (struct sockaddr *)(xisr + 1);
3860                                bcopy(paddr, &(*p_isr)->saidx.src,
3861                                        sysdep_sa_len(paddr));
3862
3863                                paddr = (struct sockaddr *)((caddr_t)paddr
3864                                                        + sysdep_sa_len(paddr));
3865                                bcopy(paddr, &(*p_isr)->saidx.dst,
3866                                        sysdep_sa_len(paddr));
3867                        }
3868
3869                        (*p_isr)->sp = new;
3870
3871                        /* initialization for the next. */
3872                        p_isr = &(*p_isr)->next;
3873                        tlen -= xisr->sadb_x_ipsecrequest_len;
3874
3875                        /* validity check */
3876                        if (tlen < 0) {
3877                                plog(LLV_ERROR, LOCATION, NULL,
3878                                        "becoming tlen < 0\n");
3879                        }
3880
3881                        xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
3882                                         + xisr->sadb_x_ipsecrequest_len);
3883                }
3884            }
3885                break;
3886        default:
3887                plog(LLV_ERROR, LOCATION, NULL,
3888                        "invalid policy type.\n");
3889                goto bad;
3890        }
3891
3892#ifdef HAVE_PFKEY_POLICY_PRIORITY
3893        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3894                        saddr + 1,
3895                        daddr + 1,
3896                        saddr->sadb_address_prefixlen,
3897                        daddr->sadb_address_prefixlen,
3898                        saddr->sadb_address_proto,
3899                        xpl->sadb_x_policy_priority,
3900                        created,
3901                        &new->spidx);
3902#else
3903        KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3904                        saddr + 1,
3905                        daddr + 1,
3906                        saddr->sadb_address_prefixlen,
3907                        daddr->sadb_address_prefixlen,
3908                        saddr->sadb_address_proto,
3909                        created,
3910                        &new->spidx);
3911#endif
3912
3913#ifdef HAVE_SECCTX
3914        if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
3915                struct sadb_x_sec_ctx *ctx;
3916
3917                ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
3918                new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
3919                new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
3920                new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
3921                memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
3922        }
3923#endif /* HAVE_SECCTX */
3924
3925        /* Set local and remote hints for that SP, if available */
3926        if (local && remote) {
3927                new->local = dupsaddr(local);
3928                new->remote = dupsaddr(remote);
3929        }
3930
3931        inssp(new);
3932
3933        return 0;
3934bad:
3935        if (new != NULL) {
3936                if (new->req != NULL)
3937                        racoon_free(new->req);
3938                racoon_free(new);
3939        }
3940        return -1;
3941}
3942
3943/* proto/mode/src->dst spi */
3944const char *
3945sadbsecas2str(src, dst, proto, spi, mode)
3946        struct sockaddr *src, *dst;
3947        int proto;
3948        u_int32_t spi;
3949        int mode;
3950{
3951        static char buf[256];
3952        u_int doi_proto, doi_mode = 0;
3953        char *p;
3954        int blen, i;
3955
3956        doi_proto = pfkey2ipsecdoi_proto(proto);
3957        if (doi_proto == ~0)
3958                return NULL;
3959        if (mode) {
3960                doi_mode = pfkey2ipsecdoi_mode(mode);
3961                if (doi_mode == ~0)
3962                        return NULL;
3963        }
3964
3965        blen = sizeof(buf) - 1;
3966        p = buf;
3967
3968        i = snprintf(p, blen, "%s%s%s ",
3969                s_ipsecdoi_proto(doi_proto),
3970                mode ? "/" : "",
3971                mode ? s_ipsecdoi_encmode(doi_mode) : "");
3972        if (i < 0 || i >= blen)
3973                return NULL;
3974        p += i;
3975        blen -= i;
3976
3977        i = snprintf(p, blen, "%s->", saddr2str(src));
3978        if (i < 0 || i >= blen)
3979                return NULL;
3980        p += i;
3981        blen -= i;
3982
3983        i = snprintf(p, blen, "%s ", saddr2str(dst));
3984        if (i < 0 || i >= blen)
3985                return NULL;
3986        p += i;
3987        blen -= i;
3988
3989        if (spi) {
3990                snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3991                    (unsigned long)ntohl(spi));
3992        }
3993
3994        return buf;
3995}
Note: See TracBrowser for help on using the repository browser.