1/* $NetBSD: isakmp_cfg.c,v 1.12.6.4 2008/11/27 15:25:20 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#ifndef ANDROID_PATCHED 42#include <utmp.h> 43#endif 44#if defined(__APPLE__) && defined(__MACH__) 45#include <util.h> 46#endif 47 48#ifdef __FreeBSD__ 49# include <libutil.h> 50#endif 51#ifdef __NetBSD__ 52# include <util.h> 53#endif 54 55#include <netinet/in.h> 56#include <arpa/inet.h> 57 58#include <stdlib.h> 59#include <stdio.h> 60#include <string.h> 61#include <errno.h> 62#if TIME_WITH_SYS_TIME 63# include <sys/time.h> 64# include <time.h> 65#else 66# if HAVE_SYS_TIME_H 67# include <sys/time.h> 68# else 69# include <time.h> 70# endif 71#endif 72#include <netdb.h> 73#ifdef HAVE_UNISTD_H 74#include <unistd.h> 75#endif 76#if HAVE_STDINT_H 77#include <stdint.h> 78#endif 79#include <ctype.h> 80#include <resolv.h> 81 82#ifdef HAVE_LIBRADIUS 83#include <sys/utsname.h> 84#include <radlib.h> 85#endif 86 87#include "var.h" 88#include "misc.h" 89#include "vmbuf.h" 90#include "plog.h" 91#include "sockmisc.h" 92#include "schedule.h" 93#include "debug.h" 94 95#include "isakmp_var.h" 96#include "isakmp.h" 97#include "handler.h" 98#include "evt.h" 99#include "throttle.h" 100#include "remoteconf.h" 101#include "crypto_openssl.h" 102#include "isakmp_inf.h" 103#include "isakmp_xauth.h" 104#include "isakmp_unity.h" 105#include "isakmp_cfg.h" 106#include "strnames.h" 107#include "admin.h" 108#include "privsep.h" 109 110struct isakmp_cfg_config isakmp_cfg_config; 111 112static vchar_t *buffer_cat(vchar_t *s, vchar_t *append); 113static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *); 114#if 0 115static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); 116#endif 117static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 118 struct isakmp_data *, 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 (AUTHMETHOD(iph1)) { 452 case FICTIVE_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_PUSH(iph1->local, iph1->remote, 479 EVTT_ISAKMP_CFG_DONE, buf); 480 vfree(buf); 481 } 482 } 483#endif 484 485 return 0; 486} 487 488int 489isakmp_cfg_request(iph1, attrpl) 490 struct ph1handle *iph1; 491 struct isakmp_pl_attr *attrpl; 492{ 493 struct isakmp_data *attr; 494 int tlen; 495 size_t alen; 496 char *npp; 497 vchar_t *payload; 498 struct isakmp_pl_attr *reply; 499 vchar_t *reply_attr; 500 int type; 501 int error = -1; 502 503 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 504 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 505 return -1; 506 } 507 memset(payload->v, 0, sizeof(*reply)); 508 509 tlen = ntohs(attrpl->h.len); 510 attr = (struct isakmp_data *)(attrpl + 1); 511 tlen -= sizeof(*attrpl); 512 513 while (tlen > 0) { 514 reply_attr = NULL; 515 type = ntohs(attr->type); 516 517 /* Handle short attributes */ 518 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 519 type &= ~ISAKMP_GEN_MASK; 520 521 plog(LLV_DEBUG, LOCATION, NULL, 522 "Short attribute %s = %d\n", 523 s_isakmp_cfg_type(type), ntohs(attr->lorv)); 524 525 switch (type) { 526 case XAUTH_TYPE: 527 reply_attr = isakmp_xauth_req(iph1, attr); 528 break; 529 default: 530 plog(LLV_WARNING, LOCATION, NULL, 531 "Ignored short attribute %s\n", 532 s_isakmp_cfg_type(type)); 533 break; 534 } 535 536 tlen -= sizeof(*attr); 537 attr++; 538 539 if (reply_attr != NULL) { 540 payload = buffer_cat(payload, reply_attr); 541 vfree(reply_attr); 542 } 543 544 continue; 545 } 546 547 type = ntohs(attr->type); 548 alen = ntohs(attr->lorv); 549 550 /* Check that the attribute fit in the packet */ 551 if (tlen < alen) { 552 plog(LLV_ERROR, LOCATION, NULL, 553 "Short attribute %s\n", 554 s_isakmp_cfg_type(type)); 555 goto end; 556 } 557 558 plog(LLV_DEBUG, LOCATION, NULL, 559 "Attribute %s, len %zu\n", 560 s_isakmp_cfg_type(type), alen); 561 562 switch(type) { 563 case INTERNAL_IP4_ADDRESS: 564 case INTERNAL_IP4_NETMASK: 565 case INTERNAL_IP4_DNS: 566 case INTERNAL_IP4_NBNS: 567 case INTERNAL_IP4_SUBNET: 568 reply_attr = isakmp_cfg_net(iph1, attr); 569 break; 570 571 case XAUTH_TYPE: 572 case XAUTH_USER_NAME: 573 case XAUTH_USER_PASSWORD: 574 case XAUTH_PASSCODE: 575 case XAUTH_MESSAGE: 576 case XAUTH_CHALLENGE: 577 case XAUTH_DOMAIN: 578 case XAUTH_STATUS: 579 case XAUTH_NEXT_PIN: 580 case XAUTH_ANSWER: 581 reply_attr = isakmp_xauth_req(iph1, attr); 582 break; 583 584 case APPLICATION_VERSION: 585 reply_attr = isakmp_cfg_string(iph1, 586 attr, ISAKMP_CFG_RACOON_VERSION); 587 break; 588 589 case UNITY_BANNER: 590 case UNITY_PFS: 591 case UNITY_SAVE_PASSWD: 592 case UNITY_DEF_DOMAIN: 593 case UNITY_DDNS_HOSTNAME: 594 case UNITY_FW_TYPE: 595 case UNITY_SPLITDNS_NAME: 596 case UNITY_SPLIT_INCLUDE: 597 case UNITY_LOCAL_LAN: 598 case UNITY_NATT_PORT: 599 case UNITY_BACKUP_SERVERS: 600 reply_attr = isakmp_unity_req(iph1, attr); 601 break; 602 603 case INTERNAL_ADDRESS_EXPIRY: 604 default: 605 plog(LLV_WARNING, LOCATION, NULL, 606 "Ignored attribute %s\n", 607 s_isakmp_cfg_type(type)); 608 break; 609 } 610 611 npp = (char *)attr; 612 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); 613 tlen -= (sizeof(*attr) + alen); 614 615 if (reply_attr != NULL) { 616 payload = buffer_cat(payload, reply_attr); 617 vfree(reply_attr); 618 } 619 620 } 621 622 reply = (struct isakmp_pl_attr *)payload->v; 623 reply->h.len = htons(payload->l); 624 reply->type = ISAKMP_CFG_REPLY; 625 reply->id = attrpl->id; 626 627 plog(LLV_DEBUG, LOCATION, NULL, 628 "Sending MODE_CFG REPLY\n"); 629 630 error = isakmp_cfg_send(iph1, payload, 631 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 632 633 if (iph1->status == PHASE1ST_ESTABLISHED) { 634 switch (AUTHMETHOD(iph1)) { 635 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 636 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 637 /* Unimplemented */ 638 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 639 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 640 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 641 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 642 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 643 script_hook(iph1, SCRIPT_PHASE1_UP); 644 break; 645 default: 646 break; 647 } 648 } 649 650end: 651 vfree(payload); 652 653 return error; 654} 655 656int 657isakmp_cfg_set(iph1, attrpl) 658 struct ph1handle *iph1; 659 struct isakmp_pl_attr *attrpl; 660{ 661 struct isakmp_data *attr; 662 int tlen; 663 size_t alen; 664 char *npp; 665 vchar_t *payload; 666 struct isakmp_pl_attr *reply; 667 vchar_t *reply_attr; 668 int type; 669 int error = -1; 670 671 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 672 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 673 return -1; 674 } 675 memset(payload->v, 0, sizeof(*reply)); 676 677 tlen = ntohs(attrpl->h.len); 678 attr = (struct isakmp_data *)(attrpl + 1); 679 tlen -= sizeof(*attrpl); 680 681 /* 682 * We should send ack for the attributes we accepted 683 */ 684 while (tlen > 0) { 685 reply_attr = NULL; 686 type = ntohs(attr->type); 687 688 plog(LLV_DEBUG, LOCATION, NULL, 689 "Attribute %s\n", 690 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); 691 692 switch (type & ~ISAKMP_GEN_MASK) { 693 case XAUTH_STATUS: 694 reply_attr = isakmp_xauth_set(iph1, attr); 695 break; 696 default: 697 plog(LLV_DEBUG, LOCATION, NULL, 698 "Unexpected SET attribute %s\n", 699 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK)); 700 break; 701 } 702 703 if (reply_attr != NULL) { 704 payload = buffer_cat(payload, reply_attr); 705 vfree(reply_attr); 706 } 707 708 /* 709 * Move to next attribute. If we run out of the packet, 710 * tlen becomes negative and we exit. 711 */ 712 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 713 tlen -= sizeof(*attr); 714 attr++; 715 } else { 716 alen = ntohs(attr->lorv); 717 tlen -= (sizeof(*attr) + alen); 718 npp = (char *)attr; 719 attr = (struct isakmp_data *) 720 (npp + sizeof(*attr) + alen); 721 } 722 } 723 724 reply = (struct isakmp_pl_attr *)payload->v; 725 reply->h.len = htons(payload->l); 726 reply->type = ISAKMP_CFG_ACK; 727 reply->id = attrpl->id; 728 729 plog(LLV_DEBUG, LOCATION, NULL, 730 "Sending MODE_CFG ACK\n"); 731 732 error = isakmp_cfg_send(iph1, payload, 733 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 734 735 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) { 736 if (iph1->status == PHASE1ST_ESTABLISHED) 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 return isakmp_cfg_addr4(iph1, 907 attr, &isakmp_cfg_config.network4); 908 break; 909 910 default: 911 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); 912 break; 913 } 914 return NULL; 915} 916 917#if 0 918static vchar_t * 919isakmp_cfg_void(iph1, attr) 920 struct ph1handle *iph1; 921 struct isakmp_data *attr; 922{ 923 vchar_t *buffer; 924 struct isakmp_data *new; 925 926 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 927 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 928 return NULL; 929 } 930 931 new = (struct isakmp_data *)buffer->v; 932 933 new->type = attr->type; 934 new->lorv = htons(0); 935 936 return buffer; 937} 938#endif 939 940vchar_t * 941isakmp_cfg_copy(iph1, attr) 942 struct ph1handle *iph1; 943 struct isakmp_data *attr; 944{ 945 vchar_t *buffer; 946 size_t len = 0; 947 948 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV) 949 len = ntohs(attr->lorv); 950 951 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 952 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 953 return NULL; 954 } 955 956 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv)); 957 958 return buffer; 959} 960 961vchar_t * 962isakmp_cfg_short(iph1, attr, value) 963 struct ph1handle *iph1; 964 struct isakmp_data *attr; 965 int value; 966{ 967 vchar_t *buffer; 968 struct isakmp_data *new; 969 int type; 970 971 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 972 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 973 return NULL; 974 } 975 976 new = (struct isakmp_data *)buffer->v; 977 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; 978 979 new->type = htons(type | ISAKMP_GEN_TV); 980 new->lorv = htons(value); 981 982 return buffer; 983} 984 985vchar_t * 986isakmp_cfg_varlen(iph1, attr, string, len) 987 struct ph1handle *iph1; 988 struct isakmp_data *attr; 989 char *string; 990 size_t len; 991{ 992 vchar_t *buffer; 993 struct isakmp_data *new; 994 char *data; 995 996 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 997 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 998 return NULL; 999 } 1000 1001 new = (struct isakmp_data *)buffer->v; 1002 1003 new->type = attr->type; 1004 new->lorv = htons(len); 1005 data = (char *)(new + 1); 1006 1007 memcpy(data, string, len); 1008 1009 return buffer; 1010} 1011vchar_t * 1012isakmp_cfg_string(iph1, attr, string) 1013 struct ph1handle *iph1; 1014 struct isakmp_data *attr; 1015 char *string; 1016{ 1017 size_t len = strlen(string); 1018 return isakmp_cfg_varlen(iph1, attr, string, len); 1019} 1020 1021static vchar_t * 1022isakmp_cfg_addr4(iph1, attr, addr) 1023 struct ph1handle *iph1; 1024 struct isakmp_data *attr; 1025 in_addr_t *addr; 1026{ 1027 vchar_t *buffer; 1028 struct isakmp_data *new; 1029 size_t len; 1030 1031 len = sizeof(*addr); 1032 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 1033 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1034 return NULL; 1035 } 1036 1037 new = (struct isakmp_data *)buffer->v; 1038 1039 new->type = attr->type; 1040 new->lorv = htons(len); 1041 memcpy(new + 1, addr, len); 1042 1043 return buffer; 1044} 1045 1046static vchar_t * 1047isakmp_cfg_addr4_list(iph1, attr, addr, nbr) 1048 struct ph1handle *iph1; 1049 struct isakmp_data *attr; 1050 in_addr_t *addr; 1051 int nbr; 1052{ 1053 int error = -1; 1054 vchar_t *buffer = NULL; 1055 vchar_t *bufone = NULL; 1056 struct isakmp_data *new; 1057 size_t len; 1058 int i; 1059 1060 len = sizeof(*addr); 1061 if ((buffer = vmalloc(0)) == NULL) { 1062 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1063 goto out; 1064 } 1065 for(i = 0; i < nbr; i++) { 1066 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) { 1067 plog(LLV_ERROR, LOCATION, NULL, 1068 "Cannot allocate memory\n"); 1069 goto out; 1070 } 1071 new = (struct isakmp_data *)bufone->v; 1072 new->type = attr->type; 1073 new->lorv = htons(len); 1074 memcpy(new + 1, &addr[i], len); 1075 new += (len + sizeof(*attr)); 1076 buffer = buffer_cat(buffer, bufone); 1077 vfree(bufone); 1078 } 1079 1080 error = 0; 1081 1082out: 1083 if ((error != 0) && (buffer != NULL)) { 1084 vfree(buffer); 1085 buffer = NULL; 1086 } 1087 1088 return buffer; 1089} 1090 1091struct isakmp_ivm * 1092isakmp_cfg_newiv(iph1, msgid) 1093 struct ph1handle *iph1; 1094 u_int32_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 */ 1114int 1115isakmp_cfg_send(iph1, payload, np, flags, new_exchange) 1116 struct ph1handle *iph1; 1117 vchar_t *payload; 1118 u_int32_t np; 1119 int flags; 1120 int new_exchange; 1121{ 1122 struct ph2handle *iph2 = NULL; 1123 vchar_t *hash = NULL; 1124 struct isakmp *isakmp; 1125 struct isakmp_gen *gen; 1126 char *p; 1127 int tlen; 1128 int error = -1; 1129 struct isakmp_cfg_state *ics = iph1->mode_cfg; 1130 1131 /* Check if phase 1 is established */ 1132 if ((iph1->status != PHASE1ST_ESTABLISHED) || 1133 (iph1->local == NULL) || 1134 (iph1->remote == NULL)) { 1135 plog(LLV_ERROR, LOCATION, NULL, 1136 "ISAKMP mode config exchange with immature phase 1\n"); 1137 goto end; 1138 } 1139 1140 /* add new entry to isakmp status table */ 1141 iph2 = newph2(); 1142 if (iph2 == NULL) 1143 goto end; 1144 1145 iph2->dst = dupsaddr(iph1->remote); 1146 if (iph2->dst == NULL) { 1147 delph2(iph2); 1148 goto end; 1149 } 1150 iph2->src = dupsaddr(iph1->local); 1151 if (iph2->src == NULL) { 1152 delph2(iph2); 1153 goto end; 1154 } 1155 1156#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT)) 1157 if (set_port(iph2->dst, 0) == NULL || 1158 set_port(iph2->src, 0) == NULL) { 1159 plog(LLV_ERROR, LOCATION, NULL, 1160 "invalid family: %d\n", iph1->remote->sa_family); 1161 delph2(iph2); 1162 goto end; 1163 } 1164#endif 1165 iph2->ph1 = iph1; 1166 iph2->side = INITIATOR; 1167 iph2->status = PHASE2ST_START; 1168 1169 if (new_exchange) 1170 iph2->msgid = isakmp_newmsgid2(iph1); 1171 else 1172 iph2->msgid = iph1->msgid; 1173 1174 /* get IV and HASH(1) if skeyid_a was generated. */ 1175 if (iph1->skeyid_a != NULL) { 1176 if (new_exchange) { 1177 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) { 1178 delph2(iph2); 1179 goto end; 1180 } 1181 } 1182 1183 /* generate HASH(1) */ 1184 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); 1185 if (hash == NULL) { 1186 delph2(iph2); 1187 goto end; 1188 } 1189 1190 /* initialized total buffer length */ 1191 tlen = hash->l; 1192 tlen += sizeof(*gen); 1193 } else { 1194 /* IKE-SA is not established */ 1195 hash = NULL; 1196 1197 /* initialized total buffer length */ 1198 tlen = 0; 1199 } 1200 if ((flags & ISAKMP_FLAG_A) == 0) 1201 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 1202 else 1203 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 1204 1205 insph2(iph2); 1206 bindph12(iph1, iph2); 1207 1208 tlen += sizeof(*isakmp) + payload->l; 1209 1210 /* create buffer for isakmp payload */ 1211 iph2->sendbuf = vmalloc(tlen); 1212 if (iph2->sendbuf == NULL) { 1213 plog(LLV_ERROR, LOCATION, NULL, 1214 "failed to get buffer to send.\n"); 1215 goto err; 1216 } 1217 1218 /* create isakmp header */ 1219 isakmp = (struct isakmp *)iph2->sendbuf->v; 1220 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 1221 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 1222 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 1223 isakmp->v = iph1->version; 1224 isakmp->etype = ISAKMP_ETYPE_CFG; 1225 isakmp->flags = iph2->flags; 1226 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 1227 isakmp->len = htonl(tlen); 1228 p = (char *)(isakmp + 1); 1229 1230 /* create HASH payload */ 1231 if (hash != NULL) { 1232 gen = (struct isakmp_gen *)p; 1233 gen->np = np & 0xff; 1234 gen->len = htons(sizeof(*gen) + hash->l); 1235 p += sizeof(*gen); 1236 memcpy(p, hash->v, hash->l); 1237 p += hash->l; 1238 } 1239 1240 /* add payload */ 1241 memcpy(p, payload->v, payload->l); 1242 p += payload->l; 1243 1244#ifdef HAVE_PRINT_ISAKMP_C 1245 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 1246#endif 1247 1248 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n"); 1249 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l); 1250 1251 /* encoding */ 1252 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 1253 vchar_t *tmp; 1254 1255 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 1256 ics->ivm->ive, ics->ivm->iv); 1257 VPTRINIT(iph2->sendbuf); 1258 if (tmp == NULL) 1259 goto err; 1260 iph2->sendbuf = tmp; 1261 } 1262 1263 /* HDR*, HASH(1), ATTR */ 1264 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 1265 VPTRINIT(iph2->sendbuf); 1266 goto err; 1267 } 1268 1269 plog(LLV_DEBUG, LOCATION, NULL, 1270 "sendto mode config %s.\n", s_isakmp_nptype(np)); 1271 1272 /* 1273 * XXX We might need to resend the message... 1274 */ 1275 1276 error = 0; 1277 VPTRINIT(iph2->sendbuf); 1278 1279err: 1280 if (iph2->sendbuf != NULL) 1281 vfree(iph2->sendbuf); 1282 1283 unbindph12(iph2); 1284 remph2(iph2); 1285 delph2(iph2); 1286end: 1287 if (hash) 1288 vfree(hash); 1289 return error; 1290} 1291 1292 1293void 1294isakmp_cfg_rmstate(iph1) 1295 struct ph1handle *iph1; 1296{ 1297 struct isakmp_cfg_state *state = iph1->mode_cfg; 1298 1299 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0) 1300 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); 1301 1302 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED) 1303 isakmp_cfg_putport(iph1, state->port); 1304 1305 /* Delete the IV if it's still there */ 1306 if(iph1->mode_cfg->ivm) { 1307 oakley_delivm(iph1->mode_cfg->ivm); 1308 iph1->mode_cfg->ivm = NULL; 1309 } 1310 1311 /* Free any allocated splitnet lists */ 1312 if(iph1->mode_cfg->split_include != NULL) 1313 splitnet_list_free(iph1->mode_cfg->split_include, 1314 &iph1->mode_cfg->include_count); 1315 if(iph1->mode_cfg->split_local != NULL) 1316 splitnet_list_free(iph1->mode_cfg->split_local, 1317 &iph1->mode_cfg->local_count); 1318 1319 xauth_rmstate(&state->xauth); 1320 1321 racoon_free(state); 1322 iph1->mode_cfg = NULL; 1323 1324 return; 1325} 1326 1327struct isakmp_cfg_state * 1328isakmp_cfg_mkstate(void) 1329{ 1330 struct isakmp_cfg_state *state; 1331 1332 if ((state = racoon_malloc(sizeof(*state))) == NULL) { 1333 plog(LLV_ERROR, LOCATION, NULL, 1334 "Cannot allocate memory for mode config state\n"); 1335 return NULL; 1336 } 1337 memset(state, 0, sizeof(*state)); 1338 1339 return state; 1340} 1341 1342int 1343isakmp_cfg_getport(iph1) 1344 struct ph1handle *iph1; 1345{ 1346 unsigned int i; 1347 size_t size = isakmp_cfg_config.pool_size; 1348 1349 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED) 1350 return iph1->mode_cfg->port; 1351 1352 if (isakmp_cfg_config.port_pool == NULL) { 1353 plog(LLV_ERROR, LOCATION, NULL, 1354 "isakmp_cfg_config.port_pool == NULL\n"); 1355 return -1; 1356 } 1357 1358 for (i = 0; i < size; i++) { 1359 if (isakmp_cfg_config.port_pool[i].used == 0) 1360 break; 1361 } 1362 1363 if (i == size) { 1364 plog(LLV_ERROR, LOCATION, NULL, 1365 "No more addresses available\n"); 1366 return -1; 1367 } 1368 1369 isakmp_cfg_config.port_pool[i].used = 1; 1370 1371 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i); 1372 1373 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED; 1374 iph1->mode_cfg->port = i; 1375 1376 return i; 1377} 1378 1379int 1380isakmp_cfg_putport(iph1, index) 1381 struct ph1handle *iph1; 1382 unsigned int index; 1383{ 1384 if (isakmp_cfg_config.port_pool == NULL) { 1385 plog(LLV_ERROR, LOCATION, NULL, 1386 "isakmp_cfg_config.port_pool == NULL\n"); 1387 return -1; 1388 } 1389 1390 if (isakmp_cfg_config.port_pool[index].used == 0) { 1391 plog(LLV_ERROR, LOCATION, NULL, 1392 "Attempt to release an unallocated address (port %d)\n", 1393 index); 1394 return -1; 1395 } 1396 1397#ifdef HAVE_LIBPAM 1398 /* Cleanup PAM status associated with the port */ 1399 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM) 1400 privsep_cleanup_pam(index); 1401#endif 1402 isakmp_cfg_config.port_pool[index].used = 0; 1403 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED; 1404 1405 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index); 1406 1407 return 0; 1408} 1409 1410#ifdef HAVE_LIBPAM 1411void 1412cleanup_pam(port) 1413 int port; 1414{ 1415 if (isakmp_cfg_config.port_pool[port].pam != NULL) { 1416 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS); 1417 isakmp_cfg_config.port_pool[port].pam = NULL; 1418 } 1419 1420 return; 1421} 1422#endif 1423 1424/* Accounting, only for RADIUS or PAM */ 1425static int 1426isakmp_cfg_accounting(iph1, inout) 1427 struct ph1handle *iph1; 1428 int inout; 1429{ 1430#ifdef HAVE_LIBPAM 1431 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM) 1432 return privsep_accounting_pam(iph1->mode_cfg->port, 1433 inout); 1434#endif 1435#ifdef HAVE_LIBRADIUS 1436 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) 1437 return isakmp_cfg_accounting_radius(iph1, inout); 1438#endif 1439 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM) 1440 return privsep_accounting_system(iph1->mode_cfg->port, 1441 iph1->remote, iph1->mode_cfg->login, inout); 1442 return 0; 1443} 1444 1445#ifdef HAVE_LIBPAM 1446int 1447isakmp_cfg_accounting_pam(port, inout) 1448 int port; 1449 int inout; 1450{ 1451 int error = 0; 1452 pam_handle_t *pam; 1453 1454 if (isakmp_cfg_config.port_pool == NULL) { 1455 plog(LLV_ERROR, LOCATION, NULL, 1456 "isakmp_cfg_config.port_pool == NULL\n"); 1457 return -1; 1458 } 1459 1460 pam = isakmp_cfg_config.port_pool[port].pam; 1461 if (pam == NULL) { 1462 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n"); 1463 return -1; 1464 } 1465 1466 switch (inout) { 1467 case ISAKMP_CFG_LOGIN: 1468 error = pam_open_session(pam, 0); 1469 break; 1470 case ISAKMP_CFG_LOGOUT: 1471 error = pam_close_session(pam, 0); 1472 pam_end(pam, error); 1473 isakmp_cfg_config.port_pool[port].pam = NULL; 1474 break; 1475 default: 1476 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1477 break; 1478 } 1479 1480 if (error != 0) { 1481 plog(LLV_ERROR, LOCATION, NULL, 1482 "pam_open_session/pam_close_session failed: %s\n", 1483 pam_strerror(pam, error)); 1484 return -1; 1485 } 1486 1487 return 0; 1488} 1489#endif /* HAVE_LIBPAM */ 1490 1491#ifdef HAVE_LIBRADIUS 1492static int 1493isakmp_cfg_accounting_radius(iph1, inout) 1494 struct ph1handle *iph1; 1495 int inout; 1496{ 1497 /* For first time use, initialize Radius */ 1498 if (radius_acct_state == NULL) { 1499 if ((radius_acct_state = rad_acct_open()) == NULL) { 1500 plog(LLV_ERROR, LOCATION, NULL, 1501 "Cannot init librradius\n"); 1502 return -1; 1503 } 1504 1505 if (rad_config(radius_acct_state, NULL) != 0) { 1506 plog(LLV_ERROR, LOCATION, NULL, 1507 "Cannot open librarius config file: %s\n", 1508 rad_strerror(radius_acct_state)); 1509 rad_close(radius_acct_state); 1510 radius_acct_state = NULL; 1511 return -1; 1512 } 1513 } 1514 1515 if (rad_create_request(radius_acct_state, 1516 RAD_ACCOUNTING_REQUEST) != 0) { 1517 plog(LLV_ERROR, LOCATION, NULL, 1518 "rad_create_request failed: %s\n", 1519 rad_strerror(radius_acct_state)); 1520 return -1; 1521 } 1522 1523 if (rad_put_string(radius_acct_state, RAD_USER_NAME, 1524 iph1->mode_cfg->login) != 0) { 1525 plog(LLV_ERROR, LOCATION, NULL, 1526 "rad_put_string failed: %s\n", 1527 rad_strerror(radius_acct_state)); 1528 return -1; 1529 } 1530 1531 switch (inout) { 1532 case ISAKMP_CFG_LOGIN: 1533 inout = RAD_START; 1534 break; 1535 case ISAKMP_CFG_LOGOUT: 1536 inout = RAD_STOP; 1537 break; 1538 default: 1539 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1540 break; 1541 } 1542 1543 if (rad_put_addr(radius_acct_state, 1544 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) { 1545 plog(LLV_ERROR, LOCATION, NULL, 1546 "rad_put_addr failed: %s\n", 1547 rad_strerror(radius_acct_state)); 1548 return -1; 1549 } 1550 1551 if (rad_put_addr(radius_acct_state, 1552 RAD_LOGIN_IP_HOST, 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_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) { 1560 plog(LLV_ERROR, LOCATION, NULL, 1561 "rad_put_int failed: %s\n", 1562 rad_strerror(radius_acct_state)); 1563 return -1; 1564 } 1565 1566 if (isakmp_cfg_radius_common(radius_acct_state, 1567 iph1->mode_cfg->port) != 0) 1568 return -1; 1569 1570 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) { 1571 plog(LLV_ERROR, LOCATION, NULL, 1572 "rad_send_request failed: %s\n", 1573 rad_strerror(radius_acct_state)); 1574 return -1; 1575 } 1576 1577 return 0; 1578} 1579#endif /* HAVE_LIBRADIUS */ 1580 1581/* 1582 * Attributes common to all RADIUS requests 1583 */ 1584#ifdef HAVE_LIBRADIUS 1585int 1586isakmp_cfg_radius_common(radius_state, port) 1587 struct rad_handle *radius_state; 1588 int port; 1589{ 1590 struct utsname name; 1591 static struct hostent *host = NULL; 1592 struct in_addr nas_addr; 1593 1594 /* 1595 * Find our own IP by resolving our nodename 1596 */ 1597 if (host == NULL) { 1598 if (uname(&name) != 0) { 1599 plog(LLV_ERROR, LOCATION, NULL, 1600 "uname failed: %s\n", strerror(errno)); 1601 return -1; 1602 } 1603 1604 if ((host = gethostbyname(name.nodename)) == NULL) { 1605 plog(LLV_ERROR, LOCATION, NULL, 1606 "gethostbyname failed: %s\n", strerror(errno)); 1607 return -1; 1608 } 1609 } 1610 1611 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr)); 1612 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) { 1613 plog(LLV_ERROR, LOCATION, NULL, 1614 "rad_put_addr failed: %s\n", 1615 rad_strerror(radius_state)); 1616 return -1; 1617 } 1618 1619 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) { 1620 plog(LLV_ERROR, LOCATION, NULL, 1621 "rad_put_int failed: %s\n", 1622 rad_strerror(radius_state)); 1623 return -1; 1624 } 1625 1626 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) { 1627 plog(LLV_ERROR, LOCATION, NULL, 1628 "rad_put_int failed: %s\n", 1629 rad_strerror(radius_state)); 1630 return -1; 1631 } 1632 1633 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) { 1634 plog(LLV_ERROR, LOCATION, NULL, 1635 "rad_put_int failed: %s\n", 1636 rad_strerror(radius_state)); 1637 return -1; 1638 } 1639 1640 return 0; 1641} 1642#endif 1643 1644#ifndef ANDROID_PATCHED 1645 1646/* 1647 Logs the user into the utmp system files. 1648*/ 1649 1650int 1651isakmp_cfg_accounting_system(port, raddr, usr, inout) 1652 int port; 1653 struct sockaddr *raddr; 1654 char *usr; 1655 int inout; 1656{ 1657 int error = 0; 1658 struct utmp ut; 1659 char term[UT_LINESIZE]; 1660 char addr[NI_MAXHOST]; 1661 1662 if (usr == NULL || usr[0]=='\0') { 1663 plog(LLV_ERROR, LOCATION, NULL, 1664 "system accounting : no login found\n"); 1665 return -1; 1666 } 1667 1668 sprintf(term, TERMSPEC, port); 1669 1670 switch (inout) { 1671 case ISAKMP_CFG_LOGIN: 1672 strncpy(ut.ut_name, usr, UT_NAMESIZE); 1673 ut.ut_name[UT_NAMESIZE - 1] = '\0'; 1674 1675 strncpy(ut.ut_line, term, UT_LINESIZE); 1676 ut.ut_line[UT_LINESIZE - 1] = '\0'; 1677 1678 GETNAMEINFO_NULL(raddr, addr); 1679 strncpy(ut.ut_host, addr, UT_HOSTSIZE); 1680 ut.ut_host[UT_HOSTSIZE - 1] = '\0'; 1681 1682 ut.ut_time = time(NULL); 1683 1684 plog(LLV_INFO, LOCATION, NULL, 1685 "Accounting : '%s' logging on '%s' from %s.\n", 1686 ut.ut_name, ut.ut_line, ut.ut_host); 1687 1688 login(&ut); 1689 1690 break; 1691 case ISAKMP_CFG_LOGOUT: 1692 1693 plog(LLV_INFO, LOCATION, NULL, 1694 "Accounting : '%s' unlogging from '%s'.\n", 1695 usr, term); 1696 1697 logout(term); 1698 1699 break; 1700 default: 1701 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1702 break; 1703 } 1704 1705 return 0; 1706} 1707 1708#endif 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