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