xref: /freebsd/usr.sbin/ppp/auth.c (revision 972a1bcf5db5ee4c5520a1d29d3c81e81bdec84f)
1af57ed9fSAtsushi Murai /*
2af57ed9fSAtsushi Murai  *			PPP Secret Key Module
3af57ed9fSAtsushi Murai  *
4af57ed9fSAtsushi Murai  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5af57ed9fSAtsushi Murai  *
6af57ed9fSAtsushi Murai  *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
7af57ed9fSAtsushi Murai  *
8af57ed9fSAtsushi Murai  * Redistribution and use in source and binary forms are permitted
9af57ed9fSAtsushi Murai  * provided that the above copyright notice and this paragraph are
10af57ed9fSAtsushi Murai  * duplicated in all such forms and that any documentation,
11af57ed9fSAtsushi Murai  * advertising materials, and other materials related to such
12af57ed9fSAtsushi Murai  * distribution and use acknowledge that the software was developed
13af57ed9fSAtsushi Murai  * by the Internet Initiative Japan, Inc.  The name of the
14af57ed9fSAtsushi Murai  * IIJ may not be used to endorse or promote products derived
15af57ed9fSAtsushi Murai  * from this software without specific prior written permission.
16af57ed9fSAtsushi Murai  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17af57ed9fSAtsushi Murai  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18af57ed9fSAtsushi Murai  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19af57ed9fSAtsushi Murai  *
20972a1bcfSBrian Somers  * $Id: auth.c,v 1.34 1998/12/17 00:28:12 brian Exp $
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  *	TODO:
23c3899f8dSAtsushi Murai  *		o Implement check against with registered IP addresses.
24af57ed9fSAtsushi Murai  */
25972a1bcfSBrian Somers #include <sys/param.h>
2675240ed1SBrian Somers #include <netinet/in.h>
27eaa4df37SBrian Somers #include <netinet/in_systm.h>
28eaa4df37SBrian Somers #include <netinet/ip.h>
291fa665f5SBrian Somers #include <sys/un.h>
3075240ed1SBrian Somers 
31d5015272SBrian Somers #include <pwd.h>
3275240ed1SBrian Somers #include <stdio.h>
3375240ed1SBrian Somers #include <string.h>
3475240ed1SBrian Somers #include <unistd.h>
3575240ed1SBrian Somers 
3675240ed1SBrian Somers #include "mbuf.h"
3775240ed1SBrian Somers #include "defs.h"
3875240ed1SBrian Somers #include "timer.h"
39af57ed9fSAtsushi Murai #include "fsm.h"
4029e275ceSBrian Somers #include "iplist.h"
4129e275ceSBrian Somers #include "throughput.h"
42eaa4df37SBrian Somers #include "slcompress.h"
435a72b6edSBrian Somers #include "lqr.h"
445a72b6edSBrian Somers #include "hdlc.h"
45af57ed9fSAtsushi Murai #include "ipcp.h"
4653c9f6c0SAtsushi Murai #include "auth.h"
4775240ed1SBrian Somers #include "systems.h"
486140ba11SBrian Somers #include "lcp.h"
493b0f8d2eSBrian Somers #include "ccp.h"
506140ba11SBrian Somers #include "link.h"
5142d4d396SBrian Somers #include "descriptor.h"
52b6dec9f0SBrian Somers #include "chat.h"
53455aabc3SBrian Somers #include "lcpproto.h"
545ca5389aSBrian Somers #include "filter.h"
553b0f8d2eSBrian Somers #include "mp.h"
56972a1bcfSBrian Somers #ifndef NORADIUS
57972a1bcfSBrian Somers #include "radius.h"
58972a1bcfSBrian Somers #endif
595828db6dSBrian Somers #include "bundle.h"
60af57ed9fSAtsushi Murai 
61455aabc3SBrian Somers const char *
62455aabc3SBrian Somers Auth2Nam(u_short auth)
63ed6a16c1SPoul-Henning Kamp {
64455aabc3SBrian Somers   switch (auth) {
65455aabc3SBrian Somers   case PROTO_PAP:
66455aabc3SBrian Somers     return "PAP";
67455aabc3SBrian Somers   case PROTO_CHAP:
68455aabc3SBrian Somers     return "CHAP";
69455aabc3SBrian Somers   case 0:
70455aabc3SBrian Somers     return "none";
71d025849cSBrian Somers   }
72455aabc3SBrian Somers   return "unknown";
7353c9f6c0SAtsushi Murai }
7453c9f6c0SAtsushi Murai 
75d5015272SBrian Somers static int
76d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key)
77d5015272SBrian Somers {
78d5015272SBrian Somers   if (!strcmp(data, "*")) {
79d5015272SBrian Somers     /* Then look up the real password database */
80d5015272SBrian Somers     struct passwd *pw;
81d5015272SBrian Somers     int result;
82d5015272SBrian Somers 
83d5015272SBrian Somers     result = (pw = getpwnam(name)) &&
84d5015272SBrian Somers              !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
85d5015272SBrian Somers     endpwent();
86d5015272SBrian Somers     return result;
87d5015272SBrian Somers   }
88d5015272SBrian Somers 
89d5015272SBrian Somers   return !strcmp(data, key);
90d5015272SBrian Somers }
91d5015272SBrian Somers 
921ae349f5Scvs2svn int
9392b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen)
9492b09558SBrian Somers {
9592b09558SBrian Somers   FILE *fp;
9692b09558SBrian Somers   int n;
9792b09558SBrian Somers   char *vector[6];
9892b09558SBrian Somers   char buff[LINE_LEN];
9992b09558SBrian Somers 
10092b09558SBrian Somers   fp = OpenSecret(SECRETFILE);
10192b09558SBrian Somers   if (fp != NULL) {
10292b09558SBrian Somers     while (fgets(buff, sizeof buff, fp)) {
10392b09558SBrian Somers       if (buff[0] == '#')
10492b09558SBrian Somers         continue;
10592b09558SBrian Somers       buff[strlen(buff) - 1] = '\0';
10692b09558SBrian Somers       memset(vector, '\0', sizeof vector);
10792b09558SBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
10892b09558SBrian Somers       if (n < 5)
10992b09558SBrian Somers         continue;
11092b09558SBrian Somers       if (strcmp(vector[0], name) == 0) {
11192b09558SBrian Somers         CloseSecret(fp);
11292b09558SBrian Somers         if (*vector[4] == '\0')
11392b09558SBrian Somers           return 0;
11492b09558SBrian Somers         strncpy(phone, vector[4], phonelen - 1);
11592b09558SBrian Somers         phone[phonelen - 1] = '\0';
11692b09558SBrian Somers         return 1;		/* Valid */
11792b09558SBrian Somers       }
11892b09558SBrian Somers     }
11992b09558SBrian Somers     CloseSecret(fp);
12092b09558SBrian Somers   }
12192b09558SBrian Somers   *phone = '\0';
12292b09558SBrian Somers   return 0;
12392b09558SBrian Somers }
12492b09558SBrian Somers 
12592b09558SBrian Somers int
12692b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name)
127944f7098SBrian Somers {
12853c9f6c0SAtsushi Murai   FILE *fp;
12953c9f6c0SAtsushi Murai   int n;
1301ae349f5Scvs2svn   char *vector[5];
13186e02934SBrian Somers   char buff[LINE_LEN];
13253c9f6c0SAtsushi Murai 
133643f4904SBrian Somers   if (*name == '\0') {
134972a1bcfSBrian Somers     ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
135643f4904SBrian Somers     return 1;
136643f4904SBrian Somers   }
137643f4904SBrian Somers 
138972a1bcfSBrian Somers #ifndef NORADIUS
139972a1bcfSBrian Somers   if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE) {
140972a1bcfSBrian Somers     /* We've got a radius IP - it overrides everything */
141972a1bcfSBrian Somers     if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip))
142972a1bcfSBrian Somers       return 0;
143972a1bcfSBrian Somers     ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr);
144972a1bcfSBrian Somers     /* Continue with ppp.secret in case we've got a new label */
145972a1bcfSBrian Somers   }
146972a1bcfSBrian Somers #endif
147972a1bcfSBrian Somers 
148643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
149d5015272SBrian Somers   if (fp != NULL) {
15070ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
15153c9f6c0SAtsushi Murai       if (buff[0] == '#')
15253c9f6c0SAtsushi Murai         continue;
153501f5480SBrian Somers       buff[strlen(buff) - 1] = '\0';
15470ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
155e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
1561ae349f5Scvs2svn       if (n < 2)
15753c9f6c0SAtsushi Murai         continue;
158501f5480SBrian Somers       if (strcmp(vector[0], name) == 0) {
1591ae349f5Scvs2svn         CloseSecret(fp);
160972a1bcfSBrian Somers #ifndef NORADIUS
161972a1bcfSBrian Somers         if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) {
162972a1bcfSBrian Somers #endif
16392b09558SBrian Somers           if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
16492b09558SBrian Somers               !ipcp_UseHisaddr(bundle, vector[2], 1))
165643f4904SBrian Somers             return 0;
166972a1bcfSBrian Somers           ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
167972a1bcfSBrian Somers #ifndef NORADIUS
168972a1bcfSBrian Somers         }
169972a1bcfSBrian Somers #endif
17092b09558SBrian Somers         if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
17149052c95SBrian Somers           bundle_SetLabel(bundle, vector[3]);
172d5015272SBrian Somers         return 1;		/* Valid */
17353c9f6c0SAtsushi Murai       }
174501f5480SBrian Somers     }
17553c9f6c0SAtsushi Murai     CloseSecret(fp);
176643f4904SBrian Somers   }
177643f4904SBrian Somers 
178643f4904SBrian Somers #ifndef NOPASSWDAUTH
179643f4904SBrian Somers   /* Let 'em in anyway - they must have been in the passwd file */
180972a1bcfSBrian Somers   ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE);
181643f4904SBrian Somers   return 1;
182643f4904SBrian Somers #else
183972a1bcfSBrian Somers #ifndef NORADIUS
184972a1bcfSBrian Somers   if (bundle->radius.valid)
185972a1bcfSBrian Somers     return 1;
186972a1bcfSBrian Somers #endif
187972a1bcfSBrian Somers 
188972a1bcfSBrian Somers   /* Disappeared from ppp.secret ??? */
189643f4904SBrian Somers   return 0;
190643f4904SBrian Somers #endif
19153c9f6c0SAtsushi Murai }
19253c9f6c0SAtsushi Murai 
193af57ed9fSAtsushi Murai int
194972a1bcfSBrian Somers auth_Validate(struct bundle *bundle, const char *name,
195643f4904SBrian Somers              const char *key, struct physical *physical)
196af57ed9fSAtsushi Murai {
197643f4904SBrian Somers   /* Used by PAP routines */
198643f4904SBrian Somers 
199af57ed9fSAtsushi Murai   FILE *fp;
200af57ed9fSAtsushi Murai   int n;
2019c97abd8SBrian Somers   char *vector[5];
20286e02934SBrian Somers   char buff[LINE_LEN];
203af57ed9fSAtsushi Murai 
204972a1bcfSBrian Somers #ifndef NORADIUS
205972a1bcfSBrian Somers   if (*bundle->radius.cfg.file)
206972a1bcfSBrian Somers     return radius_Authenticate(&bundle->radius, bundle, name, key, NULL);
207972a1bcfSBrian Somers #endif
208972a1bcfSBrian Somers 
209643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
210643f4904SBrian Somers   if (fp != NULL) {
21170ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
212af57ed9fSAtsushi Murai       if (buff[0] == '#')
213af57ed9fSAtsushi Murai         continue;
214af57ed9fSAtsushi Murai       buff[strlen(buff) - 1] = 0;
21570ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
216e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
217af57ed9fSAtsushi Murai       if (n < 2)
218af57ed9fSAtsushi Murai         continue;
219972a1bcfSBrian Somers       if (strcmp(vector[0], name) == 0) {
220af57ed9fSAtsushi Murai         CloseSecret(fp);
221972a1bcfSBrian Somers         return auth_CheckPasswd(name, vector[1], key);
222af57ed9fSAtsushi Murai       }
223af57ed9fSAtsushi Murai     }
224af57ed9fSAtsushi Murai     CloseSecret(fp);
225d5015272SBrian Somers   }
226d5015272SBrian Somers 
227d5015272SBrian Somers #ifndef NOPASSWDAUTH
2281342caedSBrian Somers   if (Enabled(bundle, OPT_PASSWDAUTH))
229972a1bcfSBrian Somers     return auth_CheckPasswd(name, "*", key);
230d5015272SBrian Somers #endif
231d5015272SBrian Somers 
232d5015272SBrian Somers   return 0;			/* Invalid */
233af57ed9fSAtsushi Murai }
234af57ed9fSAtsushi Murai 
235af57ed9fSAtsushi Murai char *
236972a1bcfSBrian Somers auth_GetSecret(struct bundle *bundle, const char *name, int len,
237643f4904SBrian Somers               struct physical *physical)
238af57ed9fSAtsushi Murai {
239d5015272SBrian Somers   /* Used by CHAP routines */
240d5015272SBrian Somers 
241af57ed9fSAtsushi Murai   FILE *fp;
242af57ed9fSAtsushi Murai   int n;
2439c97abd8SBrian Somers   char *vector[5];
2442ff64793SBrian Somers   static char buff[LINE_LEN];
245af57ed9fSAtsushi Murai 
246643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
247af57ed9fSAtsushi Murai   if (fp == NULL)
248af57ed9fSAtsushi Murai     return (NULL);
249d5015272SBrian Somers 
25070ee81ffSBrian Somers   while (fgets(buff, sizeof buff, fp)) {
251af57ed9fSAtsushi Murai     if (buff[0] == '#')
252af57ed9fSAtsushi Murai       continue;
253af57ed9fSAtsushi Murai     buff[strlen(buff) - 1] = 0;
25470ee81ffSBrian Somers     memset(vector, '\0', sizeof vector);
255e68d210eSBrian Somers     n = MakeArgs(buff, vector, VECSIZE(vector));
256af57ed9fSAtsushi Murai     if (n < 2)
257af57ed9fSAtsushi Murai       continue;
258972a1bcfSBrian Somers     if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) {
259643f4904SBrian Somers       CloseSecret(fp);
260d5015272SBrian Somers       return vector[1];
261af57ed9fSAtsushi Murai     }
262af57ed9fSAtsushi Murai   }
263af57ed9fSAtsushi Murai   CloseSecret(fp);
264af57ed9fSAtsushi Murai   return (NULL);		/* Invalid */
265af57ed9fSAtsushi Murai }
26653c9f6c0SAtsushi Murai 
26753c9f6c0SAtsushi Murai static void
268b6e82f33SBrian Somers AuthTimeout(void *vauthp)
26953c9f6c0SAtsushi Murai {
270b6e82f33SBrian Somers   struct authinfo *authp = (struct authinfo *)vauthp;
27153c9f6c0SAtsushi Murai 
272dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
27353c9f6c0SAtsushi Murai   if (--authp->retry > 0) {
274dd7e2610SBrian Somers     timer_Start(&authp->authtimer);
275e2ebb036SBrian Somers     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
27653c9f6c0SAtsushi Murai   }
27753c9f6c0SAtsushi Murai }
27853c9f6c0SAtsushi Murai 
27953c9f6c0SAtsushi Murai void
280dd7e2610SBrian Somers auth_Init(struct authinfo *authinfo)
28153c9f6c0SAtsushi Murai {
282e2ebb036SBrian Somers   memset(authinfo, '\0', sizeof(struct authinfo));
283cd9647a1SBrian Somers   authinfo->cfg.fsmretry = DEF_FSMRETRY;
284e2ebb036SBrian Somers }
28553c9f6c0SAtsushi Murai 
286e2ebb036SBrian Somers void
287dd7e2610SBrian Somers auth_StartChallenge(struct authinfo *authp, struct physical *physical,
288e2ebb036SBrian Somers                    void (*fn)(struct authinfo *, int, struct physical *))
289e2ebb036SBrian Somers {
290e2ebb036SBrian Somers   authp->ChallengeFunc = fn;
29163b73463SBrian Somers   authp->physical = physical;
292dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
293e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
2943b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
295cd9647a1SBrian Somers   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
296e2ebb036SBrian Somers   authp->authtimer.arg = (void *) authp;
29753c9f6c0SAtsushi Murai   authp->retry = 3;
29853c9f6c0SAtsushi Murai   authp->id = 1;
299e2ebb036SBrian Somers   (*authp->ChallengeFunc)(authp, authp->id, physical);
300dd7e2610SBrian Somers   timer_Start(&authp->authtimer);
30153c9f6c0SAtsushi Murai }
30253c9f6c0SAtsushi Murai 
30353c9f6c0SAtsushi Murai void
304dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp)
30553c9f6c0SAtsushi Murai {
306dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
30763b73463SBrian Somers   authp->physical = NULL;
30853c9f6c0SAtsushi Murai }
309