]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/localconf.c
87ba373971efc83f3a78c61dea4a66a02f230611
[apple/network_cmds.git] / racoon.tproj / localconf.c
1
2 /* $KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <ctype.h>
41 #include <err.h>
42
43 #include "var.h"
44 #include "misc.h"
45 #include "vmbuf.h"
46 #include "plog.h"
47 #include "debug.h"
48
49 #include "localconf.h"
50 #include "algorithm.h"
51 #include "isakmp_var.h"
52 #include "isakmp.h"
53 #include "ipsec_doi.h"
54 #include "grabmyaddr.h"
55 #include "vendorid.h"
56 #include "str2val.h"
57 #include "safefile.h"
58 #include "admin.h"
59 #include "gcmalloc.h"
60
61 #include <CoreFoundation/CoreFoundation.h>
62 #include <Security/Security.h>
63
64 struct localconf *lcconf;
65
66 static void setdefault __P((void));
67
68 void
69 initlcconf()
70 {
71 lcconf = racoon_calloc(1, sizeof(*lcconf));
72 if (lcconf == NULL)
73 errx(1, "failed to allocate local conf.");
74
75 setdefault();
76
77 lcconf->racoon_conf = LC_DEFAULT_CF;
78 }
79
80 void
81 flushlcconf()
82 {
83 int i;
84
85 setdefault();
86 clear_myaddr(&lcconf->myaddrs);
87 for (i = 0; i < LC_PATHTYPE_MAX; i++) {
88 if (lcconf->pathinfo[i]) {
89 racoon_free(lcconf->pathinfo[i]);
90 lcconf->pathinfo[i] = NULL;
91 }
92 }
93 for (i = 0; i < LC_IDENTTYPE_MAX; i++) {
94 if (lcconf->ident[i])
95 vfree(lcconf->ident[i]);
96 lcconf->ident[i] = NULL;
97 }
98 }
99
100 static void
101 setdefault()
102 {
103 lcconf->autograbaddr = 1;
104 lcconf->port_isakmp = PORT_ISAKMP;
105 lcconf->default_af = AF_INET;
106 lcconf->pad_random = LC_DEFAULT_PAD_RANDOM;
107 lcconf->pad_randomlen = LC_DEFAULT_PAD_RANDOMLEN;
108 lcconf->pad_maxsize = LC_DEFAULT_PAD_MAXSIZE;
109 lcconf->pad_strict = LC_DEFAULT_PAD_STRICT;
110 lcconf->pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
111 lcconf->retry_counter = LC_DEFAULT_RETRY_COUNTER;
112 lcconf->retry_interval = LC_DEFAULT_RETRY_INTERVAL;
113 lcconf->count_persend = LC_DEFAULT_COUNT_PERSEND;
114 lcconf->secret_size = LC_DEFAULT_SECRETSIZE;
115 lcconf->retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
116 lcconf->wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
117 lcconf->strict_address = FALSE;
118 lcconf->complex_bundle = TRUE; /*XXX FALSE;*/
119 }
120
121 /*
122 * get PSK by string.
123 */
124 vchar_t *
125 getpskbyname(id0)
126 vchar_t *id0;
127 {
128 char *id;
129 vchar_t *key = NULL;
130
131 id = racoon_calloc(1, 1 + id0->l - sizeof(struct ipsecdoi_id_b));
132 if (id == NULL) {
133 plog(LLV_ERROR, LOCATION, NULL,
134 "failed to get psk buffer.\n");
135 goto end;
136 }
137 memcpy(id, id0->v + sizeof(struct ipsecdoi_id_b),
138 id0->l - sizeof(struct ipsecdoi_id_b));
139 id[id0->l - sizeof(struct ipsecdoi_id_b)] = '\0';
140
141 key = getpsk(id, id0->l - sizeof(struct ipsecdoi_id_b));
142
143 end:
144 if (id)
145 racoon_free(id);
146 return key;
147 }
148
149 /*
150 * get PSK from keyChain.
151 */
152 vchar_t *
153 getpskfromkeychain(const char *name)
154 {
155 SecKeychainRef keychain = NULL;
156 vchar_t *key = NULL;
157 void *cur_password = NULL;
158 UInt32 cur_password_len = 0;
159 OSStatus status;
160 char serviceName[] = "com.apple.net.racoon";
161
162 status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
163 if (status != noErr) {
164 plog(LLV_ERROR, LOCATION, NULL,
165 "failed to set system keychain domain.\n");
166 goto end;
167 }
168
169 status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem,
170 &keychain);
171 if (status != noErr) {
172 plog(LLV_ERROR, LOCATION, NULL,
173 "failed to get system keychain domain.\n");
174 goto end;
175 }
176
177 status = SecKeychainFindGenericPassword(keychain,
178 strlen(serviceName),
179 serviceName,
180 strlen(name),
181 name,
182 &cur_password_len,
183 &cur_password,
184 NULL);
185
186 switch (status) {
187
188 case noErr :
189 break;
190
191 case errSecItemNotFound :
192 break;
193
194 default :
195 plog(LLV_ERROR, LOCATION, NULL,
196 "failed to get preshared key from system keychain (error %d).\n", status);
197 }
198
199 end:
200
201 if (cur_password) {
202 key = vmalloc(cur_password_len + 1);
203 if (key == NULL) {
204 plog(LLV_ERROR, LOCATION, NULL,
205 "failed to allocate key buffer.\n");
206 }
207 else {
208 memcpy(key->v, cur_password, key->l);
209 key->v[cur_password_len] = 0;
210 }
211 free(cur_password);
212 }
213
214 if (keychain)
215 CFRelease(keychain);
216
217 return key;
218 }
219
220 /*
221 * get PSK by address.
222 */
223 vchar_t *
224 getpskbyaddr(remote)
225 struct sockaddr *remote;
226 {
227 vchar_t *key = NULL;
228 char addr[NI_MAXHOST], port[NI_MAXSERV];
229
230 GETNAMEINFO(remote, addr, port);
231
232 key = getpsk(addr, strlen(addr));
233
234 return key;
235 }
236
237 vchar_t *
238 getpsk(str, len)
239 const char *str;
240 const int len;
241 {
242 FILE *fp;
243 char buf[1024]; /* XXX how is variable length ? */
244 vchar_t *key = NULL;
245 char *p, *q;
246 size_t keylen;
247 char *k = NULL;
248
249 if (safefile(lcconf->pathinfo[LC_PATHTYPE_PSK], 1) == 0)
250 fp = fopen(lcconf->pathinfo[LC_PATHTYPE_PSK], "r");
251 else
252 fp = NULL;
253 if (fp == NULL) {
254 plog(LLV_ERROR, LOCATION, NULL,
255 "failed to open pre_share_key file %s\n",
256 lcconf->pathinfo[LC_PATHTYPE_PSK]);
257 return NULL;
258 }
259
260 while (fgets(buf, sizeof(buf), fp) != NULL) {
261 /* comment line */
262 if (buf[0] == '#')
263 continue;
264
265 /* search the end of 1st string. */
266 for (p = buf; *p != '\0' && !isspace(*p); p++)
267 ;
268 if (*p == '\0')
269 continue; /* no 2nd parameter */
270 *p = '\0';
271 /* search the 1st of 2nd string. */
272 while (isspace(*++p))
273 ;
274 if (*p == '\0')
275 continue; /* no 2nd parameter */
276 p--;
277
278 if (strncmp(buf, str, len) == 0 && buf[len] == '\0') {
279 p++;
280 keylen = 0;
281 for (q = p; *q != '\0' && *q != '\n'; q++)
282 keylen++;
283 *q = '\0';
284
285 /* fix key if hex string */
286 if (strncmp(p, "0x", 2) == 0) {
287 k = str2val(p + 2, 16, &keylen);
288 if (k == NULL) {
289 plog(LLV_ERROR, LOCATION, NULL,
290 "failed to get psk buffer.\n");
291 goto end;
292 }
293 p = k;
294 }
295
296 key = vmalloc(keylen);
297 if (key == NULL) {
298 plog(LLV_ERROR, LOCATION, NULL,
299 "failed to allocate key buffer.\n");
300 goto end;
301 }
302 memcpy(key->v, p, key->l);
303 if (k)
304 racoon_free(k);
305 goto end;
306 }
307 }
308
309 end:
310 fclose(fp);
311 return key;
312 }
313
314 /*
315 * get a file name of a type specified.
316 */
317 void
318 getpathname(path, len, type, name)
319 char *path;
320 int len, type;
321 const char *name;
322 {
323 snprintf(path, len, "%s%s%s",
324 name[0] == '/' ? "" : lcconf->pathinfo[type],
325 name[0] == '/' ? "" : "/",
326 name);
327
328 plog(LLV_DEBUG, LOCATION, NULL, "filename: %s\n", path);
329 }
330
331 #if 0 /* DELETEIT */
332 static int lc_doi2idtype[] = {
333 -1,
334 -1,
335 LC_IDENTTYPE_FQDN,
336 LC_IDENTTYPE_USERFQDN,
337 -1,
338 -1,
339 -1,
340 -1,
341 -1,
342 LC_IDENTTYPE_CERTNAME,
343 -1,
344 LC_IDENTTYPE_KEYID,
345 };
346
347 /*
348 * convert DOI value to idtype
349 * OUT -1 : NG
350 * other: converted.
351 */
352 int
353 doi2idtype(idtype)
354 int idtype;
355 {
356 if (ARRAYLEN(lc_doi2idtype) > idtype)
357 return lc_doi2idtype[idtype];
358 return -1;
359 }
360 #endif
361
362 static int lc_sittype2doi[] = {
363 IPSECDOI_SIT_IDENTITY_ONLY,
364 IPSECDOI_SIT_SECRECY,
365 IPSECDOI_SIT_INTEGRITY,
366 };
367
368 /*
369 * convert sittype to DOI value.
370 * OUT -1 : NG
371 * other: converted.
372 */
373 int
374 sittype2doi(sittype)
375 int sittype;
376 {
377 if (ARRAYLEN(lc_sittype2doi) > sittype)
378 return lc_sittype2doi[sittype];
379 return -1;
380 }
381
382 static int lc_doitype2doi[] = {
383 IPSEC_DOI,
384 };
385
386 /*
387 * convert doitype to DOI value.
388 * OUT -1 : NG
389 * other: converted.
390 */
391 int
392 doitype2doi(doitype)
393 int doitype;
394 {
395 if (ARRAYLEN(lc_doitype2doi) > doitype)
396 return lc_doitype2doi[doitype];
397 return -1;
398 }
399