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