1 /* $NetBSD: isakmp_cfg.c,v 1.9 2005/11/21 14:20:29 manu Exp $ */ 2 3 /* Id: isakmp_cfg.c,v 1.26.2.6 2005/09/23 14:29:45 manubsd Exp */ 4 5 /* 6 * Copyright (C) 2004 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 <netinet/in.h> 42 #include <arpa/inet.h> 43 44 #include <stdlib.h> 45 #include <stdio.h> 46 #include <string.h> 47 #include <errno.h> 48 #if TIME_WITH_SYS_TIME 49 # include <sys/time.h> 50 # include <time.h> 51 #else 52 # if HAVE_SYS_TIME_H 53 # include <sys/time.h> 54 # else 55 # include <time.h> 56 # endif 57 #endif 58 #include <netdb.h> 59 #ifdef HAVE_UNISTD_H 60 #include <unistd.h> 61 #endif 62 #include <ctype.h> 63 64 #ifdef HAVE_LIBRADIUS 65 #include <sys/utsname.h> 66 #include <radlib.h> 67 #endif 68 69 #include "var.h" 70 #include "misc.h" 71 #include "vmbuf.h" 72 #include "plog.h" 73 #include "sockmisc.h" 74 #include "schedule.h" 75 #include "debug.h" 76 77 #include "isakmp_var.h" 78 #include "isakmp.h" 79 #include "handler.h" 80 #include "evt.h" 81 #include "throttle.h" 82 #include "remoteconf.h" 83 #include "crypto_openssl.h" 84 #include "isakmp_inf.h" 85 #include "isakmp_xauth.h" 86 #include "isakmp_unity.h" 87 #include "isakmp_cfg.h" 88 #include "strnames.h" 89 #include "admin.h" 90 #include "privsep.h" 91 92 struct isakmp_cfg_config isakmp_cfg_config = { 93 0x00000000, /* network4 */ 94 0x00000000, /* netmask4 */ 95 0x00000000, /* dns4 */ 96 0x00000000, /* nbns4 */ 97 NULL, /* pool */ 98 ISAKMP_CFG_AUTH_SYSTEM, /* authsource */ 99 ISAKMP_CFG_CONF_LOCAL, /* confsource */ 100 ISAKMP_CFG_ACCT_NONE, /* accounting */ 101 ISAKMP_CFG_MAX_CNX, /* pool_size */ 102 THROTTLE_PENALTY, /* auth_throttle */ 103 ISAKMP_CFG_MOTD, /* motd */ 104 0, /* pfs_group */ 105 0, /* save_passwd */ 106 }; 107 108 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append); 109 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *); 110 #if 0 111 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *); 112 #endif 113 static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 114 struct isakmp_data *, in_addr_t *); 115 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *); 116 117 #define ISAKMP_CFG_LOGIN 1 118 #define ISAKMP_CFG_LOGOUT 2 119 static int isakmp_cfg_accounting(struct ph1handle *, int); 120 #ifdef HAVE_LIBRADIUS 121 static int isakmp_cfg_accounting_radius(struct ph1handle *, int); 122 #endif 123 124 /* 125 * Handle an ISAKMP config mode packet 126 * We expect HDR, HASH, ATTR 127 */ 128 void 129 isakmp_cfg_r(iph1, msg) 130 struct ph1handle *iph1; 131 vchar_t *msg; 132 { 133 struct isakmp *packet; 134 struct isakmp_gen *ph; 135 int tlen; 136 char *npp; 137 int np; 138 vchar_t *dmsg; 139 struct isakmp_ivm *ivm; 140 141 /* Check that the packet is long enough to have a header */ 142 if (msg->l < sizeof(*packet)) { 143 plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n"); 144 return; 145 } 146 147 packet = (struct isakmp *)msg->v; 148 149 /* Is it encrypted? It should be encrypted */ 150 if ((packet->flags & ISAKMP_FLAG_E) == 0) { 151 plog(LLV_ERROR, LOCATION, NULL, 152 "User credentials sent in cleartext!\n"); 153 return; 154 } 155 156 /* 157 * Decrypt the packet. If this is the beginning of a new 158 * exchange, reinitialize the IV 159 */ 160 if (iph1->mode_cfg->ivm == NULL) 161 iph1->mode_cfg->ivm = 162 isakmp_cfg_newiv(iph1, packet->msgid); 163 ivm = iph1->mode_cfg->ivm; 164 165 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive); 166 if (dmsg == NULL) { 167 plog(LLV_ERROR, LOCATION, NULL, 168 "failed to decrypt message\n"); 169 return; 170 } 171 172 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n"); 173 plogdump(LLV_DEBUG, dmsg->v, dmsg->l); 174 175 /* Now work with the decrypted packet */ 176 packet = (struct isakmp *)dmsg->v; 177 tlen = dmsg->l - sizeof(*packet); 178 ph = (struct isakmp_gen *)(packet + 1); 179 180 np = packet->np; 181 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) { 182 /* Check that the payload header fits in the packet */ 183 if (tlen < sizeof(*ph)) { 184 plog(LLV_WARNING, LOCATION, NULL, 185 "Short payload header\n"); 186 goto out; 187 } 188 189 /* Check that the payload fits in the packet */ 190 if (tlen < ntohs(ph->len)) { 191 plog(LLV_WARNING, LOCATION, NULL, 192 "Short payload\n"); 193 goto out; 194 } 195 196 plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np); 197 plogdump(LLV_DEBUG, ph, ntohs(ph->len)); 198 199 switch(np) { 200 case ISAKMP_NPTYPE_HASH: { 201 vchar_t *check; 202 vchar_t *payload; 203 size_t plen; 204 struct isakmp_gen *nph; 205 206 plen = ntohs(ph->len); 207 nph = (struct isakmp_gen *)((char *)ph + plen); 208 plen = ntohs(nph->len); 209 210 if ((payload = vmalloc(plen)) == NULL) { 211 plog(LLV_ERROR, LOCATION, NULL, 212 "Cannot allocate memory\n"); 213 goto out; 214 } 215 memcpy(payload->v, nph, plen); 216 217 if ((check = oakley_compute_hash1(iph1, 218 packet->msgid, payload)) == NULL) { 219 plog(LLV_ERROR, LOCATION, NULL, 220 "Cannot compute hash\n"); 221 vfree(payload); 222 goto out; 223 } 224 225 if (memcmp(ph + 1, check->v, check->l) != 0) { 226 plog(LLV_ERROR, LOCATION, NULL, 227 "Hash verification failed\n"); 228 vfree(payload); 229 vfree(check); 230 goto out; 231 } 232 vfree(payload); 233 vfree(check); 234 break; 235 } 236 case ISAKMP_NPTYPE_ATTR: { 237 struct isakmp_pl_attr *attrpl; 238 239 attrpl = (struct isakmp_pl_attr *)ph; 240 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl); 241 242 break; 243 } 244 default: 245 plog(LLV_WARNING, LOCATION, NULL, 246 "Unexpected next payload %d\n", np); 247 /* Skip to the next payload */ 248 break; 249 } 250 251 /* Move to the next payload */ 252 np = ph->np; 253 tlen -= ntohs(ph->len); 254 npp = (char *)ph; 255 ph = (struct isakmp_gen *)(npp + ntohs(ph->len)); 256 } 257 258 out: 259 vfree(dmsg); 260 } 261 262 int 263 isakmp_cfg_attr_r(iph1, msgid, attrpl) 264 struct ph1handle *iph1; 265 u_int32_t msgid; 266 struct isakmp_pl_attr *attrpl; 267 { 268 int type = attrpl->type; 269 270 switch (type) { 271 case ISAKMP_CFG_ACK: 272 /* ignore, but this is the time to reinit the IV */ 273 oakley_delivm(iph1->mode_cfg->ivm); 274 iph1->mode_cfg->ivm = NULL; 275 return 0; 276 break; 277 278 case ISAKMP_CFG_REPLY: 279 return isakmp_cfg_reply(iph1, attrpl); 280 break; 281 282 case ISAKMP_CFG_REQUEST: 283 iph1->msgid = msgid; 284 return isakmp_cfg_request(iph1, attrpl); 285 break; 286 287 case ISAKMP_CFG_SET: 288 iph1->msgid = msgid; 289 return isakmp_cfg_set(iph1, attrpl); 290 break; 291 292 default: 293 plog(LLV_WARNING, LOCATION, NULL, 294 "Unepected configuration exchange type %d\n", type); 295 return -1; 296 break; 297 } 298 299 return 0; 300 } 301 302 int 303 isakmp_cfg_reply(iph1, attrpl) 304 struct ph1handle *iph1; 305 struct isakmp_pl_attr *attrpl; 306 { 307 struct isakmp_data *attr; 308 int tlen; 309 size_t alen; 310 char *npp; 311 int type; 312 struct sockaddr_in *sin; 313 314 tlen = ntohs(attrpl->h.len); 315 attr = (struct isakmp_data *)(attrpl + 1); 316 tlen -= sizeof(*attrpl); 317 318 while (tlen > 0) { 319 type = ntohs(attr->type); 320 321 /* Handle short attributes */ 322 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 323 type &= ~ISAKMP_GEN_MASK; 324 325 plog(LLV_DEBUG, LOCATION, NULL, 326 "Short attribute %d = %d\n", 327 type, ntohs(attr->lorv)); 328 329 switch (type) { 330 case XAUTH_TYPE: 331 xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); 332 break; 333 334 default: 335 plog(LLV_WARNING, LOCATION, NULL, 336 "Ignored short attribute %d\n", type); 337 break; 338 } 339 340 tlen -= sizeof(*attr); 341 attr++; 342 continue; 343 } 344 345 type = ntohs(attr->type); 346 alen = ntohs(attr->lorv); 347 348 /* Check that the attribute fit in the packet */ 349 if (tlen < alen) { 350 plog(LLV_ERROR, LOCATION, NULL, 351 "Short attribute %d\n", type); 352 return -1; 353 } 354 355 plog(LLV_DEBUG, LOCATION, NULL, 356 "Attribute %d, len %zu\n", type, alen); 357 358 switch(type) { 359 case XAUTH_TYPE: 360 case XAUTH_USER_NAME: 361 case XAUTH_USER_PASSWORD: 362 case XAUTH_PASSCODE: 363 case XAUTH_MESSAGE: 364 case XAUTH_CHALLENGE: 365 case XAUTH_DOMAIN: 366 case XAUTH_STATUS: 367 case XAUTH_NEXT_PIN: 368 case XAUTH_ANSWER: 369 xauth_attr_reply(iph1, attr, ntohs(attrpl->id)); 370 break; 371 case INTERNAL_IP4_ADDRESS: 372 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4); 373 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4; 374 break; 375 case INTERNAL_IP4_NETMASK: 376 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4); 377 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4; 378 break; 379 case INTERNAL_IP4_DNS: 380 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->dns4); 381 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4; 382 break; 383 case INTERNAL_IP4_NBNS: 384 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->wins4); 385 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4; 386 break; 387 case INTERNAL_IP4_SUBNET: 388 case INTERNAL_ADDRESS_EXPIRY: 389 case UNITY_BANNER: 390 case UNITY_SAVE_PASSWD: 391 case UNITY_DEF_DOMAIN: 392 case UNITY_SPLITDNS_NAME: 393 case UNITY_SPLIT_INCLUDE: 394 case UNITY_NATT_PORT: 395 case UNITY_PFS: 396 case UNITY_FW_TYPE: 397 case UNITY_BACKUP_SERVERS: 398 case UNITY_DDNS_HOSTNAME: 399 default: 400 plog(LLV_WARNING, LOCATION, NULL, 401 "Ignored attribute %d\n", type); 402 break; 403 } 404 405 npp = (char *)attr; 406 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); 407 tlen -= (sizeof(*attr) + alen); 408 } 409 410 /* 411 * Call the SA up script hook now that we have the configuration 412 * It is done at the end of phase 1 if ISAKMP mode config is not 413 * requested. 414 */ 415 if ((iph1->status == PHASE1ST_ESTABLISHED) && 416 iph1->rmconf->mode_cfg) 417 script_hook(iph1, SCRIPT_PHASE1_UP); 418 419 #ifdef ENABLE_ADMINPORT 420 { 421 vchar_t *buf; 422 423 alen = ntohs(attrpl->h.len) - sizeof(*attrpl); 424 if ((buf = vmalloc(alen)) == NULL) { 425 plog(LLV_WARNING, LOCATION, NULL, 426 "Cannot allocate memory: %s\n", strerror(errno)); 427 } else { 428 memcpy(buf->v, attrpl + 1, buf->l); 429 EVT_PUSH(iph1->local, iph1->remote, 430 EVTT_ISAKMP_CFG_DONE, buf); 431 vfree(buf); 432 } 433 } 434 #endif 435 436 return 0; 437 } 438 439 int 440 isakmp_cfg_request(iph1, attrpl) 441 struct ph1handle *iph1; 442 struct isakmp_pl_attr *attrpl; 443 { 444 struct isakmp_data *attr; 445 int tlen; 446 size_t alen; 447 char *npp; 448 vchar_t *payload; 449 struct isakmp_pl_attr *reply; 450 vchar_t *reply_attr; 451 int type; 452 int error = -1; 453 454 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 455 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 456 return -1; 457 } 458 memset(payload->v, 0, sizeof(*reply)); 459 460 tlen = ntohs(attrpl->h.len); 461 attr = (struct isakmp_data *)(attrpl + 1); 462 tlen -= sizeof(*attrpl); 463 464 while (tlen > 0) { 465 reply_attr = NULL; 466 type = ntohs(attr->type); 467 468 /* Handle short attributes */ 469 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 470 type &= ~ISAKMP_GEN_MASK; 471 472 plog(LLV_DEBUG, LOCATION, NULL, 473 "Short attribute %d = %d\n", 474 type, ntohs(attr->lorv)); 475 476 switch (type) { 477 case XAUTH_TYPE: 478 reply_attr = isakmp_xauth_req(iph1, attr); 479 break; 480 default: 481 plog(LLV_WARNING, LOCATION, NULL, 482 "Ignored short attribute %d\n", type); 483 break; 484 } 485 486 tlen -= sizeof(*attr); 487 attr++; 488 489 if (reply_attr != NULL) { 490 payload = buffer_cat(payload, reply_attr); 491 vfree(reply_attr); 492 } 493 494 continue; 495 } 496 497 type = ntohs(attr->type); 498 alen = ntohs(attr->lorv); 499 500 /* Check that the attribute fit in the packet */ 501 if (tlen < alen) { 502 plog(LLV_ERROR, LOCATION, NULL, 503 "Short attribute %d\n", type); 504 goto end; 505 } 506 507 plog(LLV_DEBUG, LOCATION, NULL, 508 "Attribute %d, len %zu\n", type, alen); 509 510 switch(type) { 511 case INTERNAL_IP4_ADDRESS: 512 case INTERNAL_IP4_NETMASK: 513 case INTERNAL_IP4_DNS: 514 case INTERNAL_IP4_NBNS: 515 case INTERNAL_IP4_SUBNET: 516 reply_attr = isakmp_cfg_net(iph1, attr); 517 break; 518 519 case XAUTH_TYPE: 520 case XAUTH_USER_NAME: 521 case XAUTH_USER_PASSWORD: 522 case XAUTH_PASSCODE: 523 case XAUTH_MESSAGE: 524 case XAUTH_CHALLENGE: 525 case XAUTH_DOMAIN: 526 case XAUTH_STATUS: 527 case XAUTH_NEXT_PIN: 528 case XAUTH_ANSWER: 529 reply_attr = isakmp_xauth_req(iph1, attr); 530 break; 531 532 case APPLICATION_VERSION: 533 reply_attr = isakmp_cfg_string(iph1, 534 attr, ISAKMP_CFG_RACOON_VERSION); 535 break; 536 537 case UNITY_BANNER: 538 case UNITY_PFS: 539 case UNITY_SAVE_PASSWD: 540 case UNITY_DEF_DOMAIN: 541 case UNITY_DDNS_HOSTNAME: 542 case UNITY_FW_TYPE: 543 case UNITY_SPLITDNS_NAME: 544 case UNITY_SPLIT_INCLUDE: 545 case UNITY_NATT_PORT: 546 case UNITY_BACKUP_SERVERS: 547 reply_attr = isakmp_unity_req(iph1, attr); 548 break; 549 550 case INTERNAL_ADDRESS_EXPIRY: 551 default: 552 plog(LLV_WARNING, LOCATION, NULL, 553 "Ignored attribute %d\n", type); 554 break; 555 } 556 557 npp = (char *)attr; 558 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen); 559 tlen -= (sizeof(*attr) + alen); 560 561 if (reply_attr != NULL) { 562 payload = buffer_cat(payload, reply_attr); 563 vfree(reply_attr); 564 } 565 566 } 567 568 reply = (struct isakmp_pl_attr *)payload->v; 569 reply->h.len = htons(payload->l); 570 reply->type = ISAKMP_CFG_REPLY; 571 reply->id = attrpl->id; 572 573 error = isakmp_cfg_send(iph1, payload, 574 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 575 576 /* Reinit the IV */ 577 oakley_delivm(iph1->mode_cfg->ivm); 578 iph1->mode_cfg->ivm = NULL; 579 end: 580 vfree(payload); 581 582 return error; 583 } 584 585 int 586 isakmp_cfg_set(iph1, attrpl) 587 struct ph1handle *iph1; 588 struct isakmp_pl_attr *attrpl; 589 { 590 struct isakmp_data *attr; 591 int tlen; 592 size_t alen; 593 char *npp; 594 vchar_t *payload; 595 struct isakmp_pl_attr *reply; 596 vchar_t *reply_attr; 597 int type; 598 int error = -1; 599 600 if ((payload = vmalloc(sizeof(*reply))) == NULL) { 601 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 602 return -1; 603 } 604 memset(payload->v, 0, sizeof(*reply)); 605 606 tlen = ntohs(attrpl->h.len); 607 attr = (struct isakmp_data *)(attrpl + 1); 608 tlen -= sizeof(*attrpl); 609 610 /* 611 * We should send ack for the attributes we accepted 612 */ 613 while (tlen > 0) { 614 reply_attr = NULL; 615 type = ntohs(attr->type); 616 617 switch (type & ~ISAKMP_GEN_MASK) { 618 case XAUTH_STATUS: 619 reply_attr = isakmp_xauth_set(iph1, attr); 620 break; 621 default: 622 plog(LLV_DEBUG, LOCATION, NULL, 623 "Unexpected SET attribute %d\n", 624 type & ~ISAKMP_GEN_MASK); 625 break; 626 } 627 628 if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) { 629 payload = buffer_cat(payload, reply_attr); 630 vfree(reply_attr); 631 } 632 633 /* 634 * Move to next attribute. If we run out of the packet, 635 * tlen becomes negative and we exit. 636 */ 637 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) { 638 tlen -= sizeof(*attr); 639 attr++; 640 } else { 641 alen = ntohs(attr->lorv); 642 tlen -= (sizeof(*attr) + alen); 643 npp = (char *)attr; 644 attr = (struct isakmp_data *) 645 (npp + sizeof(*attr) + alen); 646 } 647 } 648 649 reply = (struct isakmp_pl_attr *)payload->v; 650 reply->h.len = htons(payload->l); 651 reply->type = ISAKMP_CFG_ACK; 652 reply->id = attrpl->id; 653 654 error = isakmp_cfg_send(iph1, payload, 655 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0); 656 657 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) { 658 if (iph1->status == PHASE1ST_ESTABLISHED) 659 isakmp_info_send_d1(iph1); 660 remph1(iph1); 661 delph1(iph1); 662 } 663 end: 664 vfree(payload); 665 666 /* 667 * If required, request ISAKMP mode config information 668 */ 669 if ((iph1->rmconf->mode_cfg) && (error == 0)) 670 error = isakmp_cfg_getconfig(iph1); 671 672 return error; 673 } 674 675 676 static vchar_t * 677 buffer_cat(s, append) 678 vchar_t *s; 679 vchar_t *append; 680 { 681 vchar_t *new; 682 683 new = vmalloc(s->l + append->l); 684 if (new == NULL) { 685 plog(LLV_ERROR, LOCATION, NULL, 686 "Cannot allocate memory\n"); 687 return s; 688 } 689 690 memcpy(new->v, s->v, s->l); 691 memcpy(new->v + s->l, append->v, append->l); 692 693 vfree(s); 694 return new; 695 } 696 697 static vchar_t * 698 isakmp_cfg_net(iph1, attr) 699 struct ph1handle *iph1; 700 struct isakmp_data *attr; 701 { 702 int type; 703 in_addr_t addr4; 704 705 type = ntohs(attr->type); 706 707 /* 708 * Don't give an address to a peer that did not succeed Xauth 709 */ 710 if (xauth_check(iph1) != 0) { 711 plog(LLV_ERROR, LOCATION, NULL, 712 "Attempt to start phase config whereas Xauth failed\n"); 713 return NULL; 714 } 715 716 switch(type) { 717 case INTERNAL_IP4_ADDRESS: 718 switch(isakmp_cfg_config.confsource) { 719 #ifdef HAVE_LIBRADIUS 720 case ISAKMP_CFG_CONF_RADIUS: 721 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) 722 && (iph1->mode_cfg->addr4.s_addr != htonl(-2))) 723 /* 724 * -2 is 255.255.255.254, RADIUS uses that 725 * to instruct the NAS to use a local pool 726 */ 727 break; 728 plog(LLV_INFO, LOCATION, NULL, 729 "No IP from RADIUS, using local pool\n"); 730 /* FALLTHROUGH */ 731 #endif 732 case ISAKMP_CFG_CONF_LOCAL: 733 if (isakmp_cfg_getport(iph1) == -1) { 734 plog(LLV_ERROR, LOCATION, NULL, 735 "Port pool depleted\n"); 736 break; 737 } 738 739 iph1->mode_cfg->addr4.s_addr = 740 htonl(ntohl(isakmp_cfg_config.network4) 741 + iph1->mode_cfg->port); 742 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL; 743 break; 744 745 default: 746 plog(LLV_ERROR, LOCATION, NULL, 747 "Unexpected confsource\n"); 748 } 749 750 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0) 751 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); 752 753 return isakmp_cfg_addr4(iph1, 754 attr, &iph1->mode_cfg->addr4.s_addr); 755 break; 756 757 case INTERNAL_IP4_NETMASK: 758 switch(isakmp_cfg_config.confsource) { 759 #ifdef HAVE_LIBRADIUS 760 case ISAKMP_CFG_CONF_RADIUS: 761 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_RADIUS) 762 break; 763 plog(LLV_INFO, LOCATION, NULL, 764 "No mask from RADIUS, using local pool\n"); 765 /* FALLTHROUGH */ 766 #endif 767 case ISAKMP_CFG_CONF_LOCAL: 768 iph1->mode_cfg->mask4.s_addr 769 = isakmp_cfg_config.netmask4; 770 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL; 771 break; 772 773 default: 774 plog(LLV_ERROR, LOCATION, NULL, 775 "Unexpected confsource\n"); 776 } 777 return isakmp_cfg_addr4(iph1, attr, 778 &iph1->mode_cfg->mask4.s_addr); 779 break; 780 781 case INTERNAL_IP4_DNS: 782 return isakmp_cfg_addr4(iph1, 783 attr, &isakmp_cfg_config.dns4); 784 break; 785 786 case INTERNAL_IP4_NBNS: 787 return isakmp_cfg_addr4(iph1, 788 attr, &isakmp_cfg_config.nbns4); 789 break; 790 791 case INTERNAL_IP4_SUBNET: 792 return isakmp_cfg_addr4(iph1, 793 attr, &isakmp_cfg_config.network4); 794 break; 795 796 default: 797 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type); 798 break; 799 } 800 801 return NULL; 802 } 803 804 #if 0 805 static vchar_t * 806 isakmp_cfg_void(iph1, attr) 807 struct ph1handle *iph1; 808 struct isakmp_data *attr; 809 { 810 vchar_t *buffer; 811 struct isakmp_data *new; 812 813 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 814 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 815 return NULL; 816 } 817 818 new = (struct isakmp_data *)buffer->v; 819 820 new->type = attr->type; 821 new->lorv = htons(0); 822 823 return buffer; 824 } 825 #endif 826 827 vchar_t * 828 isakmp_cfg_copy(iph1, attr) 829 struct ph1handle *iph1; 830 struct isakmp_data *attr; 831 { 832 vchar_t *buffer; 833 size_t len = 0; 834 835 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV) 836 len = ntohs(attr->lorv); 837 838 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 839 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 840 return NULL; 841 } 842 843 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv)); 844 845 return buffer; 846 } 847 848 vchar_t * 849 isakmp_cfg_short(iph1, attr, value) 850 struct ph1handle *iph1; 851 struct isakmp_data *attr; 852 int value; 853 { 854 vchar_t *buffer; 855 struct isakmp_data *new; 856 int type; 857 858 if ((buffer = vmalloc(sizeof(*attr))) == NULL) { 859 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 860 return NULL; 861 } 862 863 new = (struct isakmp_data *)buffer->v; 864 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK; 865 866 new->type = htons(type | ISAKMP_GEN_TV); 867 new->lorv = htons(value); 868 869 return buffer; 870 } 871 872 vchar_t * 873 isakmp_cfg_string(iph1, attr, string) 874 struct ph1handle *iph1; 875 struct isakmp_data *attr; 876 char *string; 877 { 878 vchar_t *buffer; 879 struct isakmp_data *new; 880 size_t len; 881 char *data; 882 883 len = strlen(string); 884 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 885 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 886 return NULL; 887 } 888 889 new = (struct isakmp_data *)buffer->v; 890 891 new->type = attr->type; 892 new->lorv = htons(len); 893 data = (char *)(new + 1); 894 895 memcpy(data, string, len); 896 897 return buffer; 898 } 899 900 static vchar_t * 901 isakmp_cfg_addr4(iph1, attr, addr) 902 struct ph1handle *iph1; 903 struct isakmp_data *attr; 904 in_addr_t *addr; 905 { 906 vchar_t *buffer; 907 struct isakmp_data *new; 908 size_t len; 909 910 len = sizeof(*addr); 911 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) { 912 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 913 return NULL; 914 } 915 916 new = (struct isakmp_data *)buffer->v; 917 918 new->type = attr->type; 919 new->lorv = htons(len); 920 memcpy(new + 1, addr, len); 921 922 return buffer; 923 } 924 925 struct isakmp_ivm * 926 isakmp_cfg_newiv(iph1, msgid) 927 struct ph1handle *iph1; 928 u_int32_t msgid; 929 { 930 struct isakmp_cfg_state *ics = iph1->mode_cfg; 931 932 if (ics == NULL) { 933 plog(LLV_ERROR, LOCATION, NULL, 934 "isakmp_cfg_newiv called without mode config state\n"); 935 return NULL; 936 } 937 938 if (ics->ivm != NULL) 939 oakley_delivm(ics->ivm); 940 941 ics->ivm = oakley_newiv2(iph1, msgid); 942 943 return ics->ivm; 944 } 945 946 /* Derived from isakmp_info_send_common */ 947 int 948 isakmp_cfg_send(iph1, payload, np, flags, new_exchange) 949 struct ph1handle *iph1; 950 vchar_t *payload; 951 u_int32_t np; 952 int flags; 953 int new_exchange; 954 { 955 struct ph2handle *iph2 = NULL; 956 vchar_t *hash = NULL; 957 struct isakmp *isakmp; 958 struct isakmp_gen *gen; 959 char *p; 960 int tlen; 961 int error = -1; 962 struct isakmp_cfg_state *ics = iph1->mode_cfg; 963 964 /* Check if phase 1 is established */ 965 if ((iph1->status != PHASE1ST_ESTABLISHED) || 966 (iph1->local == NULL) || 967 (iph1->remote == NULL)) { 968 plog(LLV_ERROR, LOCATION, NULL, 969 "ISAKMP mode config exchange with immature phase 1\n"); 970 goto end; 971 } 972 973 /* add new entry to isakmp status table */ 974 iph2 = newph2(); 975 if (iph2 == NULL) 976 goto end; 977 978 iph2->dst = dupsaddr(iph1->remote); 979 iph2->src = dupsaddr(iph1->local); 980 switch (iph1->remote->sa_family) { 981 case AF_INET: 982 #ifndef ENABLE_NATT 983 ((struct sockaddr_in *)iph2->dst)->sin_port = 0; 984 ((struct sockaddr_in *)iph2->src)->sin_port = 0; 985 #endif 986 break; 987 #ifdef INET6 988 case AF_INET6: 989 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0; 990 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0; 991 break; 992 #endif 993 default: 994 plog(LLV_ERROR, LOCATION, NULL, 995 "invalid family: %d\n", iph1->remote->sa_family); 996 delph2(iph2); 997 goto end; 998 } 999 iph2->ph1 = iph1; 1000 iph2->side = INITIATOR; 1001 iph2->status = PHASE2ST_START; 1002 1003 if (new_exchange) 1004 iph2->msgid = isakmp_newmsgid2(iph1); 1005 else 1006 iph2->msgid = iph1->msgid; 1007 1008 /* get IV and HASH(1) if skeyid_a was generated. */ 1009 if (iph1->skeyid_a != NULL) { 1010 if (new_exchange) { 1011 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) { 1012 delph2(iph2); 1013 goto end; 1014 } 1015 } 1016 1017 /* generate HASH(1) */ 1018 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload); 1019 if (hash == NULL) { 1020 delph2(iph2); 1021 goto end; 1022 } 1023 1024 /* initialized total buffer length */ 1025 tlen = hash->l; 1026 tlen += sizeof(*gen); 1027 } else { 1028 /* IKE-SA is not established */ 1029 hash = NULL; 1030 1031 /* initialized total buffer length */ 1032 tlen = 0; 1033 } 1034 if ((flags & ISAKMP_FLAG_A) == 0) 1035 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E); 1036 else 1037 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A); 1038 1039 insph2(iph2); 1040 bindph12(iph1, iph2); 1041 1042 tlen += sizeof(*isakmp) + payload->l; 1043 1044 /* create buffer for isakmp payload */ 1045 iph2->sendbuf = vmalloc(tlen); 1046 if (iph2->sendbuf == NULL) { 1047 plog(LLV_ERROR, LOCATION, NULL, 1048 "failed to get buffer to send.\n"); 1049 goto err; 1050 } 1051 1052 /* create isakmp header */ 1053 isakmp = (struct isakmp *)iph2->sendbuf->v; 1054 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t)); 1055 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t)); 1056 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH; 1057 isakmp->v = iph1->version; 1058 isakmp->etype = ISAKMP_ETYPE_CFG; 1059 isakmp->flags = iph2->flags; 1060 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid)); 1061 isakmp->len = htonl(tlen); 1062 p = (char *)(isakmp + 1); 1063 1064 /* create HASH payload */ 1065 if (hash != NULL) { 1066 gen = (struct isakmp_gen *)p; 1067 gen->np = np & 0xff; 1068 gen->len = htons(sizeof(*gen) + hash->l); 1069 p += sizeof(*gen); 1070 memcpy(p, hash->v, hash->l); 1071 p += hash->l; 1072 } 1073 1074 /* add payload */ 1075 memcpy(p, payload->v, payload->l); 1076 p += payload->l; 1077 1078 #ifdef HAVE_PRINT_ISAKMP_C 1079 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1); 1080 #endif 1081 1082 /* encoding */ 1083 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) { 1084 vchar_t *tmp; 1085 1086 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 1087 ics->ivm->ive, ics->ivm->iv); 1088 VPTRINIT(iph2->sendbuf); 1089 if (tmp == NULL) 1090 goto err; 1091 iph2->sendbuf = tmp; 1092 } 1093 1094 /* HDR*, HASH(1), ATTR */ 1095 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) { 1096 VPTRINIT(iph2->sendbuf); 1097 goto err; 1098 } 1099 1100 plog(LLV_DEBUG, LOCATION, NULL, 1101 "sendto mode config %s.\n", s_isakmp_nptype(np)); 1102 1103 /* 1104 * XXX We might need to resend the message... 1105 */ 1106 1107 error = 0; 1108 VPTRINIT(iph2->sendbuf); 1109 1110 err: 1111 if (iph2->sendbuf != NULL) 1112 vfree(iph2->sendbuf); 1113 1114 unbindph12(iph2); 1115 remph2(iph2); 1116 delph2(iph2); 1117 end: 1118 if (hash) 1119 vfree(hash); 1120 return error; 1121 } 1122 1123 1124 void 1125 isakmp_cfg_rmstate(iph1) 1126 struct ph1handle *iph1; 1127 { 1128 struct isakmp_cfg_state *state = iph1->mode_cfg; 1129 1130 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0) 1131 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n"); 1132 1133 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED) 1134 isakmp_cfg_putport(iph1, state->port); 1135 1136 xauth_rmstate(&state->xauth); 1137 1138 racoon_free(state); 1139 iph1->mode_cfg = NULL; 1140 1141 return; 1142 } 1143 1144 struct isakmp_cfg_state * 1145 isakmp_cfg_mkstate(void) 1146 { 1147 struct isakmp_cfg_state *state; 1148 1149 if ((state = racoon_malloc(sizeof(*state))) == NULL) { 1150 plog(LLV_ERROR, LOCATION, NULL, 1151 "Cannot allocate memory for mode config state\n"); 1152 return NULL; 1153 } 1154 memset(state, 0, sizeof(*state)); 1155 1156 return state; 1157 } 1158 1159 int 1160 isakmp_cfg_getport(iph1) 1161 struct ph1handle *iph1; 1162 { 1163 unsigned int i; 1164 size_t size = isakmp_cfg_config.pool_size; 1165 1166 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED) 1167 return iph1->mode_cfg->port; 1168 1169 if (isakmp_cfg_config.port_pool == NULL) { 1170 plog(LLV_ERROR, LOCATION, NULL, 1171 "isakmp_cfg_config.port_pool == NULL\n"); 1172 return -1; 1173 } 1174 1175 for (i = 0; i < size; i++) { 1176 if (isakmp_cfg_config.port_pool[i].used == 0) 1177 break; 1178 } 1179 1180 if (i == size) { 1181 plog(LLV_ERROR, LOCATION, NULL, 1182 "No more addresses available\n"); 1183 return -1; 1184 } 1185 1186 isakmp_cfg_config.port_pool[i].used = 1; 1187 1188 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i); 1189 1190 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED; 1191 iph1->mode_cfg->port = i; 1192 1193 return i; 1194 } 1195 1196 int 1197 isakmp_cfg_putport(iph1, index) 1198 struct ph1handle *iph1; 1199 unsigned int index; 1200 { 1201 if (isakmp_cfg_config.port_pool == NULL) { 1202 plog(LLV_ERROR, LOCATION, NULL, 1203 "isakmp_cfg_config.port_pool == NULL\n"); 1204 return -1; 1205 } 1206 1207 if (isakmp_cfg_config.port_pool[index].used == 0) { 1208 plog(LLV_ERROR, LOCATION, NULL, 1209 "Attempt to release an unallocated address (port %d)\n", 1210 index); 1211 return -1; 1212 } 1213 1214 #ifdef HAVE_LIBPAM 1215 /* Cleanup PAM status associated with the port */ 1216 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM) 1217 privsep_cleanup_pam(index); 1218 #endif 1219 isakmp_cfg_config.port_pool[index].used = 0; 1220 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED; 1221 1222 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index); 1223 1224 return 0; 1225 } 1226 1227 #ifdef HAVE_LIBPAM 1228 void 1229 cleanup_pam(port) 1230 int port; 1231 { 1232 if (isakmp_cfg_config.port_pool[port].pam != NULL) { 1233 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS); 1234 isakmp_cfg_config.port_pool[port].pam = NULL; 1235 } 1236 1237 return; 1238 } 1239 #endif 1240 1241 /* Accounting, only for RADIUS or PAM */ 1242 static int 1243 isakmp_cfg_accounting(iph1, inout) 1244 struct ph1handle *iph1; 1245 int inout; 1246 { 1247 #ifdef HAVE_LIBPAM 1248 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM) 1249 return privsep_accounting_pam(iph1->mode_cfg->port, 1250 inout); 1251 #endif 1252 #ifdef HAVE_LIBRADIUS 1253 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) 1254 return isakmp_cfg_accounting_radius(iph1, inout); 1255 #endif 1256 return 0; 1257 } 1258 1259 #ifdef HAVE_LIBPAM 1260 int 1261 isakmp_cfg_accounting_pam(port, inout) 1262 int port; 1263 int inout; 1264 { 1265 int error = 0; 1266 pam_handle_t *pam; 1267 1268 if (isakmp_cfg_config.port_pool == NULL) { 1269 plog(LLV_ERROR, LOCATION, NULL, 1270 "isakmp_cfg_config.port_pool == NULL\n"); 1271 return -1; 1272 } 1273 1274 pam = isakmp_cfg_config.port_pool[port].pam; 1275 if (pam == NULL) { 1276 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n"); 1277 return -1; 1278 } 1279 1280 switch (inout) { 1281 case ISAKMP_CFG_LOGIN: 1282 error = pam_open_session(pam, 0); 1283 break; 1284 case ISAKMP_CFG_LOGOUT: 1285 error = pam_close_session(pam, 0); 1286 pam_end(pam, error); 1287 isakmp_cfg_config.port_pool[port].pam = NULL; 1288 break; 1289 default: 1290 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1291 break; 1292 } 1293 1294 if (error != 0) { 1295 plog(LLV_ERROR, LOCATION, NULL, 1296 "pam_open_session/pam_close_session failed: %s\n", 1297 pam_strerror(pam, error)); 1298 return -1; 1299 } 1300 1301 return 0; 1302 } 1303 #endif /* HAVE_LIBPAM */ 1304 1305 #ifdef HAVE_LIBRADIUS 1306 static int 1307 isakmp_cfg_accounting_radius(iph1, inout) 1308 struct ph1handle *iph1; 1309 int inout; 1310 { 1311 /* For first time use, initialize Radius */ 1312 if (radius_acct_state == NULL) { 1313 if ((radius_acct_state = rad_acct_open()) == NULL) { 1314 plog(LLV_ERROR, LOCATION, NULL, 1315 "Cannot init librradius\n"); 1316 return -1; 1317 } 1318 1319 if (rad_config(radius_acct_state, NULL) != 0) { 1320 plog(LLV_ERROR, LOCATION, NULL, 1321 "Cannot open librarius config file: %s\n", 1322 rad_strerror(radius_acct_state)); 1323 rad_close(radius_acct_state); 1324 radius_acct_state = NULL; 1325 return -1; 1326 } 1327 } 1328 1329 if (rad_create_request(radius_acct_state, 1330 RAD_ACCOUNTING_REQUEST) != 0) { 1331 plog(LLV_ERROR, LOCATION, NULL, 1332 "rad_create_request failed: %s\n", 1333 rad_strerror(radius_acct_state)); 1334 return -1; 1335 } 1336 1337 if (rad_put_string(radius_acct_state, RAD_USER_NAME, 1338 iph1->mode_cfg->login) != 0) { 1339 plog(LLV_ERROR, LOCATION, NULL, 1340 "rad_put_string failed: %s\n", 1341 rad_strerror(radius_acct_state)); 1342 return -1; 1343 } 1344 1345 switch (inout) { 1346 case ISAKMP_CFG_LOGIN: 1347 inout = RAD_START; 1348 break; 1349 case ISAKMP_CFG_LOGOUT: 1350 inout = RAD_STOP; 1351 break; 1352 default: 1353 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n"); 1354 break; 1355 } 1356 1357 if (rad_put_addr(radius_acct_state, 1358 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) { 1359 plog(LLV_ERROR, LOCATION, NULL, 1360 "rad_put_addr failed: %s\n", 1361 rad_strerror(radius_acct_state)); 1362 return -1; 1363 } 1364 1365 if (rad_put_addr(radius_acct_state, 1366 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) { 1367 plog(LLV_ERROR, LOCATION, NULL, 1368 "rad_put_addr failed: %s\n", 1369 rad_strerror(radius_acct_state)); 1370 return -1; 1371 } 1372 1373 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) { 1374 plog(LLV_ERROR, LOCATION, NULL, 1375 "rad_put_int failed: %s\n", 1376 rad_strerror(radius_acct_state)); 1377 return -1; 1378 } 1379 1380 if (isakmp_cfg_radius_common(radius_acct_state, 1381 iph1->mode_cfg->port) != 0) 1382 return -1; 1383 1384 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) { 1385 plog(LLV_ERROR, LOCATION, NULL, 1386 "rad_send_request failed: %s\n", 1387 rad_strerror(radius_acct_state)); 1388 return -1; 1389 } 1390 1391 return 0; 1392 } 1393 #endif /* HAVE_LIBRADIUS */ 1394 1395 /* 1396 * Attributes common to all RADIUS requests 1397 */ 1398 #ifdef HAVE_LIBRADIUS 1399 int 1400 isakmp_cfg_radius_common(radius_state, port) 1401 struct rad_handle *radius_state; 1402 int port; 1403 { 1404 struct utsname name; 1405 static struct hostent *host = NULL; 1406 struct in_addr nas_addr; 1407 1408 /* 1409 * Find our own IP by resolving our nodename 1410 */ 1411 if (host == NULL) { 1412 if (uname(&name) != 0) { 1413 plog(LLV_ERROR, LOCATION, NULL, 1414 "uname failed: %s\n", strerror(errno)); 1415 return -1; 1416 } 1417 1418 if ((host = gethostbyname(name.nodename)) == NULL) { 1419 plog(LLV_ERROR, LOCATION, NULL, 1420 "gethostbyname failed: %s\n", strerror(errno)); 1421 return -1; 1422 } 1423 } 1424 1425 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr)); 1426 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) { 1427 plog(LLV_ERROR, LOCATION, NULL, 1428 "rad_put_addr failed: %s\n", 1429 rad_strerror(radius_state)); 1430 return -1; 1431 } 1432 1433 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) { 1434 plog(LLV_ERROR, LOCATION, NULL, 1435 "rad_put_int failed: %s\n", 1436 rad_strerror(radius_state)); 1437 return -1; 1438 } 1439 1440 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) { 1441 plog(LLV_ERROR, LOCATION, NULL, 1442 "rad_put_int failed: %s\n", 1443 rad_strerror(radius_state)); 1444 return -1; 1445 } 1446 1447 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) { 1448 plog(LLV_ERROR, LOCATION, NULL, 1449 "rad_put_int failed: %s\n", 1450 rad_strerror(radius_state)); 1451 return -1; 1452 } 1453 1454 return 0; 1455 } 1456 #endif 1457 1458 int 1459 isakmp_cfg_getconfig(iph1) 1460 struct ph1handle *iph1; 1461 { 1462 vchar_t *buffer; 1463 struct isakmp_pl_attr *attrpl; 1464 struct isakmp_data *attr; 1465 size_t len; 1466 int error; 1467 int attrcount; 1468 int i; 1469 int attrlist[] = { 1470 INTERNAL_IP4_ADDRESS, 1471 INTERNAL_IP4_NETMASK, 1472 INTERNAL_IP4_DNS, 1473 INTERNAL_IP4_NBNS, 1474 UNITY_BANNER, 1475 APPLICATION_VERSION, 1476 }; 1477 1478 attrcount = sizeof(attrlist) / sizeof(*attrlist); 1479 len = sizeof(*attrpl) + sizeof(*attr) * attrcount; 1480 1481 if ((buffer = vmalloc(len)) == NULL) { 1482 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 1483 return -1; 1484 } 1485 1486 attrpl = (struct isakmp_pl_attr *)buffer->v; 1487 attrpl->h.len = htons(len); 1488 attrpl->type = ISAKMP_CFG_REQUEST; 1489 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff)); 1490 1491 attr = (struct isakmp_data *)(attrpl + 1); 1492 1493 for (i = 0; i < attrcount; i++) { 1494 attr->type = htons(attrlist[i]); 1495 attr->lorv = htons(0); 1496 attr++; 1497 } 1498 1499 error = isakmp_cfg_send(iph1, buffer, 1500 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1); 1501 1502 vfree(buffer); 1503 1504 return error; 1505 } 1506 1507 static void 1508 isakmp_cfg_getaddr4(attr, ip) 1509 struct isakmp_data *attr; 1510 struct in_addr *ip; 1511 { 1512 size_t alen = ntohs(attr->lorv); 1513 in_addr_t *addr; 1514 1515 if (alen != sizeof(*ip)) { 1516 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n"); 1517 return; 1518 } 1519 1520 addr = (in_addr_t *)(attr + 1); 1521 ip->s_addr = *addr; 1522 1523 return; 1524 } 1525 1526 int 1527 isakmp_cfg_setenv(iph1, envp, envc) 1528 struct ph1handle *iph1; 1529 char ***envp; 1530 int *envc; 1531 { 1532 #define IP_MAX 40 1533 char addrstr[IP_MAX]; 1534 1535 /* 1536 * Internal IPv4 address, either if 1537 * we are a client or a server. 1538 */ 1539 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) || 1540 #ifdef HAVE_LIBRADIUS 1541 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_RADIUS) || 1542 #endif 1543 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) { 1544 inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 1545 addrstr, IP_MAX); 1546 } else 1547 addrstr[0] = '\0'; 1548 1549 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) { 1550 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n"); 1551 return -1; 1552 } 1553 1554 /* Internal IPv4 mask */ 1555 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 1556 inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 1557 addrstr, IP_MAX); 1558 else 1559 addrstr[0] = '\0'; 1560 1561 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 1562 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n"); 1563 return -1; 1564 } 1565 1566 /* Internal IPv4 DNS */ 1567 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) 1568 inet_ntop(AF_INET, &iph1->mode_cfg->dns4, 1569 addrstr, IP_MAX); 1570 else 1571 addrstr[0] = '\0'; 1572 1573 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) { 1574 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n"); 1575 return -1; 1576 } 1577 1578 /* Internal IPv4 WINS */ 1579 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) 1580 inet_ntop(AF_INET, &iph1->mode_cfg->wins4, 1581 addrstr, IP_MAX); 1582 else 1583 addrstr[0] = '\0'; 1584 1585 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) { 1586 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_WINS4\n"); 1587 return -1; 1588 } 1589 1590 return 0; 1591 } 1592