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