]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/handler.c
e2871452dc4001cd31af0c642d76a1b6f2b40117
[apple/ipsec.git] / ipsec-tools / racoon / handler.c
1 /* $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu 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 #include "fsm.h"
53
54 #ifdef ENABLE_HYBRID
55 #include <resolv.h>
56 #endif
57
58 #include "schedule.h"
59 #include "grabmyaddr.h"
60 #include "algorithm.h"
61 #include "crypto_openssl.h"
62 #include "policy.h"
63 #include "proposal.h"
64 #include "isakmp_var.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 #include "ike_session.h"
78 #include "isakmp_frag.h"
79
80 #include "sainfo.h"
81
82 #include "power_mgmt.h"
83
84
85 extern LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree;
86 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
87 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
88
89 static void ike_session_del_recvdpkt (struct recvdpkt *);
90 static void ike_session_rem_recvdpkt (struct recvdpkt *);
91 static void sweep_recvdpkt (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 static phase1_handle_t *
104 getph1byindex(ike_session_t *session, isakmp_index *index)
105 {
106 phase1_handle_t *p = NULL;
107
108 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
109 if (FSM_STATE_IS_EXPIRED(p->status))
110 continue;
111 if (memcmp(&p->index, index, sizeof(*index)) == 0)
112 return p;
113 }
114
115 return NULL;
116 }
117
118 phase1_handle_t *
119 ike_session_getph1byindex(ike_session_t *session, isakmp_index *index)
120 {
121 phase1_handle_t *p;
122 ike_session_t *cur_session = NULL;
123
124 if (session)
125 return getph1byindex(session, index);
126
127 LIST_FOREACH(cur_session, &ike_session_tree, chain) {
128 if ((p = getph1byindex(cur_session, index)) != NULL)
129 return p;
130 }
131 return NULL;
132 }
133
134
135 /*
136 * search for isakmp handler by i_ck in index.
137 */
138
139 static phase1_handle_t *
140 getph1byindex0 (ike_session_t *session, isakmp_index *index)
141 {
142 phase1_handle_t *p = NULL;
143
144 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
145 if (FSM_STATE_IS_EXPIRED(p->status))
146 continue;
147 if (memcmp(&p->index.i_ck, &index->i_ck, sizeof(cookie_t)) == 0)
148 return p;
149 }
150 return NULL;
151 }
152
153 phase1_handle_t *
154 ike_session_getph1byindex0(ike_session_t *session, isakmp_index *index)
155 {
156 phase1_handle_t *p = NULL;
157 ike_session_t *cur_session = NULL;
158
159 if (session)
160 return getph1byindex0(session, index);
161
162 LIST_FOREACH(cur_session, &ike_session_tree, chain) {
163 if ((p = getph1byindex0(cur_session, index)) != NULL)
164 return p;
165 }
166
167 return NULL;
168 }
169
170 /*
171 * search for isakmpsa handler by source and remote address.
172 * don't use port number to search because this function search
173 * with phase 2's destinaion.
174 */
175 phase1_handle_t *
176 ike_session_getph1byaddr(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
177 {
178 phase1_handle_t *p = NULL;
179
180 plog(ASL_LEVEL_DEBUG, "getph1byaddr: start\n");
181 plog(ASL_LEVEL_DEBUG, "local: %s\n", saddr2str((struct sockaddr *)local));
182 plog(ASL_LEVEL_DEBUG, "remote: %s\n", saddr2str((struct sockaddr *)remote));
183
184 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
185 if (FSM_STATE_IS_EXPIRED(p->status))
186 continue;
187 plog(ASL_LEVEL_DEBUG, "p->local: %s\n", saddr2str((struct sockaddr *)p->local));
188 plog(ASL_LEVEL_DEBUG, "p->remote: %s\n", saddr2str((struct sockaddr *)p->remote));
189 if (CMPSADDR(local, p->local) == 0
190 && CMPSADDR(remote, p->remote) == 0){
191 plog(ASL_LEVEL_DEBUG, "matched\n");
192 return p;
193 }
194 }
195
196 plog(ASL_LEVEL_DEBUG, "no match\n");
197
198 return NULL;
199 }
200
201 static phase1_handle_t *
202 sgetph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
203 {
204 phase1_handle_t *p = NULL;
205
206 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
207 if (FSM_STATE_IS_EXPIRED(p->status))
208 continue;
209 if (cmpsaddrwop(local, p->local) == 0
210 && cmpsaddrwop(remote, p->remote) == 0)
211 return p;
212 }
213
214 return NULL;
215 }
216
217 phase1_handle_t *
218 ike_session_getph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
219 {
220 phase1_handle_t *p;
221 ike_session_t *cur_session = NULL;
222
223 if (session)
224 return sgetph1byaddrwop(session, local, remote);
225
226 LIST_FOREACH(cur_session, &ike_session_tree, chain) {
227 if ((p = sgetph1byaddrwop(cur_session, local, remote)) != NULL)
228 return p;
229 }
230
231 return NULL;
232 }
233
234 /*
235 * search for isakmpsa handler by remote address.
236 * don't use port number to search because this function search
237 * with phase 2's destinaion.
238 */
239 phase1_handle_t *
240 sike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote)
241 {
242 phase1_handle_t *p = NULL;
243
244 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
245 if (FSM_STATE_IS_EXPIRED(p->status))
246 continue;
247 if (cmpsaddrwop(remote, p->remote) == 0)
248 return p;
249 }
250
251 return NULL;
252 }
253
254 phase1_handle_t *
255 ike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote)
256 {
257 phase1_handle_t *p;
258 ike_session_t *cur_session = NULL;
259
260 if (session)
261 return sike_session_getph1bydstaddrwop(session, remote);
262 else {
263 LIST_FOREACH(cur_session, &ike_session_tree, chain) {
264 if ((p = sike_session_getph1bydstaddrwop(cur_session, remote)) != NULL)
265 return p;
266 }
267 }
268 return NULL;
269 }
270
271 int
272 ike_session_islast_ph1(phase1_handle_t *ph1)
273 {
274 phase1_handle_t *p = NULL;
275
276 LIST_FOREACH(p, &ph1->parent_session->ph1tree, ph1ofsession_chain) {
277 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status))
278 continue;
279 if (CMPSADDR(ph1->remote, p->remote) == 0) {
280 if (p == ph1)
281 continue;
282 return 0;
283 }
284 }
285 return 1;
286 }
287
288 /*
289 * create new isakmp Phase 1 status record to handle isakmp in Phase1
290 */
291 phase1_handle_t *
292 ike_session_newph1(unsigned int version)
293 {
294 phase1_handle_t *iph1;
295
296 /* create new iph1 */
297 iph1 = racoon_calloc(1, sizeof(*iph1));
298 if (iph1 == NULL)
299 return NULL;
300 iph1->version = version;
301
302 #ifdef ENABLE_DPD
303 iph1->dpd_support = 0;
304 iph1->dpd_lastack = 0;
305 iph1->dpd_seq = 0;
306 iph1->dpd_fails = 0;
307 iph1->peer_sent_ike = 0;
308 iph1->dpd_r_u = NULL;
309 #endif
310 #ifdef ENABLE_VPNCONTROL_PORT
311 iph1->ping_sched = NULL;
312 #endif
313 iph1->is_dying = 0;
314 plog(ASL_LEVEL_DEBUG, "*** New Phase 1\n");
315 return iph1;
316 }
317
318 /*
319 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
320 */
321 void
322 ike_session_delph1(phase1_handle_t *iph1)
323 {
324 if (iph1 == NULL)
325 return;
326
327 #ifdef ENABLE_NATT
328 if (iph1->natt_options) {
329 racoon_free(iph1->natt_options);
330 iph1->natt_options = NULL;
331 }
332 #endif
333
334 #ifdef ENABLE_HYBRID
335 if (iph1->mode_cfg)
336 isakmp_cfg_rmstate(iph1);
337 VPTRINIT(iph1->xauth_awaiting_userinput_msg);
338 #endif
339
340 #ifdef ENABLE_DPD
341 if (iph1->dpd_r_u)
342 SCHED_KILL(iph1->dpd_r_u);
343 #endif
344 #ifdef ENABLE_VPNCONTROL_PORT
345 if (iph1->ping_sched)
346 SCHED_KILL(iph1->ping_sched);
347 #endif
348
349 if (iph1->remote) {
350 racoon_free(iph1->remote);
351 iph1->remote = NULL;
352 }
353 if (iph1->local) {
354 racoon_free(iph1->local);
355 iph1->local = NULL;
356 }
357
358 if (iph1->approval) {
359 delisakmpsa(iph1->approval);
360 iph1->approval = NULL;
361 }
362
363 sched_scrub_param(iph1);
364 if (iph1->sce)
365 SCHED_KILL(iph1->sce);
366 if (iph1->sce_rekey)
367 SCHED_KILL(iph1->sce_rekey);
368 if (iph1->scr)
369 SCHED_KILL(iph1->scr);
370
371 VPTRINIT(iph1->sendbuf);
372
373 VPTRINIT(iph1->dhpriv);
374 VPTRINIT(iph1->dhpub);
375 VPTRINIT(iph1->dhpub_p);
376 VPTRINIT(iph1->dhgxy);
377 VPTRINIT(iph1->nonce);
378 VPTRINIT(iph1->nonce_p);
379 VPTRINIT(iph1->skeyid);
380 VPTRINIT(iph1->skeyid_d);
381 VPTRINIT(iph1->skeyid_a);
382 VPTRINIT(iph1->skeyid_a_p);
383 VPTRINIT(iph1->skeyid_e);
384 VPTRINIT(iph1->skeyid_e_p);
385 VPTRINIT(iph1->skeyid_p);
386 VPTRINIT(iph1->skeyid_p_p);
387 VPTRINIT(iph1->key);
388 VPTRINIT(iph1->key_p);
389 VPTRINIT(iph1->hash);
390 VPTRINIT(iph1->sig);
391 VPTRINIT(iph1->sig_p);
392 oakley_delcert(iph1->cert);
393 iph1->cert = NULL;
394 oakley_delcert(iph1->cert_p);
395 iph1->cert_p = NULL;
396 oakley_delcert(iph1->crl_p);
397 iph1->crl_p = NULL;
398 oakley_delcert(iph1->cr_p);
399 iph1->cr_p = NULL;
400 VPTRINIT(iph1->id);
401 VPTRINIT(iph1->id_p);
402
403 if(iph1->approval != NULL)
404 delisakmpsa(iph1->approval);
405
406 if (iph1->ivm) {
407 oakley_delivm(iph1->ivm);
408 iph1->ivm = NULL;
409 }
410
411 VPTRINIT(iph1->sa);
412 VPTRINIT(iph1->sa_ret);
413
414 if (iph1->rmconf) {
415 release_rmconf(iph1->rmconf);
416 iph1->rmconf = NULL;
417 }
418
419 racoon_free(iph1);
420 }
421
422 void
423 ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
424 {
425 phase1_handle_t *p, *next;
426
427 LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) {
428 if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
429 plog(ASL_LEVEL_DEBUG,
430 "Skipping Phase 1 %s that's asserted...\n",
431 isakmp_pindex(&p->index, 0));
432 continue;
433 }
434
435 /* send delete information */
436 if (FSM_STATE_IS_ESTABLISHED(p->status)) {
437 if (ignore_estab_or_assert_handles &&
438 (ike_session_has_negoing_ph2(p->parent_session) || ike_session_has_established_ph2(p->parent_session))) {
439 plog(ASL_LEVEL_DEBUG,
440 "Skipping Phase 1 %s that's established... because it's needed by children Phase 2s\n",
441 isakmp_pindex(&p->index, 0));
442 continue;
443 }
444 /* send delete information */
445 plog(ASL_LEVEL_DEBUG,
446 "Got a Phase 1 %s to flush...\n",
447 isakmp_pindex(&p->index, 0));
448 isakmp_info_send_d1(p);
449 }
450
451 ike_session_stopped_by_controller(p->parent_session,
452 ike_session_stopped_by_flush);
453
454 ike_session_unlink_phase1(p);
455 }
456 }
457
458 /*
459 * flush isakmp-sa
460 */
461 void
462 ike_session_flush_all_phase1(int ignore_estab_or_assert_handles)
463 {
464 ike_session_t *session = NULL;
465 ike_session_t *next_session = NULL;
466
467 plog(ASL_LEVEL_DEBUG,
468 "Flushing Phase 1 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
469
470 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
471 ike_session_flush_all_phase1_for_session(session, ignore_estab_or_assert_handles);
472 }
473 }
474
475
476
477 /*
478 * search ph2handle with policy id.
479 */
480 phase2_handle_t *
481 ike_session_getph2byspid(u_int32_t spid)
482 {
483 ike_session_t *session = NULL;
484 phase2_handle_t *p;
485
486 LIST_FOREACH(session, &ike_session_tree, chain) {
487 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) {
488 /*
489 * there are ph2handle independent on policy
490 * such like informational exchange.
491 */
492 if (p->spid == spid)
493 return p;
494 }
495 }
496
497 return NULL;
498 }
499
500
501 /*
502 * search ph2handle with sequence number.
503 * Used by PF_KEY functions to locate the phase2
504 */
505 phase2_handle_t *
506 ike_session_getph2byseq(u_int32_t seq)
507 {
508 ike_session_t *session;
509 phase2_handle_t *p;
510
511 LIST_FOREACH(session, &ike_session_tree, chain) {
512 LIST_FOREACH(p, &session->ph2tree, ph2ofsession_chain) {
513 if (p->seq == seq)
514 return p;
515 }
516 }
517 return NULL;
518 }
519
520 /*
521 * search ph2handle with message id.
522 */
523 phase2_handle_t *
524 ike_session_getph2bymsgid(phase1_handle_t *iph1, u_int32_t msgid)
525 {
526 phase2_handle_t *p;
527
528 LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) {
529 if (p->msgid == msgid)
530 return p;
531 }
532
533 return NULL;
534 }
535
536 phase2_handle_t *
537 ike_session_getonlyph2(phase1_handle_t *iph1)
538 {
539 phase2_handle_t *only_ph2 = NULL;
540 phase2_handle_t *p = NULL;
541
542 LIST_FOREACH(p, &iph1->bound_ph2tree, ph2ofsession_chain) {
543 if (only_ph2) return NULL;
544 only_ph2 = p;
545 }
546
547 return only_ph2;
548 }
549
550 phase2_handle_t *
551 ike_session_getph2byid(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int32_t spid)
552 {
553 ike_session_t *session = NULL;
554 ike_session_t *next_session = NULL;
555 phase2_handle_t *p;
556 phase2_handle_t *next_iph2;
557
558 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
559 LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next_iph2) {
560 if (spid == p->spid &&
561 CMPSADDR(src, p->src) == 0 &&
562 CMPSADDR(dst, p->dst) == 0){
563 /* Sanity check to detect zombie handlers
564 * XXX Sould be done "somewhere" more interesting,
565 * because we have lots of getph2byxxxx(), but this one
566 * is called by pk_recvacquire(), so is the most important.
567 */
568 if(!FSM_STATE_IS_ESTABLISHED_OR_EXPIRED(p->status) &&
569 p->retry_counter == 0
570 && p->sce == 0 && p->scr == 0 &&
571 p->retry_checkph1 == 0){
572 plog(ASL_LEVEL_DEBUG,
573 "Zombie ph2 found, expiring it\n");
574 isakmp_ph2expire(p);
575 }else
576 return p;
577 }
578 }
579 }
580
581 return NULL;
582 }
583
584 #ifdef NOT_USED
585 phase2_handle_t *
586 ike_session_getph2bysaddr(struct sockaddr_storage *src, struct sockaddr_storage *dst)
587 {
588 ike_session_t *session;
589 phase2_handle_t *p;
590
591 LIST_FOREACH(session, &ike_session_tree, chain) {
592 LIST_FOREACH(p, &session->ph2tree, chain) {
593 if (cmpsaddrstrict(src, p->src) == 0 &&
594 cmpsaddrstrict(dst, p->dst) == 0)
595 return p;
596 }
597 }
598
599 return NULL;
600 }
601 #endif /* NOT_USED */
602
603 /*
604 * call by pk_recvexpire().
605 */
606 phase2_handle_t *
607 ike_session_getph2bysaidx(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi)
608 {
609 ike_session_t *session;
610 phase2_handle_t *iph2;
611 struct saproto *pr;
612
613 LIST_FOREACH(session, &ike_session_tree, chain) {
614 LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) {
615 if (iph2->proposal == NULL && iph2->approval == NULL)
616 continue;
617 if (iph2->approval != NULL) {
618 for (pr = iph2->approval->head; pr != NULL;
619 pr = pr->next) {
620 if (proto_id != pr->proto_id)
621 break;
622 if (spi == pr->spi || spi == pr->spi_p)
623 return iph2;
624 }
625 } else if (iph2->proposal != NULL) {
626 for (pr = iph2->proposal->head; pr != NULL;
627 pr = pr->next) {
628 if (proto_id != pr->proto_id)
629 break;
630 if (spi == pr->spi)
631 return iph2;
632 }
633 }
634 }
635 }
636
637 return NULL;
638 }
639
640 phase2_handle_t *
641 ike_session_getph2bysaidx2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi, u_int32_t *opposite_spi)
642 {
643 ike_session_t *session;
644 phase2_handle_t *iph2;
645 struct saproto *pr;
646
647 LIST_FOREACH(session, &ike_session_tree, chain) {
648 LIST_FOREACH(iph2, &session->ph2tree, ph2ofsession_chain) {
649 if (iph2->proposal == NULL && iph2->approval == NULL)
650 continue;
651 if (iph2->approval != NULL) {
652 for (pr = iph2->approval->head; pr != NULL;
653 pr = pr->next) {
654 if (proto_id != pr->proto_id)
655 break;
656 if (spi == pr->spi || spi == pr->spi_p) {
657 if (opposite_spi) {
658 *opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi;
659 }
660 return iph2;
661 }
662 }
663 } else if (iph2->proposal != NULL) {
664 for (pr = iph2->proposal->head; pr != NULL;
665 pr = pr->next) {
666 if (proto_id != pr->proto_id)
667 break;
668 if (spi == pr->spi || spi == pr->spi_p) {
669 if (opposite_spi) {
670 *opposite_spi = (spi == pr->spi)? pr->spi_p : pr->spi;
671 }
672 return iph2;
673 }
674 }
675 }
676 }
677 }
678
679 return NULL;
680 }
681
682 /*
683 * create new isakmp Phase 2 status record to handle isakmp in Phase2
684 */
685 phase2_handle_t *
686 ike_session_newph2(unsigned int version, int type)
687 {
688 phase2_handle_t *iph2 = NULL;
689
690 /* create new iph2 */
691 iph2 = racoon_calloc(1, sizeof(*iph2));
692 if (iph2 == NULL)
693 return NULL;
694 iph2->version = version;
695 iph2->phase2_type = type;
696 iph2->is_dying = 0;
697
698 plog(ASL_LEVEL_DEBUG, "*** New Phase 2\n");
699 return iph2;
700 }
701
702 /*
703 * initialize ph2handle
704 * NOTE: don't initialize src/dst.
705 * SPI in the proposal is cleared.
706 */
707 void
708 ike_session_initph2(phase2_handle_t *iph2)
709 {
710 sched_scrub_param(iph2);
711 iph2->sce = NULL;
712 iph2->scr = NULL;
713
714 VPTRINIT(iph2->sendbuf);
715 VPTRINIT(iph2->msg1);
716
717 /* clear spi, keep variables in the proposal */
718 if (iph2->proposal) {
719 struct saproto *pr;
720 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
721 pr->spi = 0;
722 }
723
724 /* clear approval */
725 if (iph2->approval) {
726 flushsaprop(iph2->approval);
727 iph2->approval = NULL;
728 }
729
730 /* clear the generated policy */
731 if (iph2->spidx_gen) {
732 delsp_bothdir(iph2->spidx_gen);
733 racoon_free(iph2->spidx_gen);
734 iph2->spidx_gen = NULL;
735 }
736
737 if (iph2->pfsgrp) {
738 oakley_dhgrp_free(iph2->pfsgrp);
739 iph2->pfsgrp = NULL;
740 }
741
742 VPTRINIT(iph2->dhpriv);
743 VPTRINIT(iph2->dhpub);
744 VPTRINIT(iph2->dhpub_p);
745 VPTRINIT(iph2->dhgxy);
746 VPTRINIT(iph2->id);
747 VPTRINIT(iph2->id_p);
748 VPTRINIT(iph2->nonce);
749 VPTRINIT(iph2->nonce_p);
750 VPTRINIT(iph2->sa);
751 VPTRINIT(iph2->sa_ret);
752
753 if (iph2->ivm) {
754 oakley_delivm(iph2->ivm);
755 iph2->ivm = NULL;
756 }
757 }
758
759 /*
760 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
761 */
762 void
763 ike_session_delph2(phase2_handle_t *iph2)
764 {
765 ike_session_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->src_id) {
776 racoon_free(iph2->src_id);
777 iph2->src_id = NULL;
778 }
779 if (iph2->dst_id) {
780 racoon_free(iph2->dst_id);
781 iph2->dst_id = NULL;
782 }
783
784 if (iph2->proposal) {
785 flushsaprop(iph2->proposal);
786 iph2->proposal = NULL;
787 }
788
789 if (iph2->sainfo) {
790 release_sainfo(iph2->sainfo);
791 iph2->sainfo = NULL;
792 }
793 VPTRINIT(iph2->id);
794 VPTRINIT(iph2->id_p);
795 VPTRINIT(iph2->ext_nat_id);
796 VPTRINIT(iph2->ext_nat_id_p);
797
798 if (iph2->sce)
799 SCHED_KILL(iph2->sce);
800 if (iph2->scr)
801 SCHED_KILL(iph2->scr);
802
803
804 racoon_free(iph2);
805 }
806
807 void
808 ike_session_flush_all_phase2_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
809 {
810 phase2_handle_t *p = NULL;
811 phase2_handle_t *next = NULL;
812 LIST_FOREACH_SAFE(p, &session->ph2tree, ph2ofsession_chain, next) {
813 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
814 continue;
815 }
816 if (ignore_estab_or_assert_handles && p->parent_session && !p->parent_session->stopped_by_vpn_controller && p->parent_session->is_asserted) {
817 plog(ASL_LEVEL_DEBUG,
818 "skipping phase2 handle that's asserted...\n");
819 continue;
820 }
821 if (FSM_STATE_IS_ESTABLISHED(p->status)){
822 if (ignore_estab_or_assert_handles) {
823 plog(ASL_LEVEL_DEBUG,
824 "skipping ph2 handler that's established...\n");
825 continue;
826 }
827 /* send delete information */
828 plog(ASL_LEVEL_DEBUG,
829 "got an established ph2 handler to flush...\n");
830 isakmp_info_send_d2(p);
831 }else{
832 plog(ASL_LEVEL_DEBUG,
833 "got a ph2 handler to flush (state %d)\n", p->status);
834 }
835
836 ike_session_stopped_by_controller(p->parent_session,
837 ike_session_stopped_by_flush);
838 delete_spd(p);
839 ike_session_unlink_phase2(p);
840 }
841 }
842
843 void
844 ike_session_flush_all_phase2(int ignore_estab_or_assert_handles)
845 {
846 ike_session_t *session = NULL;
847 ike_session_t *next_session = NULL;
848
849 plog(ASL_LEVEL_DEBUG,
850 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
851
852 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
853 ike_session_flush_all_phase2_for_session(session, ignore_estab_or_assert_handles);
854 }
855 }
856
857 /*
858 * Delete all Phase 2 handlers for this src/dst/proto. This
859 * is used during INITIAL-CONTACT processing (so no need to
860 * send a message to the peer).
861 */
862 //%%%%%%%%%%%%%%%%%%% make this smarter - find session using addresses ????
863 void
864 ike_session_deleteallph2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id)
865 {
866 ike_session_t *session = NULL;
867 ike_session_t *next_session = NULL;
868 phase2_handle_t *iph2 = NULL;
869 phase2_handle_t *next_iph2 = NULL;
870 struct saproto *pr;
871
872 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
873 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
874 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
875 continue;
876 }
877 if (iph2->proposal == NULL && iph2->approval == NULL)
878 continue;
879 if (cmpsaddrwop(src, iph2->src) != 0 ||
880 cmpsaddrwop(dst, iph2->dst) != 0) {
881 continue;
882 }
883 if (iph2->approval != NULL) {
884 for (pr = iph2->approval->head; pr != NULL;
885 pr = pr->next) {
886 if (proto_id == pr->proto_id)
887 goto zap_it;
888 }
889 } else if (iph2->proposal != NULL) {
890 for (pr = iph2->proposal->head; pr != NULL;
891 pr = pr->next) {
892 if (proto_id == pr->proto_id)
893 goto zap_it;
894 }
895 }
896 continue;
897 zap_it:
898 plog(ASL_LEVEL_DEBUG,
899 "deleteallph2: got a ph2 handler...\n");
900 if (FSM_STATE_IS_ESTABLISHED(iph2->status))
901 isakmp_info_send_d2(iph2);
902 ike_session_stopped_by_controller(iph2->parent_session,
903 ike_session_stopped_by_flush);
904 ike_session_unlink_phase2(iph2);
905 }
906 }
907 }
908
909 /*
910 * Delete all Phase 1 handlers for this src/dst.
911 */
912 void
913 ike_session_deleteallph1(struct sockaddr_storage *src, struct sockaddr_storage *dst)
914 {
915 ike_session_t *session = NULL;
916 ike_session_t *next_session = NULL;
917 phase1_handle_t *iph1 = NULL;
918 phase1_handle_t *next_iph1 = NULL;
919
920 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
921 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) {
922 if (cmpsaddrwop(src, iph1->local) != 0 ||
923 cmpsaddrwop(dst, iph1->remote) != 0) {
924 continue;
925 }
926 plog(ASL_LEVEL_DEBUG,
927 "deleteallph1: got a ph1 handler...\n");
928 if (FSM_STATE_IS_ESTABLISHED(iph1->status))
929 isakmp_info_send_d1(iph1);
930
931 ike_session_stopped_by_controller(iph1->parent_session, ike_session_stopped_by_flush);
932 ike_session_unlink_phase1(iph1);
933 }
934 }
935 }
936
937
938 /* %%% management contacted list */
939 /*
940 * search contacted list.
941 */
942 struct contacted *
943 ike_session_getcontacted(remote)
944 struct sockaddr_storage *remote;
945 {
946 struct contacted *p;
947
948 LIST_FOREACH(p, &ctdtree, chain) {
949 if (cmpsaddrstrict(remote, p->remote) == 0)
950 return p;
951 }
952
953 return NULL;
954 }
955
956 /*
957 * create new isakmp Phase 2 status record to handle isakmp in Phase2
958 */
959 int
960 ike_session_inscontacted(remote)
961 struct sockaddr_storage *remote;
962 {
963 struct contacted *new;
964
965 /* create new iph2 */
966 new = racoon_calloc(1, sizeof(*new));
967 if (new == NULL)
968 return -1;
969
970 new->remote = dupsaddr(remote);
971 if (new->remote == NULL) {
972 plog(ASL_LEVEL_ERR,
973 "failed to allocate buffer.\n");
974 racoon_free(new);
975 return -1;
976 }
977
978 LIST_INSERT_HEAD(&ctdtree, new, chain);
979
980 return 0;
981 }
982
983
984 void
985 ike_session_clear_contacted()
986 {
987 struct contacted *c, *next;
988 LIST_FOREACH_SAFE(c, &ctdtree, chain, next) {
989 LIST_REMOVE(c, chain);
990 racoon_free(c->remote);
991 racoon_free(c);
992 }
993 }
994
995 void
996 ike_session_initctdtree()
997 {
998 LIST_INIT(&ctdtree);
999 }
1000
1001 time_t
1002 ike_session_get_exp_retx_interval (int num_retries, int fixed_retry_interval)
1003 {
1004 // first 3 retries aren't exponential
1005 if (num_retries <= 3) {
1006 return (time_t)fixed_retry_interval;
1007 } else {
1008 return (time_t)(num_retries * fixed_retry_interval);
1009 }
1010 }
1011
1012 /*
1013 * check the response has been sent to the peer. when not, simply reply
1014 * the buffered packet to the peer.
1015 * OUT:
1016 * 0: the packet is received at the first time.
1017 * 1: the packet was processed before.
1018 * 2: the packet was processed before, but the address mismatches.
1019 * -1: error happened.
1020 */
1021 int
1022 ike_session_check_recvdpkt(remote, local, rbuf)
1023 struct sockaddr_storage *remote, *local;
1024 vchar_t *rbuf;
1025 {
1026 vchar_t *hash;
1027 struct recvdpkt *r;
1028 time_t t, d;
1029 int len, s;
1030
1031 /* set current time */
1032 t = time(NULL);
1033
1034 hash = eay_md5_one(rbuf);
1035 if (!hash) {
1036 plog(ASL_LEVEL_ERR,
1037 "failed to allocate buffer.\n");
1038 return -1;
1039 }
1040
1041 LIST_FOREACH(r, &rcptree, chain) {
1042 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
1043 break;
1044 }
1045 vfree(hash);
1046
1047 /* this is the first time to receive the packet */
1048 if (r == NULL)
1049 return 0;
1050
1051 /*
1052 * the packet was processed before, but the remote address mismatches.
1053 * ignore the port to accomodate port changes (e.g. floating).
1054 */
1055 if (cmpsaddrwop(remote, r->remote) != 0) {
1056 return 2;
1057 }
1058
1059 /*
1060 * it should not check the local address because the packet
1061 * may arrive at other interface.
1062 */
1063
1064 /* check the previous time to send */
1065 if (t - r->time_send < 1) {
1066 plog(ASL_LEVEL_WARNING,
1067 "the packet retransmitted in a short time from %s\n",
1068 saddr2str((struct sockaddr *)remote));
1069 /*XXX should it be error ? */
1070 }
1071
1072 /* select the socket to be sent */
1073 s = getsockmyaddr((struct sockaddr *)r->local);
1074 if (s == -1)
1075 return -1;
1076
1077 // don't send if we recently sent a response.
1078 if (r->time_send && t > r->time_send) {
1079 d = t - r->time_send;
1080 if (d < r->retry_interval) {
1081 plog(ASL_LEVEL_ERR, "already responded within the past %ld secs\n", d);
1082 return 1;
1083 }
1084 }
1085
1086 #ifdef ENABLE_FRAG
1087 if (r->frag_flags && r->sendbuf->l > ISAKMP_FRAG_MAXLEN) {
1088 /* resend the packet if needed */
1089 plog(ASL_LEVEL_ERR, "!!! retransmitting frags\n");
1090 len = sendfragsfromto(s, r->sendbuf,
1091 r->local, r->remote, lcconf->count_persend,
1092 r->frag_flags);
1093 } else {
1094 plog(ASL_LEVEL_ERR, "!!! skipped retransmitting frags: frag_flags %x, r->sendbuf->l %zu, max %d\n", r->frag_flags, r->sendbuf->l, ISAKMP_FRAG_MAXLEN);
1095 /* resend the packet if needed */
1096 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
1097 r->local, r->remote, lcconf->count_persend);
1098 }
1099 #else
1100 /* resend the packet if needed */
1101 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
1102 r->local, r->remote, lcconf->count_persend);
1103 #endif
1104 if (len == -1) {
1105 plog(ASL_LEVEL_ERR, "sendfromto failed\n");
1106 return -1;
1107 }
1108
1109 /* check the retry counter */
1110 r->retry_counter--;
1111 if (r->retry_counter <= 0) {
1112 ike_session_rem_recvdpkt(r);
1113 ike_session_del_recvdpkt(r);
1114 plog(ASL_LEVEL_DEBUG,
1115 "deleted the retransmission packet to %s.\n",
1116 saddr2str((struct sockaddr *)remote));
1117 } else {
1118 r->time_send = t;
1119 r->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - r->retry_counter),
1120 lcconf->retry_interval);
1121 }
1122
1123 return 1;
1124 }
1125
1126 /*
1127 * adding a hash of received packet into the received list.
1128 */
1129 int
1130 ike_session_add_recvdpkt(remote, local, sbuf, rbuf, non_esp, frag_flags)
1131 struct sockaddr_storage *remote, *local;
1132 vchar_t *sbuf, *rbuf;
1133 size_t non_esp;
1134 u_int32_t frag_flags;
1135 {
1136 struct recvdpkt *new = NULL;
1137
1138 if (lcconf->retry_counter == 0) {
1139 /* no need to add it */
1140 return 0;
1141 }
1142
1143 new = racoon_calloc(1, sizeof(*new));
1144 if (!new) {
1145 plog(ASL_LEVEL_ERR,
1146 "failed to allocate buffer.\n");
1147 return -1;
1148 }
1149
1150 new->hash = eay_md5_one(rbuf);
1151 if (!new->hash) {
1152 plog(ASL_LEVEL_ERR,
1153 "failed to allocate buffer.\n");
1154 ike_session_del_recvdpkt(new);
1155 return -1;
1156 }
1157 new->remote = dupsaddr(remote);
1158 if (new->remote == NULL) {
1159 plog(ASL_LEVEL_ERR,
1160 "failed to allocate buffer.\n");
1161 ike_session_del_recvdpkt(new);
1162 return -1;
1163 }
1164 new->local = dupsaddr(local);
1165 if (new->local == NULL) {
1166 plog(ASL_LEVEL_ERR,
1167 "failed to allocate buffer.\n");
1168 ike_session_del_recvdpkt(new);
1169 return -1;
1170 }
1171
1172 if (non_esp) {
1173 plog (ASL_LEVEL_DEBUG, "Adding NON-ESP marker\n");
1174
1175 /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1176 must added just before the packet itself. For this we must
1177 allocate a new buffer and release it at the end. */
1178 if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) {
1179 plog(ASL_LEVEL_ERR,
1180 "failed to allocate extra buf for non-esp\n");
1181 ike_session_del_recvdpkt(new);
1182 return -1;
1183 }
1184 *ALIGNED_CAST(u_int32_t *)new->sendbuf->v = 0;
1185 memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l);
1186 } else {
1187 new->sendbuf = vdup(sbuf);
1188 if (new->sendbuf == NULL) {
1189 plog(ASL_LEVEL_ERR,
1190 "failed to allocate buffer.\n");
1191 ike_session_del_recvdpkt(new);
1192 return -1;
1193 }
1194 }
1195
1196 new->retry_counter = lcconf->retry_counter;
1197 new->time_send = 0;
1198 new->created = time(NULL);
1199 #ifdef ENABLE_FRAG
1200 if (frag_flags) {
1201 new->frag_flags = frag_flags;
1202 }
1203 #endif
1204 new->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - new->retry_counter),
1205 lcconf->retry_interval);
1206
1207 LIST_INSERT_HEAD(&rcptree, new, chain);
1208
1209 return 0;
1210 }
1211
1212 void
1213 ike_session_del_recvdpkt(r)
1214 struct recvdpkt *r;
1215 {
1216 if (r->remote)
1217 racoon_free(r->remote);
1218 if (r->local)
1219 racoon_free(r->local);
1220 if (r->hash)
1221 vfree(r->hash);
1222 if (r->sendbuf)
1223 vfree(r->sendbuf);
1224 racoon_free(r);
1225 }
1226
1227 void
1228 ike_session_rem_recvdpkt(r)
1229 struct recvdpkt *r;
1230 {
1231 LIST_REMOVE(r, chain);
1232 }
1233
1234 void
1235 sweep_recvdpkt(dummy)
1236 void *dummy;
1237 {
1238 struct recvdpkt *r, *next;
1239 time_t t, lt;
1240
1241 /* set current time */
1242 t = time(NULL);
1243
1244 /* set the lifetime of the retransmission */
1245 lt = lcconf->retry_counter * lcconf->retry_interval;
1246
1247 LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
1248 if (t - r->created > lt) {
1249 ike_session_rem_recvdpkt(r);
1250 ike_session_del_recvdpkt(r);
1251 }
1252 }
1253
1254 sched_new(lt, sweep_recvdpkt, &rcptree);
1255 }
1256
1257 void
1258 ike_session_clear_recvdpkt()
1259 {
1260 struct recvdpkt *r, *next;
1261
1262 LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
1263 ike_session_rem_recvdpkt(r);
1264 ike_session_del_recvdpkt(r);
1265 }
1266 sched_scrub_param(&rcptree);
1267 }
1268
1269 void
1270 ike_session_init_recvdpkt()
1271 {
1272 time_t lt = lcconf->retry_counter * lcconf->retry_interval;
1273
1274 LIST_INIT(&rcptree);
1275
1276 sched_new(lt, sweep_recvdpkt, &rcptree);
1277 }
1278
1279 #ifdef NOT_USED
1280 #ifdef ENABLE_HYBRID
1281 /*
1282 * Returns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
1283 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
1284 */
1285 int
1286 exclude_cfg_addr(const struct sockaddr_storage *addr)
1287 {
1288 ike_session_t *session;
1289 phase1_handle_t *p;
1290 struct sockaddr_in *sin;
1291
1292 LIST_FOREACH(session, &ike_session_tree, chain) {
1293 LIST_FOREACH(p, &session->ph1tree, chain) {
1294 if ((p->mode_cfg != NULL) &&
1295 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
1296 (addr->ss_family == AF_INET)) {
1297 sin = (struct sockaddr_in *)addr;
1298 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
1299 return 0;
1300 }
1301 }
1302 }
1303
1304 return 1;
1305 }
1306 #endif
1307 #endif /* NOT_USED */
1308
1309 int
1310 ike_session_expire_session(ike_session_t *session)
1311 {
1312 int found = 0;
1313 phase1_handle_t *p;
1314 phase1_handle_t *next;
1315 phase2_handle_t *p2;
1316
1317 if (session == NULL)
1318 return 0;
1319
1320 LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) {
1321 if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) {
1322 continue;
1323 }
1324
1325 if (FSM_STATE_IS_ESTABLISHED(p2->status))
1326 isakmp_info_send_d2(p2);
1327 isakmp_ph2expire(p2);
1328 found++;
1329 }
1330
1331 LIST_FOREACH_SAFE(p, &session->ph1tree, ph1ofsession_chain, next) {
1332 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
1333 continue;
1334 }
1335
1336 ike_session_purge_ph2s_by_ph1(p);
1337 if (FSM_STATE_IS_ESTABLISHED(p->status))
1338 isakmp_info_send_d1(p);
1339 isakmp_ph1expire(p);
1340 found++;
1341 }
1342
1343 return found;
1344 }
1345
1346 #ifdef ENABLE_HYBRID
1347 int
1348 ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote)
1349 {
1350 int found = 0;
1351 ike_session_t *session = NULL;
1352 ike_session_t *next_session = NULL;
1353 phase1_handle_t *p;
1354 phase2_handle_t *p2;
1355
1356 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1357 LIST_FOREACH(p2, &session->ph2tree, ph2ofsession_chain) {
1358 if (p2->is_dying || FSM_STATE_IS_EXPIRED(p2->status)) {
1359 continue;
1360 }
1361 if (cmpsaddrwop(remote, p2->dst) == 0) {
1362 plog(ASL_LEVEL_DEBUG,
1363 "in %s... purging Phase 2 structures\n", __FUNCTION__);
1364 if (FSM_STATE_IS_ESTABLISHED(p2->status))
1365 isakmp_info_send_d2(p2);
1366 isakmp_ph2expire(p2);
1367 found++;
1368 }
1369 }
1370
1371 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
1372 if (p->is_dying || FSM_STATE_IS_EXPIRED(p->status)) {
1373 continue;
1374 }
1375 if (cmpsaddrwop(remote, p->remote) == 0) {
1376 plog(ASL_LEVEL_DEBUG,
1377 "in %s... purging Phase 1 and related Phase 2 structures\n", __FUNCTION__);
1378 ike_session_purge_ph2s_by_ph1(p);
1379 if (FSM_STATE_IS_ESTABLISHED(p->status))
1380 isakmp_info_send_d1(p);
1381 isakmp_ph1expire(p);
1382 found++;
1383 }
1384 }
1385 }
1386
1387 return found;
1388 }
1389
1390 void
1391 ike_session_purgephXbyspid(u_int32_t spid, int del_boundph1)
1392 {
1393 ike_session_t *session = NULL;
1394 ike_session_t *next_session = NULL;
1395 phase2_handle_t *iph2 = NULL;
1396 phase2_handle_t *next_iph2 = NULL;
1397 phase1_handle_t *iph1 = NULL;
1398 phase1_handle_t *next_iph1 = NULL;
1399
1400 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1401 // do ph2's first... we need the ph1s for notifications
1402 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1403 if (spid == iph2->spid) {
1404 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
1405 continue;
1406 }
1407 if (FSM_STATE_IS_ESTABLISHED(iph2->status)) {
1408 isakmp_info_send_d2(iph2);
1409 }
1410 ike_session_stopped_by_controller(iph2->parent_session,
1411 ike_session_stopped_by_flush);
1412 isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
1413 }
1414 }
1415
1416 // do the ph1s last. %%%%%%%%%%%%%%%%%% re-organize this - check del_boundph1 first
1417 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1418 if (spid == iph2->spid) {
1419 if (del_boundph1 && iph2->parent_session) {
1420 LIST_FOREACH_SAFE(iph1, &iph2->parent_session->ph1tree, ph1ofsession_chain, next_iph1) {
1421 if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
1422 continue;
1423 }
1424 if (FSM_STATE_IS_ESTABLISHED(iph1->status)) {
1425 isakmp_info_send_d1(iph1);
1426 }
1427 isakmp_ph1expire(iph1);
1428 }
1429 }
1430 }
1431 }
1432 }
1433 }
1434
1435 #endif
1436
1437 #ifdef ENABLE_DPD
1438 int
1439 ike_session_ph1_force_dpd (struct sockaddr_storage *remote)
1440 {
1441 int status = -1;
1442 ike_session_t *session = NULL;
1443 phase1_handle_t *p = NULL;
1444
1445 LIST_FOREACH(session, &ike_session_tree, chain) {
1446 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
1447 if (cmpsaddrwop(remote, p->remote) == 0) {
1448 if (FSM_STATE_IS_ESTABLISHED(p->status) &&
1449 !p->is_dying &&
1450 p->dpd_support &&
1451 p->rmconf->dpd_interval) {
1452 if(!p->dpd_fails) {
1453 isakmp_info_send_r_u(p);
1454 status = 0;
1455 } else {
1456 plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n");
1457 }
1458 if (p->parent_session) {
1459 p->parent_session->controller_awaiting_peer_resp = 1;
1460 }
1461 } else {
1462 plog(ASL_LEVEL_DEBUG, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
1463 p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
1464 }
1465 }
1466 }
1467 }
1468
1469 return status;
1470 }
1471 #endif
1472
1473 void
1474 sweep_sleepwake(void)
1475 {
1476 ike_session_t *session = NULL;
1477 ike_session_t *next_session = NULL;
1478 phase2_handle_t *iph2 = NULL;
1479 phase2_handle_t *next_iph2 = NULL;
1480 phase1_handle_t *iph1 = NULL;
1481 phase1_handle_t *next_iph1 = NULL;
1482
1483 LIST_FOREACH_SAFE(session, &ike_session_tree, chain, next_session) {
1484 // do the ph1s.
1485 LIST_FOREACH_SAFE(iph1, &session->ph1tree, ph1ofsession_chain, next_iph1) {
1486 if (iph1->parent_session && iph1->parent_session->is_asserted) {
1487 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's been asserted.\n",
1488 isakmp_pindex(&iph1->index, 0));
1489 continue;
1490 }
1491 if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
1492 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 1 %s because it's already expired.\n",
1493 isakmp_pindex(&iph1->index, 0));
1494 continue;
1495 }
1496 if (iph1->sce) {
1497 time_t xtime;
1498 if (sched_get_time(iph1->sce, &xtime)) {
1499 if (xtime <= swept_at) {
1500 SCHED_KILL(iph1->sce);
1501 SCHED_KILL(iph1->sce_rekey);
1502 iph1->is_dying = 1;
1503 fsm_set_state(&iph1->status, IKEV1_STATE_PHASE1_EXPIRED);
1504 ike_session_update_ph1_ph2tree(iph1); // move unbind/rebind ph2s to from current ph1
1505 iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
1506 plog(ASL_LEVEL_DEBUG, "Phase 1 %s expired while sleeping: quick deletion.\n",
1507 isakmp_pindex(&iph1->index, 0));
1508 }
1509 }
1510 }
1511 if (iph1->sce_rekey) {
1512 time_t xtime;
1513 if (sched_get_time(iph1->sce_rekey, &xtime)) {
1514 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1515 SCHED_KILL(iph1->sce_rekey);
1516 }
1517 }
1518 }
1519 if (iph1->scr) {
1520 time_t xtime;
1521 if (sched_get_time(iph1->scr, &xtime)) {
1522 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1523 SCHED_KILL(iph1->scr);
1524 }
1525 }
1526 }
1527 #ifdef ENABLE_DPD
1528 if (iph1->dpd_r_u) {
1529 time_t xtime;
1530 if (sched_get_time(iph1->dpd_r_u, &xtime)) {
1531 if (FSM_STATE_IS_EXPIRED(iph1->status) || xtime <= swept_at) {
1532 SCHED_KILL(iph1->dpd_r_u);
1533 }
1534 }
1535 }
1536 #endif
1537 }
1538
1539 // do ph2's next
1540 LIST_FOREACH_SAFE(iph2, &session->ph2tree, ph2ofsession_chain, next_iph2) {
1541 if (iph2->parent_session && iph2->parent_session->is_asserted) {
1542 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's been asserted.\n");
1543 continue;
1544 }
1545 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
1546 plog(ASL_LEVEL_DEBUG, "Skipping sweep of Phase 2 because it's already expired.\n");
1547 continue;
1548 }
1549 if (iph2->sce) {
1550 time_t xtime;
1551 if (sched_get_time(iph2->sce, &xtime)) {
1552 if (xtime <= swept_at) {
1553 fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
1554 iph2->is_dying = 1;
1555 isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
1556 ike_session_stopped_by_controller(iph2->parent_session,
1557 ike_session_stopped_by_sleepwake);
1558 plog(ASL_LEVEL_DEBUG, "Phase 2 expired while sleeping: quick deletion.\n");
1559 }
1560 }
1561 }
1562 if (iph2->scr) {
1563 time_t xtime;
1564 if (sched_get_time(iph2->scr, &xtime)) {
1565 if (FSM_STATE_IS_EXPIRED(iph2->status) || xtime <= swept_at) {
1566 SCHED_KILL(iph2->scr);
1567 }
1568 }
1569 }
1570 }
1571 }
1572 //%%%%%%%%%%%%%%% fix this
1573 // do the ike_session last
1574 ike_session_sweep_sleepwake();
1575 }