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