1 /* $KAME: localconf.c,v 1.33 2001/08/09 07:32:19 sakane Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
34 #include <sys/types.h>
35 #include <sys/param.h>
50 #include "localconf.h"
51 #include "algorithm.h"
54 #include "isakmp_var.h"
56 #include "ipsec_doi.h"
57 #include "grabmyaddr.h"
65 #include <CoreFoundation/CoreFoundation.h>
66 #if HAVE_SECURITY_FRAMEWORK
67 #include <Security/Security.h>
69 typedef void * SecKeychainRef
;
72 struct localconf
*lcconf
;
74 static void setdefault
__P((void));
79 lcconf
= racoon_calloc(1, sizeof(*lcconf
));
81 errx(1, "failed to allocate local conf.");
84 lcconf
->sock_vpncontrol
= -1; /* not to be done during flush */
85 lcconf
->racoon_conf
= LC_DEFAULT_CF
;
86 TAILQ_INIT(&lcconf
->saved_msg_queue
);
96 for (i
= 0; i
< LC_PATHTYPE_MAX
; i
++) {
97 if (lcconf
->pathinfo
[i
]) {
98 racoon_free(lcconf
->pathinfo
[i
]);
99 lcconf
->pathinfo
[i
] = NULL
;
102 for (i
= 0; i
< LC_IDENTTYPE_MAX
; i
++) {
103 if (lcconf
->ident
[i
])
104 vfree(lcconf
->ident
[i
]);
105 lcconf
->ident
[i
] = NULL
;
107 if (lcconf
->ext_nat_id
) {
108 vfree(lcconf
->ext_nat_id
);
109 lcconf
->ext_nat_id
= NULL
;
118 lcconf
->chroot
= NULL
;
119 lcconf
->autograbaddr
= 1;
120 lcconf
->port_isakmp
= PORT_ISAKMP
;
121 lcconf
->port_isakmp_natt
= PORT_ISAKMP_NATT
;
122 lcconf
->default_af
= AF_INET
;
123 lcconf
->pad_random
= LC_DEFAULT_PAD_RANDOM
;
124 lcconf
->pad_randomlen
= LC_DEFAULT_PAD_RANDOMLEN
;
125 lcconf
->pad_maxsize
= LC_DEFAULT_PAD_MAXSIZE
;
126 lcconf
->pad_strict
= LC_DEFAULT_PAD_STRICT
;
127 lcconf
->pad_excltail
= LC_DEFAULT_PAD_EXCLTAIL
;
128 lcconf
->retry_counter
= LC_DEFAULT_RETRY_COUNTER
;
129 lcconf
->retry_interval
= LC_DEFAULT_RETRY_INTERVAL
;
130 lcconf
->count_persend
= LC_DEFAULT_COUNT_PERSEND
;
131 lcconf
->secret_size
= LC_DEFAULT_SECRETSIZE
;
132 lcconf
->retry_checkph1
= LC_DEFAULT_RETRY_CHECKPH1
;
133 lcconf
->wait_ph2complete
= LC_DEFAULT_WAIT_PH2COMPLETE
;
134 lcconf
->strict_address
= FALSE
;
135 lcconf
->complex_bundle
= TRUE
; /*XXX FALSE;*/
136 lcconf
->gss_id_enc
= LC_GSSENC_UTF16LE
; /* Windows compatibility */
137 lcconf
->natt_ka_interval
= LC_DEFAULT_NATT_KA_INTERVAL
;
138 lcconf
->auto_exit_delay
= 0;
139 lcconf
->auto_exit_state
&= ~LC_AUTOEXITSTATE_SET
;
140 lcconf
->auto_exit_state
|= LC_AUTOEXITSTATE_CLIENT
; /* always auto exit as default */
153 plog(LLV_DEBUG
, LOCATION
, NULL
, "Getting pre-shared key by name.\n");
155 id
= racoon_calloc(1, 1 + id0
->l
- sizeof(struct ipsecdoi_id_b
));
157 plog(LLV_ERROR
, LOCATION
, NULL
,
158 "failed to get psk buffer.\n");
161 memcpy(id
, id0
->v
+ sizeof(struct ipsecdoi_id_b
),
162 id0
->l
- sizeof(struct ipsecdoi_id_b
));
163 id
[id0
->l
- sizeof(struct ipsecdoi_id_b
)] = '\0';
166 key
= privsep_getpsk(id
, id0
->l
- sizeof(struct ipsecdoi_id_b
));
168 key
= getpsk(id
, id0
->l
- sizeof(struct ipsecdoi_id_b
));
179 * get PSK from keyChain.
182 getpskfromkeychain(const char *name
, u_int8_t etype
, int secrettype
, vchar_t
*id_p
)
184 SecKeychainRef keychain
= NULL
;
186 void *cur_password
= NULL
;
187 UInt32 cur_password_len
= 0;
189 char serviceName
[] = "com.apple.net.racoon";
191 plog(LLV_DEBUG
, LOCATION
, NULL
, "Getting pre-shared key from keychain.\n");
193 status
= SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem
);
194 if (status
!= noErr
) {
195 plog(LLV_ERROR
, LOCATION
, NULL
,
196 "failed to set system keychain domain.\n");
200 status
= SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem
,
202 if (status
!= noErr
) {
203 plog(LLV_ERROR
, LOCATION
, NULL
,
204 "failed to get system keychain domain.\n");
208 if (secrettype
== SECRETTYPE_KEYCHAIN_BY_ID
&& etype
== ISAKMP_ETYPE_AGG
) {
209 /* try looking up based on peers id */
211 char* peer_id
= NULL
;
212 int idlen
= id_p
->l
- sizeof(struct ipsecdoi_id_b
);
213 u_int8_t id_type
= ((struct ipsecdoi_id_b
*)(id_p
->v
))->type
;
216 case IPSECDOI_ID_IPV4_ADDR
:
217 case IPSECDOI_ID_IPV6_ADDR
:
218 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
219 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
220 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
221 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
222 case IPSECDOI_ID_DER_ASN1_DN
:
223 case IPSECDOI_ID_DER_ASN1_GN
:
227 case IPSECDOI_ID_FQDN
:
228 case IPSECDOI_ID_USER_FQDN
:
229 case IPSECDOI_ID_KEY_ID
:
230 peer_id
= racoon_malloc(1 + idlen
);
233 memcpy(peer_id
, id_p
->v
+ sizeof(struct ipsecdoi_id_b
), idlen
);
234 *(peer_id
+ idlen
) = '\0';
235 plog(LLV_ERROR
, LOCATION
, NULL
,
236 "getting shared secret from keychain using %s.\n", peer_id
);
244 status
= SecKeychainFindGenericPassword(keychain
,
253 /* try find it using using only the peer id. */
254 if (status
== errSecItemNotFound
)
255 status
= SecKeychainFindGenericPassword(keychain
,
264 racoon_free(peer_id
);
267 /* otherwise fall through to use the default value */
271 /* use the value in remote config sharedsecret field
272 this is either the value specified for lookup or the
273 default when lookup by id fails.
275 status
= SecKeychainFindGenericPassword(keychain
,
284 /* try find it using using only name. */
285 if (status
== errSecItemNotFound
)
286 status
= SecKeychainFindGenericPassword(keychain
,
301 case errSecItemNotFound
:
305 plog(LLV_ERROR
, LOCATION
, NULL
,
306 "failed to get preshared key from system keychain (error %d).\n", status
);
312 key
= vmalloc(cur_password_len
);
314 plog(LLV_ERROR
, LOCATION
, NULL
,
315 "failed to allocate key buffer.\n");
317 memcpy(key
->v
, cur_password
, cur_password_len
);
329 * get PSK by address.
333 struct sockaddr
*remote
;
336 char addr
[NI_MAXHOST
], port
[NI_MAXSERV
];
338 plog(LLV_DEBUG
, LOCATION
, NULL
, "Getting pre-shared key by addr.\n");
340 GETNAMEINFO(remote
, addr
, port
);
343 key
= privsep_getpsk(addr
, strlen(addr
));
345 key
= getpsk(addr
, strlen(addr
));
357 char buf
[1024]; /* XXX how is variable length ? */
363 plog(LLV_DEBUG
, LOCATION
, NULL
, "Getting pre-shared key from file.\n");
365 if (safefile(lcconf
->pathinfo
[LC_PATHTYPE_PSK
], 1) == 0)
366 fp
= fopen(lcconf
->pathinfo
[LC_PATHTYPE_PSK
], "r");
370 plog(LLV_ERROR
, LOCATION
, NULL
,
371 "failed to open pre_share_key file %s\n",
372 lcconf
->pathinfo
[LC_PATHTYPE_PSK
]);
376 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
381 /* search the end of 1st string. */
382 for (p
= buf
; *p
!= '\0' && !isspace((int)*p
); p
++)
385 continue; /* no 2nd parameter */
387 /* search the 1st of 2nd string. */
388 while (isspace((int)*++p
))
391 continue; /* no 2nd parameter */
393 if (strncmp(buf
, str
, len
) == 0 && buf
[len
] == '\0') {
396 for (q
= p
; *q
!= '\0' && *q
!= '\n'; q
++)
400 /* fix key if hex string */
401 if (strncmp(p
, "0x", 2) == 0) {
402 k
= str2val(p
+ 2, 16, &keylen
);
404 plog(LLV_ERROR
, LOCATION
, NULL
,
405 "failed to get psk buffer.\n");
411 key
= vmalloc(keylen
);
413 plog(LLV_ERROR
, LOCATION
, NULL
,
414 "failed to allocate key buffer.\n");
417 memcpy(key
->v
, p
, key
->l
);
430 * get a file name of a type specified.
433 getpathname(path
, len
, type
, name
)
438 snprintf(path
, len
, "%s%s%s",
439 name
[0] == '/' ? "" : lcconf
->pathinfo
[type
],
440 name
[0] == '/' ? "" : "/",
443 plog(LLV_DEBUG
, LOCATION
, NULL
, "filename: %s\n", path
);
447 static int lc_doi2idtype
[] = {
451 LC_IDENTTYPE_USERFQDN
,
457 LC_IDENTTYPE_CERTNAME
,
463 * convert DOI value to idtype
471 if (ARRAYLEN(lc_doi2idtype
) > idtype
)
472 return lc_doi2idtype
[idtype
];
477 static int lc_sittype2doi
[] = {
478 IPSECDOI_SIT_IDENTITY_ONLY
,
479 IPSECDOI_SIT_SECRECY
,
480 IPSECDOI_SIT_INTEGRITY
,
484 * convert sittype to DOI value.
492 if (ARRAYLEN(lc_sittype2doi
) > sittype
)
493 return lc_sittype2doi
[sittype
];
497 static int lc_doitype2doi
[] = {
502 * convert doitype to DOI value.
510 if (ARRAYLEN(lc_doitype2doi
) > doitype
)
511 return lc_doitype2doi
[doitype
];