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