1 /*	$NetBSD: remoteconf.c,v 1.30 2018/05/19 20:14:56 maxv 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 #include PATH_IPSEC_H
46 
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <errno.h>
51 
52 #include "var.h"
53 #include "misc.h"
54 #include "vmbuf.h"
55 #include "plog.h"
56 #include "sockmisc.h"
57 #include "genlist.h"
58 #include "debug.h"
59 
60 #include "isakmp_var.h"
61 #ifdef ENABLE_HYBRID
62 #include "isakmp_xauth.h"
63 #endif
64 #include "isakmp.h"
65 #include "ipsec_doi.h"
66 #include "crypto_openssl.h"
67 #include "oakley.h"
68 #include "remoteconf.h"
69 #include "localconf.h"
70 #include "grabmyaddr.h"
71 #include "policy.h"
72 #include "proposal.h"
73 #include "vendorid.h"
74 #include "gcmalloc.h"
75 #include "strnames.h"
76 #include "algorithm.h"
77 #include "nattraversal.h"
78 #include "isakmp_frag.h"
79 #include "handler.h"
80 #include "genlist.h"
81 #include "rsalist.h"
82 
83 typedef TAILQ_HEAD(_rmtree, remoteconf) remoteconf_tailq_head_t;
84 static remoteconf_tailq_head_t rmtree, rmtree_save;
85 
86 /*
87  * Script hook names and script hook paths
88  */
89 char *script_names[SCRIPT_MAX + 1] = {
90 	"phase1_up", "phase1_down", "phase1_dead" };
91 
92 /*%%%*/
93 
94 int
rmconf_match_identity(rmconf,id_p)95 rmconf_match_identity(rmconf, id_p)
96 	struct remoteconf *rmconf;
97 	vchar_t *id_p;
98 {
99 	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id_p->v;
100 	struct sockaddr *sa;
101 	caddr_t sa1, sa2;
102 	vchar_t ident;
103 	struct idspec *id;
104 	struct genlist_entry *gpb;
105 
106 	/* compare with the ID if specified. */
107 	if (!genlist_next(rmconf->idvl_p, 0))
108 		return 0;
109 
110 	for (id = genlist_next(rmconf->idvl_p, &gpb); id; id = genlist_next(0, &gpb)) {
111 		/* No ID specified in configuration, so it is ok */
112 		if (id->id == 0)
113 			return 0;
114 
115 		/* check the type of both IDs */
116 		if (id->idtype != doi2idtype(id_b->type))
117 			continue;  /* ID type mismatch */
118 
119 		/* compare defined ID with the ID sent by peer. */
120 		switch (id->idtype) {
121 		case IDTYPE_ASN1DN:
122 			ident.v = id_p->v + sizeof(*id_b);
123 			ident.l = id_p->l - sizeof(*id_b);
124 			if (eay_cmp_asn1dn(id->id, &ident) == 0)
125 				return 0;
126 			break;
127 		case IDTYPE_ADDRESS:
128 			sa = (struct sockaddr *)id->id->v;
129 			sa2 = (caddr_t)(id_b + 1);
130 			switch (sa->sa_family) {
131 			case AF_INET:
132 				if (id_p->l - sizeof(*id_b) != sizeof(struct in_addr))
133 					continue;  /* ID value mismatch */
134 				sa1 = (caddr_t) &((struct sockaddr_in *)sa)->sin_addr;
135 				if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0)
136 					return 0;
137 				break;
138 #ifdef INET6
139 			case AF_INET6:
140 				if (id_p->l - sizeof(*id_b) != sizeof(struct in6_addr))
141 					continue;  /* ID value mismatch */
142 				sa1 = (caddr_t) &((struct sockaddr_in6 *)sa)->sin6_addr;
143 				if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0)
144 					return 0;
145 				break;
146 #endif
147 			default:
148 				break;
149 			}
150 			break;
151 		default:
152 			if (memcmp(id->id->v, id_b + 1, id->id->l) == 0)
153 				return 0;
154 			break;
155 		}
156 	}
157 
158 	plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n");
159 	if (rmconf->verify_identifier)
160 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
161 
162 	return 0;
163 }
164 
165 static int
rmconf_match_etype_and_approval(struct remoteconf * rmconf,int etype,struct isakmpsa * approval)166 rmconf_match_etype_and_approval(struct remoteconf *rmconf, int etype,
167     struct isakmpsa *approval)
168 {
169 	if (check_etypeok(rmconf, (void *) (intptr_t) etype) == 0)
170 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
171 
172 	if (approval == NULL)
173 		return 0;
174 
175 	if (etype == ISAKMP_ETYPE_AGG &&
176 	    approval->dh_group != rmconf->dh_group)
177 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
178 
179 	if (checkisakmpsa(rmconf->pcheck_level, approval,
180 			  rmconf->proposal) == NULL)
181 		return ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
182 
183 	return 0;
184 }
185 
186 enum rmconf_match_t {
187 	MATCH_NONE		= 0,
188 	MATCH_BASIC		= 0x0000001,
189 	MATCH_ADDRESS		= 0x0000002,
190 	MATCH_SA		= 0x0000004,
191 	MATCH_IDENTITY		= 0x0000008,
192 	MATCH_AUTH_IDENTITY	= 0x0000010,
193 };
194 
195 static int
rmconf_match_type(struct rmconfselector * rmsel,struct remoteconf * rmconf)196 rmconf_match_type(struct rmconfselector *rmsel, struct remoteconf *rmconf)
197 {
198 	int ret = MATCH_NONE, tmp;
199 
200 	/* No match at all: unwanted anonymous */
201 	if ((rmsel->flags & GETRMCONF_F_NO_ANONYMOUS) &&
202 	    rmconf->remote->sa_family == AF_UNSPEC){
203 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
204 		     "Not matched: Anonymous conf.\n");
205 		return MATCH_NONE;
206 	}
207 
208 	if ((rmsel->flags & GETRMCONF_F_NO_PASSIVE) && rmconf->passive){
209 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
210 		     "Not matched: passive conf.\n");
211 		return MATCH_NONE;
212 	}
213 
214 	ret |= MATCH_BASIC;
215 
216 	/* Check address */
217 	if (rmsel->remote != NULL) {
218 		if (rmconf->remote->sa_family != AF_UNSPEC) {
219 			if (cmpsaddr(rmsel->remote, rmconf->remote) == CMPSADDR_MISMATCH){
220 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
221 				     "Not matched: address mismatch.\n");
222 				return MATCH_NONE;
223 			}
224 
225 			/* Address matched */
226 			ret |= MATCH_ADDRESS;
227 		}
228 	}
229 
230 	/* Check etype and approval */
231 	if (rmsel->etype != ISAKMP_ETYPE_NONE) {
232 		tmp=rmconf_match_etype_and_approval(rmconf, rmsel->etype,
233 						    rmsel->approval);
234 		if (tmp != 0){
235 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
236 			     "Not matched: etype (%d)/approval mismatch (%d).\n", rmsel->etype, tmp);
237 			return MATCH_NONE;
238 		}
239 		ret |= MATCH_SA;
240 	}
241 
242 	/* Check identity */
243 	if (rmsel->identity != NULL && rmconf->verify_identifier) {
244 		if (rmconf_match_identity(rmconf, rmsel->identity) != 0){
245 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
246 			     "Not matched: identity mismatch.\n");
247 			return MATCH_NONE;
248 		}
249 		ret |= MATCH_IDENTITY;
250 	}
251 
252 	/* Check certificate request */
253 	if (rmsel->certificate_request != NULL) {
254 		if (oakley_get_certtype(rmsel->certificate_request) !=
255 		    oakley_get_certtype(rmconf->mycert)){
256 			plog(LLV_DEBUG2, LOCATION, rmsel->remote,
257 			     "Not matched: cert type mismatch.\n");
258 			return MATCH_NONE;
259 		}
260 
261 		if (rmsel->certificate_request->l > 1) {
262 			vchar_t *issuer;
263 
264 			issuer = eay_get_x509asn1issuername(rmconf->mycert);
265 			if (rmsel->certificate_request->l - 1 != issuer->l ||
266 			    memcmp(rmsel->certificate_request->v + 1,
267 				   issuer->v, issuer->l) != 0) {
268 				vfree(issuer);
269 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
270 				     "Not matched: cert issuer mismatch.\n");
271 				return MATCH_NONE;
272 			}
273 			vfree(issuer);
274 		} else {
275 			if (!rmconf->match_empty_cr){
276 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
277 				     "Not matched: empty certificate request.\n");
278 				return MATCH_NONE;
279 			}
280 		}
281 
282 		ret |= MATCH_AUTH_IDENTITY;
283 	}
284 
285 	return ret;
286 }
287 
rmconf_selector_from_ph1(rmsel,iph1)288 void rmconf_selector_from_ph1(rmsel, iph1)
289 	struct rmconfselector *rmsel;
290 	struct ph1handle *iph1;
291 {
292 	memset(rmsel, 0, sizeof(*rmsel));
293 	rmsel->flags = 0;
294 	rmsel->remote = iph1->remote;
295 	rmsel->etype = iph1->etype;
296 	rmsel->approval = iph1->approval;
297 	rmsel->identity = iph1->id_p;
298 	rmsel->certificate_request = iph1->cr_p;
299 }
300 
301 int
enumrmconf(rmsel,enum_func,enum_arg)302 enumrmconf(rmsel, enum_func, enum_arg)
303 	struct rmconfselector *rmsel;
304 	int (* enum_func)(struct remoteconf *rmconf, void *arg);
305 	void *enum_arg;
306 {
307 	struct remoteconf *p;
308 	int ret = 0;
309 
310 	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
311 		plog(LLV_DEBUG2, LOCATION, rmsel->remote,
312 		     "Checking remote conf \"%s\" %s.\n", p->name,
313 		     p->remote->sa_family == AF_UNSPEC ?
314 		     "anonymous" : saddr2str(p->remote));
315 
316 		if (rmsel != NULL) {
317 			if (rmconf_match_type(rmsel, p) == MATCH_NONE){
318 				plog(LLV_DEBUG2, LOCATION, rmsel->remote,
319 				     "Not matched.\n");
320 				continue;
321 			}
322 		}
323 
324 		plog(LLV_DEBUG2, LOCATION, NULL,
325 		     "enumrmconf: \"%s\" matches.\n", p->name);
326 
327 		ret = (*enum_func)(p, enum_arg);
328 		if (ret)
329 			break;
330 	}
331 
332 	return ret;
333 }
334 
335 struct rmconf_find_context {
336 	struct rmconfselector sel;
337 
338 	struct remoteconf *rmconf;
339 	int match_type;
340 	int num_found;
341 };
342 
343 static int
rmconf_find(struct remoteconf * rmconf,void * ctx)344 rmconf_find(struct remoteconf *rmconf, void *ctx)
345 {
346 	struct rmconf_find_context *fctx = (struct rmconf_find_context *) ctx;
347 	int match_type;
348 
349 	/* First matching remote conf? */
350 	match_type = rmconf_match_type(&fctx->sel, rmconf);
351 
352 	if (fctx->rmconf != NULL) {
353 		/* More ambiguous matches are ignored. */
354 		if (match_type < fctx->match_type)
355 			return 0;
356 
357 		if (match_type == fctx->match_type) {
358 			/* Ambiguous match */
359 			fctx->num_found++;
360 			return 0;
361 		}
362 	}
363 
364 	/* More exact match found */
365 	fctx->match_type = match_type;
366 	fctx->num_found = 1;
367 	fctx->rmconf = rmconf;
368 
369 	return 0;
370 }
371 
372 /*
373  * search remote configuration.
374  * don't use port number to search if its value is either IPSEC_PORT_ANY.
375  * If matching anonymous entry, then new entry is copied from anonymous entry.
376  * If no anonymous entry found, then return NULL.
377  * OUT:	NULL:	NG
378  *	Other:	remote configuration entry.
379  */
380 
381 struct remoteconf *
getrmconf(remote,flags)382 getrmconf(remote, flags)
383 	struct sockaddr *remote;
384 	int flags;
385 {
386 	struct rmconf_find_context ctx;
387 
388 	memset(&ctx, 0, sizeof(ctx));
389 	ctx.sel.flags = flags;
390 	ctx.sel.remote = remote;
391 
392 	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
393 		plog(LLV_ERROR, LOCATION, remote,
394 		     "multiple exact configurations.\n");
395 		return NULL;
396 	}
397 
398 	if (ctx.rmconf == NULL) {
399 		plog(LLV_DEBUG, LOCATION, remote,
400 		     "no remote configuration found.\n");
401 		return NULL;
402 	}
403 
404 	if (ctx.num_found != 1) {
405 		plog(LLV_DEBUG, LOCATION, remote,
406 		     "multiple non-exact configurations found.\n");
407 		return NULL;
408 	}
409 
410 	plog(LLV_DEBUG, LOCATION, remote,
411 	     "configuration \"%s\" selected.\n",
412 	     ctx.rmconf->name);
413 
414 	return ctx.rmconf;
415 }
416 
417 struct remoteconf *
getrmconf_by_ph1(iph1)418 getrmconf_by_ph1(iph1)
419 	struct ph1handle *iph1;
420 {
421 	struct rmconf_find_context ctx;
422 
423 	memset(&ctx, 0, sizeof(ctx));
424 	rmconf_selector_from_ph1(&ctx.sel, iph1);
425 	if (loglevel >= LLV_DEBUG) {
426 		char *idstr = NULL;
427 
428 		if (iph1->id_p != NULL)
429 			idstr = ipsecdoi_id2str(iph1->id_p);
430 
431 		plog(LLV_DEBUG, LOCATION, iph1->remote,
432 			"getrmconf_by_ph1: remote %s, identity %s.\n",
433 			saddr2str(iph1->remote), idstr ? idstr : "<any>");
434 
435 		if (idstr)
436 			racoon_free(idstr);
437 	}
438 
439 	if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) {
440 		plog(LLV_ERROR, LOCATION, iph1->remote,
441 		     "multiple exact configurations.\n");
442 		return RMCONF_ERR_MULTIPLE;
443 	}
444 
445 	if (ctx.rmconf == NULL) {
446 		plog(LLV_DEBUG, LOCATION, iph1->remote,
447 		     "no remote configuration found\n");
448 		return NULL;
449 	}
450 
451 	if (ctx.num_found != 1) {
452 		plog(LLV_DEBUG, LOCATION, iph1->remote,
453 		     "multiple non-exact configurations found.\n");
454 		return RMCONF_ERR_MULTIPLE;
455 	}
456 
457 	plog(LLV_DEBUG, LOCATION, iph1->remote,
458 	     "configuration \"%s\" selected.\n",
459 	     ctx.rmconf->name);
460 
461 	return ctx.rmconf;
462 }
463 
464 struct remoteconf *
getrmconf_by_name(name)465 getrmconf_by_name(name)
466 	const char *name;
467 {
468 	struct remoteconf *p;
469 
470 	plog(LLV_DEBUG, LOCATION, NULL,
471 	     "getrmconf_by_name: remote \"%s\".\n",
472 	     name);
473 
474 	RACOON_TAILQ_FOREACH_REVERSE(p, &rmtree, _rmtree, chain) {
475 		if (p->name == NULL)
476 			continue;
477 
478 		if (strcmp(name, p->name) == 0)
479 			return p;
480 	}
481 
482 	return NULL;
483 }
484 
485 struct remoteconf *
newrmconf()486 newrmconf()
487 {
488 	struct remoteconf *new;
489 	int i;
490 
491 	new = racoon_calloc(1, sizeof(*new));
492 	if (new == NULL)
493 		return NULL;
494 
495 	new->proposal = NULL;
496 
497 	/* set default */
498 	new->doitype = IPSEC_DOI;
499 	new->sittype = IPSECDOI_SIT_IDENTITY_ONLY;
500 	new->idvtype = IDTYPE_UNDEFINED;
501 	new->idvl_p = genlist_init();
502 	new->nonce_size = DEFAULT_NONCE_SIZE;
503 	new->passive = FALSE;
504 	new->ike_frag = FALSE;
505 	new->esp_frag = IP_MAXPACKET;
506 	new->ini_contact = TRUE;
507 	new->mode_cfg = FALSE;
508 	new->pcheck_level = PROP_CHECK_STRICT;
509 	new->verify_identifier = FALSE;
510 	new->verify_cert = TRUE;
511 	new->cacertfile = NULL;
512 	new->send_cert = TRUE;
513 	new->send_cr = TRUE;
514 	new->match_empty_cr = FALSE;
515 	new->support_proxy = FALSE;
516 	for (i = 0; i <= SCRIPT_MAX; i++)
517 		new->script[i] = NULL;
518 	new->gen_policy = FALSE;
519 	new->nat_traversal = FALSE;
520 	new->rsa_private = genlist_init();
521 	new->rsa_public = genlist_init();
522 	new->idv = NULL;
523 	new->key = NULL;
524 
525 	new->dpd = TRUE; /* Enable DPD support by default */
526 	new->dpd_interval = 0; /* Disable DPD checks by default */
527 	new->dpd_retry = 5;
528 	new->dpd_maxfails = 5;
529 
530 	new->rekey = REKEY_ON;
531 
532 	new->weak_phase1_check = 0;
533 
534 #ifdef ENABLE_HYBRID
535 	new->xauth = NULL;
536 #endif
537 
538 	new->lifetime = oakley_get_defaultlifetime();
539 
540 	return new;
541 }
542 
543 static void *
dupidvl(void * entry,void * arg)544 dupidvl(void *entry, void *arg)
545 {
546 	struct idspec *id;
547 	struct idspec *old = (struct idspec *) entry;
548 	id = newidspec();
549 	if (!id) return (void *) -1;
550 
551 	if (set_identifier(&id->id, old->idtype, old->id) != 0) {
552 		racoon_free(id);
553 		return (void *) -1;
554 	}
555 
556 	id->idtype = old->idtype;
557 
558 	genlist_append(arg, id);
559 	return NULL;
560 }
561 
562 static void *
duprsa(void * entry,void * arg)563 duprsa(void *entry, void *arg)
564 {
565 	struct rsa_key *new;
566 
567 	new = rsa_key_dup((struct rsa_key *)entry);
568 	if (new == NULL)
569 		return (void *) -1;
570 	genlist_append(arg, new);
571 
572 	/* keep genlist_foreach going */
573 	return NULL;
574 }
575 
576 /* Creates shallow copy of a remote config. Used for "inherit" keyword. */
577 struct remoteconf *
duprmconf_shallow(rmconf)578 duprmconf_shallow (rmconf)
579 	struct remoteconf *rmconf;
580 {
581 	struct remoteconf *new;
582 
583 	new = racoon_calloc(1, sizeof(*new));
584 	if (new == NULL)
585 		return NULL;
586 
587 	memcpy(new, rmconf, sizeof(*new));
588 	new->name = NULL;
589 	new->inherited_from = rmconf;
590 
591 	new->proposal = NULL; /* will be filled by set_isakmp_proposal() */
592 
593 	/* Better to set remote to NULL to avoid that the destination
594 	 * rmconf uses the same allocated memory as the source rmconf.
595 	 */
596 	new->remote = NULL;
597 
598 	return new;
599 }
600 
601 /* Copies pointer structures of an inherited remote config.
602  * Used by "inherit" mechanism in a two step copy method, necessary to
603  * prevent both double free() and memory leak during config reload.
604  */
605 int
duprmconf_finish(new)606 duprmconf_finish (new)
607 	struct remoteconf *new;
608 {
609 	struct remoteconf *rmconf;
610 	int i;
611 
612 	if (new->inherited_from == NULL)
613 		return 0; /* nothing todo, no inheritance */
614 
615 	rmconf = new->inherited_from;
616 
617 	/* duplicate dynamic structures unless value overridden */
618 	if (new->etypes != NULL && new->etypes == rmconf->etypes)
619 		new->etypes = dupetypes(new->etypes);
620 	if (new->idvl_p == rmconf->idvl_p) {
621 		new->idvl_p = genlist_init();
622 		genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
623 	}
624 
625 	if (new->rsa_private == rmconf->rsa_private) {
626 		new->rsa_private = genlist_init();
627 		genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private);
628 	}
629 	if (new->rsa_public == rmconf->rsa_public) {
630 		new->rsa_public = genlist_init();
631 		genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public);
632 	}
633 	if (new->remote != NULL && new->remote == rmconf->remote) {
634 		new->remote = racoon_malloc(sizeof(*new->remote));
635 		if (new->remote == NULL) {
636 			plog(LLV_ERROR, LOCATION, NULL,
637 			    "duprmconf_finish: malloc failed (remote)\n");
638 			exit(1);
639 		}
640 		memcpy(new->remote, rmconf->remote, sizeof(*new->remote));
641 	}
642 	if (new->spspec != NULL && new->spspec == rmconf->spspec) {
643 		dupspspec_list(new, rmconf);
644 	}
645 
646 	/* proposal has been deep copied already from spspec's, see
647 	 * cfparse.y:set_isakmp_proposal, which in turn calls
648 	 * cfparse.y:expand_isakmpspec where the copying happens.
649 	 */
650 
651 #ifdef ENABLE_HYBRID
652 	if (new->xauth != NULL && new->xauth == rmconf->xauth) {
653 		new->xauth = xauth_rmconf_dup(new->xauth);
654 		if (new->xauth == NULL)
655 			exit(1);
656 	}
657 #endif
658 
659         /* duplicate strings unless value overridden */
660 	if (new->mycertfile != NULL && new->mycertfile == rmconf->mycertfile) {
661 		new->mycertfile = racoon_strdup(new->mycertfile);
662 		STRDUP_FATAL(new->mycertfile);
663 	}
664 	if (new->myprivfile != NULL && new->myprivfile == rmconf->myprivfile) {
665 		new->myprivfile = racoon_strdup(new->myprivfile);
666 		STRDUP_FATAL(new->myprivfile);
667 	}
668 	if (new->peerscertfile != NULL && new->peerscertfile == rmconf->peerscertfile) {
669 		new->peerscertfile = racoon_strdup(new->peerscertfile);
670 		STRDUP_FATAL(new->peerscertfile);
671 	}
672 	if (new->cacertfile != NULL && new->cacertfile == rmconf->cacertfile) {
673 		new->cacertfile = racoon_strdup(new->cacertfile);
674 		STRDUP_FATAL(new->cacertfile);
675 	}
676 	if (new->idv != NULL && new->idv == rmconf->idv) {
677 		new->idv = vdup(new->idv);
678 		STRDUP_FATAL(new->idv);
679 	}
680 	if (new->key != NULL && new->key == rmconf->key) {
681 		new->key = vdup(new->key);
682 		STRDUP_FATAL(new->key);
683 	}
684 	if (new->mycert != NULL && new->mycert == rmconf->mycert) {
685 		new->mycert = vdup(new->mycert);
686 		STRDUP_FATAL(new->mycert);
687 	}
688 	if (new->peerscert != NULL && new->peerscert == rmconf->peerscert) {
689 		new->peerscert = vdup(new->peerscert);
690 		STRDUP_FATAL(new->peerscert);
691 	}
692 	if (new->cacert != NULL && new->cacert == rmconf->cacert) {
693 		new->cacert = vdup(new->cacert);
694 		STRDUP_FATAL(new->cacert);
695 	}
696 	for (i = 0; i <= SCRIPT_MAX; i++)
697 		if (new->script[i] != NULL && new->script[i] == rmconf->script[i]) {
698 			new->script[i] = vdup(new->script[i]);
699 			STRDUP_FATAL(new->script[i]);
700 		}
701 
702 	return 0;
703 }
704 
705 static void
idspec_free(void * data)706 idspec_free(void *data)
707 {
708 	vfree (((struct idspec *)data)->id);
709 	free (data);
710 }
711 
712 void
delrmconf(rmconf)713 delrmconf(rmconf)
714 	struct remoteconf *rmconf;
715 {
716 	int i;
717 
718 	if (rmconf == NULL)
719 		return;
720 
721 #ifdef ENABLE_HYBRID
722 	if (rmconf->xauth)
723 		xauth_rmconf_delete(&rmconf->xauth);
724 #endif
725 	if (rmconf->etypes){
726 		deletypes(rmconf->etypes);
727 		rmconf->etypes=NULL;
728 	}
729 	if (rmconf->idv)
730 		vfree(rmconf->idv);
731 	if (rmconf->key)
732 		vfree(rmconf->key);
733 	if (rmconf->idvl_p)
734 		genlist_free(rmconf->idvl_p, idspec_free);
735 	if (rmconf->dhgrp)
736 		oakley_dhgrp_free(rmconf->dhgrp);
737 	if (rmconf->proposal)
738 		delisakmpsa(rmconf->proposal);
739 	flushspspec(rmconf);
740 	if (rmconf->mycert)
741 		vfree(rmconf->mycert);
742 	if (rmconf->mycertfile)
743 		racoon_free(rmconf->mycertfile);
744 	if (rmconf->myprivfile)
745 		racoon_free(rmconf->myprivfile);
746 	if (rmconf->peerscert)
747 		vfree(rmconf->peerscert);
748 	if (rmconf->peerscertfile)
749 		racoon_free(rmconf->peerscertfile);
750 	if (rmconf->cacert)
751 		vfree(rmconf->cacert);
752 	if (rmconf->cacertfile)
753 		racoon_free(rmconf->cacertfile);
754 	if (rmconf->rsa_private)
755 		genlist_free(rmconf->rsa_private, rsa_key_free);
756 	if (rmconf->rsa_public)
757 		genlist_free(rmconf->rsa_public, rsa_key_free);
758 	if (rmconf->name)
759 		racoon_free(rmconf->name);
760 	if (rmconf->remote)
761 		racoon_free(rmconf->remote);
762 	for (i = 0; i <= SCRIPT_MAX; i++)
763 		if (rmconf->script[i])
764 			vfree(rmconf->script[i]);
765 
766 	racoon_free(rmconf);
767 }
768 
769 void
delisakmpsa(sa)770 delisakmpsa(sa)
771 	struct isakmpsa *sa;
772 {
773 	if (sa->dhgrp)
774 		oakley_dhgrp_free(sa->dhgrp);
775 	if (sa->next)
776 		delisakmpsa(sa->next);
777 #ifdef HAVE_GSSAPI
778 	if (sa->gssid)
779 		vfree(sa->gssid);
780 #endif
781 	racoon_free(sa);
782 }
783 
784 struct etypes *
dupetypes(orig)785 dupetypes(orig)
786 	struct etypes *orig;
787 {
788 	struct etypes *new;
789 
790 	if (!orig)
791 		return NULL;
792 
793 	new = racoon_malloc(sizeof(struct etypes));
794 	if (new == NULL)
795 		return NULL;
796 
797 	new->type = orig->type;
798 	new->next = NULL;
799 
800 	if (orig->next)
801 		new->next=dupetypes(orig->next);
802 
803 	return new;
804 }
805 
806 void
deletypes(e)807 deletypes(e)
808 	struct etypes *e;
809 {
810 	if (e->next)
811 		deletypes(e->next);
812 	racoon_free(e);
813 }
814 
815 /*
816  * insert into head of list.
817  */
818 void
insrmconf(new)819 insrmconf(new)
820 	struct remoteconf *new;
821 {
822 	if (new->name == NULL) {
823 		new->name = racoon_strdup(saddr2str(new->remote));
824 	}
825 	if (new->remote == NULL) {
826 		new->remote = newsaddr(sizeof(struct sockaddr));
827 		new->remote->sa_family = AF_UNSPEC;
828 	}
829 
830 	TAILQ_INSERT_HEAD(&rmtree, new, chain);
831 }
832 
833 void
remrmconf(rmconf)834 remrmconf(rmconf)
835 	struct remoteconf *rmconf;
836 {
837 	TAILQ_REMOVE(&rmtree, rmconf, chain);
838 }
839 
840 void
flushrmconf()841 flushrmconf()
842 {
843 	struct remoteconf *p, *next;
844 
845 	for (p = TAILQ_FIRST(&rmtree); p; p = next) {
846 		next = TAILQ_NEXT(p, chain);
847 		remrmconf(p);
848 		delrmconf(p);
849 	}
850 }
851 
852 void
initrmconf()853 initrmconf()
854 {
855 	TAILQ_INIT(&rmtree);
856 }
857 
858 void
rmconf_start_reload()859 rmconf_start_reload()
860 {
861 	rmtree_save=rmtree;
862 	initrmconf();
863 }
864 
865 void
rmconf_finish_reload()866 rmconf_finish_reload()
867 {
868 	remoteconf_tailq_head_t rmtree_tmp;
869 
870 	rmtree_tmp=rmtree;
871 	rmtree=rmtree_save;
872 	flushrmconf();
873 	initrmconf();
874 	rmtree=rmtree_tmp;
875 }
876 
877 
878 
879 /* check exchange type to be acceptable */
880 int
check_etypeok(rmconf,ctx)881 check_etypeok(rmconf, ctx)
882 	struct remoteconf *rmconf;
883 	void *ctx;
884 {
885 	u_int8_t etype = (u_int8_t) (intptr_t) ctx;
886 	struct etypes *e;
887 
888 	for (e = rmconf->etypes; e != NULL; e = e->next) {
889 		if (e->type == etype)
890 			return 1;
891 		plog(LLV_DEBUG2, LOCATION, NULL,
892 		     "Etype mismatch: got %d, expected %d.\n", e->type, etype);
893 	}
894 
895 	return 0;
896 }
897 
898 /*%%%*/
899 struct isakmpsa *
newisakmpsa()900 newisakmpsa()
901 {
902 	struct isakmpsa *new;
903 
904 	new = racoon_calloc(1, sizeof(*new));
905 	if (new == NULL)
906 		return NULL;
907 
908 	/*
909 	 * Just for sanity, make sure this is initialized.  This is
910 	 * filled in for real when the ISAKMP proposal is configured.
911 	 */
912 	new->vendorid = VENDORID_UNKNOWN;
913 
914 	new->next = NULL;
915 #ifdef HAVE_GSSAPI
916 	new->gssid = NULL;
917 #endif
918 
919 	return new;
920 }
921 
922 /*
923  * insert into tail of list.
924  */
925 void
insisakmpsa(new,rmconf)926 insisakmpsa(new, rmconf)
927 	struct isakmpsa *new;
928 	struct remoteconf *rmconf;
929 {
930 	struct isakmpsa *p;
931 
932 	if (rmconf->proposal == NULL) {
933 		rmconf->proposal = new;
934 		return;
935 	}
936 
937 	for (p = rmconf->proposal; p->next != NULL; p = p->next)
938 		;
939 	p->next = new;
940 }
941 
942 static void *
dump_peers_identifiers(void * entry,void * arg)943 dump_peers_identifiers (void *entry, void *arg)
944 {
945 	struct idspec *id = (struct idspec*) entry;
946 	char buf[1024], *pbuf;
947 	pbuf = buf;
948 	pbuf += sprintf (pbuf, "\tpeers_identifier %s",
949 			 s_idtype (id->idtype));
950 	if (id->id)
951 		pbuf += sprintf (pbuf, " \"%s\"", id->id->v);
952 	plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
953 	return NULL;
954 }
955 
956 static int
dump_rmconf_single(struct remoteconf * p,void * data)957 dump_rmconf_single (struct remoteconf *p, void *data)
958 {
959 	struct etypes *etype = p->etypes;
960 	struct isakmpsa *prop = p->proposal;
961 	char buf[1024], *pbuf;
962 
963 	pbuf = buf;
964 
965 	pbuf += sprintf(pbuf, "remote \"%s\"", p->name);
966 	if (p->inherited_from)
967 		pbuf += sprintf(pbuf, " inherit \"%s\"",
968 				p->inherited_from->name);
969 	plog(LLV_INFO, LOCATION, NULL, "%s {\n", buf);
970 	pbuf = buf;
971 	pbuf += sprintf(pbuf, "\texchange_type ");
972 	while (etype) {
973 		pbuf += sprintf (pbuf, "%s%s", s_etype(etype->type),
974 				 etype->next != NULL ? ", " : ";\n");
975 		etype = etype->next;
976 	}
977 	plog(LLV_INFO, LOCATION, NULL, "%s", buf);
978 	plog(LLV_INFO, LOCATION, NULL, "\tdoi %s;\n", s_doi(p->doitype));
979 	pbuf = buf;
980 	pbuf += sprintf(pbuf, "\tmy_identifier %s", s_idtype (p->idvtype));
981 	if (p->idvtype == IDTYPE_ASN1DN) {
982 		plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
983 		plog(LLV_INFO, LOCATION, NULL,
984 		     "\tcertificate_type %s \"%s\" \"%s\";\n",
985 		     oakley_get_certtype(p->mycert) == ISAKMP_CERT_X509SIGN
986 		       ? "x509" : "*UNKNOWN*",
987 		     p->mycertfile, p->myprivfile);
988 
989 		switch (oakley_get_certtype(p->peerscert)) {
990 		case ISAKMP_CERT_NONE:
991 			plog(LLV_INFO, LOCATION, NULL,
992 			     "\t/* peers certificate from payload */\n");
993 			break;
994 		case ISAKMP_CERT_X509SIGN:
995 			plog(LLV_INFO, LOCATION, NULL,
996 			     "\tpeers_certfile \"%s\";\n", p->peerscertfile);
997 			break;
998 		case ISAKMP_CERT_DNS:
999 			plog(LLV_INFO, LOCATION, NULL,
1000 			     "\tpeers_certfile dnssec;\n");
1001 			break;
1002 		default:
1003 			plog(LLV_INFO, LOCATION, NULL,
1004 			     "\tpeers_certfile *UNKNOWN* (%d)\n",
1005 			     oakley_get_certtype(p->peerscert));
1006 			break;
1007 		}
1008 	}
1009 	else {
1010 		if (p->idv)
1011 			pbuf += sprintf (pbuf, " \"%s\"", p->idv->v);
1012 		plog(LLV_INFO, LOCATION, NULL, "%s;\n", buf);
1013 		genlist_foreach(p->idvl_p, &dump_peers_identifiers, NULL);
1014 	}
1015 
1016 	plog(LLV_INFO, LOCATION, NULL, "\trekey %s;\n",
1017 		p->rekey == REKEY_FORCE ? "force" : s_switch (p->rekey));
1018 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cert %s;\n",
1019 		s_switch (p->send_cert));
1020 	plog(LLV_INFO, LOCATION, NULL, "\tsend_cr %s;\n",
1021 		s_switch (p->send_cr));
1022 	plog(LLV_INFO, LOCATION, NULL, "\tmatch_empty_cr %s;\n",
1023 		s_switch (p->match_empty_cr));
1024 	plog(LLV_INFO, LOCATION, NULL, "\tverify_cert %s;\n",
1025 		s_switch (p->verify_cert));
1026 	plog(LLV_INFO, LOCATION, NULL, "\tverify_identifier %s;\n",
1027 		s_switch (p->verify_identifier));
1028 	plog(LLV_INFO, LOCATION, NULL, "\tnat_traversal %s;\n",
1029 		p->nat_traversal == NATT_FORCE ?
1030 			"force" : s_switch (p->nat_traversal));
1031 	plog(LLV_INFO, LOCATION, NULL, "\tnonce_size %d;\n",
1032 		p->nonce_size);
1033 	plog(LLV_INFO, LOCATION, NULL, "\tpassive %s;\n",
1034 		s_switch (p->passive));
1035 	plog(LLV_INFO, LOCATION, NULL, "\tike_frag %s;\n",
1036 		p->ike_frag == ISAKMP_FRAG_FORCE ?
1037 			"force" : s_switch (p->ike_frag));
1038 	plog(LLV_INFO, LOCATION, NULL, "\tesp_frag %d;\n", p->esp_frag);
1039 	plog(LLV_INFO, LOCATION, NULL, "\tinitial_contact %s;\n",
1040 		s_switch (p->ini_contact));
1041 	plog(LLV_INFO, LOCATION, NULL, "\tgenerate_policy %s;\n",
1042 		s_switch (p->gen_policy));
1043 	plog(LLV_INFO, LOCATION, NULL, "\tsupport_proxy %s;\n",
1044 		s_switch (p->support_proxy));
1045 
1046 	while (prop) {
1047 		plog(LLV_INFO, LOCATION, NULL, "\n");
1048 		plog(LLV_INFO, LOCATION, NULL,
1049 			"\t/* prop_no=%d, trns_no=%d */\n",
1050 			prop->prop_no, prop->trns_no);
1051 		plog(LLV_INFO, LOCATION, NULL, "\tproposal {\n");
1052 		plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime time %lu sec;\n",
1053 			(long)prop->lifetime);
1054 		plog(LLV_INFO, LOCATION, NULL, "\t\tlifetime bytes %zd;\n",
1055 			prop->lifebyte);
1056 		plog(LLV_INFO, LOCATION, NULL, "\t\tdh_group %s;\n",
1057 			alg_oakley_dhdef_name(prop->dh_group));
1058 		plog(LLV_INFO, LOCATION, NULL, "\t\tencryption_algorithm %s;\n",
1059 			alg_oakley_encdef_name(prop->enctype));
1060 		plog(LLV_INFO, LOCATION, NULL, "\t\thash_algorithm %s;\n",
1061 			alg_oakley_hashdef_name(prop->hashtype));
1062 		plog(LLV_INFO, LOCATION, NULL, "\t\tauthentication_method %s;\n",
1063 			alg_oakley_authdef_name(prop->authmethod));
1064 		plog(LLV_INFO, LOCATION, NULL, "\t}\n");
1065 		prop = prop->next;
1066 	}
1067 	plog(LLV_INFO, LOCATION, NULL, "}\n");
1068 	plog(LLV_INFO, LOCATION, NULL, "\n");
1069 
1070 	return 0;
1071 }
1072 
1073 void
dumprmconf()1074 dumprmconf()
1075 {
1076 	enumrmconf(NULL, dump_rmconf_single, NULL);
1077 }
1078 
1079 struct idspec *
newidspec()1080 newidspec()
1081 {
1082 	struct idspec *new;
1083 
1084 	new = racoon_calloc(1, sizeof(*new));
1085 	if (new == NULL)
1086 		return NULL;
1087 	new->idtype = IDTYPE_ADDRESS;
1088 	new->id = NULL;
1089 	return new;
1090 }
1091 
1092 vchar_t *
script_path_add(path)1093 script_path_add(path)
1094 	vchar_t *path;
1095 {
1096 	char *script_dir;
1097 	vchar_t *new_path;
1098 	size_t len;
1099 
1100 	script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT];
1101 
1102 	/* Try to find the script in the script directory */
1103 	if ((path->v[0] != '/') && (script_dir != NULL)) {
1104 		len = strlen(script_dir) + sizeof("/") + path->l + 1;
1105 
1106 		if ((new_path = vmalloc(len)) == NULL) {
1107 			plog(LLV_ERROR, LOCATION, NULL,
1108 			    "Cannot allocate memory: %s\n", strerror(errno));
1109 			return NULL;
1110 		}
1111 
1112 		new_path->v[0] = '\0';
1113 		(void)strlcat(new_path->v, script_dir, len);
1114 		(void)strlcat(new_path->v, "/", len);
1115 		(void)strlcat(new_path->v, path->v, len);
1116 
1117 		vfree(path);
1118 		path = new_path;
1119 	}
1120 
1121 	return path;
1122 }
1123 
1124 
1125 struct isakmpsa *
dupisakmpsa(struct isakmpsa * sa)1126 dupisakmpsa(struct isakmpsa *sa)
1127 {
1128 	struct isakmpsa *res = NULL;
1129 
1130 	if(sa == NULL)
1131 		return NULL;
1132 
1133 	res = newisakmpsa();
1134 	if(res == NULL)
1135 		return NULL;
1136 
1137 	*res = *sa;
1138 #ifdef HAVE_GSSAPI
1139 	if (sa->gssid != NULL)
1140 		res->gssid = vdup(sa->gssid);
1141 #endif
1142 	res->next = NULL;
1143 
1144 	if(sa->dhgrp != NULL)
1145 		oakley_setdhgroup(sa->dh_group, &res->dhgrp);
1146 
1147 	return res;
1148 
1149 }
1150 
1151 #ifdef ENABLE_HYBRID
1152 int
isakmpsa_switch_authmethod(authmethod)1153 isakmpsa_switch_authmethod(authmethod)
1154 	int authmethod;
1155 {
1156 	switch(authmethod) {
1157 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1158 		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
1159 		break;
1160 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1161 		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
1162 		break;
1163 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1164 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
1165 		break;
1166 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1167 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
1168 		break;
1169 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1170 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
1171 		break;
1172 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1173 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
1174 		break;
1175 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1176 		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I;
1177 		break;
1178 	default:
1179 		break;
1180 	}
1181 
1182 	return authmethod;
1183 }
1184 #endif
1185 
1186 /*
1187  * Given a proposed ISAKMP SA, and a list of acceptable
1188  * ISAKMP SAs, it compares using pcheck_level policy and
1189  * returns first match (if any).
1190  */
1191 struct isakmpsa *
checkisakmpsa(pcheck_level,proposal,acceptable)1192 checkisakmpsa(pcheck_level, proposal, acceptable)
1193 	int pcheck_level;
1194 	struct isakmpsa *proposal, *acceptable;
1195 {
1196 	struct isakmpsa *p;
1197 
1198 	for (p = acceptable; p != NULL; p = p->next){
1199 		plog(LLV_DEBUG2, LOCATION, NULL,
1200 		     "checkisakmpsa:\nauthmethod: %d / %d\n",
1201 		     isakmpsa_switch_authmethod(proposal->authmethod), isakmpsa_switch_authmethod(p->authmethod));
1202 		if (isakmpsa_switch_authmethod(proposal->authmethod) != isakmpsa_switch_authmethod(p->authmethod) ||
1203 		    proposal->enctype != p->enctype ||
1204                     proposal->dh_group != p->dh_group ||
1205 		    proposal->hashtype != p->hashtype)
1206 			continue;
1207 
1208 		switch (pcheck_level) {
1209 		case PROP_CHECK_OBEY:
1210 			break;
1211 
1212 		case PROP_CHECK_CLAIM:
1213 		case PROP_CHECK_STRICT:
1214 			if (proposal->encklen < p->encklen ||
1215 #if 0
1216 			    proposal->lifebyte > p->lifebyte ||
1217 #endif
1218 			    proposal->lifetime > p->lifetime)
1219 				continue;
1220 			break;
1221 
1222 		case PROP_CHECK_EXACT:
1223 			if (proposal->encklen != p->encklen ||
1224 #if 0
1225                             proposal->lifebyte != p->lifebyte ||
1226 #endif
1227 			    proposal->lifetime != p->lifetime)
1228 				continue;
1229 			break;
1230 
1231 		default:
1232 			continue;
1233 		}
1234 
1235 		return p;
1236 	}
1237 
1238 	return NULL;
1239 }
1240