1/*	$NetBSD: handler.c,v 1.9.6.8 2009/04/20 13:25:27 tteras Exp $	*/
2
3/* Id: handler.c,v 1.28 2006/05/26 12:17:29 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 <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43#include <time.h>
44#include <errno.h>
45
46#include "var.h"
47#include "misc.h"
48#include "vmbuf.h"
49#include "plog.h"
50#include "sockmisc.h"
51#include "debug.h"
52
53#ifdef ENABLE_HYBRID
54#include <resolv.h>
55#endif
56
57#include "schedule.h"
58#include "grabmyaddr.h"
59#include "algorithm.h"
60#include "crypto_openssl.h"
61#include "policy.h"
62#include "proposal.h"
63#include "isakmp_var.h"
64#include "evt.h"
65#include "isakmp.h"
66#ifdef ENABLE_HYBRID
67#include "isakmp_xauth.h"
68#include "isakmp_cfg.h"
69#endif
70#include "isakmp_inf.h"
71#include "oakley.h"
72#include "remoteconf.h"
73#include "localconf.h"
74#include "handler.h"
75#include "gcmalloc.h"
76#include "nattraversal.h"
77
78#include "sainfo.h"
79
80#ifdef HAVE_GSSAPI
81#include "gssapi.h"
82#endif
83
84static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
85static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
86static LIST_HEAD(_ctdtree_, contacted) ctdtree;
87static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
88
89static void del_recvdpkt __P((struct recvdpkt *));
90static void rem_recvdpkt __P((struct recvdpkt *));
91static void sweep_recvdpkt __P((void *));
92
93/*
94 * functions about management of the isakmp status table
95 */
96/* %%% management phase 1 handler */
97/*
98 * search for isakmpsa handler with isakmp index.
99 */
100
101extern caddr_t val2str(const char *, size_t);
102
103struct ph1handle *
104getph1byindex(index)
105	isakmp_index *index;
106{
107	struct ph1handle *p;
108
109	LIST_FOREACH(p, &ph1tree, chain) {
110		if (p->status == PHASE1ST_EXPIRED)
111			continue;
112		if (memcmp(&p->index, index, sizeof(*index)) == 0)
113			return p;
114	}
115
116	return NULL;
117}
118
119
120/*
121 * search for isakmp handler by i_ck in index.
122 */
123struct ph1handle *
124getph1byindex0(index)
125	isakmp_index *index;
126{
127	struct ph1handle *p;
128
129	LIST_FOREACH(p, &ph1tree, chain) {
130		if (p->status == PHASE1ST_EXPIRED)
131			continue;
132		if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
133			return p;
134	}
135
136	return NULL;
137}
138
139/*
140 * search for isakmpsa handler by source and remote address.
141 * don't use port number to search because this function search
142 * with phase 2's destinaion.
143 */
144struct ph1handle *
145getph1byaddr(local, remote, established)
146	struct sockaddr *local, *remote;
147	int established;
148{
149	struct ph1handle *p;
150
151	plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n");
152	plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local));
153	plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote));
154
155	LIST_FOREACH(p, &ph1tree, chain) {
156		if (p->status == PHASE1ST_EXPIRED)
157			continue;
158		plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local));
159		plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote));
160
161		if(established && p->status != PHASE1ST_ESTABLISHED){
162			plog(LLV_DEBUG2, LOCATION, NULL, "status %d, skipping\n", p->status);
163			continue;
164		}
165		if (CMPSADDR(local, p->local) == 0
166			&& CMPSADDR(remote, p->remote) == 0){
167			plog(LLV_DEBUG2, LOCATION, NULL, "matched\n");
168			return p;
169		}
170	}
171
172	plog(LLV_DEBUG2, LOCATION, NULL, "no match\n");
173
174	return NULL;
175}
176
177struct ph1handle *
178getph1byaddrwop(local, remote)
179	struct sockaddr *local, *remote;
180{
181	struct ph1handle *p;
182
183	LIST_FOREACH(p, &ph1tree, chain) {
184		if (p->status == PHASE1ST_EXPIRED)
185			continue;
186		if (cmpsaddrwop(local, p->local) == 0
187		 && cmpsaddrwop(remote, p->remote) == 0)
188			return p;
189	}
190
191	return NULL;
192}
193
194/*
195 * search for isakmpsa handler by remote address.
196 * don't use port number to search because this function search
197 * with phase 2's destinaion.
198 */
199struct ph1handle *
200getph1bydstaddrwop(remote)
201	struct sockaddr *remote;
202{
203	struct ph1handle *p;
204
205	LIST_FOREACH(p, &ph1tree, chain) {
206		if (p->status == PHASE1ST_EXPIRED)
207			continue;
208		if (cmpsaddrwop(remote, p->remote) == 0)
209			return p;
210	}
211
212	return NULL;
213}
214
215/*
216 * dump isakmp-sa
217 */
218vchar_t *
219dumpph1()
220{
221	struct ph1handle *iph1;
222	struct ph1dump *pd;
223	int cnt = 0;
224	vchar_t *buf;
225
226	/* get length of buffer */
227	LIST_FOREACH(iph1, &ph1tree, chain)
228		cnt++;
229
230	buf = vmalloc(cnt * sizeof(struct ph1dump));
231	if (buf == NULL) {
232		plog(LLV_ERROR, LOCATION, NULL,
233			"failed to get buffer\n");
234		return NULL;
235	}
236	pd = (struct ph1dump *)buf->v;
237
238	LIST_FOREACH(iph1, &ph1tree, chain) {
239		memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
240		pd->status = iph1->status;
241		pd->side = iph1->side;
242		memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
243		memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
244		pd->version = iph1->version;
245		pd->etype = iph1->etype;
246		pd->created = iph1->created;
247		pd->ph2cnt = iph1->ph2cnt;
248		pd++;
249	}
250
251	return buf;
252}
253
254/*
255 * create new isakmp Phase 1 status record to handle isakmp in Phase1
256 */
257struct ph1handle *
258newph1()
259{
260	struct ph1handle *iph1;
261
262	/* create new iph1 */
263	iph1 = racoon_calloc(1, sizeof(*iph1));
264	if (iph1 == NULL)
265		return NULL;
266
267	iph1->status = PHASE1ST_SPAWN;
268
269#ifdef ENABLE_DPD
270	iph1->dpd_support = 0;
271	iph1->dpd_lastack = 0;
272	iph1->dpd_seq = 0;
273	iph1->dpd_fails = 0;
274	iph1->dpd_r_u = NULL;
275#endif
276
277	return iph1;
278}
279
280/*
281 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
282 */
283void
284delph1(iph1)
285	struct ph1handle *iph1;
286{
287	if (iph1 == NULL)
288		return;
289
290	/* SA down shell script hook */
291	script_hook(iph1, SCRIPT_PHASE1_DOWN);
292
293	EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
294
295#ifdef ENABLE_NATT
296	if (iph1->natt_flags & NAT_KA_QUEUED)
297		natt_keepalive_remove (iph1->local, iph1->remote);
298
299	if (iph1->natt_options) {
300		racoon_free(iph1->natt_options);
301		iph1->natt_options = NULL;
302	}
303#endif
304
305#ifdef ENABLE_HYBRID
306	if (iph1->mode_cfg)
307		isakmp_cfg_rmstate(iph1);
308#endif
309
310#ifdef ENABLE_DPD
311	SCHED_KILL(iph1->dpd_r_u);
312#endif
313
314	if (iph1->remote) {
315		racoon_free(iph1->remote);
316		iph1->remote = NULL;
317	}
318	if (iph1->local) {
319		racoon_free(iph1->local);
320		iph1->local = NULL;
321	}
322	if (iph1->approval) {
323		delisakmpsa(iph1->approval);
324		iph1->approval = NULL;
325	}
326
327	VPTRINIT(iph1->authstr);
328
329	sched_scrub_param(iph1);
330	iph1->sce = NULL;
331	iph1->scr = NULL;
332
333	VPTRINIT(iph1->sendbuf);
334
335	VPTRINIT(iph1->dhpriv);
336	VPTRINIT(iph1->dhpub);
337	VPTRINIT(iph1->dhpub_p);
338	VPTRINIT(iph1->dhgxy);
339	VPTRINIT(iph1->nonce);
340	VPTRINIT(iph1->nonce_p);
341	VPTRINIT(iph1->skeyid);
342	VPTRINIT(iph1->skeyid_d);
343	VPTRINIT(iph1->skeyid_a);
344	VPTRINIT(iph1->skeyid_e);
345	VPTRINIT(iph1->key);
346	VPTRINIT(iph1->hash);
347	VPTRINIT(iph1->sig);
348	VPTRINIT(iph1->sig_p);
349	oakley_delcert(iph1->cert);
350	iph1->cert = NULL;
351	oakley_delcert(iph1->cert_p);
352	iph1->cert_p = NULL;
353	oakley_delcert(iph1->crl_p);
354	iph1->crl_p = NULL;
355	oakley_delcert(iph1->cr_p);
356	iph1->cr_p = NULL;
357	VPTRINIT(iph1->id);
358	VPTRINIT(iph1->id_p);
359
360	if(iph1->approval != NULL)
361		delisakmpsa(iph1->approval);
362
363	if (iph1->ivm) {
364		oakley_delivm(iph1->ivm);
365		iph1->ivm = NULL;
366	}
367
368	VPTRINIT(iph1->sa);
369	VPTRINIT(iph1->sa_ret);
370
371#ifdef HAVE_GSSAPI
372	VPTRINIT(iph1->gi_i);
373	VPTRINIT(iph1->gi_r);
374
375	gssapi_free_state(iph1);
376#endif
377
378	racoon_free(iph1);
379}
380
381/*
382 * create new isakmp Phase 1 status record to handle isakmp in Phase1
383 */
384int
385insph1(iph1)
386	struct ph1handle *iph1;
387{
388	/* validity check */
389	if (iph1->remote == NULL) {
390		plog(LLV_ERROR, LOCATION, NULL,
391			"invalid isakmp SA handler. no remote address.\n");
392		return -1;
393	}
394	LIST_INSERT_HEAD(&ph1tree, iph1, chain);
395
396	return 0;
397}
398
399void
400remph1(iph1)
401	struct ph1handle *iph1;
402{
403	LIST_REMOVE(iph1, chain);
404}
405
406/*
407 * flush isakmp-sa
408 */
409void
410flushph1()
411{
412	struct ph1handle *p, *next;
413
414	for (p = LIST_FIRST(&ph1tree); p; p = next) {
415		next = LIST_NEXT(p, chain);
416
417		/* send delete information */
418		if (p->status == PHASE1ST_ESTABLISHED)
419			isakmp_info_send_d1(p);
420
421		remph1(p);
422		delph1(p);
423	}
424}
425
426void
427initph1tree()
428{
429	LIST_INIT(&ph1tree);
430}
431
432/* %%% management phase 2 handler */
433/*
434 * search ph2handle with policy id.
435 */
436struct ph2handle *
437getph2byspid(spid)
438      u_int32_t spid;
439{
440	struct ph2handle *p;
441
442	LIST_FOREACH(p, &ph2tree, chain) {
443		/*
444		 * there are ph2handle independent on policy
445		 * such like informational exchange.
446		 */
447		if (p->spid == spid)
448			return p;
449	}
450
451	return NULL;
452}
453
454/*
455 * search ph2handle with sequence number.
456 */
457struct ph2handle *
458getph2byseq(seq)
459	u_int32_t seq;
460{
461	struct ph2handle *p;
462
463	LIST_FOREACH(p, &ph2tree, chain) {
464		if (p->seq == seq)
465			return p;
466	}
467
468	return NULL;
469}
470
471/*
472 * search ph2handle with message id.
473 */
474struct ph2handle *
475getph2bymsgid(iph1, msgid)
476	struct ph1handle *iph1;
477	u_int32_t msgid;
478{
479	struct ph2handle *p;
480
481	LIST_FOREACH(p, &ph2tree, chain) {
482		if (p->msgid == msgid && p->ph1 == iph1)
483			return p;
484	}
485
486	return NULL;
487}
488
489struct ph2handle *
490getph2byid(src, dst, spid)
491	struct sockaddr *src, *dst;
492	u_int32_t spid;
493{
494	struct ph2handle *p;
495
496	LIST_FOREACH(p, &ph2tree, chain) {
497		if (spid == p->spid &&
498		    CMPSADDR(src, p->src) == 0 &&
499		    CMPSADDR(dst, p->dst) == 0){
500			/* Sanity check to detect zombie handlers
501			 * XXX Sould be done "somewhere" more interesting,
502			 * because we have lots of getph2byxxxx(), but this one
503			 * is called by pk_recvacquire(), so is the most important.
504			 */
505			if(p->status < PHASE2ST_ESTABLISHED &&
506			   p->retry_counter == 0
507			   && p->sce == NULL && p->scr == NULL){
508				plog(LLV_DEBUG, LOCATION, NULL,
509					 "Zombie ph2 found, expiring it\n");
510				isakmp_ph2expire(p);
511			}else
512				return p;
513		}
514	}
515
516	return NULL;
517}
518
519struct ph2handle *
520getph2bysaddr(src, dst)
521	struct sockaddr *src, *dst;
522{
523	struct ph2handle *p;
524
525	LIST_FOREACH(p, &ph2tree, chain) {
526		if (cmpsaddrstrict(src, p->src) == 0 &&
527		    cmpsaddrstrict(dst, p->dst) == 0)
528			return p;
529	}
530
531	return NULL;
532}
533
534/*
535 * call by pk_recvexpire().
536 */
537struct ph2handle *
538getph2bysaidx(src, dst, proto_id, spi)
539	struct sockaddr *src, *dst;
540	u_int proto_id;
541	u_int32_t spi;
542{
543	struct ph2handle *iph2;
544	struct saproto *pr;
545
546	LIST_FOREACH(iph2, &ph2tree, chain) {
547		if (iph2->proposal == NULL && iph2->approval == NULL)
548			continue;
549		if (iph2->approval != NULL) {
550			for (pr = iph2->approval->head; pr != NULL;
551			     pr = pr->next) {
552				if (proto_id != pr->proto_id)
553					break;
554				if (spi == pr->spi || spi == pr->spi_p)
555					return iph2;
556			}
557		} else if (iph2->proposal != NULL) {
558			for (pr = iph2->proposal->head; pr != NULL;
559			     pr = pr->next) {
560				if (proto_id != pr->proto_id)
561					break;
562				if (spi == pr->spi)
563					return iph2;
564			}
565		}
566	}
567
568	return NULL;
569}
570
571/*
572 * create new isakmp Phase 2 status record to handle isakmp in Phase2
573 */
574struct ph2handle *
575newph2()
576{
577	struct ph2handle *iph2 = NULL;
578
579	/* create new iph2 */
580	iph2 = racoon_calloc(1, sizeof(*iph2));
581	if (iph2 == NULL)
582		return NULL;
583
584	iph2->status = PHASE1ST_SPAWN;
585
586	return iph2;
587}
588
589/*
590 * initialize ph2handle
591 * NOTE: don't initialize src/dst.
592 *       SPI in the proposal is cleared.
593 */
594void
595initph2(iph2)
596	struct ph2handle *iph2;
597{
598	sched_scrub_param(iph2);
599	iph2->sce = NULL;
600	iph2->scr = NULL;
601
602	VPTRINIT(iph2->sendbuf);
603	VPTRINIT(iph2->msg1);
604
605	/* clear spi, keep variables in the proposal */
606	if (iph2->proposal) {
607		struct saproto *pr;
608		for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
609			pr->spi = 0;
610	}
611
612	/* clear approval */
613	if (iph2->approval) {
614		flushsaprop(iph2->approval);
615		iph2->approval = NULL;
616	}
617
618	/* clear the generated policy */
619	if (iph2->spidx_gen) {
620		delsp_bothdir((struct policyindex *)iph2->spidx_gen);
621		racoon_free(iph2->spidx_gen);
622		iph2->spidx_gen = NULL;
623	}
624
625	if (iph2->pfsgrp) {
626		oakley_dhgrp_free(iph2->pfsgrp);
627		iph2->pfsgrp = NULL;
628	}
629
630	VPTRINIT(iph2->dhpriv);
631	VPTRINIT(iph2->dhpub);
632	VPTRINIT(iph2->dhpub_p);
633	VPTRINIT(iph2->dhgxy);
634	VPTRINIT(iph2->id);
635	VPTRINIT(iph2->id_p);
636	VPTRINIT(iph2->nonce);
637	VPTRINIT(iph2->nonce_p);
638	VPTRINIT(iph2->sa);
639	VPTRINIT(iph2->sa_ret);
640
641	if (iph2->ivm) {
642		oakley_delivm(iph2->ivm);
643		iph2->ivm = NULL;
644	}
645}
646
647/*
648 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
649 */
650void
651delph2(iph2)
652	struct ph2handle *iph2;
653{
654	initph2(iph2);
655
656	if (iph2->src) {
657		racoon_free(iph2->src);
658		iph2->src = NULL;
659	}
660	if (iph2->dst) {
661		racoon_free(iph2->dst);
662		iph2->dst = NULL;
663	}
664	if (iph2->src_id) {
665	      racoon_free(iph2->src_id);
666	      iph2->src_id = NULL;
667	}
668	if (iph2->dst_id) {
669	      racoon_free(iph2->dst_id);
670	      iph2->dst_id = NULL;
671	}
672
673	if (iph2->proposal) {
674		flushsaprop(iph2->proposal);
675		iph2->proposal = NULL;
676	}
677
678	racoon_free(iph2);
679}
680
681/*
682 * create new isakmp Phase 2 status record to handle isakmp in Phase2
683 */
684int
685insph2(iph2)
686	struct ph2handle *iph2;
687{
688	LIST_INSERT_HEAD(&ph2tree, iph2, chain);
689
690	return 0;
691}
692
693void
694remph2(iph2)
695	struct ph2handle *iph2;
696{
697	LIST_REMOVE(iph2, chain);
698}
699
700void
701initph2tree()
702{
703	LIST_INIT(&ph2tree);
704}
705
706void
707flushph2()
708{
709	struct ph2handle *p, *next;
710
711	plog(LLV_DEBUG2, LOCATION, NULL,
712		 "flushing all ph2 handlers...\n");
713
714	for (p = LIST_FIRST(&ph2tree); p; p = next) {
715		next = LIST_NEXT(p, chain);
716
717		/* send delete information */
718		if (p->status == PHASE2ST_ESTABLISHED){
719			plog(LLV_DEBUG2, LOCATION, NULL,
720				 "got a ph2 handler to flush...\n");
721			isakmp_info_send_d2(p);
722		}else{
723			plog(LLV_DEBUG2, LOCATION, NULL,
724				 "skipping ph2 handler (state %d)\n", p->status);
725		}
726
727		delete_spd(p, 0);
728		unbindph12(p);
729		remph2(p);
730		delph2(p);
731	}
732}
733
734/*
735 * Delete all Phase 2 handlers for this src/dst/proto.  This
736 * is used during INITIAL-CONTACT processing (so no need to
737 * send a message to the peer).
738 */
739void
740deleteallph2(src, dst, proto_id)
741	struct sockaddr *src, *dst;
742	u_int proto_id;
743{
744	struct ph2handle *iph2, *next;
745	struct saproto *pr;
746
747	for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
748		next = LIST_NEXT(iph2, chain);
749		if (iph2->proposal == NULL && iph2->approval == NULL)
750			continue;
751		if (iph2->approval != NULL) {
752			for (pr = iph2->approval->head; pr != NULL;
753			     pr = pr->next) {
754				if (proto_id == pr->proto_id)
755					goto zap_it;
756			}
757		} else if (iph2->proposal != NULL) {
758			for (pr = iph2->proposal->head; pr != NULL;
759			     pr = pr->next) {
760				if (proto_id == pr->proto_id)
761					goto zap_it;
762			}
763		}
764		continue;
765 zap_it:
766		unbindph12(iph2);
767		remph2(iph2);
768		delph2(iph2);
769	}
770}
771
772/* %%% */
773void
774bindph12(iph1, iph2)
775	struct ph1handle *iph1;
776	struct ph2handle *iph2;
777{
778	iph2->ph1 = iph1;
779	LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
780}
781
782void
783unbindph12(iph2)
784	struct ph2handle *iph2;
785{
786	if (iph2->ph1 != NULL) {
787		iph2->ph1 = NULL;
788		LIST_REMOVE(iph2, ph1bind);
789	}
790}
791
792/* %%% management contacted list */
793/*
794 * search contacted list.
795 */
796struct contacted *
797getcontacted(remote)
798	struct sockaddr *remote;
799{
800	struct contacted *p;
801
802	LIST_FOREACH(p, &ctdtree, chain) {
803		if (cmpsaddrstrict(remote, p->remote) == 0)
804			return p;
805	}
806
807	return NULL;
808}
809
810/*
811 * create new isakmp Phase 2 status record to handle isakmp in Phase2
812 */
813int
814inscontacted(remote)
815	struct sockaddr *remote;
816{
817	struct contacted *new;
818
819	/* create new iph2 */
820	new = racoon_calloc(1, sizeof(*new));
821	if (new == NULL)
822		return -1;
823
824	new->remote = dupsaddr(remote);
825	if (new->remote == NULL) {
826		plog(LLV_ERROR, LOCATION, NULL,
827			"failed to allocate buffer.\n");
828		racoon_free(new);
829		return -1;
830	}
831
832	LIST_INSERT_HEAD(&ctdtree, new, chain);
833
834	return 0;
835}
836
837void
838initctdtree()
839{
840	LIST_INIT(&ctdtree);
841}
842
843/*
844 * check the response has been sent to the peer.  when not, simply reply
845 * the buffered packet to the peer.
846 * OUT:
847 *	 0:	the packet is received at the first time.
848 *	 1:	the packet was processed before.
849 *	 2:	the packet was processed before, but the address mismatches.
850 *	-1:	error happened.
851 */
852int
853check_recvdpkt(remote, local, rbuf)
854	struct sockaddr *remote, *local;
855	vchar_t *rbuf;
856{
857	vchar_t *hash;
858	struct recvdpkt *r;
859	time_t t;
860	int len, s;
861
862	/* set current time */
863	t = time(NULL);
864
865	hash = eay_md5_one(rbuf);
866	if (!hash) {
867		plog(LLV_ERROR, LOCATION, NULL,
868			"failed to allocate buffer.\n");
869		return -1;
870	}
871
872	LIST_FOREACH(r, &rcptree, chain) {
873		if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
874			break;
875	}
876	vfree(hash);
877
878	/* this is the first time to receive the packet */
879	if (r == NULL)
880		return 0;
881
882	/*
883	 * the packet was processed before, but the remote address mismatches.
884	 */
885	if (cmpsaddrstrict(remote, r->remote) != 0)
886		return 2;
887
888	/*
889	 * it should not check the local address because the packet
890	 * may arrive at other interface.
891	 */
892
893	/* check the previous time to send */
894	if (t - r->time_send < 1) {
895		plog(LLV_WARNING, LOCATION, NULL,
896			"the packet retransmitted in a short time from %s\n",
897			saddr2str(remote));
898		/*XXX should it be error ? */
899	}
900
901	/* select the socket to be sent */
902	s = getsockmyaddr(r->local);
903	if (s == -1)
904		return -1;
905
906	/* resend the packet if needed */
907	len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
908			r->local, r->remote, lcconf->count_persend);
909	if (len == -1) {
910		plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
911		return -1;
912	}
913
914	/* check the retry counter */
915	r->retry_counter--;
916	if (r->retry_counter <= 0) {
917		rem_recvdpkt(r);
918		del_recvdpkt(r);
919		plog(LLV_DEBUG, LOCATION, NULL,
920			"deleted the retransmission packet to %s.\n",
921			saddr2str(remote));
922	} else
923		r->time_send = t;
924
925	return 1;
926}
927
928/*
929 * adding a hash of received packet into the received list.
930 */
931int
932add_recvdpkt(remote, local, sbuf, rbuf)
933	struct sockaddr *remote, *local;
934	vchar_t *sbuf, *rbuf;
935{
936	struct recvdpkt *new = NULL;
937
938	if (lcconf->retry_counter == 0) {
939		/* no need to add it */
940		return 0;
941	}
942
943	new = racoon_calloc(1, sizeof(*new));
944	if (!new) {
945		plog(LLV_ERROR, LOCATION, NULL,
946			"failed to allocate buffer.\n");
947		return -1;
948	}
949
950	new->hash = eay_md5_one(rbuf);
951	if (!new->hash) {
952		plog(LLV_ERROR, LOCATION, NULL,
953			"failed to allocate buffer.\n");
954		del_recvdpkt(new);
955		return -1;
956	}
957	new->remote = dupsaddr(remote);
958	if (new->remote == NULL) {
959		plog(LLV_ERROR, LOCATION, NULL,
960			"failed to allocate buffer.\n");
961		del_recvdpkt(new);
962		return -1;
963	}
964	new->local = dupsaddr(local);
965	if (new->local == NULL) {
966		plog(LLV_ERROR, LOCATION, NULL,
967			"failed to allocate buffer.\n");
968		del_recvdpkt(new);
969		return -1;
970	}
971	new->sendbuf = vdup(sbuf);
972	if (new->sendbuf == NULL) {
973		plog(LLV_ERROR, LOCATION, NULL,
974			"failed to allocate buffer.\n");
975		del_recvdpkt(new);
976		return -1;
977	}
978
979	new->retry_counter = lcconf->retry_counter;
980	new->time_send = 0;
981	new->created = time(NULL);
982
983	LIST_INSERT_HEAD(&rcptree, new, chain);
984
985	return 0;
986}
987
988void
989del_recvdpkt(r)
990	struct recvdpkt *r;
991{
992	if (r->remote)
993		racoon_free(r->remote);
994	if (r->local)
995		racoon_free(r->local);
996	if (r->hash)
997		vfree(r->hash);
998	if (r->sendbuf)
999		vfree(r->sendbuf);
1000	racoon_free(r);
1001}
1002
1003void
1004rem_recvdpkt(r)
1005	struct recvdpkt *r;
1006{
1007	LIST_REMOVE(r, chain);
1008}
1009
1010void
1011sweep_recvdpkt(dummy)
1012	void *dummy;
1013{
1014	struct recvdpkt *r, *next;
1015	time_t t, lt;
1016
1017	/* set current time */
1018	t = time(NULL);
1019
1020	/* set the lifetime of the retransmission */
1021	lt = lcconf->retry_counter * lcconf->retry_interval;
1022
1023	for (r = LIST_FIRST(&rcptree); r; r = next) {
1024		next = LIST_NEXT(r, chain);
1025
1026		if (t - r->created > lt) {
1027			rem_recvdpkt(r);
1028			del_recvdpkt(r);
1029		}
1030	}
1031
1032	sched_new(lt, sweep_recvdpkt, NULL);
1033}
1034
1035void
1036init_recvdpkt()
1037{
1038	time_t lt = lcconf->retry_counter * lcconf->retry_interval;
1039
1040	LIST_INIT(&rcptree);
1041
1042	sched_new(lt, sweep_recvdpkt, NULL);
1043}
1044
1045#ifdef ENABLE_HYBRID
1046/*
1047 * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
1048 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
1049 */
1050int
1051exclude_cfg_addr(addr)
1052	const struct sockaddr *addr;
1053{
1054	struct ph1handle *p;
1055	struct sockaddr_in *sin;
1056
1057	LIST_FOREACH(p, &ph1tree, chain) {
1058		if ((p->mode_cfg != NULL) &&
1059		    (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
1060		    (addr->sa_family == AF_INET)) {
1061			sin = (struct sockaddr_in *)addr;
1062			if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
1063				return 0;
1064		}
1065	}
1066
1067	return 1;
1068}
1069#endif
1070
1071
1072
1073/*
1074 * Reload conf code
1075 */
1076static int revalidate_ph2(struct ph2handle *iph2){
1077	struct sainfoalg *alg;
1078	int found, check_level;
1079	struct sainfo *sainfo;
1080	struct saprop *approval;
1081	struct ph1handle *iph1;
1082
1083	/*
1084	 * Get the new sainfo using values of the old one
1085	 */
1086	if (iph2->sainfo != NULL) {
1087		iph2->sainfo = getsainfo(iph2->sainfo->idsrc,
1088					  iph2->sainfo->iddst, iph2->sainfo->id_i,
1089					  iph2->sainfo->remoteid);
1090	}
1091	approval = iph2->approval;
1092	sainfo = iph2->sainfo;
1093
1094	if (sainfo == NULL) {
1095		/*
1096		 * Sainfo has been removed
1097		 */
1098		plog(LLV_DEBUG, LOCATION, NULL,
1099			 "Reload: No sainfo for ph2\n");
1100		return 0;
1101	}
1102
1103	if (approval == NULL) {
1104		/*
1105		 * XXX why do we have a NULL approval sometimes ???
1106		 */
1107		plog(LLV_DEBUG, LOCATION, NULL,
1108			 "No approval found !\n");
1109		return 0;
1110	}
1111
1112	/*
1113	 * Don't care about proposals, should we do something ?
1114	 * We have to keep iph2->proposal valid at least for initiator,
1115	 * for pk_sendgetspi()
1116	 */
1117
1118	plog(LLV_DEBUG, LOCATION, NULL, "active single bundle:\n");
1119	printsaprop0(LLV_DEBUG, approval);
1120
1121	/*
1122	 * Validate approval against sainfo
1123	 * Note: we must have an updated ph1->rmconf before doing that,
1124	 * we'll set check_level to EXACT if we don't have a ph1
1125	 * XXX try tu find the new remote section to get the new check level ?
1126	 * XXX lifebyte
1127	 */
1128	if (iph2->ph1 != NULL)
1129		iph1=iph2->ph1;
1130	else
1131		iph1=getph1byaddr(iph2->src, iph2->dst, 0);
1132
1133	if(iph1 != NULL && iph1->rmconf != NULL) {
1134		check_level = iph1->rmconf->pcheck_level;
1135	} else {
1136		if(iph1 != NULL)
1137			plog(LLV_DEBUG, LOCATION, NULL, "No phase1 rmconf found !\n");
1138		else
1139			plog(LLV_DEBUG, LOCATION, NULL, "No phase1 found !\n");
1140		check_level = PROP_CHECK_EXACT;
1141	}
1142
1143	switch (check_level) {
1144	case PROP_CHECK_OBEY:
1145		plog(LLV_DEBUG, LOCATION, NULL,
1146			 "Reload: OBEY for ph2, ok\n");
1147		return 1;
1148		break;
1149
1150	case PROP_CHECK_STRICT:
1151		/* FALLTHROUGH */
1152	case PROP_CHECK_CLAIM:
1153		if (sainfo->lifetime < approval->lifetime) {
1154			plog(LLV_DEBUG, LOCATION, NULL,
1155				 "Reload: lifetime mismatch\n");
1156			return 0;
1157		}
1158
1159#if 0
1160		/* Lifebyte is deprecated, just ignore it
1161		 */
1162		if (sainfo->lifebyte < approval->lifebyte) {
1163			plog(LLV_DEBUG, LOCATION, NULL,
1164				 "Reload: lifebyte mismatch\n");
1165			return 0;
1166		}
1167#endif
1168
1169		if (sainfo->pfs_group &&
1170		   sainfo->pfs_group != approval->pfs_group) {
1171			plog(LLV_DEBUG, LOCATION, NULL,
1172				 "Reload: PFS group mismatch\n");
1173			return 0;
1174		}
1175		break;
1176
1177	case PROP_CHECK_EXACT:
1178		if (sainfo->lifetime != approval->lifetime ||
1179#if 0
1180			/* Lifebyte is deprecated, just ignore it
1181			 */
1182		    sainfo->lifebyte != approval->lifebyte ||
1183#endif
1184		    sainfo->pfs_group != iph2->approval->pfs_group) {
1185			plog(LLV_DEBUG, LOCATION, NULL,
1186			    "Reload: lifetime | pfs mismatch\n");
1187			return 0;
1188		}
1189		break;
1190
1191	default:
1192		plog(LLV_DEBUG, LOCATION, NULL,
1193			 "Reload: Shouldn't be here !\n");
1194		return 0;
1195		break;
1196	}
1197
1198	for (alg = sainfo->algs[algclass_ipsec_auth]; alg; alg = alg->next) {
1199		if (alg->alg == approval->head->head->authtype)
1200			break;
1201	}
1202	if (alg == NULL) {
1203		plog(LLV_DEBUG, LOCATION, NULL,
1204			 "Reload: alg == NULL (auth)\n");
1205		return 0;
1206	}
1207
1208	found = 0;
1209	for (alg = sainfo->algs[algclass_ipsec_enc];
1210	    (found == 0 && alg != NULL); alg = alg->next) {
1211		plog(LLV_DEBUG, LOCATION, NULL,
1212			 "Reload: next ph2 enc alg...\n");
1213
1214		if (alg->alg != approval->head->head->trns_id){
1215			plog(LLV_DEBUG, LOCATION, NULL,
1216				 "Reload: encmode mismatch (%d / %d)\n",
1217				 alg->alg, approval->head->head->trns_id);
1218			continue;
1219		}
1220
1221		switch (check_level){
1222		/* PROP_CHECK_STRICT cannot happen here */
1223		case PROP_CHECK_EXACT:
1224			if (alg->encklen != approval->head->head->encklen) {
1225				plog(LLV_DEBUG, LOCATION, NULL,
1226					 "Reload: enclen mismatch\n");
1227				continue;
1228			}
1229			break;
1230
1231		case PROP_CHECK_CLAIM:
1232			/* FALLTHROUGH */
1233		case PROP_CHECK_STRICT:
1234			if (alg->encklen > approval->head->head->encklen) {
1235				plog(LLV_DEBUG, LOCATION, NULL,
1236					 "Reload: enclen mismatch\n");
1237				continue;
1238			}
1239			break;
1240
1241		default:
1242			plog(LLV_ERROR, LOCATION, NULL,
1243			    "unexpected check_level\n");
1244			continue;
1245			break;
1246		}
1247		found = 1;
1248	}
1249
1250	if (!found){
1251		plog(LLV_DEBUG, LOCATION, NULL,
1252			 "Reload: No valid enc\n");
1253		return 0;
1254	}
1255
1256	/*
1257	 * XXX comp
1258	 */
1259	plog(LLV_DEBUG, LOCATION, NULL,
1260		 "Reload: ph2 check ok\n");
1261
1262	return 1;
1263}
1264
1265
1266static void
1267remove_ph2(struct ph2handle *iph2)
1268{
1269	u_int32_t spis[2];
1270
1271	if(iph2 == NULL)
1272		return;
1273
1274	plog(LLV_DEBUG, LOCATION, NULL,
1275		 "Deleting a Ph2...\n");
1276
1277	if (iph2->status == PHASE2ST_ESTABLISHED)
1278		isakmp_info_send_d2(iph2);
1279
1280	if(iph2->approval != NULL && iph2->approval->head != NULL){
1281		spis[0]=iph2->approval->head->spi;
1282		spis[1]=iph2->approval->head->spi_p;
1283
1284		/* purge_ipsec_spi() will do all the work:
1285		 * - delete SPIs in kernel
1286		 * - delete generated SPD
1287		 * - unbind / rem / del ph2
1288		 */
1289		purge_ipsec_spi(iph2->dst, iph2->approval->head->proto_id,
1290						spis, 2);
1291	}else{
1292		unbindph12(iph2);
1293		remph2(iph2);
1294		delph2(iph2);
1295	}
1296}
1297
1298static void remove_ph1(struct ph1handle *iph1){
1299	struct ph2handle *iph2, *iph2_next;
1300
1301	if(iph1 == NULL)
1302		return;
1303
1304	plog(LLV_DEBUG, LOCATION, NULL,
1305		 "Removing PH1...\n");
1306
1307	if (iph1->status == PHASE1ST_ESTABLISHED){
1308		for (iph2 = LIST_FIRST(&iph1->ph2tree); iph2; iph2 = iph2_next) {
1309			iph2_next = LIST_NEXT(iph2, chain);
1310			remove_ph2(iph2);
1311		}
1312		isakmp_info_send_d1(iph1);
1313	}
1314	iph1->status = PHASE1ST_EXPIRED;
1315	iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1316}
1317
1318
1319static int revalidate_ph1tree_rmconf(void){
1320	struct ph1handle *p, *next;
1321	struct remoteconf *newrmconf;
1322
1323	for (p = LIST_FIRST(&ph1tree); p; p = next) {
1324		next = LIST_NEXT(p, chain);
1325
1326		if (p->status == PHASE1ST_EXPIRED)
1327			continue;
1328
1329		newrmconf=getrmconf(p->remote);
1330		if(newrmconf == NULL){
1331			p->rmconf = NULL;
1332			remove_ph1(p);
1333		}else{
1334			/* Do not free old rmconf, it is just a pointer to an entry in rmtree
1335			 */
1336			p->rmconf=newrmconf;
1337			if(p->approval != NULL){
1338				struct isakmpsa *tmpsa;
1339
1340				tmpsa=dupisakmpsa(p->approval);
1341				if(tmpsa != NULL){
1342					delisakmpsa(p->approval);
1343					p->approval=tmpsa;
1344					p->approval->rmconf=newrmconf;
1345				}
1346			}
1347		}
1348	}
1349
1350	return 1;
1351}
1352
1353
1354/* rmconf is already updated here
1355 */
1356static int revalidate_ph1(struct ph1handle *iph1){
1357	struct isakmpsa *p, *approval;
1358	struct etypes *e;
1359
1360	if(iph1 == NULL ||
1361	   iph1->approval == NULL ||
1362		iph1->rmconf == NULL)
1363		return 0;
1364
1365	approval=iph1->approval;
1366
1367	for (e = iph1->rmconf->etypes; e != NULL; e = e->next){
1368		if (iph1->etype == e->type)
1369			break;
1370	}
1371
1372	if (e == NULL){
1373		plog(LLV_DEBUG, LOCATION, NULL,
1374			 "Reload: Exchange type mismatch\n");
1375		return 0;
1376	}
1377
1378	if (iph1->etype == ISAKMP_ETYPE_AGG &&
1379	   approval->dh_group != iph1->rmconf->dh_group){
1380		plog(LLV_DEBUG, LOCATION, NULL,
1381			 "Reload: DH mismatch\n");
1382		return 0;
1383	}
1384
1385	for (p=iph1->rmconf->proposal; p != NULL; p=p->next){
1386		plog(LLV_DEBUG, LOCATION, NULL,
1387			 "Reload: Trying next proposal...\n");
1388
1389		if(approval->authmethod != p->authmethod){
1390			plog(LLV_DEBUG, LOCATION, NULL,
1391				 "Reload: Authmethod mismatch\n");
1392			continue;
1393		}
1394
1395		if(approval->enctype != p->enctype){
1396			plog(LLV_DEBUG, LOCATION, NULL,
1397				 "Reload: enctype mismatch\n");
1398			continue;
1399		}
1400
1401		switch (iph1->rmconf->pcheck_level) {
1402		case PROP_CHECK_OBEY:
1403			plog(LLV_DEBUG, LOCATION, NULL,
1404				 "Reload: OBEY pcheck level, ok...\n");
1405			return 1;
1406			break;
1407
1408		case PROP_CHECK_CLAIM:
1409			/* FALLTHROUGH */
1410		case PROP_CHECK_STRICT:
1411			if (approval->encklen < p->encklen) {
1412				plog(LLV_DEBUG, LOCATION, NULL,
1413					 "Reload: encklen mismatch\n");
1414				continue;
1415			}
1416
1417			if (approval->lifetime > p->lifetime) {
1418				plog(LLV_DEBUG, LOCATION, NULL,
1419					 "Reload: lifetime mismatch\n");
1420				continue;
1421			}
1422
1423#if 0
1424			/* Lifebyte is deprecated, just ignore it
1425			 */
1426			if (approval->lifebyte > p->lifebyte) {
1427				plog(LLV_DEBUG, LOCATION, NULL,
1428					 "Reload: lifebyte mismatch\n");
1429				continue;
1430			}
1431#endif
1432			break;
1433
1434		case PROP_CHECK_EXACT:
1435			if (approval->encklen != p->encklen) {
1436				plog(LLV_DEBUG, LOCATION, NULL,
1437					 "Reload: encklen mismatch\n");
1438				continue;
1439			}
1440
1441			if (approval->lifetime != p->lifetime) {
1442				plog(LLV_DEBUG, LOCATION, NULL,
1443					 "Reload: lifetime mismatch\n");
1444				continue;
1445			}
1446
1447#if 0
1448			/* Lifebyte is deprecated, just ignore it
1449			 */
1450			if (approval->lifebyte != p->lifebyte) {
1451				plog(LLV_DEBUG, LOCATION, NULL,
1452					 "Reload: lifebyte mismatch\n");
1453				continue;
1454			}
1455#endif
1456			break;
1457
1458		default:
1459			plog(LLV_ERROR, LOCATION, NULL,
1460			    "unexpected check_level\n");
1461			continue;
1462			break;
1463		}
1464
1465		if (approval->hashtype != p->hashtype) {
1466			plog(LLV_DEBUG, LOCATION, NULL,
1467				 "Reload: hashtype mismatch\n");
1468			continue;
1469		}
1470
1471		if (iph1->etype != ISAKMP_ETYPE_AGG &&
1472		    approval->dh_group != p->dh_group) {
1473			plog(LLV_DEBUG, LOCATION, NULL,
1474				 "Reload: dhgroup mismatch\n");
1475			continue;
1476		}
1477
1478		plog(LLV_DEBUG, LOCATION, NULL, "Reload: Conf ok\n");
1479		return 1;
1480	}
1481
1482	plog(LLV_DEBUG, LOCATION, NULL, "Reload: No valid conf found\n");
1483	return 0;
1484}
1485
1486
1487static int revalidate_ph1tree(void){
1488	struct ph1handle *p, *next;
1489
1490	for (p = LIST_FIRST(&ph1tree); p; p = next) {
1491		next = LIST_NEXT(p, chain);
1492
1493		if (p->status == PHASE1ST_EXPIRED)
1494			continue;
1495
1496		if(!revalidate_ph1(p))
1497			remove_ph1(p);
1498	}
1499
1500	return 1;
1501}
1502
1503static int revalidate_ph2tree(void){
1504	struct ph2handle *p, *next;
1505
1506	for (p = LIST_FIRST(&ph2tree); p; p = next) {
1507		next = LIST_NEXT(p, chain);
1508
1509		if (p->status == PHASE2ST_EXPIRED)
1510			continue;
1511
1512		if(!revalidate_ph2(p)){
1513			plog(LLV_DEBUG, LOCATION, NULL,
1514				 "PH2 not validated, removing it\n");
1515			remove_ph2(p);
1516		}
1517	}
1518
1519	return 1;
1520}
1521
1522int
1523revalidate_ph12(void)
1524{
1525
1526	revalidate_ph1tree_rmconf();
1527
1528	revalidate_ph2tree();
1529	revalidate_ph1tree();
1530
1531	return 1;
1532}
1533
1534#ifdef ENABLE_HYBRID
1535struct ph1handle *
1536getph1bylogin(login)
1537	char *login;
1538{
1539	struct ph1handle *p;
1540
1541	LIST_FOREACH(p, &ph1tree, chain) {
1542		if (p->mode_cfg == NULL)
1543			continue;
1544		if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0)
1545			return p;
1546	}
1547
1548	return NULL;
1549}
1550
1551int
1552purgeph1bylogin(login)
1553	char *login;
1554{
1555	struct ph1handle *p;
1556	int found = 0;
1557
1558	LIST_FOREACH(p, &ph1tree, chain) {
1559		if (p->mode_cfg == NULL)
1560			continue;
1561		if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) {
1562			if (p->status == PHASE1ST_ESTABLISHED)
1563				isakmp_info_send_d1(p);
1564			purge_remote(p);
1565			found++;
1566		}
1567	}
1568
1569	return found;
1570}
1571#endif
1572