xref: /freebsd/usr.sbin/ppp/auth.c (revision 501f54801141c5d09dabc3d2d01b81fe0a985802)
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  *
20501f5480SBrian Somers  * $Id: auth.c,v 1.30 1998/06/15 19:06:35 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
90dd7e2610SBrian Somers auth_Select(struct bundle *bundle, const char *name, struct physical *physical)
91944f7098SBrian Somers {
9253c9f6c0SAtsushi Murai   FILE *fp;
9353c9f6c0SAtsushi Murai   int n;
941ae349f5Scvs2svn   char *vector[5];
9586e02934SBrian Somers   char buff[LINE_LEN];
9653c9f6c0SAtsushi Murai 
97643f4904SBrian Somers   if (*name == '\0') {
98643f4904SBrian Somers     ipcp_Setup(&bundle->ncp.ipcp);
99643f4904SBrian Somers     return 1;
100643f4904SBrian Somers   }
101643f4904SBrian Somers 
102643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
103d5015272SBrian Somers   if (fp != NULL) {
10470ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
10553c9f6c0SAtsushi Murai       if (buff[0] == '#')
10653c9f6c0SAtsushi Murai         continue;
107501f5480SBrian Somers       buff[strlen(buff) - 1] = '\0';
10870ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
109e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
1101ae349f5Scvs2svn       if (n < 2)
11153c9f6c0SAtsushi Murai         continue;
112501f5480SBrian Somers       if (strcmp(vector[0], name) == 0) {
1131ae349f5Scvs2svn 	CloseSecret(fp);
114dd7e2610SBrian Somers 	if (n > 2 && !ipcp_UseHisaddr(bundle, vector[2], 1))
115643f4904SBrian Somers 	  return 0;
1165828db6dSBrian Somers 	ipcp_Setup(&bundle->ncp.ipcp);
1171ae349f5Scvs2svn 	if (n > 3)
11849052c95SBrian Somers 	  bundle_SetLabel(bundle, vector[3]);
119d5015272SBrian Somers 	return 1;		/* Valid */
12053c9f6c0SAtsushi Murai       }
121501f5480SBrian Somers     }
12253c9f6c0SAtsushi Murai     CloseSecret(fp);
123643f4904SBrian Somers   }
124643f4904SBrian Somers 
125643f4904SBrian Somers #ifndef NOPASSWDAUTH
126643f4904SBrian Somers   /* Let 'em in anyway - they must have been in the passwd file */
127643f4904SBrian Somers   ipcp_Setup(&bundle->ncp.ipcp);
128643f4904SBrian Somers   return 1;
129643f4904SBrian Somers #else
130643f4904SBrian Somers   /* Disappeared from ppp.secret ? */
131643f4904SBrian Somers   return 0;
132643f4904SBrian Somers #endif
13353c9f6c0SAtsushi Murai }
13453c9f6c0SAtsushi Murai 
135af57ed9fSAtsushi Murai int
136dd7e2610SBrian Somers auth_Validate(struct bundle *bundle, const char *system,
137643f4904SBrian Somers              const char *key, struct physical *physical)
138af57ed9fSAtsushi Murai {
139643f4904SBrian Somers   /* Used by PAP routines */
140643f4904SBrian Somers 
141af57ed9fSAtsushi Murai   FILE *fp;
142af57ed9fSAtsushi Murai   int n;
1439c97abd8SBrian Somers   char *vector[5];
14486e02934SBrian Somers   char buff[LINE_LEN];
145af57ed9fSAtsushi Murai 
146643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
147643f4904SBrian Somers   if (fp != NULL) {
14870ee81ffSBrian Somers     while (fgets(buff, sizeof buff, fp)) {
149af57ed9fSAtsushi Murai       if (buff[0] == '#')
150af57ed9fSAtsushi Murai         continue;
151af57ed9fSAtsushi Murai       buff[strlen(buff) - 1] = 0;
15270ee81ffSBrian Somers       memset(vector, '\0', sizeof vector);
153e68d210eSBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
154af57ed9fSAtsushi Murai       if (n < 2)
155af57ed9fSAtsushi Murai         continue;
156af57ed9fSAtsushi Murai       if (strcmp(vector[0], system) == 0) {
157af57ed9fSAtsushi Murai 	CloseSecret(fp);
158643f4904SBrian Somers         return auth_CheckPasswd(vector[0], vector[1], key);
159af57ed9fSAtsushi Murai       }
160af57ed9fSAtsushi Murai     }
161af57ed9fSAtsushi Murai     CloseSecret(fp);
162d5015272SBrian Somers   }
163d5015272SBrian Somers 
164d5015272SBrian Somers #ifndef NOPASSWDAUTH
1651342caedSBrian Somers   if (Enabled(bundle, OPT_PASSWDAUTH))
166d5015272SBrian Somers     return auth_CheckPasswd(system, "*", key);
167d5015272SBrian Somers #endif
168d5015272SBrian Somers 
169d5015272SBrian Somers   return 0;			/* Invalid */
170af57ed9fSAtsushi Murai }
171af57ed9fSAtsushi Murai 
172af57ed9fSAtsushi Murai char *
173dd7e2610SBrian Somers auth_GetSecret(struct bundle *bundle, const char *system, int len,
174643f4904SBrian Somers               struct physical *physical)
175af57ed9fSAtsushi Murai {
176d5015272SBrian Somers   /* Used by CHAP routines */
177d5015272SBrian Somers 
178af57ed9fSAtsushi Murai   FILE *fp;
179af57ed9fSAtsushi Murai   int n;
1809c97abd8SBrian Somers   char *vector[5];
181d93d3a9cSBrian Somers   char buff[LINE_LEN];
182af57ed9fSAtsushi Murai 
183643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
184af57ed9fSAtsushi Murai   if (fp == NULL)
185af57ed9fSAtsushi Murai     return (NULL);
186d5015272SBrian Somers 
18770ee81ffSBrian Somers   while (fgets(buff, sizeof buff, fp)) {
188af57ed9fSAtsushi Murai     if (buff[0] == '#')
189af57ed9fSAtsushi Murai       continue;
190af57ed9fSAtsushi Murai     buff[strlen(buff) - 1] = 0;
19170ee81ffSBrian Somers     memset(vector, '\0', sizeof vector);
192e68d210eSBrian Somers     n = MakeArgs(buff, vector, VECSIZE(vector));
193af57ed9fSAtsushi Murai     if (n < 2)
194af57ed9fSAtsushi Murai       continue;
195af57ed9fSAtsushi Murai     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
196643f4904SBrian Somers       CloseSecret(fp);
197d5015272SBrian Somers       return vector[1];
198af57ed9fSAtsushi Murai     }
199af57ed9fSAtsushi Murai   }
200af57ed9fSAtsushi Murai   CloseSecret(fp);
201af57ed9fSAtsushi Murai   return (NULL);		/* Invalid */
202af57ed9fSAtsushi Murai }
20353c9f6c0SAtsushi Murai 
20453c9f6c0SAtsushi Murai static void
205b6e82f33SBrian Somers AuthTimeout(void *vauthp)
20653c9f6c0SAtsushi Murai {
207b6e82f33SBrian Somers   struct authinfo *authp = (struct authinfo *)vauthp;
20853c9f6c0SAtsushi Murai 
209dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
21053c9f6c0SAtsushi Murai   if (--authp->retry > 0) {
211dd7e2610SBrian Somers     timer_Start(&authp->authtimer);
212e2ebb036SBrian Somers     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
21353c9f6c0SAtsushi Murai   }
21453c9f6c0SAtsushi Murai }
21553c9f6c0SAtsushi Murai 
21653c9f6c0SAtsushi Murai void
217dd7e2610SBrian Somers auth_Init(struct authinfo *authinfo)
21853c9f6c0SAtsushi Murai {
219e2ebb036SBrian Somers   memset(authinfo, '\0', sizeof(struct authinfo));
220cd9647a1SBrian Somers   authinfo->cfg.fsmretry = DEF_FSMRETRY;
221e2ebb036SBrian Somers }
22253c9f6c0SAtsushi Murai 
223e2ebb036SBrian Somers void
224dd7e2610SBrian Somers auth_StartChallenge(struct authinfo *authp, struct physical *physical,
225e2ebb036SBrian Somers                    void (*fn)(struct authinfo *, int, struct physical *))
226e2ebb036SBrian Somers {
227e2ebb036SBrian Somers   authp->ChallengeFunc = fn;
22863b73463SBrian Somers   authp->physical = physical;
229dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
230e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
2313b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
232cd9647a1SBrian Somers   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
233e2ebb036SBrian Somers   authp->authtimer.arg = (void *) authp;
23453c9f6c0SAtsushi Murai   authp->retry = 3;
23553c9f6c0SAtsushi Murai   authp->id = 1;
236e2ebb036SBrian Somers   (*authp->ChallengeFunc)(authp, authp->id, physical);
237dd7e2610SBrian Somers   timer_Start(&authp->authtimer);
23853c9f6c0SAtsushi Murai }
23953c9f6c0SAtsushi Murai 
24053c9f6c0SAtsushi Murai void
241dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp)
24253c9f6c0SAtsushi Murai {
243dd7e2610SBrian Somers   timer_Stop(&authp->authtimer);
24463b73463SBrian Somers   authp->physical = NULL;
24553c9f6c0SAtsushi Murai }
246