1/* 2 * Layer Two Tunnelling Protocol Daemon 3 * Copyright (C) 1998 Adtran, Inc. 4 * Copyright (C) 2002 Jeff McAdams 5 * 6 * Mark Spencer 7 * 8 * This software is distributed under the terms 9 * of the GPL, which you should have received 10 * along with this source. 11 * 12 * File format handling 13 * 14 */ 15 16#include <stdio.h> 17#include <string.h> 18#include <unistd.h> 19#include <stdlib.h> 20#include <netdb.h> 21#include <netinet/in.h> 22#include <time.h> 23#include <sys/types.h> 24#include <sys/socket.h> 25 26#include "l2tp.h" 27 28struct lns *lnslist; 29struct lac *laclist; 30struct lns *deflns; 31struct lac *deflac; 32struct global gconfig; 33char filerr[STRLEN]; 34 35int parse_config (FILE *); 36struct keyword words[]; 37 38int init_config () 39{ 40 FILE *f; 41 int returnedValue; 42 43 gconfig.port = UDP_LISTEN_PORT; 44 lnslist = NULL; 45 laclist = NULL; 46 deflac = (struct lac *) malloc (sizeof (struct lac)); 47 48 f = fopen (gconfig.configfile, "r"); 49 if (!f) 50 { 51 f = fopen (gconfig.altconfigfile, "r"); 52 if (f) 53 { 54 strncpy (gconfig.authfile, gconfig.altauthfile, 55 sizeof (gconfig.authfile)); 56 } 57 else 58 { 59 log (LOG_CRIT, "%s: Unable to open config file %s or %s\n", 60 __FUNCTION__, gconfig.configfile, gconfig.altconfigfile); 61 return -1; 62 } 63 64 } 65 returnedValue = parse_config (f); 66 fclose (f); 67 return (returnedValue); 68 filerr[0] = 0; 69} 70 71struct lns *new_lns () 72{ 73 struct lns *tmp; 74 tmp = (struct lns *) malloc (sizeof (struct lns)); 75 if (!tmp) 76 { 77 log (LOG_CRIT, "%s: Unable to allocate memory for new LNS\n", 78 __FUNCTION__); 79 return NULL; 80 } 81 tmp->next = NULL; 82 tmp->exclusive = 0; 83 tmp->localaddr = 0; 84 tmp->tun_rws = DEFAULT_RWS_SIZE; 85 tmp->call_rws = DEFAULT_RWS_SIZE; 86 tmp->hbit = 0; 87 tmp->lbit = 0; 88 tmp->authpeer = 0; 89 tmp->authself = -1; 90 tmp->authname[0] = 0; 91 tmp->peername[0] = 0; 92 tmp->hostname[0] = 0; 93 tmp->entname[0] = 0; 94 tmp->range = NULL; 95 tmp->lacs = NULL; 96 tmp->passwdauth = 0; 97 tmp->pap_require = 0; 98 tmp->pap_refuse = 0; 99 tmp->chap_require = 0; 100 tmp->chap_refuse = 0; 101 tmp->idle = 0; 102 tmp->pridns = 0; 103 tmp->secdns = 0; 104 tmp->priwins = 0; 105 tmp->secwins = 0; 106 tmp->proxyarp = 0; 107 tmp->proxyauth = 0; 108 tmp->challenge = 0; 109 tmp->debug = 0; 110 tmp->pppoptfile[0] = 0; 111 tmp->t = NULL; 112 return tmp; 113} 114 115struct lac *new_lac () 116{ 117 struct lac *tmp; 118 tmp = (struct lac *) malloc (sizeof (struct lac)); 119 if (!tmp) 120 { 121 log (LOG_CRIT, "%s: Unable to allocate memory for lac entry!\n", 122 __FUNCTION__); 123 return NULL; 124 } 125 tmp->next = NULL; 126 tmp->rsched = NULL; 127 tmp->localaddr = 0; 128 tmp->remoteaddr = 0; 129 tmp->lns = 0; 130 tmp->tun_rws = DEFAULT_RWS_SIZE; 131 tmp->call_rws = DEFAULT_RWS_SIZE; 132 tmp->hbit = 0; 133 tmp->lbit = 0; 134 tmp->authpeer = 0; 135 tmp->authself = -1; 136 tmp->authname[0] = 0; 137 tmp->peername[0] = 0; 138 tmp->hostname[0] = 0; 139 tmp->entname[0] = 0; 140 tmp->pap_require = 0; 141 tmp->pap_refuse = 0; 142 tmp->chap_require = 0; 143 tmp->chap_refuse = 0; 144 tmp->t = NULL; 145 tmp->redial = 0; 146 tmp->rtries = 0; 147 tmp->rmax = 0; 148 tmp->challenge = 0; 149 tmp->autodial = 0; 150 tmp->rtimeout = 30; 151 tmp->active = 0; 152 tmp->debug = 0; 153 tmp->pppoptfile[0] = 0; 154 tmp->defaultroute = 0; 155 return tmp; 156} 157 158int yesno (char *value) 159{ 160 if (!strcasecmp (value, "yes") || !strcasecmp (value, "y") || 161 !strcasecmp (value, "true")) 162 return 1; 163 else if (!strcasecmp (value, "no") || !strcasecmp (value, "n") || 164 !strcasecmp (value, "false")) 165 return 0; 166 else 167 return -1; 168} 169 170int set_boolean (char *word, char *value, int *ptr) 171{ 172 int val; 173#ifdef DEBUG_FILE 174 log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value); 175#endif /* ; */ 176 if ((val = yesno (value)) < 0) 177 { 178 snprintf (filerr, sizeof (filerr), "%s must be 'yes' or 'no'\n", 179 word); 180 return -1; 181 } 182 *ptr = val; 183 return 0; 184} 185 186int set_int (char *word, char *value, int *ptr) 187{ 188 int val; 189#ifdef DEBUG_FILE 190 log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value); 191#endif /* ; */ 192 if ((val = atoi (value)) < 0) 193 { 194 snprintf (filerr, sizeof (filerr), "%s must be a number\n", word); 195 return -1; 196 } 197 *ptr = val; 198 return 0; 199} 200 201int set_string (char *word, char *value, char *ptr, int len) 202{ 203#ifdef DEBUG_FILE 204 log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value); 205#endif /* ; */ 206 strncpy (ptr, value, len); 207 return 0; 208} 209 210int set_port (char *word, char *value, int context, void *item) 211{ 212 switch (context & ~CONTEXT_DEFAULT) 213 { 214 case CONTEXT_GLOBAL: 215#ifdef DEBUG_FILE 216 log (LOG_DEBUG, "set_port: Setting global port number to %s\n", 217 value); 218#endif 219 set_int (word, value, &(((struct global *) item)->port)); 220 break; 221 default: 222 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 223 word); 224 return -1; 225 } 226 return 0; 227} 228 229int set_rtimeout (char *word, char *value, int context, void *item) 230{ 231 if (atoi (value) < 1) 232 { 233 snprintf (filerr, sizeof (filerr), 234 "rtimeout value must be at least 1\n"); 235 return -1; 236 } 237 switch (context & ~CONTEXT_DEFAULT) 238 { 239 case CONTEXT_LAC: 240#ifdef DEBUG_FILE 241 log (LOG_DEBUG, "set_rtimeout: Setting redial timeout to %s\n", 242 value); 243#endif 244 set_int (word, value, &(((struct lac *) item)->rtimeout)); 245 break; 246 default: 247 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 248 word); 249 return -1; 250 } 251 return 0; 252} 253 254int set_rws (char *word, char *value, int context, void *item) 255{ 256 if (atoi (value) < -1) 257 { 258 snprintf (filerr, sizeof (filerr), 259 "receive window size must be at least -1\n"); 260 return -1; 261 } 262 switch (context & ~CONTEXT_DEFAULT) 263 { 264 case CONTEXT_LAC: 265 if (word[0] == 'c') 266 set_int (word, value, &(((struct lac *) item)->call_rws)); 267 if (word[0] == 't') 268 { 269 set_int (word, value, &(((struct lac *) item)->tun_rws)); 270 if (((struct lac *) item)->tun_rws < 1) 271 { 272 snprintf (filerr, sizeof (filerr), 273 "receive window size for tunnels must be at least 1\n"); 274 return -1; 275 } 276 } 277 break; 278 case CONTEXT_LNS: 279 if (word[0] == 'c') 280 set_int (word, value, &(((struct lns *) item)->call_rws)); 281 if (word[0] == 't') 282 { 283 set_int (word, value, &(((struct lns *) item)->tun_rws)); 284 if (((struct lns *) item)->tun_rws < 1) 285 { 286 snprintf (filerr, sizeof (filerr), 287 "receive window size for tunnels must be at least 1\n"); 288 return -1; 289 } 290 } 291 break; 292 default: 293 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 294 word); 295 return -1; 296 } 297 return 0; 298} 299 300int set_rmax (char *word, char *value, int context, void *item) 301{ 302 if (atoi (value) < 1) 303 { 304 snprintf (filerr, sizeof (filerr), "rmax value must be at least 1\n"); 305 return -1; 306 } 307 switch (context & ~CONTEXT_DEFAULT) 308 { 309 case CONTEXT_LAC: 310#ifdef DEBUG_FILE 311 log (LOG_DEBUG, "set_rmax: Setting max redials to %s\n", value); 312#endif 313 set_int (word, value, &(((struct lac *) item)->rmax)); 314 break; 315 default: 316 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 317 word); 318 return -1; 319 } 320 return 0; 321} 322 323int set_authfile (char *word, char *value, int context, void *item) 324{ 325 if (!strlen (value)) 326 { 327 snprintf (filerr, sizeof (filerr), 328 "no filename specified for authentication\n"); 329 return -1; 330 } 331 switch (context & ~CONTEXT_DEFAULT) 332 { 333 case CONTEXT_GLOBAL: 334#ifdef DEBUG_FILE 335 log (LOG_DEBUG, "set_authfile: Setting global auth file to '%s'\n", 336 value); 337#endif /* ; */ 338 strncpy (((struct global *) item)->authfile, value, 339 sizeof (((struct global *)item)->authfile)); 340 break; 341 default: 342 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 343 word); 344 return -1; 345 } 346 return 0; 347} 348 349int set_autodial (char *word, char *value, int context, void *item) 350{ 351 switch (context & ~CONTEXT_DEFAULT) 352 { 353 case CONTEXT_LAC: 354 if (set_boolean (word, value, &(((struct lac *) item)->autodial))) 355 return -1; 356 break; 357 default: 358 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 359 word); 360 return -1; 361 } 362 return 0; 363} 364 365int set_flow (char *word, char *value, int context, void *item) 366{ 367 int v; 368 set_boolean (word, value, &v); 369 if (v < 0) 370 return -1; 371 switch (context & ~CONTEXT_DEFAULT) 372 { 373 case CONTEXT_LAC: 374 if (v) 375 { 376 if (((struct lac *) item)->call_rws < 0) 377 ((struct lac *) item)->call_rws = 0; 378 } 379 else 380 { 381 ((struct lac *) item)->call_rws = -1; 382 } 383 break; 384 case CONTEXT_LNS: 385 if (v) 386 { 387 if (((struct lns *) item)->call_rws < 0) 388 ((struct lns *) item)->call_rws = 0; 389 } 390 else 391 { 392 ((struct lns *) item)->call_rws = -1; 393 } 394 break; 395 default: 396 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 397 word); 398 return -1; 399 } 400 return 0; 401} 402 403int set_defaultroute (char *word, char *value, int context, void *item) 404{ 405 switch (context & ~CONTEXT_DEFAULT) 406 { 407 case CONTEXT_LAC: 408 if (set_boolean (word, value, &(((struct lac *) item)->defaultroute))) 409 return -1; 410 break; 411 default: 412 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 413 word); 414 return -1; 415 } 416 return 0; 417} 418 419int set_authname (char *word, char *value, int context, void *item) 420{ 421 struct lac *l = (struct lac *) item; 422 struct lns *n = (struct lns *) item; 423 switch (context & ~CONTEXT_DEFAULT) 424 { 425 case CONTEXT_LNS: 426 if (set_string (word, value, n->authname, sizeof (n->authname))) 427 return -1; 428 break; 429 case CONTEXT_LAC: 430 if (set_string (word, value, l->authname, sizeof (l->authname))) 431 return -1; 432 break; 433 default: 434 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 435 word); 436 return -1; 437 } 438 return 0; 439} 440 441int set_hostname (char *word, char *value, int context, void *item) 442{ 443 struct lac *l = (struct lac *) item; 444 struct lns *n = (struct lns *) item; 445 switch (context & ~CONTEXT_DEFAULT) 446 { 447 case CONTEXT_LNS: 448 if (set_string (word, value, n->hostname, sizeof (n->hostname))) 449 return -1; 450 break; 451 case CONTEXT_LAC: 452 if (set_string (word, value, l->hostname, sizeof (l->hostname))) 453 return -1; 454 break; 455 default: 456 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 457 word); 458 return -1; 459 } 460 return 0; 461} 462 463int set_passwdauth (char *word, char *value, int context, void *item) 464{ 465 switch (context & ~CONTEXT_DEFAULT) 466 { 467 case CONTEXT_LNS: 468 if (set_boolean (word, value, &(((struct lns *) item)->passwdauth))) 469 return -1; 470 break; 471 default: 472 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 473 word); 474 return -1; 475 } 476 return 0; 477} 478 479int set_hbit (char *word, char *value, int context, void *item) 480{ 481 switch (context & ~CONTEXT_DEFAULT) 482 { 483 case CONTEXT_LAC: 484 if (set_boolean (word, value, &(((struct lac *) item)->hbit))) 485 return -1; 486 break; 487 case CONTEXT_LNS: 488 if (set_boolean (word, value, &(((struct lns *) item)->hbit))) 489 return -1; 490 break; 491 default: 492 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 493 word); 494 return -1; 495 } 496 return 0; 497} 498 499int set_challenge (char *word, char *value, int context, void *item) 500{ 501 switch (context & ~CONTEXT_DEFAULT) 502 { 503 case CONTEXT_LAC: 504 if (set_boolean (word, value, &(((struct lac *) item)->challenge))) 505 return -1; 506 break; 507 case CONTEXT_LNS: 508 if (set_boolean (word, value, &(((struct lns *) item)->challenge))) 509 return -1; 510 break; 511 default: 512 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 513 word); 514 return -1; 515 } 516 return 0; 517} 518 519int set_lbit (char *word, char *value, int context, void *item) 520{ 521 switch (context & ~CONTEXT_DEFAULT) 522 { 523 case CONTEXT_LAC: 524 if (set_boolean (word, value, &(((struct lac *) item)->lbit))) 525 return -1; 526 break; 527 case CONTEXT_LNS: 528 if (set_boolean (word, value, &(((struct lns *) item)->lbit))) 529 return -1; 530 break; 531 default: 532 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 533 word); 534 return -1; 535 } 536 return 0; 537} 538 539 540int set_debug (char *word, char *value, int context, void *item) 541{ 542 switch (context & ~CONTEXT_DEFAULT) 543 { 544 case CONTEXT_LAC: 545 if (set_boolean (word, value, &(((struct lac *) item)->debug))) 546 return -1; 547 break; 548 case CONTEXT_LNS: 549 if (set_boolean (word, value, &(((struct lns *) item)->debug))) 550 return -1; 551 break; 552 default: 553 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 554 word); 555 return -1; 556 } 557 return 0; 558} 559 560int set_pppoptfile (char *word, char *value, int context, void *item) 561{ 562 struct lac *l = (struct lac *) item; 563 struct lns *n = (struct lns *) item; 564 switch (context & ~CONTEXT_DEFAULT) 565 { 566 case CONTEXT_LNS: 567 if (set_string (word, value, n->pppoptfile, sizeof (n->pppoptfile))) 568 return -1; 569 break; 570 case CONTEXT_LAC: 571 if (set_string (word, value, l->pppoptfile, sizeof (l->pppoptfile))) 572 return -1; 573 break; 574 default: 575 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 576 word); 577 return -1; 578 } 579 return 0; 580} 581 582int set_papchap (char *word, char *value, int context, void *item) 583{ 584 int result; 585 char *c; 586 struct lac *l = (struct lac *) item; 587 struct lns *n = (struct lns *) item; 588 if (set_boolean (word, value, &result)) 589 return -1; 590 c = strchr (word, ' '); 591 c++; 592 switch (context & ~CONTEXT_DEFAULT) 593 { 594 case CONTEXT_LAC: 595 if (c[0] == 'p') /* PAP */ 596 if (word[2] == 'f') 597 l->pap_refuse = result; 598 else 599 l->pap_require = result; 600 else if (c[0] == 'a') /* Authentication */ 601 if (word[2] == 'f') 602 l->authself = result; 603 else 604 l->authpeer = result; 605 else /* CHAP */ if (word[2] == 'f') 606 l->chap_refuse = result; 607 else 608 l->chap_require = result; 609 break; 610 case CONTEXT_LNS: 611 if (c[0] == 'p') /* PAP */ 612 if (word[2] == 'f') 613 n->pap_refuse = result; 614 else 615 n->pap_require = result; 616 else if (c[0] == 'a') /* Authentication */ 617 if (word[2] == 'f') 618 n->authself = !result; 619 else 620 n->authpeer = result; 621 else /* CHAP */ if (word[2] == 'f') 622 n->chap_refuse = result; 623 else 624 n->chap_require = result; 625 break; 626 default: 627 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 628 word); 629 return -1; 630 } 631 return 0; 632} 633 634int set_redial (char *word, char *value, int context, void *item) 635{ 636 switch (context & ~CONTEXT_DEFAULT) 637 { 638 case CONTEXT_LAC: 639 if (set_boolean (word, value, &(((struct lac *) item)->redial))) 640 return -1; 641 break; 642 default: 643 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 644 word); 645 return -1; 646 } 647 return 0; 648} 649 650int set_accesscontrol (char *word, char *value, int context, void *item) 651{ 652 switch (context & ~CONTEXT_DEFAULT) 653 { 654 case CONTEXT_GLOBAL: 655 if (set_boolean 656 (word, value, &(((struct global *) item)->accesscontrol))) 657 return -1; 658 break; 659 default: 660 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 661 word); 662 return -1; 663 } 664 return 0; 665} 666 667int set_userspace (char *word, char *value, int context, void *item) 668{ 669 switch (context & ~CONTEXT_DEFAULT) 670 { 671 case CONTEXT_GLOBAL: 672 if (set_boolean 673 (word, value, &(((struct global *) item)->forceuserspace))) 674 return -1; 675 break; 676 default: 677 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 678 word); 679 return -1; 680 } 681 return 0; 682} 683 684struct iprange *set_range (char *word, char *value, struct iprange *in) 685{ 686 char *c, *d = NULL; 687 struct iprange *ipr, *p; 688 struct hostent *hp; 689 c = strchr (value, '-'); 690 if (c) 691 { 692 d = c + 1; 693 *c = 0; 694 while ((c >= value) && (*c < 33)) 695 *(c--) = 0; 696 while (*d && (*d < 33)) 697 d++; 698 } 699 if (!strlen (value) || (c && !strlen (d))) 700 { 701 snprintf (filerr, sizeof (filerr), 702 "format is '%s <host or ip> - <host or ip>'\n", word); 703 return NULL; 704 } 705 ipr = (struct iprange *) malloc (sizeof (struct iprange)); 706 ipr->next = NULL; 707 hp = gethostbyname (value); 708 if (!hp) 709 { 710 snprintf (filerr, sizeof (filerr), "Unknown host %s\n", value); 711 free (ipr); 712 return NULL; 713 } 714 bcopy (hp->h_addr, &ipr->start, sizeof (unsigned int)); 715 if (c) 716 { 717 hp = gethostbyname (d); 718 if (!hp) 719 { 720 snprintf (filerr, sizeof (filerr), "Unknown host %s\n", d); 721 free (ipr); 722 return NULL; 723 } 724 bcopy (hp->h_addr, &ipr->end, sizeof (unsigned int)); 725 } 726 else 727 ipr->end = ipr->start; 728 if (ntohl (ipr->start) > ntohl (ipr->end)) 729 { 730 snprintf (filerr, sizeof (filerr), "start is greater than end!\n"); 731 free (ipr); 732 return NULL; 733 } 734 if (word[0] == 'n') 735 ipr->sense = SENSE_DENY; 736 else 737 ipr->sense = SENSE_ALLOW; 738 p = in; 739 if (p) 740 { 741 while (p->next) 742 p = p->next; 743 p->next = ipr; 744 return in; 745 } 746 else 747 return ipr; 748} 749 750int set_iprange (char *word, char *value, int context, void *item) 751{ 752 struct lns *lns = (struct lns *) item; 753 switch (context & ~CONTEXT_DEFAULT) 754 { 755 case CONTEXT_LNS: 756 break; 757 default: 758 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 759 word); 760 return -1; 761 } 762 lns->range = set_range (word, value, lns->range); 763 if (!lns->range) 764 return -1; 765#ifdef DEBUG_FILE 766 log (LOG_DEBUG, "range start = %x, end = %x, sense=%ud\n", 767 ntohl (ipr->start), ntohl (ipr->end), ipr->sense); 768#endif 769 return 0; 770} 771 772int set_lac (char *word, char *value, int context, void *item) 773{ 774 struct lns *lns = (struct lns *) item; 775 switch (context & ~CONTEXT_DEFAULT) 776 { 777 case CONTEXT_LNS: 778 break; 779 default: 780 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 781 word); 782 return -1; 783 } 784 lns->lacs = set_range (word, value, lns->lacs); 785 if (!lns->lacs) 786 return -1; 787#ifdef DEBUG_FILE 788 log (LOG_DEBUG, "lac start = %x, end = %x, sense=%ud\n", 789 ntohl (ipr->start), ntohl (ipr->end), ipr->sense); 790#endif 791 return 0; 792} 793 794int set_exclusive (char *word, char *value, int context, void *item) 795{ 796 switch (context & ~CONTEXT_DEFAULT) 797 { 798 case CONTEXT_LNS: 799 if (set_boolean (word, value, &(((struct lns *) item)->exclusive))) 800 return -1; 801 break; 802 default: 803 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 804 word); 805 return -1; 806 } 807 return 0; 808} 809 810int set_ip (char *word, char *value, unsigned int *addr) 811{ 812 struct hostent *hp; 813 hp = gethostbyname (value); 814 if (!hp) 815 { 816 snprintf (filerr, sizeof (filerr), "%s: host '%s' not found\n", 817 __FUNCTION__, value); 818 return -1; 819 } 820 bcopy (hp->h_addr, addr, sizeof (unsigned int)); 821 return 0; 822} 823 824int set_localaddr (char *word, char *value, int context, void *item) 825{ 826 struct lac *l; 827 struct lns *n; 828 switch (context & ~CONTEXT_DEFAULT) 829 { 830 case CONTEXT_LAC: 831 l = (struct lac *) item; 832 return set_ip (word, value, &(l->localaddr)); 833 case CONTEXT_LNS: 834 n = (struct lns *) item; 835 return set_ip (word, value, &(n->localaddr)); 836 default: 837 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 838 word); 839 return -1; 840 } 841 return 0; 842} 843 844int set_remoteaddr (char *word, char *value, int context, void *item) 845{ 846 struct lac *l; 847 switch (context & ~CONTEXT_DEFAULT) 848 { 849 case CONTEXT_LAC: 850 l = (struct lac *) item; 851 return set_ip (word, value, &(l->remoteaddr)); 852 default: 853 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 854 word); 855 return -1; 856 } 857 return 0; 858} 859 860int set_lns (char *word, char *value, int context, void *item) 861{ 862 struct hostent *hp; 863 struct lac *l; 864 struct host *ipr, *pos; 865 char *d; 866 switch (context & ~CONTEXT_DEFAULT) 867 { 868 case CONTEXT_LAC: 869#ifdef DEBUG_FILE 870 log (LOG_DEBUG, "set_lns: setting LNS to '%s'\n", value); 871#endif 872 l = (struct lac *) item; 873 d = strchr (value, ':'); 874 if (d) 875 { 876 d[0] = 0; 877 d++; 878 } 879 hp = gethostbyname (value); 880 if (!hp) 881 { 882 snprintf (filerr, sizeof (filerr), "no such host '%s'\n", value); 883 return -1; 884 } 885 ipr = malloc (sizeof (struct host)); 886 ipr->next = NULL; 887 pos = l->lns; 888 if (!pos) 889 { 890 l->lns = ipr; 891 } 892 else 893 { 894 while (pos->next) 895 pos = pos->next; 896 pos->next = ipr; 897 } 898 strncpy (ipr->hostname, value, sizeof (ipr->hostname)); 899 if (d) 900 ipr->port = atoi (d); 901 else 902 ipr->port = UDP_LISTEN_PORT; 903 break; 904 default: 905 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", 906 word); 907 return -1; 908 } 909 return 0; 910} 911 912int set_rand_sys () 913{ 914 log(LOG_WARN, "The \"rand()\" function call is not a very good source" 915 "of randomness\n"); 916 rand_source = RAND_SYS; 917 return 0; 918} 919 920int set_rand_dev () 921{ 922 rand_source = RAND_DEV; 923 return 0; 924} 925 926int set_rand_egd (char *value) 927{ 928 log(LOG_WARN, "%s: not yet implemented!\n", __FUNCTION__); 929 rand_source = RAND_EGD; 930 return -1; 931} 932 933int set_rand_source (char *word, char *value, int context, void *item) 934{ 935 time_t seconds; 936 /* 937 * We're going to go ahead and seed the rand() function with srand() 938 * because even if we set the randomness source to dev or egd, they 939 * can fall back to sys if they fail, so we want to make sure we at 940 * least have *some* semblance of randomness available from the 941 * rand() function 942 */ 943 /* 944 * This is a sucky random number seed...just the result from the 945 * time() call...but...the user requested to use the rand() 946 * function, which is a pretty sucky source of randomness 947 * regardless...at least we can get a almost sorta decent seed. If 948 * you have any better suggestions for creating a seed...lemme know 949 * :/ 950 */ 951 seconds = time(NULL); 952 srand(seconds); 953 954 if (context != CONTEXT_GLOBAL) 955 { 956 log(LOG_WARN, "%s: %s not valid in context %d\n", 957 __FUNCTION__, word, context); 958 return -1; 959 } 960 /* WORKING HERE */ 961 if (strlen(value) == 0) 962 { 963 snprintf(filerr, sizeof (filerr), "no randomness source specified\n"); 964 return -1; 965 } 966 if (strncmp(value, "egd", 3) == 0) 967 { 968 return set_rand_egd(value); 969 } 970 else if (strncmp(value, "dev", 3) == 0) 971 { 972 return set_rand_dev(); 973 } 974 else if (strncmp(value, "sys", 3) == 0) 975 { 976 return set_rand_sys(); 977 } 978 else 979 { 980 log(LOG_WARN, "%s: %s is not a valid randomness source\n", 981 __FUNCTION__, value); 982 return -1; 983 984 } 985} 986 987int parse_config (FILE * f) 988{ 989 /* Read in the configuration file handed to us */ 990 /* FIXME: I should check for incompatible options */ 991 int context = 0; 992 char buf[STRLEN]; 993 char *s, *d, *t; 994 int linenum = 0; 995 int def = 0; 996 struct keyword *kw; 997 void *data = NULL; 998 struct lns *tl; 999 struct lac *tc; 1000 while (!feof (f)) 1001 { 1002 fgets (buf, sizeof (buf), f); 1003 if (feof (f)) 1004 break; 1005 linenum++; 1006 s = buf; 1007 /* Strip comments */ 1008 while (*s && *s != ';') 1009 s++; 1010 *s = 0; 1011 s = buf; 1012 if (!strlen (buf)) 1013 continue; 1014 while ((*s < 33) && *s) 1015 s++; /* Skip over beginning white space */ 1016 t = s + strlen (s); 1017 while ((t >= s) && (*t < 33)) 1018 *(t--) = 0; /* Ditch trailing white space */ 1019 if (!strlen (s)) 1020 continue; 1021 if (s[0] == '[') 1022 { 1023 /* We've got a context description */ 1024 if (!(t = strchr (s, ']'))) 1025 { 1026 log (LOG_CRIT, "parse_config: line %d: No closing bracket\n", 1027 linenum); 1028 return -1; 1029 } 1030 t[0] = 0; 1031 s++; 1032 if ((d = strchr (s, ' '))) 1033 { 1034 /* There's a parameter */ 1035 d[0] = 0; 1036 d++; 1037 } 1038 if (d && !strcasecmp (d, "default")) 1039 def = CONTEXT_DEFAULT; 1040 else 1041 def = 0; 1042 if (!strcasecmp (s, "global")) 1043 { 1044 context = CONTEXT_GLOBAL; 1045#ifdef DEBUG_FILE 1046 log (LOG_DEBUG, 1047 "parse_config: global context descriptor %s\n", 1048 d ? d : ""); 1049#endif 1050 data = &gconfig; 1051 } 1052 else if (!strcasecmp (s, "lns")) 1053 { 1054 context = CONTEXT_LNS; 1055 if (def) 1056 { 1057 if (!deflns) 1058 { 1059 deflns = new_lns (); 1060 strncpy (deflns->entname, "default", 1061 sizeof (deflns->entname)); 1062 } 1063 data = deflns; 1064 continue; 1065 } 1066 data = NULL; 1067 tl = lnslist; 1068 if (d) 1069 { 1070 while (tl) 1071 { 1072 if (!strcasecmp (d, tl->entname)) 1073 break; 1074 tl = tl->next; 1075 } 1076 if (tl) 1077 data = tl; 1078 } 1079 if (!data) 1080 { 1081 data = new_lns (); 1082 if (!data) 1083 return -1; 1084 ((struct lns *) data)->next = lnslist; 1085 lnslist = (struct lns *) data; 1086 } 1087 if (d) 1088 strncpy (((struct lns *) data)->entname, 1089 d, sizeof (((struct lns *) data)->entname)); 1090#ifdef DEBUG_FILE 1091 log (LOG_DEBUG, "parse_config: lns context descriptor %s\n", 1092 d ? d : ""); 1093#endif 1094 } 1095 else if (!strcasecmp (s, "lac")) 1096 { 1097 context = CONTEXT_LAC; 1098 if (def) 1099 { 1100 if (!deflac) 1101 { 1102 deflac = new_lac (); 1103 strncpy (deflac->entname, "default", 1104 sizeof (deflac->entname)); 1105 } 1106 data = deflac; 1107 continue; 1108 } 1109 data = NULL; 1110 tc = laclist; 1111 if (d) 1112 { 1113 while (tc) 1114 { 1115 if (!strcasecmp (d, tc->entname)) 1116 break; 1117 tc = tc->next; 1118 } 1119 if (tc) 1120 data = tc; 1121 } 1122 if (!data) 1123 { 1124 data = new_lac (); 1125 if (!data) 1126 return -1; 1127 ((struct lac *) data)->next = laclist; 1128 laclist = (struct lac *) data; 1129 } 1130 if (d) 1131 strncpy (((struct lac *) data)->entname, 1132 d, sizeof (((struct lac *) data)->entname)); 1133#ifdef DEBUG_FILE 1134 log (LOG_DEBUG, "parse_config: lac context descriptor %s\n", 1135 d ? d : ""); 1136#endif 1137 } 1138 else 1139 { 1140 log (LOG_WARN, 1141 "parse_config: line %d: unknown context '%s'\n", linenum, 1142 s); 1143 return -1; 1144 } 1145 } 1146 else 1147 { 1148 if (!context) 1149 { 1150 log (LOG_WARN, 1151 "parse_config: line %d: data '%s' occurs with no context\n", 1152 linenum, s); 1153 return -1; 1154 } 1155 if (!(t = strchr (s, '='))) 1156 { 1157 log (LOG_WARN, "parse_config: line %d: no '=' in data\n", 1158 linenum); 1159 return -1; 1160 } 1161 d = t; 1162 d--; 1163 t++; 1164 while ((d >= s) && (*d < 33)) 1165 d--; 1166 d++; 1167 *d = 0; 1168 while (*t && (*t < 33)) 1169 t++; 1170#ifdef DEBUG_FILE 1171 log (LOG_DEBUG, "parse_config: field is %s, value is %s\n", s, t); 1172#endif 1173 /* Okay, bit twidling is done. Let's handle this */ 1174 for (kw = words; kw->keyword; kw++) 1175 { 1176 if (!strcasecmp (s, kw->keyword)) 1177 { 1178 if (kw->handler (s, t, context | def, data)) 1179 { 1180 log (LOG_WARN, "parse_config: line %d: %s", linenum, 1181 filerr); 1182 return -1; 1183 } 1184 break; 1185 } 1186 } 1187 if (!kw->keyword) 1188 { 1189 log (LOG_CRIT, "parse_config: line %d: Unknown field '%s'\n", 1190 linenum, s); 1191 return -1; 1192 } 1193 } 1194 } 1195 return 0; 1196} 1197 1198struct keyword words[] = { 1199 {"port", &set_port}, 1200 {"rand source", &set_rand_source}, 1201 {"auth file", &set_authfile}, 1202 {"exclusive", &set_exclusive}, 1203 {"autodial", &set_autodial}, 1204 {"redial", &set_redial}, 1205 {"redial timeout", &set_rtimeout}, 1206 {"lns", &set_lns}, 1207 {"max redials", &set_rmax}, 1208 {"access control", &set_accesscontrol}, 1209 {"force userspace", &set_userspace}, 1210 {"ip range", &set_iprange}, 1211 {"no ip range", &set_iprange}, 1212 {"lac", &set_lac}, 1213 {"no lac", &set_lac}, 1214 {"local ip", &set_localaddr}, 1215 {"remote ip", &set_remoteaddr}, 1216 {"defaultroute", &set_defaultroute}, 1217 {"length bit", &set_lbit}, 1218 {"hidden bit", &set_hbit}, 1219 {"require pap", &set_papchap}, 1220 {"require chap", &set_papchap}, 1221 {"require authentication", &set_papchap}, 1222 {"require auth", &set_papchap}, 1223 {"refuse pap", &set_papchap}, 1224 {"refuse chap", &set_papchap}, 1225 {"refuse authentication", &set_papchap}, 1226 {"refuse auth", &set_papchap}, 1227 {"unix authentication", &set_passwdauth}, 1228 {"unix auth", &set_passwdauth}, 1229 {"name", &set_authname}, 1230 {"hostname", &set_hostname}, 1231 {"ppp debug", &set_debug}, 1232 {"pppoptfile", &set_pppoptfile}, 1233 {"call rws", &set_rws}, 1234 {"tunnel rws", &set_rws}, 1235 {"flow bit", &set_flow}, 1236 {"challenge", &set_challenge}, 1237 {NULL, NULL} 1238}; 1239