1 /* $OpenBSD: auth.c,v 1.31 2009/10/27 23:59:53 deraadt Exp $ */ 2 3 /* 4 * auth.c - PPP authentication and phase control. 5 * 6 * Copyright (c) 1989-2002 Paul Mackerras. 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(s) of the authors of this software must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. 23 * 24 * 4. Redistributions of any form whatsoever must retain the following 25 * acknowledgment: 26 * "This product includes software developed by Paul Mackerras 27 * <paulus@samba.org>". 28 * 29 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 30 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 31 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 32 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 33 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 34 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 35 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 36 * 37 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in 48 * the documentation and/or other materials provided with the 49 * distribution. 50 * 51 * 3. The name "Carnegie Mellon University" must not be used to 52 * endorse or promote products derived from this software without 53 * prior written permission. For permission or any legal 54 * details, please contact 55 * Office of Technology Transfer 56 * Carnegie Mellon University 57 * 5000 Forbes Avenue 58 * Pittsburgh, PA 15213-3890 59 * (412) 268-4387, fax: (412) 268-7395 60 * tech-transfer@andrew.cmu.edu 61 * 62 * 4. Redistributions of any form whatsoever must retain the following 63 * acknowledgment: 64 * "This product includes software developed by Computing Services 65 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 66 * 67 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 68 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 69 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 70 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 71 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 72 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 73 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 74 */ 75 76 #include <stdio.h> 77 #include <stddef.h> 78 #include <stdlib.h> 79 #include <unistd.h> 80 #include <syslog.h> 81 #include <pwd.h> 82 #include <string.h> 83 #include <sys/types.h> 84 #include <sys/stat.h> 85 #include <sys/socket.h> 86 #include <utmp.h> 87 #include <fcntl.h> 88 #if defined(_PATH_LASTLOG) && defined(_linux_) 89 #include <lastlog.h> 90 #endif 91 92 #include <netdb.h> 93 #include <netinet/in.h> 94 #include <arpa/inet.h> 95 96 #ifdef USE_PAM 97 #include <security/pam_appl.h> 98 #endif 99 100 #ifdef HAS_SHADOW 101 #include <shadow.h> 102 #ifndef PW_PPP 103 #define PW_PPP PW_LOGIN 104 #endif 105 #endif 106 107 #include "pppd.h" 108 #include "fsm.h" 109 #include "lcp.h" 110 #include "ipcp.h" 111 #include "upap.h" 112 #include "chap.h" 113 #ifdef CBCP_SUPPORT 114 #include "cbcp.h" 115 #endif 116 #include "pathnames.h" 117 118 /* Used for storing a sequence of words. Usually malloced. */ 119 struct wordlist { 120 struct wordlist *next; 121 char word[1]; 122 }; 123 124 /* Bits in scan_authfile return value */ 125 #define NONWILD_SERVER 1 126 #define NONWILD_CLIENT 2 127 128 #define ISWILD(word) (word[0] == '*' && word[1] == 0) 129 130 #define FALSE 0 131 #define TRUE 1 132 133 /* The name by which the peer authenticated itself to us. */ 134 char peer_authname[MAXNAMELEN]; 135 136 /* Records which authentication operations haven't completed yet. */ 137 static int auth_pending[NUM_PPP]; 138 139 /* Set if we have successfully called plogin() */ 140 static int logged_in; 141 142 /* Set if we have run the /etc/ppp/auth-up script. */ 143 static int did_authup; 144 145 /* List of addresses which the peer may use. */ 146 static struct wordlist *addresses[NUM_PPP]; 147 148 /* Number of network protocols which we have opened. */ 149 static int num_np_open; 150 151 /* Number of network protocols which have come up. */ 152 static int num_np_up; 153 154 /* Set if we got the contents of passwd[] from the pap-secrets file. */ 155 static int passwd_from_file; 156 157 /* Bits in auth_pending[] */ 158 #define PAP_WITHPEER 1 159 #define PAP_PEER 2 160 #define CHAP_WITHPEER 4 161 #define CHAP_PEER 8 162 163 extern char *crypt(const char *, const char *); 164 165 /* Prototypes for procedures local to this file. */ 166 167 static void network_phase(int); 168 static void check_idle(void *); 169 static void connect_time_expired(void *); 170 static int plogin(char *, char *, char **, int *); 171 static void plogout(void); 172 static int null_login(int); 173 static int get_pap_passwd(char *); 174 static int have_pap_secret(void); 175 static int have_chap_secret(char *, char *, u_int32_t); 176 static int ip_addr_check(u_int32_t, struct wordlist *); 177 static int scan_authfile(FILE *, char *, char *, u_int32_t, char *, 178 struct wordlist **, char *); 179 static void free_wordlist(struct wordlist *); 180 static void auth_script(char *); 181 static void set_allowed_addrs(int, struct wordlist *); 182 183 /* 184 * An Open on LCP has requested a change from Dead to Establish phase. 185 * Do what's necessary to bring the physical layer up. 186 */ 187 void 188 link_required(unit) 189 int unit; 190 { 191 } 192 193 /* 194 * LCP has terminated the link; go to the Dead phase and take the 195 * physical layer down. 196 */ 197 void 198 link_terminated(unit) 199 int unit; 200 { 201 if (phase == PHASE_DEAD) 202 return; 203 if (logged_in) 204 plogout(); 205 phase = PHASE_DEAD; 206 syslog(LOG_NOTICE, "Connection terminated."); 207 } 208 209 /* 210 * LCP has gone down; it will either die or try to re-establish. 211 */ 212 void 213 link_down(unit) 214 int unit; 215 { 216 int i; 217 struct protent *protp; 218 219 if (did_authup) { 220 auth_script(_PATH_AUTHDOWN); 221 did_authup = 0; 222 } 223 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 224 if (!protp->enabled_flag) 225 continue; 226 if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) 227 (*protp->lowerdown)(unit); 228 if (protp->protocol < 0xC000 && protp->close != NULL) 229 (*protp->close)(unit, "LCP down"); 230 } 231 num_np_open = 0; 232 num_np_up = 0; 233 if (phase != PHASE_DEAD) 234 phase = PHASE_TERMINATE; 235 } 236 237 /* 238 * The link is established. 239 * Proceed to the Dead, Authenticate or Network phase as appropriate. 240 */ 241 void 242 link_established(unit) 243 int unit; 244 { 245 int auth; 246 lcp_options *wo = &lcp_wantoptions[unit]; 247 lcp_options *go = &lcp_gotoptions[unit]; 248 lcp_options *ho = &lcp_hisoptions[unit]; 249 int i; 250 struct protent *protp; 251 252 /* 253 * Tell higher-level protocols that LCP is up. 254 */ 255 for (i = 0; (protp = protocols[i]) != NULL; ++i) 256 if (protp->protocol != PPP_LCP && protp->enabled_flag 257 && protp->lowerup != NULL) 258 (*protp->lowerup)(unit); 259 260 if (auth_required && !(go->neg_chap || go->neg_upap)) { 261 /* 262 * We wanted the peer to authenticate itself, and it refused: 263 * treat it as though it authenticated with PAP using a username 264 * of "" and a password of "". If that's not OK, boot it out. 265 */ 266 if (!wo->neg_upap || !null_login(unit)) { 267 syslog(LOG_WARNING, "peer refused to authenticate"); 268 lcp_close(unit, "peer refused to authenticate"); 269 return; 270 } 271 } 272 273 phase = PHASE_AUTHENTICATE; 274 auth = 0; 275 if (go->neg_chap) { 276 ChapAuthPeer(unit, our_name, go->chap_mdtype); 277 auth |= CHAP_PEER; 278 } else if (go->neg_upap) { 279 upap_authpeer(unit); 280 auth |= PAP_PEER; 281 } 282 if (ho->neg_chap) { 283 ChapAuthWithPeer(unit, user, ho->chap_mdtype); 284 auth |= CHAP_WITHPEER; 285 } else if (ho->neg_upap) { 286 if (passwd[0] == 0) { 287 passwd_from_file = 1; 288 if (!get_pap_passwd(passwd)) 289 syslog(LOG_ERR, "No secret found for PAP login"); 290 } 291 upap_authwithpeer(unit, user, passwd); 292 auth |= PAP_WITHPEER; 293 } 294 auth_pending[unit] = auth; 295 296 if (!auth) 297 network_phase(unit); 298 } 299 300 /* 301 * Proceed to the network phase. 302 */ 303 static void 304 network_phase(unit) 305 int unit; 306 { 307 int i; 308 struct protent *protp; 309 lcp_options *go = &lcp_gotoptions[unit]; 310 311 /* 312 * If the peer had to authenticate, run the auth-up script now. 313 */ 314 if ((go->neg_chap || go->neg_upap) && !did_authup) { 315 auth_script(_PATH_AUTHUP); 316 did_authup = 1; 317 } 318 319 #ifdef CBCP_SUPPORT 320 /* 321 * If we negotiated callback, do it now. 322 */ 323 if (go->neg_cbcp) { 324 phase = PHASE_CALLBACK; 325 (*cbcp_protent.open)(unit); 326 return; 327 } 328 #endif 329 330 phase = PHASE_NETWORK; 331 #if 0 332 if (!demand) 333 set_filters(&pass_filter, &active_filter); 334 #endif 335 for (i = 0; (protp = protocols[i]) != NULL; ++i) 336 if (protp->protocol < 0xC000 && protp->enabled_flag 337 && protp->open != NULL) { 338 (*protp->open)(unit); 339 if (protp->protocol != PPP_CCP) 340 ++num_np_open; 341 } 342 343 if (num_np_open == 0) 344 /* nothing to do */ 345 lcp_close(0, "No network protocols running"); 346 } 347 348 /* 349 * The peer has failed to authenticate himself using `protocol'. 350 */ 351 void 352 auth_peer_fail(unit, protocol) 353 int unit, protocol; 354 { 355 /* 356 * Authentication failure: take the link down 357 */ 358 lcp_close(unit, "Authentication failed"); 359 } 360 361 /* 362 * The peer has been successfully authenticated using `protocol'. 363 */ 364 void 365 auth_peer_success(unit, protocol, name, namelen) 366 int unit, protocol; 367 char *name; 368 int namelen; 369 { 370 int bit; 371 372 switch (protocol) { 373 case PPP_CHAP: 374 bit = CHAP_PEER; 375 break; 376 case PPP_PAP: 377 bit = PAP_PEER; 378 break; 379 default: 380 syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", 381 protocol); 382 return; 383 } 384 385 /* 386 * Save the authenticated name of the peer for later. 387 */ 388 if (namelen > sizeof(peer_authname) - 1) 389 namelen = sizeof(peer_authname) - 1; 390 BCOPY(name, peer_authname, namelen); 391 peer_authname[namelen] = 0; 392 script_setenv("PEERNAME", peer_authname); 393 394 /* 395 * If there is no more authentication still to be done, 396 * proceed to the network (or callback) phase. 397 */ 398 if ((auth_pending[unit] &= ~bit) == 0) 399 network_phase(unit); 400 } 401 402 /* 403 * We have failed to authenticate ourselves to the peer using `protocol'. 404 */ 405 void 406 auth_withpeer_fail(unit, protocol) 407 int unit, protocol; 408 { 409 if (passwd_from_file) 410 BZERO(passwd, MAXSECRETLEN); 411 /* 412 * We've failed to authenticate ourselves to our peer. 413 * He'll probably take the link down, and there's not much 414 * we can do except wait for that. 415 */ 416 } 417 418 /* 419 * We have successfully authenticated ourselves with the peer using `protocol'. 420 */ 421 void 422 auth_withpeer_success(unit, protocol) 423 int unit, protocol; 424 { 425 int bit; 426 427 switch (protocol) { 428 case PPP_CHAP: 429 bit = CHAP_WITHPEER; 430 break; 431 case PPP_PAP: 432 if (passwd_from_file) 433 BZERO(passwd, MAXSECRETLEN); 434 bit = PAP_WITHPEER; 435 break; 436 default: 437 syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", 438 protocol); 439 bit = 0; 440 } 441 442 /* 443 * If there is no more authentication still being done, 444 * proceed to the network (or callback) phase. 445 */ 446 if ((auth_pending[unit] &= ~bit) == 0) 447 network_phase(unit); 448 } 449 450 451 /* 452 * np_up - a network protocol has come up. 453 */ 454 void 455 np_up(unit, proto) 456 int unit, proto; 457 { 458 if (num_np_up == 0) { 459 /* 460 * At this point we consider that the link has come up successfully. 461 */ 462 need_holdoff = 0; 463 464 if (idle_time_limit > 0) 465 TIMEOUT(check_idle, NULL, idle_time_limit); 466 467 /* 468 * Set a timeout to close the connection once the maximum 469 * connect time has expired. 470 */ 471 if (maxconnect > 0) 472 TIMEOUT(connect_time_expired, 0, maxconnect); 473 474 /* 475 * Detach now, if the updetach option was given. 476 */ 477 if (nodetach == -1) 478 detach(); 479 } 480 ++num_np_up; 481 } 482 483 /* 484 * np_down - a network protocol has gone down. 485 */ 486 void 487 np_down(unit, proto) 488 int unit, proto; 489 { 490 if (--num_np_up == 0 && idle_time_limit > 0) { 491 UNTIMEOUT(check_idle, NULL); 492 } 493 } 494 495 /* 496 * np_finished - a network protocol has finished using the link. 497 */ 498 void 499 np_finished(unit, proto) 500 int unit, proto; 501 { 502 if (--num_np_open <= 0) { 503 /* no further use for the link: shut up shop. */ 504 lcp_close(0, "No network protocols running"); 505 } 506 } 507 508 /* 509 * check_idle - check whether the link has been idle for long 510 * enough that we can shut it down. 511 */ 512 static void 513 check_idle(arg) 514 void *arg; 515 { 516 struct ppp_idle idle; 517 time_t itime; 518 519 if (!get_idle_time(0, &idle)) 520 return; 521 itime = MIN(idle.xmit_idle, idle.recv_idle); 522 if (itime >= idle_time_limit) { 523 /* link is idle: shut it down. */ 524 syslog(LOG_INFO, "Terminating connection due to lack of activity."); 525 lcp_close(0, "Link inactive"); 526 } else { 527 TIMEOUT(check_idle, NULL, idle_time_limit - itime); 528 } 529 } 530 531 /* 532 * connect_time_expired - log a message and close the connection. 533 */ 534 static void 535 connect_time_expired(arg) 536 void *arg; 537 { 538 syslog(LOG_INFO, "Connect time expired"); 539 lcp_close(0, "Connect time expired"); /* Close connection */ 540 } 541 542 /* 543 * auth_check_options - called to check authentication options. 544 */ 545 void 546 auth_check_options() 547 { 548 lcp_options *wo = &lcp_wantoptions[0]; 549 int can_auth; 550 ipcp_options *ipwo = &ipcp_wantoptions[0]; 551 u_int32_t remote; 552 553 /* Default our_name to hostname, and user to our_name */ 554 if (our_name[0] == 0 || usehostname) 555 strlcpy(our_name, hostname, MAXHOSTNAMELEN); 556 if (user[0] == 0) 557 strlcpy(user, our_name, MAXNAMELEN); 558 559 /* If authentication is required, ask peer for CHAP or PAP. */ 560 if (auth_required && !wo->neg_chap && !wo->neg_upap) { 561 wo->neg_chap = 1; 562 wo->neg_upap = 1; 563 } 564 565 /* 566 * Check whether we have appropriate secrets to use 567 * to authenticate the peer. 568 */ 569 can_auth = wo->neg_upap && (uselogin || have_pap_secret()); 570 if (!can_auth && wo->neg_chap) { 571 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 572 can_auth = have_chap_secret(remote_name, our_name, remote); 573 } 574 575 if (auth_required && !can_auth) { 576 option_error("peer authentication required but no suitable secret(s) found\n"); 577 if (remote_name[0] == 0) 578 option_error("for authenticating any peer to us (%s)\n", our_name); 579 else 580 option_error("for authenticating peer %s to us (%s)\n", 581 remote_name, our_name); 582 exit(1); 583 } 584 585 /* 586 * Check whether the user tried to override certain values 587 * set by root. 588 */ 589 if (!auth_required && auth_req_info.priv > 0) { 590 if (!default_device && devnam_info.priv == 0) { 591 option_error("can't override device name when noauth option used"); 592 exit(1); 593 } 594 if ((connector != NULL && connector_info.priv == 0) 595 || (disconnector != NULL && disconnector_info.priv == 0) 596 || (welcomer != NULL && welcomer_info.priv == 0)) { 597 option_error("can't override connect, disconnect or welcome"); 598 option_error("option values when noauth option used"); 599 exit(1); 600 } 601 } 602 } 603 604 /* 605 * auth_reset - called when LCP is starting negotiations to recheck 606 * authentication options, i.e. whether we have appropriate secrets 607 * to use for authenticating ourselves and/or the peer. 608 */ 609 void 610 auth_reset(unit) 611 int unit; 612 { 613 lcp_options *go = &lcp_gotoptions[unit]; 614 lcp_options *ao = &lcp_allowoptions[0]; 615 ipcp_options *ipwo = &ipcp_wantoptions[0]; 616 u_int32_t remote; 617 618 ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); 619 ao->neg_chap = !refuse_chap 620 && have_chap_secret(user, remote_name, (u_int32_t)0); 621 622 if (go->neg_upap && !uselogin && !have_pap_secret()) 623 go->neg_upap = 0; 624 if (go->neg_chap) { 625 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 626 if (!have_chap_secret(remote_name, our_name, remote)) 627 go->neg_chap = 0; 628 } 629 } 630 631 632 /* 633 * check_passwd - Check the user name and passwd against the PAP secrets 634 * file. If requested, also check against the system password database, 635 * and login the user if OK. 636 * 637 * returns: 638 * UPAP_AUTHNAK: Authentication failed. 639 * UPAP_AUTHACK: Authentication succeeded. 640 * In either case, msg points to an appropriate message. 641 */ 642 int 643 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) 644 int unit; 645 char *auser; 646 int userlen; 647 char *apasswd; 648 int passwdlen; 649 char **msg; 650 int *msglen; 651 { 652 int ret; 653 char *filename; 654 FILE *f; 655 struct wordlist *addrs; 656 u_int32_t remote; 657 ipcp_options *ipwo = &ipcp_wantoptions[unit]; 658 char passwd[256], user[256]; 659 char secret[MAXWORDLEN]; 660 static int attempts = 0; 661 662 /* 663 * Make copies of apasswd and auser, then null-terminate them. 664 */ 665 BCOPY(apasswd, passwd, passwdlen); 666 passwd[passwdlen] = '\0'; 667 BCOPY(auser, user, userlen); 668 user[userlen] = '\0'; 669 *msg = (char *) 0; 670 671 /* 672 * Open the file of pap secrets and scan for a suitable secret 673 * for authenticating this user. 674 */ 675 filename = _PATH_UPAPFILE; 676 addrs = NULL; 677 ret = UPAP_AUTHACK; 678 f = fopen(filename, "r"); 679 if (f == NULL) { 680 syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); 681 ret = UPAP_AUTHNAK; 682 } else { 683 check_access(f, filename); 684 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 685 if (scan_authfile(f, user, our_name, remote, 686 secret, &addrs, filename) < 0 687 || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0) 688 && strcmp(crypt(passwd, secret), secret) != 0)) { 689 syslog(LOG_WARNING, "PAP authentication failure for %s", user); 690 ret = UPAP_AUTHNAK; 691 } 692 fclose(f); 693 } 694 695 if (uselogin && ret == UPAP_AUTHACK) { 696 ret = plogin(user, passwd, msg, msglen); 697 if (ret == UPAP_AUTHNAK) { 698 syslog(LOG_WARNING, "PAP login failure for %s", user); 699 } 700 } 701 702 if (ret == UPAP_AUTHNAK) { 703 if (*msg == (char *) 0) 704 *msg = "Login incorrect"; 705 *msglen = strlen(*msg); 706 /* 707 * Frustrate passwd stealer programs. 708 * Allow 10 tries, but start backing off after 3 (stolen from login). 709 * On 10'th, drop the connection. 710 */ 711 if (attempts++ >= 10) { 712 syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s", 713 attempts, devnam, user); 714 quit(); 715 } 716 if (attempts > 3) 717 sleep((u_int) (attempts - 3) * 5); 718 if (addrs != NULL) 719 free_wordlist(addrs); 720 721 } else { 722 attempts = 0; /* Reset count */ 723 if (*msg == (char *) 0) 724 *msg = "Login ok"; 725 *msglen = strlen(*msg); 726 set_allowed_addrs(unit, addrs); 727 } 728 729 BZERO(passwd, sizeof(passwd)); 730 BZERO(secret, sizeof(secret)); 731 732 return ret; 733 } 734 735 /* 736 * This function is needed for PAM. 737 */ 738 739 #ifdef USE_PAM 740 static char *PAM_username = ""; 741 static char *PAM_password = ""; 742 743 #ifdef PAM_ESTABLISH_CRED /* new PAM defines :(^ */ 744 #define MY_PAM_STRERROR(err_code) (char *) pam_strerror(pamh,err_code) 745 #else 746 #define MY_PAM_STRERROR(err_code) (char *) pam_strerror(err_code) 747 #endif 748 749 static int pam_conv (int num_msg, 750 const struct pam_message **msg, 751 struct pam_response **resp, 752 void *appdata_ptr) 753 { 754 int count = 0, replies = 0; 755 struct pam_response *reply = NULL; 756 int size = 0; 757 758 for (count = 0; count < num_msg; count++) 759 { 760 struct pam_response *newreply; 761 int newsize = size + sizeof (struct pam_response); 762 newreply = realloc (reply, newsize); /* ANSI: is malloc() if reply==NULL */ 763 if (!newreply) { 764 free(reply); 765 reply = NULL; 766 return PAM_CONV_ERR; 767 } 768 reply = newreply; 769 size = newsize; 770 771 switch (msg[count]->msg_style) 772 { 773 case PAM_PROMPT_ECHO_ON: 774 reply[replies].resp_retcode = PAM_SUCCESS; 775 reply[replies++].resp = strdup(PAM_username); /* never NULL */ 776 break; 777 778 case PAM_PROMPT_ECHO_OFF: 779 reply[replies].resp_retcode = PAM_SUCCESS; 780 reply[replies++].resp = strdup(PAM_password); /* never NULL */ 781 break; 782 783 case PAM_TEXT_INFO: 784 reply[replies].resp_retcode = PAM_SUCCESS; 785 reply[replies++].resp = NULL; 786 break; 787 788 case PAM_ERROR_MSG: 789 default: 790 free (reply); 791 return PAM_CONV_ERR; 792 } 793 } 794 795 if (resp) 796 *resp = reply; 797 else 798 free (reply); 799 800 return PAM_SUCCESS; 801 } 802 #endif 803 804 /* 805 * plogin - Check the user name and password against the system 806 * password database, and login the user if OK. 807 * 808 * returns: 809 * UPAP_AUTHNAK: Login failed. 810 * UPAP_AUTHACK: Login succeeded. 811 * In either case, msg points to an appropriate message. 812 */ 813 814 static int 815 plogin(user, passwd, msg, msglen) 816 char *user; 817 char *passwd; 818 char **msg; 819 int *msglen; 820 { 821 822 #ifdef USE_PAM 823 824 struct pam_conv pam_conversation; 825 pam_handle_t *pamh; 826 int pam_error; 827 /* 828 * Fill the pam_conversion structure 829 */ 830 memset (&pam_conversation, '\0', sizeof (struct pam_conv)); 831 pam_conversation.conv = &pam_conv; 832 833 pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); 834 835 if (pam_error != PAM_SUCCESS) { 836 *msg = MY_PAM_STRERROR (pam_error); 837 return UPAP_AUTHNAK; 838 } 839 /* 840 * Define the fields for the credential validation 841 */ 842 (void) pam_set_item (pamh, PAM_TTY, devnam); 843 PAM_username = user; 844 PAM_password = passwd; 845 /* 846 * Validate the user 847 */ 848 pam_error = pam_authenticate (pamh, PAM_SILENT); 849 if (pam_error == PAM_SUCCESS) { 850 pam_error = pam_acct_mgmt (pamh, PAM_SILENT); 851 852 /* start a session for this user. Session closed when link ends. */ 853 if (pam_error == PAM_SUCCESS) 854 (void) pam_open_session (pamh, PAM_SILENT); 855 } 856 857 *msg = MY_PAM_STRERROR (pam_error); 858 859 PAM_username = 860 PAM_password = ""; 861 /* 862 * Clean up the mess 863 */ 864 (void) pam_end (pamh, pam_error); 865 866 if (pam_error != PAM_SUCCESS) 867 return UPAP_AUTHNAK; 868 /* 869 * Use the non-PAM methods directly 870 */ 871 #else /* #ifdef USE_PAM */ 872 873 struct passwd *pw; 874 char *tty; 875 876 #ifdef HAS_SHADOW 877 struct spwd *spwd; 878 struct spwd *getspnam(); 879 #endif 880 881 pw = getpwnam(user); 882 endpwent(); 883 if (pw == NULL) { 884 return (UPAP_AUTHNAK); 885 } 886 887 #ifdef HAS_SHADOW 888 spwd = getspnam(user); 889 endspent(); 890 if (spwd) { 891 /* check the age of the password entry */ 892 long now = time(NULL) / 86400L; 893 894 if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) 895 || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) 896 && spwd->sp_lstchg >= 0 897 && now >= spwd->sp_lstchg + spwd->sp_max)) { 898 syslog(LOG_WARNING, "Password for %s has expired", user); 899 return (UPAP_AUTHNAK); 900 } 901 pw->pw_passwd = spwd->sp_pwdp; 902 } 903 #endif 904 905 /* 906 * If no passwd, don't let them login. 907 */ 908 if (pw->pw_passwd == NULL || *pw->pw_passwd == '\0' 909 || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) 910 return (UPAP_AUTHNAK); 911 912 /* These functions are not enabled for PAM. The reason for this is that */ 913 /* there is not necessarily a "passwd" entry for this user. That is */ 914 /* real purpose of 'PAM' -- to virtualize the account data from the */ 915 /* application. If you want to do the same thing, write the entry in */ 916 /* the 'session' hook. */ 917 918 /* 919 * Write a wtmp entry for this user. 920 */ 921 922 tty = devnam; 923 if (strncmp(tty, "/dev/", 5) == 0) 924 tty += 5; 925 logwtmp(tty, user, remote_name); /* Add wtmp login entry */ 926 927 #if defined(_PATH_LASTLOG) 928 { 929 struct lastlog ll; 930 int fd; 931 932 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { 933 (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); 934 memset((void *)&ll, 0, sizeof(ll)); 935 (void)time(&ll.ll_time); 936 (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 937 (void)write(fd, (char *)&ll, sizeof(ll)); 938 (void)close(fd); 939 } 940 } 941 #endif 942 943 #endif /* #ifdef USE_PAM */ 944 945 syslog(LOG_INFO, "user %s logged in", user); 946 logged_in = TRUE; 947 948 return (UPAP_AUTHACK); 949 } 950 951 /* 952 * plogout - Logout the user. 953 */ 954 static void 955 plogout() 956 { 957 #ifdef USE_PAM 958 struct pam_conv pam_conversation; 959 pam_handle_t *pamh; 960 int pam_error; 961 /* 962 * Fill the pam_conversion structure. The PAM specification states that the 963 * session must be able to be closed by a totally different handle from which 964 * it was created. Hold the PAM group to their own specification! 965 */ 966 memset (&pam_conversation, '\0', sizeof (struct pam_conv)); 967 pam_conversation.conv = &pam_conv; 968 969 pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); 970 if (pam_error == PAM_SUCCESS) { 971 (void) pam_set_item (pamh, PAM_TTY, devnam); 972 (void) pam_close_session (pamh, PAM_SILENT); 973 (void) pam_end (pamh, PAM_SUCCESS); 974 } 975 976 #else 977 char *tty; 978 979 tty = devnam; 980 if (strncmp(tty, "/dev/", 5) == 0) 981 tty += 5; 982 logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ 983 #endif 984 985 logged_in = FALSE; 986 } 987 988 989 /* 990 * null_login - Check if a username of "" and a password of "" are 991 * acceptable, and iff so, set the list of acceptable IP addresses 992 * and return 1. 993 */ 994 static int 995 null_login(unit) 996 int unit; 997 { 998 char *filename; 999 FILE *f; 1000 int i, ret; 1001 struct wordlist *addrs; 1002 char secret[MAXWORDLEN]; 1003 1004 /* 1005 * Open the file of pap secrets and scan for a suitable secret. 1006 * We don't accept a wildcard client. 1007 */ 1008 filename = _PATH_UPAPFILE; 1009 addrs = NULL; 1010 f = fopen(filename, "r"); 1011 if (f == NULL) 1012 return 0; 1013 check_access(f, filename); 1014 1015 i = scan_authfile(f, "", our_name, (u_int32_t)0, secret, &addrs, filename); 1016 ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0; 1017 BZERO(secret, sizeof(secret)); 1018 1019 if (ret) 1020 set_allowed_addrs(unit, addrs); 1021 else 1022 free_wordlist(addrs); 1023 1024 fclose(f); 1025 return ret; 1026 } 1027 1028 1029 /* 1030 * get_pap_passwd - get a password for authenticating ourselves with 1031 * our peer using PAP. Returns 1 on success, 0 if no suitable password 1032 * could be found. 1033 */ 1034 static int 1035 get_pap_passwd(passwd) 1036 char *passwd; 1037 { 1038 char *filename; 1039 FILE *f; 1040 int ret; 1041 struct wordlist *addrs; 1042 char secret[MAXWORDLEN]; 1043 1044 filename = _PATH_UPAPFILE; 1045 addrs = NULL; 1046 f = fopen(filename, "r"); 1047 if (f == NULL) 1048 return 0; 1049 check_access(f, filename); 1050 ret = scan_authfile(f, user, 1051 remote_name[0]? remote_name: NULL, 1052 (u_int32_t)0, secret, NULL, filename); 1053 fclose(f); 1054 if (ret < 0) 1055 return 0; 1056 if (passwd != NULL) 1057 strlcpy(passwd, secret, MAXSECRETLEN); 1058 BZERO(secret, sizeof(secret)); 1059 return 1; 1060 } 1061 1062 1063 /* 1064 * have_pap_secret - check whether we have a PAP file with any 1065 * secrets that we could possibly use for authenticating the peer. 1066 */ 1067 static int 1068 have_pap_secret() 1069 { 1070 FILE *f; 1071 int ret; 1072 char *filename; 1073 ipcp_options *ipwo = &ipcp_wantoptions[0]; 1074 u_int32_t remote; 1075 1076 filename = _PATH_UPAPFILE; 1077 f = fopen(filename, "r"); 1078 if (f == NULL) 1079 return 0; 1080 1081 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 1082 ret = scan_authfile(f, NULL, our_name, remote, NULL, NULL, filename); 1083 fclose(f); 1084 if (ret < 0) 1085 return 0; 1086 1087 return 1; 1088 } 1089 1090 1091 /* 1092 * have_chap_secret - check whether we have a CHAP file with a 1093 * secret that we could possibly use for authenticating `client' 1094 * on `server'. Either can be the null string, meaning we don't 1095 * know the identity yet. 1096 */ 1097 static int 1098 have_chap_secret(client, server, remote) 1099 char *client; 1100 char *server; 1101 u_int32_t remote; 1102 { 1103 FILE *f; 1104 int ret; 1105 char *filename; 1106 1107 filename = _PATH_CHAPFILE; 1108 f = fopen(filename, "r"); 1109 if (f == NULL) 1110 return 0; 1111 1112 if (client[0] == 0) 1113 client = NULL; 1114 else if (server[0] == 0) 1115 server = NULL; 1116 1117 ret = scan_authfile(f, client, server, remote, NULL, NULL, filename); 1118 fclose(f); 1119 if (ret < 0) 1120 return 0; 1121 1122 return 1; 1123 } 1124 1125 1126 /* 1127 * get_secret - open the CHAP secret file and return the secret 1128 * for authenticating the given client on the given server. 1129 * (We could be either client or server). 1130 */ 1131 int 1132 get_secret(unit, client, server, secret, secret_len, save_addrs) 1133 int unit; 1134 char *client; 1135 char *server; 1136 char *secret; 1137 int *secret_len; 1138 int save_addrs; 1139 { 1140 FILE *f; 1141 int ret, len; 1142 char *filename; 1143 struct wordlist *addrs; 1144 char secbuf[MAXWORDLEN]; 1145 1146 filename = _PATH_CHAPFILE; 1147 addrs = NULL; 1148 secbuf[0] = 0; 1149 1150 f = fopen(filename, "r"); 1151 if (f == NULL) { 1152 syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename); 1153 return 0; 1154 } 1155 check_access(f, filename); 1156 1157 ret = scan_authfile(f, client, server, (u_int32_t)0, 1158 secbuf, &addrs, filename); 1159 fclose(f); 1160 if (ret < 0) 1161 return 0; 1162 1163 if (save_addrs) 1164 set_allowed_addrs(unit, addrs); 1165 1166 len = strlen(secbuf); 1167 if (len > MAXSECRETLEN) { 1168 syslog(LOG_ERR, "Secret for %s on %s is too long", client, server); 1169 len = MAXSECRETLEN; 1170 } 1171 BCOPY(secbuf, secret, len); 1172 BZERO(secbuf, sizeof(secbuf)); 1173 *secret_len = len; 1174 1175 return 1; 1176 } 1177 1178 /* 1179 * set_allowed_addrs() - set the list of allowed addresses. 1180 */ 1181 static void 1182 set_allowed_addrs(unit, addrs) 1183 int unit; 1184 struct wordlist *addrs; 1185 { 1186 if (addresses[unit] != NULL) 1187 free_wordlist(addresses[unit]); 1188 addresses[unit] = addrs; 1189 1190 /* 1191 * If there's only one authorized address we might as well 1192 * ask our peer for that one right away 1193 */ 1194 if (addrs != NULL && addrs->next == NULL) { 1195 char *p = addrs->word; 1196 struct ipcp_options *wo = &ipcp_wantoptions[unit]; 1197 struct in_addr ina; 1198 struct hostent *hp; 1199 1200 if (*p != '!' && *p != '-' && !ISWILD(p) && strchr(p, '/') == NULL) { 1201 hp = gethostbyname(p); 1202 if (hp != NULL && hp->h_addrtype == AF_INET) 1203 wo->hisaddr = *(u_int32_t *)hp->h_addr; 1204 else if (inet_aton(p, &ina) == 1) 1205 wo->hisaddr = ina.s_addr; 1206 } 1207 } 1208 } 1209 1210 /* 1211 * auth_ip_addr - check whether the peer is authorized to use 1212 * a given IP address. Returns 1 if authorized, 0 otherwise. 1213 */ 1214 int 1215 auth_ip_addr(unit, addr) 1216 int unit; 1217 u_int32_t addr; 1218 { 1219 return ip_addr_check(addr, addresses[unit]); 1220 } 1221 1222 static int 1223 ip_addr_check(addr, addrs) 1224 u_int32_t addr; 1225 struct wordlist *addrs; 1226 { 1227 u_int32_t mask, ah; 1228 struct in_addr ina; 1229 int accept, r = 1; 1230 char *ptr_word, *ptr_mask; 1231 struct hostent *hp; 1232 struct netent *np; 1233 1234 /* don't allow loopback or multicast address */ 1235 if (bad_ip_adrs(addr)) 1236 return 0; 1237 1238 if (addrs == NULL) 1239 return !auth_required; /* no addresses authorized */ 1240 1241 for (; addrs != NULL; addrs = addrs->next) { 1242 /* "-" means no addresses authorized, "*" means any address allowed */ 1243 ptr_word = addrs->word; 1244 if (strcmp(ptr_word, "-") == 0) 1245 break; 1246 if (strcmp(ptr_word, "*") == 0) 1247 return 1; 1248 1249 accept = 1; 1250 if (*ptr_word == '!') { 1251 accept = 0; 1252 ++ptr_word; 1253 } 1254 1255 mask = ~ (u_int32_t) 0; 1256 ptr_mask = strchr (ptr_word, '/'); 1257 if (ptr_mask != NULL) { 1258 int bit_count; 1259 1260 bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10); 1261 if (bit_count <= 0 || bit_count > 32) { 1262 syslog (LOG_WARNING, 1263 "invalid address length %s in auth. address list", 1264 ptr_mask); 1265 continue; 1266 } 1267 *ptr_mask = '\0'; 1268 mask <<= 32 - bit_count; 1269 } 1270 1271 hp = gethostbyname(ptr_word); 1272 if (hp != NULL && hp->h_addrtype == AF_INET) { 1273 ina.s_addr = *(u_int32_t *)hp->h_addr; 1274 } else { 1275 np = getnetbyname (ptr_word); 1276 if (np != NULL && np->n_addrtype == AF_INET) 1277 ina.s_addr = htonl (np->n_net); 1278 else 1279 r = inet_aton (ptr_word, &ina); 1280 if (ptr_mask == NULL) { 1281 /* calculate appropriate mask for net */ 1282 ah = ntohl(ina.s_addr); 1283 if (IN_CLASSA(ah)) 1284 mask = IN_CLASSA_NET; 1285 else if (IN_CLASSB(ah)) 1286 mask = IN_CLASSB_NET; 1287 else if (IN_CLASSC(ah)) 1288 mask = IN_CLASSC_NET; 1289 } 1290 } 1291 1292 if (ptr_mask != NULL) 1293 *ptr_mask = '/'; 1294 1295 if (r == 0) 1296 syslog (LOG_WARNING, 1297 "unknown host %s in auth. address list", 1298 addrs->word); 1299 else 1300 /* Here ina.s_addr and addr are in network byte order, 1301 and mask is in host order. */ 1302 if (((addr ^ ina.s_addr) & htonl(mask)) == 0) 1303 return accept; 1304 } 1305 return 0; /* not in list => can't have it */ 1306 } 1307 1308 /* 1309 * bad_ip_adrs - return 1 if the IP address is one we don't want 1310 * to use, such as an address in the loopback net or a multicast address. 1311 * addr is in network byte order. 1312 */ 1313 int 1314 bad_ip_adrs(addr) 1315 u_int32_t addr; 1316 { 1317 addr = ntohl(addr); 1318 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET 1319 || IN_MULTICAST(addr) || IN_BADCLASS(addr); 1320 } 1321 1322 /* 1323 * check_access - complain if a secret file has too-liberal permissions. 1324 */ 1325 void 1326 check_access(f, filename) 1327 FILE *f; 1328 char *filename; 1329 { 1330 struct stat sbuf; 1331 1332 if (fstat(fileno(f), &sbuf) < 0) { 1333 syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename); 1334 } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { 1335 syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename); 1336 } 1337 } 1338 1339 1340 /* 1341 * scan_authfile - Scan an authorization file for a secret suitable 1342 * for authenticating `client' on `server'. The return value is -1 1343 * if no secret is found, otherwise >= 0. The return value has 1344 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and 1345 * NONWILD_SERVER set if the secret didn't have "*" for the server. 1346 * Any following words on the line (i.e. address authorization 1347 * info) are placed in a wordlist and returned in *addrs. 1348 */ 1349 static int 1350 scan_authfile(f, client, server, ipaddr, secret, addrs, filename) 1351 FILE *f; 1352 char *client; 1353 char *server; 1354 u_int32_t ipaddr; 1355 char *secret; 1356 struct wordlist **addrs; 1357 char *filename; 1358 { 1359 int newline, xxx; 1360 int got_flag, best_flag; 1361 FILE *sf; 1362 struct wordlist *ap, *addr_list, *alist, *alast; 1363 char word[MAXWORDLEN]; 1364 char atfile[MAXWORDLEN]; 1365 char lsecret[MAXWORDLEN]; 1366 1367 if (addrs != NULL) 1368 *addrs = NULL; 1369 addr_list = NULL; 1370 if (!getword(f, word, &newline, filename)) 1371 return -1; /* file is empty??? */ 1372 newline = 1; 1373 best_flag = -1; 1374 for (;;) { 1375 /* 1376 * Skip until we find a word at the start of a line. 1377 */ 1378 while (!newline && getword(f, word, &newline, filename)) 1379 ; 1380 if (!newline) 1381 break; /* got to end of file */ 1382 1383 /* 1384 * Got a client - check if it's a match or a wildcard. 1385 */ 1386 got_flag = 0; 1387 if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { 1388 newline = 0; 1389 continue; 1390 } 1391 if (!ISWILD(word)) 1392 got_flag = NONWILD_CLIENT; 1393 1394 /* 1395 * Now get a server and check if it matches. 1396 */ 1397 if (!getword(f, word, &newline, filename)) 1398 break; 1399 if (newline) 1400 continue; 1401 if (server != NULL && strcmp(word, server) != 0 && !ISWILD(word)) 1402 continue; 1403 if (!ISWILD(word)) 1404 got_flag |= NONWILD_SERVER; 1405 1406 /* 1407 * Got some sort of a match - see if it's better than what 1408 * we have already. 1409 */ 1410 if (got_flag <= best_flag) 1411 continue; 1412 1413 /* 1414 * Get the secret. 1415 */ 1416 if (!getword(f, word, &newline, filename)) 1417 break; 1418 if (newline) 1419 continue; 1420 1421 /* 1422 * Special syntax: @filename means read secret from file. 1423 */ 1424 if (word[0] == '@') { 1425 strlcpy(atfile, word+1, sizeof atfile); 1426 if ((sf = fopen(atfile, "r")) == NULL) { 1427 syslog(LOG_WARNING, "can't open indirect secret file %s", 1428 atfile); 1429 continue; 1430 } 1431 check_access(sf, atfile); 1432 if (!getword(sf, word, &xxx, atfile)) { 1433 syslog(LOG_WARNING, "no secret in indirect secret file %s", 1434 atfile); 1435 fclose(sf); 1436 continue; 1437 } 1438 fclose(sf); 1439 } 1440 if (secret != NULL) 1441 strlcpy(lsecret, word, sizeof lsecret); 1442 1443 /* 1444 * Now read address authorization info and make a wordlist. 1445 */ 1446 alist = alast = NULL; 1447 for (;;) { 1448 size_t wordlen; 1449 1450 if (!getword(f, word, &newline, filename) || newline) 1451 break; 1452 wordlen = strlen(word); /* NUL in struct wordlist */ 1453 ap = (struct wordlist *) malloc(sizeof(struct wordlist) + 1454 wordlen); 1455 1456 if (ap == NULL) 1457 novm("authorized addresses"); 1458 ap->next = NULL; 1459 strlcpy(ap->word, word, wordlen + 1); 1460 if (alist == NULL) 1461 alist = ap; 1462 else 1463 alast->next = ap; 1464 alast = ap; 1465 } 1466 1467 /* 1468 * Check if the given IP address is allowed by the wordlist. 1469 */ 1470 if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) { 1471 free_wordlist(alist); 1472 continue; 1473 } 1474 1475 /* 1476 * This is the best so far; remember it. 1477 */ 1478 best_flag = got_flag; 1479 if (addr_list) 1480 free_wordlist(addr_list); 1481 addr_list = alist; 1482 if (secret != NULL) 1483 strlcpy(secret, lsecret, MAXWORDLEN); 1484 1485 if (!newline) 1486 break; 1487 } 1488 1489 if (addrs != NULL) 1490 *addrs = addr_list; 1491 else if (addr_list != NULL) 1492 free_wordlist(addr_list); 1493 1494 return best_flag; 1495 } 1496 1497 /* 1498 * free_wordlist - release memory allocated for a wordlist. 1499 */ 1500 static void 1501 free_wordlist(wp) 1502 struct wordlist *wp; 1503 { 1504 struct wordlist *next; 1505 1506 while (wp != NULL) { 1507 next = wp->next; 1508 free(wp); 1509 wp = next; 1510 } 1511 } 1512 1513 /* 1514 * auth_script - execute a script with arguments 1515 * interface-name peer-name real-user tty speed 1516 */ 1517 static void 1518 auth_script(script) 1519 char *script; 1520 { 1521 char strspeed[32]; 1522 struct passwd *pw; 1523 char struid[32]; 1524 char *user_name; 1525 char *argv[8]; 1526 1527 if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) 1528 user_name = pw->pw_name; 1529 else { 1530 snprintf(struid, sizeof struid, "%u", getuid()); 1531 user_name = struid; 1532 } 1533 snprintf(strspeed, sizeof strspeed, "%d", baud_rate); 1534 1535 argv[0] = script; 1536 argv[1] = ifname; 1537 argv[2] = peer_authname; 1538 argv[3] = user_name; 1539 argv[4] = devnam; 1540 argv[5] = strspeed; 1541 argv[6] = NULL; 1542 1543 run_program(script, argv, 0); 1544 } 1545