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