Home | History | Annotate | Line # | Download | only in racoon
      1 /*	$NetBSD: localconf.c,v 1.12 2025/03/08 16:39:08 christos Exp $	*/
      2 
      3 /*	$KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane 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 
     39 #include <stdlib.h>
     40 #include <stdio.h>
     41 #include <string.h>
     42 #include <errno.h>
     43 #include <ctype.h>
     44 #include <err.h>
     45 
     46 #include "var.h"
     47 #include "misc.h"
     48 #include "vmbuf.h"
     49 #include "plog.h"
     50 #include "debug.h"
     51 
     52 #include "localconf.h"
     53 #include "algorithm.h"
     54 #include "admin.h"
     55 #include "privsep.h"
     56 #include "isakmp_var.h"
     57 #include "isakmp.h"
     58 #include "ipsec_doi.h"
     59 #include "grabmyaddr.h"
     60 #include "vendorid.h"
     61 #include "str2val.h"
     62 #include "safefile.h"
     63 #include "admin.h"
     64 #include "gcmalloc.h"
     65 
     66 struct localconf *lcconf = NULL;
     67 
     68 static void setdefault(void);
     69 
     70 void
     71 initlcconf()
     72 {
     73 	if (lcconf == NULL) {
     74 		lcconf = racoon_calloc(1, sizeof(*lcconf));
     75 		if (lcconf == NULL)
     76 			errx(1, "failed to allocate local conf.");
     77 
     78 		// Important: assure all pointers within lcconf to be NULL.
     79 		memset(lcconf, 0, sizeof(*lcconf));
     80 	}
     81 
     82 	setdefault();
     83 	lcconf->racoon_conf = __UNCONST(LC_DEFAULT_CF);
     84 }
     85 
     86 void
     87 lcconf_setchroot(char* chroot)
     88 {
     89 	if (lcconf->chroot) {
     90 		racoon_free(lcconf->chroot);
     91 		lcconf->chroot = NULL;
     92 	}
     93 	lcconf->chroot = chroot;
     94 }
     95 
     96 int
     97 lcconf_setpath(char* path, unsigned int path_type)
     98 {
     99 	if (path_type >= LC_PATHTYPE_MAX)
    100 		return -1;
    101 
    102 	if (lcconf->pathinfo[path_type])
    103 		racoon_free(lcconf->pathinfo[path_type]);
    104 
    105 	lcconf->pathinfo[path_type] = path;
    106 
    107 	return 0;
    108 }
    109 
    110 void
    111 flushlcconf()
    112 {
    113 	int i;
    114 
    115 	setdefault();
    116 	myaddr_flush();
    117 
    118 	for (i = 0; i < LC_PATHTYPE_MAX; i++) {
    119 		if (lcconf->pathinfo[i]) {
    120 			racoon_free(lcconf->pathinfo[i]);
    121 			lcconf->pathinfo[i] = NULL;
    122 		}
    123 	}
    124 }
    125 
    126 static void
    127 setdefault()
    128 {
    129 	lcconf->uid = 0;
    130 	lcconf->gid = 0;
    131 
    132 	{
    133 		int i = 0;
    134 		for (; i < LC_PATHTYPE_MAX; i++) {
    135 			if (lcconf->pathinfo[i]) {
    136 				racoon_free(lcconf->pathinfo[i]);
    137 				lcconf->pathinfo[i] = NULL;
    138 			}
    139 		}
    140 	}
    141 
    142 	lcconf_setchroot(NULL);
    143 
    144 	lcconf->port_isakmp = PORT_ISAKMP;
    145 	lcconf->port_isakmp_natt = PORT_ISAKMP_NATT;
    146 	lcconf->default_af = AF_INET;
    147 	lcconf->pad_random = LC_DEFAULT_PAD_RANDOM;
    148 	lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN;
    149 	lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE;
    150 	lcconf->pad_strict = LC_DEFAULT_PAD_STRICT;
    151 	lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
    152 	lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER;
    153 	lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL;
    154 	lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND;
    155 	lcconf->secret_size = LC_DEFAULT_SECRETSIZE;
    156 	lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
    157 	lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
    158 	lcconf->strict_address = FALSE;
    159 	lcconf->complex_bundle = TRUE; /*XXX FALSE;*/
    160 	lcconf->gss_id_enc = LC_GSSENC_UTF16LE; /* Windows compatibility */
    161 	lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
    162 	lcconf->pfkey_buffer_size = LC_DEFAULT_PFKEY_BUFFER_SIZE;
    163 }
    164 
    165 /*
    166  * get PSK by string.
    167  */
    168 vchar_t *
    169 getpskbyname(vchar_t *id0)
    170 {
    171 	char *id;
    172 	vchar_t *key = NULL;
    173 
    174 	id = racoon_calloc(1, 1 + id0->l - sizeof(struct ipsecdoi_id_b));
    175 	if (id == NULL) {
    176 		plog(LLV_ERROR, LOCATION, NULL,
    177 			"failed to get psk buffer.\n");
    178 		goto end;
    179 	}
    180 	memcpy(id, id0->v + sizeof(struct ipsecdoi_id_b),
    181 		id0->l - sizeof(struct ipsecdoi_id_b));
    182 	id[id0->l - sizeof(struct ipsecdoi_id_b)] = '\0';
    183 
    184 	key = privsep_getpsk(id, id0->l - sizeof(struct ipsecdoi_id_b));
    185 
    186 end:
    187 	if (id)
    188 		racoon_free(id);
    189 	return key;
    190 }
    191 
    192 /*
    193  * get PSK by address.
    194  */
    195 vchar_t *
    196 getpskbyaddr(struct sockaddr *remote)
    197 {
    198 	vchar_t *key = NULL;
    199 	char addr[NI_MAXHOST], port[NI_MAXSERV];
    200 
    201 	GETNAMEINFO(remote, addr, port);
    202 
    203 	key = privsep_getpsk(addr, strlen(addr));
    204 
    205 	return key;
    206 }
    207 
    208 vchar_t *
    209 getpsk(const char *str, const int len)
    210 {
    211 	FILE *fp;
    212 	char buf[1024];	/* XXX how is variable length ? */
    213 	vchar_t *key = NULL;
    214 	char *p, *q;
    215 	size_t keylen;
    216 	char *k = NULL;
    217 
    218 	if (safefile(lcconf->pathinfo[LC_PATHTYPE_PSK], 1) == 0)
    219 		fp = fopen(lcconf->pathinfo[LC_PATHTYPE_PSK], "r");
    220 	else
    221 		fp = NULL;
    222 	if (fp == NULL) {
    223 		plog(LLV_ERROR, LOCATION, NULL,
    224 			"failed to open pre_share_key file %s\n",
    225 			lcconf->pathinfo[LC_PATHTYPE_PSK]);
    226 		return NULL;
    227 	}
    228 
    229 	while (fgets(buf, sizeof(buf), fp) != NULL) {
    230 		/* comment line */
    231 		if (buf[0] == '#')
    232 			continue;
    233 
    234 		/* search the end of 1st string. */
    235 		for (p = buf; *p != '\0' && !isspace((unsigned char)*p); p++)
    236 			continue;
    237 		if (*p == '\0')
    238 			continue;	/* no 2nd parameter */
    239 		*p = '\0';
    240 		/* search the 1st of 2nd string. */
    241 		while (isspace((unsigned char)*++p))
    242 			continue;
    243 		if (*p == '\0')
    244 			continue;	/* no 2nd parameter */
    245 		p--;
    246 		if (
    247 #ifdef ENABLE_WILDCARD_MATCH
    248 		    strncmp(buf, "*", 2) == 0 ||
    249 #endif
    250 		    (strncmp(buf, str, len) == 0 && buf[len] == '\0')) {
    251 			p++;
    252 			keylen = 0;
    253 			for (q = p; *q != '\0' && *q != '\n'; q++)
    254 				keylen++;
    255 			*q = '\0';
    256 
    257 			/* fix key if hex string */
    258 			if (strncmp(p, "0x", 2) == 0) {
    259 				k = str2val(p + 2, 16, &keylen);
    260 				if (k == NULL) {
    261 					plog(LLV_ERROR, LOCATION, NULL,
    262 						"failed to get psk buffer.\n");
    263 					goto end;
    264 				}
    265 				p = k;
    266 			}
    267 
    268 			key = vmalloc(keylen);
    269 			if (key == NULL) {
    270 				plog(LLV_ERROR, LOCATION, NULL,
    271 					"failed to allocate key buffer.\n");
    272 				goto end;
    273 			}
    274 			memcpy(key->v, p, key->l);
    275 			if (k)
    276 				racoon_free(k);
    277 			goto end;
    278 		}
    279 	}
    280 
    281 end:
    282 	fclose(fp);
    283 	return key;
    284 }
    285 
    286 /*
    287  * get a file name of a type specified.
    288  */
    289 void
    290 getpathname(char *path, int len, int type, const char *name)
    291 {
    292 	snprintf(path, len, "%s%s%s",
    293 		name[0] == '/' ? "" : lcconf->pathinfo[type],
    294 		name[0] == '/' ? "" : "/",
    295 		name);
    296 
    297 	plog(LLV_DEBUG, LOCATION, NULL, "filename: %s\n", path);
    298 }
    299 
    300 #if 0 /* DELETEIT */
    301 static int lc_doi2idtype[] = {
    302 	-1,
    303 	-1,
    304 	LC_IDENTTYPE_FQDN,
    305 	LC_IDENTTYPE_USERFQDN,
    306 	-1,
    307 	-1,
    308 	-1,
    309 	-1,
    310 	-1,
    311 	LC_IDENTTYPE_CERTNAME,
    312 	-1,
    313 	LC_IDENTTYPE_KEYID,
    314 };
    315 
    316 /*
    317  * convert DOI value to idtype
    318  * OUT	-1   : NG
    319  *	other: converted.
    320  */
    321 int
    322 doi2idtype(idtype)
    323 	int idtype;
    324 {
    325 	if (ARRAYLEN(lc_doi2idtype) > idtype)
    326 		return lc_doi2idtype[idtype];
    327 	return -1;
    328 }
    329 #endif
    330 
    331 static int lc_sittype2doi[] = {
    332 	IPSECDOI_SIT_IDENTITY_ONLY,
    333 	IPSECDOI_SIT_SECRECY,
    334 	IPSECDOI_SIT_INTEGRITY,
    335 };
    336 
    337 /*
    338  * convert sittype to DOI value.
    339  * OUT	-1   : NG
    340  *	other: converted.
    341  */
    342 int
    343 sittype2doi(int sittype)
    344 {
    345 	if (ARRAYLEN(lc_sittype2doi) > sittype)
    346 		return lc_sittype2doi[sittype];
    347 	return -1;
    348 }
    349 
    350 static int lc_doitype2doi[] = {
    351 	IPSEC_DOI,
    352 };
    353 
    354 /*
    355  * convert doitype to DOI value.
    356  * OUT	-1   : NG
    357  *	other: converted.
    358  */
    359 int
    360 doitype2doi(int doitype)
    361 {
    362 	if (ARRAYLEN(lc_doitype2doi) > doitype)
    363 		return lc_doitype2doi[doitype];
    364 	return -1;
    365 }
    366 
    367 
    368 
    369 static void
    370 saverestore_params(int f)
    371 {
    372 	static uint16_t s_port_isakmp;
    373 
    374 	/* 0: save, 1: restore */
    375 	if (f) {
    376 		lcconf->port_isakmp = s_port_isakmp;
    377 	} else {
    378 		s_port_isakmp = lcconf->port_isakmp;
    379 	}
    380 }
    381 
    382 void
    383 restore_params()
    384 {
    385 	saverestore_params(1);
    386 }
    387 
    388 void
    389 save_params()
    390 {
    391 	saverestore_params(0);
    392 }
    393