xref: /freebsd/usr.sbin/ppp/auth.c (revision 1fa665f5b363853f2e5ebdf453e9af3b7e752729)
11ae349f5Scvs2svn /*
21ae349f5Scvs2svn  *			PPP Secret Key Module
31ae349f5Scvs2svn  *
41ae349f5Scvs2svn  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
51ae349f5Scvs2svn  *
61ae349f5Scvs2svn  *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
71ae349f5Scvs2svn  *
81ae349f5Scvs2svn  * Redistribution and use in source and binary forms are permitted
91ae349f5Scvs2svn  * provided that the above copyright notice and this paragraph are
101ae349f5Scvs2svn  * duplicated in all such forms and that any documentation,
111ae349f5Scvs2svn  * advertising materials, and other materials related to such
121ae349f5Scvs2svn  * distribution and use acknowledge that the software was developed
131ae349f5Scvs2svn  * by the Internet Initiative Japan, Inc.  The name of the
141ae349f5Scvs2svn  * IIJ may not be used to endorse or promote products derived
151ae349f5Scvs2svn  * from this software without specific prior written permission.
161ae349f5Scvs2svn  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
171ae349f5Scvs2svn  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
181ae349f5Scvs2svn  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
191ae349f5Scvs2svn  *
201fa665f5SBrian Somers  * $Id: auth.c,v 1.27.2.24 1998/04/24 19:15:55 brian Exp $
211ae349f5Scvs2svn  *
221ae349f5Scvs2svn  *	TODO:
231ae349f5Scvs2svn  *		o Implement check against with registered IP addresses.
241ae349f5Scvs2svn  */
252764b86aSBrian Somers #include <sys/types.h>
261ae349f5Scvs2svn #include <netinet/in.h>
27eaa4df37SBrian Somers #include <netinet/in_systm.h>
28eaa4df37SBrian Somers #include <netinet/ip.h>
291fa665f5SBrian Somers #include <sys/un.h>
301ae349f5Scvs2svn 
31d5015272SBrian Somers #include <pwd.h>
321ae349f5Scvs2svn #include <stdio.h>
331ae349f5Scvs2svn #include <string.h>
341ae349f5Scvs2svn #include <unistd.h>
351ae349f5Scvs2svn 
361ae349f5Scvs2svn #include "mbuf.h"
371ae349f5Scvs2svn #include "defs.h"
381ae349f5Scvs2svn #include "timer.h"
391ae349f5Scvs2svn #include "fsm.h"
4029e275ceSBrian Somers #include "iplist.h"
4129e275ceSBrian Somers #include "throughput.h"
42eaa4df37SBrian Somers #include "slcompress.h"
431ae349f5Scvs2svn #include "ipcp.h"
441ae349f5Scvs2svn #include "auth.h"
451ae349f5Scvs2svn #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"
57455aabc3SBrian Somers 
58455aabc3SBrian Somers const char *
59455aabc3SBrian Somers Auth2Nam(u_short auth)
60455aabc3SBrian Somers {
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";
68455aabc3SBrian Somers   }
69455aabc3SBrian Somers   return "unknown";
70455aabc3SBrian Somers }
711ae349f5Scvs2svn 
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
90643f4904SBrian Somers AuthSelect(struct bundle *bundle, const char *name, struct physical *physical)
911ae349f5Scvs2svn {
921ae349f5Scvs2svn   FILE *fp;
931ae349f5Scvs2svn   int n;
941ae349f5Scvs2svn   char *vector[5];
951ae349f5Scvs2svn   char buff[LINE_LEN];
961ae349f5Scvs2svn 
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) {
1041ae349f5Scvs2svn     while (fgets(buff, sizeof buff, fp)) {
1051ae349f5Scvs2svn       if (buff[0] == '#')
1061ae349f5Scvs2svn         continue;
1071ae349f5Scvs2svn       buff[strlen(buff) - 1] = 0;
1081ae349f5Scvs2svn       memset(vector, '\0', sizeof vector);
1091ae349f5Scvs2svn       n = MakeArgs(buff, vector, VECSIZE(vector));
1101ae349f5Scvs2svn       if (n < 2)
1111ae349f5Scvs2svn         continue;
112643f4904SBrian Somers       if (strcmp(vector[0], name) == 0)
1131ae349f5Scvs2svn 	CloseSecret(fp);
114643f4904SBrian Somers /*
115643f4904SBrian Somers 	memset(&bundle->ncp.ipcp.cfg.peer_range, '\0',
116643f4904SBrian Somers                sizeof bundle->ncp.ipcp.cfg.peer_range);
117643f4904SBrian Somers */
1187a6f8720SBrian Somers 	if (n > 2 && !UseHisaddr(bundle, vector[2], 1))
119643f4904SBrian Somers 	  return 0;
1205828db6dSBrian Somers 	ipcp_Setup(&bundle->ncp.ipcp);
1211ae349f5Scvs2svn 	if (n > 3)
12249052c95SBrian Somers 	  bundle_SetLabel(bundle, vector[3]);
123d5015272SBrian Somers 	return 1;		/* Valid */
124643f4904SBrian Somers     }
125d5015272SBrian Somers     CloseSecret(fp);
126643f4904SBrian Somers   }
127643f4904SBrian Somers 
128643f4904SBrian Somers #ifndef NOPASSWDAUTH
129643f4904SBrian Somers   /* Let 'em in anyway - they must have been in the passwd file */
130643f4904SBrian Somers   ipcp_Setup(&bundle->ncp.ipcp);
131643f4904SBrian Somers   return 1;
132643f4904SBrian Somers #else
133643f4904SBrian Somers   /* Disappeared from ppp.secret ? */
134643f4904SBrian Somers   return 0;
135643f4904SBrian Somers #endif
136643f4904SBrian Somers }
137643f4904SBrian Somers 
138643f4904SBrian Somers int
139643f4904SBrian Somers AuthValidate(struct bundle *bundle, const char *system,
140643f4904SBrian Somers              const char *key, struct physical *physical)
141643f4904SBrian Somers {
142643f4904SBrian Somers   /* Used by PAP routines */
143643f4904SBrian Somers 
144643f4904SBrian Somers   FILE *fp;
145643f4904SBrian Somers   int n;
146643f4904SBrian Somers   char *vector[5];
147643f4904SBrian Somers   char buff[LINE_LEN];
148643f4904SBrian Somers 
149643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
150643f4904SBrian Somers   if (fp != NULL) {
151643f4904SBrian Somers     while (fgets(buff, sizeof buff, fp)) {
152643f4904SBrian Somers       if (buff[0] == '#')
153643f4904SBrian Somers         continue;
154643f4904SBrian Somers       buff[strlen(buff) - 1] = 0;
155643f4904SBrian Somers       memset(vector, '\0', sizeof vector);
156643f4904SBrian Somers       n = MakeArgs(buff, vector, VECSIZE(vector));
157643f4904SBrian Somers       if (n < 2)
158643f4904SBrian Somers         continue;
159643f4904SBrian Somers       if (strcmp(vector[0], system) == 0) {
160643f4904SBrian Somers 	CloseSecret(fp);
161643f4904SBrian Somers         return auth_CheckPasswd(vector[0], vector[1], key);
1621ae349f5Scvs2svn       }
1631ae349f5Scvs2svn     }
1641ae349f5Scvs2svn     CloseSecret(fp);
165d5015272SBrian Somers   }
166d5015272SBrian Somers 
167d5015272SBrian Somers #ifndef NOPASSWDAUTH
1681342caedSBrian Somers   if (Enabled(bundle, OPT_PASSWDAUTH))
169d5015272SBrian Somers     return auth_CheckPasswd(system, "*", key);
170d5015272SBrian Somers #endif
171d5015272SBrian Somers 
172d5015272SBrian Somers   return 0;			/* Invalid */
1731ae349f5Scvs2svn }
1741ae349f5Scvs2svn 
1751ae349f5Scvs2svn char *
176643f4904SBrian Somers AuthGetSecret(struct bundle *bundle, const char *system, int len,
177643f4904SBrian Somers               struct physical *physical)
1781ae349f5Scvs2svn {
179d5015272SBrian Somers   /* Used by CHAP routines */
180d5015272SBrian Somers 
1811ae349f5Scvs2svn   FILE *fp;
1821ae349f5Scvs2svn   int n;
1831ae349f5Scvs2svn   char *vector[5];
184d5015272SBrian Somers   static char buff[LINE_LEN];
1851ae349f5Scvs2svn 
186643f4904SBrian Somers   fp = OpenSecret(SECRETFILE);
1871ae349f5Scvs2svn   if (fp == NULL)
1881ae349f5Scvs2svn     return (NULL);
189d5015272SBrian Somers 
1901ae349f5Scvs2svn   while (fgets(buff, sizeof buff, fp)) {
1911ae349f5Scvs2svn     if (buff[0] == '#')
1921ae349f5Scvs2svn       continue;
1931ae349f5Scvs2svn     buff[strlen(buff) - 1] = 0;
1941ae349f5Scvs2svn     memset(vector, '\0', sizeof vector);
1951ae349f5Scvs2svn     n = MakeArgs(buff, vector, VECSIZE(vector));
1961ae349f5Scvs2svn     if (n < 2)
1971ae349f5Scvs2svn       continue;
1981ae349f5Scvs2svn     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
199643f4904SBrian Somers       CloseSecret(fp);
200d5015272SBrian Somers       return vector[1];
2011ae349f5Scvs2svn     }
2021ae349f5Scvs2svn   }
2031ae349f5Scvs2svn   CloseSecret(fp);
2041ae349f5Scvs2svn   return (NULL);		/* Invalid */
2051ae349f5Scvs2svn }
2061ae349f5Scvs2svn 
2071ae349f5Scvs2svn static void
2081ae349f5Scvs2svn AuthTimeout(void *vauthp)
2091ae349f5Scvs2svn {
2101ae349f5Scvs2svn   struct authinfo *authp = (struct authinfo *)vauthp;
2111ae349f5Scvs2svn 
212e2ebb036SBrian Somers   StopTimer(&authp->authtimer);
2131ae349f5Scvs2svn   if (--authp->retry > 0) {
214e2ebb036SBrian Somers     StartTimer(&authp->authtimer);
215e2ebb036SBrian Somers     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
2161ae349f5Scvs2svn   }
2171ae349f5Scvs2svn }
2181ae349f5Scvs2svn 
2191ae349f5Scvs2svn void
220e2ebb036SBrian Somers authinfo_Init(struct authinfo *authinfo)
2211ae349f5Scvs2svn {
222e2ebb036SBrian Somers   memset(authinfo, '\0', sizeof(struct authinfo));
223cd9647a1SBrian Somers   authinfo->cfg.fsmretry = DEF_FSMRETRY;
224e2ebb036SBrian Somers }
2251ae349f5Scvs2svn 
226e2ebb036SBrian Somers void
227e2ebb036SBrian Somers StartAuthChallenge(struct authinfo *authp, struct physical *physical,
228e2ebb036SBrian Somers                    void (*fn)(struct authinfo *, int, struct physical *))
229e2ebb036SBrian Somers {
230e2ebb036SBrian Somers   authp->ChallengeFunc = fn;
23163b73463SBrian Somers   authp->physical = physical;
232e2ebb036SBrian Somers   StopTimer(&authp->authtimer);
233e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
2343b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
235cd9647a1SBrian Somers   authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
236e2ebb036SBrian Somers   authp->authtimer.arg = (void *) authp;
2371ae349f5Scvs2svn   authp->retry = 3;
2381ae349f5Scvs2svn   authp->id = 1;
239e2ebb036SBrian Somers   (*authp->ChallengeFunc)(authp, authp->id, physical);
240e2ebb036SBrian Somers   StartTimer(&authp->authtimer);
2411ae349f5Scvs2svn }
2421ae349f5Scvs2svn 
2431ae349f5Scvs2svn void
2441ae349f5Scvs2svn StopAuthTimer(struct authinfo *authp)
2451ae349f5Scvs2svn {
2461ae349f5Scvs2svn   StopTimer(&authp->authtimer);
24763b73463SBrian Somers   authp->physical = NULL;
2481ae349f5Scvs2svn }
249