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