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