]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/handler.c
ipsec-93.8.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / handler.c
1 /* $NetBSD: handler.c,v 1.9.6.6 2007/06/06 09:20:12 vanhu Exp $ */
2
3 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <time.h>
44 #include <errno.h>
45
46 #include "var.h"
47 #include "misc.h"
48 #include "vmbuf.h"
49 #include "plog.h"
50 #include "sockmisc.h"
51 #include "debug.h"
52
53 #ifdef ENABLE_HYBRID
54 #include <resolv.h>
55 #endif
56
57 #include "schedule.h"
58 #include "grabmyaddr.h"
59 #include "algorithm.h"
60 #include "crypto_openssl.h"
61 #include "policy.h"
62 #include "proposal.h"
63 #include "isakmp_var.h"
64 #include "evt.h"
65 #include "isakmp.h"
66 #ifdef ENABLE_HYBRID
67 #include "isakmp_xauth.h"
68 #include "isakmp_cfg.h"
69 #endif
70 #include "isakmp_inf.h"
71 #include "oakley.h"
72 #include "remoteconf.h"
73 #include "localconf.h"
74 #include "handler.h"
75 #include "gcmalloc.h"
76 #include "nattraversal.h"
77 #include "ike_session.h"
78
79 #include "sainfo.h"
80
81 #ifdef HAVE_GSSAPI
82 #include "gssapi.h"
83 #endif
84
85 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
86 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
87 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
88 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
89
90 static void del_recvdpkt __P((struct recvdpkt *));
91 static void rem_recvdpkt __P((struct recvdpkt *));
92 static void sweep_recvdpkt __P((void *));
93
94 /*
95 * functions about management of the isakmp status table
96 */
97 /* %%% management phase 1 handler */
98 /*
99 * search for isakmpsa handler with isakmp index.
100 */
101
102 extern caddr_t val2str(const char *, size_t);
103
104 struct ph1handle *
105 getph1byindex(index)
106 isakmp_index *index;
107 {
108 struct ph1handle *p;
109
110 LIST_FOREACH(p, &ph1tree, chain) {
111 if (p->status == PHASE1ST_EXPIRED)
112 continue;
113 if (memcmp(&p->index, index, sizeof(*index)) == 0)
114 return p;
115 }
116
117 return NULL;
118 }
119
120 /*
121 * search for isakmp handler by i_ck in index.
122 */
123 struct ph1handle *
124 getph1byindex0(index)
125 isakmp_index *index;
126 {
127 struct ph1handle *p;
128
129 LIST_FOREACH(p, &ph1tree, chain) {
130 if (p->status == PHASE1ST_EXPIRED)
131 continue;
132 if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
133 return p;
134 }
135
136 return NULL;
137 }
138
139 /*
140 * search for isakmpsa handler by source and remote address.
141 * don't use port number to search because this function search
142 * with phase 2's destinaion.
143 */
144 struct ph1handle *
145 getph1byaddr(local, remote)
146 struct sockaddr *local, *remote;
147 {
148 struct ph1handle *p;
149
150 plog(LLV_DEBUG2, LOCATION, NULL, "getph1byaddr: start\n");
151 plog(LLV_DEBUG2, LOCATION, NULL, "local: %s\n", saddr2str(local));
152 plog(LLV_DEBUG2, LOCATION, NULL, "remote: %s\n", saddr2str(remote));
153
154 LIST_FOREACH(p, &ph1tree, chain) {
155 if (p->status == PHASE1ST_EXPIRED)
156 continue;
157 plog(LLV_DEBUG2, LOCATION, NULL, "p->local: %s\n", saddr2str(p->local));
158 plog(LLV_DEBUG2, LOCATION, NULL, "p->remote: %s\n", saddr2str(p->remote));
159 if (CMPSADDR(local, p->local) == 0
160 && CMPSADDR(remote, p->remote) == 0){
161 plog(LLV_DEBUG2, LOCATION, NULL, "matched\n");
162 return p;
163 }
164 }
165
166 plog(LLV_DEBUG2, LOCATION, NULL, "no match\n");
167
168 return NULL;
169 }
170
171 struct ph1handle *
172 getph1byaddrwop(local, remote)
173 struct sockaddr *local, *remote;
174 {
175 struct ph1handle *p;
176
177 LIST_FOREACH(p, &ph1tree, chain) {
178 if (p->status == PHASE1ST_EXPIRED)
179 continue;
180 if (cmpsaddrwop(local, p->local) == 0
181 && cmpsaddrwop(remote, p->remote) == 0)
182 return p;
183 }
184
185 return NULL;
186 }
187
188 /*
189 * search for isakmpsa handler by remote address.
190 * don't use port number to search because this function search
191 * with phase 2's destinaion.
192 */
193 struct ph1handle *
194 getph1bydstaddrwop(remote)
195 struct sockaddr *remote;
196 {
197 struct ph1handle *p;
198
199 LIST_FOREACH(p, &ph1tree, chain) {
200 if (p->status == PHASE1ST_EXPIRED)
201 continue;
202 if (cmpsaddrwop(remote, p->remote) == 0)
203 return p;
204 }
205
206 return NULL;
207 }
208
209 int
210 islast_ph1(ph1)
211 struct ph1handle *ph1;
212 {
213 struct ph1handle *p;
214
215 LIST_FOREACH(p, &ph1tree, chain) {
216 if (p->status == PHASE1ST_EXPIRED)
217 continue;
218 if (CMPSADDR(ph1->remote, p->remote) == 0) {
219 if (p == ph1)
220 continue;
221 return 0;
222 }
223 }
224 return 1;
225 }
226
227 /*
228 * dump isakmp-sa
229 */
230 vchar_t *
231 dumpph1()
232 {
233 struct ph1handle *iph1;
234 struct ph1dump *pd;
235 int cnt = 0;
236 vchar_t *buf;
237
238 /* get length of buffer */
239 LIST_FOREACH(iph1, &ph1tree, chain)
240 cnt++;
241
242 buf = vmalloc(cnt * sizeof(struct ph1dump));
243 if (buf == NULL) {
244 plog(LLV_ERROR, LOCATION, NULL,
245 "failed to get buffer\n");
246 return NULL;
247 }
248 pd = (struct ph1dump *)buf->v;
249
250 LIST_FOREACH(iph1, &ph1tree, chain) {
251 memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
252 pd->status = iph1->status;
253 pd->side = iph1->side;
254 memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
255 memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
256 pd->version = iph1->version;
257 pd->etype = iph1->etype;
258 pd->created = iph1->created;
259 pd->ph2cnt = iph1->ph2cnt;
260 pd++;
261 }
262
263 return buf;
264 }
265
266 /*
267 * create new isakmp Phase 1 status record to handle isakmp in Phase1
268 */
269 struct ph1handle *
270 newph1()
271 {
272 struct ph1handle *iph1;
273
274 /* create new iph1 */
275 iph1 = racoon_calloc(1, sizeof(*iph1));
276 if (iph1 == NULL)
277 return NULL;
278
279 iph1->status = PHASE1ST_SPAWN;
280
281 #ifdef ENABLE_DPD
282 iph1->dpd_support = 0;
283 iph1->dpd_lastack = 0;
284 iph1->dpd_seq = 0;
285 iph1->dpd_fails = 0;
286 iph1->peer_sent_ike = 0;
287 iph1->dpd_r_u = NULL;
288 #endif
289 #ifdef ENABLE_VPNCONTROL_PORT
290 iph1->ping_sched = NULL;
291 #endif
292 iph1->is_dying = 0;
293 return iph1;
294 }
295
296 /*
297 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
298 */
299 void
300 delph1(iph1)
301 struct ph1handle *iph1;
302 {
303 if (iph1 == NULL)
304 return;
305
306 /* SA down shell script hook */
307 script_hook(iph1, SCRIPT_PHASE1_DOWN);
308
309 EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
310
311 #ifdef ENABLE_NATT
312 #ifndef __APPLE__
313 if (iph1->natt_flags & NAT_KA_QUEUED)
314 natt_keepalive_remove (iph1->local, iph1->remote);
315 #endif /* __APPLE__ */
316 if (iph1->natt_options) {
317 racoon_free(iph1->natt_options);
318 iph1->natt_options = NULL;
319 }
320 #endif
321
322 #ifdef ENABLE_HYBRID
323 if (iph1->mode_cfg)
324 isakmp_cfg_rmstate(iph1);
325 VPTRINIT(iph1->xauth_awaiting_userinput_msg);
326 #endif
327
328 #ifdef ENABLE_DPD
329 if (iph1->dpd_r_u != NULL)
330 SCHED_KILL(iph1->dpd_r_u);
331 #endif
332 #ifdef ENABLE_VPNCONTROL_PORT
333 if (iph1->ping_sched != NULL)
334 SCHED_KILL(iph1->ping_sched);
335 #endif
336
337 if (iph1->remote) {
338 racoon_free(iph1->remote);
339 iph1->remote = NULL;
340 }
341 if (iph1->local) {
342 racoon_free(iph1->local);
343 iph1->local = NULL;
344 }
345
346 if (iph1->approval) {
347 delisakmpsa(iph1->approval);
348 iph1->approval = NULL;
349 }
350
351 VPTRINIT(iph1->authstr);
352
353 sched_scrub_param(iph1);
354 iph1->sce = NULL;
355 iph1->sce_rekey = NULL;
356 iph1->scr = NULL;
357
358 VPTRINIT(iph1->sendbuf);
359
360 VPTRINIT(iph1->dhpriv);
361 VPTRINIT(iph1->dhpub);
362 VPTRINIT(iph1->dhpub_p);
363 VPTRINIT(iph1->dhgxy);
364 VPTRINIT(iph1->nonce);
365 VPTRINIT(iph1->nonce_p);
366 VPTRINIT(iph1->skeyid);
367 VPTRINIT(iph1->skeyid_d);
368 VPTRINIT(iph1->skeyid_a);
369 VPTRINIT(iph1->skeyid_e);
370 VPTRINIT(iph1->key);
371 VPTRINIT(iph1->hash);
372 VPTRINIT(iph1->sig);
373 VPTRINIT(iph1->sig_p);
374 oakley_delcert(iph1->cert);
375 iph1->cert = NULL;
376 oakley_delcert(iph1->cert_p);
377 iph1->cert_p = NULL;
378 oakley_delcert(iph1->crl_p);
379 iph1->crl_p = NULL;
380 oakley_delcert(iph1->cr_p);
381 iph1->cr_p = NULL;
382 VPTRINIT(iph1->id);
383 VPTRINIT(iph1->id_p);
384
385 if(iph1->approval != NULL)
386 delisakmpsa(iph1->approval);
387
388 if (iph1->ivm) {
389 oakley_delivm(iph1->ivm);
390 iph1->ivm = NULL;
391 }
392
393 VPTRINIT(iph1->sa);
394 VPTRINIT(iph1->sa_ret);
395
396 #ifdef HAVE_GSSAPI
397 VPTRINIT(iph1->gi_i);
398 VPTRINIT(iph1->gi_r);
399
400 gssapi_free_state(iph1);
401 #endif
402
403 #ifdef __APPLE__
404 if (iph1->parent_session) {
405 ike_session_unlink_ph1_from_session(iph1);
406 }
407 if (iph1->rmconf) {
408 unlink_rmconf_from_ph1(iph1->rmconf);
409 iph1->rmconf = NULL;
410 }
411 #endif
412
413 racoon_free(iph1);
414 }
415
416 /*
417 * create new isakmp Phase 1 status record to handle isakmp in Phase1
418 */
419 int
420 insph1(iph1)
421 struct ph1handle *iph1;
422 {
423 /* validity check */
424 if (iph1->remote == NULL) {
425 plog(LLV_ERROR, LOCATION, NULL,
426 "invalid isakmp SA handler. no remote address.\n");
427 return -1;
428 }
429 LIST_INSERT_HEAD(&ph1tree, iph1, chain);
430
431 return 0;
432 }
433
434 void
435 remph1(iph1)
436 struct ph1handle *iph1;
437 {
438 LIST_REMOVE(iph1, chain);
439 }
440
441 /*
442 * flush isakmp-sa
443 */
444 void
445 flushph1(int ignore_established_handles)
446 {
447 struct ph1handle *p, *next;
448
449 for (p = LIST_FIRST(&ph1tree); p; p = next) {
450 next = LIST_NEXT(p, chain);
451
452 /* send delete information */
453 if (p->status == PHASE1ST_ESTABLISHED) {
454 if (ignore_established_handles &&
455 (ike_session_has_negoing_ph2(p->parent_session) ||
456 p->mode_cfg->flags)) {
457 plog(LLV_DEBUG2, LOCATION, NULL,
458 "skipping ph1 handler that's established... because it's needed by children phase2s\n");
459 continue;
460 }
461 /* send delete information */
462 plog(LLV_DEBUG2, LOCATION, NULL,
463 "got a ph1 handler to flush...\n");
464 isakmp_info_send_d1(p);
465 }
466
467 ike_session_stopped_by_controller(p->parent_session,
468 ike_session_stopped_by_flush);
469 remph1(p);
470 delph1(p);
471 }
472 }
473
474 void
475 initph1tree()
476 {
477 LIST_INIT(&ph1tree);
478 }
479
480 /* %%% management phase 2 handler */
481 /*
482 * search ph2handle with policy id.
483 */
484 struct ph2handle *
485 getph2byspid(spid)
486 u_int32_t spid;
487 {
488 struct ph2handle *p;
489
490 LIST_FOREACH(p, &ph2tree, chain) {
491 /*
492 * there are ph2handle independent on policy
493 * such like informational exchange.
494 */
495 if (p->spid == spid)
496 return p;
497 }
498
499 return NULL;
500 }
501
502 /*
503 * search ph2handle with sequence number.
504 */
505 struct ph2handle *
506 getph2byseq(seq)
507 u_int32_t seq;
508 {
509 struct ph2handle *p;
510
511 LIST_FOREACH(p, &ph2tree, chain) {
512 if (p->seq == seq)
513 return p;
514 }
515
516 return NULL;
517 }
518
519 /*
520 * search ph2handle with message id.
521 */
522 struct ph2handle *
523 getph2bymsgid(iph1, msgid)
524 struct ph1handle *iph1;
525 u_int32_t msgid;
526 {
527 struct ph2handle *p;
528
529 LIST_FOREACH(p, &ph2tree, chain) {
530 if (p->msgid == msgid)
531 return p;
532 }
533
534 return NULL;
535 }
536
537 struct ph2handle *
538 getph2byid(src, dst, spid)
539 struct sockaddr *src, *dst;
540 u_int32_t spid;
541 {
542 struct ph2handle *p;
543
544 LIST_FOREACH(p, &ph2tree, chain) {
545 if (spid == p->spid &&
546 CMPSADDR(src, p->src) == 0 &&
547 CMPSADDR(dst, p->dst) == 0){
548 /* Sanity check to detect zombie handlers
549 * XXX Sould be done "somewhere" more interesting,
550 * because we have lots of getph2byxxxx(), but this one
551 * is called by pk_recvacquire(), so is the most important.
552 */
553 if(p->status < PHASE2ST_ESTABLISHED &&
554 p->retry_counter == 0
555 && p->sce == NULL && p->scr == NULL){
556 plog(LLV_DEBUG, LOCATION, NULL,
557 "Zombie ph2 found, expiring it\n");
558 isakmp_ph2expire(p);
559 }else
560 return p;
561 }
562 }
563
564 return NULL;
565 }
566
567 struct ph2handle *
568 getph2bysaddr(src, dst)
569 struct sockaddr *src, *dst;
570 {
571 struct ph2handle *p;
572
573 LIST_FOREACH(p, &ph2tree, chain) {
574 if (cmpsaddrstrict(src, p->src) == 0 &&
575 cmpsaddrstrict(dst, p->dst) == 0)
576 return p;
577 }
578
579 return NULL;
580 }
581
582 /*
583 * call by pk_recvexpire().
584 */
585 struct ph2handle *
586 getph2bysaidx(src, dst, proto_id, spi)
587 struct sockaddr *src, *dst;
588 u_int proto_id;
589 u_int32_t spi;
590 {
591 struct ph2handle *iph2;
592 struct saproto *pr;
593
594 LIST_FOREACH(iph2, &ph2tree, chain) {
595 if (iph2->proposal == NULL && iph2->approval == NULL)
596 continue;
597 if (iph2->approval != NULL) {
598 for (pr = iph2->approval->head; pr != NULL;
599 pr = pr->next) {
600 if (proto_id != pr->proto_id)
601 break;
602 if (spi == pr->spi || spi == pr->spi_p)
603 return iph2;
604 }
605 } else if (iph2->proposal != NULL) {
606 for (pr = iph2->proposal->head; pr != NULL;
607 pr = pr->next) {
608 if (proto_id != pr->proto_id)
609 break;
610 if (spi == pr->spi)
611 return iph2;
612 }
613 }
614 }
615
616 return NULL;
617 }
618
619 /*
620 * create new isakmp Phase 2 status record to handle isakmp in Phase2
621 */
622 struct ph2handle *
623 newph2()
624 {
625 struct ph2handle *iph2 = NULL;
626
627 /* create new iph2 */
628 iph2 = racoon_calloc(1, sizeof(*iph2));
629 if (iph2 == NULL)
630 return NULL;
631
632 iph2->status = PHASE1ST_SPAWN;
633 iph2->is_dying = 0;
634
635 return iph2;
636 }
637
638 /*
639 * initialize ph2handle
640 * NOTE: don't initialize src/dst.
641 * SPI in the proposal is cleared.
642 */
643 void
644 initph2(iph2)
645 struct ph2handle *iph2;
646 {
647 sched_scrub_param(iph2);
648 iph2->sce = NULL;
649 iph2->scr = NULL;
650
651 VPTRINIT(iph2->sendbuf);
652 VPTRINIT(iph2->msg1);
653
654 /* clear spi, keep variables in the proposal */
655 if (iph2->proposal) {
656 struct saproto *pr;
657 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
658 pr->spi = 0;
659 }
660
661 /* clear approval */
662 if (iph2->approval) {
663 flushsaprop(iph2->approval);
664 iph2->approval = NULL;
665 }
666
667 /* clear the generated policy */
668 if (iph2->spidx_gen) {
669 delsp_bothdir((struct policyindex *)iph2->spidx_gen);
670 racoon_free(iph2->spidx_gen);
671 iph2->spidx_gen = NULL;
672 }
673
674 if (iph2->pfsgrp) {
675 oakley_dhgrp_free(iph2->pfsgrp);
676 iph2->pfsgrp = NULL;
677 }
678
679 VPTRINIT(iph2->dhpriv);
680 VPTRINIT(iph2->dhpub);
681 VPTRINIT(iph2->dhpub_p);
682 VPTRINIT(iph2->dhgxy);
683 VPTRINIT(iph2->id);
684 VPTRINIT(iph2->id_p);
685 VPTRINIT(iph2->nonce);
686 VPTRINIT(iph2->nonce_p);
687 VPTRINIT(iph2->sa);
688 VPTRINIT(iph2->sa_ret);
689
690 if (iph2->ivm) {
691 oakley_delivm(iph2->ivm);
692 iph2->ivm = NULL;
693 }
694 }
695
696 /*
697 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
698 */
699 void
700 delph2(iph2)
701 struct ph2handle *iph2;
702 {
703 initph2(iph2);
704
705 if (iph2->src) {
706 racoon_free(iph2->src);
707 iph2->src = NULL;
708 }
709 if (iph2->dst) {
710 racoon_free(iph2->dst);
711 iph2->dst = NULL;
712 }
713 if (iph2->src_id) {
714 racoon_free(iph2->src_id);
715 iph2->src_id = NULL;
716 }
717 if (iph2->dst_id) {
718 racoon_free(iph2->dst_id);
719 iph2->dst_id = NULL;
720 }
721
722 if (iph2->proposal) {
723 flushsaprop(iph2->proposal);
724 iph2->proposal = NULL;
725 }
726
727 #ifdef __APPLE__
728 if (iph2->parent_session) {
729 ike_session_unlink_ph2_from_session(iph2);
730 }
731 if (iph2->sainfo) {
732 unlink_sainfo_from_ph2(iph2->sainfo);
733 iph2->sainfo = NULL;
734 }
735 if (iph2->ext_nat_id) {
736 vfree(iph2->ext_nat_id);
737 iph2->ext_nat_id = NULL;
738 }
739 if (iph2->ext_nat_id_p) {
740 vfree(iph2->ext_nat_id_p);
741 iph2->ext_nat_id_p = NULL;
742 }
743 #endif
744
745 racoon_free(iph2);
746 }
747
748 /*
749 * create new isakmp Phase 2 status record to handle isakmp in Phase2
750 */
751 int
752 insph2(iph2)
753 struct ph2handle *iph2;
754 {
755 LIST_INSERT_HEAD(&ph2tree, iph2, chain);
756
757 return 0;
758 }
759
760 void
761 remph2(iph2)
762 struct ph2handle *iph2;
763 {
764 LIST_REMOVE(iph2, chain);
765 }
766
767 void
768 initph2tree()
769 {
770 LIST_INIT(&ph2tree);
771 }
772
773 void
774 flushph2(int ignore_established_handles)
775 {
776 struct ph2handle *p, *next;
777
778 plog(LLV_DEBUG2, LOCATION, NULL,
779 "flushing all ph2 handlers...\n");
780
781 for (p = LIST_FIRST(&ph2tree); p; p = next) {
782 next = LIST_NEXT(p, chain);
783 if (p->is_dying || p->status == PHASE2ST_EXPIRED) {
784 continue;
785 }
786 if (p->status == PHASE2ST_ESTABLISHED){
787 if (ignore_established_handles) {
788 plog(LLV_DEBUG2, LOCATION, NULL,
789 "skipping ph2 handler that's established...\n");
790 continue;
791 }
792 /* send delete information */
793 plog(LLV_DEBUG2, LOCATION, NULL,
794 "got an established ph2 handler to flush...\n");
795 isakmp_info_send_d2(p);
796 }else{
797 plog(LLV_DEBUG2, LOCATION, NULL,
798 "got a ph2 handler to flush (state %d)\n", p->status);
799 }
800
801 ike_session_stopped_by_controller(p->parent_session,
802 ike_session_stopped_by_flush);
803 delete_spd(p);
804 unbindph12(p);
805 remph2(p);
806 delph2(p);
807 }
808 }
809
810 /*
811 * Delete all Phase 2 handlers for this src/dst/proto. This
812 * is used during INITIAL-CONTACT processing (so no need to
813 * send a message to the peer).
814 */
815 void
816 deleteallph2(src, dst, proto_id)
817 struct sockaddr *src, *dst;
818 u_int proto_id;
819 {
820 struct ph2handle *iph2, *next;
821 struct saproto *pr;
822
823 for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
824 next = LIST_NEXT(iph2, chain);
825 if (iph2->is_dying || iph2->status == PHASE2ST_EXPIRED) {
826 continue;
827 }
828 if (iph2->proposal == NULL && iph2->approval == NULL)
829 continue;
830 if (cmpsaddrwop(src, iph2->src) != 0 ||
831 cmpsaddrwop(dst, iph2->dst) != 0) {
832 continue;
833 }
834 if (iph2->approval != NULL) {
835 for (pr = iph2->approval->head; pr != NULL;
836 pr = pr->next) {
837 if (proto_id == pr->proto_id)
838 goto zap_it;
839 }
840 } else if (iph2->proposal != NULL) {
841 for (pr = iph2->proposal->head; pr != NULL;
842 pr = pr->next) {
843 if (proto_id == pr->proto_id)
844 goto zap_it;
845 }
846 }
847 continue;
848 zap_it:
849 plog(LLV_DEBUG2, LOCATION, NULL,
850 "deleteallph2: got a ph2 handler...\n");
851 if (iph2->status == PHASE2ST_ESTABLISHED)
852 isakmp_info_send_d2(iph2);
853 ike_session_stopped_by_controller(iph2->parent_session,
854 ike_session_stopped_by_flush);
855 unbindph12(iph2);
856 remph2(iph2);
857 delph2(iph2);
858 }
859 }
860
861 /*
862 * Delete all Phase 1 handlers for this src/dst.
863 */
864 void
865 deleteallph1(src, dst)
866 struct sockaddr *src, *dst;
867 {
868 struct ph1handle *iph1, *next;
869
870 for (iph1 = LIST_FIRST(&ph1tree); iph1 != NULL; iph1 = next) {
871 next = LIST_NEXT(iph1, chain);
872 if (cmpsaddrwop(src, iph1->local) != 0 ||
873 cmpsaddrwop(dst, iph1->remote) != 0) {
874 continue;
875 }
876 plog(LLV_DEBUG2, LOCATION, NULL,
877 "deleteallph1: got a ph1 handler...\n");
878 if (iph1->status == PHASE2ST_ESTABLISHED)
879 isakmp_info_send_d1(iph1);
880
881 ike_session_stopped_by_controller(iph1->parent_session,
882 ike_session_stopped_by_flush);
883 remph1(iph1);
884 delph1(iph1);
885 }
886 }
887
888 /* %%% */
889 void
890 bindph12(iph1, iph2)
891 struct ph1handle *iph1;
892 struct ph2handle *iph2;
893 {
894 if (iph2->ph1 && (struct ph1handle *)iph2->ph1bind.le_next == iph1) {
895 plog(LLV_ERROR, LOCATION, NULL, "duplicate %s.\n", __FUNCTION__);
896 }
897 iph2->ph1 = iph1;
898 LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
899 }
900
901 void
902 unbindph12(iph2)
903 struct ph2handle *iph2;
904 {
905 if (iph2->ph1 != NULL) {
906 plog(LLV_DEBUG, LOCATION, NULL, "unbindph12.\n");
907 iph2->ph1 = NULL;
908 LIST_REMOVE(iph2, ph1bind);
909 }
910 }
911
912 void
913 rebindph12(new_ph1, iph2)
914 struct ph1handle *new_ph1;
915 struct ph2handle *iph2;
916 {
917 if (!new_ph1) {
918 return;
919 }
920
921 // reconcile the ph1-to-ph2 binding
922 plog(LLV_DEBUG, LOCATION, NULL, "rebindph12.\n");
923 unbindph12(iph2);
924 bindph12(new_ph1, iph2);
925 // recalculate ivm since ph1 binding has changed
926 if (iph2->ivm != NULL) {
927 oakley_delivm(iph2->ivm);
928 if (new_ph1->status == PHASE1ST_ESTABLISHED) {
929 iph2->ivm = oakley_newiv2(new_ph1, iph2->msgid);
930 plog(LLV_DEBUG, LOCATION, NULL, "ph12 binding changed... recalculated ivm.\n");
931 } else {
932 iph2->ivm = NULL;
933 }
934 }
935 }
936
937 /* %%% management contacted list */
938 /*
939 * search contacted list.
940 */
941 struct contacted *
942 getcontacted(remote)
943 struct sockaddr *remote;
944 {
945 struct contacted *p;
946
947 LIST_FOREACH(p, &ctdtree, chain) {
948 if (cmpsaddrstrict(remote, p->remote) == 0)
949 return p;
950 }
951
952 return NULL;
953 }
954
955 /*
956 * create new isakmp Phase 2 status record to handle isakmp in Phase2
957 */
958 int
959 inscontacted(remote)
960 struct sockaddr *remote;
961 {
962 struct contacted *new;
963
964 /* create new iph2 */
965 new = racoon_calloc(1, sizeof(*new));
966 if (new == NULL)
967 return -1;
968
969 new->remote = dupsaddr(remote);
970 if (new->remote == NULL) {
971 plog(LLV_ERROR, LOCATION, NULL,
972 "failed to allocate buffer.\n");
973 racoon_free(new);
974 return -1;
975 }
976
977 LIST_INSERT_HEAD(&ctdtree, new, chain);
978
979 return 0;
980 }
981
982
983 void
984 clear_contacted()
985 {
986 struct contacted *c, *next;
987
988 for (c = LIST_FIRST(&ctdtree); c; c = next) {
989 next = LIST_NEXT(c, chain);
990 LIST_REMOVE(c, chain);
991 racoon_free(c->remote);
992 racoon_free(c);
993 }
994 }
995
996 void
997 initctdtree()
998 {
999 LIST_INIT(&ctdtree);
1000 }
1001
1002 /*
1003 * check the response has been sent to the peer. when not, simply reply
1004 * the buffered packet to the peer.
1005 * OUT:
1006 * 0: the packet is received at the first time.
1007 * 1: the packet was processed before.
1008 * 2: the packet was processed before, but the address mismatches.
1009 * -1: error happened.
1010 */
1011 int
1012 check_recvdpkt(remote, local, rbuf)
1013 struct sockaddr *remote, *local;
1014 vchar_t *rbuf;
1015 {
1016 vchar_t *hash;
1017 struct recvdpkt *r;
1018 time_t t;
1019 int len, s;
1020
1021 /* set current time */
1022 t = time(NULL);
1023
1024 hash = eay_md5_one(rbuf);
1025 if (!hash) {
1026 plog(LLV_ERROR, LOCATION, NULL,
1027 "failed to allocate buffer.\n");
1028 return -1;
1029 }
1030
1031 LIST_FOREACH(r, &rcptree, chain) {
1032 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
1033 break;
1034 }
1035 vfree(hash);
1036
1037 /* this is the first time to receive the packet */
1038 if (r == NULL)
1039 return 0;
1040
1041 /*
1042 * the packet was processed before, but the remote address mismatches.
1043 * ignore the port to accomodate port changes (e.g. floating).
1044 */
1045 if (cmpsaddrwop(remote, r->remote) != 0) {
1046 return 2;
1047 }
1048
1049 /*
1050 * it should not check the local address because the packet
1051 * may arrive at other interface.
1052 */
1053
1054 /* check the previous time to send */
1055 if (t - r->time_send < 1) {
1056 plog(LLV_WARNING, LOCATION, NULL,
1057 "the packet retransmitted in a short time from %s\n",
1058 saddr2str(remote));
1059 /*XXX should it be error ? */
1060 }
1061
1062 /* select the socket to be sent */
1063 s = getsockmyaddr(r->local);
1064 if (s == -1)
1065 return -1;
1066
1067 /* resend the packet if needed */
1068 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
1069 r->local, r->remote, lcconf->count_persend);
1070 if (len == -1) {
1071 plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
1072 return -1;
1073 }
1074
1075 /* check the retry counter */
1076 r->retry_counter--;
1077 if (r->retry_counter <= 0) {
1078 rem_recvdpkt(r);
1079 del_recvdpkt(r);
1080 plog(LLV_DEBUG, LOCATION, NULL,
1081 "deleted the retransmission packet to %s.\n",
1082 saddr2str(remote));
1083 } else
1084 r->time_send = t;
1085
1086 return 1;
1087 }
1088
1089 /*
1090 * adding a hash of received packet into the received list.
1091 */
1092 int
1093 add_recvdpkt(remote, local, sbuf, rbuf, non_esp)
1094 struct sockaddr *remote, *local;
1095 vchar_t *sbuf, *rbuf;
1096 size_t non_esp;
1097 {
1098 struct recvdpkt *new = NULL;
1099
1100 if (lcconf->retry_counter == 0) {
1101 /* no need to add it */
1102 return 0;
1103 }
1104
1105 new = racoon_calloc(1, sizeof(*new));
1106 if (!new) {
1107 plog(LLV_ERROR, LOCATION, NULL,
1108 "failed to allocate buffer.\n");
1109 return -1;
1110 }
1111
1112 new->hash = eay_md5_one(rbuf);
1113 if (!new->hash) {
1114 plog(LLV_ERROR, LOCATION, NULL,
1115 "failed to allocate buffer.\n");
1116 del_recvdpkt(new);
1117 return -1;
1118 }
1119 new->remote = dupsaddr(remote);
1120 if (new->remote == NULL) {
1121 plog(LLV_ERROR, LOCATION, NULL,
1122 "failed to allocate buffer.\n");
1123 del_recvdpkt(new);
1124 return -1;
1125 }
1126 new->local = dupsaddr(local);
1127 if (new->local == NULL) {
1128 plog(LLV_ERROR, LOCATION, NULL,
1129 "failed to allocate buffer.\n");
1130 del_recvdpkt(new);
1131 return -1;
1132 }
1133
1134 if (non_esp) {
1135 plog (LLV_DEBUG, LOCATION, NULL, "Adding NON-ESP marker\n");
1136
1137 /* If NAT-T port floating is in use, 4 zero bytes (non-ESP marker)
1138 must added just before the packet itself. For this we must
1139 allocate a new buffer and release it at the end. */
1140 if ((new->sendbuf = vmalloc (sbuf->l + non_esp)) == NULL) {
1141 plog(LLV_ERROR, LOCATION, NULL,
1142 "failed to allocate extra buf for non-esp\n");
1143 del_recvdpkt(new);
1144 return -1;
1145 }
1146 *(u_int32_t *)new->sendbuf->v = 0;
1147 memcpy(new->sendbuf->v + non_esp, sbuf->v, sbuf->l);
1148 } else {
1149 new->sendbuf = vdup(sbuf);
1150 if (new->sendbuf == NULL) {
1151 plog(LLV_ERROR, LOCATION, NULL,
1152 "failed to allocate buffer.\n");
1153 del_recvdpkt(new);
1154 return -1;
1155 }
1156 }
1157
1158 new->retry_counter = lcconf->retry_counter;
1159 new->time_send = 0;
1160 new->created = time(NULL);
1161
1162 LIST_INSERT_HEAD(&rcptree, new, chain);
1163
1164 return 0;
1165 }
1166
1167 void
1168 del_recvdpkt(r)
1169 struct recvdpkt *r;
1170 {
1171 if (r->remote)
1172 racoon_free(r->remote);
1173 if (r->local)
1174 racoon_free(r->local);
1175 if (r->hash)
1176 vfree(r->hash);
1177 if (r->sendbuf)
1178 vfree(r->sendbuf);
1179 racoon_free(r);
1180 }
1181
1182 void
1183 rem_recvdpkt(r)
1184 struct recvdpkt *r;
1185 {
1186 LIST_REMOVE(r, chain);
1187 }
1188
1189 void
1190 sweep_recvdpkt(dummy)
1191 void *dummy;
1192 {
1193 struct recvdpkt *r, *next;
1194 time_t t, lt;
1195
1196 /* set current time */
1197 t = time(NULL);
1198
1199 /* set the lifetime of the retransmission */
1200 lt = lcconf->retry_counter * lcconf->retry_interval;
1201
1202 for (r = LIST_FIRST(&rcptree); r; r = next) {
1203 next = LIST_NEXT(r, chain);
1204
1205 if (t - r->created > lt) {
1206 rem_recvdpkt(r);
1207 del_recvdpkt(r);
1208 }
1209 }
1210
1211 sched_new(lt, sweep_recvdpkt, &rcptree);
1212 }
1213
1214 void
1215 clear_recvdpkt()
1216 {
1217 struct recvdpkt *r, *next;
1218
1219 for (r = LIST_FIRST(&rcptree); r; r = next) {
1220 next = LIST_NEXT(r, chain);
1221 rem_recvdpkt(r);
1222 del_recvdpkt(r);
1223 }
1224 sched_scrub_param(&rcptree);
1225 }
1226
1227 void
1228 init_recvdpkt()
1229 {
1230 time_t lt = lcconf->retry_counter * lcconf->retry_interval;
1231
1232 LIST_INIT(&rcptree);
1233
1234 sched_new(lt, sweep_recvdpkt, &rcptree);
1235 }
1236
1237 #ifdef ENABLE_HYBRID
1238 /*
1239 * Returns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
1240 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
1241 */
1242 int
1243 exclude_cfg_addr(addr)
1244 const struct sockaddr *addr;
1245 {
1246 struct ph1handle *p;
1247 struct sockaddr_in *sin;
1248
1249 LIST_FOREACH(p, &ph1tree, chain) {
1250 if ((p->mode_cfg != NULL) &&
1251 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
1252 (addr->sa_family == AF_INET)) {
1253 sin = (struct sockaddr_in *)addr;
1254 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
1255 return 0;
1256 }
1257 }
1258
1259 return 1;
1260 }
1261 #endif
1262
1263 #ifdef ENABLE_HYBRID
1264 struct ph1handle *
1265 getph1bylogin(login)
1266 char *login;
1267 {
1268 struct ph1handle *p;
1269
1270 LIST_FOREACH(p, &ph1tree, chain) {
1271 if (p->mode_cfg == NULL)
1272 continue;
1273 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0)
1274 return p;
1275 }
1276
1277 return NULL;
1278 }
1279
1280 int
1281 purgeph1bylogin(login)
1282 char *login;
1283 {
1284 struct ph1handle *p;
1285 int found = 0;
1286
1287 LIST_FOREACH(p, &ph1tree, chain) {
1288 if (p->mode_cfg == NULL)
1289 continue;
1290 if (strncmp(p->mode_cfg->login, login, LOGINLEN) == 0) {
1291 if (p->status == PHASE1ST_ESTABLISHED)
1292 isakmp_info_send_d1(p);
1293 purge_remote(p);
1294 found++;
1295 }
1296 }
1297
1298 return found;
1299 }
1300
1301 int
1302 purgephXbydstaddrwop(remote)
1303 struct sockaddr *remote;
1304 {
1305 int found = 0;
1306 struct ph1handle *p;
1307
1308 LIST_FOREACH(p, &ph1tree, chain) {
1309 if (cmpsaddrwop(remote, p->remote) == 0) {
1310 plog(LLV_WARNING, LOCATION, NULL,
1311 "in %s... purging phase1 and related phase2s\n", __FUNCTION__);
1312 ike_session_purge_ph2s_by_ph1(p);
1313 if (p->status == PHASE1ST_ESTABLISHED)
1314 isakmp_info_send_d1(p);
1315 isakmp_ph1expire(p);
1316 found++;
1317 }
1318 }
1319
1320 return found;
1321 }
1322
1323 void
1324 purgephXbyspid(u_int32_t spid,
1325 int del_boundph1)
1326 {
1327 struct ph2handle *iph2;
1328 struct ph1handle *iph1;
1329
1330 // do ph2's first... we need the ph1s for notifications
1331 LIST_FOREACH(iph2, &ph2tree, chain) {
1332 if (spid == iph2->spid) {
1333 if (iph2->is_dying || iph2->status == PHASE2ST_EXPIRED) {
1334 continue;
1335 }
1336 if (iph2->status == PHASE2ST_ESTABLISHED) {
1337 isakmp_info_send_d2(iph2);
1338 }
1339 ike_session_stopped_by_controller(iph2->parent_session,
1340 ike_session_stopped_by_flush);
1341 isakmp_ph2expire(iph2); // iph2 will go down 1 second later.
1342 }
1343 }
1344
1345 // do the ph1s last.
1346 LIST_FOREACH(iph2, &ph2tree, chain) {
1347 if (spid == iph2->spid) {
1348 if (del_boundph1 && iph2->parent_session) {
1349 for (iph1 = LIST_FIRST(&iph2->parent_session->ikev1_state.ph1tree); iph1; iph1 = LIST_NEXT(iph1, ph1ofsession_chain)) {
1350 if (iph1->is_dying || iph1->status == PHASE1ST_EXPIRED) {
1351 continue;
1352 }
1353 if (iph1->status == PHASE1ST_ESTABLISHED) {
1354 isakmp_info_send_d1(iph1);
1355 }
1356 isakmp_ph1expire(iph1);
1357 }
1358 }
1359 }
1360 }
1361 }
1362
1363 #endif
1364
1365 #ifdef ENABLE_DPD
1366 int
1367 ph1_force_dpd (struct sockaddr *remote)
1368 {
1369 int status = -1;
1370 struct ph1handle *p;
1371
1372 LIST_FOREACH(p, &ph1tree, chain) {
1373 if (cmpsaddrwop(remote, p->remote) == 0) {
1374 if (p->status == PHASE1ST_ESTABLISHED &&
1375 !p->is_dying &&
1376 p->dpd_support &&
1377 p->rmconf->dpd_interval) {
1378 if(!p->dpd_fails) {
1379 isakmp_info_send_r_u(p);
1380 status = 0;
1381 } else {
1382 plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (dpd already in progress).\n");
1383 }
1384 } else {
1385 plog(LLV_DEBUG2, LOCATION, NULL, "skipping forced-DPD for phase1 (status %d, dying %d, dpd-support %d, dpd-interval %d).\n",
1386 p->status, p->is_dying, p->dpd_support, p->rmconf->dpd_interval);
1387 }
1388 }
1389 }
1390
1391 return status;
1392 }
1393 #endif