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