]> git.ozlabs.org Git - ppp.git/blob - pppd/auth.c
cdeb2b6b7874daa292c32b23082f89c4134eae93
[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.1 1993/11/11 03:54:25 paulus Exp $";
37 #endif
38
39 #include <stdio.h>
40 #include <stddef.h>
41 #include <syslog.h>
42 #include <pwd.h>
43 #include <string.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46
47 #include <netdb.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50
51 #include "ppp.h"
52 #include "pppd.h"
53 #include "fsm.h"
54 #include "lcp.h"
55 #include "upap.h"
56 #include "chap.h"
57 #include "ipcp.h"
58 #include "pathnames.h"
59
60 #ifdef sparc
61 #include <alloca.h>
62 #ifndef __GNUC__
63 /* why alloca.h doesn't define what alloca() returns is a mystery */
64 char *alloca __ARGS((int));
65 #endif /*__GNUC__*/
66 #endif /*sparc*/
67
68 /* Used for storing a sequence of words.  Usually malloced. */
69 struct wordlist {
70     struct wordlist     *next;
71     char                word[1];
72 };
73
74 /* Bits in scan_authfile return value */
75 #define NONWILD_SERVER  1
76 #define NONWILD_CLIENT  2
77
78 #define ISWILD(word)    (word[0] == '*' && word[1] == 0)
79
80 #define FALSE   0
81 #define TRUE    1
82
83 extern char user[];
84 extern char passwd[];
85 extern char devname[];
86 extern char our_name[];
87 extern char remote_name[];
88 extern char hostname[];
89 extern int uselogin;
90 extern int usehostname;
91 extern int auth_required;
92
93 /* Records which authentication operations haven't completed yet. */
94 static int auth_pending[NPPP];
95 static int logged_in;
96 static struct wordlist *addresses[NPPP];
97
98 /* Bits in auth_pending[] */
99 #define UPAP_WITHPEER   1
100 #define UPAP_PEER       2
101 #define CHAP_WITHPEER   4
102 #define CHAP_PEER       8
103
104 /* Prototypes */
105 void check_access __ARGS((FILE *, char *));
106
107 static int  login __ARGS((char *, char *, char **, int *));
108 static void logout __ARGS((void));
109 static int  get_upap_passwd __ARGS((void));
110 static int  have_upap_secret __ARGS((void));
111 static int  have_chap_secret __ARGS((char *, char *));
112 static int  scan_authfile __ARGS((FILE *, char *, char *, char *,
113                                   struct wordlist **, char *));
114 static void free_wordlist __ARGS((struct wordlist *));
115
116 extern char *crypt __ARGS((char *, char *));
117
118 /*
119  * An Open on LCP has requested a change from Dead to Establish phase.
120  * Do what's necessary to bring the physical layer up.
121  */
122 void
123 link_required(unit)
124     int unit;
125 {
126 }
127
128 /*
129  * LCP has terminated the link; go to the Dead phase and take the
130  * physical layer down.
131  */
132 void
133 link_terminated(unit)
134     int unit;
135 {
136     if (logged_in)
137         logout();
138     if (lcp_wantoptions[unit].restart) {
139         lcp_lowerdown(unit);
140         lcp_lowerup(unit);
141     } else
142         EXIT(unit);
143 }
144
145 /*
146  * The link is established.
147  * Proceed to the Dead, Authenticate or Network phase as appropriate.
148  */
149 void
150 link_established(unit)
151     int unit;
152 {
153     int auth;
154     lcp_options *wo = &lcp_wantoptions[unit];
155     lcp_options *go = &lcp_gotoptions[unit];
156     lcp_options *ho = &lcp_hisoptions[unit];
157
158     if (auth_required && !(go->neg_chap || go->neg_upap)) {
159         /*
160          * We wanted the peer to authenticate himself, and he refused:
161          * tell him to go away.
162          */
163         syslog(LOG_WARNING, "peer refused to authenticate");
164         lcp_close(unit);
165         return;
166     }
167
168     auth = 0;
169     if (go->neg_chap) {
170         ChapAuthPeer(unit, our_name, go->chap_mdtype);
171         auth |= CHAP_PEER;
172     } else if (go->neg_upap) {
173         upap_authpeer(unit);
174         auth |= UPAP_PEER;
175     }
176     if (ho->neg_chap) {
177         ChapAuthWithPeer(unit, our_name, ho->chap_mdtype);
178         auth |= CHAP_WITHPEER;
179     } else if (ho->neg_upap) {
180         upap_authwithpeer(unit, user, passwd);
181         auth |= UPAP_WITHPEER;
182     }
183     auth_pending[unit] = auth;
184
185     if (!auth)
186         ipcp_open(unit);
187 }
188
189 /*
190  * The peer has failed to authenticate himself using `protocol'.
191  */
192 void
193 auth_peer_fail(unit, protocol)
194     int unit, protocol;
195 {
196     /*
197      * Authentication failure: take the link down
198      */
199     lcp_close(unit);
200 }
201
202 /*
203  * The peer has been successfully authenticated using `protocol'.
204  */
205 void
206 auth_peer_success(unit, protocol)
207     int unit, protocol;
208 {
209     int bit;
210
211     switch (protocol) {
212     case CHAP:
213         bit = CHAP_PEER;
214         break;
215     case UPAP:
216         bit = UPAP_PEER;
217         break;
218     default:
219         syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
220                protocol);
221         return;
222     }
223
224     /*
225      * If there is no more authentication still to be done,
226      * proceed to the network phase.
227      */
228     if ((auth_pending[unit] &= ~bit) == 0)
229         ipcp_open(unit);
230 }
231
232 /*
233  * We have failed to authenticate ourselves to the peer using `protocol'.
234  */
235 void
236 auth_withpeer_fail(unit, protocol)
237     int unit, protocol;
238 {
239     /*
240      * We've failed to authenticate ourselves to our peer.
241      * He'll probably take the link down, and there's not much
242      * we can do except wait for that.
243      */
244 }
245
246 /*
247  * We have successfully authenticated ourselves with the peer using `protocol'.
248  */
249 void
250 auth_withpeer_success(unit, protocol)
251     int unit, protocol;
252 {
253     int bit;
254
255     switch (protocol) {
256     case CHAP:
257         bit = CHAP_WITHPEER;
258         break;
259     case UPAP:
260         bit = UPAP_WITHPEER;
261         break;
262     default:
263         syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
264                protocol);
265     }
266
267     /*
268      * If there is no more authentication still being done,
269      * proceed to the network phase.
270      */
271     if ((auth_pending[unit] &= ~bit) == 0)
272         ipcp_open(unit);
273 }
274
275
276 /*
277  * check_auth_options - called to check authentication options.
278  */
279 void
280 check_auth_options()
281 {
282     lcp_options *wo = &lcp_wantoptions[0];
283     lcp_options *ao = &lcp_allowoptions[0];
284
285     /* Default our_name to hostname, and user to our_name */
286     if (our_name[0] == 0 || usehostname)
287         strcpy(our_name, hostname);
288     if (user[0] == 0)
289         strcpy(user, our_name);
290
291     /* If authentication is required, ask peer for CHAP or PAP. */
292     if (auth_required && !wo->neg_chap && !wo->neg_upap) {
293         wo->neg_chap = 1;
294         wo->neg_upap = 1;
295     }
296
297     /*
298      * Check whether we have appropriate secrets to use
299      * to authenticate ourselves and/or the peer.
300      */
301     if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd())
302         ao->neg_upap = 0;
303     if (wo->neg_upap && !uselogin && !have_upap_secret())
304         wo->neg_upap = 0;
305     if (ao->neg_chap && !have_chap_secret(our_name, remote_name))
306         ao->neg_chap = 0;
307     if (wo->neg_chap && !have_chap_secret(remote_name, our_name))
308         wo->neg_chap = 0;
309
310     if (auth_required && !wo->neg_chap && !wo->neg_upap) {
311         fprintf(stderr, "\
312 pppd: peer authentication required but no authentication files accessible\n");
313         exit(1);
314     }
315
316 }
317
318
319 /*
320  * check_passwd - Check the user name and passwd against the PAP secrets
321  * file.  If requested, also check against the system password database,
322  * and login the user if OK.
323  *
324  * returns:
325  *      UPAP_AUTHNAK: Authentication failed.
326  *      UPAP_AUTHACK: Authentication succeeded.
327  * In either case, msg points to an appropriate message.
328  */
329 int
330 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
331     int unit;
332     char *auser;
333     int userlen;
334     char *apasswd;
335     int passwdlen;
336     char **msg;
337     int *msglen;
338 {
339     int ret;
340     char *filename;
341     FILE *f;
342     struct wordlist *addrs;
343     char passwd[256], user[256];
344     char secret[MAXWORDLEN];
345     static int attempts = 0;
346
347     /*
348      * Make copies of apasswd and auser, then null-terminate them.
349      */
350     BCOPY(apasswd, passwd, passwdlen);
351     passwd[passwdlen] = '\0';
352     BCOPY(auser, user, userlen);
353     user[userlen] = '\0';
354
355     /*
356      * Open the file of upap secrets and scan for a suitable secret
357      * for authenticating this user.
358      */
359     filename = _PATH_UPAPFILE;
360     addrs = NULL;
361     ret = UPAP_AUTHACK;
362     f = fopen(filename, "r");
363     if (f == NULL) {
364         if (!uselogin) {
365             syslog(LOG_ERR, "Can't open upap password file %s: %m", filename);
366             ret = UPAP_AUTHNAK;
367         }
368
369     } else {
370         check_access(f, filename);
371         if (scan_authfile(f, user, our_name, secret, &addrs, filename) < 0
372             || (secret[0] != 0 && strcmp(passwd, secret) != 0
373                 && strcmp(crypt(passwd, secret), secret) != 0)) {
374             syslog(LOG_WARNING, "upap authentication failure for %s", user);
375             ret = UPAP_AUTHNAK;
376         }
377         fclose(f);
378     }
379
380     if (uselogin && ret == UPAP_AUTHACK) {
381         ret = login(user, passwd, msg, msglen);
382         if (ret == UPAP_AUTHNAK) {
383             syslog(LOG_WARNING, "upap login failure for %s", user);
384         }
385     }
386
387     if (ret == UPAP_AUTHNAK) {
388         *msg = "Login incorrect";
389         *msglen = strlen(*msg);
390         /*
391          * Frustrate passwd stealer programs.
392          * Allow 10 tries, but start backing off after 3 (stolen from login).
393          * On 10'th, drop the connection.
394          */
395         if (attempts++ >= 10) {
396             syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s",
397                    attempts, devname, user);
398             quit();
399         }
400         if (attempts > 3)
401             sleep((u_int) (attempts - 3) * 5);
402         if (addrs != NULL)
403             free_wordlist(addrs);
404
405     } else {
406         attempts = 0;                   /* Reset count */
407         *msg = "Login ok";
408         *msglen = strlen(*msg);
409         if (addresses[unit] != NULL)
410             free_wordlist(addresses[unit]);
411         addresses[unit] = addrs;
412     }
413
414     return ret;
415 }
416
417
418 /*
419  * login - Check the user name and password against the system
420  * password database, and login the user if OK.
421  *
422  * returns:
423  *      UPAP_AUTHNAK: Login failed.
424  *      UPAP_AUTHACK: Login succeeded.
425  * In either case, msg points to an appropriate message.
426  */
427 static int
428 login(user, passwd, msg, msglen)
429     char *user;
430     char *passwd;
431     char **msg;
432     int *msglen;
433 {
434     struct passwd *pw;
435     char *epasswd;
436     char *tty;
437
438     if ((pw = getpwnam(user)) == NULL) {
439         return (UPAP_AUTHNAK);
440     }
441
442     /*
443      * XXX If no passwd, let them login without one.
444      */
445     if (pw->pw_passwd == '\0') {
446         return (UPAP_AUTHACK);
447     }
448
449     epasswd = crypt(passwd, pw->pw_passwd);
450     if (strcmp(epasswd, pw->pw_passwd)) {
451         return (UPAP_AUTHNAK);
452     }
453
454     syslog(LOG_INFO, "user %s logged in", user);
455
456     /*
457      * Write a wtmp entry for this user.
458      */
459     tty = strrchr(devname, '/');
460     if (tty == NULL)
461         tty = devname;
462     else
463         tty++;
464     logwtmp(tty, user, "");             /* Add wtmp login entry */
465     logged_in = TRUE;
466
467     return (UPAP_AUTHACK);
468 }
469
470 /*
471  * logout - Logout the user.
472  */
473 static void
474 logout()
475 {
476     char *tty;
477
478     tty = strrchr(devname, '/');
479     if (tty == NULL)
480         tty = devname;
481     else
482         tty++;
483     logwtmp(tty, "", "");               /* Wipe out wtmp logout entry */
484     logged_in = FALSE;
485 }
486
487
488 /*
489  * get_upap_passwd - get a password for authenticating ourselves with
490  * our peer using PAP.  Returns 1 on success, 0 if no suitable password
491  * could be found.
492  */
493 static int
494 get_upap_passwd()
495 {
496     char *filename;
497     FILE *f;
498     struct wordlist *addrs;
499     char secret[MAXWORDLEN];
500
501     filename = _PATH_UPAPFILE;
502     addrs = NULL;
503     f = fopen(filename, "r");
504     if (f == NULL)
505         return 0;
506     check_access(f, filename);
507     if (scan_authfile(f, user, remote_name, secret, NULL, filename) < 0)
508         return 0;
509     strncpy(passwd, secret, MAXSECRETLEN);
510     passwd[MAXSECRETLEN-1] = 0;
511     return 1;
512 }
513
514
515 /*
516  * have_upap_secret - check whether we have a PAP file with any
517  * secrets that we could possibly use for authenticating the peer.
518  */
519 static int
520 have_upap_secret()
521 {
522     FILE *f;
523     int ret;
524     char *filename;
525
526     filename = _PATH_UPAPFILE;
527     f = fopen(filename, "r");
528     if (f == NULL)
529         return 0;
530
531     ret = scan_authfile(f, NULL, our_name, NULL, NULL, filename);
532     fclose(f);
533     if (ret < 0)
534         return 0;
535
536     return 1;
537 }
538
539
540 /*
541  * have_chap_secret - check whether we have a CHAP file with a
542  * secret that we could possibly use for authenticating `client'
543  * on `server'.  Either can be the null string, meaning we don't
544  * know the identity yet.
545  */
546 int
547 have_chap_secret(client, server)
548     char *client;
549     char *server;
550 {
551     FILE *f;
552     int ret;
553     char *filename;
554
555     filename = _PATH_CHAPFILE;
556     f = fopen(filename, "r");
557     if (f == NULL)
558         return 0;
559
560     if (client[0] == 0)
561         client = NULL;
562     else if (server[0] == 0)
563         server = NULL;
564
565     ret = scan_authfile(f, client, server, NULL, NULL, filename);
566     fclose(f);
567     if (ret < 0)
568         return 0;
569
570     return 1;
571 }
572
573
574 /*
575  * get_secret - open the CHAP secret file and return the secret
576  * for authenticating the given client on the given server.
577  * (We could be either client or server).
578  */
579 int
580 get_secret(unit, client, server, secret, secret_len, save_addrs)
581     int unit;
582     char *client;
583     char *server;
584     char *secret;
585     int *secret_len;
586 {
587     FILE *f;
588     int ret, len;
589     char *filename;
590     struct wordlist *addrs;
591     char secbuf[MAXWORDLEN];
592
593     filename = _PATH_CHAPFILE;
594     addrs = NULL;
595     secbuf[0] = 0;
596
597     f = fopen(filename, "r");
598     if (f == NULL) {
599         syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename);
600         return 0;
601     }
602     check_access(f, filename);
603
604     ret = scan_authfile(f, client, server, secbuf, &addrs, filename);
605     fclose(f);
606     if (ret < 0)
607         return 0;
608
609     if (save_addrs) {
610         if (addresses[unit] != NULL)
611             free_wordlist(addresses[unit]);
612         addresses[unit] = addrs;
613     }
614
615     len = strlen(secbuf);
616     if (len > MAXSECRETLEN) {
617         syslog(LOG_ERR, "Secret for %s on %s is too long", client, server);
618         len = MAXSECRETLEN;
619     }
620     BCOPY(secbuf, secret, len);
621     *secret_len = len;
622
623     return 1;
624 }
625
626 /*
627  * auth_ip_addr - check whether the peer is authorized to use
628  * a given IP address.  Returns 1 if authorized, 0 otherwise.
629  */
630 int
631 auth_ip_addr(unit, addr)
632     int unit;
633     u_long addr;
634 {
635     u_long a;
636     struct hostent *hp;
637     struct wordlist *addrs;
638
639     if ((addrs = addresses[unit]) == NULL)
640         return 1;               /* no restriction */
641
642     for (; addrs != NULL; addrs = addrs->next) {
643         /* "-" means no addresses authorized */
644         if (strcmp(addrs->word, "-") == 0)
645             break;
646         if ((a = inet_addr(addrs->word)) == -1) {
647             if ((hp = gethostbyname(addrs->word)) == NULL) {
648                 syslog(LOG_WARNING, "unknown host %s in auth. address list",
649                        addrs->word);
650                 continue;
651             } else
652                 a = *(u_long *)hp->h_addr;
653         }
654         if (addr == a)
655             return 1;
656     }
657     return 0;                   /* not in list => can't have it */
658 }
659
660 /*
661  * check_access - complain if a secret file has too-liberal permissions.
662  */
663 void
664 check_access(f, filename)
665     FILE *f;
666     char *filename;
667 {
668     struct stat sbuf;
669
670     if (fstat(fileno(f), &sbuf) < 0) {
671         syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename);
672     } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
673         syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename);
674     }
675 }
676
677
678 /*
679  * scan_authfile - Scan an authorization file for a secret suitable
680  * for authenticating `client' on `server'.  The return value is -1
681  * if no secret is found, otherwise >= 0.  The return value has
682  * NONWILD_CLIENT set if the secret didn't have "*" for the client, and
683  * NONWILD_SERVER set if the secret didn't have "*" for the server.
684  * Any following words on the line (i.e. address authorization
685  * info) are placed in a wordlist and returned in *addrs.  
686  */
687 static int
688 scan_authfile(f, client, server, secret, addrs, filename)
689     FILE *f;
690     char *client;
691     char *server;
692     char *secret;
693     struct wordlist **addrs;
694     char *filename;
695 {
696     int newline, xxx;
697     int got_flag, best_flag;
698     FILE *sf;
699     struct wordlist *ap, *addr_list, *addr_last;
700     char word[MAXWORDLEN];
701     char atfile[MAXWORDLEN];
702
703     if (addrs != NULL)
704         *addrs = NULL;
705     addr_list = NULL;
706     if (!getword(f, word, &newline, filename))
707         return -1;              /* file is empty??? */
708     newline = 1;
709     best_flag = -1;
710     for (;;) {
711         /*
712          * Skip until we find a word at the start of a line.
713          */
714         while (!newline && getword(f, word, &newline, filename))
715             ;
716         if (!newline)
717             break;              /* got to end of file */
718
719         /*
720          * Got a client - check if it's a match or a wildcard.
721          */
722         got_flag = 0;
723         if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
724             newline = 0;
725             continue;
726         }
727         if (!ISWILD(word))
728             got_flag = NONWILD_CLIENT;
729
730         /*
731          * Now get a server and check if it matches.
732          */
733         if (!getword(f, word, &newline, filename))
734             break;
735         if (newline)
736             continue;
737         if (server != NULL && strcmp(word, server) != 0 && !ISWILD(word))
738             continue;
739         if (!ISWILD(word))
740             got_flag |= NONWILD_SERVER;
741
742         /*
743          * Got some sort of a match - see if it's better than what
744          * we have already.
745          */
746         if (got_flag <= best_flag)
747             continue;
748
749         /*
750          * Get the secret.
751          */
752         if (!getword(f, word, &newline, filename))
753             break;
754         if (newline)
755             continue;
756
757         /*
758          * Special syntax: @filename means read secret from file.
759          */
760         if (word[0] == '@') {
761             strcpy(atfile, word+1);
762             if ((sf = fopen(atfile, "r")) == NULL) {
763                 syslog(LOG_WARNING, "can't open indirect secret file %s",
764                        atfile);
765                 continue;
766             }
767             check_access(sf, atfile);
768             if (!getword(sf, word, &xxx, atfile)) {
769                 syslog(LOG_WARNING, "no secret in indirect secret file %s",
770                        atfile);
771                 fclose(sf);
772                 continue;
773             }
774             fclose(sf);
775         }
776         if (secret != NULL)
777             strcpy(secret, word);
778                 
779         best_flag = got_flag;
780
781         /*
782          * Now read address authorization info and make a wordlist.
783          */
784         if (addr_list)
785             free_wordlist(addr_list);
786         addr_list = NULL;
787         for (;;) {
788             if (!getword(f, word, &newline, filename) || newline)
789                 break;
790             ap = (struct wordlist *) malloc(sizeof(struct wordlist)
791                                             + strlen(word));
792             if (ap == NULL)
793                 novm("authorized addresses");
794             ap->next = NULL;
795             strcpy(ap->word, word);
796             if (addr_list == NULL)
797                 addr_list = ap;
798             else
799                 addr_last->next = ap;
800             addr_last = ap;
801         }
802         if (!newline)
803             break;
804     }
805
806     if (addrs != NULL)
807         *addrs = addr_list;
808     else if (addr_list != NULL)
809         free_wordlist(addr_list);
810
811     return best_flag;
812 }
813
814 /*
815  * free_wordlist - release memory allocated for a wordlist.
816  */
817 static void
818 free_wordlist(wp)
819     struct wordlist *wp;
820 {
821     struct wordlist *next;
822
823     while (wp != NULL) {
824         next = wp->next;
825         free(wp);
826         wp = next;
827     }
828 }