1 /* $OpenBSD: main.c,v 1.59 2024/08/23 00:43:34 millert Exp $ */ 2 3 /* 4 * main.c - Point-to-Point Protocol main module 5 * 6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any legal 23 * details, please contact 24 * Office of Technology Transfer 25 * Carnegie Mellon University 26 * 5000 Forbes Avenue 27 * Pittsburgh, PA 15213-3890 28 * (412) 268-4387, fax: (412) 268-7395 29 * tech-transfer@andrew.cmu.edu 30 * 31 * 4. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by Computing Services 34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 35 * 36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 */ 44 45 #include <sys/types.h> 46 #include <sys/wait.h> 47 #include <sys/time.h> 48 #include <sys/resource.h> 49 #include <sys/stat.h> 50 #include <sys/socket.h> 51 #include <net/if.h> 52 #include <stdio.h> 53 #include <ctype.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.h> 57 #include <limits.h> 58 #include <signal.h> 59 #include <errno.h> 60 #include <fcntl.h> 61 #include <syslog.h> 62 #include <netdb.h> 63 #include <utmp.h> 64 #include <pwd.h> 65 66 #include "pppd.h" 67 #include "magic.h" 68 #include "fsm.h" 69 #include "lcp.h" 70 #include "ipcp.h" 71 #include "upap.h" 72 #include "chap.h" 73 #include "ccp.h" 74 #include "pathnames.h" 75 #include "patchlevel.h" 76 77 #ifdef CBCP_SUPPORT 78 #include "cbcp.h" 79 #endif 80 81 #if defined(SUNOS4) 82 extern char *strerror(); 83 #endif 84 85 #ifdef AT_CHANGE 86 #include "atcp.h" 87 #endif 88 89 /* interface vars */ 90 char ifname[IFNAMSIZ]; /* Interface name */ 91 int ifunit; /* Interface unit number */ 92 93 char hostname[HOST_NAME_MAX+1]; /* Our hostname */ 94 static char default_devnam[PATH_MAX]; /* name of default device */ 95 static pid_t pid; /* Our pid */ 96 static uid_t uid; /* Our real user-id */ 97 static int conn_running; /* we have a [dis]connector running */ 98 static volatile sig_atomic_t crashed = 0; 99 100 int ttyfd = -1; /* Serial port file descriptor */ 101 mode_t tty_mode = -1; /* Original access permissions to tty */ 102 int baud_rate; /* Actual bits/second for serial device */ 103 int hungup; /* terminal has been hung up */ 104 int privileged; /* we're running as real uid root */ 105 int need_holdoff; /* need holdoff period before restarting */ 106 int detached; /* have detached from terminal */ 107 108 int phase; /* where the link is at */ 109 volatile sig_atomic_t kill_link; 110 volatile sig_atomic_t open_ccp_flag; 111 volatile sig_atomic_t got_sigchld; 112 113 char **script_env; /* Env. variable values for scripts */ 114 int s_env_nalloc; /* # words avail at script_env */ 115 116 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ 117 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ 118 119 static int locked; /* lock() has succeeded */ 120 121 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; 122 123 /* Prototypes for procedures local to this file. */ 124 125 static void cleanup(void); 126 static void close_tty(void); 127 static void get_input(void); 128 static void calltimeout(void); 129 static struct timeval *timeleft(struct timeval *); 130 static void kill_my_pg(int); 131 static void hup(int); 132 static void term(int); 133 static void chld(int); 134 static void toggle_debug(int); 135 static void open_ccp(int); 136 static void bad_signal(int); 137 static void holdoff_end(void *); 138 static int device_script(char *, int, int); 139 static void reap_kids(void); 140 static void pr_log(void *, char *, ...); 141 142 extern char *ttyname(int); 143 extern char *getlogin(void); 144 int main(int, char *[]); 145 146 #ifdef ultrix 147 #undef O_NONBLOCK 148 #define O_NONBLOCK O_NDELAY 149 #endif 150 151 #ifdef ULTRIX 152 #define setlogmask(x) 153 #endif 154 155 /* 156 * PPP Data Link Layer "protocol" table. 157 * One entry per supported protocol. 158 * The last entry must be NULL. 159 */ 160 struct protent *protocols[] = { 161 &lcp_protent, 162 &pap_protent, 163 &chap_protent, 164 #ifdef CBCP_SUPPORT 165 &cbcp_protent, 166 #endif 167 &ipcp_protent, 168 &ccp_protent, 169 #ifdef AT_CHANGE 170 &atcp_protent, 171 #endif 172 NULL 173 }; 174 175 int 176 main(int argc, char *argv[]) 177 { 178 int i, fdflags; 179 struct sigaction sa; 180 char *p; 181 struct passwd *pw; 182 struct timeval timo; 183 sigset_t mask; 184 struct protent *protp; 185 struct stat statbuf; 186 char numbuf[16]; 187 188 phase = PHASE_INITIALIZE; 189 p = ttyname(0); 190 if (p) 191 strlcpy(devnam, p, PATH_MAX); 192 strlcpy(default_devnam, devnam, sizeof default_devnam); 193 194 script_env = NULL; 195 196 /* Initialize syslog facilities */ 197 #ifdef ULTRIX 198 openlog("pppd", LOG_PID); 199 #else 200 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); 201 setlogmask(LOG_UPTO(LOG_INFO)); 202 #endif 203 204 if (gethostname(hostname, sizeof hostname) < 0 ) { 205 option_error("Couldn't get hostname: %m"); 206 die(1); 207 } 208 209 uid = getuid(); 210 privileged = uid == 0; 211 snprintf(numbuf, sizeof numbuf, "%u", uid); 212 script_setenv("UID", numbuf); 213 214 /* 215 * Initialize to the standard option set, then parse, in order, 216 * the system options file, the user's options file, 217 * the tty's options file, and the command line arguments. 218 */ 219 for (i = 0; (protp = protocols[i]) != NULL; ++i) 220 (*protp->init)(0); 221 222 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) 223 || !options_from_user()) 224 exit(1); 225 scan_args(argc-1, argv+1); /* look for tty name on command line */ 226 if (!options_for_tty() 227 || !parse_args(argc-1, argv+1)) 228 exit(1); 229 230 /* 231 * Check that we are running as root. 232 */ 233 if (geteuid() != 0) { 234 option_error("must be root to run %s, since it is not setuid-root", 235 argv[0]); 236 die(1); 237 } 238 239 if (!ppp_available()) { 240 option_error(no_ppp_msg); 241 exit(1); 242 } 243 244 /* 245 * Check that the options given are valid and consistent. 246 */ 247 sys_check_options(); 248 auth_check_options(); 249 for (i = 0; (protp = protocols[i]) != NULL; ++i) 250 if (protp->check_options != NULL) 251 (*protp->check_options)(); 252 if (demand && connector == 0) { 253 option_error("connect script required for demand-dialling\n"); 254 exit(1); 255 } 256 257 script_setenv("DEVICE", devnam); 258 snprintf(numbuf, sizeof numbuf, "%d", baud_rate); 259 script_setenv("SPEED", numbuf); 260 261 /* 262 * If the user has specified the default device name explicitly, 263 * pretend they hadn't. 264 */ 265 if (!default_device && strcmp(devnam, default_devnam) == 0) 266 default_device = 1; 267 if (default_device) 268 nodetach = 1; 269 270 /* 271 * Initialize system-dependent stuff and magic number package. 272 */ 273 sys_init(); 274 magic_init(); 275 if (debug) 276 setlogmask(LOG_UPTO(LOG_DEBUG)); 277 278 /* 279 * Detach ourselves from the terminal, if required, 280 * and identify who is running us. 281 */ 282 if (nodetach == 0) 283 detach(); 284 pid = getpid(); 285 p = getlogin(); 286 if (p == NULL) { 287 pw = getpwuid(uid); 288 if (pw != NULL && pw->pw_name != NULL) 289 p = pw->pw_name; 290 else 291 p = "(unknown)"; 292 } 293 syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %u", 294 VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); 295 296 /* 297 * Compute mask of all interesting signals and install signal handlers 298 * for each. Only one signal handler may be active at a time. Therefore, 299 * all other signals should be masked when any handler is executing. 300 */ 301 sigemptyset(&mask); 302 sigaddset(&mask, SIGHUP); 303 sigaddset(&mask, SIGINT); 304 sigaddset(&mask, SIGTERM); 305 sigaddset(&mask, SIGCHLD); 306 307 #define SIGNAL(s, handler) { \ 308 sa.sa_handler = handler; \ 309 if (sigaction(s, &sa, NULL) < 0) { \ 310 syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ 311 die(1); \ 312 } \ 313 } 314 315 sa.sa_mask = mask; 316 sa.sa_flags = 0; 317 SIGNAL(SIGHUP, hup); /* Hangup */ 318 SIGNAL(SIGINT, term); /* Interrupt */ 319 SIGNAL(SIGTERM, term); /* Terminate */ 320 SIGNAL(SIGCHLD, chld); 321 322 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ 323 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ 324 325 /* 326 * Install a handler for other signals which would otherwise 327 * cause pppd to exit without cleaning up. 328 */ 329 SIGNAL(SIGABRT, bad_signal); 330 SIGNAL(SIGALRM, bad_signal); 331 SIGNAL(SIGFPE, bad_signal); 332 SIGNAL(SIGILL, bad_signal); 333 SIGNAL(SIGPIPE, bad_signal); 334 SIGNAL(SIGQUIT, bad_signal); 335 #if SIGSEGV_CHECK 336 SIGNAL(SIGSEGV, bad_signal); 337 #endif 338 #ifdef SIGBUS 339 SIGNAL(SIGBUS, bad_signal); 340 #endif 341 #ifdef SIGEMT 342 SIGNAL(SIGEMT, bad_signal); 343 #endif 344 #ifdef SIGPOLL 345 SIGNAL(SIGPOLL, bad_signal); 346 #endif 347 #ifdef SIGPROF 348 SIGNAL(SIGPROF, bad_signal); 349 #endif 350 #ifdef SIGSYS 351 SIGNAL(SIGSYS, bad_signal); 352 #endif 353 #ifdef SIGTRAP 354 SIGNAL(SIGTRAP, bad_signal); 355 #endif 356 #ifdef SIGVTALRM 357 SIGNAL(SIGVTALRM, bad_signal); 358 #endif 359 #ifdef SIGXCPU 360 SIGNAL(SIGXCPU, bad_signal); 361 #endif 362 #ifdef SIGXFSZ 363 SIGNAL(SIGXFSZ, bad_signal); 364 #endif 365 366 /* 367 * Apparently we can get a SIGPIPE when we call syslog, if 368 * syslogd has died and been restarted. Ignoring it seems 369 * be sufficient. 370 */ 371 signal(SIGPIPE, SIG_IGN); 372 373 /* 374 * If we're doing dial-on-demand, set up the interface now. 375 */ 376 if (demand) { 377 /* 378 * Open the loopback channel and set it up to be the ppp interface. 379 */ 380 open_ppp_loopback(); 381 382 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 383 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 384 script_setenv("IFNAME", ifname); 385 386 /* 387 * Configure the interface and mark it up, etc. 388 */ 389 demand_conf(); 390 } 391 392 for (;;) { 393 394 need_holdoff = 1; 395 396 if (demand) { 397 /* 398 * Don't do anything until we see some activity. 399 */ 400 phase = PHASE_DORMANT; 401 kill_link = 0; 402 demand_unblock(); 403 for (;;) { 404 wait_loop_output(timeleft(&timo)); 405 calltimeout(); 406 if (kill_link) { 407 if (!persist) 408 die(0); 409 kill_link = 0; 410 } 411 if (get_loop_output()) 412 break; 413 reap_kids(); 414 } 415 416 /* 417 * Now we want to bring up the link. 418 */ 419 demand_drop(); 420 syslog(LOG_INFO, "Starting link"); 421 } 422 423 /* 424 * Lock the device if we've been asked to. 425 */ 426 if (lockflag && !default_device) { 427 if (lock(devnam) < 0) 428 goto fail; 429 locked = 1; 430 } 431 432 /* 433 * Open the serial device and set it up to be the ppp interface. 434 * First we open it in non-blocking mode so we can set the 435 * various termios flags appropriately. If we aren't dialling 436 * out and we want to use the modem lines, we reopen it later 437 * in order to wait for the carrier detect signal from the modem. 438 */ 439 while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR)) < 0) { 440 if (errno != EINTR) 441 syslog(LOG_ERR, "Failed to open %s: %m", devnam); 442 if (!persist || errno != EINTR) 443 goto fail; 444 } 445 if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 446 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 447 syslog(LOG_WARNING, 448 "Couldn't reset non-blocking mode on device: %m"); 449 450 hungup = 0; 451 kill_link = 0; 452 453 /* 454 * Do the equivalent of `mesg n' to stop broadcast messages. 455 */ 456 if (fstat(ttyfd, &statbuf) < 0 457 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { 458 syslog(LOG_WARNING, 459 "Couldn't restrict write permissions to %s: %m", devnam); 460 } else 461 tty_mode = statbuf.st_mode; 462 463 /* run connection script */ 464 if (connector && connector[0]) { 465 MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); 466 467 /* 468 * Set line speed, flow control, etc. 469 * On most systems we set CLOCAL for now so that we can talk 470 * to the modem before carrier comes up. But this has the 471 * side effect that we might miss it if CD drops before we 472 * get to clear CLOCAL below. On systems where we can talk 473 * successfully to the modem with CLOCAL clear and CD down, 474 * we can clear CLOCAL at this point. 475 */ 476 set_up_tty(ttyfd, (modem_chat == 0)); 477 478 /* drop dtr to hang up in case modem is off hook */ 479 if (!default_device && modem) { 480 setdtr(ttyfd, FALSE); 481 sleep(1); 482 setdtr(ttyfd, TRUE); 483 } 484 485 if (device_script(connector, ttyfd, ttyfd) < 0) { 486 syslog(LOG_ERR, "Connect script failed"); 487 setdtr(ttyfd, FALSE); 488 goto fail; 489 } 490 491 syslog(LOG_INFO, "Serial connection established."); 492 sleep(1); /* give it time to set up its terminal */ 493 } 494 495 set_up_tty(ttyfd, 0); 496 497 /* reopen tty if necessary to wait for carrier */ 498 if (connector == NULL && modem) { 499 while ((i = open(devnam, O_RDWR)) < 0) { 500 if (errno != EINTR) 501 syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); 502 if (!persist || errno != EINTR || hungup || kill_link) 503 goto fail; 504 } 505 close(i); 506 } 507 508 /* run welcome script, if any */ 509 if (welcomer && welcomer[0]) { 510 if (device_script(welcomer, ttyfd, ttyfd) < 0) 511 syslog(LOG_WARNING, "Welcome script failed"); 512 } 513 514 /* set up the serial device as a ppp interface */ 515 establish_ppp(ttyfd); 516 517 if (!demand) { 518 519 syslog(LOG_INFO, "Using interface ppp%d", ifunit); 520 (void) snprintf(ifname, sizeof ifname, "ppp%d", ifunit); 521 script_setenv("IFNAME", ifname); 522 } 523 524 /* 525 * Start opening the connection and wait for 526 * incoming events (reply, timeout, etc.). 527 */ 528 syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); 529 lcp_lowerup(0); 530 lcp_open(0); /* Start protocol */ 531 for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { 532 wait_input(timeleft(&timo)); 533 calltimeout(); 534 get_input(); 535 if (kill_link) { 536 lcp_close(0, "User request"); 537 kill_link = 0; 538 } 539 if (open_ccp_flag) { 540 if (phase == PHASE_NETWORK) { 541 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ 542 (*ccp_protent.open)(0); 543 } 544 open_ccp_flag = 0; 545 } 546 reap_kids(); /* Don't leave dead kids lying around */ 547 } 548 549 /* 550 * If we may want to bring the link up again, transfer 551 * the ppp unit back to the loopback. Set the 552 * real serial device back to its normal mode of operation. 553 */ 554 clean_check(); 555 if (demand) 556 restore_loop(); 557 disestablish_ppp(ttyfd); 558 559 /* 560 * Run disconnector script, if requested. 561 * XXX we may not be able to do this if the line has hung up! 562 */ 563 if (disconnector && !hungup) { 564 set_up_tty(ttyfd, 1); 565 if (device_script(disconnector, ttyfd, ttyfd) < 0) { 566 syslog(LOG_WARNING, "disconnect script failed"); 567 } else { 568 syslog(LOG_INFO, "Serial link disconnected."); 569 } 570 } 571 572 fail: 573 if (ttyfd >= 0) 574 close_tty(); 575 if (locked) { 576 unlock(); 577 locked = 0; 578 } 579 580 if (!persist) 581 die(1); 582 583 if (holdoff > 0 && need_holdoff) { 584 phase = PHASE_HOLDOFF; 585 TIMEOUT(holdoff_end, NULL, holdoff); 586 do { 587 wait_time(timeleft(&timo)); 588 calltimeout(); 589 if (kill_link) { 590 if (!persist) 591 die(0); 592 kill_link = 0; 593 phase = PHASE_DORMANT; /* allow signal to end holdoff */ 594 } 595 reap_kids(); 596 } while (phase == PHASE_HOLDOFF); 597 } 598 } 599 600 die(0); 601 return 0; 602 } 603 604 /* 605 * detach - detach us from the controlling terminal. 606 */ 607 void 608 detach(void) 609 { 610 if (detached) 611 return; 612 if (daemon(0, 0) < 0) { 613 perror("Couldn't detach from controlling terminal"); 614 die(1); 615 } 616 detached = 1; 617 pid = getpid(); 618 } 619 620 /* 621 * holdoff_end - called via a timeout when the holdoff period ends. 622 */ 623 static void 624 holdoff_end(void *arg) 625 { 626 phase = PHASE_DORMANT; 627 } 628 629 /* 630 * get_input - called when incoming data is available. 631 */ 632 static void 633 get_input(void) 634 { 635 int len, i; 636 u_char *p; 637 u_short protocol; 638 struct protent *protp; 639 640 p = inpacket_buf; /* point to beginning of packet buffer */ 641 642 len = read_packet(inpacket_buf); 643 if (len < 0) 644 return; 645 646 if (len == 0) { 647 syslog(LOG_NOTICE, "Modem hangup"); 648 hungup = 1; 649 lcp_lowerdown(0); /* serial link is no longer available */ 650 link_terminated(0); 651 return; 652 } 653 654 if (debug /*&& (debugflags & DBG_INPACKET)*/) 655 log_packet(p, len, "rcvd ", LOG_DEBUG); 656 657 if (len < PPP_HDRLEN) { 658 MAINDEBUG((LOG_INFO, "io(): Received short packet.")); 659 return; 660 } 661 662 p += 2; /* Skip address and control */ 663 GETSHORT(protocol, p); 664 len -= PPP_HDRLEN; 665 666 /* 667 * Toss all non-LCP packets unless LCP is OPEN. 668 */ 669 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { 670 MAINDEBUG((LOG_INFO, 671 "get_input: Received non-LCP packet when LCP not open.")); 672 return; 673 } 674 675 /* 676 * Until we get past the authentication phase, toss all packets 677 * except LCP, LQR and authentication packets. 678 */ 679 if (phase <= PHASE_AUTHENTICATE 680 && !(protocol == PPP_LCP || protocol == PPP_LQR 681 || protocol == PPP_PAP || protocol == PPP_CHAP)) { 682 MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d", 683 protocol, phase)); 684 return; 685 } 686 687 /* 688 * Upcall the proper protocol input routine. 689 */ 690 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 691 if (protp->protocol == protocol && protp->enabled_flag) { 692 (*protp->input)(0, p, len); 693 return; 694 } 695 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag 696 && protp->datainput != NULL) { 697 (*protp->datainput)(0, p, len); 698 return; 699 } 700 } 701 702 if (debug) 703 syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); 704 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); 705 } 706 707 708 /* 709 * quit - Clean up state and exit (with an error indication). 710 */ 711 void 712 quit(void) 713 { 714 die(1); 715 } 716 717 /* 718 * die - like quit, except we can specify an exit status. 719 */ 720 void 721 die(int status) 722 { 723 struct syslog_data sdata = SYSLOG_DATA_INIT; 724 725 cleanup(); 726 syslog_r(LOG_INFO, &sdata, "Exit."); 727 _exit(status); 728 } 729 730 /* 731 * cleanup - restore anything which needs to be restored before we exit 732 */ 733 static void 734 cleanup(void) 735 { 736 sys_cleanup(); 737 738 if (ttyfd >= 0) 739 close_tty(); 740 741 if (locked) 742 unlock(); 743 } 744 745 /* 746 * close_tty - restore the terminal device and close it. 747 */ 748 static void 749 close_tty(void) 750 { 751 disestablish_ppp(ttyfd); 752 753 /* drop dtr to hang up */ 754 if (modem) { 755 setdtr(ttyfd, FALSE); 756 /* 757 * This sleep is in case the serial port has CLOCAL set by default, 758 * and consequently will reassert DTR when we close the device. 759 */ 760 sleep(1); 761 } 762 763 restore_tty(ttyfd); 764 765 if (tty_mode != (mode_t) -1) 766 fchmod(ttyfd, tty_mode); 767 768 close(ttyfd); 769 ttyfd = -1; 770 } 771 772 773 struct callout { 774 struct timeval c_time; /* time at which to call routine */ 775 void *c_arg; /* argument to routine */ 776 void (*c_func)(void *); /* routine */ 777 struct callout *c_next; 778 }; 779 780 static struct callout *callout = NULL; /* Callout list */ 781 static struct timeval timenow; /* Current time */ 782 783 /* 784 * timeout - Schedule a timeout. 785 * 786 * Note that this timeout takes the number of seconds, NOT hz (as in 787 * the kernel). 788 */ 789 void 790 timeout(void (*func)(void *), void *arg, int time) 791 { 792 struct callout *newp, *p, **pp; 793 794 MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", 795 (long) func, (long) arg, time)); 796 797 /* 798 * Allocate timeout. 799 */ 800 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { 801 syslog(LOG_ERR, "Out of memory in timeout()!"); 802 die(1); 803 } 804 newp->c_arg = arg; 805 newp->c_func = func; 806 gettimeofday(&timenow, NULL); 807 newp->c_time.tv_sec = timenow.tv_sec + time; 808 newp->c_time.tv_usec = timenow.tv_usec; 809 810 /* 811 * Find correct place and link it in. 812 */ 813 for (pp = &callout; (p = *pp); pp = &p->c_next) 814 if (newp->c_time.tv_sec < p->c_time.tv_sec 815 || (newp->c_time.tv_sec == p->c_time.tv_sec 816 && newp->c_time.tv_usec < p->c_time.tv_sec)) 817 break; 818 newp->c_next = p; 819 *pp = newp; 820 } 821 822 823 /* 824 * untimeout - Unschedule a timeout. 825 */ 826 void 827 untimeout(void (*func)(void *), void *arg) 828 { 829 struct callout **copp, *freep; 830 831 MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); 832 833 /* 834 * Find first matching timeout and remove it from the list. 835 */ 836 for (copp = &callout; (freep = *copp); copp = &freep->c_next) 837 if (freep->c_func == func && freep->c_arg == arg) { 838 *copp = freep->c_next; 839 (void) free((char *) freep); 840 break; 841 } 842 } 843 844 845 /* 846 * calltimeout - Call any timeout routines which are now due. 847 */ 848 static void 849 calltimeout(void) 850 { 851 struct callout *p; 852 853 while (callout != NULL) { 854 p = callout; 855 856 if (gettimeofday(&timenow, NULL) < 0) { 857 syslog(LOG_ERR, "Failed to get time of day: %m"); 858 die(1); 859 } 860 if (!(p->c_time.tv_sec < timenow.tv_sec 861 || (p->c_time.tv_sec == timenow.tv_sec 862 && p->c_time.tv_usec <= timenow.tv_usec))) 863 break; /* no, it's not time yet */ 864 865 callout = p->c_next; 866 (*p->c_func)(p->c_arg); 867 868 free((char *) p); 869 } 870 } 871 872 873 /* 874 * timeleft - return the length of time until the next timeout is due. 875 */ 876 static struct timeval * 877 timeleft(struct timeval *tvp) 878 { 879 if (callout == NULL) 880 return NULL; 881 882 gettimeofday(&timenow, NULL); 883 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; 884 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; 885 if (tvp->tv_usec < 0) { 886 tvp->tv_usec += 1000000; 887 tvp->tv_sec -= 1; 888 } 889 if (tvp->tv_sec < 0) 890 tvp->tv_sec = tvp->tv_usec = 0; 891 892 return tvp; 893 } 894 895 896 /* 897 * kill_my_pg - send a signal to our process group, and ignore it ourselves. 898 */ 899 static void 900 kill_my_pg(int sig) 901 { 902 struct sigaction act, oldact; 903 904 act.sa_handler = SIG_IGN; 905 act.sa_flags = 0; 906 kill(0, sig); 907 sigaction(sig, &act, &oldact); 908 sigaction(sig, &oldact, NULL); 909 } 910 911 912 /* 913 * hup - Catch SIGHUP signal. 914 * 915 * Indicates that the physical layer has been disconnected. 916 * We don't rely on this indication; if the user has sent this 917 * signal, we just take the link down. 918 */ 919 static void 920 hup(int sig) 921 { 922 int save_errno = errno; 923 struct syslog_data sdata = SYSLOG_DATA_INIT; 924 925 if (crashed) 926 _exit(127); 927 syslog_r(LOG_INFO, &sdata, "Hangup (SIGHUP)"); 928 kill_link = 1; 929 if (conn_running) 930 /* Send the signal to the [dis]connector process(es) also */ 931 kill_my_pg(sig); 932 errno = save_errno; 933 } 934 935 936 /* 937 * term - Catch SIGTERM signal and SIGINT signal (^C/del). 938 * 939 * Indicates that we should initiate a graceful disconnect and exit. 940 */ 941 static void 942 term(int sig) 943 { 944 int save_errno = errno; 945 struct syslog_data sdata = SYSLOG_DATA_INIT; 946 947 if (crashed) 948 _exit(127); 949 syslog_r(LOG_INFO, &sdata, "Terminating on signal %d.", sig); 950 persist = 0; /* don't try to restart */ 951 kill_link = 1; 952 if (conn_running) 953 /* Send the signal to the [dis]connector process(es) also */ 954 kill_my_pg(sig); 955 errno = save_errno; 956 } 957 958 959 /* 960 * chld - Catch SIGCHLD signal. 961 * Calls reap_kids to get status for any dead kids. 962 */ 963 static void 964 chld(int sig) 965 { 966 got_sigchld = 1; 967 } 968 969 970 /* 971 * toggle_debug - Catch SIGUSR1 signal. 972 * 973 * Toggle debug flag. 974 */ 975 static void 976 toggle_debug(int sig) 977 { 978 debug = !debug; 979 if (debug) { 980 setlogmask(LOG_UPTO(LOG_DEBUG)); /* XXX safe, but wrong */ 981 } else { 982 setlogmask(LOG_UPTO(LOG_WARNING)); /* XXX safe, but wrong */ 983 } 984 } 985 986 987 /* 988 * open_ccp - Catch SIGUSR2 signal. 989 * 990 * Try to (re)negotiate compression. 991 */ 992 static void 993 open_ccp(int sig) 994 { 995 open_ccp_flag = 1; 996 } 997 998 999 /* 1000 * bad_signal - We've caught a fatal signal. Clean up state and exit. 1001 */ 1002 static void 1003 bad_signal(int sig) 1004 { 1005 struct syslog_data sdata = SYSLOG_DATA_INIT; 1006 1007 if (crashed) 1008 _exit(127); 1009 crashed = 1; 1010 syslog_r(LOG_ERR, &sdata, "Fatal signal %d", sig); 1011 if (conn_running) 1012 kill_my_pg(SIGTERM); 1013 die(1); /* XXX unsafe! */ 1014 } 1015 1016 1017 /* 1018 * device_script - run a program to connect or disconnect the 1019 * serial device. 1020 */ 1021 static int 1022 device_script(char *program, int in, int out) 1023 { 1024 pid_t pid; 1025 int status; 1026 int errfd; 1027 gid_t gid; 1028 uid_t uid; 1029 1030 conn_running = 1; 1031 pid = fork(); 1032 1033 if (pid < 0) { 1034 conn_running = 0; 1035 syslog(LOG_ERR, "Failed to create child process: %m"); 1036 die(1); 1037 } 1038 1039 if (pid == 0) { 1040 sys_close(); 1041 closelog(); 1042 if (in == out) { 1043 if (in != 0) { 1044 dup2(in, 0); 1045 close(in); 1046 } 1047 dup2(0, 1); 1048 } else { 1049 if (out == 0) 1050 out = dup(out); 1051 if (in != 0) { 1052 dup2(in, 0); 1053 close(in); 1054 } 1055 if (out != 1) { 1056 dup2(out, 1); 1057 close(out); 1058 } 1059 } 1060 if (nodetach == 0) { 1061 close(2); 1062 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); 1063 if (errfd >= 0 && errfd != 2) { 1064 dup2(errfd, 2); 1065 close(errfd); 1066 } 1067 } 1068 1069 /* revoke privs */ 1070 gid = getgid(); 1071 uid = getuid(); 1072 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1073 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1074 _exit(1); 1075 } 1076 1077 execl("/bin/sh", "sh", "-c", program, (char *)NULL); 1078 syslog(LOG_ERR, "could not exec /bin/sh: %m"); 1079 _exit(99); 1080 /* NOTREACHED */ 1081 } 1082 1083 while (waitpid(pid, &status, 0) < 0) { 1084 if (errno == EINTR) 1085 continue; 1086 syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); 1087 die(1); 1088 } 1089 conn_running = 0; 1090 1091 return (status == 0 ? 0 : -1); 1092 } 1093 1094 1095 /* 1096 * run-program - execute a program with given arguments, 1097 * but don't wait for it. 1098 * If the program can't be executed, logs an error unless 1099 * must_exist is 0 and the program file doesn't exist. 1100 */ 1101 int 1102 run_program(char *prog, char **args, int must_exist) 1103 { 1104 pid_t pid; 1105 uid_t uid; 1106 gid_t gid; 1107 1108 pid = fork(); 1109 if (pid == -1) { 1110 syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); 1111 return -1; 1112 } 1113 if (pid == 0) { 1114 int new_fd; 1115 1116 /* Leave the current location */ 1117 (void) setsid(); /* No controlling tty. */ 1118 (void) umask (S_IRWXG|S_IRWXO); 1119 (void) chdir ("/"); /* no current directory. */ 1120 1121 /* revoke privs */ 1122 uid = getuid(); 1123 gid = getgid(); 1124 if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) { 1125 syslog(LOG_ERR, "revoke privileges: %s", strerror(errno)); 1126 _exit(1); 1127 } 1128 1129 /* Ensure that nothing of our device environment is inherited. */ 1130 sys_close(); 1131 closelog(); 1132 close (0); 1133 close (1); 1134 close (2); 1135 close (ttyfd); /* tty interface to the ppp device */ 1136 1137 /* Don't pass handles to the PPP device, even by accident. */ 1138 new_fd = open (_PATH_DEVNULL, O_RDWR); 1139 if (new_fd >= 0) { 1140 if (new_fd != 0) { 1141 dup2 (new_fd, 0); /* stdin <- /dev/null */ 1142 close (new_fd); 1143 } 1144 dup2 (0, 1); /* stdout -> /dev/null */ 1145 dup2 (0, 2); /* stderr -> /dev/null */ 1146 } 1147 1148 /* Force the priority back to zero if pppd is running higher. */ 1149 if (setpriority (PRIO_PROCESS, 0, 0) < 0) 1150 syslog (LOG_WARNING, "can't reset priority to 0: %m"); 1151 1152 /* SysV recommends a second fork at this point. */ 1153 1154 /* run the program; give it a null environment */ 1155 execve(prog, args, script_env); 1156 if (must_exist || errno != ENOENT) 1157 syslog(LOG_WARNING, "Can't execute %s: %m", prog); 1158 _exit(1); 1159 } 1160 MAINDEBUG((LOG_DEBUG, "Script %s started; pid = %ld", prog, (long)pid)); 1161 return 0; 1162 } 1163 1164 1165 /* 1166 * reap_kids - get status from any dead child processes, 1167 * and log a message for abnormal terminations. 1168 */ 1169 static void 1170 reap_kids(void) 1171 { 1172 int status; 1173 pid_t pid; 1174 1175 if (!got_sigchld) 1176 return; 1177 got_sigchld = 0; 1178 1179 for (;;) { 1180 pid = waitpid(-1, &status, WNOHANG); 1181 switch (pid) { 1182 case -1: 1183 if (errno == EINTR) 1184 continue; 1185 if (errno != ECHILD) 1186 syslog(LOG_ERR, "Error waiting for child process: %m"); 1187 return; 1188 case 0: 1189 /* No children left */ 1190 return; 1191 default: 1192 if (WIFSIGNALED(status)) { 1193 syslog(LOG_WARNING, 1194 "Child process %d terminated with signal %d", 1195 (int)pid, WTERMSIG(status)); 1196 } 1197 break; 1198 } 1199 } 1200 } 1201 1202 1203 /* 1204 * log_packet - format a packet and log it. 1205 */ 1206 1207 char line[256]; /* line to be logged accumulated here */ 1208 char *linep; 1209 1210 void 1211 log_packet(u_char *p, int len, char *prefix, int level) 1212 { 1213 strlcpy(line, prefix, sizeof line); 1214 linep = line + strlen(line); 1215 format_packet(p, len, pr_log, NULL); 1216 if (linep != line) 1217 syslog(level, "%s", line); 1218 } 1219 1220 /* 1221 * format_packet - make a readable representation of a packet, 1222 * calling `printer(arg, format, ...)' to output it. 1223 */ 1224 void 1225 format_packet(u_char *p, int len, void (*printer)(void *, char *, ...), void *arg) 1226 { 1227 int i, n; 1228 u_short proto; 1229 u_char x; 1230 struct protent *protp; 1231 1232 if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 1233 p += 2; 1234 GETSHORT(proto, p); 1235 len -= PPP_HDRLEN; 1236 for (i = 0; (protp = protocols[i]) != NULL; ++i) 1237 if (proto == protp->protocol) 1238 break; 1239 if (protp != NULL) { 1240 printer(arg, "[%s", protp->name); 1241 n = (*protp->printpkt)(p, len, printer, arg); 1242 printer(arg, "]"); 1243 p += n; 1244 len -= n; 1245 } else { 1246 printer(arg, "[proto=0x%x]", proto); 1247 } 1248 } 1249 1250 for (; len > 0; --len) { 1251 GETCHAR(x, p); 1252 printer(arg, " %.2x", x); 1253 } 1254 } 1255 1256 static void 1257 pr_log(void *arg, char *fmt, ...) 1258 { 1259 int n; 1260 va_list pvar; 1261 char buf[256]; 1262 1263 va_start(pvar, fmt); 1264 1265 n = vfmtmsg(buf, sizeof(buf), fmt, pvar); 1266 va_end(pvar); 1267 1268 if (linep + n + 1 > line + sizeof(line)) { 1269 syslog(LOG_DEBUG, "%s", line); 1270 linep = line; 1271 } 1272 strlcpy(linep, buf, line + sizeof line - linep); 1273 linep += n; 1274 } 1275 1276 /* 1277 * print_string - print a readable representation of a string using 1278 * printer. 1279 */ 1280 void 1281 print_string(char *p, int len, void (*printer)(void *, char *, ...), void *arg) 1282 { 1283 int c; 1284 1285 printer(arg, "\""); 1286 for (; len > 0; --len) { 1287 c = *p++; 1288 if (' ' <= c && c <= '~') { 1289 if (c == '\\' || c == '"') 1290 printer(arg, "\\"); 1291 printer(arg, "%c", c); 1292 } else { 1293 switch (c) { 1294 case '\n': 1295 printer(arg, "\\n"); 1296 break; 1297 case '\r': 1298 printer(arg, "\\r"); 1299 break; 1300 case '\t': 1301 printer(arg, "\\t"); 1302 break; 1303 default: 1304 printer(arg, "\\%.3o", c); 1305 } 1306 } 1307 } 1308 printer(arg, "\""); 1309 } 1310 1311 /* 1312 * novm - log an error message saying we ran out of memory, and die. 1313 */ 1314 void 1315 novm(char *msg) 1316 { 1317 syslog(LOG_ERR, "Virtual memory exhausted allocating %s", msg); 1318 die(1); 1319 } 1320 1321 /* 1322 * fmtmsg - format a message into a buffer. Like snprintf except we 1323 * also specify the length of the output buffer, and we handle 1324 * %m (error message) and %I (IP address) formats. 1325 * Doesn't do floating-point formats. 1326 * Returns the number of chars put into buf. 1327 */ 1328 int 1329 fmtmsg(char *buf, int buflen, char *fmt, ...) 1330 { 1331 va_list args; 1332 int n; 1333 1334 va_start(args, fmt); 1335 n = vfmtmsg(buf, buflen, fmt, args); 1336 va_end(args); 1337 return n; 1338 } 1339 1340 /* 1341 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. 1342 */ 1343 #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) 1344 1345 int 1346 vfmtmsg(char *buf, int buflen, char *fmt, va_list args) 1347 { 1348 int c, i, n; 1349 int width, prec, fillch; 1350 int base, len, neg, quoted; 1351 unsigned long val = 0; 1352 char *str, *f, *buf0; 1353 unsigned char *p; 1354 char num[32]; 1355 time_t t; 1356 static char hexchars[] = "0123456789abcdef"; 1357 1358 buf0 = buf; 1359 --buflen; 1360 while (buflen > 0) { 1361 for (f = fmt; *f != '%' && *f != 0; ++f) 1362 ; 1363 if (f > fmt) { 1364 len = f - fmt; 1365 if (len > buflen) 1366 len = buflen; 1367 memcpy(buf, fmt, len); 1368 buf += len; 1369 buflen -= len; 1370 fmt = f; 1371 } 1372 if (*fmt == 0) 1373 break; 1374 c = *++fmt; 1375 width = prec = 0; 1376 fillch = ' '; 1377 if (c == '0') { 1378 fillch = '0'; 1379 c = *++fmt; 1380 } 1381 if (c == '*') { 1382 width = va_arg(args, int); 1383 c = *++fmt; 1384 } else { 1385 while (isdigit(c)) { 1386 width = width * 10 + c - '0'; 1387 c = *++fmt; 1388 } 1389 } 1390 if (c == '.') { 1391 c = *++fmt; 1392 if (c == '*') { 1393 prec = va_arg(args, int); 1394 c = *++fmt; 1395 } else { 1396 while (isdigit(c)) { 1397 prec = prec * 10 + c - '0'; 1398 c = *++fmt; 1399 } 1400 } 1401 } 1402 str = 0; 1403 base = 0; 1404 neg = 0; 1405 ++fmt; 1406 switch (c) { 1407 case 'd': 1408 i = va_arg(args, int); 1409 if (i < 0) { 1410 neg = 1; 1411 val = -i; 1412 } else 1413 val = i; 1414 base = 10; 1415 break; 1416 case 'o': 1417 val = va_arg(args, unsigned int); 1418 base = 8; 1419 break; 1420 case 'x': 1421 val = va_arg(args, unsigned int); 1422 base = 16; 1423 break; 1424 case 'p': 1425 val = (unsigned long) va_arg(args, void *); 1426 base = 16; 1427 neg = 2; 1428 break; 1429 case 's': 1430 str = va_arg(args, char *); 1431 break; 1432 case 'c': 1433 num[0] = va_arg(args, int); 1434 num[1] = 0; 1435 str = num; 1436 break; 1437 case 'm': 1438 str = strerror(errno); 1439 break; 1440 case 'I': 1441 str = ip_ntoa(va_arg(args, u_int32_t)); 1442 break; 1443 case 't': 1444 time(&t); 1445 str = ctime(&t); 1446 str += 4; /* chop off the day name */ 1447 str[15] = 0; /* chop off year and newline */ 1448 break; 1449 case 'v': /* "visible" string */ 1450 case 'q': /* quoted string */ 1451 quoted = c == 'q'; 1452 p = va_arg(args, unsigned char *); 1453 if (fillch == '0' && prec > 0) { 1454 n = prec; 1455 } else { 1456 n = strlen((char *)p); 1457 if (prec > 0 && prec < n) 1458 n = prec; 1459 } 1460 while (n > 0 && buflen > 0) { 1461 c = *p++; 1462 --n; 1463 if (!quoted && c >= 0x80) { 1464 OUTCHAR('M'); 1465 OUTCHAR('-'); 1466 c -= 0x80; 1467 } 1468 if (quoted && (c == '"' || c == '\\')) 1469 OUTCHAR('\\'); 1470 if (c < 0x20 || (0x7f <= c && c < 0xa0)) { 1471 if (quoted) { 1472 OUTCHAR('\\'); 1473 switch (c) { 1474 case '\t': OUTCHAR('t'); break; 1475 case '\n': OUTCHAR('n'); break; 1476 case '\b': OUTCHAR('b'); break; 1477 case '\f': OUTCHAR('f'); break; 1478 default: 1479 OUTCHAR('x'); 1480 OUTCHAR(hexchars[c >> 4]); 1481 OUTCHAR(hexchars[c & 0xf]); 1482 } 1483 } else { 1484 if (c == '\t') 1485 OUTCHAR(c); 1486 else { 1487 OUTCHAR('^'); 1488 OUTCHAR(c ^ 0x40); 1489 } 1490 } 1491 } else 1492 OUTCHAR(c); 1493 } 1494 continue; 1495 default: 1496 *buf++ = '%'; 1497 if (c != '%') 1498 --fmt; /* so %z outputs %z etc. */ 1499 --buflen; 1500 continue; 1501 } 1502 if (base != 0) { 1503 str = num + sizeof(num); 1504 *--str = 0; 1505 while (str > num + neg) { 1506 *--str = hexchars[val % base]; 1507 val = val / base; 1508 if (--prec <= 0 && val == 0) 1509 break; 1510 } 1511 switch (neg) { 1512 case 1: 1513 *--str = '-'; 1514 break; 1515 case 2: 1516 *--str = 'x'; 1517 *--str = '0'; 1518 break; 1519 } 1520 len = num + sizeof(num) - 1 - str; 1521 } else { 1522 len = strlen(str); 1523 if (prec > 0 && len > prec) 1524 len = prec; 1525 } 1526 if (width > 0) { 1527 if (width > buflen) 1528 width = buflen; 1529 if ((n = width - len) > 0) { 1530 buflen -= n; 1531 for (; n > 0; --n) 1532 *buf++ = fillch; 1533 } 1534 } 1535 if (len > buflen) 1536 len = buflen; 1537 memcpy(buf, str, len); 1538 buf += len; 1539 buflen -= len; 1540 } 1541 *buf = 0; 1542 return buf - buf0; 1543 } 1544 1545 /* 1546 * script_setenv - set an environment variable value to be used 1547 * for scripts that we run (e.g. ip-up, auth-up, etc.) 1548 */ 1549 void 1550 script_setenv(char *var, char *value) 1551 { 1552 int vl = strlen(var); 1553 int i; 1554 char *p, *newstring; 1555 1556 if (asprintf(&newstring, "%s=%s", var, value) == -1) 1557 novm("script_setenv"); 1558 1559 /* check if this variable is already set */ 1560 if (script_env != 0) { 1561 for (i = 0; (p = script_env[i]) != 0; ++i) { 1562 if (strncmp(p, var, vl) == 0 && p[vl] == '=') { 1563 free(p); 1564 script_env[i] = newstring; 1565 return; 1566 } 1567 } 1568 } else { 1569 i = 0; 1570 script_env = (char **) calloc(16, sizeof(char *)); 1571 if (script_env == 0) 1572 novm("script_setenv"); 1573 s_env_nalloc = 16; 1574 } 1575 1576 /* reallocate script_env with more space if needed */ 1577 if (i + 1 >= s_env_nalloc) { 1578 int new_n = i + 17; 1579 char **newenv = reallocarray(script_env, 1580 new_n, sizeof(char *)); 1581 if (newenv == 0) 1582 novm("script_setenv"); 1583 script_env = newenv; 1584 s_env_nalloc = new_n; 1585 } 1586 1587 script_env[i] = newstring; 1588 script_env[i+1] = 0; 1589 } 1590