xref: /freebsd/usr.sbin/ppp/auth.c (revision 92b095588304eafcb4ba45699fe8afec726b5969)
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  *
2092b09558SBrian Somers  * $Id: auth.c,v 1.31 1998/07/19 21:07:24 brian Exp $
21af57ed9fSAtsushi Murai  *
22af57ed9fSAtsushi Murai  *	TODO:
23c3899f8dSAtsushi Murai  *		o Implement check against with registered IP addresses.
24af57ed9fSAtsushi Murai  */
252764b86aSBrian Somers #include <sys/types.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"
43af57ed9fSAtsushi Murai #include "ipcp.h"
4453c9f6c0SAtsushi Murai #include "auth.h"
4575240ed1SBrian Somers #include "systems.h"
466140ba11SBrian Somers #include "lcp.h"
47879ed6faSBrian Somers #include "lqr.h"
486140ba11SBrian Somers #include "hdlc.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"
565828db6dSBrian Somers #include "bundle.h"
57af57ed9fSAtsushi Murai 
58455aabc3SBrian Somers const char *
59455aabc3SBrian Somers Auth2Nam(u_short auth)
60ed6a16c1SPoul-Henning Kamp {
61455aabc3SBrian Somers   switch (auth) {
62455aabc3SBrian Somers   case PROTO_PAP:
63455aabc3SBrian Somers     return "PAP";
64455aabc3SBrian Somers   case PROTO_CHAP:
65455aabc3SBrian Somers     return "CHAP";
66455aabc3SBrian Somers   case 0:
67455aabc3SBrian Somers     return "none";
68d025849cSBrian Somers   }
69455aabc3SBrian Somers   return "unknown";
7053c9f6c0SAtsushi Murai }
7153c9f6c0SAtsushi Murai 
72d5015272SBrian Somers static int
73d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key)
74d5015272SBrian Somers {
75d5015272SBrian Somers   if (!strcmp(data, "*")) {
76d5015272SBrian Somers     /* Then look up the real password database */
77d5015272SBrian Somers     struct passwd *pw;
78d5015272SBrian Somers     int result;
79d5015272SBrian Somers 
80d5015272SBrian Somers     result = (pw = getpwnam(name)) &&
81d5015272SBrian Somers              !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
82d5015272SBrian Somers     endpwent();
83d5015272SBrian Somers     return result;
84d5015272SBrian Somers   }
85d5015272SBrian Somers 
86d5015272SBrian Somers   return !strcmp(data, key);
87d5015272SBrian Somers }
88d5015272SBrian Somers 
891ae349f5Scvs2svn int
9092b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen)
9192b09558SBrian Somers {
9292b09558SBrian Somers   FILE *fp;
9392b09558SBrian Somers   int n;
9492b09558SBrian Somers   char *vector[6];
9592b09558SBrian Somers   char buff[LINE_LEN];
9692b09558SBrian Somers 
9792b09558SBrian Somers   fp = OpenSecret(SECRETFILE);
9892b09558SBrian Somers   if (fp != NULL) {
9992b09558SBrian Somers     while (fgets(buff, sizeof buff, fp)) {
10092b09558SBrian Somers       if (buff[0] == '#')
10192b09558SBrian Somers         continue;
10292b09558SBrian Somers       buff[strlen(buff) - 1] = '\0';
10392b09558SBrian Somers       memset(vector, '\0', sizeof vector);
10492b09558SBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
10592b09558SBrian Somers       if (n < 5)
10692b09558SBrian Somers         continue;
10792b09558SBrian Somers       if (strcmp(vector[0], name) == 0) {
10892b09558SBrian Somers 	CloseSecret(fp);
10992b09558SBrian Somers 	if (*vector[4] == '\0')
11092b09558SBrian Somers           return 0;
11192b09558SBrian Somers         strncpy(phone, vector[4], phonelen - 1);
11292b09558SBrian Somers         phone[phonelen - 1] = '\0';
11392b09558SBrian Somers 	return 1;		/* Valid */
11492b09558SBrian Somers       }
11592b09558SBrian Somers     }
11692b09558SBrian Somers     CloseSecret(fp);
11792b09558SBrian Somers   }
11892b09558SBrian Somers   *phone = '\0';
11992b09558SBrian Somers   return 0;
12092b09558SBrian Somers }
12192b09558SBrian Somers 
12292b09558SBrian Somers int
12392b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name)
124944f7098SBrian Somers {
12553c9f6c0SAtsushi Murai   FILE *fp;
12653c9f6c0SAtsushi Murai   int n;
1271ae349f5Scvs2svn   char *vector[5];
12886e02934SBrian Somers   char buff[LINE_LEN];
12953c9f6c0SAtsushi Murai 
130643f4904SBrian Somers   if (*name == '\0') {
131643f4904SBrian Somers     ipcp_Setup(&bundle->ncp.ipcp);
132643f4904SBrian Somers     return 1;
133643f4904SBrian Somers   }
134643f4904SBrian Somers 
135643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
136d5015272SBrian Somers   if (fp != NULL) {
13770ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
13853c9f6c0SAtsushi Murai       if (buff[0] == '#')
13953c9f6c0SAtsushi Murai         continue;
140501f5480SBrian Somers       buff[strlen(buff) - 1] = '\0';
14170ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
142e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
1431ae349f5Scvs2svn       if (n < 2)
14453c9f6c0SAtsushi Murai         continue;
145501f5480SBrian Somers       if (strcmp(vector[0], name) == 0) {
1461ae349f5Scvs2svn 	CloseSecret(fp);
14792b09558SBrian Somers 	if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
14892b09558SBrian Somers             !ipcp_UseHisaddr(bundle, vector[2], 1))
149643f4904SBrian Somers 	  return 0;
1505828db6dSBrian Somers 	ipcp_Setup(&bundle->ncp.ipcp);
15192b09558SBrian Somers 	if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
15249052c95SBrian Somers 	  bundle_SetLabel(bundle, vector[3]);
153d5015272SBrian Somers 	return 1;		/* Valid */
15453c9f6c0SAtsushi Murai       }
155501f5480SBrian Somers     }
15653c9f6c0SAtsushi Murai     CloseSecret(fp);
157643f4904SBrian Somers   }
158643f4904SBrian Somers 
159643f4904SBrian Somers #ifndef NOPASSWDAUTH
160643f4904SBrian Somers   /* Let 'em in anyway - they must have been in the passwd file */
161643f4904SBrian Somers   ipcp_Setup(&bundle->ncp.ipcp);
162643f4904SBrian Somers   return 1;
163643f4904SBrian Somers #else
164643f4904SBrian Somers   /* Disappeared from ppp.secret ? */
165643f4904SBrian Somers   return 0;
166643f4904SBrian Somers #endif
16753c9f6c0SAtsushi Murai }
16853c9f6c0SAtsushi Murai 
169af57ed9fSAtsushi Murai int
170dd7e2610SBrian Somers auth_Validate(struct bundle *bundle, const char *system,
171643f4904SBrian Somers              const char *key, struct physical *physical)
172af57ed9fSAtsushi Murai {
173643f4904SBrian Somers   /* Used by PAP routines */
174643f4904SBrian Somers 
175af57ed9fSAtsushi Murai   FILE *fp;
176af57ed9fSAtsushi Murai   int n;
1779c97abd8SBrian Somers   char *vector[5];
17886e02934SBrian Somers   char buff[LINE_LEN];
179af57ed9fSAtsushi Murai 
180643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
181643f4904SBrian Somers   if (fp != NULL) {
18270ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
183af57ed9fSAtsushi Murai       if (buff[0] == '#')
184af57ed9fSAtsushi Murai         continue;
185af57ed9fSAtsushi Murai       buff[strlen(buff) - 1] = 0;
18670ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
187e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
188af57ed9fSAtsushi Murai       if (n < 2)
189af57ed9fSAtsushi Murai         continue;
190af57ed9fSAtsushi Murai       if (strcmp(vector[0], system) == 0) {
191af57ed9fSAtsushi Murai 	CloseSecret(fp);
192643f4904SBrian Somers         return auth_CheckPasswd(vector[0], vector[1], key);
193af57ed9fSAtsushi Murai       }
194af57ed9fSAtsushi Murai     }
195af57ed9fSAtsushi Murai     CloseSecret(fp);
196d5015272SBrian Somers   }
197d5015272SBrian Somers 
198d5015272SBrian Somers #ifndef NOPASSWDAUTH
1991342caedSBrian Somers   if (Enabled(bundle, OPT_PASSWDAUTH))
200d5015272SBrian Somers     return auth_CheckPasswd(system, "*", key);
201d5015272SBrian Somers #endif
202d5015272SBrian Somers 
203d5015272SBrian Somers   return 0;			/* Invalid */
204af57ed9fSAtsushi Murai }
205af57ed9fSAtsushi Murai 
206af57ed9fSAtsushi Murai char *
207dd7e2610SBrian Somers auth_GetSecret(struct bundle *bundle, const char *system, int len,
208643f4904SBrian Somers               struct physical *physical)
209af57ed9fSAtsushi Murai {
210d5015272SBrian Somers   /* Used by CHAP routines */
211d5015272SBrian Somers 
212af57ed9fSAtsushi Murai   FILE *fp;
213af57ed9fSAtsushi Murai   int n;
2149c97abd8SBrian Somers   char *vector[5];
215d93d3a9cSBrian Somers   char buff[LINE_LEN];
216af57ed9fSAtsushi Murai 
217643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
218af57ed9fSAtsushi Murai   if (fp == NULL)
219af57ed9fSAtsushi Murai     return (NULL);
220d5015272SBrian Somers 
22170ee81ffSBrian Somers   while (fgets(buff, sizeof buff, fp)) {
222af57ed9fSAtsushi Murai     if (buff[0] == '#')
223af57ed9fSAtsushi Murai       continue;
224af57ed9fSAtsushi Murai     buff[strlen(buff) - 1] = 0;
22570ee81ffSBrian Somers     memset(vector, '\0', sizeof vector);
226e68d210eSBrian Somers     n = MakeArgs(buff, vector, VECSIZE(vector));
227af57ed9fSAtsushi Murai     if (n < 2)
228af57ed9fSAtsushi Murai       continue;
229af57ed9fSAtsushi Murai     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
230643f4904SBrian Somers       CloseSecret(fp);
231d5015272SBrian Somers       return vector[1];
232af57ed9fSAtsushi Murai     }
233af57ed9fSAtsushi Murai   }
234af57ed9fSAtsushi Murai   CloseSecret(fp);
235af57ed9fSAtsushi Murai   return (NULL);		/* Invalid */
236af57ed9fSAtsushi Murai }
23753c9f6c0SAtsushi Murai 
23853c9f6c0SAtsushi Murai static void
239b6e82f33SBrian Somers AuthTimeout(void *vauthp)
24053c9f6c0SAtsushi Murai {
241b6e82f33SBrian Somers   struct authinfo *authp = (struct authinfo *)vauthp;
24253c9f6c0SAtsushi Murai 
243dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
24453c9f6c0SAtsushi Murai   if (--authp->retry > 0) {
245dd7e2610SBrian Somers     timer_Start(&authp->authtimer);
246e2ebb036SBrian Somers     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
24753c9f6c0SAtsushi Murai   }
24853c9f6c0SAtsushi Murai }
24953c9f6c0SAtsushi Murai 
25053c9f6c0SAtsushi Murai void
251dd7e2610SBrian Somers auth_Init(struct authinfo *authinfo)
25253c9f6c0SAtsushi Murai {
253e2ebb036SBrian Somers   memset(authinfo, '\0', sizeof(struct authinfo));
254cd9647a1SBrian Somers   authinfo->cfg.fsmretry = DEF_FSMRETRY;
255e2ebb036SBrian Somers }
25653c9f6c0SAtsushi Murai 
257e2ebb036SBrian Somers void
258dd7e2610SBrian Somers auth_StartChallenge(struct authinfo *authp, struct physical *physical,
259e2ebb036SBrian Somers                    void (*fn)(struct authinfo *, int, struct physical *))
260e2ebb036SBrian Somers {
261e2ebb036SBrian Somers   authp->ChallengeFunc = fn;
26263b73463SBrian Somers   authp->physical = physical;
263dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
264e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
2653b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
266cd9647a1SBrian Somers   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
267e2ebb036SBrian Somers   authp->authtimer.arg = (void *) authp;
26853c9f6c0SAtsushi Murai   authp->retry = 3;
26953c9f6c0SAtsushi Murai   authp->id = 1;
270e2ebb036SBrian Somers   (*authp->ChallengeFunc)(authp, authp->id, physical);
271dd7e2610SBrian Somers   timer_Start(&authp->authtimer);
27253c9f6c0SAtsushi Murai }
27353c9f6c0SAtsushi Murai 
27453c9f6c0SAtsushi Murai void
275dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp)
27653c9f6c0SAtsushi Murai {
277dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
27863b73463SBrian Somers   authp->physical = NULL;
27953c9f6c0SAtsushi Murai }
280