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

5-freebsd-12
Last change on this file since 8645c9d7 was 8645c9d7, checked in by Christian Mauderer <christian.mauderer@…>, on Jun 6, 2018 at 9:11:52 AM

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: 62.3 KB
Line 
1/*      $NetBSD: isakmp_quick.c,v 1.29 2011/03/14 17:18:13 tteras Exp $ */
2
3/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd 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 <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39
40#include <netinet/in.h>
41
42#include <stdlib.h>
43#include <stdio.h>
44#include <string.h>
45#include <errno.h>
46#if TIME_WITH_SYS_TIME
47# include <sys/time.h>
48# include <time.h>
49#else
50# if HAVE_SYS_TIME_H
51#  include <sys/time.h>
52# else
53#  include <time.h>
54# endif
55#endif
56
57#include PATH_IPSEC_H
58
59#include "var.h"
60#include "vmbuf.h"
61#include "schedule.h"
62#include "misc.h"
63#include "plog.h"
64#include "debug.h"
65
66#include "localconf.h"
67#include "remoteconf.h"
68#include "handler.h"
69#include "policy.h"
70#include "proposal.h"
71#include "isakmp_var.h"
72#include "isakmp.h"
73#include "isakmp_inf.h"
74#include "isakmp_quick.h"
75#include "oakley.h"
76#include "ipsec_doi.h"
77#include "crypto_openssl.h"
78#include "pfkey.h"
79#include "policy.h"
80#include "algorithm.h"
81#include "sockmisc.h"
82#include "proposal.h"
83#include "sainfo.h"
84#include "admin.h"
85#include "strnames.h"
86
87#ifdef ENABLE_HYBRID
88#include <resolv.h>
89#include "isakmp_xauth.h"
90#include "isakmp_cfg.h"
91#endif
92
93#ifdef ENABLE_NATT
94#include "nattraversal.h"
95#endif
96
97/* quick mode */
98static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
99static int get_sainfo_r __P((struct ph2handle *));
100static int get_proposal_r __P((struct ph2handle *));
101static int ph2_recv_n __P((struct ph2handle *, struct isakmp_gen *));
102static void quick_timeover_stub __P((struct sched *));
103static void quick_timeover __P((struct ph2handle *));
104
105/* called from scheduler */
106static void
107quick_timeover_stub(p)
108        struct sched *p;
109{
110        quick_timeover(container_of(p, struct ph2handle, sce));
111}
112
113static void
114quick_timeover(iph2)
115        struct ph2handle *iph2;
116{
117        plog(LLV_ERROR, LOCATION, NULL,
118                "%s give up to get IPsec-SA due to time up to wait.\n",
119                saddrwop2str(iph2->dst));
120
121        /* If initiator side, send error to kernel by SADB_ACQUIRE. */
122        if (iph2->side == INITIATOR)
123                pk_sendeacquire(iph2);
124
125        remph2(iph2);
126        delph2(iph2);
127}
128
129/* %%%
130 * Quick Mode
131 */
132/*
133 * begin Quick Mode as initiator.  send pfkey getspi message to kernel.
134 */
135int
136quick_i1prep(iph2, msg)
137        struct ph2handle *iph2;
138        vchar_t *msg; /* must be null pointer */
139{
140        int error = ISAKMP_INTERNAL_ERROR;
141
142        /* validity check */
143        if (iph2->status != PHASE2ST_STATUS2) {
144                plog(LLV_ERROR, LOCATION, NULL,
145                        "status mismatched %d.\n", iph2->status);
146                goto end;
147        }
148
149        iph2->msgid = isakmp_newmsgid2(iph2->ph1);
150        iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
151        if (iph2->ivm == NULL)
152                return 0;
153
154        iph2->status = PHASE2ST_GETSPISENT;
155
156        /* don't anything if local test mode. */
157        if (f_local) {
158                error = 0;
159                goto end;
160        }
161
162        /* send getspi message */
163        if (pk_sendgetspi(iph2) < 0)
164                goto end;
165
166        plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
167
168        sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
169                       quick_timeover_stub);
170
171        error = 0;
172
173end:
174        return error;
175}
176
177/*
178 * send to responder
179 *      HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
180 */
181int
182quick_i1send(iph2, msg)
183        struct ph2handle *iph2;
184        vchar_t *msg; /* must be null pointer */
185{
186        vchar_t *body = NULL;
187        vchar_t *hash = NULL;
188        struct isakmp_gen *gen;
189        char *p;
190        int tlen;
191        int error = ISAKMP_INTERNAL_ERROR;
192        int natoa = ISAKMP_NPTYPE_NONE;
193        int pfsgroup, idci, idcr;
194        int np;
195        struct ipsecdoi_id_b *id, *id_p;
196#ifdef ENABLE_NATT
197        vchar_t *nat_oai = NULL;
198        vchar_t *nat_oar = NULL;
199#endif
200
201        /* validity check */
202        if (msg != NULL) {
203                plog(LLV_ERROR, LOCATION, NULL,
204                        "msg has to be NULL in this function.\n");
205                goto end;
206        }
207        if (iph2->status != PHASE2ST_GETSPIDONE) {
208                plog(LLV_ERROR, LOCATION, NULL,
209                        "status mismatched %d.\n", iph2->status);
210                goto end;
211        }
212
213        /* create SA payload for my proposal */
214        if (ipsecdoi_setph2proposal(iph2) < 0)
215                goto end;
216
217        /* generate NONCE value */
218        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
219        if (iph2->nonce == NULL)
220                goto end;
221
222        /*
223         * DH value calculation is kicked out into cfparse.y.
224         * because pfs group can not be negotiated, it's only to be checked
225         * acceptable.
226         */
227        /* generate KE value if need */
228        pfsgroup = iph2->proposal->pfs_group;
229        if (pfsgroup) {
230                /* DH group settting if PFS is required. */
231                if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
232                        plog(LLV_ERROR, LOCATION, NULL,
233                                "failed to set DH value.\n");
234                        goto end;
235                }
236                if (oakley_dh_generate(iph2->pfsgrp,
237                                &iph2->dhpub, &iph2->dhpriv) < 0) {
238                        goto end;
239                }
240        }
241
242        /* generate ID value */
243        if (ipsecdoi_setid2(iph2) < 0) {
244                plog(LLV_ERROR, LOCATION, NULL,
245                        "failed to get ID.\n");
246                goto end;
247        }
248        plog(LLV_DEBUG, LOCATION, NULL, "IDci:\n");
249        plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
250        plog(LLV_DEBUG, LOCATION, NULL, "IDcr:\n");
251        plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
252
253        /*
254         * we do not attach IDci nor IDcr, under the following condition:
255         * - all proposals are transport mode
256         * - no MIP6 or proxy
257         * - id payload suggests to encrypt all the traffic (no specific
258         *   protocol type)
259         * - SA endpoints and IKE addresses for the nego are the same
260         *   (iph2->src/dst)
261         */
262        id = (struct ipsecdoi_id_b *)iph2->id->v;
263        id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
264        if (id->proto_id == 0 &&
265            id_p->proto_id == 0 &&
266            iph2->ph1->rmconf->support_proxy == 0 &&
267            iph2->sa_src == NULL && iph2->sa_dst == NULL &&
268            ipsecdoi_transportmode(iph2->proposal)) {
269                idci = idcr = 0;
270        } else
271                idci = idcr = 1;
272
273#ifdef ENABLE_NATT
274        /*
275         * RFC3947 5.2. if we propose UDP-Encapsulated-Transport
276         * we should send NAT-OA
277         */
278        if (ipsecdoi_transportmode(iph2->proposal)
279         && (iph2->ph1->natt_flags & NAT_DETECTED)) {
280                natoa = iph2->ph1->natt_options->payload_nat_oa;
281
282                nat_oai = ipsecdoi_sockaddr2id(iph2->src,
283                        IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
284                nat_oar = ipsecdoi_sockaddr2id(iph2->dst,
285                        IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
286
287                if (nat_oai == NULL || nat_oar == NULL) {
288                        plog(LLV_ERROR, LOCATION, NULL,
289                                "failed to generate NAT-OA payload.\n");
290                        goto end;
291                }
292
293                plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n");
294                plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l);
295                plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n");
296                plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l);
297        } else {
298                natoa = ISAKMP_NPTYPE_NONE;
299        }
300#endif
301
302        /* create SA;NONCE payload, and KE if need, and IDii, IDir. */
303        tlen = + sizeof(*gen) + iph2->sa->l
304                + sizeof(*gen) + iph2->nonce->l;
305        if (pfsgroup)
306                tlen += (sizeof(*gen) + iph2->dhpub->l);
307        if (idci)
308                tlen += sizeof(*gen) + iph2->id->l;
309        if (idcr)
310                tlen += sizeof(*gen) + iph2->id_p->l;
311#ifdef ENABLE_NATT
312        if (natoa != ISAKMP_NPTYPE_NONE)
313                tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
314#endif
315
316        body = vmalloc(tlen);
317        if (body == NULL) {
318                plog(LLV_ERROR, LOCATION, NULL,
319                        "failed to get buffer to send.\n");
320                goto end;
321        }
322
323        p = body->v;
324
325        /* add SA payload */
326        p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE);
327
328        /* add NONCE payload */
329        if (pfsgroup)
330                np = ISAKMP_NPTYPE_KE;
331        else if (idci || idcr)
332                np = ISAKMP_NPTYPE_ID;
333        else
334                np = natoa;
335        p = set_isakmp_payload(p, iph2->nonce, np);
336
337        /* add KE payload if need. */
338        np = (idci || idcr) ? ISAKMP_NPTYPE_ID : natoa;
339        if (pfsgroup)
340                p = set_isakmp_payload(p, iph2->dhpub, np);
341
342        /* IDci */
343        np = (idcr) ? ISAKMP_NPTYPE_ID : natoa;
344        if (idci)
345                p = set_isakmp_payload(p, iph2->id, np);
346
347        /* IDcr */
348        if (idcr)
349                p = set_isakmp_payload(p, iph2->id_p, natoa);
350
351#ifdef ENABLE_NATT
352        /* NAT-OA */
353        if (natoa != ISAKMP_NPTYPE_NONE) {
354                p = set_isakmp_payload(p, nat_oai, natoa);
355                p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
356        }
357#endif
358
359        /* generate HASH(1) */
360        hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
361        if (hash == NULL)
362                goto end;
363
364        /* send isakmp payload */
365        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
366        if (iph2->sendbuf == NULL)
367                goto end;
368
369        /* send the packet, add to the schedule to resend */
370        if (isakmp_ph2send(iph2) == -1)
371                goto end;
372
373        /* change status of isakmp status entry */
374        iph2->status = PHASE2ST_MSG1SENT;
375
376        error = 0;
377
378end:
379        if (body != NULL)
380                vfree(body);
381        if (hash != NULL)
382                vfree(hash);
383#ifdef ENABLE_NATT
384        if (nat_oai != NULL)
385                vfree(nat_oai);
386        if (nat_oar != NULL)
387                vfree(nat_oar);
388#endif
389
390        return error;
391}
392
393/*
394 * receive from responder
395 *      HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
396 */
397int
398quick_i2recv(iph2, msg0)
399        struct ph2handle *iph2;
400        vchar_t *msg0;
401{
402        vchar_t *msg = NULL;
403        vchar_t *hbuf = NULL;   /* for hash computing. */
404        vchar_t *pbuf = NULL;   /* for payload parsing */
405        vchar_t *idci = NULL;
406        vchar_t *idcr = NULL;
407        struct isakmp_parse_t *pa;
408        struct isakmp *isakmp = (struct isakmp *)msg0->v;
409        struct isakmp_pl_hash *hash = NULL;
410        char *p;
411        int tlen;
412        int error = ISAKMP_INTERNAL_ERROR;
413
414        /* validity check */
415        if (iph2->status != PHASE2ST_MSG1SENT) {
416                plog(LLV_ERROR, LOCATION, NULL,
417                        "status mismatched %d.\n", iph2->status);
418                goto end;
419        }
420
421        /* decrypt packet */
422        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
423                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
424                        "Packet wasn't encrypted.\n");
425                goto end;
426        }
427        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
428        if (msg == NULL)
429                goto end;
430
431        /* create buffer for validating HASH(2) */
432        /*
433         * ordering rule:
434         *      1. the first one must be HASH
435         *      2. the second one must be SA (added in isakmp-oakley-05!)
436         *      3. two IDs must be considered as IDci, then IDcr
437         */
438        pbuf = isakmp_parse(msg);
439        if (pbuf == NULL)
440                goto end;
441        pa = (struct isakmp_parse_t *)pbuf->v;
442
443        /* HASH payload is fixed postion */
444        if (pa->type != ISAKMP_NPTYPE_HASH) {
445                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
446                        "received invalid next payload type %d, "
447                        "expecting %d.\n",
448                        pa->type, ISAKMP_NPTYPE_HASH);
449                goto end;
450        }
451        hash = (struct isakmp_pl_hash *)pa->ptr;
452        pa++;
453
454        /*
455         * this restriction was introduced in isakmp-oakley-05.
456         * we do not check this for backward compatibility.
457         * TODO: command line/config file option to enable/disable this code
458         */
459        /* HASH payload is fixed postion */
460        if (pa->type != ISAKMP_NPTYPE_SA) {
461                plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
462                        "received invalid next payload type %d, "
463                        "expecting %d.\n",
464                        pa->type, ISAKMP_NPTYPE_HASH);
465        }
466
467        /* allocate buffer for computing HASH(2) */
468        tlen = iph2->nonce->l
469                + ntohl(isakmp->len) - sizeof(*isakmp);
470        hbuf = vmalloc(tlen);
471        if (hbuf == NULL) {
472                plog(LLV_ERROR, LOCATION, NULL,
473                        "failed to get hash buffer.\n");
474                goto end;
475        }
476        p = hbuf->v + iph2->nonce->l;   /* retain the space for Ni_b */
477
478        /*
479         * parse the payloads.
480         * copy non-HASH payloads into hbuf, so that we can validate HASH.
481         */
482        iph2->sa_ret = NULL;
483        tlen = 0;       /* count payload length except of HASH payload. */
484        for (; pa->type; pa++) {
485
486                /* copy to buffer for HASH */
487                /* Don't modify the payload */
488                memcpy(p, pa->ptr, pa->len);
489
490                switch (pa->type) {
491                case ISAKMP_NPTYPE_SA:
492                        if (iph2->sa_ret != NULL) {
493                                plog(LLV_ERROR, LOCATION, NULL,
494                                        "Ignored, multiple SA "
495                                        "isn't supported.\n");
496                                break;
497                        }
498                        if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0) {
499                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
500                                        "duplicate ISAKMP_NPTYPE_SA.\n");
501                                goto end;
502                        }
503                        break;
504
505                case ISAKMP_NPTYPE_NONCE:
506                        if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
507                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
508                                        "duplicate ISAKMP_NPTYPE_NONCE.\n");
509                                goto end;
510                        }
511                        break;
512
513                case ISAKMP_NPTYPE_KE:
514                        if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
515                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
516                                        "duplicate ISAKMP_NPTYPE_KE.\n");
517                                goto end;
518                        }
519                        break;
520
521                case ISAKMP_NPTYPE_ID:
522                        if (idci == NULL) {
523                                if (isakmp_p2ph(&idci, pa->ptr) < 0)
524                                        goto end;
525                        } else if (idcr == NULL) {
526                                if (isakmp_p2ph(&idcr, pa->ptr) < 0)
527                                        goto end;
528                        } else {
529                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
530                                        "too many ISAKMP_NPTYPE_ID payloads.\n");
531                                goto end;
532                        }
533                        break;
534
535                case ISAKMP_NPTYPE_N:
536                        ph2_recv_n(iph2, pa->ptr);
537                        break;
538
539#ifdef ENABLE_NATT
540                case ISAKMP_NPTYPE_NATOA_DRAFT:
541                case ISAKMP_NPTYPE_NATOA_RFC:
542                    {
543                        struct sockaddr_storage addr;
544                        struct sockaddr *daddr;
545                        u_int8_t prefix;
546                        u_int16_t ul_proto;
547                        vchar_t *vp = NULL;
548
549                        if (isakmp_p2ph(&vp, pa->ptr) < 0)
550                                goto end;
551
552                        error = ipsecdoi_id2sockaddr(vp,
553                                        (struct sockaddr *) &addr,
554                                        &prefix, &ul_proto);
555
556                        vfree(vp);
557
558                        if (error)
559                                goto end;
560
561                        daddr = dupsaddr((struct sockaddr *) &addr);
562                        if (daddr == NULL)
563                                goto end;
564
565                        if (iph2->natoa_src == NULL)
566                                iph2->natoa_src = daddr;
567                        else if (iph2->natoa_dst == NULL)
568                                iph2->natoa_dst = daddr;
569                        else {
570                                racoon_free(daddr);
571                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
572                                        "too many ISAKMP_NPTYPE_NATOA payloads.\n");
573                                goto end;
574                        }
575                    }
576                        break;
577#endif
578
579                default:
580                        /* don't send information, see ident_r1recv() */
581                        plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
582                                "ignore the packet, "
583                                "received unexpecting payload type %d.\n",
584                                pa->type);
585                        goto end;
586                }
587
588                p += pa->len;
589
590                /* compute true length of payload. */
591                tlen += pa->len;
592        }
593
594        /* payload existency check */
595        if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
596                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
597                        "few isakmp message received.\n");
598                goto end;
599        }
600
601        /* identity check */
602        if (idci != NULL) {
603                struct sockaddr_storage proposed_addr, got_addr;
604                u_int8_t proposed_prefix, got_prefix;
605                u_int16_t proposed_ulproto, got_ulproto;
606
607                error = ipsecdoi_id2sockaddr(iph2->id,
608                                        (struct sockaddr *) &proposed_addr,
609                                        &proposed_prefix, &proposed_ulproto);
610                if (error)
611                        goto end;
612
613                error = ipsecdoi_id2sockaddr(idci,
614                                        (struct sockaddr *) &got_addr,
615                                        &got_prefix, &got_ulproto);
616                if (error)
617                        goto end;
618
619                if (proposed_prefix != got_prefix
620                 || proposed_ulproto != got_ulproto) {
621                        plog(LLV_DEBUG, LOCATION, NULL,
622                                "IDci prefix/ulproto does not match proposal.\n");
623                        error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
624                        goto end;
625                }
626#ifdef ENABLE_NATT
627                set_port(iph2->natoa_src,
628                         extract_port((struct sockaddr *) &proposed_addr));
629#endif
630
631                if (cmpsaddr((struct sockaddr *) &proposed_addr,
632                             (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
633                        plog(LLV_DEBUG, LOCATION, NULL,
634                                "IDci matches proposal.\n");
635#ifdef ENABLE_NATT
636                } else if (iph2->natoa_src != NULL
637                        && cmpsaddr(iph2->natoa_src,
638                                    (struct sockaddr *) &got_addr) == 0) {
639                        plog(LLV_DEBUG, LOCATION, NULL,
640                                "IDci matches NAT-OAi.\n");
641#endif
642                } else {
643                        plog(LLV_ERROR, LOCATION, NULL,
644                                "mismatched IDci was returned.\n");
645                        error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
646                        goto end;
647                }
648        }
649        if (idcr != NULL) {
650                struct sockaddr_storage proposed_addr, got_addr;
651                u_int8_t proposed_prefix, got_prefix;
652                u_int16_t proposed_ulproto, got_ulproto;
653
654                error = ipsecdoi_id2sockaddr(iph2->id_p,
655                                        (struct sockaddr *) &proposed_addr,
656                                        &proposed_prefix, &proposed_ulproto);
657                if (error)
658                        goto end;
659
660                error = ipsecdoi_id2sockaddr(idcr,
661                                        (struct sockaddr *) &got_addr,
662                                        &got_prefix, &got_ulproto);
663                if (error)
664                        goto end;
665
666                if (proposed_prefix != got_prefix
667                 || proposed_ulproto != got_ulproto) {
668                        plog(LLV_DEBUG, LOCATION, NULL,
669                                "IDcr prefix/ulproto does not match proposal.\n");
670                        error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
671                        goto end;
672                }
673
674#ifdef ENABLE_NATT
675                set_port(iph2->natoa_dst,
676                         extract_port((struct sockaddr *) &proposed_addr));
677#endif
678
679                if (cmpsaddr((struct sockaddr *) &proposed_addr,
680                             (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
681                        plog(LLV_DEBUG, LOCATION, NULL,
682                                "IDcr matches proposal.\n");
683#ifdef ENABLE_NATT
684                } else if (iph2->natoa_dst != NULL
685                        && cmpsaddr(iph2->natoa_dst,
686                                    (struct sockaddr *) &got_addr) == CMPSADDR_MATCH) {
687                        plog(LLV_DEBUG, LOCATION, NULL,
688                                "IDcr matches NAT-OAr.\n");
689#endif
690                } else {
691                        plog(LLV_ERROR, LOCATION, NULL,
692                                "mismatched IDcr was returned.\n");
693                        error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
694                        goto end;
695                }
696        }
697
698        /* Fixed buffer for calculating HASH */
699        memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
700        plog(LLV_DEBUG, LOCATION, NULL,
701                "HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
702                hbuf->l, tlen + iph2->nonce->l);
703        /* adjust buffer length for HASH */
704        hbuf->l = iph2->nonce->l + tlen;
705
706        /* validate HASH(2) */
707    {
708        char *r_hash;
709        vchar_t *my_hash = NULL;
710        int result;
711
712        r_hash = (char *)hash + sizeof(*hash);
713
714        plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:");
715        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
716
717        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
718        if (my_hash == NULL)
719                goto end;
720
721        result = memcmp(my_hash->v, r_hash, my_hash->l);
722        vfree(my_hash);
723
724        if (result) {
725                plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
726                        "HASH(2) mismatch.\n");
727                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
728                goto end;
729        }
730    }
731
732        /* validity check SA payload sent from responder */
733        if (ipsecdoi_checkph2proposal(iph2) < 0) {
734                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
735                        "proposal check failed.\n");
736                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
737                goto end;
738        }
739
740        /* change status of isakmp status entry */
741        iph2->status = PHASE2ST_STATUS6;
742
743        error = 0;
744
745end:
746        if (hbuf)
747                vfree(hbuf);
748        if (pbuf)
749                vfree(pbuf);
750        if (msg)
751                vfree(msg);
752        if (idci)
753                vfree(idci);
754        if (idcr)
755                vfree(idcr);
756
757        if (error) {
758                VPTRINIT(iph2->sa_ret);
759                VPTRINIT(iph2->nonce_p);
760                VPTRINIT(iph2->dhpub_p);
761                VPTRINIT(iph2->id);
762                VPTRINIT(iph2->id_p);
763#ifdef ENABLE_NATT
764                if (iph2->natoa_src) {
765                        racoon_free(iph2->natoa_src);
766                        iph2->natoa_src = NULL;
767                }
768                if (iph2->natoa_dst) {
769                        racoon_free(iph2->natoa_dst);
770                        iph2->natoa_dst = NULL;
771                }
772#endif
773        }
774
775        return error;
776}
777
778/*
779 * send to responder
780 *      HDR*, HASH(3)
781 */
782int
783quick_i2send(iph2, msg0)
784        struct ph2handle *iph2;
785        vchar_t *msg0;
786{
787        vchar_t *msg = NULL;
788        vchar_t *buf = NULL;
789        vchar_t *hash = NULL;
790        char *p = NULL;
791        int tlen;
792        int error = ISAKMP_INTERNAL_ERROR;
793
794        /* validity check */
795        if (iph2->status != PHASE2ST_STATUS6) {
796                plog(LLV_ERROR, LOCATION, NULL,
797                        "status mismatched %d.\n", iph2->status);
798                goto end;
799        }
800
801        /* generate HASH(3) */
802    {
803        vchar_t *tmp = NULL;
804
805        plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n");
806
807        tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l);
808        if (tmp == NULL) { 
809                plog(LLV_ERROR, LOCATION, NULL,
810                        "failed to get hash buffer.\n");
811                goto end;
812        }
813        memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l);
814        memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l);
815
816        hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
817        vfree(tmp);
818
819        if (hash == NULL)
820                goto end;
821    }
822
823        /* create buffer for isakmp payload */
824        tlen = sizeof(struct isakmp)
825                + sizeof(struct isakmp_gen) + hash->l;
826        buf = vmalloc(tlen);
827        if (buf == NULL) { 
828                plog(LLV_ERROR, LOCATION, NULL,
829                        "failed to get buffer to send.\n");
830                goto end;
831        }
832
833        /* create isakmp header */
834        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
835        if (p == NULL)
836                goto end;
837
838        /* add HASH(3) payload */
839        p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
840
841#ifdef HAVE_PRINT_ISAKMP_C
842        isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
843#endif
844
845        /* encoding */
846        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
847        if (iph2->sendbuf == NULL)
848                goto end;
849
850        /* if there is commit bit, need resending */
851        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
852                /* send the packet, add to the schedule to resend */
853                if (isakmp_ph2send(iph2) == -1)
854                        goto end;
855        } else {
856                /* send the packet */
857                if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
858                        goto end;
859        }
860
861        /* the sending message is added to the received-list. */
862        if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
863                        iph2->sendbuf, msg0) == -1) {
864                plog(LLV_ERROR , LOCATION, NULL,
865                        "failed to add a response packet to the tree.\n");
866                goto end;
867        }
868
869        /* compute both of KEYMATs */
870        if (oakley_compute_keymat(iph2, INITIATOR) < 0)
871                goto end;
872
873        iph2->status = PHASE2ST_ADDSA;
874
875        /* don't anything if local test mode. */
876        if (f_local) {
877                error = 0;
878                goto end;
879        }
880
881        /* if there is commit bit don't set up SA now. */
882        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
883                iph2->status = PHASE2ST_COMMIT;
884                error = 0;
885                goto end;
886        }
887
888        /* Do UPDATE for initiator */
889        plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
890        if (pk_sendupdate(iph2) < 0) {
891                plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
892                goto end;
893        }
894        plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
895
896        /* Do ADD for responder */
897        if (pk_sendadd(iph2) < 0) {
898                plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
899                goto end;
900        }
901        plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
902
903        error = 0;
904
905end:
906        if (buf != NULL)
907                vfree(buf);
908        if (msg != NULL)
909                vfree(msg);
910        if (hash != NULL)
911                vfree(hash);
912
913        return error;
914}
915
916/*
917 * receive from responder
918 *      HDR#*, HASH(4), notify
919 */
920int
921quick_i3recv(iph2, msg0)
922        struct ph2handle *iph2;
923        vchar_t *msg0;
924{
925        vchar_t *msg = NULL;
926        vchar_t *pbuf = NULL;   /* for payload parsing */
927        struct isakmp_parse_t *pa;
928        struct isakmp_pl_hash *hash = NULL;
929        vchar_t *notify = NULL;
930        int error = ISAKMP_INTERNAL_ERROR;
931
932        /* validity check */
933        if (iph2->status != PHASE2ST_COMMIT) {
934                plog(LLV_ERROR, LOCATION, NULL,
935                        "status mismatched %d.\n", iph2->status);
936                goto end;
937        }
938
939        /* decrypt packet */
940        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
941                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
942                        "Packet wasn't encrypted.\n");
943                goto end;
944        }
945        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
946        if (msg == NULL)
947                goto end;
948
949        /* validate the type of next payload */
950        pbuf = isakmp_parse(msg);
951        if (pbuf == NULL)
952                goto end;
953
954        for (pa = (struct isakmp_parse_t *)pbuf->v;
955             pa->type != ISAKMP_NPTYPE_NONE;
956             pa++) {
957
958                switch (pa->type) {
959                case ISAKMP_NPTYPE_HASH:
960                        hash = (struct isakmp_pl_hash *)pa->ptr;
961                        break;
962                case ISAKMP_NPTYPE_N:
963                        if (notify != NULL) {
964                                plog(LLV_WARNING, LOCATION, NULL,
965                                    "Ignoring multiples notifications\n");
966                                break;
967                        }
968                        ph2_recv_n(iph2, pa->ptr);
969                        notify = vmalloc(pa->len);
970                        if (notify == NULL) {
971                                plog(LLV_ERROR, LOCATION, NULL,
972                                        "failed to get notify buffer.\n");
973                                goto end;
974                        }
975                        memcpy(notify->v, pa->ptr, notify->l);
976                        break;
977                default:
978                        /* don't send information, see ident_r1recv() */
979                        plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
980                                "ignore the packet, "
981                                "received unexpecting payload type %d.\n",
982                                pa->type);
983                        goto end;
984                }
985        }
986
987        /* payload existency check */
988        if (hash == NULL) {
989                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
990                        "few isakmp message received.\n");
991                goto end;
992        }
993
994        /* validate HASH(4) */
995    {
996        char *r_hash;
997        vchar_t *my_hash = NULL;
998        vchar_t *tmp = NULL;
999        int result;
1000
1001        r_hash = (char *)hash + sizeof(*hash);
1002
1003        plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:");
1004        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
1005
1006        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1007        vfree(tmp);
1008        if (my_hash == NULL)
1009                goto end;
1010
1011        result = memcmp(my_hash->v, r_hash, my_hash->l);
1012        vfree(my_hash);
1013
1014        if (result) {
1015                plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
1016                        "HASH(4) mismatch.\n");
1017                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1018                goto end;
1019        }
1020    }
1021
1022        iph2->status = PHASE2ST_ADDSA;
1023        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
1024
1025        /* don't anything if local test mode. */
1026        if (f_local) {
1027                error = 0;
1028                goto end;
1029        }
1030
1031        /* Do UPDATE for initiator */
1032        plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
1033        if (pk_sendupdate(iph2) < 0) {
1034                plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
1035                goto end;
1036        }
1037        plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
1038
1039        /* Do ADD for responder */
1040        if (pk_sendadd(iph2) < 0) {
1041                plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
1042                goto end;
1043        }
1044        plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
1045
1046        error = 0;
1047
1048end:
1049        if (msg != NULL)
1050                vfree(msg);
1051        if (pbuf != NULL)
1052                vfree(pbuf);
1053        if (notify != NULL)
1054                vfree(notify);
1055
1056        return error;
1057}
1058
1059/*
1060 * receive from initiator
1061 *      HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1062 */
1063int
1064quick_r1recv(iph2, msg0)
1065        struct ph2handle *iph2;
1066        vchar_t *msg0;
1067{
1068        vchar_t *msg = NULL;
1069        vchar_t *hbuf = NULL;   /* for hash computing. */
1070        vchar_t *pbuf = NULL;   /* for payload parsing */
1071        struct isakmp_parse_t *pa;
1072        struct isakmp *isakmp = (struct isakmp *)msg0->v;
1073        struct isakmp_pl_hash *hash = NULL;
1074        char *p;
1075        int tlen;
1076        int f_id_order; /* for ID payload detection */
1077        int error = ISAKMP_INTERNAL_ERROR;
1078
1079        /* validity check */
1080        if (iph2->status != PHASE2ST_START) {
1081                plog(LLV_ERROR, LOCATION, NULL,
1082                        "status mismatched %d.\n", iph2->status);
1083                goto end;
1084        }
1085
1086        /* decrypting */
1087        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1088                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1089                        "Packet wasn't encrypted.\n");
1090                error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1091                goto end;
1092        }
1093        /* decrypt packet */
1094        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
1095        if (msg == NULL) {
1096                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1097                        "Packet decryption failed.\n");
1098                goto end;
1099        }
1100
1101        /* create buffer for using to validate HASH(1) */
1102        /*
1103         * ordering rule:
1104         *      1. the first one must be HASH
1105         *      2. the second one must be SA (added in isakmp-oakley-05!)
1106         *      3. two IDs must be considered as IDci, then IDcr
1107         */
1108        pbuf = isakmp_parse(msg);
1109        if (pbuf == NULL)
1110                goto end;
1111        pa = (struct isakmp_parse_t *)pbuf->v;
1112
1113        /* HASH payload is fixed postion */
1114        if (pa->type != ISAKMP_NPTYPE_HASH) {
1115                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1116                        "received invalid next payload type %d, "
1117                        "expecting %d.\n",
1118                        pa->type, ISAKMP_NPTYPE_HASH);
1119                error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
1120                goto end;
1121        }
1122        hash = (struct isakmp_pl_hash *)pa->ptr;
1123        pa++;
1124
1125        /*
1126         * this restriction was introduced in isakmp-oakley-05.
1127         * we do not check this for backward compatibility.
1128         * TODO: command line/config file option to enable/disable this code
1129         */
1130        /* HASH payload is fixed postion */
1131        if (pa->type != ISAKMP_NPTYPE_SA) {
1132                plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
1133                        "received invalid next payload type %d, "
1134                        "expecting %d.\n",
1135                        pa->type, ISAKMP_NPTYPE_SA);
1136                error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
1137        }
1138
1139        /* allocate buffer for computing HASH(1) */
1140        tlen = ntohl(isakmp->len) - sizeof(*isakmp);
1141        hbuf = vmalloc(tlen);
1142        if (hbuf == NULL) {
1143                plog(LLV_ERROR, LOCATION, NULL,
1144                        "failed to get hash buffer.\n");
1145                goto end;
1146        }
1147        p = hbuf->v;
1148
1149        /*
1150         * parse the payloads.
1151         * copy non-HASH payloads into hbuf, so that we can validate HASH.
1152         */
1153        iph2->sa = NULL;        /* we don't support multi SAs. */
1154        iph2->nonce_p = NULL;
1155        iph2->dhpub_p = NULL;
1156        iph2->id_p = NULL;
1157        iph2->id = NULL;
1158        tlen = 0;       /* count payload length except of HASH payload. */
1159
1160        /*
1161         * IDi2 MUST be immediatelly followed by IDr2.  We allowed the
1162         * illegal case, but logged.  First ID payload is to be IDi2.
1163         * And next ID payload is to be IDr2.
1164         */
1165        f_id_order = 0;
1166
1167        for (; pa->type; pa++) {
1168
1169                /* copy to buffer for HASH */
1170                /* Don't modify the payload */
1171                memcpy(p, pa->ptr, pa->len);
1172
1173                if (pa->type != ISAKMP_NPTYPE_ID)
1174                        f_id_order = 0;
1175
1176                switch (pa->type) {
1177                case ISAKMP_NPTYPE_SA:
1178                        if (iph2->sa != NULL) {
1179                                plog(LLV_ERROR, LOCATION, NULL,
1180                                        "Multi SAs isn't supported.\n");
1181                                goto end;
1182                        }
1183                        if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0) {
1184                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1185                                        "duplicate ISAKMP_NPTYPE_SA.\n");
1186                                goto end;
1187                        }
1188                        break;
1189
1190                case ISAKMP_NPTYPE_NONCE:
1191                        if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0) {
1192                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1193                                        "duplicate ISAKMP_NPTYPE_NONCE.\n");
1194                                goto end;
1195                        }
1196                        break;
1197
1198                case ISAKMP_NPTYPE_KE:
1199                        if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0) {
1200                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1201                                        "duplicate ISAKMP_NPTYPE_KE.\n");
1202                                goto end;
1203                        }
1204                        break;
1205
1206                case ISAKMP_NPTYPE_ID:
1207                        if (iph2->id_p == NULL) {
1208                                /* for IDci */
1209                                f_id_order++;
1210
1211                                if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0)
1212                                        goto end;
1213
1214                        } else if (iph2->id == NULL) {
1215                                /* for IDcr */
1216                                if (f_id_order == 0) {
1217                                        plog(LLV_ERROR, LOCATION, NULL,
1218                                                "IDr2 payload is not "
1219                                                "immediatelly followed "
1220                                                "by IDi2. We allowed.\n");
1221                                        /* XXX we allowed in this case. */
1222                                }
1223
1224                                if (isakmp_p2ph(&iph2->id, pa->ptr) < 0)
1225                                        goto end;
1226                        } else {
1227                                plog(LLV_ERROR, LOCATION, NULL,
1228                                        "received too many ID payloads.\n");
1229                                plogdump(LLV_ERROR, iph2->id->v, iph2->id->l);
1230                                error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1231                                goto end;
1232                        }
1233                        break;
1234
1235                case ISAKMP_NPTYPE_N:
1236                        ph2_recv_n(iph2, pa->ptr);
1237                        break;
1238
1239#ifdef ENABLE_NATT
1240                case ISAKMP_NPTYPE_NATOA_DRAFT:
1241                case ISAKMP_NPTYPE_NATOA_RFC:
1242                    {
1243                        struct sockaddr_storage addr;
1244                        struct sockaddr *daddr;
1245                        u_int8_t prefix;
1246                        u_int16_t ul_proto;
1247                        vchar_t *vp = NULL;
1248
1249                        if (isakmp_p2ph(&vp, pa->ptr) < 0)
1250                                goto end;
1251
1252                        error = ipsecdoi_id2sockaddr(vp,
1253                                        (struct sockaddr *) &addr,
1254                                        &prefix, &ul_proto);
1255
1256                        vfree(vp);
1257
1258                        if (error)
1259                                goto end;
1260
1261                        daddr = dupsaddr((struct sockaddr *) &addr);
1262                        if (daddr == NULL)
1263                                goto end;
1264
1265                        if (iph2->natoa_dst == NULL)
1266                                iph2->natoa_dst = daddr;
1267                        else if (iph2->natoa_src == NULL)
1268                                iph2->natoa_src = daddr;
1269                        else {
1270                                racoon_free(daddr);
1271                                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1272                                        "received too many NAT-OA payloads.\n");
1273                                error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1274                                goto end;
1275                        }
1276                    }
1277                        break;
1278#endif
1279
1280                default:
1281                        plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1282                                "ignore the packet, "
1283                                "received unexpecting payload type %d.\n",
1284                                pa->type);
1285                        error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1286                        goto end;
1287                }
1288
1289                p += pa->len;
1290
1291                /* compute true length of payload. */
1292                tlen += pa->len;
1293        }
1294
1295        /* payload existency check */
1296        if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
1297                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1298                        "few isakmp message received.\n");
1299                error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1300                goto end;
1301        }
1302
1303        if (iph2->id_p) {
1304                plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:");
1305                plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
1306        }
1307        if (iph2->id) {
1308                plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:");
1309                plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
1310        }
1311
1312        /* adjust buffer length for HASH */
1313        hbuf->l = tlen;
1314
1315        /* validate HASH(1) */
1316    {
1317        char *r_hash;
1318        vchar_t *my_hash = NULL;
1319        int result;
1320
1321        r_hash = (caddr_t)hash + sizeof(*hash);
1322
1323        plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:");
1324        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
1325
1326        my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
1327        if (my_hash == NULL)
1328                goto end;
1329
1330        result = memcmp(my_hash->v, r_hash, my_hash->l);
1331        vfree(my_hash);
1332
1333        if (result) {
1334                plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
1335                        "HASH(1) mismatch.\n");
1336                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1337                goto end;
1338        }
1339    }
1340
1341        /* get sainfo */
1342        error = get_sainfo_r(iph2);
1343        if (error) {
1344                plog(LLV_ERROR, LOCATION, NULL,
1345                        "failed to get sainfo.\n");
1346                goto end;
1347        }
1348
1349
1350        /* check the existence of ID payload and create responder's proposal */
1351        error = get_proposal_r(iph2);
1352        switch (error) {
1353        case -2:
1354                /* generate a policy template from peer's proposal */
1355                if (set_proposal_from_proposal(iph2)) {
1356                        plog(LLV_ERROR, LOCATION, NULL,
1357                                "failed to generate a proposal template "
1358                                "from client's proposal.\n");
1359                        error = ISAKMP_INTERNAL_ERROR;
1360                        goto end;
1361                }
1362                /*FALLTHROUGH*/
1363        case 0:
1364                /* select single proposal or reject it. */
1365                if (ipsecdoi_selectph2proposal(iph2) < 0) {
1366                        plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1367                                "no proposal chosen.\n");
1368                        error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1369                        goto end;
1370                }
1371                break;
1372        default:
1373                plog(LLV_ERROR, LOCATION, NULL,
1374                        "failed to get proposal for responder.\n");
1375                goto end;
1376        }
1377
1378        /* check KE and attribute of PFS */
1379        if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
1380                plog(LLV_ERROR, LOCATION, NULL,
1381                        "no PFS is specified, but peer sends KE.\n");
1382                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1383                goto end;
1384        }
1385        if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
1386                plog(LLV_ERROR, LOCATION, NULL,
1387                        "PFS is specified, but peer doesn't sends KE.\n");
1388                error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1389                goto end;
1390        }
1391
1392        /*
1393         * save the packet from the initiator in order to resend the
1394         * responder's first packet against this packet.
1395         */
1396        iph2->msg1 = vdup(msg0);
1397
1398        /* change status of isakmp status entry */
1399        iph2->status = PHASE2ST_STATUS2;
1400
1401        error = 0;
1402
1403end:
1404        if (hbuf)
1405                vfree(hbuf);
1406        if (msg)
1407                vfree(msg);
1408        if (pbuf)
1409                vfree(pbuf);
1410
1411        if (error) {
1412                VPTRINIT(iph2->sa);
1413                VPTRINIT(iph2->nonce_p);
1414                VPTRINIT(iph2->dhpub_p);
1415                VPTRINIT(iph2->id);
1416                VPTRINIT(iph2->id_p);
1417#ifdef ENABLE_NATT
1418                if (iph2->natoa_src) {
1419                        racoon_free(iph2->natoa_src);
1420                        iph2->natoa_src = NULL;
1421                }
1422                if (iph2->natoa_dst) {
1423                        racoon_free(iph2->natoa_dst);
1424                        iph2->natoa_dst = NULL;
1425                }
1426#endif
1427        }
1428
1429        return error;
1430}
1431
1432/*
1433 * call pfkey_getspi.
1434 */
1435int
1436quick_r1prep(iph2, msg)
1437        struct ph2handle *iph2;
1438        vchar_t *msg;
1439{
1440        int error = ISAKMP_INTERNAL_ERROR;
1441
1442        /* validity check */
1443        if (iph2->status != PHASE2ST_STATUS2) {
1444                plog(LLV_ERROR, LOCATION, NULL,
1445                        "status mismatched %d.\n", iph2->status);
1446                goto end;
1447        }
1448
1449        iph2->status = PHASE2ST_GETSPISENT;
1450
1451        /* send getspi message */
1452        if (pk_sendgetspi(iph2) < 0)
1453                goto end;
1454
1455        plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
1456
1457        sched_schedule(&iph2->sce, lcconf->wait_ph2complete,
1458                       quick_timeover_stub);
1459
1460        error = 0;
1461
1462end:
1463        return error;
1464}
1465
1466/*
1467 * send to initiator
1468 *      HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ] [, NAT-OAi, NAT-OAr ]
1469 */
1470int
1471quick_r2send(iph2, msg)
1472        struct ph2handle *iph2;
1473        vchar_t *msg;
1474{
1475        vchar_t *body = NULL;
1476        vchar_t *hash = NULL;
1477        struct isakmp_gen *gen;
1478        char *p;
1479        int tlen;
1480        int error = ISAKMP_INTERNAL_ERROR;
1481        int natoa = ISAKMP_NPTYPE_NONE;
1482        int pfsgroup;
1483        u_int8_t *np_p = NULL;
1484#ifdef ENABLE_NATT
1485        vchar_t *nat_oai = NULL;
1486        vchar_t *nat_oar = NULL;
1487#endif
1488
1489        /* validity check */
1490        if (msg != NULL) {
1491                plog(LLV_ERROR, LOCATION, NULL,
1492                        "msg has to be NULL in this function.\n");
1493                goto end;
1494        }
1495        if (iph2->status != PHASE2ST_GETSPIDONE) {
1496                plog(LLV_ERROR, LOCATION, NULL,
1497                        "status mismatched %d.\n", iph2->status);
1498                goto end;
1499        }
1500
1501        /* update responders SPI */
1502        if (ipsecdoi_updatespi(iph2) < 0) {
1503                plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n");
1504                goto end;
1505        }
1506
1507        /* generate NONCE value */
1508        iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
1509        if (iph2->nonce == NULL)
1510                goto end;
1511
1512        /* generate KE value if need */
1513        pfsgroup = iph2->approval->pfs_group;
1514        if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1515                /* DH group settting if PFS is required. */
1516                if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
1517                        plog(LLV_ERROR, LOCATION, NULL,
1518                                "failed to set DH value.\n");
1519                        goto end;
1520                }
1521                /* generate DH public value */
1522                if (oakley_dh_generate(iph2->pfsgrp,
1523                                &iph2->dhpub, &iph2->dhpriv) < 0) {
1524                        goto end;
1525                }
1526        }
1527
1528#ifdef ENABLE_NATT
1529        /*
1530         * RFC3947 5.2. if we chose UDP-Encapsulated-Transport
1531         * we should send NAT-OA
1532         */
1533        if (ipsecdoi_transportmode(iph2->proposal)
1534         && (iph2->ph1->natt_flags & NAT_DETECTED)) {
1535                natoa = iph2->ph1->natt_options->payload_nat_oa;
1536
1537                nat_oai = ipsecdoi_sockaddr2id(iph2->dst,
1538                        IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
1539                nat_oar = ipsecdoi_sockaddr2id(iph2->src,
1540                        IPSECDOI_PREFIX_HOST, IPSEC_ULPROTO_ANY);
1541
1542                if (nat_oai == NULL || nat_oar == NULL) {
1543                        plog(LLV_ERROR, LOCATION, NULL,
1544                                "failed to generate NAT-OA payload.\n");
1545                        goto end;
1546                }
1547
1548                plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAi:\n");
1549                plogdump(LLV_DEBUG, nat_oai->v, nat_oai->l);
1550                plog(LLV_DEBUG, LOCATION, NULL, "NAT-OAr:\n");
1551                plogdump(LLV_DEBUG, nat_oar->v, nat_oar->l);
1552        }
1553#endif
1554
1555        /* create SA;NONCE payload, and KE and ID if need */
1556        tlen = sizeof(*gen) + iph2->sa_ret->l
1557                + sizeof(*gen) + iph2->nonce->l;
1558        if (iph2->dhpub_p != NULL && pfsgroup != 0)
1559                tlen += (sizeof(*gen) + iph2->dhpub->l);
1560        if (iph2->id_p != NULL)
1561                tlen += (sizeof(*gen) + iph2->id_p->l
1562                        + sizeof(*gen) + iph2->id->l);
1563#ifdef ENABLE_NATT
1564        if (natoa != ISAKMP_NPTYPE_NONE)
1565                tlen += 2 * sizeof(*gen) + nat_oai->l + nat_oar->l;
1566#endif
1567
1568        body = vmalloc(tlen);
1569        if (body == NULL) { 
1570                plog(LLV_ERROR, LOCATION, NULL,
1571                        "failed to get buffer to send.\n");
1572                goto end;
1573        }
1574        p = body->v;
1575
1576        /* make SA payload */ 
1577        p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE);
1578
1579        /* add NONCE payload */
1580        np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
1581        p = set_isakmp_payload(p, iph2->nonce,
1582                (iph2->dhpub_p != NULL && pfsgroup != 0)
1583                                ? ISAKMP_NPTYPE_KE
1584                                : (iph2->id_p != NULL
1585                                        ? ISAKMP_NPTYPE_ID
1586                                        : natoa));
1587
1588        /* add KE payload if need. */
1589        if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1590                np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
1591                p = set_isakmp_payload(p, iph2->dhpub,
1592                        (iph2->id_p == NULL)
1593                                ? natoa
1594                                : ISAKMP_NPTYPE_ID);
1595        }
1596
1597        /* add ID payloads received. */
1598        if (iph2->id_p != NULL) {
1599                /* IDci */
1600                p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
1601                /* IDcr */
1602                np_p = &((struct isakmp_gen *)p)->np;   /* XXX */
1603                p = set_isakmp_payload(p, iph2->id, natoa);
1604        }
1605
1606#ifdef ENABLE_NATT
1607        /* NAT-OA */
1608        if (natoa != ISAKMP_NPTYPE_NONE) {
1609                p = set_isakmp_payload(p, nat_oai, natoa);
1610                p = set_isakmp_payload(p, nat_oar, ISAKMP_NPTYPE_NONE);
1611        }
1612#endif
1613
1614        /* add a RESPONDER-LIFETIME notify payload if needed */
1615    {
1616        vchar_t *data = NULL;
1617        struct saprop *pp = iph2->approval;
1618        struct saproto *pr;
1619
1620        if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) {
1621                u_int32_t v = htonl((u_int32_t)pp->lifetime);
1622                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1623                                        IPSECDOI_ATTR_SA_LD_TYPE_SEC);
1624                if (!data)
1625                        goto end;
1626                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1627                                        (caddr_t)&v, sizeof(v));
1628                if (!data)
1629                        goto end;
1630        }
1631        if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
1632                u_int32_t v = htonl((u_int32_t)pp->lifebyte);
1633                data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1634                                        IPSECDOI_ATTR_SA_LD_TYPE_KB);
1635                if (!data)
1636                        goto end;
1637                data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1638                                        (caddr_t)&v, sizeof(v));
1639                if (!data)
1640                        goto end;
1641        }
1642
1643        /*
1644         * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1645         * in the case of SA bundle ?
1646         */
1647        if (data) {
1648                for (pr = pp->head; pr; pr = pr->next) {
1649                        body = isakmp_add_pl_n(body, &np_p,
1650                                        ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
1651                        if (!body) {
1652                                vfree(data);
1653                                return error;   /* XXX */
1654                        }
1655                }
1656                vfree(data);
1657        }
1658    }
1659
1660        /* generate HASH(2) */
1661    {
1662        vchar_t *tmp;
1663
1664        tmp = vmalloc(iph2->nonce_p->l + body->l);
1665        if (tmp == NULL) { 
1666                plog(LLV_ERROR, LOCATION, NULL,
1667                        "failed to get hash buffer.\n");
1668                goto end;
1669        }
1670        memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1671        memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l);
1672
1673        hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
1674        vfree(tmp);
1675
1676        if (hash == NULL)
1677                goto end;
1678    }
1679
1680        /* send isakmp payload */
1681        iph2->sendbuf = quick_ir1mx(iph2, body, hash);
1682        if (iph2->sendbuf == NULL)
1683                goto end;
1684
1685        /* send the packet, add to the schedule to resend */
1686        if (isakmp_ph2send(iph2) == -1)
1687                goto end;
1688
1689        /* the sending message is added to the received-list. */
1690        if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) {
1691                plog(LLV_ERROR , LOCATION, NULL,
1692                        "failed to add a response packet to the tree.\n");
1693                goto end;
1694        }
1695
1696        /* change status of isakmp status entry */
1697        iph2->status = PHASE2ST_MSG1SENT;
1698
1699        error = 0;
1700
1701end:
1702        if (body != NULL)
1703                vfree(body);
1704        if (hash != NULL)
1705                vfree(hash);
1706#ifdef ENABLE_NATT
1707        if (nat_oai != NULL)
1708                vfree(nat_oai);
1709        if (nat_oar != NULL)
1710                vfree(nat_oar);
1711#endif
1712
1713        return error;
1714}
1715
1716/*
1717 * receive from initiator
1718 *      HDR*, HASH(3)
1719
1720 */
1721int
1722quick_r3recv(iph2, msg0)
1723        struct ph2handle *iph2;
1724        vchar_t *msg0;
1725{
1726        vchar_t *msg = NULL;
1727        vchar_t *pbuf = NULL;   /* for payload parsing */
1728        struct isakmp_parse_t *pa;
1729        struct isakmp_pl_hash *hash = NULL;
1730        int error = ISAKMP_INTERNAL_ERROR;
1731
1732        /* validity check */
1733        if (iph2->status != PHASE2ST_MSG1SENT) {
1734                plog(LLV_ERROR, LOCATION, NULL,
1735                        "status mismatched %d.\n", iph2->status);
1736                goto end;
1737        }
1738
1739        /* decrypt packet */
1740        if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1741                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1742                        "Packet wasn't encrypted.\n");
1743                goto end;
1744        }
1745        msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
1746        if (msg == NULL)
1747                goto end;
1748
1749        /* validate the type of next payload */
1750        pbuf = isakmp_parse(msg);
1751        if (pbuf == NULL)
1752                goto end;
1753
1754        for (pa = (struct isakmp_parse_t *)pbuf->v;
1755             pa->type != ISAKMP_NPTYPE_NONE;
1756             pa++) {
1757
1758                switch (pa->type) {
1759                case ISAKMP_NPTYPE_HASH:
1760                        hash = (struct isakmp_pl_hash *)pa->ptr;
1761                        break;
1762                case ISAKMP_NPTYPE_N:
1763                        ph2_recv_n(iph2, pa->ptr);
1764                        break;
1765                default:
1766                        /* don't send information, see ident_r1recv() */
1767                        plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1768                                "ignore the packet, "
1769                                "received unexpecting payload type %d.\n",
1770                                pa->type);
1771                        goto end;
1772                }
1773        }
1774
1775        /* payload existency check */
1776        if (hash == NULL) {
1777                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1778                        "few isakmp message received.\n");
1779                goto end;
1780        }
1781
1782        /* validate HASH(3) */
1783        /* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1784    {
1785        char *r_hash;
1786        vchar_t *my_hash = NULL;
1787        vchar_t *tmp = NULL;
1788        int result;
1789
1790        r_hash = (char *)hash + sizeof(*hash);
1791
1792        plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:");
1793        plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
1794
1795        tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l);
1796        if (tmp == NULL) { 
1797                plog(LLV_ERROR, LOCATION, NULL,
1798                        "failed to get hash buffer.\n");
1799                goto end;
1800        }
1801        memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1802        memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l);
1803
1804        my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
1805        vfree(tmp);
1806        if (my_hash == NULL)
1807                goto end;
1808
1809        result = memcmp(my_hash->v, r_hash, my_hash->l);
1810        vfree(my_hash);
1811
1812        if (result) {
1813                plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1814                        "HASH(3) mismatch.\n");
1815                error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1816                goto end;
1817        }
1818    }
1819
1820        /* if there is commit bit, don't set up SA now. */
1821        if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
1822                iph2->status = PHASE2ST_COMMIT;
1823        } else
1824                iph2->status = PHASE2ST_STATUS6;
1825
1826        error = 0;
1827
1828end:
1829        if (pbuf != NULL)
1830                vfree(pbuf);
1831        if (msg != NULL)
1832                vfree(msg);
1833
1834        return error;
1835}
1836
1837/*
1838 * send to initiator
1839 *      HDR#*, HASH(4), notify
1840 */
1841int
1842quick_r3send(iph2, msg0)
1843        struct ph2handle *iph2;
1844        vchar_t *msg0;
1845{
1846        vchar_t *buf = NULL;
1847        vchar_t *myhash = NULL;
1848        struct isakmp_pl_n *n;
1849        vchar_t *notify = NULL;
1850        char *p;
1851        int tlen;
1852        int error = ISAKMP_INTERNAL_ERROR;
1853
1854        /* validity check */
1855        if (iph2->status != PHASE2ST_COMMIT) {
1856                plog(LLV_ERROR, LOCATION, NULL,
1857                        "status mismatched %d.\n", iph2->status);
1858                goto end;
1859        }
1860
1861        /* generate HASH(4) */
1862        /* XXX What can I do in the case of multiple different SA */
1863        plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n");
1864
1865        /* XXX What should I do if there are multiple SAs ? */
1866        tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
1867        notify = vmalloc(tlen);
1868        if (notify == NULL) { 
1869                plog(LLV_ERROR, LOCATION, NULL,
1870                        "failed to get notify buffer.\n");
1871                goto end;
1872        }
1873        n = (struct isakmp_pl_n *)notify->v;
1874        n->h.np = ISAKMP_NPTYPE_NONE;
1875        n->h.len = htons(tlen);
1876        n->doi = htonl(IPSEC_DOI);
1877        n->proto_id = iph2->approval->head->proto_id;
1878        n->spi_size = sizeof(iph2->approval->head->spisize);
1879        n->type = htons(ISAKMP_NTYPE_CONNECTED);
1880        memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
1881
1882        myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1883        if (myhash == NULL)
1884                goto end;
1885
1886        /* create buffer for isakmp payload */
1887        tlen = sizeof(struct isakmp)
1888                + sizeof(struct isakmp_gen) + myhash->l
1889                + notify->l;
1890        buf = vmalloc(tlen);
1891        if (buf == NULL) { 
1892                plog(LLV_ERROR, LOCATION, NULL,
1893                        "failed to get buffer to send.\n");
1894                goto end;
1895        }
1896
1897        /* create isakmp header */
1898        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1899        if (p == NULL)
1900                goto end;
1901
1902        /* add HASH(4) payload */
1903        p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
1904
1905        /* add notify payload */
1906        memcpy(p, notify->v, notify->l);
1907
1908#ifdef HAVE_PRINT_ISAKMP_C
1909        isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1910#endif
1911
1912        /* encoding */
1913        iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1914        if (iph2->sendbuf == NULL)
1915                goto end;
1916
1917        /* send the packet */
1918        if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
1919                goto end;
1920
1921        /* the sending message is added to the received-list. */
1922        if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) {
1923                plog(LLV_ERROR , LOCATION, NULL,
1924                        "failed to add a response packet to the tree.\n");
1925                goto end;
1926        }
1927
1928        iph2->status = PHASE2ST_COMMIT;
1929
1930        error = 0;
1931
1932end:
1933        if (buf != NULL)
1934                vfree(buf);
1935        if (myhash != NULL)
1936                vfree(myhash);
1937        if (notify != NULL)
1938                vfree(notify);
1939
1940        return error;
1941}
1942
1943int
1944tunnel_mode_prop(p)
1945        struct saprop *p;
1946{
1947        struct saproto *pr;
1948
1949        for (pr = p->head; pr; pr = pr->next)
1950                if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL)
1951                        return 1;
1952        return 0;
1953}
1954
1955/*
1956 * set SA to kernel.
1957 */
1958int
1959quick_r3prep(iph2, msg0)
1960        struct ph2handle *iph2;
1961        vchar_t *msg0;
1962{
1963        int error = ISAKMP_INTERNAL_ERROR;
1964
1965        /* validity check */
1966        if (iph2->status != PHASE2ST_STATUS6) {
1967                plog(LLV_ERROR, LOCATION, NULL,
1968                        "status mismatched %d.\n", iph2->status);
1969                goto end;
1970        }
1971
1972        /* compute both of KEYMATs */
1973        if (oakley_compute_keymat(iph2, RESPONDER) < 0)
1974                goto end;
1975
1976        iph2->status = PHASE2ST_ADDSA;
1977        iph2->flags ^= ISAKMP_FLAG_C;   /* reset bit */
1978
1979        /* don't anything if local test mode. */
1980        if (f_local) {
1981                error = 0;
1982                goto end;
1983        }
1984
1985        /* Do UPDATE as responder */
1986        plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
1987        if (pk_sendupdate(iph2) < 0) {
1988                plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
1989                goto end;
1990        }
1991        plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
1992
1993        /* Do ADD for responder */
1994        if (pk_sendadd(iph2) < 0) {
1995                plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
1996                goto end;
1997        }
1998        plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
1999
2000        /*
2001         * set policies into SPD if the policy is generated
2002         * from peer's policy.
2003         */
2004        if (iph2->spidx_gen) {
2005
2006                struct policyindex *spidx;
2007                struct sockaddr_storage addr;
2008                u_int8_t pref;
2009                struct sockaddr *src = iph2->src;
2010                struct sockaddr *dst = iph2->dst;
2011
2012                /* make inbound policy */
2013                iph2->src = dst;
2014                iph2->dst = src;
2015                if (pk_sendspdupdate2(iph2) < 0) {
2016                        plog(LLV_ERROR, LOCATION, NULL,
2017                                "pfkey spdupdate2(inbound) failed.\n");
2018                        goto end;
2019                }
2020                plog(LLV_DEBUG, LOCATION, NULL,
2021                        "pfkey spdupdate2(inbound) sent.\n");
2022
2023                spidx = (struct policyindex *)iph2->spidx_gen;
2024#ifdef HAVE_POLICY_FWD
2025                /* make forward policy if required */
2026                if (tunnel_mode_prop(iph2->approval)) {
2027                        spidx->dir = IPSEC_DIR_FWD;
2028                        if (pk_sendspdupdate2(iph2) < 0) {
2029                                plog(LLV_ERROR, LOCATION, NULL,
2030                                        "pfkey spdupdate2(forward) failed.\n");
2031                                goto end;
2032                        }
2033                        plog(LLV_DEBUG, LOCATION, NULL,
2034                                "pfkey spdupdate2(forward) sent.\n");
2035                }
2036#endif
2037
2038                /* make outbound policy */
2039                iph2->src = src;
2040                iph2->dst = dst;
2041                spidx->dir = IPSEC_DIR_OUTBOUND;
2042                addr = spidx->src;
2043                spidx->src = spidx->dst;
2044                spidx->dst = addr;
2045                pref = spidx->prefs;
2046                spidx->prefs = spidx->prefd;
2047                spidx->prefd = pref;
2048
2049                if (pk_sendspdupdate2(iph2) < 0) {
2050                        plog(LLV_ERROR, LOCATION, NULL,
2051                                "pfkey spdupdate2(outbound) failed.\n");
2052                        goto end;
2053                }
2054                plog(LLV_DEBUG, LOCATION, NULL,
2055                        "pfkey spdupdate2(outbound) sent.\n");
2056
2057                /* spidx_gen is unnecessary any more */
2058                delsp_bothdir((struct policyindex *)iph2->spidx_gen);
2059                racoon_free(iph2->spidx_gen);
2060                iph2->spidx_gen = NULL;
2061                iph2->generated_spidx=1;
2062        }
2063
2064        error = 0;
2065
2066end:
2067        return error;
2068}
2069
2070/*
2071 * create HASH, body (SA, NONCE) payload with isakmp header.
2072 */
2073static vchar_t *
2074quick_ir1mx(iph2, body, hash)
2075        struct ph2handle *iph2;
2076        vchar_t *body, *hash;
2077{
2078        struct isakmp *isakmp;
2079        vchar_t *buf = NULL, *new = NULL;
2080        char *p;
2081        int tlen;
2082        struct isakmp_gen *gen;
2083        int error = ISAKMP_INTERNAL_ERROR;
2084
2085        /* create buffer for isakmp payload */
2086        tlen = sizeof(*isakmp)
2087                + sizeof(*gen) + hash->l
2088                + body->l;
2089        buf = vmalloc(tlen);
2090        if (buf == NULL) { 
2091                plog(LLV_ERROR, LOCATION, NULL,
2092                        "failed to get buffer to send.\n");
2093                goto end;
2094        }
2095
2096        /* re-set encryption flag, for serurity. */
2097        iph2->flags |= ISAKMP_FLAG_E;
2098
2099        /* set isakmp header */
2100        p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
2101        if (p == NULL)
2102                goto end;
2103
2104        /* add HASH payload */
2105        /* XXX is next type always SA ? */
2106        p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA);
2107
2108        /* add body payload */
2109        memcpy(p, body->v, body->l);
2110
2111#ifdef HAVE_PRINT_ISAKMP_C
2112        isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
2113#endif
2114
2115        /* encoding */
2116        new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
2117       
2118        if (new == NULL)
2119                goto end;
2120
2121        vfree(buf);
2122
2123        buf = new;
2124
2125        error = 0;
2126
2127end:
2128        if (error && buf != NULL) {
2129                vfree(buf);
2130                buf = NULL;
2131        }
2132
2133        return buf;
2134}
2135
2136/*
2137 * get remote's sainfo.
2138 * NOTE: this function is for responder.
2139 */
2140static int
2141get_sainfo_r(iph2)
2142        struct ph2handle *iph2;
2143{
2144        vchar_t *idsrc = NULL, *iddst = NULL, *client = NULL;
2145        int error = ISAKMP_INTERNAL_ERROR;
2146
2147        if (iph2->id == NULL) {
2148                idsrc = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST,
2149                                        IPSEC_ULPROTO_ANY);
2150        } else {
2151                idsrc = vdup(iph2->id);
2152        }
2153        if (idsrc == NULL) {
2154                plog(LLV_ERROR, LOCATION, NULL,
2155                        "failed to set ID for source.\n");
2156                goto end;
2157        }
2158
2159        if (iph2->id_p == NULL) {
2160                iddst = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
2161                                        IPSEC_ULPROTO_ANY);
2162        } else {
2163                iddst = vdup(iph2->id_p);
2164        }
2165        if (iddst == NULL) {
2166                plog(LLV_ERROR, LOCATION, NULL,
2167                        "failed to set ID for destination.\n");
2168                goto end;
2169        }
2170
2171#ifdef ENABLE_HYBRID
2172
2173        /* clientaddr check : obtain modecfg address */
2174        if (iph2->ph1->mode_cfg != NULL) {
2175                if ((iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2176                    (iph2->ph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)){
2177                        struct sockaddr saddr;
2178                        saddr.sa_family = AF_INET;
2179#ifndef __linux__
2180                        saddr.sa_len = sizeof(struct sockaddr_in);
2181#endif
2182                        ((struct sockaddr_in *)&saddr)->sin_port = IPSEC_PORT_ANY;
2183                        memcpy(&((struct sockaddr_in *)&saddr)->sin_addr, 
2184                                &iph2->ph1->mode_cfg->addr4, sizeof(struct in_addr));
2185                        client = ipsecdoi_sockaddr2id(&saddr, 32, IPSEC_ULPROTO_ANY);
2186                }
2187        }
2188
2189        /* clientaddr check, fallback to peer address */
2190        if (client == NULL)
2191        {
2192                client = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
2193                                        IPSEC_ULPROTO_ANY);
2194        }
2195#endif
2196
2197        /* obtain a matching sainfo section */
2198        iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p, client, iph2->ph1->rmconf->ph1id);
2199        if (iph2->sainfo == NULL) {
2200                plog(LLV_ERROR, LOCATION, NULL,
2201                        "failed to get sainfo.\n");
2202                goto end;
2203        }
2204
2205#ifdef ENABLE_HYBRID
2206        /* xauth group inclusion check */
2207        if (iph2->sainfo->group != NULL)
2208                if(group_check(iph2->ph1,&iph2->sainfo->group->v,1))
2209                        goto end;
2210#endif
2211
2212        plog(LLV_DEBUG, LOCATION, NULL,
2213                "selected sainfo: %s\n", sainfo2str(iph2->sainfo));
2214
2215        error = 0;
2216end:
2217        if (idsrc)
2218                vfree(idsrc);
2219        if (iddst)
2220                vfree(iddst);
2221        if (client)
2222                vfree(client);
2223
2224        return error;
2225}
2226
2227/*
2228 * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
2229 * are IP address and same address family.
2230 * Then get remote's policy from SPD copied from kernel.
2231 * If the type of ID payload is address or subnet type, then the index is
2232 * made from the payload.  If there is no ID payload, or the type of ID
2233 * payload is NOT address type, then the index is made from the address
2234 * pair of phase 1.
2235 * NOTE: This function is only for responder.
2236 */
2237static int
2238get_proposal_r(iph2)
2239        struct ph2handle *iph2;
2240{
2241        struct policyindex spidx;
2242        struct secpolicy *sp_in, *sp_out;
2243        int idi2type = 0;       /* switch whether copy IDs into id[src,dst]. */
2244        int error = ISAKMP_INTERNAL_ERROR;
2245
2246        /* check the existence of ID payload */
2247        if ((iph2->id_p != NULL && iph2->id == NULL)
2248         || (iph2->id_p == NULL && iph2->id != NULL)) {
2249                plog(LLV_ERROR, LOCATION, NULL,
2250                        "Both IDs wasn't found in payload.\n");
2251                return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
2252        }
2253
2254        /* make sure if sa_[src, dst] are null. */
2255        if (iph2->sa_src || iph2->sa_dst) {
2256                plog(LLV_ERROR, LOCATION, NULL,
2257                        "Why do ID[src,dst] exist already.\n");
2258                return ISAKMP_INTERNAL_ERROR;
2259        }
2260
2261        memset(&spidx, 0, sizeof(spidx));
2262
2263#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
2264
2265        /* make a spidx; a key to search SPD */
2266        spidx.dir = IPSEC_DIR_INBOUND;
2267        spidx.ul_proto = 0;
2268
2269        /*
2270         * make destination address in spidx from either ID payload
2271         * or phase 1 address into a address in spidx.
2272         */
2273        if (iph2->id != NULL
2274         && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
2275          || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
2276          || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2277          || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2278                /* get a destination address of a policy */
2279                error = ipsecdoi_id2sockaddr(iph2->id,
2280                                (struct sockaddr *)&spidx.dst,
2281                                &spidx.prefd, &spidx.ul_proto);
2282                if (error)
2283                        return error;
2284
2285#ifdef INET6
2286                /*
2287                 * get scopeid from the SA address.
2288                 * note that the phase 1 source address is used as
2289                 * a destination address to search for a inbound policy entry
2290                 * because rcoon is responder.
2291                 */
2292                if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
2293                        error = setscopeid((struct sockaddr *)&spidx.dst,
2294                                            iph2->src);
2295                        if (error)
2296                                return error;
2297                }
2298#endif
2299
2300                if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
2301                 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
2302                        idi2type = _XIDT(iph2->id);
2303
2304        } else {
2305
2306                plog(LLV_DEBUG, LOCATION, NULL,
2307                        "get a destination address of SP index "
2308                        "from phase1 address "
2309                        "due to no ID payloads found "
2310                        "OR because ID type is not address.\n");
2311
2312                /*
2313                 * copy the SOURCE address of IKE into the DESTINATION address
2314                 * of the key to search the SPD because the direction of policy
2315                 * is inbound.
2316                 */
2317                memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
2318                switch (spidx.dst.ss_family) {
2319                case AF_INET:
2320                        spidx.prefd = sizeof(struct in_addr) << 3;
2321                        break;
2322#ifdef INET6
2323                case AF_INET6:
2324                        spidx.prefd = sizeof(struct in6_addr) << 3;
2325                        break;
2326#endif
2327                default:
2328                        spidx.prefd = 0;
2329                        break;
2330                }
2331        }
2332
2333        /* make source address in spidx */
2334        if (iph2->id_p != NULL
2335         && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
2336          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
2337          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
2338          || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
2339                /* get a source address of inbound SA */
2340                error = ipsecdoi_id2sockaddr(iph2->id_p,
2341                                (struct sockaddr *)&spidx.src,
2342                                &spidx.prefs, &spidx.ul_proto);
2343                if (error)
2344                        return error;
2345
2346#ifdef INET6
2347                /*
2348                 * get scopeid from the SA address.
2349                 * for more detail, see above of this function.
2350                 */
2351                if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
2352                        error = setscopeid((struct sockaddr *)&spidx.src,
2353                                            iph2->dst);
2354                        if (error)
2355                                return error;
2356                }
2357#endif
2358
2359                /* Before setting iph2->[sa_src, sa_dst] with the addresses
2360                 * provided in ID payloads, we check:
2361                 * - they are both addresses of same family
2362                 * - sainfo has not been selected only based on ID payload
2363                 *   information but also based on specific Phase 1
2364                 *   credentials (iph2->sainfo->id_i is defined), i.e.
2365                 *   local configuration _explicitly_ expect that user
2366                 *   (e.g. from asn1dn "C=FR, ...") with those IDs) */
2367                if (_XIDT(iph2->id_p) == idi2type &&
2368                    spidx.dst.ss_family == spidx.src.ss_family &&
2369                    iph2->sainfo && iph2->sainfo->id_i) {
2370
2371                        iph2->sa_src = dupsaddr((struct sockaddr *)&spidx.dst);
2372                        if (iph2->sa_src  == NULL) {
2373                                plog(LLV_ERROR, LOCATION, NULL,
2374                                    "buffer allocation failed.\n");
2375                                return ISAKMP_INTERNAL_ERROR;
2376                        }
2377
2378                        iph2->sa_dst = dupsaddr((struct sockaddr *)&spidx.src);
2379                        if (iph2->sa_dst  == NULL) {
2380                                plog(LLV_ERROR, LOCATION, NULL,
2381                                    "buffer allocation failed.\n");
2382                                return ISAKMP_INTERNAL_ERROR;
2383                        }
2384                } else {
2385                        plog(LLV_DEBUG, LOCATION, NULL,
2386                             "Either family (%d - %d), types (%d - %d) of ID "
2387                             "from initiator differ or matching sainfo "
2388                             "has no id_i defined for the peer. Not filling "
2389                             "iph2->sa_src and iph2->sa_dst.\n",
2390                             spidx.src.ss_family, spidx.dst.ss_family,
2391                             _XIDT(iph2->id_p),idi2type);
2392                }
2393#ifdef ENABLE_NATT
2394                if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
2395                        u_int16_t port;
2396
2397                        port = extract_port(&spidx.src);
2398                        memcpy(&spidx.src, iph2->ph1->remote,
2399                            sysdep_sa_len(iph2->ph1->remote));
2400                        set_port(&spidx.src, port);
2401                        switch (spidx.src.ss_family) {
2402                        case AF_INET:
2403                                spidx.prefs = sizeof(struct in_addr) << 3;
2404                                break;
2405#ifdef INET6
2406                        case AF_INET6:
2407                                spidx.prefs = sizeof(struct in6_addr) << 3;
2408                                break;
2409#endif
2410                        default:
2411                                spidx.prefs = 0;
2412                                break;
2413                        }
2414                        plog(LLV_DEBUG, LOCATION,
2415                                NULL, "use NAT address %s as src\n",
2416                                saddr2str((struct sockaddr *)&spidx.src));
2417                }
2418#endif
2419        } else {
2420                plog(LLV_DEBUG, LOCATION, NULL,
2421                     "get a source address of SP index from Phase 1"
2422                     "addresses due to no ID payloads found"
2423                     "OR because ID type is not address.\n");
2424
2425                /* see above comment. */
2426                memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
2427                switch (spidx.src.ss_family) {
2428                case AF_INET:
2429                        spidx.prefs = sizeof(struct in_addr) << 3;
2430                        break;
2431#ifdef INET6
2432                case AF_INET6:
2433                        spidx.prefs = sizeof(struct in6_addr) << 3;
2434                        break;
2435#endif
2436                default:
2437                        spidx.prefs = 0;
2438                        break;
2439                }
2440        }
2441
2442#undef _XIDT
2443
2444        plog(LLV_DEBUG, LOCATION, NULL,
2445                "get src address from ID payload "
2446                "%s prefixlen=%u ul_proto=%u\n",
2447                saddr2str((struct sockaddr *)&spidx.src),
2448                spidx.prefs, spidx.ul_proto);
2449        plog(LLV_DEBUG, LOCATION, NULL,
2450                "get dst address from ID payload "
2451                "%s prefixlen=%u ul_proto=%u\n",
2452                saddr2str((struct sockaddr *)&spidx.dst),
2453                spidx.prefd, spidx.ul_proto);
2454
2455        /*
2456         * convert the ul_proto if it is 0
2457         * because 0 in ID payload means a wild card.
2458         */
2459        if (spidx.ul_proto == 0)
2460                spidx.ul_proto = IPSEC_ULPROTO_ANY;
2461
2462#ifdef HAVE_SECCTX
2463        /*
2464         * Need to use security context in spidx to ensure the correct
2465         * policy is selected. The only way to get the security context
2466         * is to look into the proposal sent by peer ahead of time.
2467         */
2468        if (get_security_context(iph2->sa, &spidx)) {
2469                plog(LLV_ERROR, LOCATION, NULL,
2470                     "error occurred trying to get security context.\n");
2471                return ISAKMP_INTERNAL_ERROR;
2472        }
2473#endif /* HAVE_SECCTX */
2474
2475        /* get inbound policy */
2476        sp_in = getsp_r(&spidx);
2477        if (sp_in == NULL) {
2478                if (iph2->ph1->rmconf->gen_policy) {
2479                        plog(LLV_INFO, LOCATION, NULL,
2480                                "no policy found, "
2481                                "try to generate the policy : %s\n",
2482                                spidx2str(&spidx));
2483                        iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2484                        if (!iph2->spidx_gen) {
2485                                plog(LLV_ERROR, LOCATION, NULL,
2486                                        "buffer allocation failed.\n");
2487                                return ISAKMP_INTERNAL_ERROR;
2488                        }
2489                        memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2490                        return -2;      /* special value */
2491                }
2492                plog(LLV_ERROR, LOCATION, NULL,
2493                        "no policy found: %s\n", spidx2str(&spidx));
2494                return ISAKMP_INTERNAL_ERROR;
2495        }
2496        /* Refresh existing generated policies
2497         */
2498        if (iph2->ph1->rmconf->gen_policy) {
2499                plog(LLV_INFO, LOCATION, NULL,
2500                         "Update the generated policy : %s\n",
2501                         spidx2str(&spidx));
2502                iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2503                if (!iph2->spidx_gen) {
2504                        plog(LLV_ERROR, LOCATION, NULL,
2505                                 "buffer allocation failed.\n");
2506                        return ISAKMP_INTERNAL_ERROR;
2507                }
2508                memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2509        }
2510
2511        /* get outbound policy */
2512    {
2513        struct sockaddr_storage addr;
2514        u_int8_t pref;
2515
2516        spidx.dir = IPSEC_DIR_OUTBOUND;
2517        addr = spidx.src;
2518        spidx.src = spidx.dst;
2519        spidx.dst = addr;
2520        pref = spidx.prefs;
2521        spidx.prefs = spidx.prefd;
2522        spidx.prefd = pref;
2523
2524        sp_out = getsp_r(&spidx);
2525        if (!sp_out) {
2526                plog(LLV_WARNING, LOCATION, NULL,
2527                        "no outbound policy found: %s\n",
2528                        spidx2str(&spidx));
2529        }
2530    }
2531
2532        plog(LLV_DEBUG, LOCATION, NULL,
2533                "suitable SP found:%s\n", spidx2str(&spidx));
2534
2535        /*
2536         * In the responder side, the inbound policy should be using IPsec.
2537         * outbound policy is not checked currently.
2538         */
2539        if (sp_in->policy != IPSEC_POLICY_IPSEC) {
2540                plog(LLV_ERROR, LOCATION, NULL,
2541                        "policy found, but no IPsec required: %s\n",
2542                        spidx2str(&spidx));
2543                return ISAKMP_INTERNAL_ERROR;
2544        }
2545
2546        /* set new proposal derived from a policy into the iph2->proposal. */
2547        if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
2548                plog(LLV_ERROR, LOCATION, NULL,
2549                        "failed to create saprop.\n");
2550                return ISAKMP_INTERNAL_ERROR;
2551        }
2552
2553#ifdef HAVE_SECCTX
2554        if (spidx.sec_ctx.ctx_str) {
2555                set_secctx_in_proposal(iph2, spidx);
2556        }
2557#endif /* HAVE_SECCTX */
2558
2559        iph2->spid = sp_in->id;
2560
2561        return 0;
2562}
2563
2564/*
2565 * handle a notification payload inside phase2 exchange.
2566 * phase2 is always encrypted, so it does not need to be checked
2567 * for explicitely.
2568 */
2569static int
2570ph2_recv_n(iph2, gen)
2571        struct ph2handle *iph2;
2572        struct isakmp_gen *gen;
2573{
2574        struct ph1handle *iph1 = iph2->ph1;
2575        struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen;
2576        u_int type;
2577        int check_level;
2578
2579        type = ntohs(notify->type);
2580        switch (type) {
2581        case ISAKMP_NTYPE_CONNECTED:
2582                break;
2583        case ISAKMP_NTYPE_INITIAL_CONTACT:
2584                return isakmp_info_recv_initialcontact(iph1, iph2);
2585        case ISAKMP_NTYPE_RESPONDER_LIFETIME:
2586                ipsecdoi_parse_responder_lifetime(notify,
2587                        &iph2->lifetime_secs, &iph2->lifetime_kb);
2588
2589                if (iph1 != NULL && iph1->rmconf != NULL) {
2590                        check_level = iph1->rmconf->pcheck_level;
2591                } else {
2592                        if (iph1 != NULL)
2593                                plog(LLV_DEBUG, LOCATION, NULL,
2594                                        "No phase1 rmconf found !\n");
2595                        else
2596                                plog(LLV_DEBUG, LOCATION, NULL,
2597                                        "No phase1 found !\n");
2598                        check_level = PROP_CHECK_EXACT;
2599                }
2600
2601                switch (check_level) {
2602                case PROP_CHECK_OBEY:
2603                        break;
2604                case PROP_CHECK_STRICT:
2605                case PROP_CHECK_CLAIM:
2606                        if (iph2->sainfo == NULL
2607                         || iph2->sainfo->lifetime <= iph2->lifetime_secs) {
2608                                plog(LLV_WARNING, LOCATION, NULL,
2609                                        "RESPONDER-LIFETIME: lifetime mismatch\n");
2610                                iph2->lifetime_secs = 0;
2611                        }
2612                        break;
2613                case PROP_CHECK_EXACT:
2614                        if (iph2->sainfo == NULL
2615                         || iph2->sainfo->lifetime != iph2->lifetime_secs) {
2616                                plog(LLV_WARNING, LOCATION, NULL,
2617                                        "RESPONDER-LIFETIME: lifetime mismatch\n");
2618                                iph2->lifetime_secs = 0;
2619                        }
2620                        break;
2621                }
2622                break;
2623        default:
2624                isakmp_log_notify(iph2->ph1, notify, "phase2 exchange");
2625                isakmp_info_send_n2(iph2, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE,
2626                        NULL);
2627                break;
2628        }
2629        return 0;
2630}
2631
Note: See TracBrowser for help on using the repository browser.