1/*	$KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $	*/
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
18 *
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
29 * SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <sys/param.h>
34
35#include <stdlib.h>
36#include <stdio.h>
37#include <string.h>
38#include <errno.h>
39#include <ctype.h>
40#include <err.h>
41
42#include "var.h"
43#include "misc.h"
44#include "vmbuf.h"
45#include "plog.h"
46#include "debug.h"
47
48#include "localconf.h"
49#include "algorithm.h"
50#include "isakmp_var.h"
51#include "isakmp.h"
52#include "ipsec_doi.h"
53#include "grabmyaddr.h"
54#include "vendorid.h"
55#include "str2val.h"
56#include "safefile.h"
57#include "admin.h"
58#include "gcmalloc.h"
59
60struct localconf *lcconf;
61
62static void setdefault __P((void));
63static vchar_t *getpsk __P((const char *, const int));
64
65void
66initlcconf()
67{
68	lcconf = racoon_calloc(1, sizeof(*lcconf));
69	if (lcconf == NULL)
70		errx(1, "failed to allocate local conf.");
71
72	setdefault();
73
74	lcconf->racoon_conf = LC_DEFAULT_CF;
75}
76
77void
78flushlcconf()
79{
80	int i;
81
82	setdefault();
83	clear_myaddr(&lcconf->myaddrs);
84	for (i = 0; i < LC_PATHTYPE_MAX; i++) {
85		if (lcconf->pathinfo[i]) {
86			racoon_free(lcconf->pathinfo[i]);
87			lcconf->pathinfo[i] = NULL;
88		}
89	}
90	for (i = 0; i < LC_IDENTTYPE_MAX; i++) {
91		if (lcconf->ident[i])
92			vfree(lcconf->ident[i]);
93		lcconf->ident[i] = NULL;
94	}
95}
96
97static void
98setdefault()
99{
100	lcconf->autograbaddr = 1;
101	lcconf->port_isakmp = PORT_ISAKMP;
102	lcconf->default_af = AF_INET;
103	lcconf->pad_random = LC_DEFAULT_PAD_RANDOM;
104	lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN;
105	lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE;
106	lcconf->pad_strict = LC_DEFAULT_PAD_STRICT;
107	lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
108	lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER;
109	lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL;
110	lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND;
111	lcconf->secret_size = LC_DEFAULT_SECRETSIZE;
112	lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
113	lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
114	lcconf->strict_address = FALSE;
115	lcconf->complex_bundle = TRUE;
116}
117
118/*
119 * get PSK by string.
120 */
121vchar_t *
122getpskbyname(id0)
123	vchar_t *id0;
124{
125	char *id;
126	vchar_t *key = NULL;
127
128	id = racoon_calloc(1, 1 + id0->l - sizeof(struct ipsecdoi_id_b));
129	if (id == NULL) {
130		plog(LLV_ERROR, LOCATION, NULL,
131			"failed to get psk buffer.\n");
132		goto end;
133	}
134	memcpy(id, id0->v + sizeof(struct ipsecdoi_id_b),
135		id0->l - sizeof(struct ipsecdoi_id_b));
136	id[id0->l - sizeof(struct ipsecdoi_id_b)] = '\0';
137
138	key = getpsk(id, id0->l - sizeof(struct ipsecdoi_id_b));
139
140end:
141	if (id)
142		racoon_free(id);
143	return key;
144}
145
146/*
147 * get PSK by address.
148 */
149vchar_t *
150getpskbyaddr(remote)
151	struct sockaddr *remote;
152{
153	vchar_t *key = NULL;
154	char addr[NI_MAXHOST], port[NI_MAXSERV];
155
156	GETNAMEINFO(remote, addr, port);
157
158	key = getpsk(addr, strlen(addr));
159
160	return key;
161}
162
163static vchar_t *
164getpsk(str, len)
165	const char *str;
166	const int len;
167{
168	FILE *fp;
169	char buf[1024];
170	vchar_t *key = NULL;
171	char *p, *q;
172	size_t keylen;
173	char *k = NULL;
174
175	if (safefile(lcconf->pathinfo[LC_PATHTYPE_PSK], 1) == 0)
176		fp = fopen(lcconf->pathinfo[LC_PATHTYPE_PSK], "r");
177	else
178		fp = NULL;
179	if (fp == NULL) {
180		plog(LLV_ERROR, LOCATION, NULL,
181			"failed to open pre_share_key file %s\n",
182			lcconf->pathinfo[LC_PATHTYPE_PSK]);
183		return NULL;
184	}
185
186	while (fgets(buf, sizeof(buf), fp) != NULL) {
187		/* comment line */
188		if (buf[0] == '#')
189			continue;
190
191		/* search the end of 1st string. */
192		for (p = buf; *p != '\0' && !isspace(*p); p++)
193			;
194		if (*p == '\0')
195			continue;	/* no 2nd parameter */
196		*p = '\0';
197		/* search the 1st of 2nd string. */
198		while (isspace(*++p))
199			;
200		if (*p == '\0')
201			continue;	/* no 2nd parameter */
202		p--;
203		if (strncmp(buf, str, len) == 0 && buf[len] == '\0') {
204			p++;
205			keylen = 0;
206			for (q = p; *q != '\0' && *q != '\n'; q++)
207				keylen++;
208			*q = '\0';
209
210			/* fix key if hex string */
211			if (strncmp(p, "0x", 2) == 0) {
212				k = str2val(p + 2, 16, &keylen);
213				if (k == NULL) {
214					plog(LLV_ERROR, LOCATION, NULL,
215						"failed to get psk buffer.\n");
216					goto end;
217				}
218				p = k;
219			}
220
221			key = vmalloc(keylen);
222			if (key == NULL) {
223				plog(LLV_ERROR, LOCATION, NULL,
224					"failed to allocate key buffer.\n");
225				goto end;
226			}
227			memcpy(key->v, p, key->l);
228			if (k)
229				racoon_free(k);
230			goto end;
231		}
232	}
233
234end:
235	fclose(fp);
236	return key;
237}
238
239/*
240 * get a file name of a type specified.
241 */
242void
243getpathname(path, len, type, name)
244	char *path;
245	int len, type;
246	const char *name;
247{
248	snprintf(path, len, "%s%s%s",
249		name[0] == '/' ? "" : lcconf->pathinfo[type],
250		name[0] == '/' ? "" : "/",
251		name);
252
253	plog(LLV_DEBUG, LOCATION, NULL, "filename: %s\n", path);
254}
255
256
257static int lc_sittype2doi[] = {
258	IPSECDOI_SIT_IDENTITY_ONLY,
259	IPSECDOI_SIT_SECRECY,
260	IPSECDOI_SIT_INTEGRITY,
261};
262
263/*
264 * convert sittype to DOI value.
265 * OUT	-1   : NG
266 *	other: converted.
267 */
268int
269sittype2doi(sittype)
270	int sittype;
271{
272	if (ARRAYLEN(lc_sittype2doi) > sittype)
273		return lc_sittype2doi[sittype];
274	return -1;
275}
276
277static int lc_doitype2doi[] = {
278	IPSEC_DOI,
279};
280
281/*
282 * convert doitype to DOI value.
283 * OUT	-1   : NG
284 *	other: converted.
285 */
286int
287doitype2doi(doitype)
288	int doitype;
289{
290	if (ARRAYLEN(lc_doitype2doi) > doitype)
291		return lc_doitype2doi[doitype];
292	return -1;
293}
294