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