]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/handler.c
ipsec-326.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
A
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"
52b7d2ce
A
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"
d1e348cf 73#include "ike_session.h"
65c25746 74#include "isakmp_frag.h"
d1e348cf
A
75
76#include "sainfo.h"
52b7d2ce 77
e8d9021d 78#include "power_mgmt.h"
52b7d2ce 79
65c25746 80extern LIST_HEAD(_ike_session_tree_, ike_session) ike_session_tree;
52b7d2ce
A
81static LIST_HEAD(_ctdtree_, contacted) ctdtree;
82static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
83
65c25746
A
84static void ike_session_del_recvdpkt (struct recvdpkt *);
85static void ike_session_rem_recvdpkt (struct recvdpkt *);
86static void sweep_recvdpkt (void *);
52b7d2ce
A
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
65c25746 96extern caddr_t val2str (const char *, size_t);
52b7d2ce 97
65c25746
A
98static phase1_handle_t *
99getph1byindex(ike_session_t *session, isakmp_index *index)
52b7d2ce 100{
65c25746
A
101 phase1_handle_t *p = NULL;
102
103 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
104 if (FSM_STATE_IS_EXPIRED(p->status))
52b7d2ce
A
105 continue;
106 if (memcmp(&p->index, index, sizeof(*index)) == 0)
107 return p;
108 }
65c25746 109
52b7d2ce
A
110 return NULL;
111}
112
65c25746
A
113phase1_handle_t *
114ike_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
52b7d2ce
A
130/*
131 * search for isakmp handler by i_ck in index.
132 */
52b7d2ce 133
65c25746
A
134static phase1_handle_t *
135getph1byindex0 (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}
52b7d2ce 147
65c25746
A
148phase1_handle_t *
149ike_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
52b7d2ce
A
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 */
65c25746
A
170phase1_handle_t *
171ike_session_getph1byaddr(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
52b7d2ce 172{
65c25746
A
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))
52b7d2ce 181 continue;
65c25746
A
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));
52b7d2ce 184 if (CMPSADDR(local, p->local) == 0
d1e348cf 185 && CMPSADDR(remote, p->remote) == 0){
65c25746 186 plog(ASL_LEVEL_DEBUG, "matched\n");
52b7d2ce 187 return p;
d1e348cf 188 }
52b7d2ce 189 }
65c25746
A
190
191 plog(ASL_LEVEL_DEBUG, "no match\n");
192
52b7d2ce
A
193 return NULL;
194}
195
65c25746
A
196static phase1_handle_t *
197sgetph1byaddrwop(ike_session_t *session, struct sockaddr_storage *local, struct sockaddr_storage *remote)
52b7d2ce 198{
65c25746
A
199 phase1_handle_t *p = NULL;
200
201 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
202 if (FSM_STATE_IS_EXPIRED(p->status))
52b7d2ce
A
203 continue;
204 if (cmpsaddrwop(local, p->local) == 0
65c25746 205 && cmpsaddrwop(remote, p->remote) == 0)
52b7d2ce
A
206 return p;
207 }
65c25746
A
208
209 return NULL;
210}
52b7d2ce 211
65c25746
A
212phase1_handle_t *
213ike_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
52b7d2ce
A
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 */
65c25746
A
234phase1_handle_t *
235sike_session_getph1bydstaddrwop(ike_session_t *session, struct sockaddr_storage *remote)
52b7d2ce 236{
65c25746
A
237 phase1_handle_t *p = NULL;
238
239 LIST_FOREACH(p, &session->ph1tree, ph1ofsession_chain) {
d06a7ccb 240 if (FSM_STATE_IS_EXPIRED(p->status)) {
65c25746 241 continue;
d06a7ccb
A
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) {
65c25746 251 return p;
d06a7ccb 252 }
65c25746
A
253 }
254
255 return NULL;
256}
52b7d2ce 257
65c25746
A
258phase1_handle_t *
259ike_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;
52b7d2ce
A
273}
274
d1e348cf 275int
65c25746 276ike_session_islast_ph1(phase1_handle_t *ph1)
d1e348cf 277{
65c25746
A
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))
d1e348cf
A
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
52b7d2ce
A
292/*
293 * create new isakmp Phase 1 status record to handle isakmp in Phase1
294 */
65c25746
A
295phase1_handle_t *
296ike_session_newph1(unsigned int version)
52b7d2ce 297{
65c25746
A
298 phase1_handle_t *iph1;
299
52b7d2ce
A
300 /* create new iph1 */
301 iph1 = racoon_calloc(1, sizeof(*iph1));
302 if (iph1 == NULL)
303 return NULL;
65c25746 304 iph1->version = version;
52b7d2ce
A
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;
d1e348cf 311 iph1->peer_sent_ike = 0;
52b7d2ce
A
312 iph1->dpd_r_u = NULL;
313#endif
d1e348cf
A
314#ifdef ENABLE_VPNCONTROL_PORT
315 iph1->ping_sched = NULL;
316#endif
317 iph1->is_dying = 0;
7ebaebe2 318 plog(ASL_LEVEL_NOTICE, "New Phase 1\n");
52b7d2ce
A
319 return iph1;
320}
321
322/*
323 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
324 */
325void
65c25746 326ike_session_delph1(phase1_handle_t *iph1)
52b7d2ce 327{
d1e348cf
A
328 if (iph1 == NULL)
329 return;
65c25746 330
52b7d2ce 331#ifdef ENABLE_NATT
52b7d2ce
A
332 if (iph1->natt_options) {
333 racoon_free(iph1->natt_options);
334 iph1->natt_options = NULL;
335 }
336#endif
65c25746 337
d1e348cf
A
338#ifdef ENABLE_HYBRID
339 if (iph1->mode_cfg)
340 isakmp_cfg_rmstate(iph1);
341 VPTRINIT(iph1->xauth_awaiting_userinput_msg);
342#endif
65c25746 343
52b7d2ce 344#ifdef ENABLE_DPD
65c25746 345 if (iph1->dpd_r_u)
52b7d2ce
A
346 SCHED_KILL(iph1->dpd_r_u);
347#endif
d1e348cf 348#ifdef ENABLE_VPNCONTROL_PORT
65c25746 349 if (iph1->ping_sched)
d1e348cf
A
350 SCHED_KILL(iph1->ping_sched);
351#endif
65c25746 352
52b7d2ce
A
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 }
65c25746 361
52b7d2ce
A
362 if (iph1->approval) {
363 delisakmpsa(iph1->approval);
364 iph1->approval = NULL;
365 }
65c25746 366
52b7d2ce 367 sched_scrub_param(iph1);
65c25746
A
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
52b7d2ce 375 VPTRINIT(iph1->sendbuf);
65c25746 376
52b7d2ce
A
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);
65c25746 386 VPTRINIT(iph1->skeyid_a_p);
52b7d2ce 387 VPTRINIT(iph1->skeyid_e);
65c25746 388 VPTRINIT(iph1->skeyid_e_p);
52b7d2ce 389 VPTRINIT(iph1->key);
65c25746 390 VPTRINIT(iph1->key_p);
52b7d2ce
A
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);
65c25746 404
d1e348cf
A
405 if(iph1->approval != NULL)
406 delisakmpsa(iph1->approval);
65c25746 407
52b7d2ce
A
408 if (iph1->ivm) {
409 oakley_delivm(iph1->ivm);
410 iph1->ivm = NULL;
411 }
65c25746 412
52b7d2ce
A
413 VPTRINIT(iph1->sa);
414 VPTRINIT(iph1->sa_ret);
65c25746 415
d1e348cf 416 if (iph1->rmconf) {
65c25746 417 release_rmconf(iph1->rmconf);
d1e348cf
A
418 iph1->rmconf = NULL;
419 }
65c25746 420
52b7d2ce
A
421 racoon_free(iph1);
422}
423
52b7d2ce 424void
65c25746 425ike_session_flush_all_phase1_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
52b7d2ce 426{
65c25746
A
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) {
7ebaebe2 431 plog(ASL_LEVEL_NOTICE,
65c25746
A
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))) {
7ebaebe2 441 plog(ASL_LEVEL_NOTICE,
65c25746
A
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 */
7ebaebe2 447 plog(ASL_LEVEL_NOTICE,
65c25746
A
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 }
52b7d2ce
A
458}
459
460/*
461 * flush isakmp-sa
462 */
463void
65c25746 464ike_session_flush_all_phase1(int ignore_estab_or_assert_handles)
52b7d2ce 465{
65c25746
A
466 ike_session_t *session = NULL;
467 ike_session_t *next_session = NULL;
d1e348cf 468
7ebaebe2 469 plog(ASL_LEVEL_NOTICE,
65c25746
A
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 }
52b7d2ce
A
475}
476
52b7d2ce 477
65c25746 478
52b7d2ce
A
479/*
480 * search ph2handle with policy id.
481 */
65c25746
A
482phase2_handle_t *
483ike_session_getph2byspid(u_int32_t spid)
52b7d2ce 484{
65c25746
A
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
52b7d2ce
A
499 return NULL;
500}
501
65c25746 502
52b7d2ce
A
503/*
504 * search ph2handle with sequence number.
65c25746 505 * Used by PF_KEY functions to locate the phase2
52b7d2ce 506 */
65c25746
A
507phase2_handle_t *
508ike_session_getph2byseq(u_int32_t seq)
52b7d2ce 509{
65c25746
A
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 }
52b7d2ce
A
519 return NULL;
520}
521
522/*
523 * search ph2handle with message id.
524 */
65c25746
A
525phase2_handle_t *
526ike_session_getph2bymsgid(phase1_handle_t *iph1, u_int32_t msgid)
52b7d2ce 527{
65c25746
A
528 phase2_handle_t *p;
529
530 LIST_FOREACH(p, &iph1->parent_session->ph2tree, ph2ofsession_chain) {
d9c572c0 531 if (p->msgid == msgid && !p->is_defunct)
52b7d2ce
A
532 return p;
533 }
65c25746 534
52b7d2ce
A
535 return NULL;
536}
537
65c25746
A
538phase2_handle_t *
539ike_session_getonlyph2(phase1_handle_t *iph1)
52b7d2ce 540{
65c25746
A
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}
52b7d2ce 551
65c25746
A
552phase2_handle_t *
553ike_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){
7ebaebe2 574 plog(ASL_LEVEL_NOTICE,
65c25746
A
575 "Zombie ph2 found, expiring it\n");
576 isakmp_ph2expire(p);
577 }else
578 return p;
579 }
580 }
581 }
582
52b7d2ce
A
583 return NULL;
584}
585
65c25746
A
586#ifdef NOT_USED
587phase2_handle_t *
588ike_session_getph2bysaddr(struct sockaddr_storage *src, struct sockaddr_storage *dst)
52b7d2ce 589{
65c25746
A
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
52b7d2ce
A
601 return NULL;
602}
65c25746 603#endif /* NOT_USED */
52b7d2ce
A
604
605/*
606 * call by pk_recvexpire().
607 */
65c25746
A
608phase2_handle_t *
609ike_session_getph2bysaidx(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id, u_int32_t spi)
52b7d2ce 610{
65c25746
A
611 ike_session_t *session;
612 phase2_handle_t *iph2;
52b7d2ce 613 struct saproto *pr;
65c25746
A
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}
52b7d2ce 641
65c25746
A
642phase2_handle_t *
643ike_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
52b7d2ce
A
681 return NULL;
682}
683
684/*
685 * create new isakmp Phase 2 status record to handle isakmp in Phase2
686 */
65c25746
A
687phase2_handle_t *
688ike_session_newph2(unsigned int version, int type)
52b7d2ce 689{
65c25746
A
690 phase2_handle_t *iph2 = NULL;
691
52b7d2ce
A
692 /* create new iph2 */
693 iph2 = racoon_calloc(1, sizeof(*iph2));
694 if (iph2 == NULL)
695 return NULL;
65c25746
A
696 iph2->version = version;
697 iph2->phase2_type = type;
d1e348cf 698 iph2->is_dying = 0;
65c25746 699
7ebaebe2 700 plog(ASL_LEVEL_NOTICE, "New Phase 2\n");
52b7d2ce
A
701 return iph2;
702}
703
704/*
705 * initialize ph2handle
706 * NOTE: don't initialize src/dst.
707 * SPI in the proposal is cleared.
708 */
709void
65c25746 710ike_session_initph2(phase2_handle_t *iph2)
52b7d2ce
A
711{
712 sched_scrub_param(iph2);
713 iph2->sce = NULL;
714 iph2->scr = NULL;
65c25746 715
52b7d2ce
A
716 VPTRINIT(iph2->sendbuf);
717 VPTRINIT(iph2->msg1);
65c25746 718
52b7d2ce
A
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 }
65c25746 725
52b7d2ce
A
726 /* clear approval */
727 if (iph2->approval) {
728 flushsaprop(iph2->approval);
729 iph2->approval = NULL;
730 }
65c25746 731
52b7d2ce
A
732 /* clear the generated policy */
733 if (iph2->spidx_gen) {
85f41bec 734 delsp_bothdir(iph2->spidx_gen);
52b7d2ce
A
735 racoon_free(iph2->spidx_gen);
736 iph2->spidx_gen = NULL;
737 }
65c25746 738
52b7d2ce
A
739 if (iph2->pfsgrp) {
740 oakley_dhgrp_free(iph2->pfsgrp);
741 iph2->pfsgrp = NULL;
742 }
65c25746 743
52b7d2ce
A
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);
65c25746 754
52b7d2ce
A
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 */
764void
65c25746 765ike_session_delph2(phase2_handle_t *iph2)
52b7d2ce 766{
65c25746
A
767 ike_session_initph2(iph2);
768
52b7d2ce
A
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) {
65c25746
A
778 racoon_free(iph2->src_id);
779 iph2->src_id = NULL;
52b7d2ce
A
780 }
781 if (iph2->dst_id) {
65c25746
A
782 racoon_free(iph2->dst_id);
783 iph2->dst_id = NULL;
52b7d2ce 784 }
65c25746 785
52b7d2ce
A
786 if (iph2->proposal) {
787 flushsaprop(iph2->proposal);
788 iph2->proposal = NULL;
789 }
65c25746 790
d1e348cf 791 if (iph2->sainfo) {
65c25746 792 release_sainfo(iph2->sainfo);
d1e348cf
A
793 iph2->sainfo = NULL;
794 }
65c25746
A
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
52b7d2ce
A
805 racoon_free(iph2);
806}
807
52b7d2ce 808void
65c25746 809ike_session_flush_all_phase2_for_session(ike_session_t *session, int ignore_estab_or_assert_handles)
52b7d2ce 810{
65c25746
A
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) {
7ebaebe2 818 plog(ASL_LEVEL_NOTICE,
65c25746
A
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) {
7ebaebe2 824 plog(ASL_LEVEL_NOTICE,
65c25746
A
825 "skipping ph2 handler that's established...\n");
826 continue;
827 }
828 /* send delete information */
7ebaebe2 829 plog(ASL_LEVEL_NOTICE,
65c25746
A
830 "got an established ph2 handler to flush...\n");
831 isakmp_info_send_d2(p);
832 }else{
7ebaebe2 833 plog(ASL_LEVEL_NOTICE,
65c25746
A
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 }
52b7d2ce
A
842}
843
844void
65c25746 845ike_session_flush_all_phase2(int ignore_estab_or_assert_handles)
52b7d2ce 846{
65c25746
A
847 ike_session_t *session = NULL;
848 ike_session_t *next_session = NULL;
849
7ebaebe2 850 plog(ASL_LEVEL_NOTICE,
e8d9021d 851 "flushing ph2 handles: ignore_estab_or_assert %d...\n", ignore_estab_or_assert_handles);
65c25746
A
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 }
52b7d2ce
A
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 */
65c25746 863//%%%%%%%%%%%%%%%%%%% make this smarter - find session using addresses ????
52b7d2ce 864void
65c25746 865ike_session_deleteallph2(struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int proto_id)
52b7d2ce 866{
65c25746
A
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;
52b7d2ce 871 struct saproto *pr;
65c25746
A
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 }
d1e348cf 897 continue;
65c25746 898 zap_it:
7ebaebe2 899 plog(ASL_LEVEL_NOTICE,
65c25746
A
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);
d1e348cf 906 }
65c25746 907 }
52b7d2ce
A
908}
909
d1e348cf
A
910/*
911 * Delete all Phase 1 handlers for this src/dst.
912 */
913void
65c25746 914ike_session_deleteallph1(struct sockaddr_storage *src, struct sockaddr_storage *dst)
d1e348cf 915{
65c25746
A
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 }
7ebaebe2 927 plog(ASL_LEVEL_NOTICE,
65c25746
A
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);
d1e348cf 934 }
65c25746 935 }
52b7d2ce
A
936}
937
d1e348cf 938
52b7d2ce
A
939/* %%% management contacted list */
940/*
941 * search contacted list.
942 */
943struct contacted *
65c25746
A
944ike_session_getcontacted(remote)
945struct sockaddr_storage *remote;
52b7d2ce
A
946{
947 struct contacted *p;
65c25746 948
52b7d2ce
A
949 LIST_FOREACH(p, &ctdtree, chain) {
950 if (cmpsaddrstrict(remote, p->remote) == 0)
951 return p;
952 }
65c25746 953
52b7d2ce
A
954 return NULL;
955}
956
957/*
958 * create new isakmp Phase 2 status record to handle isakmp in Phase2
959 */
960int
65c25746
A
961ike_session_inscontacted(remote)
962struct sockaddr_storage *remote;
52b7d2ce
A
963{
964 struct contacted *new;
65c25746 965
52b7d2ce
A
966 /* create new iph2 */
967 new = racoon_calloc(1, sizeof(*new));
968 if (new == NULL)
969 return -1;
65c25746
A
970
971 new->remote = dupsaddr(remote);
d1e348cf 972 if (new->remote == NULL) {
65c25746
A
973 plog(ASL_LEVEL_ERR,
974 "failed to allocate buffer.\n");
d1e348cf
A
975 racoon_free(new);
976 return -1;
977 }
65c25746 978
52b7d2ce 979 LIST_INSERT_HEAD(&ctdtree, new, chain);
65c25746 980
52b7d2ce
A
981 return 0;
982}
983
984
985void
65c25746 986ike_session_clear_contacted()
52b7d2ce
A
987{
988 struct contacted *c, *next;
65c25746 989 LIST_FOREACH_SAFE(c, &ctdtree, chain, next) {
52b7d2ce
A
990 LIST_REMOVE(c, chain);
991 racoon_free(c->remote);
992 racoon_free(c);
993 }
994}
995
996void
65c25746 997ike_session_initctdtree()
52b7d2ce
A
998{
999 LIST_INIT(&ctdtree);
1000}
1001
e8d9021d 1002time_t
65c25746 1003ike_session_get_exp_retx_interval (int num_retries, int fixed_retry_interval)
e8d9021d
A
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
52b7d2ce
A
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 */
1022int
65c25746
A
1023ike_session_check_recvdpkt(remote, local, rbuf)
1024struct sockaddr_storage *remote, *local;
1025vchar_t *rbuf;
52b7d2ce
A
1026{
1027 vchar_t *hash;
1028 struct recvdpkt *r;
e8d9021d 1029 time_t t, d;
52b7d2ce 1030 int len, s;
65c25746 1031
52b7d2ce
A
1032 /* set current time */
1033 t = time(NULL);
65c25746 1034
52b7d2ce
A
1035 hash = eay_md5_one(rbuf);
1036 if (!hash) {
65c25746
A
1037 plog(ASL_LEVEL_ERR,
1038 "failed to allocate buffer.\n");
52b7d2ce
A
1039 return -1;
1040 }
65c25746 1041
52b7d2ce
A
1042 LIST_FOREACH(r, &rcptree, chain) {
1043 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
1044 break;
1045 }
1046 vfree(hash);
65c25746 1047
52b7d2ce
A
1048 /* this is the first time to receive the packet */
1049 if (r == NULL)
1050 return 0;
65c25746 1051
52b7d2ce
A
1052 /*
1053 * the packet was processed before, but the remote address mismatches.
65c25746 1054 * ignore the port to accomodate port changes (e.g. floating).
52b7d2ce 1055 */
d1e348cf 1056 if (cmpsaddrwop(remote, r->remote) != 0) {
65c25746
A
1057 return 2;
1058 }
1059
52b7d2ce
A
1060 /*
1061 * it should not check the local address because the packet
1062 * may arrive at other interface.
1063 */
65c25746 1064
52b7d2ce
A
1065 /* check the previous time to send */
1066 if (t - r->time_send < 1) {
65c25746
A
1067 plog(ASL_LEVEL_WARNING,
1068 "the packet retransmitted in a short time from %s\n",
1069 saddr2str((struct sockaddr *)remote));
52b7d2ce
A
1070 /*XXX should it be error ? */
1071 }
65c25746 1072
52b7d2ce 1073 /* select the socket to be sent */
85f41bec 1074 s = getsockmyaddr((struct sockaddr *)r->local);
52b7d2ce
A
1075 if (s == -1)
1076 return -1;
65c25746 1077
e8d9021d
A
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) {
65c25746 1082 plog(ASL_LEVEL_ERR, "already responded within the past %ld secs\n", d);
e8d9021d
A
1083 return 1;
1084 }
1085 }
65c25746 1086
e8d9021d
A
1087#ifdef ENABLE_FRAG
1088 if (r->frag_flags && r->sendbuf->l > ISAKMP_FRAG_MAXLEN) {
1089 /* resend the packet if needed */
65c25746 1090 plog(ASL_LEVEL_ERR, "!!! retransmitting frags\n");
e8d9021d
A
1091 len = sendfragsfromto(s, r->sendbuf,
1092 r->local, r->remote, lcconf->count_persend,
1093 r->frag_flags);
1094 } else {
65c25746 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);
e8d9021d
A
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
52b7d2ce
A
1101 /* resend the packet if needed */
1102 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
65c25746 1103 r->local, r->remote, lcconf->count_persend);
e8d9021d 1104#endif
52b7d2ce 1105 if (len == -1) {
65c25746 1106 plog(ASL_LEVEL_ERR, "sendfromto failed\n");
52b7d2ce
A
1107 return -1;
1108 }
65c25746 1109
52b7d2ce
A
1110 /* check the retry counter */
1111 r->retry_counter--;
1112 if (r->retry_counter <= 0) {
65c25746
A
1113 ike_session_rem_recvdpkt(r);
1114 ike_session_del_recvdpkt(r);
7ebaebe2 1115 plog(ASL_LEVEL_NOTICE,
65c25746
A
1116 "deleted the retransmission packet to %s.\n",
1117 saddr2str((struct sockaddr *)remote));
e8d9021d 1118 } else {
52b7d2ce 1119 r->time_send = t;
65c25746 1120 r->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - r->retry_counter),
e8d9021d
A
1121 lcconf->retry_interval);
1122 }
65c25746 1123
52b7d2ce
A
1124 return 1;
1125}
1126
1127/*
1128 * adding a hash of received packet into the received list.
1129 */
1130int
65c25746
A
1131ike_session_add_recvdpkt(remote, local, sbuf, rbuf, non_esp, frag_flags)
1132struct sockaddr_storage *remote, *local;
1133vchar_t *sbuf, *rbuf;
1134size_t non_esp;
1135u_int32_t frag_flags;
52b7d2ce
A
1136{
1137 struct recvdpkt *new = NULL;
65c25746 1138
52b7d2ce
A
1139 if (lcconf->retry_counter == 0) {
1140 /* no need to add it */
1141 return 0;
1142 }
65c25746 1143
52b7d2ce
A
1144 new = racoon_calloc(1, sizeof(*new));
1145 if (!new) {
65c25746
A
1146 plog(ASL_LEVEL_ERR,
1147 "failed to allocate buffer.\n");
52b7d2ce
A
1148 return -1;
1149 }
65c25746 1150
52b7d2ce
A
1151 new->hash = eay_md5_one(rbuf);
1152 if (!new->hash) {
65c25746
A
1153 plog(ASL_LEVEL_ERR,
1154 "failed to allocate buffer.\n");
1155 ike_session_del_recvdpkt(new);
52b7d2ce
A
1156 return -1;
1157 }
65c25746 1158 new->remote = dupsaddr(remote);
52b7d2ce 1159 if (new->remote == NULL) {
65c25746
A
1160 plog(ASL_LEVEL_ERR,
1161 "failed to allocate buffer.\n");
1162 ike_session_del_recvdpkt(new);
52b7d2ce
A
1163 return -1;
1164 }
65c25746 1165 new->local = dupsaddr(local);
52b7d2ce 1166 if (new->local == NULL) {
65c25746
A
1167 plog(ASL_LEVEL_ERR,
1168 "failed to allocate buffer.\n");
1169 ike_session_del_recvdpkt(new);
52b7d2ce
A
1170 return -1;
1171 }
65c25746 1172
d1e348cf 1173 if (non_esp) {
65c25746
A
1174 plog (ASL_LEVEL_DEBUG, "Adding NON-ESP marker\n");
1175
d1e348cf
A
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) {
65c25746 1180 plog(ASL_LEVEL_ERR,
d1e348cf 1181 "failed to allocate extra buf for non-esp\n");
65c25746 1182 ike_session_del_recvdpkt(new);
d1e348cf
A
1183 return -1;
1184 }
85f41bec 1185 *ALIGNED_CAST(u_int32_t *)new->sendbuf->v = 0;
d1e348cf
A
1186 memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l);
1187 } else {
1188 new->sendbuf = vdup(sbuf);
1189 if (new->sendbuf == NULL) {
65c25746 1190 plog(ASL_LEVEL_ERR,
d1e348cf 1191 "failed to allocate buffer.\n");
65c25746 1192 ike_session_del_recvdpkt(new);
d1e348cf
A
1193 return -1;
1194 }
1195 }
65c25746 1196
52b7d2ce
A
1197 new->retry_counter = lcconf->retry_counter;
1198 new->time_send = 0;
1199 new->created = time(NULL);
e8d9021d
A
1200#ifdef ENABLE_FRAG
1201 if (frag_flags) {
1202 new->frag_flags = frag_flags;
1203 }
1204#endif
65c25746 1205 new->retry_interval = ike_session_get_exp_retx_interval((lcconf->retry_counter - new->retry_counter),
e8d9021d 1206 lcconf->retry_interval);
65c25746 1207
52b7d2ce 1208 LIST_INSERT_HEAD(&rcptree, new, chain);
65c25746 1209
52b7d2ce
A
1210 return 0;
1211}
1212
1213void
65c25746
A
1214ike_session_del_recvdpkt(r)
1215struct recvdpkt *r;
52b7d2ce
A
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
1228void
65c25746
A
1229ike_session_rem_recvdpkt(r)
1230struct recvdpkt *r;
52b7d2ce
A
1231{
1232 LIST_REMOVE(r, chain);
1233}
1234
1235void
1236sweep_recvdpkt(dummy)
65c25746 1237void *dummy;
52b7d2ce
A
1238{
1239 struct recvdpkt *r, *next;
1240 time_t t, lt;
65c25746 1241
52b7d2ce
A
1242 /* set current time */
1243 t = time(NULL);
65c25746 1244
52b7d2ce
A
1245 /* set the lifetime of the retransmission */
1246 lt = lcconf->retry_counter * lcconf->retry_interval;
65c25746
A
1247
1248 LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
52b7d2ce 1249 if (t - r->created > lt) {
65c25746
A
1250 ike_session_rem_recvdpkt(r);
1251 ike_session_del_recvdpkt(r);
52b7d2ce
A
1252 }
1253 }
65c25746 1254
47612122 1255 sched_new(lt, sweep_recvdpkt, &rcptree);
52b7d2ce
A
1256}
1257
1258void
65c25746 1259ike_session_clear_recvdpkt()
52b7d2ce
A
1260{
1261 struct recvdpkt *r, *next;
1262
65c25746
A
1263 LIST_FOREACH_SAFE(r, &rcptree, chain, next) {
1264 ike_session_rem_recvdpkt(r);
1265 ike_session_del_recvdpkt(r);
52b7d2ce 1266 }
47612122 1267 sched_scrub_param(&rcptree);
52b7d2ce
A
1268}
1269
1270void
65c25746 1271ike_session_init_recvdpkt()
52b7d2ce
A
1272{
1273 time_t lt = lcconf->retry_counter * lcconf->retry_interval;
65c25746 1274
52b7d2ce 1275 LIST_INIT(&rcptree);
65c25746 1276
47612122 1277 sched_new(lt, sweep_recvdpkt, &rcptree);
52b7d2ce
A
1278}
1279
65c25746 1280#ifdef NOT_USED
52b7d2ce
A
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 */
1286int
65c25746 1287exclude_cfg_addr(const struct sockaddr_storage *addr)
52b7d2ce 1288{
65c25746
A
1289 ike_session_t *session;
1290 phase1_handle_t *p;
52b7d2ce 1291 struct sockaddr_in *sin;
65c25746
A
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
52b7d2ce
A
1305 return 1;
1306}
1307#endif
65c25746 1308#endif /* NOT_USED */
d1e348cf
A
1309
1310int
65c25746
A
1311ike_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 }
d1e348cf 1325
d9c572c0 1326 // Don't send a delete, since the ph1 implies the removal of ph2s
65c25746
A
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 }
d1e348cf
A
1342
1343 return found;
1344}
1345
65c25746 1346#ifdef ENABLE_HYBRID
d1e348cf 1347int
65c25746 1348ike_session_purgephXbydstaddrwop(struct sockaddr_storage *remote)
d1e348cf
A
1349{
1350 int found = 0;
65c25746
A
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)) {
85f41bec
A
1359 continue;
1360 }
65c25746 1361 if (cmpsaddrwop(remote, p2->dst) == 0) {
7ebaebe2 1362 plog(ASL_LEVEL_NOTICE,
65c25746
A
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)) {
85f41bec
A
1373 continue;
1374 }
65c25746 1375 if (cmpsaddrwop(remote, p->remote) == 0) {
7ebaebe2 1376 plog(ASL_LEVEL_NOTICE,
65c25746
A
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
d1e348cf
A
1387 return found;
1388}
1389
1390void
65c25746 1391ike_session_purgephXbyspid(u_int32_t spid, int del_boundph1)
d1e348cf 1392{
65c25746
A
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.
d1e348cf 1413 }
d1e348cf 1414 }
65c25746
A
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);
d1e348cf 1428 }
d1e348cf
A
1429 }
1430 }
65c25746
A
1431 }
1432 }
d1e348cf
A
1433}
1434
1435#endif
1436
1437#ifdef ENABLE_DPD
1438int
65c25746 1439ike_session_ph1_force_dpd (struct sockaddr_storage *remote)
d1e348cf
A
1440{
1441 int status = -1;
65c25746
A
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 {
7ebaebe2 1456 plog(ASL_LEVEL_NOTICE, "Skipping forced-DPD for Phase 1 (dpd already in progress).\n");
65c25746
A
1457 }
1458 if (p->parent_session) {
1459 p->parent_session->controller_awaiting_peer_resp = 1;
1460 }
d1e348cf 1461 } else {
7ebaebe2 1462 plog(ASL_LEVEL_NOTICE, "Skipping forced-DPD for Phase 1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
65c25746 1463 p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
e8d9021d 1464 }
d1e348cf
A
1465 }
1466 }
1467 }
65c25746 1468
d1e348cf
A
1469 return status;
1470}
1471#endif
e8d9021d
A
1472
1473void
1474sweep_sleepwake(void)
1475{
65c25746
A
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) {
7ebaebe2 1487 plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 1 %s because it's been asserted.\n",
65c25746
A
1488 isakmp_pindex(&iph1->index, 0));
1489 continue;
1490 }
1491 if (iph1->is_dying || FSM_STATE_IS_EXPIRED(iph1->status)) {
7ebaebe2 1492 plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 1 %s because it's already expired.\n",
65c25746
A
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);
7ebaebe2 1506 plog(ASL_LEVEL_NOTICE, "Phase 1 %s expired while sleeping: quick deletion.\n",
65c25746
A
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) {
7ebaebe2 1542 plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 2 because it's been asserted.\n");
65c25746
A
1543 continue;
1544 }
1545 if (iph2->is_dying || FSM_STATE_IS_EXPIRED(iph2->status)) {
7ebaebe2 1546 plog(ASL_LEVEL_NOTICE, "Skipping sweep of Phase 2 because it's already expired.\n");
65c25746
A
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);
7ebaebe2 1558 plog(ASL_LEVEL_NOTICE, "Phase 2 expired while sleeping: quick deletion.\n");
65c25746
A
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
e8d9021d
A
1573 // do the ike_session last
1574 ike_session_sweep_sleepwake();
1575}
d06a7ccb
A
1576
1577uint32_t
1578iph1_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
1596uint32_t
1597iph2_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}