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