mods from Al to use PAM; run auth-up/down scripts
[ppp.git] / pppd / auth.c
1 /*
2  * auth.c - PPP authentication and phase control.
3  *
4  * Copyright (c) 1993 The Australian National University.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms are permitted
8  * provided that the above copyright notice and this paragraph are
9  * duplicated in all such forms and that any documentation,
10  * advertising materials, and other materials related to such
11  * distribution and use acknowledge that the software was developed
12  * by the Australian National University.  The name of the University
13  * may not be used to endorse or promote products derived from this
14  * software without specific prior written permission.
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * Copyright (c) 1989 Carnegie Mellon University.
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms are permitted
23  * provided that the above copyright notice and this paragraph are
24  * duplicated in all such forms and that any documentation,
25  * advertising materials, and other materials related to such
26  * distribution and use acknowledge that the software was developed
27  * by Carnegie Mellon University.  The name of the
28  * University may not be used to endorse or promote products derived
29  * from this software without specific prior written permission.
30  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
31  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
32  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
33  */
34
35 #ifndef lint
36 static char rcsid[] = "$Id: auth.c,v 1.24 1996/06/26 00:56:11 paulus Exp $";
37 #endif
38
39 #include <stdio.h>
40 #include <stddef.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <syslog.h>
44 #include <pwd.h>
45 #include <string.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <sys/socket.h>
49
50 #include <netdb.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
53
54 #ifdef SVR4
55 #include <crypt.h>
56 #else
57 #ifdef SUNOS4
58 extern char *crypt();
59 #endif
60 #endif
61
62 #ifdef USE_PAM
63 #include <security/pam_appl.h>
64 #include <security/pam_modules.h>
65 #endif
66
67 #ifdef HAS_SHADOW
68 #include <shadow.h>
69 #include <shadow/pwauth.h>
70 #ifndef PW_PPP
71 #define PW_PPP PW_LOGIN
72 #endif
73 #endif
74
75 #include "pppd.h"
76 #include "fsm.h"
77 #include "lcp.h"
78 #include "ipcp.h"
79 #include "upap.h"
80 #include "chap.h"
81 #include "pathnames.h"
82
83 #if defined(sun) && defined(sparc)
84 #include <alloca.h>
85 #endif /*sparc*/
86
87 /* Used for storing a sequence of words.  Usually malloced. */
88 struct wordlist {
89     struct wordlist     *next;
90     char                word[1];
91 };
92
93 /* Bits in scan_authfile return value */
94 #define NONWILD_SERVER  1
95 #define NONWILD_CLIENT  2
96
97 #define ISWILD(word)    (word[0] == '*' && word[1] == 0)
98
99 #define FALSE   0
100 #define TRUE    1
101
102 /* The name by which the peer authenticated itself to us. */
103 char peer_authname[MAXNAMELEN];
104
105 /* Records which authentication operations haven't completed yet. */
106 static int auth_pending[NUM_PPP];
107
108 /* Set if we have successfully called login() */
109 static int logged_in;
110
111 /* Set if we have run the /etc/ppp/auth-up script. */
112 static int did_authup;
113
114 /* List of addresses which the peer may use. */
115 static struct wordlist *addresses[NUM_PPP];
116
117 /* Number of network protocols which we have opened. */
118 static int num_np_open;
119
120 /* Number of network protocols which have come up. */
121 static int num_np_up;
122
123 /* Bits in auth_pending[] */
124 #define UPAP_WITHPEER   1
125 #define UPAP_PEER       2
126 #define CHAP_WITHPEER   4
127 #define CHAP_PEER       8
128
129 /* Prototypes for procedures local to this file. */
130
131 static void network_phase __P((int));
132 static void check_idle __P((caddr_t));
133 static int  login __P((char *, char *, char **, int *));
134 static void logout __P((void));
135 static int  null_login __P((int));
136 static int  get_upap_passwd __P((void));
137 static int  have_upap_secret __P((void));
138 static int  have_chap_secret __P((char *, char *, u_int32_t));
139 static int  ip_addr_check __P((u_int32_t, struct wordlist *));
140 static int  scan_authfile __P((FILE *, char *, char *, u_int32_t, char *,
141                                struct wordlist **, char *));
142 static void free_wordlist __P((struct wordlist *));
143 static void auth_script __P((char *));
144
145 /*
146  * An Open on LCP has requested a change from Dead to Establish phase.
147  * Do what's necessary to bring the physical layer up.
148  */
149 void
150 link_required(unit)
151     int unit;
152 {
153 }
154
155 /*
156  * LCP has terminated the link; go to the Dead phase and take the
157  * physical layer down.
158  */
159 void
160 link_terminated(unit)
161     int unit;
162 {
163     if (phase == PHASE_DEAD)
164         return;
165     if (logged_in)
166         logout();
167     phase = PHASE_DEAD;
168     syslog(LOG_NOTICE, "Connection terminated.");
169 }
170
171 /*
172  * LCP has gone down; it will either die or try to re-establish.
173  */
174 void
175 link_down(unit)
176     int unit;
177 {
178     int i;
179     struct protent *protp;
180
181     if (did_authup) {
182         auth_script(_PATH_AUTHDOWN);
183         did_authup = 0;
184     }
185     for (i = 0; (protp = protocols[i]) != NULL; ++i) {
186         if (!protp->enabled_flag)
187             continue;
188         if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
189             (*protp->lowerdown)(unit);
190         if (protp->protocol < 0xC000 && protp->close != NULL)
191             (*protp->close)(unit, "LCP down");
192     }
193     num_np_open = 0;
194     num_np_up = 0;
195     phase = PHASE_TERMINATE;
196 }
197
198 /*
199  * The link is established.
200  * Proceed to the Dead, Authenticate or Network phase as appropriate.
201  */
202 void
203 link_established(unit)
204     int unit;
205 {
206     int auth;
207     lcp_options *wo = &lcp_wantoptions[unit];
208     lcp_options *go = &lcp_gotoptions[unit];
209     lcp_options *ho = &lcp_hisoptions[unit];
210     int i;
211     struct protent *protp;
212
213     /*
214      * Tell higher-level protocols that LCP is up.
215      */
216     for (i = 0; (protp = protocols[i]) != NULL; ++i)
217         if (protp->protocol != PPP_LCP && protp->enabled_flag
218             && protp->lowerup != NULL)
219             (*protp->lowerup)(unit);
220
221     if (auth_required && !(go->neg_chap || go->neg_upap)) {
222         /*
223          * We wanted the peer to authenticate itself, and it refused:
224          * treat it as though it authenticated with PAP using a username
225          * of "" and a password of "".  If that's not OK, boot it out.
226          */
227         if (!wo->neg_upap || !null_login(unit)) {
228             syslog(LOG_WARNING, "peer refused to authenticate");
229             lcp_close(unit, "peer refused to authenticate");
230             phase = PHASE_TERMINATE;
231             return;
232         }
233     }
234
235     phase = PHASE_AUTHENTICATE;
236     auth = 0;
237     if (go->neg_chap) {
238         ChapAuthPeer(unit, our_name, go->chap_mdtype);
239         auth |= CHAP_PEER;
240     } else if (go->neg_upap) {
241         upap_authpeer(unit);
242         auth |= UPAP_PEER;
243     }
244     if (ho->neg_chap) {
245         ChapAuthWithPeer(unit, our_name, ho->chap_mdtype);
246         auth |= CHAP_WITHPEER;
247     } else if (ho->neg_upap) {
248         upap_authwithpeer(unit, user, passwd);
249         auth |= UPAP_WITHPEER;
250     }
251     auth_pending[unit] = auth;
252
253     if (!auth)
254         network_phase(unit);
255 }
256
257 /*
258  * Proceed to the network phase.
259  */
260 static void
261 network_phase(unit)
262     int unit;
263 {
264     int i;
265     struct protent *protp;
266     lcp_options *go = &lcp_gotoptions[unit];
267
268     /*
269      * If the peer had to authenticate, run the auth-up script now.
270      */
271     if ((go->neg_chap || go->neg_upap) && !did_authup) {
272         auth_script(_PATH_AUTHUP);
273         did_authup = 1;
274     }
275
276     phase = PHASE_NETWORK;
277 #if 0
278     if (!demand)
279         set_filters(&pass_filter, &active_filter);
280 #endif
281     for (i = 0; (protp = protocols[i]) != NULL; ++i)
282         if (protp->protocol < 0xC000 && protp->enabled_flag
283             && protp->open != NULL) {
284             (*protp->open)(unit);
285             if (protp->protocol != PPP_CCP)
286                 ++num_np_open;
287         }
288 }
289
290 /*
291  * The peer has failed to authenticate himself using `protocol'.
292  */
293 void
294 auth_peer_fail(unit, protocol)
295     int unit, protocol;
296 {
297     /*
298      * Authentication failure: take the link down
299      */
300     lcp_close(unit, "Authentication failed");
301     phase = PHASE_TERMINATE;
302 }
303
304 /*
305  * The peer has been successfully authenticated using `protocol'.
306  */
307 void
308 auth_peer_success(unit, protocol, name, namelen)
309     int unit, protocol;
310     char *name;
311     int namelen;
312 {
313     int bit;
314
315     switch (protocol) {
316     case PPP_CHAP:
317         bit = CHAP_PEER;
318         break;
319     case PPP_PAP:
320         bit = UPAP_PEER;
321         break;
322     default:
323         syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
324                protocol);
325         return;
326     }
327
328     /*
329      * Save the authenticated name of the peer for later.
330      */
331     if (namelen > sizeof(peer_authname) - 1)
332         namelen = sizeof(peer_authname) - 1;
333     BCOPY(name, peer_authname, namelen);
334     peer_authname[namelen] = 0;
335
336     /*
337      * If there is no more authentication still to be done,
338      * proceed to the network phase.
339      */
340     if ((auth_pending[unit] &= ~bit) == 0)
341         network_phase(unit);
342 }
343
344 /*
345  * We have failed to authenticate ourselves to the peer using `protocol'.
346  */
347 void
348 auth_withpeer_fail(unit, protocol)
349     int unit, protocol;
350 {
351     /*
352      * We've failed to authenticate ourselves to our peer.
353      * He'll probably take the link down, and there's not much
354      * we can do except wait for that.
355      */
356 }
357
358 /*
359  * We have successfully authenticated ourselves with the peer using `protocol'.
360  */
361 void
362 auth_withpeer_success(unit, protocol)
363     int unit, protocol;
364 {
365     int bit;
366
367     switch (protocol) {
368     case PPP_CHAP:
369         bit = CHAP_WITHPEER;
370         break;
371     case PPP_PAP:
372         bit = UPAP_WITHPEER;
373         break;
374     default:
375         syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
376                protocol);
377         bit = 0;
378     }
379
380     /*
381      * If there is no more authentication still being done,
382      * proceed to the network phase.
383      */
384     if ((auth_pending[unit] &= ~bit) == 0)
385         network_phase(unit);
386 }
387
388
389 /*
390  * np_up - a network protocol has come up.
391  */
392 void
393 np_up(unit, proto)
394     int unit, proto;
395 {
396     if (num_np_up == 0 && idle_time_limit > 0) {
397         TIMEOUT(check_idle, NULL, idle_time_limit);
398     }
399     ++num_np_up;
400 }
401
402 /*
403  * np_down - a network protocol has gone down.
404  */
405 void
406 np_down(unit, proto)
407     int unit, proto;
408 {
409     if (--num_np_up == 0 && idle_time_limit > 0) {
410         UNTIMEOUT(check_idle, NULL);
411     }
412 }
413
414 /*
415  * np_finished - a network protocol has finished using the link.
416  */
417 void
418 np_finished(unit, proto)
419     int unit, proto;
420 {
421     if (--num_np_open <= 0) {
422         /* no further use for the link: shut up shop. */
423         lcp_close(0, "No network protocols running");
424     }
425 }
426
427 /*
428  * check_idle - check whether the link has been idle for long
429  * enough that we can shut it down.
430  */
431 static void
432 check_idle(arg)
433     caddr_t arg;
434 {
435     struct ppp_idle idle;
436     time_t itime;
437
438     if (!get_idle_time(0, &idle))
439         return;
440     itime = MIN(idle.xmit_idle, idle.recv_idle);
441     if (itime >= idle_time_limit) {
442         /* link is idle: shut it down. */
443         syslog(LOG_INFO, "Terminating connection due to lack of activity.");
444         lcp_close(0, "Link inactive");
445     } else {
446         TIMEOUT(check_idle, NULL, idle_time_limit - itime);
447     }
448 }
449
450 /*
451  * auth_check_options - called to check authentication options.
452  */
453 void
454 auth_check_options()
455 {
456     lcp_options *wo = &lcp_wantoptions[0];
457     lcp_options *ao = &lcp_allowoptions[0];
458     ipcp_options *ipwo = &ipcp_wantoptions[0];
459     u_int32_t remote;
460
461     /* Default our_name to hostname, and user to our_name */
462     if (our_name[0] == 0 || usehostname)
463         strcpy(our_name, hostname);
464     if (user[0] == 0)
465         strcpy(user, our_name);
466
467     /* If authentication is required, ask peer for CHAP or PAP. */
468     if (auth_required && !wo->neg_chap && !wo->neg_upap) {
469         wo->neg_chap = 1;
470         wo->neg_upap = 1;
471     }
472
473     /*
474      * Check whether we have appropriate secrets to use
475      * to authenticate ourselves and/or the peer.
476      */
477     if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd())
478         ao->neg_upap = 0;
479     if (wo->neg_upap && !uselogin && !have_upap_secret())
480         wo->neg_upap = 0;
481     if (ao->neg_chap && !have_chap_secret(our_name, remote_name, (u_int32_t)0))
482         ao->neg_chap = 0;
483     if (wo->neg_chap) {
484         remote = ipwo->accept_remote? 0: ipwo->hisaddr;
485         if (!have_chap_secret(remote_name, our_name, remote))
486             wo->neg_chap = 0;
487     }
488
489     if (auth_required && !wo->neg_chap && !wo->neg_upap) {
490         fprintf(stderr, "\
491 pppd: peer authentication required but no suitable secret(s) found\n");
492         exit(1);
493     }
494
495 }
496
497
498 /*
499  * check_passwd - Check the user name and passwd against the PAP secrets
500  * file.  If requested, also check against the system password database,
501  * and login the user if OK.
502  *
503  * returns:
504  *      UPAP_AUTHNAK: Authentication failed.
505  *      UPAP_AUTHACK: Authentication succeeded.
506  * In either case, msg points to an appropriate message.
507  */
508 int
509 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
510     int unit;
511     char *auser;
512     int userlen;
513     char *apasswd;
514     int passwdlen;
515     char **msg;
516     int *msglen;
517 {
518     int ret;
519     char *filename;
520     FILE *f;
521     struct wordlist *addrs;
522     u_int32_t remote;
523     ipcp_options *ipwo = &ipcp_wantoptions[unit];
524     char passwd[256], user[256];
525     char secret[MAXWORDLEN];
526     static int attempts = 0;
527
528     /*
529      * Make copies of apasswd and auser, then null-terminate them.
530      */
531     BCOPY(apasswd, passwd, passwdlen);
532     passwd[passwdlen] = '\0';
533     BCOPY(auser, user, userlen);
534     user[userlen] = '\0';
535     *msg = (char *) 0;
536
537     /*
538      * Open the file of upap secrets and scan for a suitable secret
539      * for authenticating this user.
540      */
541     filename = _PATH_UPAPFILE;
542     addrs = NULL;
543     ret = UPAP_AUTHACK;
544     f = fopen(filename, "r");
545     if (f == NULL) {
546         if (!uselogin) {
547             syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename);
548             ret = UPAP_AUTHNAK;
549         }
550
551     } else {
552         check_access(f, filename);
553         remote = ipwo->accept_remote? 0: ipwo->hisaddr;
554         if (scan_authfile(f, user, our_name, remote,
555                           secret, &addrs, filename) < 0
556             || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0)
557                 && strcmp(crypt(passwd, secret), secret) != 0)) {
558             syslog(LOG_WARNING, "PAP authentication failure for %s", user);
559             ret = UPAP_AUTHNAK;
560         }
561         fclose(f);
562     }
563
564     if (uselogin && ret == UPAP_AUTHACK) {
565         ret = login(user, passwd, msg, msglen);
566         if (ret == UPAP_AUTHNAK) {
567             syslog(LOG_WARNING, "PAP login failure for %s", user);
568         }
569     }
570
571     if (ret == UPAP_AUTHNAK) {
572         if (*msg == (char *) 0)
573             *msg = "Login incorrect";
574         *msglen = strlen(*msg);
575         /*
576          * Frustrate passwd stealer programs.
577          * Allow 10 tries, but start backing off after 3 (stolen from login).
578          * On 10'th, drop the connection.
579          */
580         if (attempts++ >= 10) {
581             syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s",
582                    attempts, devnam, user);
583             quit();
584         }
585         if (attempts > 3)
586             sleep((u_int) (attempts - 3) * 5);
587         if (addrs != NULL)
588             free_wordlist(addrs);
589
590     } else {
591         attempts = 0;                   /* Reset count */
592         if (*msg == (char *) 0)
593             *msg = "Login ok";
594         *msglen = strlen(*msg);
595         if (addresses[unit] != NULL)
596             free_wordlist(addresses[unit]);
597         addresses[unit] = addrs;
598     }
599
600     return ret;
601 }
602
603 #ifdef HAS_SHADOW
604 /**************
605  * This function was lifted from the shadow-3.3.2 version by John Haugh II.
606  * It is included because the function was not in the standard libshadow
607  * library. If it is included in the library then I can remove it from here.
608  */
609
610 #define DAY     (24L*3600L)
611 /*
612  * isexpired - determine if account is expired yet
613  *
614  *      isexpired calculates the expiration date based on the
615  *      password expiration criteria.
616  */
617
618 /*ARGSUSED*/
619 int
620 isexpired (pw, sp)
621 struct  passwd  *pw;
622 struct  spwd    *sp;
623 {
624         long    clock;
625
626         clock = time ((time_t *) 0) / DAY;
627
628         /*
629          * Quick and easy - there is an expired account field
630          * along with an inactive account field.  Do the expired
631          * one first since it is worse.
632          */
633
634         if (sp->sp_expire > 0 && sp->sp_expire < clock)
635                 return 3;
636
637         if (sp->sp_inact > 0 && sp->sp_lstchg > 0 && sp->sp_max > 0 &&
638                         sp->sp_inact + sp->sp_lstchg + sp->sp_max < clock)
639                 return 2;
640
641         /*
642          * The last and max fields must be present for an account
643          * to have an expired password.  A maximum of >10000 days
644          * is considered to be infinite.
645          */
646
647         if (sp->sp_lstchg == -1 ||
648                         sp->sp_max == -1 || sp->sp_max >= 10000L)
649                 return 0;
650
651         /*
652          * Calculate today's day and the day on which the password
653          * is going to expire.  If that date has already passed,
654          * the password has expired.
655          */
656
657         if (sp->sp_lstchg + sp->sp_max < clock)
658                 return 1;
659
660         return 0;
661 }
662 #endif
663
664
665 /*
666  * This function is needed for PAM. However, it should not be called.
667  * If it is, return the error code.
668  */
669
670 #ifdef USE_PAM
671 static int pam_conv(int num_msg, const struct pam_message **msg,
672                     struct pam_response **resp, void *appdata_ptr)
673 {
674     return PAM_CONV_ERR;
675 }
676 #endif
677
678 /*
679  * login - Check the user name and password against the system
680  * password database, and login the user if OK.
681  *
682  * returns:
683  *      UPAP_AUTHNAK: Login failed.
684  *      UPAP_AUTHACK: Login succeeded.
685  * In either case, msg points to an appropriate message.
686  */
687
688 static int
689 login(user, passwd, msg, msglen)
690     char *user;
691     char *passwd;
692     char **msg;
693     int *msglen;
694 {
695     char *tty;
696
697 #ifdef USE_PAM
698     struct pam_conv pam_conversation;
699     pam_handle_t *pamh;
700     int pam_error;
701     char *pass;
702     char *dev;
703 /*
704  * Fill the pam_conversion structure
705  */
706     memset (&pam_conversation, '\0', sizeof (struct pam_conv));
707     pam_conversation.conv = &pam_conv;
708
709     pam_error = pam_start ("ppp", user, &pam_conversation, &pamh);
710     if (pam_error != PAM_SUCCESS) {
711         *msg = (char *) pam_strerror (pam_error);
712         return UPAP_AUTHNAK;
713     }
714 /*
715  * Define the fields for the credintial validation
716  */
717     (void) pam_set_item (pamh, PAM_AUTHTOK, passwd);
718     (void) pam_set_item (pamh, PAM_TTY, devnam);
719 /*
720  * Validate the user
721  */
722     pam_error = pam_authenticate (pamh, PAM_SILENT);
723     if (pam_error == PAM_SUCCESS)
724         pam_error = pam_acct_mgmt (pamh, PAM_SILENT);
725
726     *msg = (char *) pam_strerror (pam_error);
727 /*
728  * Clean up the mess
729  */
730     (void) pam_end (pamh, pam_error);
731
732     if (pam_error != PAM_SUCCESS)
733         return UPAP_AUTHNAK;
734 /*
735  * Use the non-PAM methods directly
736  */
737 #else /* #ifdef USE_PAM */
738
739     struct passwd *pw;
740     char *epasswd;
741
742 #ifdef HAS_SHADOW
743     struct spwd *spwd;
744     struct spwd *getspnam();
745 #endif
746
747     if ((pw = getpwnam(user)) == NULL) {
748         return (UPAP_AUTHNAK);
749     }
750
751 #ifdef HAS_SHADOW
752     if ((spwd = getspnam(user)) == NULL) {
753         pw->pw_passwd = "";
754     } else {
755         pw->pw_passwd = spwd->sp_pwdp;
756     }
757 #endif
758
759     /*
760      * XXX If no passwd, let them login without one.
761      */
762     if (pw->pw_passwd == '\0') {
763         return (UPAP_AUTHACK);
764     }
765
766 #ifdef HAS_SHADOW
767     if (pw->pw_passwd) {
768         if (pw->pw_passwd[0] == '@') {
769             if (pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) {
770                 return (UPAP_AUTHNAK);
771             }
772         } else {
773             epasswd = pw_encrypt(passwd, pw->pw_passwd);
774             if (strcmp(epasswd, pw->pw_passwd)) {
775                 return (UPAP_AUTHNAK);
776             }
777         }
778         /* check the age of the password entry */
779         if (spwd && (isexpired (pw, spwd) != 0)) {
780             return (UPAP_AUTHNAK);
781         }
782     }
783 #else
784     epasswd = crypt(passwd, pw->pw_passwd);
785     if (strcmp(epasswd, pw->pw_passwd)) {
786         return (UPAP_AUTHNAK);
787     }
788 #endif
789 #endif /* #ifdef USE_PAM */
790
791     syslog(LOG_INFO, "user %s logged in", user);
792
793     /*
794      * Write a wtmp entry for this user.
795      */
796     tty = devnam;
797     if (strncmp(tty, "/dev/", 5) == 0)
798         tty += 5;
799     logwtmp(tty, user, remote_name);            /* Add wtmp login entry */
800     logged_in = TRUE;
801
802     return (UPAP_AUTHACK);
803 }
804
805 /*
806  * logout - Logout the user.
807  */
808 static void
809 logout()
810 {
811     char *tty;
812
813     tty = devnam;
814     if (strncmp(tty, "/dev/", 5) == 0)
815         tty += 5;
816     logwtmp(tty, "", "");               /* Wipe out wtmp logout entry */
817     logged_in = FALSE;
818 }
819
820
821 /*
822  * null_login - Check if a username of "" and a password of "" are
823  * acceptable, and iff so, set the list of acceptable IP addresses
824  * and return 1.
825  */
826 static int
827 null_login(unit)
828     int unit;
829 {
830     char *filename;
831     FILE *f;
832     int i, ret;
833     struct wordlist *addrs;
834     char secret[MAXWORDLEN];
835
836     /*
837      * Open the file of upap secrets and scan for a suitable secret.
838      * We don't accept a wildcard client.
839      */
840     filename = _PATH_UPAPFILE;
841     addrs = NULL;
842     f = fopen(filename, "r");
843     if (f == NULL)
844         return 0;
845     check_access(f, filename);
846
847     i = scan_authfile(f, "", our_name, (u_int32_t)0, secret, &addrs, filename);
848     ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0;
849
850     if (ret) {
851         if (addresses[unit] != NULL)
852             free_wordlist(addresses[unit]);
853         addresses[unit] = addrs;
854     }
855
856     fclose(f);
857     return ret;
858 }
859
860
861 /*
862  * get_upap_passwd - get a password for authenticating ourselves with
863  * our peer using PAP.  Returns 1 on success, 0 if no suitable password
864  * could be found.
865  */
866 static int
867 get_upap_passwd()
868 {
869     char *filename;
870     FILE *f;
871     struct wordlist *addrs;
872     char secret[MAXWORDLEN];
873
874     filename = _PATH_UPAPFILE;
875     addrs = NULL;
876     f = fopen(filename, "r");
877     if (f == NULL)
878         return 0;
879     check_access(f, filename);
880     if (scan_authfile(f, user, remote_name, (u_int32_t)0,
881                       secret, NULL, filename) < 0)
882         return 0;
883     strncpy(passwd, secret, MAXSECRETLEN);
884     passwd[MAXSECRETLEN-1] = 0;
885     return 1;
886 }
887
888
889 /*
890  * have_upap_secret - check whether we have a PAP file with any
891  * secrets that we could possibly use for authenticating the peer.
892  */
893 static int
894 have_upap_secret()
895 {
896     FILE *f;
897     int ret;
898     char *filename;
899     ipcp_options *ipwo = &ipcp_wantoptions[0];
900     u_int32_t remote;
901
902     filename = _PATH_UPAPFILE;
903     f = fopen(filename, "r");
904     if (f == NULL)
905         return 0;
906
907     remote = ipwo->accept_remote? 0: ipwo->hisaddr;
908     ret = scan_authfile(f, NULL, our_name, remote, NULL, NULL, filename);
909     fclose(f);
910     if (ret < 0)
911         return 0;
912
913     return 1;
914 }
915
916
917 /*
918  * have_chap_secret - check whether we have a CHAP file with a
919  * secret that we could possibly use for authenticating `client'
920  * on `server'.  Either can be the null string, meaning we don't
921  * know the identity yet.
922  */
923 static int
924 have_chap_secret(client, server, remote)
925     char *client;
926     char *server;
927     u_int32_t remote;
928 {
929     FILE *f;
930     int ret;
931     char *filename;
932
933     filename = _PATH_CHAPFILE;
934     f = fopen(filename, "r");
935     if (f == NULL)
936         return 0;
937
938     if (client[0] == 0)
939         client = NULL;
940     else if (server[0] == 0)
941         server = NULL;
942
943     ret = scan_authfile(f, client, server, remote, NULL, NULL, filename);
944     fclose(f);
945     if (ret < 0)
946         return 0;
947
948     return 1;
949 }
950
951
952 /*
953  * get_secret - open the CHAP secret file and return the secret
954  * for authenticating the given client on the given server.
955  * (We could be either client or server).
956  */
957 int
958 get_secret(unit, client, server, secret, secret_len, save_addrs)
959     int unit;
960     char *client;
961     char *server;
962     char *secret;
963     int *secret_len;
964     int save_addrs;
965 {
966     FILE *f;
967     int ret, len;
968     char *filename;
969     struct wordlist *addrs;
970     char secbuf[MAXWORDLEN];
971
972     filename = _PATH_CHAPFILE;
973     addrs = NULL;
974     secbuf[0] = 0;
975
976     f = fopen(filename, "r");
977     if (f == NULL) {
978         syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename);
979         return 0;
980     }
981     check_access(f, filename);
982
983     ret = scan_authfile(f, client, server, (u_int32_t)0,
984                         secbuf, &addrs, filename);
985     fclose(f);
986     if (ret < 0)
987         return 0;
988
989     if (save_addrs) {
990         if (addresses[unit] != NULL)
991             free_wordlist(addresses[unit]);
992         addresses[unit] = addrs;
993     }
994
995     len = strlen(secbuf);
996     if (len > MAXSECRETLEN) {
997         syslog(LOG_ERR, "Secret for %s on %s is too long", client, server);
998         len = MAXSECRETLEN;
999     }
1000     BCOPY(secbuf, secret, len);
1001     *secret_len = len;
1002
1003     return 1;
1004 }
1005
1006 /*
1007  * auth_ip_addr - check whether the peer is authorized to use
1008  * a given IP address.  Returns 1 if authorized, 0 otherwise.
1009  */
1010 int
1011 auth_ip_addr(unit, addr)
1012     int unit;
1013     u_int32_t addr;
1014 {
1015     return ip_addr_check(addr, addresses[unit]);
1016 }
1017
1018 static int
1019 ip_addr_check(addr, addrs)
1020     u_int32_t addr;
1021     struct wordlist *addrs;
1022 {
1023     u_int32_t a, mask, ah;
1024     int accept;
1025     char *ptr_word, *ptr_mask;
1026     struct hostent *hp;
1027     struct netent *np;
1028
1029     /* don't allow loopback or multicast address */
1030     if (bad_ip_adrs(addr))
1031         return 0;
1032
1033     if (addrs == NULL)
1034         return 1;               /* no restriction */
1035
1036     for (; addrs != NULL; addrs = addrs->next) {
1037         /* "-" means no addresses authorized */
1038         ptr_word = addrs->word;
1039         if (strcmp(ptr_word, "-") == 0)
1040             break;
1041
1042         accept = 1;
1043         if (*ptr_word == '!') {
1044             accept = 0;
1045             ++ptr_word;
1046         }
1047
1048         mask = ~ (u_int32_t) 0;
1049         ptr_mask = strchr (ptr_word, '/');
1050         if (ptr_mask != NULL) {
1051             int bit_count;
1052
1053             bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10);
1054             if (bit_count <= 0 || bit_count > 32) {
1055                 syslog (LOG_WARNING,
1056                         "invalid address length %s in auth. address list",
1057                         ptr_mask);
1058                 continue;
1059             }
1060             *ptr_mask = '\0';
1061             mask <<= 32 - bit_count;
1062         }
1063
1064         hp = gethostbyname(ptr_word);
1065         if (hp != NULL && hp->h_addrtype == AF_INET) {
1066             a    = *(u_int32_t *)hp->h_addr;
1067             mask = ~ (u_int32_t) 0;     /* are we sure we want this? */
1068         } else {
1069             np = getnetbyname (ptr_word);
1070             if (np != NULL && np->n_addrtype == AF_INET)
1071                 a = htonl (*(u_int32_t *)np->n_net);
1072             else
1073                 a = inet_addr (ptr_word);
1074             if (ptr_mask == NULL) {
1075                 /* calculate appropriate mask for net */
1076                 ah = ntohl(a);
1077                 if (IN_CLASSA(ah))
1078                     mask = IN_CLASSA_NET;
1079                 else if (IN_CLASSB(ah))
1080                     mask = IN_CLASSB_NET;
1081                 else if (IN_CLASSC(ah))
1082                     mask = IN_CLASSC_NET;
1083             }
1084         }
1085
1086         if (ptr_mask != NULL)
1087             *ptr_mask = '/';
1088
1089         if (a == -1L)
1090             syslog (LOG_WARNING,
1091                     "unknown host %s in auth. address list",
1092                     addrs->word);
1093         else
1094             if (((addr ^ a) & htonl(mask)) == 0)
1095                 return accept;
1096     }
1097     return 0;                   /* not in list => can't have it */
1098 }
1099
1100 /*
1101  * bad_ip_adrs - return 1 if the IP address is one we don't want
1102  * to use, such as an address in the loopback net or a multicast address.
1103  * addr is in network byte order.
1104  */
1105 int
1106 bad_ip_adrs(addr)
1107     u_int32_t addr;
1108 {
1109     addr = ntohl(addr);
1110     return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
1111         || IN_MULTICAST(addr) || IN_BADCLASS(addr);
1112 }
1113
1114 /*
1115  * check_access - complain if a secret file has too-liberal permissions.
1116  */
1117 void
1118 check_access(f, filename)
1119     FILE *f;
1120     char *filename;
1121 {
1122     struct stat sbuf;
1123
1124     if (fstat(fileno(f), &sbuf) < 0) {
1125         syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename);
1126     } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
1127         syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename);
1128     }
1129 }
1130
1131
1132 /*
1133  * scan_authfile - Scan an authorization file for a secret suitable
1134  * for authenticating `client' on `server'.  The return value is -1
1135  * if no secret is found, otherwise >= 0.  The return value has
1136  * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
1137  * NONWILD_SERVER set if the secret didn't have "*" for the server.
1138  * Any following words on the line (i.e. address authorization
1139  * info) are placed in a wordlist and returned in *addrs.  
1140  */
1141 static int
1142 scan_authfile(f, client, server, ipaddr, secret, addrs, filename)
1143     FILE *f;
1144     char *client;
1145     char *server;
1146     u_int32_t ipaddr;
1147     char *secret;
1148     struct wordlist **addrs;
1149     char *filename;
1150 {
1151     int newline, xxx;
1152     int got_flag, best_flag;
1153     FILE *sf;
1154     struct wordlist *ap, *addr_list, *alist, *alast;
1155     char word[MAXWORDLEN];
1156     char atfile[MAXWORDLEN];
1157     char lsecret[MAXWORDLEN];
1158
1159     if (addrs != NULL)
1160         *addrs = NULL;
1161     addr_list = NULL;
1162     if (!getword(f, word, &newline, filename))
1163         return -1;              /* file is empty??? */
1164     newline = 1;
1165     best_flag = -1;
1166     for (;;) {
1167         /*
1168          * Skip until we find a word at the start of a line.
1169          */
1170         while (!newline && getword(f, word, &newline, filename))
1171             ;
1172         if (!newline)
1173             break;              /* got to end of file */
1174
1175         /*
1176          * Got a client - check if it's a match or a wildcard.
1177          */
1178         got_flag = 0;
1179         if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
1180             newline = 0;
1181             continue;
1182         }
1183         if (!ISWILD(word))
1184             got_flag = NONWILD_CLIENT;
1185
1186         /*
1187          * Now get a server and check if it matches.
1188          */
1189         if (!getword(f, word, &newline, filename))
1190             break;
1191         if (newline)
1192             continue;
1193         if (server != NULL && strcmp(word, server) != 0 && !ISWILD(word))
1194             continue;
1195         if (!ISWILD(word))
1196             got_flag |= NONWILD_SERVER;
1197
1198         /*
1199          * Got some sort of a match - see if it's better than what
1200          * we have already.
1201          */
1202         if (got_flag <= best_flag)
1203             continue;
1204
1205         /*
1206          * Get the secret.
1207          */
1208         if (!getword(f, word, &newline, filename))
1209             break;
1210         if (newline)
1211             continue;
1212
1213         /*
1214          * Special syntax: @filename means read secret from file.
1215          */
1216         if (word[0] == '@') {
1217             strcpy(atfile, word+1);
1218             if ((sf = fopen(atfile, "r")) == NULL) {
1219                 syslog(LOG_WARNING, "can't open indirect secret file %s",
1220                        atfile);
1221                 continue;
1222             }
1223             check_access(sf, atfile);
1224             if (!getword(sf, word, &xxx, atfile)) {
1225                 syslog(LOG_WARNING, "no secret in indirect secret file %s",
1226                        atfile);
1227                 fclose(sf);
1228                 continue;
1229             }
1230             fclose(sf);
1231         }
1232         if (secret != NULL)
1233             strcpy(lsecret, word);
1234
1235         /*
1236          * Now read address authorization info and make a wordlist.
1237          */
1238         alist = alast = NULL;
1239         for (;;) {
1240             if (!getword(f, word, &newline, filename) || newline)
1241                 break;
1242             ap = (struct wordlist *) malloc(sizeof(struct wordlist)
1243                                             + strlen(word));
1244             if (ap == NULL)
1245                 novm("authorized addresses");
1246             ap->next = NULL;
1247             strcpy(ap->word, word);
1248             if (alist == NULL)
1249                 alist = ap;
1250             else
1251                 alast->next = ap;
1252             alast = ap;
1253         }
1254
1255         /*
1256          * Check if the given IP address is allowed by the wordlist.
1257          */
1258         if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) {
1259             free_wordlist(alist);
1260             continue;
1261         }
1262
1263         /*
1264          * This is the best so far; remember it.
1265          */
1266         best_flag = got_flag;
1267         if (addr_list)
1268             free_wordlist(addr_list);
1269         addr_list = alist;
1270         if (secret != NULL)
1271             strcpy(secret, lsecret);
1272
1273         if (!newline)
1274             break;
1275     }
1276
1277     if (addrs != NULL)
1278         *addrs = addr_list;
1279     else if (addr_list != NULL)
1280         free_wordlist(addr_list);
1281
1282     return best_flag;
1283 }
1284
1285 /*
1286  * free_wordlist - release memory allocated for a wordlist.
1287  */
1288 static void
1289 free_wordlist(wp)
1290     struct wordlist *wp;
1291 {
1292     struct wordlist *next;
1293
1294     while (wp != NULL) {
1295         next = wp->next;
1296         free(wp);
1297         wp = next;
1298     }
1299 }
1300
1301 /*
1302  * auth_script - execute a script with arguments
1303  * interface-name peer-name real-user tty speed
1304  */
1305 static void
1306 auth_script(script)
1307     char *script;
1308 {
1309     char strspeed[32];
1310     struct passwd *pw;
1311     char struid[32];
1312     char *user_name;
1313     char *argv[8];
1314
1315     if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL)
1316         user_name = pw->pw_name;
1317     else {
1318         sprintf(struid, "%d", getuid());
1319         user_name = struid;
1320     }
1321     sprintf(strspeed, "%d", baud_rate);
1322
1323     argv[0] = script;
1324     argv[1] = ifname;
1325     argv[2] = peer_authname;
1326     argv[3] = user_name;
1327     argv[4] = devnam;
1328     argv[5] = strspeed;
1329     argv[6] = NULL;
1330
1331     run_program(script, argv, 0);
1332 }