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