• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
84 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
85 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
86 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
87 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
88 
89 static void del_recvdpkt __P((struct recvdpkt *));
90 static void rem_recvdpkt __P((struct recvdpkt *));
91 static 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 
101 extern caddr_t val2str(const char *, size_t);
102 
103 struct ph1handle *
getph1byindex(index)104 getph1byindex(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  */
123 struct ph1handle *
getph1byindex0(index)124 getph1byindex0(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  */
144 struct ph1handle *
getph1byaddr(local,remote,established)145 getph1byaddr(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 
177 struct ph1handle *
getph1byaddrwop(local,remote)178 getph1byaddrwop(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  */
199 struct ph1handle *
getph1bydstaddrwop(remote)200 getph1bydstaddrwop(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  */
218 vchar_t *
dumpph1()219 dumpph1()
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  */
257 struct ph1handle *
newph1()258 newph1()
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  */
283 void
delph1(iph1)284 delph1(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  */
384 int
insph1(iph1)385 insph1(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 
399 void
remph1(iph1)400 remph1(iph1)
401 	struct ph1handle *iph1;
402 {
403 	LIST_REMOVE(iph1, chain);
404 }
405 
406 /*
407  * flush isakmp-sa
408  */
409 void
flushph1()410 flushph1()
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 
426 void
initph1tree()427 initph1tree()
428 {
429 	LIST_INIT(&ph1tree);
430 }
431 
432 /* %%% management phase 2 handler */
433 /*
434  * search ph2handle with policy id.
435  */
436 struct ph2handle *
getph2byspid(spid)437 getph2byspid(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  */
457 struct ph2handle *
getph2byseq(seq)458 getph2byseq(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  */
474 struct ph2handle *
getph2bymsgid(iph1,msgid)475 getph2bymsgid(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 
489 struct ph2handle *
getph2byid(src,dst,spid)490 getph2byid(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 
519 struct ph2handle *
getph2bysaddr(src,dst)520 getph2bysaddr(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  */
537 struct ph2handle *
getph2bysaidx(src,dst,proto_id,spi)538 getph2bysaidx(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  */
574 struct ph2handle *
newph2()575 newph2()
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  */
594 void
initph2(iph2)595 initph2(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  */
650 void
delph2(iph2)651 delph2(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  */
684 int
insph2(iph2)685 insph2(iph2)
686 	struct ph2handle *iph2;
687 {
688 	LIST_INSERT_HEAD(&ph2tree, iph2, chain);
689 
690 	return 0;
691 }
692 
693 void
remph2(iph2)694 remph2(iph2)
695 	struct ph2handle *iph2;
696 {
697 	LIST_REMOVE(iph2, chain);
698 }
699 
700 void
initph2tree()701 initph2tree()
702 {
703 	LIST_INIT(&ph2tree);
704 }
705 
706 void
flushph2()707 flushph2()
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  */
739 void
deleteallph2(src,dst,proto_id)740 deleteallph2(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 /* %%% */
773 void
bindph12(iph1,iph2)774 bindph12(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 
782 void
unbindph12(iph2)783 unbindph12(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  */
796 struct contacted *
getcontacted(remote)797 getcontacted(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  */
813 int
inscontacted(remote)814 inscontacted(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 
837 void
initctdtree()838 initctdtree()
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  */
852 int
check_recvdpkt(remote,local,rbuf)853 check_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  */
931 int
add_recvdpkt(remote,local,sbuf,rbuf)932 add_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 
988 void
del_recvdpkt(r)989 del_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 
1003 void
rem_recvdpkt(r)1004 rem_recvdpkt(r)
1005 	struct recvdpkt *r;
1006 {
1007 	LIST_REMOVE(r, chain);
1008 }
1009 
1010 void
sweep_recvdpkt(dummy)1011 sweep_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 
1035 void
init_recvdpkt()1036 init_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  */
1050 int
exclude_cfg_addr(addr)1051 exclude_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  */
revalidate_ph2(struct ph2handle * iph2)1076 static 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 
1266 static void
remove_ph2(struct ph2handle * iph2)1267 remove_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 
remove_ph1(struct ph1handle * iph1)1298 static 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 
revalidate_ph1tree_rmconf(void)1319 static 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  */
revalidate_ph1(struct ph1handle * iph1)1356 static 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 
revalidate_ph1tree(void)1487 static 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 
revalidate_ph2tree(void)1503 static 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 
1522 int
revalidate_ph12(void)1523 revalidate_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
1535 struct ph1handle *
getph1bylogin(login)1536 getph1bylogin(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 
1551 int
purgeph1bylogin(login)1552 purgeph1bylogin(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