xref: /freebsd/usr.sbin/ppp/auth.c (revision 11afcc8f9f96d657b8e6f7547c02c1957331fc96)
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.30 1998/06/15 19:06:35 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 "ipcp.h"
44 #include "auth.h"
45 #include "systems.h"
46 #include "lcp.h"
47 #include "lqr.h"
48 #include "hdlc.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_Select(struct bundle *bundle, const char *name, struct physical *physical)
91 {
92   FILE *fp;
93   int n;
94   char *vector[5];
95   char buff[LINE_LEN];
96 
97   if (*name == '\0') {
98     ipcp_Setup(&bundle->ncp.ipcp);
99     return 1;
100   }
101 
102   fp = OpenSecret(SECRETFILE);
103   if (fp != NULL) {
104     while (fgets(buff, sizeof buff, fp)) {
105       if (buff[0] == '#')
106         continue;
107       buff[strlen(buff) - 1] = '\0';
108       memset(vector, '\0', sizeof vector);
109       n = MakeArgs(buff, vector, VECSIZE(vector));
110       if (n < 2)
111         continue;
112       if (strcmp(vector[0], name) == 0) {
113 	CloseSecret(fp);
114 	if (n > 2 && !ipcp_UseHisaddr(bundle, vector[2], 1))
115 	  return 0;
116 	ipcp_Setup(&bundle->ncp.ipcp);
117 	if (n > 3)
118 	  bundle_SetLabel(bundle, vector[3]);
119 	return 1;		/* Valid */
120       }
121     }
122     CloseSecret(fp);
123   }
124 
125 #ifndef NOPASSWDAUTH
126   /* Let 'em in anyway - they must have been in the passwd file */
127   ipcp_Setup(&bundle->ncp.ipcp);
128   return 1;
129 #else
130   /* Disappeared from ppp.secret ? */
131   return 0;
132 #endif
133 }
134 
135 int
136 auth_Validate(struct bundle *bundle, const char *system,
137              const char *key, struct physical *physical)
138 {
139   /* Used by PAP routines */
140 
141   FILE *fp;
142   int n;
143   char *vector[5];
144   char buff[LINE_LEN];
145 
146   fp = OpenSecret(SECRETFILE);
147   if (fp != NULL) {
148     while (fgets(buff, sizeof buff, fp)) {
149       if (buff[0] == '#')
150         continue;
151       buff[strlen(buff) - 1] = 0;
152       memset(vector, '\0', sizeof vector);
153       n = MakeArgs(buff, vector, VECSIZE(vector));
154       if (n < 2)
155         continue;
156       if (strcmp(vector[0], system) == 0) {
157 	CloseSecret(fp);
158         return auth_CheckPasswd(vector[0], vector[1], key);
159       }
160     }
161     CloseSecret(fp);
162   }
163 
164 #ifndef NOPASSWDAUTH
165   if (Enabled(bundle, OPT_PASSWDAUTH))
166     return auth_CheckPasswd(system, "*", key);
167 #endif
168 
169   return 0;			/* Invalid */
170 }
171 
172 char *
173 auth_GetSecret(struct bundle *bundle, const char *system, int len,
174               struct physical *physical)
175 {
176   /* Used by CHAP routines */
177 
178   FILE *fp;
179   int n;
180   char *vector[5];
181   char buff[LINE_LEN];
182 
183   fp = OpenSecret(SECRETFILE);
184   if (fp == NULL)
185     return (NULL);
186 
187   while (fgets(buff, sizeof buff, fp)) {
188     if (buff[0] == '#')
189       continue;
190     buff[strlen(buff) - 1] = 0;
191     memset(vector, '\0', sizeof vector);
192     n = MakeArgs(buff, vector, VECSIZE(vector));
193     if (n < 2)
194       continue;
195     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
196       CloseSecret(fp);
197       return vector[1];
198     }
199   }
200   CloseSecret(fp);
201   return (NULL);		/* Invalid */
202 }
203 
204 static void
205 AuthTimeout(void *vauthp)
206 {
207   struct authinfo *authp = (struct authinfo *)vauthp;
208 
209   timer_Stop(&authp->authtimer);
210   if (--authp->retry > 0) {
211     timer_Start(&authp->authtimer);
212     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
213   }
214 }
215 
216 void
217 auth_Init(struct authinfo *authinfo)
218 {
219   memset(authinfo, '\0', sizeof(struct authinfo));
220   authinfo->cfg.fsmretry = DEF_FSMRETRY;
221 }
222 
223 void
224 auth_StartChallenge(struct authinfo *authp, struct physical *physical,
225                    void (*fn)(struct authinfo *, int, struct physical *))
226 {
227   authp->ChallengeFunc = fn;
228   authp->physical = physical;
229   timer_Stop(&authp->authtimer);
230   authp->authtimer.func = AuthTimeout;
231   authp->authtimer.name = "auth";
232   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
233   authp->authtimer.arg = (void *) authp;
234   authp->retry = 3;
235   authp->id = 1;
236   (*authp->ChallengeFunc)(authp, authp->id, physical);
237   timer_Start(&authp->authtimer);
238 }
239 
240 void
241 auth_StopTimer(struct authinfo *authp)
242 {
243   timer_Stop(&authp->authtimer);
244   authp->physical = NULL;
245 }
246