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 */
91static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
92static int get_sainfo_r __P((struct ph2handle *));
93static 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 */
101int
102quick_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
139end:
140	return error;
141}
142
143/*
144 * send to responder
145 * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
146 */
147int
148quick_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
296end:
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 */
309int
310quick_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
528end:
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 */
551int
552quick_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
675end:
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 */
690int
691quick_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
818end:
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 */
833int
834quick_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
1124end:
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 */
1146int
1147quick_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
1173end:
1174	return error;
1175}
1176
1177/*
1178 * send to initiator
1179 * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1180 */
1181int
1182quick_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
1369end:
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 */
1382int
1383quick_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
1489end:
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 */
1502int
1503quick_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
1593end:
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
1604int
1605tunnel_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 */
1619int
1620quick_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
1727end:
1728	return error;
1729}
1730
1731/*
1732 * create HASH, body (SA, NONCE) payload with isakmp header.
1733 */
1734static vchar_t *
1735quick_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
1788end:
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 */
1801static int
1802get_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;
1888end:
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 */
1907static int
1908get_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