]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/remoteconf.c
0a0d27758ed026af6ea42bbab9fe60b7918e0230
[apple/ipsec.git] / ipsec-tools / racoon / remoteconf.c
1 /* $NetBSD: remoteconf.c,v 1.9.4.1 2007/08/01 11:52:22 vanhu Exp $ */
2
3 /* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 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 #include <sys/queue.h>
40
41 #include <netinet/in.h>
42 #include <netinet/in_systm.h>
43 #include <netinet/ip.h>
44
45 #ifndef HAVE_NETINET6_IPSEC
46 #include <netinet/ipsec.h>
47 #else
48 #include <netinet6/ipsec.h>
49 #endif
50
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <errno.h>
55
56 #include "var.h"
57 #include "misc.h"
58 #include "vmbuf.h"
59 #include "plog.h"
60 #include "sockmisc.h"
61 #include "genlist.h"
62 #include "debug.h"
63
64 #include "isakmp_var.h"
65 #ifdef ENABLE_HYBRID
66 #include "isakmp_xauth.h"
67 #endif
68 #include "isakmp.h"
69 #include "ipsec_doi.h"
70 #include "oakley.h"
71 #include "remoteconf.h"
72 #include "localconf.h"
73 #include "grabmyaddr.h"
74 #include "policy.h"
75 #include "proposal.h"
76 #include "vendorid.h"
77 #include "gcmalloc.h"
78 #include "strnames.h"
79 #include "algorithm.h"
80 #include "nattraversal.h"
81 #include "isakmp_frag.h"
82 #include "genlist.h"
83
84 static TAILQ_HEAD(_rmtree, remoteconf) rmtree;
85
86 /*
87 * Script hook names and script hook paths
88 */
89 char *script_names[SCRIPT_MAX + 1] = { "phase1_up", "phase1_down" };
90
91 /*%%%*/
92 /*
93 * search remote configuration.
94 * don't use port number to search if its value is either IPSEC_PORT_ANY.
95 * If matching anonymous entry, then new entry is copied from anonymous entry.
96 * If no anonymous entry found, then return NULL.
97 * OUT: NULL: NG
98 * Other: remote configuration entry.
99 */
100 struct remoteconf *
101 getrmconf_strict(remote, allow_anon)
102 struct sockaddr_storage *remote;
103 int allow_anon;
104 {
105 struct remoteconf *p;
106 struct remoteconf *p_withport_besteffort = NULL;
107 struct remoteconf *p_with_prefix = NULL;
108 struct remoteconf *p_with_prefix_besteffort = NULL;
109 int last_prefix = 0;
110 struct remoteconf *anon = NULL;
111
112 int withport;
113 char buf[NI_MAXHOST + NI_MAXSERV + 10];
114 char addr[NI_MAXHOST], port[NI_MAXSERV];
115
116 withport = 0;
117
118 /*
119 * We never have ports set in our remote configurations, but when
120 * NAT-T is enabled, the kernel can have policies with ports and
121 * send us an acquire message for a destination that has a port set.
122 * If we do this port check here, we have to fallback to a best-effort result (without the port).
123 *
124 * In an ideal world, we would be able to have remote conf with
125 * port, and the port could be a wildcard. That test could be used.
126 */
127 switch (remote->ss_family) {
128 case AF_INET:
129 if (((struct sockaddr_in *)remote)->sin_port != IPSEC_PORT_ANY)
130 withport = 1;
131 break;
132 #ifdef INET6
133 case AF_INET6:
134 if (((struct sockaddr_in6 *)remote)->sin6_port != IPSEC_PORT_ANY)
135 withport = 1;
136 break;
137 #endif
138 case AF_UNSPEC:
139 break;
140
141 default:
142 plog(LLV_ERROR2, LOCATION, NULL,
143 "invalid ip address family: %d\n", remote->ss_family);
144 return NULL;
145 }
146
147 if (remote->ss_family == AF_UNSPEC)
148 snprintf (buf, sizeof(buf), "%s", "anonymous");
149 else {
150 GETNAMEINFO((struct sockaddr *)remote, addr, port);
151 snprintf(buf, sizeof(buf), "%s%s%s%s", addr,
152 withport ? "[" : "",
153 withport ? port : "",
154 withport ? "]" : "");
155 }
156
157 TAILQ_FOREACH(p, &rmtree, chain) {
158 if (p->to_delete || p->to_remove) {
159 continue;
160 }
161
162 if (remote->ss_family == AF_UNSPEC
163 && remote->ss_family == p->remote->ss_family) {
164 plog(LLV_DEBUG, LOCATION, NULL,
165 "configuration found for %s.\n", buf);
166 return p;
167 }
168 if (p->remote_prefix == 0) {
169 if ((!withport && cmpsaddrwop(remote, p->remote) == 0)
170 || (withport && cmpsaddrstrict(remote, p->remote) == 0)) {
171 plog(LLV_DEBUG, LOCATION, NULL,
172 "configuration found for %s.\n", buf);
173 return p;
174 } else if (withport && cmpsaddrwop(remote, p->remote) == 0) {
175 // for withport: save the pointer for the best-effort search
176 p_withport_besteffort = p;
177 }
178 } else {
179 if ((!withport && cmpsaddrwop_withprefix(remote, p->remote, p->remote_prefix) == 0)
180 || (withport && cmpsaddrstrict_withprefix(remote, p->remote, p->remote_prefix) == 0)) {
181 if (p->remote_prefix >= last_prefix) {
182 p_with_prefix = p;
183 last_prefix = p->remote_prefix;
184 }
185 } else if (withport && cmpsaddrwop_withprefix(remote, p->remote, p->remote_prefix) == 0) {
186 if (p->remote_prefix >= last_prefix) {
187 p_with_prefix_besteffort = p;
188 last_prefix = p->remote_prefix;
189 }
190 }
191 }
192
193 /* save the pointer to the anonymous configuration */
194 if (p->remote->ss_family == AF_UNSPEC)
195 anon = p;
196 }
197
198 if (p_withport_besteffort) {
199 plog(LLV_DEBUG, LOCATION, NULL,
200 "configuration found for %s.\n", buf);
201 return p_withport_besteffort;
202 }
203 if (p_with_prefix) {
204 plog(LLV_DEBUG, LOCATION, NULL,
205 "configuration found for %s.\n", buf);
206 return p_with_prefix;
207 }
208 if (p_with_prefix_besteffort) {
209 plog(LLV_DEBUG, LOCATION, NULL,
210 "configuration found for %s.\n", buf);
211 return p_with_prefix_besteffort;
212 }
213 if (allow_anon && anon != NULL) {
214 plog(LLV_DEBUG, LOCATION, NULL,
215 "anonymous configuration selected for %s.\n", buf);
216 return anon;
217 }
218
219 plog(LLV_DEBUG, LOCATION, NULL,
220 "no remote configuration found.\n");
221
222 return NULL;
223 }
224
225 int
226 no_remote_configs(ignore_anonymous)
227 int ignore_anonymous;
228 {
229
230 struct remoteconf *p;
231 #if !TARGET_OS_EMBEDDED
232 static const char default_idv[] = "macuser@localhost";
233 static const int default_idv_len = sizeof(default_idv) - 1;
234 #endif
235
236 TAILQ_FOREACH(p, &rmtree, chain) {
237 if (ignore_anonymous) {
238 if (p->remote->ss_family == AF_UNSPEC) /* anonymous */
239 continue;
240 }
241 #if !TARGET_OS_EMBEDDED
242 // ignore the default btmm ipv6 config thats always present in racoon.conf
243 if (p->remote->ss_family == AF_INET6 &&
244 p->idvtype == IDTYPE_USERFQDN &&
245 p->idv != NULL &&
246 p->idv->l == default_idv_len &&
247 strncmp(p->idv->v, default_idv, p->idv->l) == 0) {
248 continue;
249 }
250 #endif
251 return 0;
252 }
253 return 1;
254 }
255
256 struct remoteconf *
257 getrmconf(remote)
258 struct sockaddr_storage *remote;
259 {
260 return getrmconf_strict(remote, 1);
261 }
262
263 int
264 link_rmconf_to_ph1 (struct remoteconf *new)
265 {
266 if (!new) {
267 return(-1);
268 }
269 if (new->to_delete ||
270 new->to_remove) {
271 return(-1);
272 }
273 new->linked_to_ph1++;
274 return(0);
275 }
276
277 int
278 unlink_rmconf_from_ph1 (struct remoteconf *old)
279 {
280 if (!old) {
281 return(-1);
282 }
283 if (old->linked_to_ph1 <= 0) {
284 return(-1);
285 }
286 old->linked_to_ph1--;
287 if (old->linked_to_ph1 == 0) {
288 if (old->to_remove) {
289 remrmconf(old);
290 }
291 if (old->to_delete) {
292 delrmconf(old);
293 }
294 }
295 return(0);
296 }
297
298 struct remoteconf *
299 newrmconf()
300 {
301 struct remoteconf *new;
302 int i;
303
304 new = racoon_calloc(1, sizeof(*new));
305 if (new == NULL)
306 return NULL;
307
308 new->proposal = NULL;
309
310 /* set default */
311 new->doitype = IPSEC_DOI;
312 new->sittype = IPSECDOI_SIT_IDENTITY_ONLY;
313 new->idvtype = IDTYPE_UNDEFINED;
314 new->idvl_p = genlist_init();
315 new->nonce_size = DEFAULT_NONCE_SIZE;
316 new->passive = FALSE;
317 new->ike_frag = ISAKMP_FRAG_FORCE;
318 new->esp_frag = IP_MAXPACKET;
319 new->ini_contact = TRUE;
320 new->mode_cfg = FALSE;
321 new->pcheck_level = PROP_CHECK_STRICT;
322 new->verify_identifier = FALSE;
323 new->verify_cert = TRUE;
324 new->getcert_method = ISAKMP_GETCERT_PAYLOAD;
325 new->getcacert_method = ISAKMP_GETCERT_LOCALFILE;
326 new->cacerttype = ISAKMP_CERT_X509SIGN;
327 new->certtype = ISAKMP_CERT_NONE;
328 new->cacertfile = NULL;
329 new->send_cert = TRUE;
330 new->send_cr = TRUE;
331 new->support_proxy = FALSE;
332 for (i = 0; i <= SCRIPT_MAX; i++)
333 new->script[i] = NULL;
334 new->gen_policy = FALSE;
335 new->retry_counter = lcconf->retry_counter;
336 new->retry_interval = lcconf->retry_interval;
337 new->nat_traversal = NATT_ON;
338 new->natt_multiple_user = FALSE;
339 new->natt_keepalive = TRUE;
340 new->to_remove = FALSE;
341 new->to_delete = FALSE;
342 new->linked_to_ph1 = 0;
343 new->idv = NULL;
344 new->key = NULL;
345
346 new->dpd = TRUE; /* Enable DPD support by default */
347 new->dpd_interval = 0; /* Disable DPD checks by default */
348 new->dpd_retry = 5;
349 new->dpd_maxfails = 5;
350 new->dpd_algo = DPD_ALGO_INBOUND_DETECT;
351 new->idle_timeout = 0;
352
353 new->weak_phase1_check = 0;
354
355 #ifdef ENABLE_HYBRID
356 new->xauth = NULL;
357 #endif
358 new->initiate_ph1rekey = TRUE;
359 return new;
360 }
361
362 struct remoteconf *
363 copyrmconf(remote)
364 struct sockaddr_storage *remote;
365 {
366 struct remoteconf *new, *old;
367
368 old = getrmconf_strict (remote, 0);
369 if (old == NULL) {
370 plog (LLV_ERROR, LOCATION, NULL,
371 "Remote configuration for '%s' not found!\n",
372 saddr2str((struct sockaddr *)remote));
373 return NULL;
374 }
375
376 new = duprmconf (old);
377
378 return new;
379 }
380
381 void *
382 dupidvl(entry, arg)
383 void *entry;
384 void *arg;
385 {
386 struct idspec *id;
387 struct idspec *old = (struct idspec *) entry;
388 id = newidspec();
389 if (!id) return (void *) -1;
390
391 if (set_identifier(&id->id, old->idtype, old->id) != 0) {
392 racoon_free(id);
393 return (void *) -1;
394 }
395
396 id->idtype = old->idtype;
397
398 genlist_append(arg, id);
399 return NULL;
400 }
401
402 struct remoteconf *
403 duprmconf (rmconf)
404 struct remoteconf *rmconf;
405 {
406 struct remoteconf *new;
407 int i;
408
409 new = racoon_calloc(1, sizeof(*new));
410 if (new == NULL)
411 return NULL;
412 memcpy (new, rmconf, sizeof (*new));
413 // FIXME: We should duplicate remote, proposal, etc.
414 // This is now handled in the cfparse.y
415 // new->proposal = ...;
416
417 // zero-out pointers
418 new->remote = NULL;
419 new->keychainCertRef = NULL; /* peristant keychain ref for cert */
420 new->shared_secret = NULL; /* shared secret */
421 new->open_dir_auth_group = NULL; /* group to be used to authorize user */
422 new->proposal = NULL;
423 new->cacertfile = NULL;
424 for (i = 0; i <= SCRIPT_MAX; i++)
425 new->script[i] = NULL;
426 new->to_remove = FALSE;
427 new->to_delete = FALSE;
428 new->linked_to_ph1 = 0;
429 new->idv = NULL;
430 new->key = NULL;
431 #ifdef ENABLE_HYBRID
432 new->xauth = NULL;
433 #endif
434
435 /* duplicate dynamic structures */
436 if (new->etypes)
437 new->etypes=dupetypes(new->etypes);
438 new->idvl_p = genlist_init();
439 genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
440
441 return new;
442 }
443
444 static void
445 idspec_free(void *data)
446 {
447 vfree (((struct idspec *)data)->id);
448 free (data);
449 }
450
451 static void
452 proposalspec_free(struct proposalspec *head)
453 {
454
455 struct proposalspec* next_propsp = head;
456
457 while (next_propsp) {
458 struct proposalspec* curr_propsp;
459 struct secprotospec* next_protosp;
460
461 curr_propsp = next_propsp;
462 next_propsp = next_propsp->next;
463 next_protosp = curr_propsp->spspec;
464 while (next_protosp) {
465 struct secprotospec* curr_protosp;
466
467 curr_protosp = next_protosp;
468 next_protosp = next_protosp->next;
469
470 if (curr_protosp->gssid)
471 free(curr_protosp->gssid);
472 if (curr_protosp->remote)
473 free(curr_protosp->remote);
474 racoon_free(curr_protosp);
475 }
476 racoon_free(curr_propsp);
477 }
478 }
479
480 void
481 delrmconf(rmconf)
482 struct remoteconf *rmconf;
483 {
484 if (rmconf->linked_to_ph1) {
485 rmconf->to_delete = TRUE;
486 return;
487 }
488 if (rmconf->remote)
489 racoon_free(rmconf->remote);
490 #ifdef ENABLE_HYBRID
491 if (rmconf->xauth)
492 xauth_rmconf_delete(&rmconf->xauth);
493 #endif
494 if (rmconf->etypes) {
495 deletypes(rmconf->etypes);
496 rmconf->etypes=NULL;
497 }
498 if (rmconf->idv)
499 vfree(rmconf->idv);
500 if (rmconf->idvl_p)
501 genlist_free(rmconf->idvl_p, idspec_free);
502 if (rmconf->dhgrp)
503 oakley_dhgrp_free(rmconf->dhgrp);
504 if (rmconf->proposal)
505 delisakmpsa(rmconf->proposal);
506 if (rmconf->mycertfile)
507 racoon_free(rmconf->mycertfile);
508 if (rmconf->myprivfile)
509 racoon_free(rmconf->myprivfile);
510 if (rmconf->peerscertfile)
511 racoon_free(rmconf->peerscertfile);
512 if (rmconf->cacertfile)
513 racoon_free(rmconf->cacertfile);
514 if (rmconf->prhead)
515 proposalspec_free(rmconf->prhead);
516 if (rmconf->shared_secret)
517 vfree(rmconf->shared_secret);
518 if (rmconf->keychainCertRef)
519 vfree(rmconf->keychainCertRef);
520 if (rmconf->open_dir_auth_group)
521 vfree(rmconf->open_dir_auth_group);
522
523 racoon_free(rmconf);
524 }
525
526 void
527 delisakmpsa(sa)
528 struct isakmpsa *sa;
529 {
530 if (sa->dhgrp)
531 oakley_dhgrp_free(sa->dhgrp);
532 if (sa->next)
533 delisakmpsa(sa->next);
534 #ifdef HAVE_GSSAPI
535 if (sa->gssid)
536 vfree(sa->gssid);
537 #endif
538 racoon_free(sa);
539 }
540
541 struct etypes *
542 dupetypes(orig)
543 struct etypes *orig;
544 {
545 struct etypes *new;
546
547 if (!orig)
548 return NULL;
549
550 new = racoon_malloc(sizeof(struct etypes));
551 if (new == NULL)
552 return NULL;
553
554 new->type = orig->type;
555 new->next = NULL;
556
557 if (orig->next)
558 new->next=dupetypes(orig->next);
559
560 return new;
561 }
562
563 void
564 deletypes(e)
565 struct etypes *e;
566 {
567 if (e->next)
568 deletypes(e->next);
569 racoon_free(e);
570 }
571
572 /*
573 * insert into head of list.
574 */
575 void
576 insrmconf(new)
577 struct remoteconf *new;
578 {
579 TAILQ_INSERT_HEAD(&rmtree, new, chain);
580 }
581
582 void
583 remrmconf(rmconf)
584 struct remoteconf *rmconf;
585 {
586 if (rmconf->linked_to_ph1) {
587 rmconf->to_remove = TRUE;
588 return;
589 }
590 TAILQ_REMOVE(&rmtree, rmconf, chain);
591 }
592
593 void
594 flushrmconf()
595 {
596 struct remoteconf *p, *next;
597
598 for (p = TAILQ_FIRST(&rmtree); p; p = next) {
599 next = TAILQ_NEXT(p, chain);
600 remrmconf(p);
601 delrmconf(p);
602 }
603 }
604
605 void
606 initrmconf()
607 {
608 TAILQ_INIT(&rmtree);
609 }
610
611 /* check exchange type to be acceptable */
612 struct etypes *
613 check_etypeok(rmconf, etype)
614 struct remoteconf *rmconf;
615 u_int8_t etype;
616 {
617 struct etypes *e;
618
619 for (e = rmconf->etypes; e != NULL; e = e->next) {
620 if (e->type == etype)
621 break;
622 }
623
624 return e;
625 }
626
627 /*%%%*/
628 struct isakmpsa *
629 newisakmpsa()
630 {
631 struct isakmpsa *new;
632
633 new = racoon_calloc(1, sizeof(*new));
634 if (new == NULL)
635 return NULL;
636
637 /*
638 * Just for sanity, make sure this is initialized. This is
639 * filled in for real when the ISAKMP proposal is configured.
640 */
641 new->vendorid = VENDORID_UNKNOWN;
642
643 new->next = NULL;
644 new->rmconf = NULL;
645 #ifdef HAVE_GSSAPI
646 new->gssid = NULL;
647 #endif
648
649 return new;
650 }
651
652 /*
653 * insert into tail of list.
654 */
655 void
656 insisakmpsa(new, rmconf)
657 struct isakmpsa *new;
658 struct remoteconf *rmconf;
659 {
660 struct isakmpsa *p;
661
662 new->rmconf = rmconf;
663
664 if (rmconf->proposal == NULL) {
665 rmconf->proposal = new;
666 return;
667 }
668
669 for (p = rmconf->proposal; p->next != NULL; p = p->next)
670 ;
671 p->next = new;
672
673 return;
674 }
675
676 struct remoteconf *
677 foreachrmconf(rmconf_func_t rmconf_func, void *data)
678 {
679 struct remoteconf *p, *ret = NULL;
680
681 TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
682 ret = (*rmconf_func)(p, data);
683 if (ret)
684 break;
685 }
686
687 return ret;
688 }
689
690 static void *
691 dump_peers_identifiers (void *entry, void *arg)
692 {
693 struct idspec *id = (struct idspec*) entry;
694 char buf[1024], *pbuf;
695 pbuf = buf;
696 pbuf += snprintf (pbuf, sizeof(buf) - (pbuf - buf), "\tpeers_identifier %s",
697 s_idtype (id->idtype));
698 if (id->id)
699 pbuf += snprintf (pbuf, sizeof(buf) - (pbuf - buf), " \"%s\"", id->id->v);
700 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
701 return NULL;
702 }
703
704 static struct remoteconf *
705 dump_rmconf_single (struct remoteconf *p, void *data)
706 {
707 struct etypes *etype = p->etypes;
708 struct isakmpsa *prop = p->proposal;
709 char buf[1024], *pbuf;
710
711 pbuf = buf;
712 if (p->remote_prefix)
713 pbuf += snprintf(pbuf, sizeof(buf) - (pbuf - buf), "remote %s",
714 saddr2str_with_prefix((struct sockaddr *)p->remote, p->remote_prefix));
715 else
716 pbuf += snprintf(pbuf, sizeof(buf) - (pbuf - buf), "remote %s", saddr2str((struct sockaddr *)p->remote));
717 if (p->inherited_from)
718 pbuf += snprintf(pbuf, sizeof(buf) - (pbuf - buf), " inherit %s",
719 saddr2str((struct sockaddr *)p->inherited_from->remote));
720 plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf);
721 pbuf = buf;
722 pbuf += snprintf(pbuf, sizeof(buf) - (pbuf - buf), "\texchange_type ");
723 while (etype) {
724 pbuf += snprintf (pbuf, sizeof(buf) - (pbuf - buf), "%s%s", s_etype(etype->type),
725 etype->next != NULL ? ", " : ";\n");
726 etype = etype->next;
727 }
728 plog(LLV_INFO, LOCATION, NULL, "%s", buf);
729 plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype));
730 pbuf = buf;
731 pbuf += snprintf(pbuf, sizeof(buf) - (pbuf - buf), "\tmy_identifier %s", s_idtype (p->idvtype));
732 if (p->idvtype == IDTYPE_ASN1DN) {
733 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
734 plog(LLV_INFO, LOCATION, NULL, "\tcertificate_type %s \"%s\" \"%s\";\n",
735 p->certtype == ISAKMP_CERT_X509SIGN ? "x509" : "*UNKNOWN*",
736 p->mycertfile, p->myprivfile);
737 switch (p->getcert_method) {
738 case 0:
739 break;
740 case ISAKMP_GETCERT_PAYLOAD:
741 plog(LLV_INFO, LOCATION, NULL, "\t/* peers certificate from payload */\n");
742 break;
743 case ISAKMP_GETCERT_LOCALFILE:
744 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile \"%s\";\n", p->peerscertfile);
745 break;
746 case ISAKMP_GETCERT_DNS:
747 plog(LLV_INFO, LOCATION, NULL, "\tpeer_certfile dnssec;\n");
748 break;
749 default:
750 plog(LLV_INFO, LOCATION, NULL, "\tpeers_certfile *UNKNOWN* (%d)\n", p->getcert_method);
751 }
752 }
753 else {
754 if (p->idv)
755 pbuf += snprintf (pbuf, sizeof(buf) - (pbuf - buf), " \"%s\"", p->idv->v);
756 plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
757 genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL);
758 }
759
760 plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n",
761 s_switch (p->send_cert));
762 plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n",
763 s_switch (p->send_cr));
764 plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n",
765 s_switch (p->verify_cert));
766 plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n",
767 s_switch (p->verify_identifier));
768 plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n",
769 p->nat_traversal == NATT_FORCE ?
770 "force" : s_switch (p->nat_traversal));
771 plog(LLV_INFO, LOCATION, NULL, "\tnatt_multiple_user %s;\n",
772 s_switch (p->natt_multiple_user));
773 plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n",
774 p->nonce_size);
775 plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n",
776 s_switch (p->passive));
777 plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n",
778 p->ike_frag == ISAKMP_FRAG_FORCE ?
779 "force" : s_switch (p->ike_frag));
780 plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag);
781 plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n",
782 s_switch (p->ini_contact));
783 plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n",
784 s_switch (p->gen_policy));
785 plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n",
786 s_switch (p->support_proxy));
787
788 while (prop) {
789 plog(LLV_INFO, LOCATION, NULL, "\n");
790 plog(LLV_INFO, LOCATION, NULL,
791 "\t/* prop_no=%d, trns_no=%d, rmconf=%s */\n",
792 prop->prop_no, prop->trns_no,
793 saddr2str((struct sockaddr *)prop->rmconf->remote));
794 plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n");
795 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n",
796 (long)prop->lifetime);
797 plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n",
798 prop->lifebyte);
799 plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n",
800 alg_oakley_dhdef_name(prop->dh_group));
801 plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n",
802 alg_oakley_encdef_name(prop->enctype));
803 plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n",
804 alg_oakley_hashdef_name(prop->hashtype));
805 plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n",
806 alg_oakley_authdef_name(prop->authmethod));
807 plog(LLV_INFO, LOCATION, NULL, "\t}\n");
808 prop = prop->next;
809 }
810 plog(LLV_INFO, LOCATION, NULL, "}\n");
811 plog(LLV_INFO, LOCATION, NULL, "\n");
812
813 return NULL;
814 }
815
816 void
817 dumprmconf()
818 {
819 foreachrmconf (dump_rmconf_single, NULL);
820 }
821
822 struct idspec *
823 newidspec()
824 {
825 struct idspec *new;
826
827 new = racoon_calloc(1, sizeof(*new));
828 if (new == NULL)
829 return NULL;
830 new->idtype = IDTYPE_ADDRESS;
831
832 return new;
833 }
834
835 vchar_t *
836 script_path_add(path)
837 vchar_t *path;
838 {
839 char *script_dir;
840 vchar_t *new_path;
841 size_t len;
842
843 script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT];
844
845 /* Try to find the script in the script directory */
846 if ((path->v[0] != '/') && (script_dir != NULL)) {
847 len = strlen(script_dir) + sizeof("/") + path->l + 1;
848
849 if ((new_path = vmalloc(len)) == NULL) {
850 plog(LLV_ERROR, LOCATION, NULL,
851 "Cannot allocate memory: %s\n", strerror(errno));
852 return NULL;
853 }
854
855 new_path->v[0] = '\0';
856 (void)strlcat(new_path->v, script_dir, new_path->l);
857 (void)strlcat(new_path->v, "/", new_path->l);
858 (void)strlcat(new_path->v, path->v, new_path->l);
859
860 vfree(path);
861 path = new_path;
862 }
863
864 return path;
865 }
866
867
868 struct isakmpsa *
869 dupisakmpsa(struct isakmpsa *sa)
870 {
871 struct isakmpsa *res = NULL;
872
873 if (sa == NULL)
874 return NULL;
875
876 res = newisakmpsa();
877 if(res == NULL)
878 return NULL;
879
880 *res = *sa;
881 #ifdef HAVE_GSSAPI
882 res->gssid=vdup(sa->gssid);
883 #endif
884 res->next=NULL;
885
886 if (sa->dhgrp != NULL)
887 oakley_setdhgroup(sa->dh_group, &(res->dhgrp));
888
889 return res;
890
891 }
892