1 /* $Id: handler.c,v 1.13 2004/11/21 19:36:26 manubsd Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
52 #include "grabmyaddr.h"
53 #include "algorithm.h"
54 #include "crypto_openssl.h"
57 #include "isakmp_var.h"
61 #include "isakmp_xauth.h"
62 #include "isakmp_cfg.h"
64 #include "isakmp_inf.h"
66 #include "remoteconf.h"
67 #include "localconf.h"
70 #include "nattraversal.h"
76 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
77 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
78 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
79 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
81 static void del_recvdpkt __P((struct recvdpkt *));
82 static void rem_recvdpkt __P((struct recvdpkt *));
83 static void sweep_recvdpkt __P((void *));
86 * functions about management of the isakmp status table
88 /* %%% management phase 1 handler */
90 * search for isakmpsa handler with isakmp index.
93 extern caddr_t val2str(const char *, size_t);
101 LIST_FOREACH(p, &ph1tree, chain) {
102 if (p->status == PHASE1ST_EXPIRED)
104 if (memcmp(&p->index, index, sizeof(*index)) == 0)
112 * search for isakmp handler by i_ck in index.
115 getph1byindex0(index)
120 LIST_FOREACH(p, &ph1tree, chain) {
121 if (p->status == PHASE1ST_EXPIRED)
123 if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
131 * search for isakmpsa handler by source and remote address.
132 * don't use port number to search because this function search
133 * with phase 2's destinaion.
136 getph1byaddr(local, remote)
137 struct sockaddr *local, *remote;
141 LIST_FOREACH(p, &ph1tree, chain) {
142 if (p->status == PHASE1ST_EXPIRED)
144 if (cmpsaddrwop(local, p->local) == 0
145 && cmpsaddrwop(remote, p->remote) == 0)
153 * search for isakmpsa handler by remote address.
154 * don't use port number to search because this function search
155 * with phase 2's destinaion.
158 getph1bydstaddr(remote)
159 struct sockaddr *remote;
163 LIST_FOREACH(p, &ph1tree, chain) {
164 if (p->status == PHASE1ST_EXPIRED)
166 if (cmpsaddrwop(remote, p->remote) == 0)
179 struct ph1handle *iph1;
184 /* get length of buffer */
185 LIST_FOREACH(iph1, &ph1tree, chain)
188 buf = vmalloc(cnt * sizeof(struct ph1dump));
190 plog(LLV_ERROR, LOCATION, NULL,
191 "failed to get buffer\n");
194 pd = (struct ph1dump *)buf->v;
196 LIST_FOREACH(iph1, &ph1tree, chain) {
197 memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
198 pd->status = iph1->status;
199 pd->side = iph1->side;
200 memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
201 memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
202 pd->version = iph1->version;
203 pd->etype = iph1->etype;
204 pd->created = iph1->created;
205 pd->ph2cnt = iph1->ph2cnt;
213 * create new isakmp Phase 1 status record to handle isakmp in Phase1
218 struct ph1handle *iph1;
220 /* create new iph1 */
221 iph1 = racoon_calloc(1, sizeof(*iph1));
225 iph1->status = PHASE1ST_SPAWN;
228 iph1->dpd_support = 0;
229 iph1->dpd_lastack = 0;
232 iph1->dpd_r_u = NULL;
239 * delete new isakmp Phase 1 status record to handle isakmp in Phase1
243 struct ph1handle *iph1;
245 /* SA down shell script hook */
247 script_hook(iph1, SCRIPT_PHASE1_DOWN);
249 EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
252 if (iph1->natt_flags & NAT_KA_QUEUED)
253 natt_keepalive_remove (iph1->local, iph1->remote);
255 if (iph1->natt_options) {
256 racoon_free(iph1->natt_options);
257 iph1->natt_options = NULL;
262 racoon_free(iph1->remote);
266 racoon_free(iph1->local);
272 isakmp_cfg_rmstate(iph1);
275 VPTRINIT(iph1->authstr);
277 sched_scrub_param(iph1);
281 VPTRINIT(iph1->sendbuf);
283 VPTRINIT(iph1->dhpriv);
284 VPTRINIT(iph1->dhpub);
285 VPTRINIT(iph1->dhpub_p);
286 VPTRINIT(iph1->dhgxy);
287 VPTRINIT(iph1->nonce);
288 VPTRINIT(iph1->nonce_p);
289 VPTRINIT(iph1->skeyid);
290 VPTRINIT(iph1->skeyid_d);
291 VPTRINIT(iph1->skeyid_a);
292 VPTRINIT(iph1->skeyid_e);
294 VPTRINIT(iph1->hash);
296 VPTRINIT(iph1->sig_p);
297 oakley_delcert(iph1->cert);
299 oakley_delcert(iph1->cert_p);
301 oakley_delcert(iph1->crl_p);
303 oakley_delcert(iph1->cr_p);
306 VPTRINIT(iph1->id_p);
309 oakley_delivm(iph1->ivm);
314 VPTRINIT(iph1->sa_ret);
317 VPTRINIT(iph1->gi_i);
318 VPTRINIT(iph1->gi_r);
320 gssapi_free_state(iph1);
327 * create new isakmp Phase 1 status record to handle isakmp in Phase1
331 struct ph1handle *iph1;
334 if (iph1->remote == NULL) {
335 plog(LLV_ERROR, LOCATION, NULL,
336 "invalid isakmp SA handler. no remote address.\n");
339 LIST_INSERT_HEAD(&ph1tree, iph1, chain);
346 struct ph1handle *iph1;
348 LIST_REMOVE(iph1, chain);
357 struct ph1handle *p, *next;
359 for (p = LIST_FIRST(&ph1tree); p; p = next) {
360 next = LIST_NEXT(p, chain);
362 /* send delete information */
363 if (p->status == PHASE1ST_ESTABLISHED)
364 isakmp_info_send_d1(p);
377 /* %%% management phase 2 handler */
379 * search ph2handle with policy id.
387 LIST_FOREACH(p, &ph2tree, chain) {
389 * there are ph2handle independent on policy
390 * such like informational exchange.
400 * search ph2handle with sequence number.
408 LIST_FOREACH(p, &ph2tree, chain) {
417 * search ph2handle with message id.
420 getph2bymsgid(iph1, msgid)
421 struct ph1handle *iph1;
426 LIST_FOREACH(p, &ph2tree, chain) {
427 if (p->msgid == msgid)
435 * call by pk_recvexpire().
438 getph2bysaidx(src, dst, proto_id, spi)
439 struct sockaddr *src, *dst;
443 struct ph2handle *iph2;
446 LIST_FOREACH(iph2, &ph2tree, chain) {
447 if (iph2->proposal == NULL && iph2->approval == NULL)
449 if (iph2->approval != NULL) {
450 for (pr = iph2->approval->head; pr != NULL;
452 if (proto_id != pr->proto_id)
454 if (spi == pr->spi || spi == pr->spi_p)
457 } else if (iph2->proposal != NULL) {
458 for (pr = iph2->proposal->head; pr != NULL;
460 if (proto_id != pr->proto_id)
472 * create new isakmp Phase 2 status record to handle isakmp in Phase2
477 struct ph2handle *iph2 = NULL;
479 /* create new iph2 */
480 iph2 = racoon_calloc(1, sizeof(*iph2));
484 iph2->status = PHASE1ST_SPAWN;
490 * initialize ph2handle
491 * NOTE: don't initialize src/dst.
492 * SPI in the proposal is cleared.
496 struct ph2handle *iph2;
498 sched_scrub_param(iph2);
502 VPTRINIT(iph2->sendbuf);
503 VPTRINIT(iph2->msg1);
505 /* clear spi, keep variables in the proposal */
506 if (iph2->proposal) {
508 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
513 if (iph2->approval) {
514 flushsaprop(iph2->approval);
515 iph2->approval = NULL;
518 /* clear the generated policy */
519 if (iph2->spidx_gen) {
520 delsp_bothdir((struct policyindex *)iph2->spidx_gen);
521 racoon_free(iph2->spidx_gen);
522 iph2->spidx_gen = NULL;
526 oakley_dhgrp_free(iph2->pfsgrp);
530 VPTRINIT(iph2->dhpriv);
531 VPTRINIT(iph2->dhpub);
532 VPTRINIT(iph2->dhpub_p);
533 VPTRINIT(iph2->dhgxy);
535 VPTRINIT(iph2->id_p);
536 VPTRINIT(iph2->nonce);
537 VPTRINIT(iph2->nonce_p);
539 VPTRINIT(iph2->sa_ret);
542 oakley_delivm(iph2->ivm);
548 * delete new isakmp Phase 2 status record to handle isakmp in Phase2
552 struct ph2handle *iph2;
557 racoon_free(iph2->src);
561 racoon_free(iph2->dst);
565 racoon_free(iph2->src_id);
569 racoon_free(iph2->dst_id);
573 if (iph2->proposal) {
574 flushsaprop(iph2->proposal);
575 iph2->proposal = NULL;
582 * create new isakmp Phase 2 status record to handle isakmp in Phase2
586 struct ph2handle *iph2;
588 LIST_INSERT_HEAD(&ph2tree, iph2, chain);
595 struct ph2handle *iph2;
597 LIST_REMOVE(iph2, chain);
609 struct ph2handle *p, *next;
611 for (p = LIST_FIRST(&ph2tree); p; p = next) {
612 next = LIST_NEXT(p, chain);
614 /* send delete information */
615 if (p->status == PHASE2ST_ESTABLISHED)
616 isakmp_info_send_d2(p);
625 * Delete all Phase 2 handlers for this src/dst/proto. This
626 * is used during INITIAL-CONTACT processing (so no need to
627 * send a message to the peer).
630 deleteallph2(src, dst, proto_id)
631 struct sockaddr *src, *dst;
634 struct ph2handle *iph2, *next;
637 for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
638 next = LIST_NEXT(iph2, chain);
639 if (iph2->proposal == NULL && iph2->approval == NULL)
641 if (iph2->approval != NULL) {
642 for (pr = iph2->approval->head; pr != NULL;
644 if (proto_id == pr->proto_id)
647 } else if (iph2->proposal != NULL) {
648 for (pr = iph2->proposal->head; pr != NULL;
650 if (proto_id == pr->proto_id)
665 struct ph1handle *iph1;
666 struct ph2handle *iph2;
669 LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
674 struct ph2handle *iph2;
676 if (iph2->ph1 != NULL) {
678 LIST_REMOVE(iph2, ph1bind);
682 /* %%% management contacted list */
684 * search contacted list.
688 struct sockaddr *remote;
692 LIST_FOREACH(p, &ctdtree, chain) {
693 if (cmpsaddrstrict(remote, p->remote) == 0)
701 * create new isakmp Phase 2 status record to handle isakmp in Phase2
705 struct sockaddr *remote;
707 struct contacted *new;
709 /* create new iph2 */
710 new = racoon_calloc(1, sizeof(*new));
714 new->remote = dupsaddr(remote);
716 LIST_INSERT_HEAD(&ctdtree, new, chain);
728 * check the response has been sent to the peer. when not, simply reply
729 * the buffered packet to the peer.
731 * 0: the packet is received at the first time.
732 * 1: the packet was processed before.
733 * 2: the packet was processed before, but the address mismatches.
734 * -1: error happened.
737 check_recvdpkt(remote, local, rbuf)
738 struct sockaddr *remote, *local;
746 /* set current time */
749 hash = eay_md5_one(rbuf);
751 plog(LLV_ERROR, LOCATION, NULL,
752 "failed to allocate buffer.\n");
756 LIST_FOREACH(r, &rcptree, chain) {
757 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
762 /* this is the first time to receive the packet */
767 * the packet was processed before, but the remote address mismatches.
769 if (cmpsaddrstrict(remote, r->remote) != 0)
773 * it should not check the local address because the packet
774 * may arrive at other interface.
777 /* check the previous time to send */
778 if (t - r->time_send < 1) {
779 plog(LLV_WARNING, LOCATION, NULL,
780 "the packet retransmitted in a short time from %s\n",
782 /*XXX should it be error ? */
785 /* select the socket to be sent */
786 s = getsockmyaddr(r->local);
790 /* resend the packet if needed */
791 len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
792 r->local, r->remote, lcconf->count_persend);
794 plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
798 /* check the retry counter */
800 if (r->retry_counter <= 0) {
803 plog(LLV_DEBUG, LOCATION, NULL,
804 "deleted the retransmission packet to %s.\n",
813 * adding a hash of received packet into the received list.
816 add_recvdpkt(remote, local, sbuf, rbuf)
817 struct sockaddr *remote, *local;
818 vchar_t *sbuf, *rbuf;
820 struct recvdpkt *new = NULL;
822 if (lcconf->retry_counter == 0) {
823 /* no need to add it */
827 new = racoon_calloc(1, sizeof(*new));
829 plog(LLV_ERROR, LOCATION, NULL,
830 "failed to allocate buffer.\n");
834 new->hash = eay_md5_one(rbuf);
836 plog(LLV_ERROR, LOCATION, NULL,
837 "failed to allocate buffer.\n");
841 new->remote = dupsaddr(remote);
842 if (new->remote == NULL) {
843 plog(LLV_ERROR, LOCATION, NULL,
844 "failed to allocate buffer.\n");
848 new->local = dupsaddr(local);
849 if (new->local == NULL) {
850 plog(LLV_ERROR, LOCATION, NULL,
851 "failed to allocate buffer.\n");
855 new->sendbuf = vdup(sbuf);
856 if (new->sendbuf == NULL) {
857 plog(LLV_ERROR, LOCATION, NULL,
858 "failed to allocate buffer.\n");
863 new->retry_counter = lcconf->retry_counter;
865 new->created = time(NULL);
867 LIST_INSERT_HEAD(&rcptree, new, chain);
877 racoon_free(r->remote);
879 racoon_free(r->local);
891 LIST_REMOVE(r, chain);
895 sweep_recvdpkt(dummy)
898 struct recvdpkt *r, *next;
901 /* set current time */
904 /* set the lifetime of the retransmission */
905 lt = lcconf->retry_counter * lcconf->retry_interval;
907 for (r = LIST_FIRST(&rcptree); r; r = next) {
908 next = LIST_NEXT(r, chain);
910 if (t - r->created > lt) {
916 sched_new(lt, sweep_recvdpkt, NULL);
922 time_t lt = lcconf->retry_counter * lcconf->retry_interval;
926 sched_new(lt, sweep_recvdpkt, NULL);
931 * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
932 * This should be in isakmp_cfg.c but ph1tree being private, it must be there
935 exclude_cfg_addr(addr)
936 const struct sockaddr *addr;
939 struct sockaddr_in *sin;
941 LIST_FOREACH(p, &ph1tree, chain) {
942 if ((p->mode_cfg != NULL) &&
943 (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
944 (addr->sa_family == AF_INET)) {
945 sin = (struct sockaddr_in *)addr;
946 if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)