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