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