1 /* $NetBSD: isakmp_cfg.c,v 1.31 2025/03/08 16:39:08 christos Exp $ */ 2 3 /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */ 4 5 /* 6 * Copyright (C) 2004-2006 Emmanuel Dreyfus 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 #include <sys/socket.h> 39 #include <sys/queue.h> 40 41 #include <utmpx.h> 42 #if defined(__APPLE__) && defined(__MACH__) 43 #include <util.h> 44 #endif 45 46 #ifdef __FreeBSD__ 47 # include <libutil.h> 48 #endif 49 #ifdef __NetBSD__ 50 # include <util.h> 51 #endif 52 53 #include <netinet/in.h> 54 #include <arpa/inet.h> 55 56 #include <stdlib.h> 57 #include <stdio.h> 58 #include <string.h> 59 #include <errno.h> 60 #if TIME_WITH_SYS_TIME 61 # include <sys/time.h> 62 # include <time.h> 63 #else 64 # if HAVE_SYS_TIME_H 65 # include <sys/time.h> 66 # else 67 # include <time.h> 68 # endif 69 #endif 70 #include <netdb.h> 71 #ifdef HAVE_UNISTD_H 72 #include <unistd.h> 73 #endif 74 #if HAVE_STDINT_H 75 #include <stdint.h> 76 #endif 77 #include <ctype.h> 78 #include <resolv.h> 79 80 #ifdef HAVE_LIBRADIUS 81 #include <sys/utsname.h> 82 #include <radlib.h> 83 #endif 84 85 #include "var.h" 86 #include "misc.h" 87 #include "vmbuf.h" 88 #include "plog.h" 89 #include "sockmisc.h" 90 #include "schedule.h" 91 #include "debug.h" 92 93 #include "isakmp_var.h" 94 #include "isakmp.h" 95 #include "handler.h" 96 #include "evt.h" 97 #include "throttle.h" 98 #include "remoteconf.h" 99 #include "crypto_openssl.h" 100 #include "isakmp_inf.h" 101 #include "isakmp_xauth.h" 102 #include "isakmp_unity.h" 103 #include "isakmp_cfg.h" 104 #include "strnames.h" 105 #include "admin.h" 106 #include "privsep.h" 107 108 struct isakmp_cfg_config isakmp_cfg_config; 109 110 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append); 111 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *); 112 #if 0 113 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); 114 #endif 115 static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 116 struct isakmp_data *, in_addr_t *); 117 static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *, 118 struct isakmp_data *, in_addr_t *, in_addr_t *); 119 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *); 120 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *, 121 struct isakmp_data *, in_addr_t *, int); 122 static void isakmp_cfg_appendaddr4(struct isakmp_data *, 123 struct in_addr *, int *, int); 124 static void isakmp_cfg_getstring(struct isakmp_data *,char *); 125 static void isakmp_cfg_iplist_to_str(char *, int, void *, int); 126 127 #define ISAKMP_CFG_LOGIN 1 128 #define ISAKMP_CFG_LOGOUT 2 129 static int isakmp_cfg_accounting(struct ph1handle *, int); 130 #ifdef HAVE_LIBRADIUS 131 static int isakmp_cfg_accounting_radius(struct ph1handle *, int); 132 #endif 133 134 /* 135 * Handle an ISAKMP config mode packet 136 * We expect HDR, HASH, ATTR 137 */ 138 void 139 isakmp_cfg_r(struct ph1handle *iph1, vchar_t *msg) 140 { 141 struct isakmp *packet; 142 struct isakmp_gen *ph; 143 size_t tlen; 144 char *npp; 145 int np; 146 vchar_t *dmsg; 147 struct isakmp_ivm *ivm; 148 149 /* Check that the packet is long enough to have a header */ 150 if (msg->l < sizeof(*packet)) { 151 plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n"); 152 return; 153 } 154 155 packet = (struct isakmp *)msg->v; 156 157 /* Is it encrypted? It should be encrypted */ 158 if ((packet->flags & ISAKMP_FLAG_E) == 0) { 159 plog(LLV_ERROR, LOCATION, NULL, 160 "User credentials sent in cleartext!\n"); 161 return; 162 } 163 164 /* 165 * Decrypt the packet. If this is the beginning of a new 166 * exchange, reinitialize the IV 167 */ 168 if (iph1->mode_cfg->ivm == NULL || 169 iph1->mode_cfg->last_msgid != packet->msgid ) 170 iph1->mode_cfg->ivm = 171 isakmp_cfg_newiv(iph1, packet->msgid); 172 ivm = iph1->mode_cfg->ivm; 173 174 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive); 175 if (dmsg == NULL) { 176 plog(LLV_ERROR, LOCATION, NULL, 177 "failed to decrypt message\n"); 178 return; 179 } 180 181 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n"); 182 plogdump(LLV_DEBUG, dmsg->v, dmsg->l); 183 184 /* Now work with the decrypted packet */ 185 packet = (struct isakmp *)dmsg->v; 186 tlen = dmsg->l - sizeof(*packet); 187 ph = (struct isakmp_gen *)(packet + 1); 188 189 np = packet->np; 190 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) { 191 /* Check that the payload header fits in the packet */ 192 if (tlen < sizeof(*ph)) { 193 plog(LLV_WARNING, LOCATION, NULL, 194 "Short payload header\n"); 195 goto out; 196 } 197 198 /* Check that the payload fits in the packet */ 199 if (tlen < ntohs(ph->len)) { 200 plog(LLV_WARNING, LOCATION, NULL, 201 "Short payload\n"); 202 goto out; 203 } 204 205 plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np); 206 plogdump(LLV_DEBUG, ph, ntohs(ph->len)); 207 208 switch(np) { 209 case ISAKMP_NPTYPE_HASH: { 210 vchar_t *check; 211 vchar_t *payload; 212 size_t plen; 213 struct isakmp_gen *nph; 214 215 plen = ntohs(ph->len); 216 nph = (struct isakmp_gen *)((char *)ph + plen); 217 plen = ntohs(nph->len); 218 219 if ((payload = vmalloc(plen)) == NULL) { 220 plog(LLV_ERROR, LOCATION, NULL, 221 "Cannot allocate memory\n"); 222 goto out; 223 } 224 memcpy(payload->v, nph, plen); 225 226 if ((check = oakley_compute_hash1(iph1, 227 packet->msgid, payload)) == NULL) { 228 plog(LLV_ERROR, LOCATION, NULL, 229 "Cannot compute hash\n"); 230 vfree(payload); 231 goto out; 232 } 233 234 if (memcmp(ph + 1, check->v, check->l) != 0) { 235 plog(LLV_ERROR, LOCATION, NULL, 236 "Hash verification failed\n"); 237 vfree(payload); 238 vfree(check); 239 goto out; 240 } 241 vfree(payload); 242 vfree(check); 243 break; 244 } 245 case ISAKMP_NPTYPE_ATTR: { 246 struct isakmp_pl_attr *attrpl; 247 248 attrpl = (struct isakmp_pl_attr *)ph; 249 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl); 250 251 break; 252 } 253 default: 254 plog(LLV_WARNING, LOCATION, NULL, 255 "Unexpected next payload %d\n", np); 256 /* Skip to the next payload */ 257 break; 258 } 259 260 /* Move to the next payload */ 261 np = ph->np; 262 tlen -= ntohs(ph->len); 263 npp = (char *)ph; 264 ph = (struct isakmp_gen *)(npp + ntohs(ph->len)); 265 } 266 267 out: 268 vfree(dmsg); 269 } 270 271 int 272 isakmp_cfg_attr_r(struct ph1handle *iph1, uint32_t msgid, 273 struct isakmp_pl_attr *attrpl) 274 { 275 int type = attrpl->type; 276 277 plog(LLV_DEBUG, LOCATION, NULL, 278 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type)); 279 switch (type) { 280 case ISAKMP_CFG_ACK: 281 /* ignore, but this is the time to reinit the IV */ 282 oakley_delivm(iph1->mode_cfg->ivm); 283 iph1->mode_cfg->ivm = NULL; 284 return 0; 285 286 case ISAKMP_CFG_REPLY: 287 return isakmp_cfg_reply(iph1, attrpl); 288 289 case ISAKMP_CFG_REQUEST: 290 iph1->msgid = msgid; 291 return isakmp_cfg_request(iph1, attrpl); 292 293 case ISAKMP_CFG_SET: 294 iph1->msgid = msgid; 295 return isakmp_cfg_set(iph1, attrpl); 296 297 default: 298 plog(LLV_WARNING, LOCATION, NULL, 299 "Unepected configuration exchange type %d\n", type); 300 return -1; 301 } 302 } 303 304 int 305 isakmp_cfg_reply(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl) 306 { 307 struct isakmp_data *attr; 308 size_t tlen; 309 size_t alen; 310 char *npp; 311 int type; 312 int error; 313 314 tlen = ntohs(attrpl->h.len); 315 attr = (struct isakmp_data *)(attrpl + 1); 316 tlen -= sizeof(*attrpl); 317 318 while (tlen > 0) { 319 type = ntohs(attr->type); 320 321 /* Handle short attributes */ 322 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 323 type &= ~ISAKMP_GEN_MASK; 324 325 plog(LLV_DEBUG, LOCATION, NULL, 326 "Short attribute %s = %d\n", 327 s_isakmp_cfg_type(type), ntohs(attr->lorv)); 328 329 switch (type) { 330 case XAUTH_TYPE: 331 if ((error = xauth_attr_reply(iph1, 332 attr, ntohs(attrpl->id))) != 0) 333 return error; 334 break; 335 336 default: 337 plog(LLV_WARNING, LOCATION, NULL, 338 "Ignored short attribute %s\n", 339 s_isakmp_cfg_type(type)); 340 break; 341 } 342 343 tlen -= sizeof(*attr); 344 attr++; 345 continue; 346 } 347 348 type = ntohs(attr->type); 349 alen = ntohs(attr->lorv); 350 351 /* Check that the attribute fit in the packet */ 352 if (tlen < alen) { 353 plog(LLV_ERROR, LOCATION, NULL, 354 "Short attribute %s\n", 355 s_isakmp_cfg_type(type)); 356 return -1; 357 } 358 359 plog(LLV_DEBUG, LOCATION, NULL, 360 "Attribute %s, len %zu\n", 361 s_isakmp_cfg_type(type), alen); 362 363 switch(type) { 364 case XAUTH_TYPE: 365 case XAUTH_USER_NAME: 366 case XAUTH_USER_PASSWORD: 367 case XAUTH_PASSCODE: 368 case XAUTH_MESSAGE: 369 case XAUTH_CHALLENGE: 370 case XAUTH_DOMAIN: 371 case XAUTH_STATUS: 372 case XAUTH_NEXT_PIN: 373 case XAUTH_ANSWER: 374 if ((error = xauth_attr_reply(iph1, 375 attr, ntohs(attrpl->id))) != 0) 376 return error; 377 break; 378 case INTERNAL_IP4_ADDRESS: 379 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4); 380 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4; 381 break; 382 case INTERNAL_IP4_NETMASK: 383 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4); 384 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; 385 break; 386 case INTERNAL_IP4_DNS: 387 isakmp_cfg_appendaddr4(attr, 388 &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index], 389 &iph1->mode_cfg->dns4_index, MAXNS); 390 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4; 391 break; 392 case INTERNAL_IP4_NBNS: 393 isakmp_cfg_appendaddr4(attr, 394 &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index], 395 &iph1->mode_cfg->wins4_index, MAXNS); 396 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4; 397 break; 398 case UNITY_DEF_DOMAIN: 399 isakmp_cfg_getstring(attr, 400 iph1->mode_cfg->default_domain); 401 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN; 402 break; 403 case UNITY_SPLIT_INCLUDE: 404 case UNITY_LOCAL_LAN: 405 case UNITY_SPLITDNS_NAME: 406 case UNITY_BANNER: 407 case UNITY_SAVE_PASSWD: 408 case UNITY_NATT_PORT: 409 case UNITY_PFS: 410 case UNITY_FW_TYPE: 411 case UNITY_BACKUP_SERVERS: 412 case UNITY_DDNS_HOSTNAME: 413 isakmp_unity_reply(iph1, attr); 414 break; 415 case INTERNAL_IP4_SUBNET: 416 case INTERNAL_ADDRESS_EXPIRY: 417 default: 418 plog(LLV_WARNING, LOCATION, NULL, 419 "Ignored attribute %s\n", 420 s_isakmp_cfg_type(type)); 421 break; 422 } 423 424 npp = (char *)attr; 425 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); 426 tlen -= (sizeof(*attr) + alen); 427 } 428 429 /* 430 * Call the SA up script hook now that we have the configuration 431 * It is done at the end of phase 1 if ISAKMP mode config is not 432 * requested. 433 */ 434 435 if ((iph1->status == PHASE1ST_ESTABLISHED) && 436 iph1->rmconf->mode_cfg) { 437 switch (iph1->approval->authmethod) { 438 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I: 439 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 440 /* Unimplemented */ 441 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 442 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: 443 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 444 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 445 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 446 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 447 script_hook(iph1, SCRIPT_PHASE1_UP); 448 break; 449 default: 450 break; 451 } 452 } 453 454 455 #ifdef ENABLE_ADMINPORT 456 { 457 vchar_t *buf; 458 459 alen = ntohs(attrpl->h.len) - sizeof(*attrpl); 460 if ((buf = vmalloc(alen)) == NULL) { 461 plog(LLV_WARNING, LOCATION, NULL, 462 "Cannot allocate memory: %s\n", strerror(errno)); 463 } else { 464 memcpy(buf->v, attrpl + 1, buf->l); 465 evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf); 466 vfree(buf); 467 } 468 } 469 #endif 470 471 return 0; 472 } 473 474 int 475 isakmp_cfg_request(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl) 476 { 477 struct isakmp_data *attr; 478 size_t tlen; 479 size_t alen; 480 char *npp; 481 vchar_t *payload; 482 struct isakmp_pl_attr *reply; 483 vchar_t *reply_attr; 484 int type; 485 int error = -1; 486 487 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 488 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 489 return -1; 490 } 491 memset(payload->v, 0, sizeof(*reply)); 492 493 tlen = ntohs(attrpl->h.len); 494 attr = (struct isakmp_data *)(attrpl + 1); 495 tlen -= sizeof(*attrpl); 496 497 while (tlen > 0) { 498 reply_attr = NULL; 499 type = ntohs(attr->type); 500 501 /* Handle short attributes */ 502 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 503 type &= ~ISAKMP_GEN_MASK; 504 505 plog(LLV_DEBUG, LOCATION, NULL, 506 "Short attribute %s = %d\n", 507 s_isakmp_cfg_type(type), ntohs(attr->lorv)); 508 509 switch (type) { 510 case XAUTH_TYPE: 511 reply_attr = isakmp_xauth_req(iph1, attr); 512 break; 513 default: 514 plog(LLV_WARNING, LOCATION, NULL, 515 "Ignored short attribute %s\n", 516 s_isakmp_cfg_type(type)); 517 break; 518 } 519 520 tlen -= sizeof(*attr); 521 attr++; 522 523 if (reply_attr != NULL) { 524 payload = buffer_cat(payload, reply_attr); 525 vfree(reply_attr); 526 } 527 528 continue; 529 } 530 531 type = ntohs(attr->type); 532 alen = ntohs(attr->lorv); 533 534 /* Check that the attribute fit in the packet */ 535 if (tlen < alen) { 536 plog(LLV_ERROR, LOCATION, NULL, 537 "Short attribute %s\n", 538 s_isakmp_cfg_type(type)); 539 goto end; 540 } 541 542 plog(LLV_DEBUG, LOCATION, NULL, 543 "Attribute %s, len %zu\n", 544 s_isakmp_cfg_type(type), alen); 545 546 switch(type) { 547 case INTERNAL_IP4_ADDRESS: 548 case INTERNAL_IP4_NETMASK: 549 case INTERNAL_IP4_DNS: 550 case INTERNAL_IP4_NBNS: 551 case INTERNAL_IP4_SUBNET: 552 reply_attr = isakmp_cfg_net(iph1, attr); 553 break; 554 555 case XAUTH_TYPE: 556 case XAUTH_USER_NAME: 557 case XAUTH_USER_PASSWORD: 558 case XAUTH_PASSCODE: 559 case XAUTH_MESSAGE: 560 case XAUTH_CHALLENGE: 561 case XAUTH_DOMAIN: 562 case XAUTH_STATUS: 563 case XAUTH_NEXT_PIN: 564 case XAUTH_ANSWER: 565 reply_attr = isakmp_xauth_req(iph1, attr); 566 break; 567 568 case APPLICATION_VERSION: 569 reply_attr = isakmp_cfg_string(iph1, 570 attr, ISAKMP_CFG_RACOON_VERSION); 571 break; 572 573 case UNITY_BANNER: 574 case UNITY_PFS: 575 case UNITY_SAVE_PASSWD: 576 case UNITY_DEF_DOMAIN: 577 case UNITY_DDNS_HOSTNAME: 578 case UNITY_FW_TYPE: 579 case UNITY_SPLITDNS_NAME: 580 case UNITY_SPLIT_INCLUDE: 581 case UNITY_LOCAL_LAN: 582 case UNITY_NATT_PORT: 583 case UNITY_BACKUP_SERVERS: 584 reply_attr = isakmp_unity_req(iph1, attr); 585 break; 586 587 case INTERNAL_ADDRESS_EXPIRY: 588 default: 589 plog(LLV_WARNING, LOCATION, NULL, 590 "Ignored attribute %s\n", 591 s_isakmp_cfg_type(type)); 592 break; 593 } 594 595 npp = (char *)attr; 596 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); 597 tlen -= (sizeof(*attr) + alen); 598 599 if (reply_attr != NULL) { 600 payload = buffer_cat(payload, reply_attr); 601 vfree(reply_attr); 602 } 603 604 } 605 606 reply = (struct isakmp_pl_attr *)payload->v; 607 reply->h.len = htons(payload->l); 608 reply->type = ISAKMP_CFG_REPLY; 609 reply->id = attrpl->id; 610 611 plog(LLV_DEBUG, LOCATION, NULL, 612 "Sending MODE_CFG REPLY\n"); 613 614 error = isakmp_cfg_send(iph1, payload, 615 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 616 617 if (iph1->status == PHASE1ST_ESTABLISHED) { 618 switch (iph1->approval->authmethod) { 619 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 620 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 621 /* Unimplemented */ 622 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 623 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 624 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 625 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 626 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 627 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 628 script_hook(iph1, SCRIPT_PHASE1_UP); 629 break; 630 default: 631 break; 632 } 633 } 634 635 end: 636 vfree(payload); 637 638 return error; 639 } 640 641 int 642 isakmp_cfg_set(struct ph1handle *iph1, struct isakmp_pl_attr *attrpl) 643 { 644 struct isakmp_data *attr; 645 size_t tlen; 646 size_t alen; 647 char *npp; 648 vchar_t *payload; 649 struct isakmp_pl_attr *reply; 650 vchar_t *reply_attr; 651 int type; 652 int error = -1; 653 654 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 655 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 656 return -1; 657 } 658 memset(payload->v, 0, sizeof(*reply)); 659 660 tlen = ntohs(attrpl->h.len); 661 attr = (struct isakmp_data *)(attrpl + 1); 662 tlen -= sizeof(*attrpl); 663 664 /* 665 * We should send ack for the attributes we accepted 666 */ 667 while (tlen > 0) { 668 reply_attr = NULL; 669 type = ntohs(attr->type); 670 671 plog(LLV_DEBUG, LOCATION, NULL, 672 "Attribute %s\n", 673 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); 674 675 switch (type & ~ISAKMP_GEN_MASK) { 676 case XAUTH_STATUS: 677 reply_attr = isakmp_xauth_set(iph1, attr); 678 break; 679 default: 680 plog(LLV_DEBUG, LOCATION, NULL, 681 "Unexpected SET attribute %s\n", 682 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); 683 break; 684 } 685 686 if (reply_attr != NULL) { 687 payload = buffer_cat(payload, reply_attr); 688 vfree(reply_attr); 689 } 690 691 /* 692 * Move to next attribute. If we run out of the packet, 693 * tlen becomes negative and we exit. 694 */ 695 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 696 tlen -= sizeof(*attr); 697 attr++; 698 } else { 699 alen = ntohs(attr->lorv); 700 tlen -= (sizeof(*attr) + alen); 701 npp = (char *)attr; 702 attr = (struct isakmp_data *) 703 (npp + sizeof(*attr) + alen); 704 } 705 } 706 707 reply = (struct isakmp_pl_attr *)payload->v; 708 reply->h.len = htons(payload->l); 709 reply->type = ISAKMP_CFG_ACK; 710 reply->id = attrpl->id; 711 712 plog(LLV_DEBUG, LOCATION, NULL, 713 "Sending MODE_CFG ACK\n"); 714 715 error = isakmp_cfg_send(iph1, payload, 716 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 717 718 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) { 719 if (iph1->status == PHASE1ST_ESTABLISHED || 720 iph1->status == PHASE1ST_DYING) 721 isakmp_info_send_d1(iph1); 722 remph1(iph1); 723 delph1(iph1); 724 iph1 = NULL; 725 } 726 727 vfree(payload); 728 729 /* 730 * If required, request ISAKMP mode config information 731 */ 732 if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0)) 733 error = isakmp_cfg_getconfig(iph1); 734 735 return error; 736 } 737 738 739 static vchar_t * 740 buffer_cat(vchar_t *s, vchar_t *append) 741 { 742 vchar_t *new; 743 744 new = vmalloc(s->l + append->l); 745 if (new == NULL) { 746 plog(LLV_ERROR, LOCATION, NULL, 747 "Cannot allocate memory\n"); 748 return s; 749 } 750 751 memcpy(new->v, s->v, s->l); 752 memcpy(new->v + s->l, append->v, append->l); 753 754 vfree(s); 755 return new; 756 } 757 758 static vchar_t * 759 isakmp_cfg_net(struct ph1handle *iph1, struct isakmp_data *attr) 760 { 761 int type; 762 int confsource; 763 764 type = ntohs(attr->type); 765 766 /* 767 * Don't give an address to a peer that did not succeed Xauth 768 */ 769 if (xauth_check(iph1) != 0) { 770 plog(LLV_ERROR, LOCATION, NULL, 771 "Attempt to start phase config whereas Xauth failed\n"); 772 return NULL; 773 } 774 775 confsource = isakmp_cfg_config.confsource; 776 /* 777 * If we have to fall back to a local 778 * configuration source, we will jump 779 * back to this point. 780 */ 781 retry_source: 782 783 switch(type) { 784 case INTERNAL_IP4_ADDRESS: 785 switch(confsource) { 786 #ifdef HAVE_LIBLDAP 787 case ISAKMP_CFG_CONF_LDAP: 788 if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) 789 break; 790 plog(LLV_INFO, LOCATION, NULL, 791 "No IP from LDAP, using local pool\n"); 792 /* FALLTHROUGH */ 793 confsource = ISAKMP_CFG_CONF_LOCAL; 794 goto retry_source; 795 #endif 796 #ifdef HAVE_LIBRADIUS 797 case ISAKMP_CFG_CONF_RADIUS: 798 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) 799 && (iph1->mode_cfg->addr4.s_addr != htonl(-2))) 800 /* 801 * -2 is 255.255.255.254, RADIUS uses that 802 * to instruct the NAS to use a local pool 803 */ 804 break; 805 plog(LLV_INFO, LOCATION, NULL, 806 "No IP from RADIUS, using local pool\n"); 807 /* FALLTHROUGH */ 808 confsource = ISAKMP_CFG_CONF_LOCAL; 809 goto retry_source; 810 #endif 811 case ISAKMP_CFG_CONF_LOCAL: 812 if (isakmp_cfg_getport(iph1) == -1) { 813 plog(LLV_ERROR, LOCATION, NULL, 814 "Port pool depleted\n"); 815 break; 816 } 817 818 iph1->mode_cfg->addr4.s_addr = 819 htonl(ntohl(isakmp_cfg_config.network4) 820 + iph1->mode_cfg->port); 821 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL; 822 break; 823 824 default: 825 plog(LLV_ERROR, LOCATION, NULL, 826 "Unexpected confsource\n"); 827 } 828 829 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0) 830 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); 831 832 return isakmp_cfg_addr4(iph1, 833 attr, &iph1->mode_cfg->addr4.s_addr); 834 835 case INTERNAL_IP4_NETMASK: 836 switch(confsource) { 837 #ifdef HAVE_LIBLDAP 838 case ISAKMP_CFG_CONF_LDAP: 839 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) 840 break; 841 plog(LLV_INFO, LOCATION, NULL, 842 "No mask from LDAP, using local pool\n"); 843 /* FALLTHROUGH */ 844 confsource = ISAKMP_CFG_CONF_LOCAL; 845 goto retry_source; 846 #endif 847 #ifdef HAVE_LIBRADIUS 848 case ISAKMP_CFG_CONF_RADIUS: 849 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN) 850 break; 851 plog(LLV_INFO, LOCATION, NULL, 852 "No mask from RADIUS, using local pool\n"); 853 /* FALLTHROUGH */ 854 confsource = ISAKMP_CFG_CONF_LOCAL; 855 goto retry_source; 856 #endif 857 case ISAKMP_CFG_CONF_LOCAL: 858 iph1->mode_cfg->mask4.s_addr 859 = isakmp_cfg_config.netmask4; 860 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL; 861 break; 862 863 default: 864 plog(LLV_ERROR, LOCATION, NULL, 865 "Unexpected confsource\n"); 866 } 867 return isakmp_cfg_addr4(iph1, attr, 868 &iph1->mode_cfg->mask4.s_addr); 869 870 case INTERNAL_IP4_DNS: 871 return isakmp_cfg_addr4_list(iph1, 872 attr, &isakmp_cfg_config.dns4[0], 873 isakmp_cfg_config.dns4_index); 874 875 case INTERNAL_IP4_NBNS: 876 return isakmp_cfg_addr4_list(iph1, 877 attr, &isakmp_cfg_config.nbns4[0], 878 isakmp_cfg_config.nbns4_index); 879 880 case INTERNAL_IP4_SUBNET: 881 if(isakmp_cfg_config.splitnet_count > 0){ 882 return isakmp_cfg_addrnet4(iph1, attr, 883 &isakmp_cfg_config.splitnet_list->network.addr4.s_addr, 884 &isakmp_cfg_config.splitnet_list->network.mask4.s_addr); 885 }else{ 886 plog(LLV_INFO, LOCATION, NULL, 887 "%s requested but no splitnet in configuration\n", 888 s_isakmp_cfg_type(type)); 889 } 890 break; 891 892 default: 893 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); 894 break; 895 } 896 return NULL; 897 } 898 899 #if 0 900 static vchar_t * 901 isakmp_cfg_void(struct ph1handle *iph1, struct isakmp_data *attr) 902 { 903 vchar_t *buffer; 904 struct isakmp_data *new; 905 906 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 907 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 908 return NULL; 909 } 910 911 new = (struct isakmp_data *)buffer->v; 912 913 new->type = attr->type; 914 new->lorv = htons(0); 915 916 return buffer; 917 } 918 #endif 919 920 /*ARGSUSED*/ 921 vchar_t * 922 isakmp_cfg_copy(struct ph1handle *iph1 __unused, struct isakmp_data *attr) 923 { 924 vchar_t *buffer; 925 size_t len = 0; 926 927 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV) 928 len = ntohs(attr->lorv); 929 930 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 931 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 932 return NULL; 933 } 934 935 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv)); 936 937 return buffer; 938 } 939 940 /*ARGSUSED*/ 941 vchar_t * 942 isakmp_cfg_short(struct ph1handle *iph1 __unused, struct isakmp_data *attr, int value) 943 { 944 vchar_t *buffer; 945 struct isakmp_data *new; 946 int type; 947 948 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 949 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 950 return NULL; 951 } 952 953 new = (struct isakmp_data *)buffer->v; 954 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; 955 956 new->type = htons(type | ISAKMP_GEN_TV); 957 new->lorv = htons(value); 958 959 return buffer; 960 } 961 962 /*ARGSUSED*/ 963 vchar_t * 964 isakmp_cfg_varlen(struct ph1handle *iph1 __unused, struct isakmp_data *attr, 965 const char *string, size_t len) 966 { 967 vchar_t *buffer; 968 struct isakmp_data *new; 969 char *data; 970 971 if (!len) 972 return NULL; 973 974 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 975 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 976 return NULL; 977 } 978 979 new = (struct isakmp_data *)buffer->v; 980 981 new->type = attr->type; 982 new->lorv = htons(len); 983 data = (char *)(new + 1); 984 985 memcpy(data, string, len); 986 987 return buffer; 988 } 989 990 vchar_t * 991 isakmp_cfg_string(struct ph1handle *iph1, struct isakmp_data *attr, 992 const char *string) 993 { 994 size_t len = strlen(string); 995 return isakmp_cfg_varlen(iph1, attr, string, len); 996 } 997 998 /*ARGSUSED*/ 999 static vchar_t * 1000 isakmp_cfg_addr4(struct ph1handle *iph1 __unused, struct isakmp_data *attr, 1001 in_addr_t *addr) 1002 { 1003 vchar_t *buffer; 1004 struct isakmp_data *new; 1005 size_t len; 1006 1007 len = sizeof(*addr); 1008 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 1009 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1010 return NULL; 1011 } 1012 1013 new = (struct isakmp_data *)buffer->v; 1014 1015 new->type = attr->type; 1016 new->lorv = htons(len); 1017 memcpy(new + 1, addr, len); 1018 1019 return buffer; 1020 } 1021 1022 /*ARGSUSED*/ 1023 static vchar_t * 1024 isakmp_cfg_addrnet4(struct ph1handle *iph1 __unused, struct isakmp_data *attr, 1025 in_addr_t *addr, in_addr_t *mask) 1026 { 1027 vchar_t *buffer; 1028 struct isakmp_data *new; 1029 size_t len; 1030 in_addr_t netbuff[2]; 1031 1032 len = sizeof(netbuff); 1033 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 1034 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1035 return NULL; 1036 } 1037 1038 new = (struct isakmp_data *)buffer->v; 1039 1040 new->type = attr->type; 1041 new->lorv = htons(len); 1042 netbuff[0]=*addr; 1043 netbuff[1]=*mask; 1044 memcpy(new + 1, netbuff, len); 1045 1046 return buffer; 1047 } 1048 1049 1050 /*ARGSUSED*/ 1051 static vchar_t * 1052 isakmp_cfg_addr4_list(struct ph1handle *iph1 __unused, struct isakmp_data *attr, 1053 in_addr_t *addr, int nbr) 1054 { 1055 int error = -1; 1056 vchar_t *buffer = NULL; 1057 vchar_t *bufone = NULL; 1058 struct isakmp_data *new; 1059 size_t len; 1060 int i; 1061 1062 len = sizeof(*addr); 1063 if ((buffer = vmalloc(0)) == NULL) { 1064 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1065 goto out; 1066 } 1067 for(i = 0; i < nbr; i++) { 1068 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) { 1069 plog(LLV_ERROR, LOCATION, NULL, 1070 "Cannot allocate memory\n"); 1071 goto out; 1072 } 1073 new = (struct isakmp_data *)bufone->v; 1074 new->type = attr->type; 1075 new->lorv = htons(len); 1076 memcpy(new + 1, &addr[i], len); 1077 new += (len + sizeof(*attr)); 1078 buffer = buffer_cat(buffer, bufone); 1079 vfree(bufone); 1080 } 1081 1082 error = 0; 1083 1084 out: 1085 if ((error != 0) && (buffer != NULL)) { 1086 vfree(buffer); 1087 buffer = NULL; 1088 } 1089 1090 return buffer; 1091 } 1092 1093 struct isakmp_ivm * 1094 isakmp_cfg_newiv(struct ph1handle *iph1, uint32_t msgid) 1095 { 1096 struct isakmp_cfg_state *ics = iph1->mode_cfg; 1097 1098 if (ics == NULL) { 1099 plog(LLV_ERROR, LOCATION, NULL, 1100 "isakmp_cfg_newiv called without mode config state\n"); 1101 return NULL; 1102 } 1103 1104 if (ics->ivm != NULL) 1105 oakley_delivm(ics->ivm); 1106 1107 ics->ivm = oakley_newiv2(iph1, msgid); 1108 ics->last_msgid = msgid; 1109 1110 return ics->ivm; 1111 } 1112 1113 /* Derived from isakmp_info_send_common */ 1114 int 1115 isakmp_cfg_send(struct ph1handle *iph1, vchar_t *payload, uint32_t np, 1116 int flags, int new_exchange) 1117 { 1118 struct ph2handle *iph2 = NULL; 1119 vchar_t *hash = NULL; 1120 struct isakmp *isakmp; 1121 struct isakmp_gen *gen; 1122 char *p; 1123 size_t tlen; 1124 int error = -1; 1125 struct isakmp_cfg_state *ics = iph1->mode_cfg; 1126 1127 /* Check if phase 1 is established */ 1128 if ((iph1->status < PHASE1ST_ESTABLISHED) || 1129 (iph1->local == NULL) || 1130 (iph1->remote == NULL)) { 1131 plog(LLV_ERROR, LOCATION, NULL, 1132 "ISAKMP mode config exchange with immature phase 1\n"); 1133 goto end; 1134 } 1135 1136 /* add new entry to isakmp status table */ 1137 iph2 = newph2(); 1138 if (iph2 == NULL) 1139 goto end; 1140 1141 iph2->dst = dupsaddr(iph1->remote); 1142 if (iph2->dst == NULL) { 1143 delph2(iph2); 1144 goto end; 1145 } 1146 iph2->src = dupsaddr(iph1->local); 1147 if (iph2->src == NULL) { 1148 delph2(iph2); 1149 goto end; 1150 } 1151 1152 iph2->side = INITIATOR; 1153 iph2->status = PHASE2ST_START; 1154 1155 if (new_exchange) 1156 iph2->msgid = isakmp_newmsgid2(iph1); 1157 else 1158 iph2->msgid = iph1->msgid; 1159 1160 /* get IV and HASH(1) if skeyid_a was generated. */ 1161 if (iph1->skeyid_a != NULL) { 1162 if (new_exchange) { 1163 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) { 1164 delph2(iph2); 1165 goto end; 1166 } 1167 } 1168 1169 /* generate HASH(1) */ 1170 hash = oakley_compute_hash1(iph1, iph2->msgid, payload); 1171 if (hash == NULL) { 1172 delph2(iph2); 1173 goto end; 1174 } 1175 1176 /* initialized total buffer length */ 1177 tlen = hash->l; 1178 tlen += sizeof(*gen); 1179 } else { 1180 /* IKE-SA is not established */ 1181 hash = NULL; 1182 1183 /* initialized total buffer length */ 1184 tlen = 0; 1185 } 1186 if ((flags & ISAKMP_FLAG_A) == 0) 1187 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 1188 else 1189 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 1190 1191 insph2(iph2); 1192 bindph12(iph1, iph2); 1193 1194 tlen += sizeof(*isakmp) + payload->l; 1195 1196 /* create buffer for isakmp payload */ 1197 iph2->sendbuf = vmalloc(tlen); 1198 if (iph2->sendbuf == NULL) { 1199 plog(LLV_ERROR, LOCATION, NULL, 1200 "failed to get buffer to send.\n"); 1201 goto err; 1202 } 1203 1204 /* create isakmp header */ 1205 isakmp = (struct isakmp *)iph2->sendbuf->v; 1206 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 1207 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 1208 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 1209 isakmp->v = iph1->version; 1210 isakmp->etype = ISAKMP_ETYPE_CFG; 1211 isakmp->flags = iph2->flags; 1212 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 1213 isakmp->len = htonl(tlen); 1214 p = (char *)(isakmp + 1); 1215 1216 /* create HASH payload */ 1217 if (hash != NULL) { 1218 gen = (struct isakmp_gen *)p; 1219 gen->np = np & 0xff; 1220 gen->len = htons(sizeof(*gen) + hash->l); 1221 p += sizeof(*gen); 1222 memcpy(p, hash->v, hash->l); 1223 p += hash->l; 1224 } 1225 1226 /* add payload */ 1227 memcpy(p, payload->v, payload->l); 1228 p += payload->l; 1229 1230 #ifdef HAVE_PRINT_ISAKMP_C 1231 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 1232 #endif 1233 1234 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n"); 1235 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l); 1236 1237 /* encoding */ 1238 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 1239 vchar_t *tmp; 1240 1241 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 1242 ics->ivm->ive, ics->ivm->iv); 1243 VPTRINIT(iph2->sendbuf); 1244 if (tmp == NULL) 1245 goto err; 1246 iph2->sendbuf = tmp; 1247 } 1248 1249 /* HDR*, HASH(1), ATTR */ 1250 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 1251 VPTRINIT(iph2->sendbuf); 1252 goto err; 1253 } 1254 1255 plog(LLV_DEBUG, LOCATION, NULL, 1256 "sendto mode config %s.\n", s_isakmp_nptype(np)); 1257 1258 /* 1259 * XXX We might need to resend the message... 1260 */ 1261 1262 error = 0; 1263 VPTRINIT(iph2->sendbuf); 1264 1265 err: 1266 if (iph2->sendbuf != NULL) 1267 vfree(iph2->sendbuf); 1268 1269 remph2(iph2); 1270 delph2(iph2); 1271 end: 1272 if (hash) 1273 vfree(hash); 1274 return error; 1275 } 1276 1277 1278 void 1279 isakmp_cfg_rmstate(struct ph1handle *iph1) 1280 { 1281 struct isakmp_cfg_state *state = iph1->mode_cfg; 1282 1283 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0) 1284 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); 1285 1286 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED) 1287 isakmp_cfg_putport(iph1, state->port); 1288 1289 /* Delete the IV if it's still there */ 1290 if(iph1->mode_cfg->ivm) { 1291 oakley_delivm(iph1->mode_cfg->ivm); 1292 iph1->mode_cfg->ivm = NULL; 1293 } 1294 1295 /* Free any allocated splitnet lists */ 1296 if(iph1->mode_cfg->split_include != NULL) 1297 splitnet_list_free(iph1->mode_cfg->split_include, 1298 &iph1->mode_cfg->include_count); 1299 if(iph1->mode_cfg->split_local != NULL) 1300 splitnet_list_free(iph1->mode_cfg->split_local, 1301 &iph1->mode_cfg->local_count); 1302 1303 xauth_rmstate(&state->xauth); 1304 1305 racoon_free(state); 1306 iph1->mode_cfg = NULL; 1307 1308 return; 1309 } 1310 1311 struct isakmp_cfg_state * 1312 isakmp_cfg_mkstate(void) 1313 { 1314 struct isakmp_cfg_state *state; 1315 1316 if ((state = racoon_malloc(sizeof(*state))) == NULL) { 1317 plog(LLV_ERROR, LOCATION, NULL, 1318 "Cannot allocate memory for mode config state\n"); 1319 return NULL; 1320 } 1321 memset(state, 0, sizeof(*state)); 1322 1323 return state; 1324 } 1325 1326 int 1327 isakmp_cfg_getport(struct ph1handle *iph1) 1328 { 1329 unsigned int i; 1330 size_t size = isakmp_cfg_config.pool_size; 1331 1332 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED) 1333 return iph1->mode_cfg->port; 1334 1335 if (isakmp_cfg_config.port_pool == NULL) { 1336 plog(LLV_ERROR, LOCATION, NULL, 1337 "isakmp_cfg_config.port_pool == NULL\n"); 1338 return -1; 1339 } 1340 1341 for (i = 0; i < size; i++) { 1342 if (isakmp_cfg_config.port_pool[i].used == 0) 1343 break; 1344 } 1345 1346 if (i == size) { 1347 plog(LLV_ERROR, LOCATION, NULL, 1348 "No more addresses available\n"); 1349 return -1; 1350 } 1351 1352 isakmp_cfg_config.port_pool[i].used = 1; 1353 1354 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i); 1355 1356 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED; 1357 iph1->mode_cfg->port = i; 1358 1359 return i; 1360 } 1361 1362 int 1363 isakmp_cfg_putport(struct ph1handle *iph1, unsigned int index) 1364 { 1365 if (isakmp_cfg_config.port_pool == NULL) { 1366 plog(LLV_ERROR, LOCATION, NULL, 1367 "isakmp_cfg_config.port_pool == NULL\n"); 1368 return -1; 1369 } 1370 1371 if (isakmp_cfg_config.port_pool[index].used == 0) { 1372 plog(LLV_ERROR, LOCATION, NULL, 1373 "Attempt to release an unallocated address (port %d)\n", 1374 index); 1375 return -1; 1376 } 1377 1378 #ifdef HAVE_LIBPAM 1379 /* Cleanup PAM status associated with the port */ 1380 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM) 1381 privsep_cleanup_pam(index); 1382 #endif 1383 isakmp_cfg_config.port_pool[index].used = 0; 1384 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED; 1385 1386 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index); 1387 1388 return 0; 1389 } 1390 1391 #ifdef HAVE_LIBPAM 1392 void 1393 cleanup_pam(int port) 1394 { 1395 if (isakmp_cfg_config.port_pool[port].pam != NULL) { 1396 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS); 1397 isakmp_cfg_config.port_pool[port].pam = NULL; 1398 } 1399 1400 return; 1401 } 1402 #endif 1403 1404 /* Accounting, only for RADIUS or PAM */ 1405 static int 1406 isakmp_cfg_accounting(struct ph1handle *iph1, int inout) 1407 { 1408 #ifdef HAVE_LIBPAM 1409 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM) 1410 return privsep_accounting_pam(iph1->mode_cfg->port, 1411 inout); 1412 #endif 1413 #ifdef HAVE_LIBRADIUS 1414 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) 1415 return isakmp_cfg_accounting_radius(iph1, inout); 1416 #endif 1417 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM) 1418 return privsep_accounting_system(iph1->mode_cfg->port, 1419 iph1->remote, iph1->mode_cfg->login, inout); 1420 return 0; 1421 } 1422 1423 #ifdef HAVE_LIBPAM 1424 int 1425 isakmp_cfg_accounting_pam(int port, int inout) 1426 { 1427 int error = 0; 1428 pam_handle_t *pam; 1429 1430 if (isakmp_cfg_config.port_pool == NULL) { 1431 plog(LLV_ERROR, LOCATION, NULL, 1432 "isakmp_cfg_config.port_pool == NULL\n"); 1433 return -1; 1434 } 1435 1436 pam = isakmp_cfg_config.port_pool[port].pam; 1437 if (pam == NULL) { 1438 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n"); 1439 return -1; 1440 } 1441 1442 switch (inout) { 1443 case ISAKMP_CFG_LOGIN: 1444 error = pam_open_session(pam, 0); 1445 break; 1446 case ISAKMP_CFG_LOGOUT: 1447 error = pam_close_session(pam, 0); 1448 pam_end(pam, error); 1449 isakmp_cfg_config.port_pool[port].pam = NULL; 1450 break; 1451 default: 1452 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1453 break; 1454 } 1455 1456 if (error != 0) { 1457 plog(LLV_ERROR, LOCATION, NULL, 1458 "pam_open_session/pam_close_session failed: %s\n", 1459 pam_strerror(pam, error)); 1460 return -1; 1461 } 1462 1463 return 0; 1464 } 1465 #endif /* HAVE_LIBPAM */ 1466 1467 #ifdef HAVE_LIBRADIUS 1468 static int 1469 isakmp_cfg_accounting_radius(struct ph1handle *iph1, int inout) 1470 { 1471 if (rad_create_request(radius_acct_state, 1472 RAD_ACCOUNTING_REQUEST) != 0) { 1473 plog(LLV_ERROR, LOCATION, NULL, 1474 "rad_create_request failed: %s\n", 1475 rad_strerror(radius_acct_state)); 1476 return -1; 1477 } 1478 1479 if (rad_put_string(radius_acct_state, RAD_USER_NAME, 1480 iph1->mode_cfg->login) != 0) { 1481 plog(LLV_ERROR, LOCATION, NULL, 1482 "rad_put_string failed: %s\n", 1483 rad_strerror(radius_acct_state)); 1484 return -1; 1485 } 1486 1487 switch (inout) { 1488 case ISAKMP_CFG_LOGIN: 1489 inout = RAD_START; 1490 break; 1491 case ISAKMP_CFG_LOGOUT: 1492 inout = RAD_STOP; 1493 break; 1494 default: 1495 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1496 break; 1497 } 1498 1499 if (rad_put_addr(radius_acct_state, 1500 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) { 1501 plog(LLV_ERROR, LOCATION, NULL, 1502 "rad_put_addr failed: %s\n", 1503 rad_strerror(radius_acct_state)); 1504 return -1; 1505 } 1506 1507 if (rad_put_addr(radius_acct_state, 1508 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) { 1509 plog(LLV_ERROR, LOCATION, NULL, 1510 "rad_put_addr failed: %s\n", 1511 rad_strerror(radius_acct_state)); 1512 return -1; 1513 } 1514 1515 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) { 1516 plog(LLV_ERROR, LOCATION, NULL, 1517 "rad_put_int failed: %s\n", 1518 rad_strerror(radius_acct_state)); 1519 return -1; 1520 } 1521 1522 if (isakmp_cfg_radius_common(radius_acct_state, 1523 iph1->mode_cfg->port) != 0) 1524 return -1; 1525 1526 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) { 1527 plog(LLV_ERROR, LOCATION, NULL, 1528 "rad_send_request failed: %s\n", 1529 rad_strerror(radius_acct_state)); 1530 return -1; 1531 } 1532 1533 return 0; 1534 } 1535 #endif /* HAVE_LIBRADIUS */ 1536 1537 /* 1538 * Attributes common to all RADIUS requests 1539 */ 1540 #ifdef HAVE_LIBRADIUS 1541 int 1542 isakmp_cfg_radius_common(struct rad_handle *radius_state, int port) 1543 { 1544 struct utsname name; 1545 static struct hostent *host = NULL; 1546 struct in_addr nas_addr; 1547 1548 /* 1549 * Find our own IP by resolving our nodename 1550 */ 1551 if (host == NULL) { 1552 if (uname(&name) != 0) { 1553 plog(LLV_ERROR, LOCATION, NULL, 1554 "uname failed: %s\n", strerror(errno)); 1555 return -1; 1556 } 1557 1558 if ((host = gethostbyname(name.nodename)) == NULL) { 1559 plog(LLV_ERROR, LOCATION, NULL, 1560 "gethostbyname failed: %s\n", strerror(errno)); 1561 return -1; 1562 } 1563 } 1564 1565 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr)); 1566 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) { 1567 plog(LLV_ERROR, LOCATION, NULL, 1568 "rad_put_addr failed: %s\n", 1569 rad_strerror(radius_state)); 1570 return -1; 1571 } 1572 1573 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) { 1574 plog(LLV_ERROR, LOCATION, NULL, 1575 "rad_put_int failed: %s\n", 1576 rad_strerror(radius_state)); 1577 return -1; 1578 } 1579 1580 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) { 1581 plog(LLV_ERROR, LOCATION, NULL, 1582 "rad_put_int failed: %s\n", 1583 rad_strerror(radius_state)); 1584 return -1; 1585 } 1586 1587 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) { 1588 plog(LLV_ERROR, LOCATION, NULL, 1589 "rad_put_int failed: %s\n", 1590 rad_strerror(radius_state)); 1591 return -1; 1592 } 1593 1594 return 0; 1595 } 1596 #endif 1597 1598 /* 1599 Logs the user into the utmp system files. 1600 */ 1601 1602 int 1603 isakmp_cfg_accounting_system(int port, struct sockaddr *raddr, char *usr, 1604 int inout) 1605 { 1606 struct utmpx ut; 1607 char addr[NI_MAXHOST]; 1608 1609 if (usr == NULL || usr[0]=='\0') { 1610 plog(LLV_ERROR, LOCATION, NULL, 1611 "system accounting : no login found\n"); 1612 return -1; 1613 } 1614 1615 memset(&ut, 0, sizeof ut); 1616 gettimeofday((struct timeval *)&ut.ut_tv, NULL); 1617 snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port); 1618 1619 switch (inout) { 1620 case ISAKMP_CFG_LOGIN: 1621 ut.ut_type = USER_PROCESS; 1622 strncpy(ut.ut_user, usr, sizeof ut.ut_user); 1623 1624 GETNAMEINFO_NULL(raddr, addr); 1625 strncpy(ut.ut_host, addr, sizeof ut.ut_host); 1626 1627 plog(LLV_INFO, LOCATION, NULL, 1628 "Accounting : '%s' logging on '%s' from %s.\n", 1629 ut.ut_user, ut.ut_id, addr); 1630 1631 pututxline(&ut); 1632 1633 break; 1634 case ISAKMP_CFG_LOGOUT: 1635 ut.ut_type = DEAD_PROCESS; 1636 1637 plog(LLV_INFO, LOCATION, NULL, 1638 "Accounting : '%s' unlogging from '%s'.\n", 1639 usr, ut.ut_id); 1640 1641 pututxline(&ut); 1642 1643 break; 1644 default: 1645 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1646 break; 1647 } 1648 1649 return 0; 1650 } 1651 1652 int 1653 isakmp_cfg_getconfig(struct ph1handle *iph1) 1654 { 1655 vchar_t *buffer; 1656 struct isakmp_pl_attr *attrpl; 1657 struct isakmp_data *attr; 1658 size_t len; 1659 int error; 1660 int attrcount; 1661 int i; 1662 int attrlist[] = { 1663 INTERNAL_IP4_ADDRESS, 1664 INTERNAL_IP4_NETMASK, 1665 INTERNAL_IP4_DNS, 1666 INTERNAL_IP4_NBNS, 1667 UNITY_BANNER, 1668 UNITY_DEF_DOMAIN, 1669 UNITY_SPLITDNS_NAME, 1670 UNITY_SPLIT_INCLUDE, 1671 UNITY_LOCAL_LAN, 1672 APPLICATION_VERSION, 1673 }; 1674 1675 attrcount = sizeof(attrlist) / sizeof(*attrlist); 1676 len = sizeof(*attrpl) + sizeof(*attr) * attrcount; 1677 1678 if ((buffer = vmalloc(len)) == NULL) { 1679 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1680 return -1; 1681 } 1682 1683 attrpl = (struct isakmp_pl_attr *)buffer->v; 1684 attrpl->h.len = htons(len); 1685 attrpl->type = ISAKMP_CFG_REQUEST; 1686 attrpl->id = htons((uint16_t)(eay_random() & 0xffff)); 1687 1688 attr = (struct isakmp_data *)(attrpl + 1); 1689 1690 for (i = 0; i < attrcount; i++) { 1691 attr->type = htons(attrlist[i]); 1692 attr->lorv = htons(0); 1693 attr++; 1694 } 1695 1696 plog(LLV_DEBUG, LOCATION, NULL, 1697 "Sending MODE_CFG REQUEST\n"); 1698 1699 error = isakmp_cfg_send(iph1, buffer, 1700 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); 1701 1702 vfree(buffer); 1703 1704 return error; 1705 } 1706 1707 static void 1708 isakmp_cfg_getaddr4(struct isakmp_data *attr, struct in_addr *ip) 1709 { 1710 size_t alen = ntohs(attr->lorv); 1711 in_addr_t *addr; 1712 1713 if (alen != sizeof(*ip)) { 1714 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); 1715 return; 1716 } 1717 1718 addr = (in_addr_t *)(attr + 1); 1719 ip->s_addr = *addr; 1720 1721 return; 1722 } 1723 1724 static void 1725 isakmp_cfg_appendaddr4(struct isakmp_data *attr, struct in_addr *ip, 1726 int *num, int max) 1727 { 1728 size_t alen = ntohs(attr->lorv); 1729 in_addr_t *addr; 1730 1731 if (alen != sizeof(*ip)) { 1732 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); 1733 return; 1734 } 1735 if (*num == max) { 1736 plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n"); 1737 return; 1738 } 1739 1740 addr = (in_addr_t *)(attr + 1); 1741 ip->s_addr = *addr; 1742 (*num)++; 1743 1744 return; 1745 } 1746 1747 static void 1748 isakmp_cfg_getstring(struct isakmp_data *attr, char *str) 1749 { 1750 size_t alen = ntohs(attr->lorv); 1751 char *src; 1752 src = (char *)(attr + 1); 1753 1754 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen)); 1755 1756 return; 1757 } 1758 1759 #define IP_MAX 40 1760 1761 void 1762 isakmp_cfg_iplist_to_str(char *dest, int count, void *addr, int withmask) 1763 { 1764 int i; 1765 size_t p; 1766 int l; 1767 struct unity_network tmp; 1768 for(i = 0, p = 0; i < count; i++) { 1769 if(withmask == 1) 1770 l = sizeof(struct unity_network); 1771 else 1772 l = sizeof(struct in_addr); 1773 memcpy(&tmp, addr, l); 1774 addr = (char *)addr + l; 1775 if((uint32_t)tmp.addr4.s_addr == 0) 1776 break; 1777 1778 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX); 1779 p += strlen(dest + p); 1780 if(withmask == 1) { 1781 dest[p] = '/'; 1782 p++; 1783 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX); 1784 p += strlen(dest + p); 1785 } 1786 dest[p] = ' '; 1787 p++; 1788 } 1789 if(p > 0) 1790 dest[p-1] = '\0'; 1791 else 1792 dest[0] = '\0'; 1793 } 1794 1795 int 1796 isakmp_cfg_setenv(struct ph1handle *iph1, char ***envp, int *envc) 1797 { 1798 char addrstr[IP_MAX]; 1799 char addrlist[IP_MAX * MAXNS + MAXNS]; 1800 char *splitlist = addrlist; 1801 char *splitlist_cidr; 1802 char defdom[MAXPATHLEN + 1]; 1803 int cidr, tmp; 1804 char cidrstr[4]; 1805 1806 plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n"); 1807 1808 /* 1809 * Internal IPv4 address, either if 1810 * we are a client or a server. 1811 */ 1812 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) || 1813 #ifdef HAVE_LIBLDAP 1814 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || 1815 #endif 1816 #ifdef HAVE_LIBRADIUS 1817 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) || 1818 #endif 1819 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) { 1820 inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 1821 addrstr, IP_MAX); 1822 } else 1823 addrstr[0] = '\0'; 1824 1825 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) { 1826 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n"); 1827 return -1; 1828 } 1829 1830 if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) { 1831 if (script_env_append(envp, envc, "XAUTH_USER", 1832 iph1->mode_cfg->xauth.authdata.generic.usr) != 0) { 1833 plog(LLV_ERROR, LOCATION, NULL, 1834 "Cannot set XAUTH_USER\n"); 1835 return -1; 1836 } 1837 } 1838 1839 /* Internal IPv4 mask */ 1840 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 1841 inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 1842 addrstr, IP_MAX); 1843 else 1844 addrstr[0] = '\0'; 1845 1846 /* 1847 * During several releases, documentation adverised INTERNAL_NETMASK4 1848 * while code was using INTERNAL_MASK4. We now do both. 1849 */ 1850 1851 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 1852 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n"); 1853 return -1; 1854 } 1855 1856 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { 1857 plog(LLV_ERROR, LOCATION, NULL, 1858 "Cannot set INTERNAL_NETMASK4\n"); 1859 return -1; 1860 } 1861 1862 tmp = ntohl(iph1->mode_cfg->mask4.s_addr); 1863 for (cidr = 0; tmp != 0; cidr++) 1864 tmp <<= 1; 1865 snprintf(cidrstr, 3, "%d", cidr); 1866 1867 if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) { 1868 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n"); 1869 return -1; 1870 } 1871 1872 /* Internal IPv4 DNS */ 1873 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) { 1874 /* First Internal IPv4 DNS (for compatibilty with older code */ 1875 inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], 1876 addrstr, IP_MAX); 1877 1878 /* Internal IPv4 DNS - all */ 1879 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index, 1880 (void *)iph1->mode_cfg->dns4, 0); 1881 } else { 1882 addrstr[0] = '\0'; 1883 addrlist[0] = '\0'; 1884 } 1885 1886 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { 1887 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n"); 1888 return -1; 1889 } 1890 if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) { 1891 plog(LLV_ERROR, LOCATION, NULL, 1892 "Cannot set INTERNAL_DNS4_LIST\n"); 1893 return -1; 1894 } 1895 1896 /* Internal IPv4 WINS */ 1897 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) { 1898 /* 1899 * First Internal IPv4 WINS 1900 * (for compatibilty with older code 1901 */ 1902 inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], 1903 addrstr, IP_MAX); 1904 1905 /* Internal IPv4 WINS - all */ 1906 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index, 1907 (void *)iph1->mode_cfg->wins4, 0); 1908 } else { 1909 addrstr[0] = '\0'; 1910 addrlist[0] = '\0'; 1911 } 1912 1913 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { 1914 plog(LLV_ERROR, LOCATION, NULL, 1915 "Cannot set INTERNAL_WINS4\n"); 1916 return -1; 1917 } 1918 if (script_env_append(envp, envc, 1919 "INTERNAL_WINS4_LIST", addrlist) != 0) { 1920 plog(LLV_ERROR, LOCATION, NULL, 1921 "Cannot set INTERNAL_WINS4_LIST\n"); 1922 return -1; 1923 } 1924 1925 /* Default domain */ 1926 if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) 1927 strncpy(defdom, 1928 iph1->mode_cfg->default_domain, 1929 MAXPATHLEN + 1); 1930 else 1931 defdom[0] = '\0'; 1932 1933 if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { 1934 plog(LLV_ERROR, LOCATION, NULL, 1935 "Cannot set DEFAULT_DOMAIN\n"); 1936 return -1; 1937 } 1938 1939 /* Split networks */ 1940 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) { 1941 splitlist = 1942 splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK); 1943 splitlist_cidr = 1944 splitnet_list_2str(iph1->mode_cfg->split_include, CIDR); 1945 } else { 1946 splitlist = addrlist; 1947 splitlist_cidr = addrlist; 1948 addrlist[0] = '\0'; 1949 } 1950 1951 if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) { 1952 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n"); 1953 return -1; 1954 } 1955 if (script_env_append(envp, envc, 1956 "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) { 1957 plog(LLV_ERROR, LOCATION, NULL, 1958 "Cannot set SPLIT_INCLUDE_CIDR\n"); 1959 return -1; 1960 } 1961 if (splitlist != addrlist) 1962 racoon_free(splitlist); 1963 if (splitlist_cidr != addrlist) 1964 racoon_free(splitlist_cidr); 1965 1966 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) { 1967 splitlist = 1968 splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK); 1969 splitlist_cidr = 1970 splitnet_list_2str(iph1->mode_cfg->split_local, CIDR); 1971 } else { 1972 splitlist = addrlist; 1973 splitlist_cidr = addrlist; 1974 addrlist[0] = '\0'; 1975 } 1976 1977 if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) { 1978 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n"); 1979 return -1; 1980 } 1981 if (script_env_append(envp, envc, 1982 "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) { 1983 plog(LLV_ERROR, LOCATION, NULL, 1984 "Cannot set SPLIT_LOCAL_CIDR\n"); 1985 return -1; 1986 } 1987 if (splitlist != addrlist) 1988 racoon_free(splitlist); 1989 if (splitlist_cidr != addrlist) 1990 racoon_free(splitlist_cidr); 1991 1992 return 0; 1993 } 1994 1995 int 1996 isakmp_cfg_resize_pool(int size) 1997 { 1998 struct isakmp_cfg_port *new_pool; 1999 size_t len; 2000 size_t i; 2001 2002 if (size == isakmp_cfg_config.pool_size) 2003 return 0; 2004 2005 plog(LLV_INFO, LOCATION, NULL, 2006 "Resize address pool from %zu to %d\n", 2007 isakmp_cfg_config.pool_size, size); 2008 2009 /* If a pool already exists, check if we can shrink it */ 2010 if ((isakmp_cfg_config.port_pool != NULL) && 2011 (size < isakmp_cfg_config.pool_size)) { 2012 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) { 2013 if (isakmp_cfg_config.port_pool[i].used) { 2014 plog(LLV_ERROR, LOCATION, NULL, 2015 "resize pool from %zu to %d impossible " 2016 "port %zu is in use\n", 2017 isakmp_cfg_config.pool_size, size, i); 2018 size = i; 2019 break; 2020 } 2021 } 2022 } 2023 2024 len = size * sizeof(*isakmp_cfg_config.port_pool); 2025 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len); 2026 if (new_pool == NULL) { 2027 plog(LLV_ERROR, LOCATION, NULL, 2028 "resize pool from %zu to %d impossible: %s", 2029 isakmp_cfg_config.pool_size, size, strerror(errno)); 2030 return -1; 2031 } 2032 2033 /* If size increase, intialize correctly the new records */ 2034 if (size > isakmp_cfg_config.pool_size) { 2035 size_t unit; 2036 size_t old_size; 2037 2038 unit = sizeof(*isakmp_cfg_config.port_pool); 2039 old_size = isakmp_cfg_config.pool_size; 2040 2041 bzero((char *)new_pool + (old_size * unit), 2042 (size - old_size) * unit); 2043 } 2044 2045 isakmp_cfg_config.port_pool = new_pool; 2046 isakmp_cfg_config.pool_size = size; 2047 2048 return 0; 2049 } 2050 2051 int 2052 isakmp_cfg_init(int cold) 2053 { 2054 int i; 2055 2056 isakmp_cfg_config.network4 = (in_addr_t)0x00000000; 2057 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000; 2058 for (i = 0; i < MAXNS; i++) 2059 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000; 2060 isakmp_cfg_config.dns4_index = 0; 2061 for (i = 0; i < MAXWINS; i++) 2062 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000; 2063 isakmp_cfg_config.nbns4_index = 0; 2064 if (cold == ISAKMP_CFG_INIT_COLD) 2065 isakmp_cfg_config.port_pool = NULL; 2066 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM; 2067 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM; 2068 if (cold == ISAKMP_CFG_INIT_COLD) { 2069 if (isakmp_cfg_config.grouplist != NULL) { 2070 for (i = 0; i < isakmp_cfg_config.groupcount; i++) 2071 racoon_free(isakmp_cfg_config.grouplist[i]); 2072 racoon_free(isakmp_cfg_config.grouplist); 2073 } 2074 } 2075 isakmp_cfg_config.grouplist = NULL; 2076 isakmp_cfg_config.groupcount = 0; 2077 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL; 2078 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE; 2079 if (cold == ISAKMP_CFG_INIT_COLD) 2080 isakmp_cfg_config.pool_size = 0; 2081 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY; 2082 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN, 2083 MAXPATHLEN); 2084 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN); 2085 2086 if (cold != ISAKMP_CFG_INIT_COLD ) 2087 if (isakmp_cfg_config.splitnet_list != NULL) 2088 splitnet_list_free(isakmp_cfg_config.splitnet_list, 2089 &isakmp_cfg_config.splitnet_count); 2090 isakmp_cfg_config.splitnet_list = NULL; 2091 isakmp_cfg_config.splitnet_count = 0; 2092 isakmp_cfg_config.splitnet_type = 0; 2093 2094 isakmp_cfg_config.pfs_group = 0; 2095 isakmp_cfg_config.save_passwd = 0; 2096 2097 if (cold != ISAKMP_CFG_INIT_COLD ) 2098 if (isakmp_cfg_config.splitdns_list != NULL) 2099 racoon_free(isakmp_cfg_config.splitdns_list); 2100 isakmp_cfg_config.splitdns_list = NULL; 2101 isakmp_cfg_config.splitdns_len = 0; 2102 2103 #if 0 2104 int error; 2105 if (cold == ISAKMP_CFG_INIT_COLD) { 2106 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0) 2107 return error; 2108 } 2109 #endif 2110 2111 return 0; 2112 } 2113 2114