1 /* $Id: remoteconf.c,v 1.26.2.5 2005/11/06 17:18:26 monas 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>
37 #include <sys/queue.h>
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
43 #ifndef HAVE_NETINET6_IPSEC
44 #include <netinet/ipsec.h>
46 #include <netinet6/ipsec.h>
62 #include "isakmp_var.h"
64 #include "ipsec_doi.h"
66 #include "remoteconf.h"
67 #include "localconf.h"
68 #include "grabmyaddr.h"
73 #include "algorithm.h"
74 #include "nattraversal.h"
78 static TAILQ_HEAD(_rmtree
, remoteconf
) rmtree
;
81 * Script hook names and script hook paths
83 char *script_names
[SCRIPT_MAX
+ 1] = { "phase1_up", "phase1_down" };
84 vchar_t
*script_paths
= NULL
;
88 * search remote configuration.
89 * don't use port number to search if its value is either IPSEC_PORT_ANY.
90 * If matching anonymous entry, then new entry is copied from anonymous entry.
91 * If no anonymous entry found, then return NULL.
93 * Other: remote configuration entry.
96 getrmconf_strict(remote
, allow_anon
)
97 struct sockaddr
*remote
;
100 struct remoteconf
*p
;
101 struct remoteconf
*anon
= NULL
;
103 char buf
[NI_MAXHOST
+ NI_MAXSERV
+ 10];
104 char addr
[NI_MAXHOST
], port
[NI_MAXSERV
];
110 * We never have ports set in our remote configurations, but when
111 * NAT-T is enabled, the kernel can have policies with ports and
112 * send us an acquire message for a destination that has a port set.
113 * If we do this port check here, we don't find the remote config.
115 * In an ideal world, we would be able to have remote conf with
116 * port, and the port could be a wildcard. That test could be used.
118 switch (remote
->sa_family
) {
120 if (((struct sockaddr_in
*)remote
)->sin_port
!= IPSEC_PORT_ANY
)
125 if (((struct sockaddr_in6
*)remote
)->sin6_port
!= IPSEC_PORT_ANY
)
133 plog(LLV_ERROR2
, LOCATION
, NULL
,
134 "invalid ip address family: %d\n", remote
->sa_family
);
137 #endif /* ENABLE_NATT */
139 if (remote
->sa_family
== AF_UNSPEC
)
140 snprintf (buf
, sizeof(buf
), "%s", "anonymous");
142 GETNAMEINFO(remote
, addr
, port
);
143 snprintf(buf
, sizeof(buf
), "%s%s%s%s", addr
,
145 withport
? port
: "",
146 withport
? "]" : "");
149 TAILQ_FOREACH(p
, &rmtree
, chain
) {
150 if ((remote
->sa_family
== AF_UNSPEC
151 && remote
->sa_family
== p
->remote
->sa_family
)
152 || (!withport
&& cmpsaddrwop(remote
, p
->remote
) == 0)
153 || (withport
&& cmpsaddrstrict(remote
, p
->remote
) == 0)) {
154 plog(LLV_DEBUG
, LOCATION
, NULL
,
155 "configuration found for %s.\n", buf
);
159 /* save the pointer to the anonymous configuration */
160 if (p
->remote
->sa_family
== AF_UNSPEC
)
164 if (allow_anon
&& anon
!= NULL
) {
165 plog(LLV_DEBUG
, LOCATION
, NULL
,
166 "anonymous configuration selected for %s.\n", buf
);
170 plog(LLV_DEBUG
, LOCATION
, NULL
,
171 "no remote configuration found.\n");
178 struct sockaddr
*remote
;
180 return getrmconf_strict(remote
, 1);
186 struct remoteconf
*new;
189 new = racoon_calloc(1, sizeof(*new));
193 new->proposal
= NULL
;
196 new->doitype
= IPSEC_DOI
;
197 new->sittype
= IPSECDOI_SIT_IDENTITY_ONLY
;
198 new->idvtype
= IDTYPE_UNDEFINED
;
199 new->idvl_p
= genlist_init();
200 new->nonce_size
= DEFAULT_NONCE_SIZE
;
201 new->passive
= FALSE
;
202 new->ike_frag
= FALSE
;
203 new->esp_frag
= IP_MAXPACKET
;
204 new->ini_contact
= TRUE
;
205 new->mode_cfg
= FALSE
;
206 new->pcheck_level
= PROP_CHECK_STRICT
;
207 new->verify_identifier
= FALSE
;
208 new->verify_cert
= TRUE
;
209 new->getcert_method
= ISAKMP_GETCERT_PAYLOAD
;
210 new->getcacert_method
= ISAKMP_GETCERT_LOCALFILE
;
211 new->cacerttype
= ISAKMP_CERT_X509SIGN
;
212 new->cacertfile
= NULL
;
213 new->send_cert
= TRUE
;
215 new->support_proxy
= FALSE
;
216 for (i
= 0; i
<= SCRIPT_MAX
; i
++)
218 new->gen_policy
= FALSE
;
219 new->retry_counter
= lcconf
->retry_counter
;
220 new->retry_interval
= lcconf
->retry_interval
;
222 new->nat_traversal
= NATT_ON
;
223 new->natt_multiple_user
= FALSE
;
225 new->nat_traversal
= NATT_OFF
;
227 new->rsa_private
= genlist_init();
228 new->rsa_public
= genlist_init();
232 new->dpd
= TRUE
; /* Enable DPD support by default */
233 new->dpd_interval
= 0; /* Disable DPD checks by default */
235 new->dpd_maxfails
= 5;
242 struct sockaddr
*remote
;
244 struct remoteconf
*new, *old
;
246 old
= getrmconf_strict (remote
, 0);
248 plog (LLV_ERROR
, LOCATION
, NULL
,
249 "Remote configuration for '%s' not found!\n",
254 new = duprmconf (old
);
265 struct idspec
*old
= (struct idspec
*) entry
;
267 if (!id
) return (void *) -1;
269 if (set_identifier(&id
->id
, old
->idtype
, old
->id
) != 0)
272 id
->idtype
= old
->idtype
;
274 genlist_append(arg
, id
);
280 struct remoteconf
*rmconf
;
282 struct remoteconf
*new;
284 new = racoon_calloc(1, sizeof(*new));
287 memcpy (new, rmconf
, sizeof (*new));
288 // FIXME: We should duplicate the proposal as well.
289 // This is now handled in the cfparse.y
290 // new->proposal = ...;
292 /* duplicate dynamic structures */
294 new->etypes
=dupetypes(new->etypes
);
295 new->idvl_p
= genlist_init();
296 genlist_foreach(rmconf
->idvl_p
, dupidvl
, new->idvl_p
);
302 idspec_free(void *data
)
304 vfree (((struct idspec
*)data
)->id
);
309 proposalspec_free(struct proposalspec
*head
)
312 struct proposalspec
* next_propsp
= head
;
314 while (next_propsp
) {
315 struct proposalspec
* curr_propsp
;
316 struct secprotospec
* next_protosp
;
318 curr_propsp
= next_propsp
;
319 next_propsp
= next_propsp
->next
;
320 next_protosp
= curr_propsp
->spspec
;
321 while (next_protosp
) {
322 struct secprotospec
* curr_protosp
;
324 curr_protosp
= next_protosp
;
325 next_protosp
= next_protosp
->next
;
327 if (curr_protosp
->gssid
)
328 free(curr_protosp
->gssid
);
329 if (curr_protosp
->remote
)
330 free(curr_protosp
->remote
);
331 racoon_free(curr_protosp
);
333 racoon_free(curr_propsp
);
339 struct remoteconf
*rmconf
;
342 racoon_free(rmconf
->remote
);
344 deletypes(rmconf
->etypes
);
348 genlist_free(rmconf
->idvl_p
, idspec_free
);
350 oakley_dhgrp_free(rmconf
->dhgrp
);
351 if (rmconf
->proposal
)
352 delisakmpsa(rmconf
->proposal
);
353 if (rmconf
->mycertfile
)
354 racoon_free(rmconf
->mycertfile
);
355 if (rmconf
->myprivfile
)
356 racoon_free(rmconf
->myprivfile
);
357 if (rmconf
->peerscertfile
)
358 racoon_free(rmconf
->peerscertfile
);
359 if (rmconf
->cacertfile
)
360 racoon_free(rmconf
->cacertfile
);
362 proposalspec_free(rmconf
->prhead
);
363 if (rmconf
->rsa_private
)
364 genlist_free(rmconf
->rsa_private
, rsa_key_free
);
365 if (rmconf
->rsa_public
)
366 genlist_free(rmconf
->rsa_public
, rsa_key_free
);
368 if (rmconf
->shared_secret
)
369 vfree(rmconf
->shared_secret
);
370 if (rmconf
->keychainCertRef
)
371 vfree(rmconf
->keychainCertRef
);
372 if (rmconf
->open_dir_auth_group
)
373 vfree(rmconf
->open_dir_auth_group
);
384 oakley_dhgrp_free(sa
->dhgrp
);
386 delisakmpsa(sa
->next
);
403 new = racoon_malloc(sizeof(struct etypes
));
407 new->type
= orig
->type
;
411 new->next
=dupetypes(orig
->next
);
426 * insert into head of list.
430 struct remoteconf
*new;
432 TAILQ_INSERT_HEAD(&rmtree
, new, chain
);
437 struct remoteconf
*rmconf
;
439 TAILQ_REMOVE(&rmtree
, rmconf
, chain
);
445 struct remoteconf
*p
, *next
;
447 for (p
= TAILQ_FIRST(&rmtree
); p
; p
= next
) {
448 next
= TAILQ_NEXT(p
, chain
);
460 /* check exchange type to be acceptable */
462 check_etypeok(rmconf
, etype
)
463 struct remoteconf
*rmconf
;
468 for (e
= rmconf
->etypes
; e
!= NULL
; e
= e
->next
) {
469 if (e
->type
== etype
)
480 struct isakmpsa
*new;
482 new = racoon_calloc(1, sizeof(*new));
487 * Just for sanity, make sure this is initialized. This is
488 * filled in for real when the ISAKMP proposal is configured.
490 new->vendorid
= VENDORID_UNKNOWN
;
502 * insert into tail of list.
505 insisakmpsa(new, rmconf
)
506 struct isakmpsa
*new;
507 struct remoteconf
*rmconf
;
511 new->rmconf
= rmconf
;
513 if (rmconf
->proposal
== NULL
) {
514 rmconf
->proposal
= new;
518 for (p
= rmconf
->proposal
; p
->next
!= NULL
; p
= p
->next
)
526 foreachrmconf(rmconf_func_t rmconf_func
, void *data
)
528 struct remoteconf
*p
, *ret
= NULL
;
530 TAILQ_FOREACH_REVERSE(p
, &rmtree
, _rmtree
, chain
) {
531 ret
= (*rmconf_func
)(p
, data
);
540 dump_peers_identifiers (void *entry
, void *arg
)
542 struct idspec
*id
= (struct idspec
*) entry
;
543 char buf
[1024], *pbuf
;
545 pbuf
+= snprintf (pbuf
, sizeof(buf
) - (pbuf
- buf
), "\tpeers_identifier %s",
546 s_idtype (id
->idtype
));
548 pbuf
+= snprintf (pbuf
, sizeof(buf
) - (pbuf
- buf
), " \"%s\"", id
->id
->v
);
549 plog(LLV_INFO
, LOCATION
, NULL
, "%s;\n", buf
);
553 static struct remoteconf
*
554 dump_rmconf_single (struct remoteconf
*p
, void *data
)
556 struct etypes
*etype
= p
->etypes
;
557 struct isakmpsa
*prop
= p
->proposal
;
558 char buf
[1024], *pbuf
;
561 pbuf
+= snprintf(pbuf
, sizeof(buf
) - (pbuf
- buf
), "remote %s", saddr2str(p
->remote
));
562 if (p
->inherited_from
)
563 pbuf
+= snprintf(pbuf
, sizeof(buf
) - (pbuf
- buf
), " inherit %s",
564 saddr2str(p
->inherited_from
->remote
));
565 plog(LLV_INFO
, LOCATION
, NULL
, "%s {\n", buf
);
567 pbuf
+= snprintf(pbuf
, sizeof(buf
) - (pbuf
- buf
), "\texchange_type ");
569 pbuf
+= snprintf (pbuf
, sizeof(buf
) - (pbuf
- buf
), "%s%s", s_etype(etype
->type
),
570 etype
->next
!= NULL
? ", " : ";\n");
573 plog(LLV_INFO
, LOCATION
, NULL
, "%s", buf
);
574 plog(LLV_INFO
, LOCATION
, NULL
, "\tdoi %s;\n", s_doi(p
->doitype
));
576 pbuf
+= snprintf(pbuf
, sizeof(buf
) - (pbuf
- buf
), "\tmy_identifier %s", s_idtype (p
->idvtype
));
577 if (p
->idvtype
== IDTYPE_ASN1DN
) {
578 plog(LLV_INFO
, LOCATION
, NULL
, "%s;\n", buf
);
579 plog(LLV_INFO
, LOCATION
, NULL
, "\tcertificate_type %s \"%s\" \"%s\";\n",
580 p
->certtype
== ISAKMP_CERT_X509SIGN
? "x509" : "*UNKNOWN*",
581 p
->mycertfile
, p
->myprivfile
);
582 switch (p
->getcert_method
) {
585 case ISAKMP_GETCERT_PAYLOAD
:
586 plog(LLV_INFO
, LOCATION
, NULL
, "\t/* peers certificate from payload */\n");
588 case ISAKMP_GETCERT_LOCALFILE
:
589 plog(LLV_INFO
, LOCATION
, NULL
, "\tpeers_certfile \"%s\";\n", p
->peerscertfile
);
591 case ISAKMP_GETCERT_DNS
:
592 plog(LLV_INFO
, LOCATION
, NULL
, "\tpeer_certfile dnssec;\n");
595 plog(LLV_INFO
, LOCATION
, NULL
, "\tpeers_certfile *UNKNOWN* (%d)\n", p
->getcert_method
);
600 pbuf
+= snprintf (pbuf
, sizeof(buf
) - (pbuf
- buf
), " \"%s\"", p
->idv
->v
);
601 plog(LLV_INFO
, LOCATION
, NULL
, "%s;\n", buf
);
602 genlist_foreach(p
->idvl_p
, &dump_peers_identifiers
, NULL
);
605 plog(LLV_INFO
, LOCATION
, NULL
, "\tsend_cert %s;\n",
606 s_switch (p
->send_cert
));
607 plog(LLV_INFO
, LOCATION
, NULL
, "\tsend_cr %s;\n",
608 s_switch (p
->send_cr
));
609 plog(LLV_INFO
, LOCATION
, NULL
, "\tverify_cert %s;\n",
610 s_switch (p
->verify_cert
));
611 plog(LLV_INFO
, LOCATION
, NULL
, "\tverify_identifier %s;\n",
612 s_switch (p
->verify_identifier
));
613 plog(LLV_INFO
, LOCATION
, NULL
, "\tnat_traversal %s;\n",
614 p
->nat_traversal
== NATT_FORCE
?
615 "force" : s_switch (p
->nat_traversal
));
617 plog(LLV_INFO
, LOCATION
, NULL
, "\tnatt_multiple_user %s;\n",
618 s_switch (p
->natt_multiple_user
));
620 plog(LLV_INFO
, LOCATION
, NULL
, "\tnonce_size %d;\n",
622 plog(LLV_INFO
, LOCATION
, NULL
, "\tpassive %s;\n",
623 s_switch (p
->passive
));
624 plog(LLV_INFO
, LOCATION
, NULL
, "\tike_frag %s;\n",
625 s_switch (p
->ike_frag
));
626 plog(LLV_INFO
, LOCATION
, NULL
, "\tesp_frag %d;\n", p
->esp_frag
);
627 plog(LLV_INFO
, LOCATION
, NULL
, "\tinitial_contact %s;\n",
628 s_switch (p
->ini_contact
));
629 plog(LLV_INFO
, LOCATION
, NULL
, "\tgenerate_policy %s;\n",
630 s_switch (p
->gen_policy
));
631 plog(LLV_INFO
, LOCATION
, NULL
, "\tsupport_proxy %s;\n",
632 s_switch (p
->support_proxy
));
635 plog(LLV_INFO
, LOCATION
, NULL
, "\n");
636 plog(LLV_INFO
, LOCATION
, NULL
,
637 "\t/* prop_no=%d, trns_no=%d, rmconf=%s */\n",
638 prop
->prop_no
, prop
->trns_no
,
639 saddr2str(prop
->rmconf
->remote
));
640 plog(LLV_INFO
, LOCATION
, NULL
, "\tproposal {\n");
641 plog(LLV_INFO
, LOCATION
, NULL
, "\t\tlifetime time %lu sec;\n",
642 (long)prop
->lifetime
);
643 plog(LLV_INFO
, LOCATION
, NULL
, "\t\tlifetime bytes %zd;\n",
645 plog(LLV_INFO
, LOCATION
, NULL
, "\t\tdh_group %s;\n",
646 alg_oakley_dhdef_name(prop
->dh_group
));
647 plog(LLV_INFO
, LOCATION
, NULL
, "\t\tencryption_algorithm %s;\n",
648 alg_oakley_encdef_name(prop
->enctype
));
649 plog(LLV_INFO
, LOCATION
, NULL
, "\t\thash_algorithm %s;\n",
650 alg_oakley_hashdef_name(prop
->hashtype
));
651 plog(LLV_INFO
, LOCATION
, NULL
, "\t\tauthentication_method %s;\n",
652 alg_oakley_authdef_name(prop
->authmethod
));
653 plog(LLV_INFO
, LOCATION
, NULL
, "\t}\n");
656 plog(LLV_INFO
, LOCATION
, NULL
, "}\n");
657 plog(LLV_INFO
, LOCATION
, NULL
, "\n");
665 foreachrmconf (dump_rmconf_single
, NULL
);
673 new = racoon_calloc(1, sizeof(*new));
676 new->idtype
= IDTYPE_ADDRESS
;
682 script_path_add(path
)
686 vchar_t
*new_storage
;
692 script_dir
= lcconf
->pathinfo
[LC_PATHTYPE_SCRIPT
];
694 /* Try to find the script in the script directory */
695 if ((path
->v
[0] != '/') && (script_dir
!= NULL
)) {
696 len
= strlen(script_dir
) + sizeof("/") + path
->l
+ 1;
698 if ((new_path
= vmalloc(len
)) == NULL
) {
699 plog(LLV_ERROR
, LOCATION
, NULL
,
700 "Cannot allocate memory: %s\n", strerror(errno
));
704 new_path
->v
[0] = '\0';
705 (void)strlcat(new_path
->v
, script_dir
, len
);
706 (void)strlcat(new_path
->v
, "/", len
);
707 (void)strlcat(new_path
->v
, path
->v
, len
);
713 /* First time, initialize */
714 if (script_paths
== NULL
)
715 len
= sizeof(vchar_t
*);
717 len
= script_paths
->l
;
719 /* Add a slot for a new path */
720 len
+= sizeof(vchar_t
*);
721 if ((new_storage
= vrealloc(script_paths
, len
)) == NULL
) {
722 plog(LLV_ERROR
, LOCATION
, NULL
,
723 "Cannot allocate memory: %s\n", strerror(errno
));
726 script_paths
= new_storage
;
728 size
= len
/ sizeof(vchar_t
*);
729 sp
= (vchar_t
**)script_paths
->v
;
740 struct isakmpsa
*res
= NULL
;
757 if (sa
->dhgrp
!= NULL
)
758 oakley_setdhgroup(sa
->dh_group
, &(res
->dhgrp
));
765 rsa_key_free(void *entry
)
767 struct rsa_key
*key
= (struct rsa_key
*)entry
;