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