xref: /freebsd/usr.sbin/ppp/auth.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
1 /*
2  *			PPP Secret Key Module
3  *
4  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5  *
6  *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the Internet Initiative Japan, Inc.  The name of the
14  * IIJ may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * $Id: auth.c,v 1.32 1998/08/07 18:42:47 brian Exp $
21  *
22  *	TODO:
23  *		o Implement check against with registered IP addresses.
24  */
25 #include <sys/types.h>
26 #include <netinet/in.h>
27 #include <netinet/in_systm.h>
28 #include <netinet/ip.h>
29 #include <sys/un.h>
30 
31 #include <pwd.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 
36 #include "mbuf.h"
37 #include "defs.h"
38 #include "timer.h"
39 #include "fsm.h"
40 #include "iplist.h"
41 #include "throughput.h"
42 #include "slcompress.h"
43 #include "lqr.h"
44 #include "hdlc.h"
45 #include "ipcp.h"
46 #include "auth.h"
47 #include "systems.h"
48 #include "lcp.h"
49 #include "ccp.h"
50 #include "link.h"
51 #include "descriptor.h"
52 #include "chat.h"
53 #include "lcpproto.h"
54 #include "filter.h"
55 #include "mp.h"
56 #include "bundle.h"
57 
58 const char *
59 Auth2Nam(u_short auth)
60 {
61   switch (auth) {
62   case PROTO_PAP:
63     return "PAP";
64   case PROTO_CHAP:
65     return "CHAP";
66   case 0:
67     return "none";
68   }
69   return "unknown";
70 }
71 
72 static int
73 auth_CheckPasswd(const char *name, const char *data, const char *key)
74 {
75   if (!strcmp(data, "*")) {
76     /* Then look up the real password database */
77     struct passwd *pw;
78     int result;
79 
80     result = (pw = getpwnam(name)) &&
81              !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
82     endpwent();
83     return result;
84   }
85 
86   return !strcmp(data, key);
87 }
88 
89 int
90 auth_SetPhoneList(const char *name, char *phone, int phonelen)
91 {
92   FILE *fp;
93   int n;
94   char *vector[6];
95   char buff[LINE_LEN];
96 
97   fp = OpenSecret(SECRETFILE);
98   if (fp != NULL) {
99     while (fgets(buff, sizeof buff, fp)) {
100       if (buff[0] == '#')
101         continue;
102       buff[strlen(buff) - 1] = '\0';
103       memset(vector, '\0', sizeof vector);
104       n = MakeArgs(buff, vector, VECSIZE(vector));
105       if (n < 5)
106         continue;
107       if (strcmp(vector[0], name) == 0) {
108 	CloseSecret(fp);
109 	if (*vector[4] == '\0')
110           return 0;
111         strncpy(phone, vector[4], phonelen - 1);
112         phone[phonelen - 1] = '\0';
113 	return 1;		/* Valid */
114       }
115     }
116     CloseSecret(fp);
117   }
118   *phone = '\0';
119   return 0;
120 }
121 
122 int
123 auth_Select(struct bundle *bundle, const char *name)
124 {
125   FILE *fp;
126   int n;
127   char *vector[5];
128   char buff[LINE_LEN];
129 
130   if (*name == '\0') {
131     ipcp_Setup(&bundle->ncp.ipcp);
132     return 1;
133   }
134 
135   fp = OpenSecret(SECRETFILE);
136   if (fp != NULL) {
137     while (fgets(buff, sizeof buff, fp)) {
138       if (buff[0] == '#')
139         continue;
140       buff[strlen(buff) - 1] = '\0';
141       memset(vector, '\0', sizeof vector);
142       n = MakeArgs(buff, vector, VECSIZE(vector));
143       if (n < 2)
144         continue;
145       if (strcmp(vector[0], name) == 0) {
146 	CloseSecret(fp);
147 	if (n > 2 && *vector[2] && strcmp(vector[2], "*") &&
148             !ipcp_UseHisaddr(bundle, vector[2], 1))
149 	  return 0;
150 	ipcp_Setup(&bundle->ncp.ipcp);
151 	if (n > 3 && *vector[3] && strcmp(vector[3], "*"))
152 	  bundle_SetLabel(bundle, vector[3]);
153 	return 1;		/* Valid */
154       }
155     }
156     CloseSecret(fp);
157   }
158 
159 #ifndef NOPASSWDAUTH
160   /* Let 'em in anyway - they must have been in the passwd file */
161   ipcp_Setup(&bundle->ncp.ipcp);
162   return 1;
163 #else
164   /* Disappeared from ppp.secret ? */
165   return 0;
166 #endif
167 }
168 
169 int
170 auth_Validate(struct bundle *bundle, const char *system,
171              const char *key, struct physical *physical)
172 {
173   /* Used by PAP routines */
174 
175   FILE *fp;
176   int n;
177   char *vector[5];
178   char buff[LINE_LEN];
179 
180   fp = OpenSecret(SECRETFILE);
181   if (fp != NULL) {
182     while (fgets(buff, sizeof buff, fp)) {
183       if (buff[0] == '#')
184         continue;
185       buff[strlen(buff) - 1] = 0;
186       memset(vector, '\0', sizeof vector);
187       n = MakeArgs(buff, vector, VECSIZE(vector));
188       if (n < 2)
189         continue;
190       if (strcmp(vector[0], system) == 0) {
191 	CloseSecret(fp);
192         return auth_CheckPasswd(vector[0], vector[1], key);
193       }
194     }
195     CloseSecret(fp);
196   }
197 
198 #ifndef NOPASSWDAUTH
199   if (Enabled(bundle, OPT_PASSWDAUTH))
200     return auth_CheckPasswd(system, "*", key);
201 #endif
202 
203   return 0;			/* Invalid */
204 }
205 
206 char *
207 auth_GetSecret(struct bundle *bundle, const char *system, int len,
208               struct physical *physical)
209 {
210   /* Used by CHAP routines */
211 
212   FILE *fp;
213   int n;
214   char *vector[5];
215   char buff[LINE_LEN];
216 
217   fp = OpenSecret(SECRETFILE);
218   if (fp == NULL)
219     return (NULL);
220 
221   while (fgets(buff, sizeof buff, fp)) {
222     if (buff[0] == '#')
223       continue;
224     buff[strlen(buff) - 1] = 0;
225     memset(vector, '\0', sizeof vector);
226     n = MakeArgs(buff, vector, VECSIZE(vector));
227     if (n < 2)
228       continue;
229     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
230       CloseSecret(fp);
231       return vector[1];
232     }
233   }
234   CloseSecret(fp);
235   return (NULL);		/* Invalid */
236 }
237 
238 static void
239 AuthTimeout(void *vauthp)
240 {
241   struct authinfo *authp = (struct authinfo *)vauthp;
242 
243   timer_Stop(&authp->authtimer);
244   if (--authp->retry > 0) {
245     timer_Start(&authp->authtimer);
246     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
247   }
248 }
249 
250 void
251 auth_Init(struct authinfo *authinfo)
252 {
253   memset(authinfo, '\0', sizeof(struct authinfo));
254   authinfo->cfg.fsmretry = DEF_FSMRETRY;
255 }
256 
257 void
258 auth_StartChallenge(struct authinfo *authp, struct physical *physical,
259                    void (*fn)(struct authinfo *, int, struct physical *))
260 {
261   authp->ChallengeFunc = fn;
262   authp->physical = physical;
263   timer_Stop(&authp->authtimer);
264   authp->authtimer.func = AuthTimeout;
265   authp->authtimer.name = "auth";
266   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
267   authp->authtimer.arg = (void *) authp;
268   authp->retry = 3;
269   authp->id = 1;
270   (*authp->ChallengeFunc)(authp, authp->id, physical);
271   timer_Start(&authp->authtimer);
272 }
273 
274 void
275 auth_StopTimer(struct authinfo *authp)
276 {
277   timer_Stop(&authp->authtimer);
278   authp->physical = NULL;
279 }
280