1 /* $NetBSD: localconf.c,v 1.8 2012/01/01 15:29:28 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 = NULL; 67 68 static void setdefault __P((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 = 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(id0) 170 vchar_t *id0; 171 { 172 char *id; 173 vchar_t *key = NULL; 174 175 id = racoon_calloc(1, 1 + id0->l - sizeof(struct ipsecdoi_id_b)); 176 if (id == NULL) { 177 plog(LLV_ERROR, LOCATION, NULL, 178 "failed to get psk buffer.\n"); 179 goto end; 180 } 181 memcpy(id, id0->v + sizeof(struct ipsecdoi_id_b), 182 id0->l - sizeof(struct ipsecdoi_id_b)); 183 id[id0->l - sizeof(struct ipsecdoi_id_b)] = '\0'; 184 185 key = privsep_getpsk(id, id0->l - sizeof(struct ipsecdoi_id_b)); 186 187 end: 188 if (id) 189 racoon_free(id); 190 return key; 191 } 192 193 /* 194 * get PSK by address. 195 */ 196 vchar_t * 197 getpskbyaddr(remote) 198 struct sockaddr *remote; 199 { 200 vchar_t *key = NULL; 201 char addr[NI_MAXHOST], port[NI_MAXSERV]; 202 203 GETNAMEINFO(remote, addr, port); 204 205 key = privsep_getpsk(addr, strlen(addr)); 206 207 return key; 208 } 209 210 vchar_t * 211 getpsk(str, len) 212 const char *str; 213 const int len; 214 { 215 FILE *fp; 216 char buf[1024]; /* XXX how is variable length ? */ 217 vchar_t *key = NULL; 218 char *p, *q; 219 size_t keylen; 220 char *k = NULL; 221 222 if (safefile(lcconf->pathinfo[LC_PATHTYPE_PSK], 1) == 0) 223 fp = fopen(lcconf->pathinfo[LC_PATHTYPE_PSK], "r"); 224 else 225 fp = NULL; 226 if (fp == NULL) { 227 plog(LLV_ERROR, LOCATION, NULL, 228 "failed to open pre_share_key file %s\n", 229 lcconf->pathinfo[LC_PATHTYPE_PSK]); 230 return NULL; 231 } 232 233 while (fgets(buf, sizeof(buf), fp) != NULL) { 234 /* comment line */ 235 if (buf[0] == '#') 236 continue; 237 238 /* search the end of 1st string. */ 239 for (p = buf; *p != '\0' && !isspace((int)*p); p++) 240 ; 241 if (*p == '\0') 242 continue; /* no 2nd parameter */ 243 *p = '\0'; 244 /* search the 1st of 2nd string. */ 245 while (isspace((int)*++p)) 246 ; 247 if (*p == '\0') 248 continue; /* no 2nd parameter */ 249 p--; 250 if (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(path, len, type, name) 291 char *path; 292 int len, type; 293 const char *name; 294 { 295 snprintf(path, len, "%s%s%s", 296 name[0] == '/' ? "" : lcconf->pathinfo[type], 297 name[0] == '/' ? "" : "/", 298 name); 299 300 plog(LLV_DEBUG, LOCATION, NULL, "filename: %s\n", path); 301 } 302 303 #if 0 /* DELETEIT */ 304 static int lc_doi2idtype[] = { 305 -1, 306 -1, 307 LC_IDENTTYPE_FQDN, 308 LC_IDENTTYPE_USERFQDN, 309 -1, 310 -1, 311 -1, 312 -1, 313 -1, 314 LC_IDENTTYPE_CERTNAME, 315 -1, 316 LC_IDENTTYPE_KEYID, 317 }; 318 319 /* 320 * convert DOI value to idtype 321 * OUT -1 : NG 322 * other: converted. 323 */ 324 int 325 doi2idtype(idtype) 326 int idtype; 327 { 328 if (ARRAYLEN(lc_doi2idtype) > idtype) 329 return lc_doi2idtype[idtype]; 330 return -1; 331 } 332 #endif 333 334 static int lc_sittype2doi[] = { 335 IPSECDOI_SIT_IDENTITY_ONLY, 336 IPSECDOI_SIT_SECRECY, 337 IPSECDOI_SIT_INTEGRITY, 338 }; 339 340 /* 341 * convert sittype to DOI value. 342 * OUT -1 : NG 343 * other: converted. 344 */ 345 int 346 sittype2doi(sittype) 347 int sittype; 348 { 349 if (ARRAYLEN(lc_sittype2doi) > sittype) 350 return lc_sittype2doi[sittype]; 351 return -1; 352 } 353 354 static int lc_doitype2doi[] = { 355 IPSEC_DOI, 356 }; 357 358 /* 359 * convert doitype to DOI value. 360 * OUT -1 : NG 361 * other: converted. 362 */ 363 int 364 doitype2doi(doitype) 365 int doitype; 366 { 367 if (ARRAYLEN(lc_doitype2doi) > doitype) 368 return lc_doitype2doi[doitype]; 369 return -1; 370 } 371 372 373 374 static void 375 saverestore_params(f) 376 int f; 377 { 378 static u_int16_t s_port_isakmp; 379 380 /* 0: save, 1: restore */ 381 if (f) { 382 lcconf->port_isakmp = s_port_isakmp; 383 } else { 384 s_port_isakmp = lcconf->port_isakmp; 385 } 386 } 387 388 void 389 restore_params() 390 { 391 saverestore_params(1); 392 } 393 394 void 395 save_params() 396 { 397 saverestore_params(0); 398 } 399