1 /* $NetBSD: handler.c,v 1.30 2009/09/03 09:29:07 tteras Exp $ */
3 /* Id: handler.c,v 1.28 2006/05/26 12:17:29 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
58 #include "grabmyaddr.h"
59 #include "algorithm.h"
60 #include "crypto_openssl.h"
63 #include "isakmp_var.h"
67 #include "isakmp_xauth.h"
68 #include "isakmp_cfg.h"
70 #include "isakmp_inf.h"
72 #include "remoteconf.h"
73 #include "localconf.h"
76 #include "nattraversal.h"
84 static LIST_HEAD(_ph1tree_
, ph1handle
) ph1tree
;
85 static LIST_HEAD(_ph2tree_
, ph2handle
) ph2tree
;
86 static LIST_HEAD(_ctdtree_
, contacted
) ctdtree
;
87 static LIST_HEAD(_rcptree_
, recvdpkt
) rcptree
;
88 static struct sched sc_sweep
= SCHED_INITIALIZER();
90 static void del_recvdpkt
__P((struct recvdpkt
*));
91 static void rem_recvdpkt
__P((struct recvdpkt
*));
94 * functions about management of the isakmp status table
96 /* %%% management phase 1 handler */
98 * search for isakmpsa handler with isakmp index.
101 extern caddr_t
val2str(const char *, size_t);
104 * Enumerate the Phase 1 tree.
105 * If enum_func() internally return a non-zero value, this specific
106 * error value is returned. 0 is returned if everything went right.
108 * Note that it is ok for enum_func() to call insph1(). Those inserted
109 * Phase 1 will not interfere with current enumeration process.
112 enumph1(sel
, enum_func
, enum_arg
)
113 struct ph1selector
*sel
;
114 int (* enum_func
)(struct ph1handle
*iph1
, void *arg
);
120 LIST_FOREACH(p
, &ph1tree
, chain
) {
122 if (sel
->local
!= NULL
&&
123 cmpsaddr(sel
->local
, p
->local
) != 0)
126 if (sel
->remote
!= NULL
&&
127 cmpsaddr(sel
->remote
, p
->remote
) != 0)
131 if ((ret
= enum_func(p
, enum_arg
)) != 0)
144 LIST_FOREACH(p
, &ph1tree
, chain
) {
145 if (p
->status
>= PHASE1ST_EXPIRED
)
147 if (memcmp(&p
->index
, index
, sizeof(*index
)) == 0)
156 * search for isakmp handler by i_ck in index.
159 getph1byindex0(index
)
164 LIST_FOREACH(p
, &ph1tree
, chain
) {
165 if (p
->status
>= PHASE1ST_EXPIRED
)
167 if (memcmp(&p
->index
, index
, sizeof(cookie_t
)) == 0)
175 * search for isakmpsa handler by source and remote address.
176 * don't use port number to search because this function search
177 * with phase 2's destinaion.
180 getph1(ph1hint
, local
, remote
, flags
)
181 struct ph1handle
*ph1hint
;
182 struct sockaddr
*local
, *remote
;
187 plog(LLV_DEBUG2
, LOCATION
, NULL
, "getph1: start\n");
188 plog(LLV_DEBUG2
, LOCATION
, NULL
, "local: %s\n", saddr2str(local
));
189 plog(LLV_DEBUG2
, LOCATION
, NULL
, "remote: %s\n", saddr2str(remote
));
191 LIST_FOREACH(p
, &ph1tree
, chain
) {
192 if (p
->status
>= PHASE1ST_DYING
)
195 plog(LLV_DEBUG2
, LOCATION
, NULL
, "p->local: %s\n", saddr2str(p
->local
));
196 plog(LLV_DEBUG2
, LOCATION
, NULL
, "p->remote: %s\n", saddr2str(p
->remote
));
198 if ((flags
& GETPH1_F_ESTABLISHED
) &&
199 (p
->status
!= PHASE1ST_ESTABLISHED
)) {
200 plog(LLV_DEBUG2
, LOCATION
, NULL
,
201 "status %d, skipping\n", p
->status
);
205 if (local
!= NULL
&& cmpsaddr(local
, p
->local
) == CMPSADDR_MISMATCH
)
208 if (remote
!= NULL
&& cmpsaddr(remote
, p
->remote
) == CMPSADDR_MISMATCH
)
211 if (ph1hint
!= NULL
) {
212 if (ph1hint
->id
&& ph1hint
->id
->l
&& p
->id
&& p
->id
->l
&&
213 (ph1hint
->id
->l
!= p
->id
->l
||
214 memcmp(ph1hint
->id
->v
, p
->id
->v
, p
->id
->l
) != 0)) {
215 plog(LLV_DEBUG2
, LOCATION
, NULL
,
216 "local identity does match hint\n");
219 if (ph1hint
->id_p
&& ph1hint
->id_p
->l
&&
220 p
->id_p
&& p
->id_p
->l
&&
221 (ph1hint
->id_p
->l
!= p
->id_p
->l
||
222 memcmp(ph1hint
->id_p
->v
, p
->id_p
->v
, p
->id_p
->l
) != 0)) {
223 plog(LLV_DEBUG2
, LOCATION
, NULL
,
224 "remote identity does match hint\n");
229 plog(LLV_DEBUG2
, LOCATION
, NULL
, "matched\n");
233 plog(LLV_DEBUG2
, LOCATION
, NULL
, "no match\n");
239 resolveph1rmconf(iph1
)
240 struct ph1handle
*iph1
;
242 struct remoteconf
*rmconf
;
244 /* INITIATOR is always expected to know the exact rmconf. */
245 if (iph1
->side
== INITIATOR
)
248 rmconf
= getrmconf_by_ph1(iph1
);
251 if (rmconf
== RMCONF_ERR_MULTIPLE
)
254 if (iph1
->rmconf
!= NULL
) {
255 if (rmconf
!= iph1
->rmconf
) {
256 plog(LLV_ERROR
, LOCATION
, NULL
,
257 "unexpected rmconf switch; killing ph1\n");
261 iph1
->rmconf
= rmconf
;
269 * move phase2s from old_iph1 to new_iph1
272 migrate_ph12(old_iph1
, new_iph1
)
273 struct ph1handle
*old_iph1
, *new_iph1
;
275 struct ph2handle
*p
, *next
;
277 /* Relocate phase2s to better phase1s or request a new phase1. */
278 for (p
= LIST_FIRST(&old_iph1
->ph2tree
); p
; p
= next
) {
279 next
= LIST_NEXT(p
, ph1bind
);
281 if (p
->status
!= PHASE2ST_ESTABLISHED
)
285 bindph12(new_iph1
, p
);
290 * the iph1 is new, migrate all phase2s that belong to a dying or dead ph1
292 void migrate_dying_ph12(iph1
)
293 struct ph1handle
*iph1
;
297 LIST_FOREACH(p
, &ph1tree
, chain
) {
300 if (p
->status
< PHASE1ST_DYING
)
303 if (cmpsaddr(iph1
->local
, p
->local
) == 0
304 && cmpsaddr(iph1
->remote
, p
->remote
) == 0)
305 migrate_ph12(p
, iph1
);
316 struct ph1handle
*iph1
;
321 /* get length of buffer */
322 LIST_FOREACH(iph1
, &ph1tree
, chain
)
325 buf
= vmalloc(cnt
* sizeof(struct ph1dump
));
327 plog(LLV_ERROR
, LOCATION
, NULL
,
328 "failed to get buffer\n");
331 pd
= (struct ph1dump
*)buf
->v
;
333 LIST_FOREACH(iph1
, &ph1tree
, chain
) {
334 memcpy(&pd
->index
, &iph1
->index
, sizeof(iph1
->index
));
335 pd
->status
= iph1
->status
;
336 pd
->side
= iph1
->side
;
337 memcpy(&pd
->remote
, iph1
->remote
, sysdep_sa_len(iph1
->remote
));
338 memcpy(&pd
->local
, iph1
->local
, sysdep_sa_len(iph1
->local
));
339 pd
->version
= iph1
->version
;
340 pd
->etype
= iph1
->etype
;
341 pd
->created
= iph1
->created
;
342 pd
->ph2cnt
= iph1
->ph2cnt
;
350 * create new isakmp Phase 1 status record to handle isakmp in Phase1
355 struct ph1handle
*iph1
;
357 /* create new iph1 */
358 iph1
= racoon_calloc(1, sizeof(*iph1
));
362 iph1
->status
= PHASE1ST_SPAWN
;
365 iph1
->dpd_support
= 0;
369 evt_list_init(&iph1
->evt_listeners
);
375 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
379 struct ph1handle
*iph1
;
384 /* SA down shell script hook */
385 script_hook(iph1
, SCRIPT_PHASE1_DOWN
);
386 evt_list_cleanup(&iph1
->evt_listeners
);
389 if (iph1
->natt_flags
& NAT_KA_QUEUED
)
390 natt_keepalive_remove (iph1
->local
, iph1
->remote
);
392 if (iph1
->natt_options
) {
393 racoon_free(iph1
->natt_options
);
394 iph1
->natt_options
= NULL
;
400 isakmp_cfg_rmstate(iph1
);
404 sched_cancel(&iph1
->dpd_r_u
);
406 sched_cancel(&iph1
->sce
);
407 sched_cancel(&iph1
->scr
);
410 racoon_free(iph1
->remote
);
414 racoon_free(iph1
->local
);
417 if (iph1
->approval
) {
418 delisakmpsa(iph1
->approval
);
419 iph1
->approval
= NULL
;
422 VPTRINIT(iph1
->authstr
);
423 VPTRINIT(iph1
->sendbuf
);
424 VPTRINIT(iph1
->dhpriv
);
425 VPTRINIT(iph1
->dhpub
);
426 VPTRINIT(iph1
->dhpub_p
);
427 VPTRINIT(iph1
->dhgxy
);
428 VPTRINIT(iph1
->nonce
);
429 VPTRINIT(iph1
->nonce_p
);
430 VPTRINIT(iph1
->skeyid
);
431 VPTRINIT(iph1
->skeyid_d
);
432 VPTRINIT(iph1
->skeyid_a
);
433 VPTRINIT(iph1
->skeyid_e
);
435 VPTRINIT(iph1
->hash
);
437 VPTRINIT(iph1
->sig_p
);
438 VPTRINIT(iph1
->cert
);
439 VPTRINIT(iph1
->cert_p
);
440 VPTRINIT(iph1
->crl_p
);
441 VPTRINIT(iph1
->cr_p
);
443 VPTRINIT(iph1
->id_p
);
445 if(iph1
->approval
!= NULL
)
446 delisakmpsa(iph1
->approval
);
449 oakley_delivm(iph1
->ivm
);
454 VPTRINIT(iph1
->sa_ret
);
457 VPTRINIT(iph1
->gi_i
);
458 VPTRINIT(iph1
->gi_r
);
460 gssapi_free_state(iph1
);
467 * create new isakmp Phase 1 status record to handle isakmp in Phase1
471 struct ph1handle
*iph1
;
474 if (iph1
->remote
== NULL
) {
475 plog(LLV_ERROR
, LOCATION
, NULL
,
476 "invalid isakmp SA handler. no remote address.\n");
479 LIST_INSERT_HEAD(&ph1tree
, iph1
, chain
);
486 struct ph1handle
*iph1
;
488 LIST_REMOVE(iph1
, chain
);
497 struct ph1handle
*p
, *next
;
499 for (p
= LIST_FIRST(&ph1tree
); p
; p
= next
) {
500 next
= LIST_NEXT(p
, chain
);
502 /* send delete information */
503 if (p
->status
>= PHASE1ST_ESTABLISHED
)
504 isakmp_info_send_d1(p
);
517 /* %%% management phase 2 handler */
520 enumph2(sel
, enum_func
, enum_arg
)
521 struct ph2selector
*sel
;
522 int (*enum_func
)(struct ph2handle
*ph2
, void *arg
);
528 LIST_FOREACH(p
, &ph2tree
, chain
) {
530 if (sel
->spid
!= 0 && sel
->spid
!= p
->spid
)
533 if (sel
->src
!= NULL
&&
534 cmpsaddr(sel
->src
, p
->src
) != 0)
537 if (sel
->dst
!= NULL
&&
538 cmpsaddr(sel
->dst
, p
->dst
) != 0)
542 if ((ret
= enum_func(p
, enum_arg
)) != 0)
550 * search ph2handle with sequence number.
558 LIST_FOREACH(p
, &ph2tree
, chain
) {
567 * search ph2handle with message id.
570 getph2bymsgid(iph1
, msgid
)
571 struct ph1handle
*iph1
;
576 LIST_FOREACH(p
, &iph1
->ph2tree
, chain
) {
577 if (p
->msgid
== msgid
&& p
->ph1
== iph1
)
584 /* Note that src and dst are not the selectors of the SP
585 * but the source and destination addresses used for
586 * for SA negotiation (best example is tunnel mode SA
587 * where src and dst are the endpoints). There is at most
588 * a unique match because racoon does not support bundles
589 * which makes that there is at most a single established
590 * SA for a given spid. One could say that src and dst
591 * are in fact useless ...
594 getph2byid(src
, dst
, spid
)
595 struct sockaddr
*src
, *dst
;
600 LIST_FOREACH(p
, &ph2tree
, chain
) {
601 if (spid
== p
->spid
&&
602 cmpsaddr(src
, p
->src
) == 0 &&
603 cmpsaddr(dst
, p
->dst
) == 0){
604 /* Sanity check to detect zombie handlers
605 * XXX Sould be done "somewhere" more interesting,
606 * because we have lots of getph2byxxxx(), but this one
607 * is called by pk_recvacquire(), so is the most important.
609 if(p
->status
< PHASE2ST_ESTABLISHED
&&
610 p
->retry_counter
== 0
611 && p
->sce
.func
== NULL
&& p
->scr
.func
== NULL
) {
612 plog(LLV_DEBUG
, LOCATION
, NULL
,
613 "Zombie ph2 found, expiring it\n");
624 getph2bysaddr(src
, dst
)
625 struct sockaddr
*src
, *dst
;
629 LIST_FOREACH(p
, &ph2tree
, chain
) {
630 if (cmpsaddr(src
, p
->src
) == 0 &&
631 cmpsaddr(dst
, p
->dst
) == 0)
639 * call by pk_recvexpire().
642 getph2bysaidx(src
, dst
, proto_id
, spi
)
643 struct sockaddr
*src
, *dst
;
647 struct ph2handle
*iph2
;
650 LIST_FOREACH(iph2
, &ph2tree
, chain
) {
651 if (iph2
->proposal
== NULL
&& iph2
->approval
== NULL
)
653 if (iph2
->approval
!= NULL
) {
654 for (pr
= iph2
->approval
->head
; pr
!= NULL
;
656 if (proto_id
!= pr
->proto_id
)
658 if (spi
== pr
->spi
|| spi
== pr
->spi_p
)
661 } else if (iph2
->proposal
!= NULL
) {
662 for (pr
= iph2
->proposal
->head
; pr
!= NULL
;
664 if (proto_id
!= pr
->proto_id
)
676 * create new isakmp Phase 2 status record to handle isakmp in Phase2
681 struct ph2handle
*iph2
= NULL
;
683 /* create new iph2 */
684 iph2
= racoon_calloc(1, sizeof(*iph2
));
688 iph2
->status
= PHASE1ST_SPAWN
;
689 evt_list_init(&iph2
->evt_listeners
);
695 * initialize ph2handle
696 * NOTE: don't initialize src/dst.
697 * SPI in the proposal is cleared.
701 struct ph2handle
*iph2
;
703 evt_list_cleanup(&iph2
->evt_listeners
);
706 sched_cancel(&iph2
->sce
);
707 sched_cancel(&iph2
->scr
);
709 VPTRINIT(iph2
->sendbuf
);
710 VPTRINIT(iph2
->msg1
);
712 /* clear spi, keep variables in the proposal */
713 if (iph2
->proposal
) {
715 for (pr
= iph2
->proposal
->head
; pr
!= NULL
; pr
= pr
->next
)
720 if (iph2
->approval
) {
721 flushsaprop(iph2
->approval
);
722 iph2
->approval
= NULL
;
725 /* clear the generated policy */
726 if (iph2
->spidx_gen
) {
727 delsp_bothdir((struct policyindex
*)iph2
->spidx_gen
);
728 racoon_free(iph2
->spidx_gen
);
729 iph2
->spidx_gen
= NULL
;
733 oakley_dhgrp_free(iph2
->pfsgrp
);
737 VPTRINIT(iph2
->dhpriv
);
738 VPTRINIT(iph2
->dhpub
);
739 VPTRINIT(iph2
->dhpub_p
);
740 VPTRINIT(iph2
->dhgxy
);
742 VPTRINIT(iph2
->id_p
);
743 VPTRINIT(iph2
->nonce
);
744 VPTRINIT(iph2
->nonce_p
);
746 VPTRINIT(iph2
->sa_ret
);
749 oakley_delivm(iph2
->ivm
);
754 if (iph2
->natoa_src
) {
755 racoon_free(iph2
->natoa_src
);
756 iph2
->natoa_src
= NULL
;
758 if (iph2
->natoa_dst
) {
759 racoon_free(iph2
->natoa_dst
);
760 iph2
->natoa_dst
= NULL
;
766 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
770 struct ph2handle
*iph2
;
775 racoon_free(iph2
->src
);
779 racoon_free(iph2
->dst
);
783 racoon_free(iph2
->sa_src
);
787 racoon_free(iph2
->sa_dst
);
791 if (iph2
->natoa_src
) {
792 racoon_free(iph2
->natoa_src
);
793 iph2
->natoa_src
= NULL
;
795 if (iph2
->natoa_dst
) {
796 racoon_free(iph2
->natoa_dst
);
797 iph2
->natoa_dst
= NULL
;
801 if (iph2
->proposal
) {
802 flushsaprop(iph2
->proposal
);
803 iph2
->proposal
= NULL
;
810 * create new isakmp Phase 2 status record to handle isakmp in Phase2
814 struct ph2handle
*iph2
;
816 LIST_INSERT_HEAD(&ph2tree
, iph2
, chain
);
823 struct ph2handle
*iph2
;
826 LIST_REMOVE(iph2
, chain
);
838 struct ph2handle
*p
, *next
;
840 plog(LLV_DEBUG2
, LOCATION
, NULL
,
841 "flushing all ph2 handlers...\n");
843 for (p
= LIST_FIRST(&ph2tree
); p
; p
= next
) {
844 next
= LIST_NEXT(p
, chain
);
846 /* send delete information */
847 if (p
->status
== PHASE2ST_ESTABLISHED
){
848 plog(LLV_DEBUG2
, LOCATION
, NULL
,
849 "got a ph2 handler to flush...\n");
850 isakmp_info_send_d2(p
);
852 plog(LLV_DEBUG2
, LOCATION
, NULL
,
853 "skipping ph2 handler (state %d)\n", p
->status
);
863 * Delete all Phase 2 handlers for this src/dst/proto. This
864 * is used during INITIAL-CONTACT processing (so no need to
865 * send a message to the peer).
868 deleteallph2(src
, dst
, proto_id
)
869 struct sockaddr
*src
, *dst
;
872 struct ph2handle
*iph2
, *next
;
875 for (iph2
= LIST_FIRST(&ph2tree
); iph2
!= NULL
; iph2
= next
) {
876 next
= LIST_NEXT(iph2
, chain
);
877 if (iph2
->proposal
== NULL
&& iph2
->approval
== NULL
)
879 if (iph2
->approval
!= NULL
) {
880 for (pr
= iph2
->approval
->head
; pr
!= NULL
;
882 if (proto_id
== pr
->proto_id
)
885 } else if (iph2
->proposal
!= NULL
) {
886 for (pr
= iph2
->proposal
->head
; pr
!= NULL
;
888 if (proto_id
== pr
->proto_id
)
902 struct ph1handle
*iph1
;
903 struct ph2handle
*iph2
;
909 LIST_INSERT_HEAD(&iph1
->ph2tree
, iph2
, ph1bind
);
914 struct ph2handle
*iph2
;
916 if (iph2
->ph1
!= NULL
) {
917 LIST_REMOVE(iph2
, ph1bind
);
923 /* %%% management contacted list */
925 * search contacted list.
929 struct sockaddr
*remote
;
933 LIST_FOREACH(p
, &ctdtree
, chain
) {
934 if (cmpsaddr(remote
, p
->remote
) == 0)
942 * create new isakmp Phase 2 status record to handle isakmp in Phase2
946 struct sockaddr
*remote
;
948 struct contacted
*new;
950 /* create new iph2 */
951 new = racoon_calloc(1, sizeof(*new));
955 new->remote
= dupsaddr(remote
);
956 if (new->remote
== NULL
) {
957 plog(LLV_ERROR
, LOCATION
, NULL
,
958 "failed to allocate buffer.\n");
963 LIST_INSERT_HEAD(&ctdtree
, new, chain
);
975 * check the response has been sent to the peer. when not, simply reply
976 * the buffered packet to the peer.
978 * 0: the packet is received at the first time.
979 * 1: the packet was processed before.
980 * 2: the packet was processed before, but the address mismatches.
981 * -1: error happened.
984 check_recvdpkt(remote
, local
, rbuf
)
985 struct sockaddr
*remote
, *local
;
990 struct timeval now
, diff
;
993 hash
= eay_md5_one(rbuf
);
995 plog(LLV_ERROR
, LOCATION
, NULL
,
996 "failed to allocate buffer.\n");
1000 LIST_FOREACH(r
, &rcptree
, chain
) {
1001 if (memcmp(hash
->v
, r
->hash
->v
, r
->hash
->l
) == 0)
1006 /* this is the first time to receive the packet */
1011 * the packet was processed before, but the remote address mismatches.
1013 if (cmpsaddr(remote
, r
->remote
) != 0)
1017 * it should not check the local address because the packet
1018 * may arrive at other interface.
1021 /* check the previous time to send */
1022 sched_get_monotonic_time(&now
);
1023 timersub(&now
, &r
->time_send
, &diff
);
1024 if (diff
.tv_sec
== 0) {
1025 plog(LLV_WARNING
, LOCATION
, NULL
,
1026 "the packet retransmitted in a short time from %s\n",
1028 /*XXX should it be error ? */
1031 /* select the socket to be sent */
1032 s
= myaddr_getfd(r
->local
);
1036 /* resend the packet if needed */
1037 len
= sendfromto(s
, r
->sendbuf
->v
, r
->sendbuf
->l
,
1038 r
->local
, r
->remote
, lcconf
->count_persend
);
1040 plog(LLV_ERROR
, LOCATION
, NULL
, "sendfromto failed\n");
1044 /* check the retry counter */
1046 if (r
->retry_counter
<= 0) {
1049 plog(LLV_DEBUG
, LOCATION
, NULL
,
1050 "deleted the retransmission packet to %s.\n",
1059 * adding a hash of received packet into the received list.
1062 add_recvdpkt(remote
, local
, sbuf
, rbuf
)
1063 struct sockaddr
*remote
, *local
;
1064 vchar_t
*sbuf
, *rbuf
;
1066 struct recvdpkt
*new = NULL
;
1068 if (lcconf
->retry_counter
== 0) {
1069 /* no need to add it */
1073 new = racoon_calloc(1, sizeof(*new));
1075 plog(LLV_ERROR
, LOCATION
, NULL
,
1076 "failed to allocate buffer.\n");
1080 new->hash
= eay_md5_one(rbuf
);
1082 plog(LLV_ERROR
, LOCATION
, NULL
,
1083 "failed to allocate buffer.\n");
1087 new->remote
= dupsaddr(remote
);
1088 if (new->remote
== NULL
) {
1089 plog(LLV_ERROR
, LOCATION
, NULL
,
1090 "failed to allocate buffer.\n");
1094 new->local
= dupsaddr(local
);
1095 if (new->local
== NULL
) {
1096 plog(LLV_ERROR
, LOCATION
, NULL
,
1097 "failed to allocate buffer.\n");
1101 new->sendbuf
= vdup(sbuf
);
1102 if (new->sendbuf
== NULL
) {
1103 plog(LLV_ERROR
, LOCATION
, NULL
,
1104 "failed to allocate buffer.\n");
1109 new->retry_counter
= lcconf
->retry_counter
;
1110 sched_get_monotonic_time(&new->time_send
);
1112 LIST_INSERT_HEAD(&rcptree
, new, chain
);
1122 racoon_free(r
->remote
);
1124 racoon_free(r
->local
);
1136 LIST_REMOVE(r
, chain
);
1140 sweep_recvdpkt(dummy
)
1141 struct sched
*dummy
;
1143 struct recvdpkt
*r
, *next
;
1144 struct timeval now
, diff
, sweep
;
1146 sched_get_monotonic_time(&now
);
1148 /* calculate sweep time; delete entries older than this */
1149 diff
.tv_sec
= lcconf
->retry_counter
* lcconf
->retry_interval
;
1151 timersub(&now
, &diff
, &sweep
);
1153 for (r
= LIST_FIRST(&rcptree
); r
; r
= next
) {
1154 next
= LIST_NEXT(r
, chain
);
1156 if (timercmp(&r
->time_send
, &sweep
, <)) {
1162 sched_schedule(&sc_sweep
, diff
.tv_sec
, sweep_recvdpkt
);
1168 time_t lt
= lcconf
->retry_counter
* lcconf
->retry_interval
;
1170 LIST_INIT(&rcptree
);
1172 sched_schedule(&sc_sweep
, lt
, sweep_recvdpkt
);
1175 #ifdef ENABLE_HYBRID
1177 * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
1178 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
1181 exclude_cfg_addr(addr
)
1182 const struct sockaddr
*addr
;
1184 struct ph1handle
*p
;
1185 struct sockaddr_in
*sin
;
1187 LIST_FOREACH(p
, &ph1tree
, chain
) {
1188 if ((p
->mode_cfg
!= NULL
) &&
1189 (p
->mode_cfg
->flags
& ISAKMP_CFG_GOT_ADDR4
) &&
1190 (addr
->sa_family
== AF_INET
)) {
1191 sin
= (struct sockaddr_in
*)addr
;
1192 if (sin
->sin_addr
.s_addr
== p
->mode_cfg
->addr4
.s_addr
)
1206 static int revalidate_ph2(struct ph2handle
*iph2
){
1207 struct sainfoalg
*alg
;
1208 int found
, check_level
;
1209 struct sainfo
*sainfo
;
1210 struct saprop
*approval
;
1211 struct ph1handle
*iph1
;
1214 * Get the new sainfo using values of the old one
1216 if (iph2
->sainfo
!= NULL
) {
1217 iph2
->sainfo
= getsainfo(iph2
->sainfo
->idsrc
,
1218 iph2
->sainfo
->iddst
, iph2
->sainfo
->id_i
,
1219 NULL
, iph2
->sainfo
->remoteid
);
1221 approval
= iph2
->approval
;
1222 sainfo
= iph2
->sainfo
;
1224 if (sainfo
== NULL
) {
1226 * Sainfo has been removed
1228 plog(LLV_DEBUG
, LOCATION
, NULL
,
1229 "Reload: No sainfo for ph2\n");
1233 if (approval
== NULL
) {
1235 * XXX why do we have a NULL approval sometimes ???
1237 plog(LLV_DEBUG
, LOCATION
, NULL
,
1238 "No approval found !\n");
1243 * Don't care about proposals, should we do something ?
1244 * We have to keep iph2->proposal valid at least for initiator,
1245 * for pk_sendgetspi()
1248 plog(LLV_DEBUG
, LOCATION
, NULL
, "active single bundle:\n");
1249 printsaprop0(LLV_DEBUG
, approval
);
1252 * Validate approval against sainfo
1253 * Note: we must have an updated ph1->rmconf before doing that,
1254 * we'll set check_level to EXACT if we don't have a ph1
1255 * XXX try tu find the new remote section to get the new check level ?
1258 if (iph2
->ph1
!= NULL
)
1261 iph1
=getph1byaddr(iph2
->src
, iph2
->dst
, 0);
1263 if(iph1
!= NULL
&& iph1
->rmconf
!= NULL
) {
1264 check_level
= iph1
->rmconf
->pcheck_level
;
1267 plog(LLV_DEBUG
, LOCATION
, NULL
, "No phase1 rmconf found !\n");
1269 plog(LLV_DEBUG
, LOCATION
, NULL
, "No phase1 found !\n");
1270 check_level
= PROP_CHECK_EXACT
;
1273 switch (check_level
) {
1274 case PROP_CHECK_OBEY
:
1275 plog(LLV_DEBUG
, LOCATION
, NULL
,
1276 "Reload: OBEY for ph2, ok\n");
1280 case PROP_CHECK_STRICT
:
1282 case PROP_CHECK_CLAIM
:
1283 if (sainfo
->lifetime
< approval
->lifetime
) {
1284 plog(LLV_DEBUG
, LOCATION
, NULL
,
1285 "Reload: lifetime mismatch\n");
1290 /* Lifebyte is deprecated, just ignore it
1292 if (sainfo
->lifebyte
< approval
->lifebyte
) {
1293 plog(LLV_DEBUG
, LOCATION
, NULL
,
1294 "Reload: lifebyte mismatch\n");
1299 if (sainfo
->pfs_group
&&
1300 sainfo
->pfs_group
!= approval
->pfs_group
) {
1301 plog(LLV_DEBUG
, LOCATION
, NULL
,
1302 "Reload: PFS group mismatch\n");
1307 case PROP_CHECK_EXACT
:
1308 if (sainfo
->lifetime
!= approval
->lifetime
||
1310 /* Lifebyte is deprecated, just ignore it
1312 sainfo
->lifebyte
!= approval
->lifebyte
||
1314 sainfo
->pfs_group
!= iph2
->approval
->pfs_group
) {
1315 plog(LLV_DEBUG
, LOCATION
, NULL
,
1316 "Reload: lifetime | pfs mismatch\n");
1322 plog(LLV_DEBUG
, LOCATION
, NULL
,
1323 "Reload: Shouldn't be here !\n");
1328 for (alg
= sainfo
->algs
[algclass_ipsec_auth
]; alg
; alg
= alg
->next
) {
1329 if (alg
->alg
== approval
->head
->head
->authtype
)
1333 plog(LLV_DEBUG
, LOCATION
, NULL
,
1334 "Reload: alg == NULL (auth)\n");
1339 for (alg
= sainfo
->algs
[algclass_ipsec_enc
];
1340 (found
== 0 && alg
!= NULL
); alg
= alg
->next
) {
1341 plog(LLV_DEBUG
, LOCATION
, NULL
,
1342 "Reload: next ph2 enc alg...\n");
1344 if (alg
->alg
!= approval
->head
->head
->trns_id
){
1345 plog(LLV_DEBUG
, LOCATION
, NULL
,
1346 "Reload: encmode mismatch (%d / %d)\n",
1347 alg
->alg
, approval
->head
->head
->trns_id
);
1351 switch (check_level
){
1352 /* PROP_CHECK_STRICT cannot happen here */
1353 case PROP_CHECK_EXACT
:
1354 if (alg
->encklen
!= approval
->head
->head
->encklen
) {
1355 plog(LLV_DEBUG
, LOCATION
, NULL
,
1356 "Reload: enclen mismatch\n");
1361 case PROP_CHECK_CLAIM
:
1363 case PROP_CHECK_STRICT
:
1364 if (alg
->encklen
> approval
->head
->head
->encklen
) {
1365 plog(LLV_DEBUG
, LOCATION
, NULL
,
1366 "Reload: enclen mismatch\n");
1372 plog(LLV_ERROR
, LOCATION
, NULL
,
1373 "unexpected check_level\n");
1381 plog(LLV_DEBUG
, LOCATION
, NULL
,
1382 "Reload: No valid enc\n");
1389 plog(LLV_DEBUG
, LOCATION
, NULL
,
1390 "Reload: ph2 check ok\n");
1397 remove_ph2(struct ph2handle
*iph2
)
1404 plog(LLV_DEBUG
, LOCATION
, NULL
,
1405 "Deleting a Ph2...\n");
1407 if (iph2
->status
== PHASE2ST_ESTABLISHED
)
1408 isakmp_info_send_d2(iph2
);
1410 if(iph2
->approval
!= NULL
&& iph2
->approval
->head
!= NULL
){
1411 spis
[0]=iph2
->approval
->head
->spi
;
1412 spis
[1]=iph2
->approval
->head
->spi_p
;
1414 /* purge_ipsec_spi() will do all the work:
1415 * - delete SPIs in kernel
1416 * - delete generated SPD
1417 * - unbind / rem / del ph2
1419 purge_ipsec_spi(iph2
->dst
, iph2
->approval
->head
->proto_id
,
1427 static void remove_ph1(struct ph1handle
*iph1
){
1428 struct ph2handle
*iph2
, *iph2_next
;
1433 plog(LLV_DEBUG
, LOCATION
, NULL
,
1434 "Removing PH1...\n");
1436 if (iph1
->status
== PHASE1ST_ESTABLISHED
||
1437 iph1
->status
== PHASE1ST_DYING
) {
1438 for (iph2
= LIST_FIRST(&iph1
->ph2tree
); iph2
; iph2
= iph2_next
) {
1439 iph2_next
= LIST_NEXT(iph2
, chain
);
1442 isakmp_info_send_d1(iph1
);
1444 iph1
->status
= PHASE1ST_EXPIRED
;
1445 sched_schedule(&iph1
->sce
, 1, isakmp_ph1delete_stub
);
1449 static int revalidate_ph1tree_rmconf(void)
1451 struct ph1handle
*p
, *next
;
1453 for (p
= LIST_FIRST(&ph1tree
); p
; p
= next
) {
1454 next
= LIST_NEXT(p
, chain
);
1456 if (p
->status
>= PHASE1ST_EXPIRED
)
1458 if (p
->rmconf
== NULL
)
1461 p
->rmconf
= getrmconf_by_ph1(p
);
1462 if (p
->rmconf
== NULL
|| p
->rmconf
== RMCONF_ERR_MULTIPLE
)
1469 static int revalidate_ph2tree(void){
1470 struct ph2handle
*p
, *next
;
1472 for (p
= LIST_FIRST(&ph2tree
); p
; p
= next
) {
1473 next
= LIST_NEXT(p
, chain
);
1475 if (p
->status
== PHASE2ST_EXPIRED
)
1478 if(!revalidate_ph2(p
)){
1479 plog(LLV_DEBUG
, LOCATION
, NULL
,
1480 "PH2 not validated, removing it\n");
1489 revalidate_ph12(void)
1492 revalidate_ph1tree_rmconf();
1493 revalidate_ph2tree();
1498 #ifdef ENABLE_HYBRID
1500 getph1bylogin(login
)
1503 struct ph1handle
*p
;
1505 LIST_FOREACH(p
, &ph1tree
, chain
) {
1506 if (p
->mode_cfg
== NULL
)
1508 if (strncmp(p
->mode_cfg
->login
, login
, LOGINLEN
) == 0)
1516 purgeph1bylogin(login
)
1519 struct ph1handle
*p
;
1522 LIST_FOREACH(p
, &ph1tree
, chain
) {
1523 if (p
->mode_cfg
== NULL
)
1525 if (strncmp(p
->mode_cfg
->login
, login
, LOGINLEN
) == 0) {
1526 if (p
->status
>= PHASE1ST_EXPIRED
)
1529 if (p
->status
>= PHASE1ST_ESTABLISHED
)
1530 isakmp_info_send_d1(p
);