xref: /freebsd/usr.sbin/ppp/auth.c (revision 3b0f8d2ed641ceeded11c0d3f253b0cacbf00880)
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  *
203b0f8d2eSBrian Somers  * $Id: auth.c,v 1.27.2.15 1998/03/16 22:53:28 brian Exp $
211ae349f5Scvs2svn  *
221ae349f5Scvs2svn  *	TODO:
231ae349f5Scvs2svn  *		o Implement check against with registered IP addresses.
241ae349f5Scvs2svn  */
251ae349f5Scvs2svn #include <sys/param.h>
261ae349f5Scvs2svn #include <netinet/in.h>
27eaa4df37SBrian Somers #include <netinet/in_systm.h>
28eaa4df37SBrian Somers #include <netinet/ip.h>
291ae349f5Scvs2svn 
3063b73463SBrian Somers #include <assert.h>
31d5015272SBrian Somers #include <pwd.h>
321ae349f5Scvs2svn #include <stdio.h>
331ae349f5Scvs2svn #include <string.h>
346140ba11SBrian Somers #include <termios.h>
351ae349f5Scvs2svn #include <unistd.h>
361ae349f5Scvs2svn 
371ae349f5Scvs2svn #include "command.h"
381ae349f5Scvs2svn #include "mbuf.h"
391ae349f5Scvs2svn #include "defs.h"
401ae349f5Scvs2svn #include "timer.h"
411ae349f5Scvs2svn #include "fsm.h"
4229e275ceSBrian Somers #include "iplist.h"
4329e275ceSBrian Somers #include "throughput.h"
44eaa4df37SBrian Somers #include "slcompress.h"
451ae349f5Scvs2svn #include "ipcp.h"
461ae349f5Scvs2svn #include "loadalias.h"
471ae349f5Scvs2svn #include "vars.h"
481ae349f5Scvs2svn #include "auth.h"
491ae349f5Scvs2svn #include "systems.h"
506140ba11SBrian Somers #include "lcp.h"
51879ed6faSBrian Somers #include "lqr.h"
526140ba11SBrian Somers #include "hdlc.h"
536140ba11SBrian Somers #include "async.h"
543b0f8d2eSBrian Somers #include "ccp.h"
556140ba11SBrian Somers #include "link.h"
5642d4d396SBrian Somers #include "descriptor.h"
578c07a7b2SBrian Somers #include "physical.h"
58b6dec9f0SBrian Somers #include "chat.h"
59455aabc3SBrian Somers #include "lcpproto.h"
605ca5389aSBrian Somers #include "filter.h"
613b0f8d2eSBrian Somers #include "mp.h"
625828db6dSBrian Somers #include "bundle.h"
63455aabc3SBrian Somers 
64455aabc3SBrian Somers const char *
65455aabc3SBrian Somers Auth2Nam(u_short auth)
66455aabc3SBrian Somers {
67455aabc3SBrian Somers   switch (auth) {
68455aabc3SBrian Somers   case PROTO_PAP:
69455aabc3SBrian Somers     return "PAP";
70455aabc3SBrian Somers   case PROTO_CHAP:
71455aabc3SBrian Somers     return "CHAP";
72455aabc3SBrian Somers   case 0:
73455aabc3SBrian Somers     return "none";
74455aabc3SBrian Somers   }
75455aabc3SBrian Somers   return "unknown";
76455aabc3SBrian Somers }
771ae349f5Scvs2svn 
781ae349f5Scvs2svn void
791ae349f5Scvs2svn LocalAuthInit()
801ae349f5Scvs2svn {
811ae349f5Scvs2svn   if (!(mode&MODE_DAEMON))
821ae349f5Scvs2svn     /* We're allowed in interactive mode */
831ae349f5Scvs2svn     VarLocalAuth = LOCAL_AUTH;
841ae349f5Scvs2svn   else if (VarHaveLocalAuthKey)
851ae349f5Scvs2svn     VarLocalAuth = *VarLocalAuthKey == '\0' ? LOCAL_AUTH : LOCAL_NO_AUTH;
861ae349f5Scvs2svn   else
871ae349f5Scvs2svn     switch (LocalAuthValidate(SECRETFILE, VarShortHost, "")) {
881ae349f5Scvs2svn     case NOT_FOUND:
891ae349f5Scvs2svn       VarLocalAuth = LOCAL_DENY;
901ae349f5Scvs2svn       break;
911ae349f5Scvs2svn     case VALID:
921ae349f5Scvs2svn       VarLocalAuth = LOCAL_AUTH;
931ae349f5Scvs2svn       break;
941ae349f5Scvs2svn     case INVALID:
951ae349f5Scvs2svn       VarLocalAuth = LOCAL_NO_AUTH;
961ae349f5Scvs2svn       break;
971ae349f5Scvs2svn     }
981ae349f5Scvs2svn }
991ae349f5Scvs2svn 
1001ae349f5Scvs2svn LOCAL_AUTH_VALID
1011ae349f5Scvs2svn LocalAuthValidate(const char *fname, const char *system, const char *key)
1021ae349f5Scvs2svn {
1031ae349f5Scvs2svn   FILE *fp;
1041ae349f5Scvs2svn   int n;
1051ae349f5Scvs2svn   char *vector[3];
1061ae349f5Scvs2svn   char buff[LINE_LEN];
1071ae349f5Scvs2svn   LOCAL_AUTH_VALID rc;
1081ae349f5Scvs2svn 
1091ae349f5Scvs2svn   rc = NOT_FOUND;		/* No system entry */
1101ae349f5Scvs2svn   fp = OpenSecret(fname);
1111ae349f5Scvs2svn   if (fp == NULL)
1121ae349f5Scvs2svn     return (rc);
1131ae349f5Scvs2svn   while (fgets(buff, sizeof buff, fp)) {
1141ae349f5Scvs2svn     if (buff[0] == '#')
1151ae349f5Scvs2svn       continue;
1161ae349f5Scvs2svn     buff[strlen(buff) - 1] = 0;
1171ae349f5Scvs2svn     memset(vector, '\0', sizeof vector);
1181ae349f5Scvs2svn     n = MakeArgs(buff, vector, VECSIZE(vector));
1191ae349f5Scvs2svn     if (n < 1)
1201ae349f5Scvs2svn       continue;
1211ae349f5Scvs2svn     if (strcmp(vector[0], system) == 0) {
1221ae349f5Scvs2svn       if ((vector[1] == (char *) NULL && (key == NULL || *key == '\0')) ||
1231ae349f5Scvs2svn           (vector[1] != (char *) NULL && strcmp(vector[1], key) == 0)) {
1241ae349f5Scvs2svn 	rc = VALID;		/* Valid   */
1251ae349f5Scvs2svn       } else {
1261ae349f5Scvs2svn 	rc = INVALID;		/* Invalid */
1271ae349f5Scvs2svn       }
1281ae349f5Scvs2svn       break;
1291ae349f5Scvs2svn     }
1301ae349f5Scvs2svn   }
1311ae349f5Scvs2svn   CloseSecret(fp);
1321ae349f5Scvs2svn   return (rc);
1331ae349f5Scvs2svn }
1341ae349f5Scvs2svn 
135d5015272SBrian Somers static int
136d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key)
137d5015272SBrian Somers {
138d5015272SBrian Somers   if (!strcmp(data, "*")) {
139d5015272SBrian Somers     /* Then look up the real password database */
140d5015272SBrian Somers     struct passwd *pw;
141d5015272SBrian Somers     int result;
142d5015272SBrian Somers 
143d5015272SBrian Somers     result = (pw = getpwnam(name)) &&
144d5015272SBrian Somers              !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
145d5015272SBrian Somers     endpwent();
146d5015272SBrian Somers     return result;
147d5015272SBrian Somers   }
148d5015272SBrian Somers 
149d5015272SBrian Somers   return !strcmp(data, key);
150d5015272SBrian Somers }
151d5015272SBrian Somers 
1521ae349f5Scvs2svn int
1537a6f8720SBrian Somers AuthValidate(struct bundle *bundle, const char *fname, const char *system,
1547a6f8720SBrian Somers              const char *key, struct physical *physical)
1551ae349f5Scvs2svn {
156d5015272SBrian Somers   /* Used by PAP routines */
157d5015272SBrian Somers 
1581ae349f5Scvs2svn   FILE *fp;
1591ae349f5Scvs2svn   int n;
1601ae349f5Scvs2svn   char *vector[5];
1611ae349f5Scvs2svn   char buff[LINE_LEN];
1621ae349f5Scvs2svn 
1631ae349f5Scvs2svn   fp = OpenSecret(fname);
164d5015272SBrian Somers   if (fp != NULL) {
1651ae349f5Scvs2svn     while (fgets(buff, sizeof buff, fp)) {
1661ae349f5Scvs2svn       if (buff[0] == '#')
1671ae349f5Scvs2svn         continue;
1681ae349f5Scvs2svn       buff[strlen(buff) - 1] = 0;
1691ae349f5Scvs2svn       memset(vector, '\0', sizeof vector);
1701ae349f5Scvs2svn       n = MakeArgs(buff, vector, VECSIZE(vector));
1711ae349f5Scvs2svn       if (n < 2)
1721ae349f5Scvs2svn         continue;
173d5015272SBrian Somers       if (strcmp(vector[0], system) == 0)
174d5015272SBrian Somers         if (auth_CheckPasswd(vector[0], vector[1], key)) {
1751ae349f5Scvs2svn 	  CloseSecret(fp);
1767a6f8720SBrian Somers 	  if (n > 2 && !UseHisaddr(bundle, vector[2], 1))
1771ae349f5Scvs2svn 	      return (0);
1787a6f8720SBrian Somers           /* XXX This should be deferred - we may join an existing bundle ! */
1795828db6dSBrian Somers 	  ipcp_Setup(&bundle->ncp.ipcp);
1801ae349f5Scvs2svn 	  if (n > 3)
1811ae349f5Scvs2svn 	    SetLabel(vector[3]);
182d5015272SBrian Somers 	  return 1;		/* Valid */
183d5015272SBrian Somers         } else {
184d5015272SBrian Somers           CloseSecret(fp);
185d5015272SBrian Somers           return 0;		/* Invalid */
1861ae349f5Scvs2svn         }
1871ae349f5Scvs2svn     }
1881ae349f5Scvs2svn     CloseSecret(fp);
189d5015272SBrian Somers   }
190d5015272SBrian Somers 
191d5015272SBrian Somers #ifndef NOPASSWDAUTH
192d5015272SBrian Somers   if (Enabled(ConfPasswdAuth))
193d5015272SBrian Somers     return auth_CheckPasswd(system, "*", key);
194d5015272SBrian Somers #endif
195d5015272SBrian Somers 
196d5015272SBrian Somers   return 0;			/* Invalid */
1971ae349f5Scvs2svn }
1981ae349f5Scvs2svn 
1991ae349f5Scvs2svn char *
2007a6f8720SBrian Somers AuthGetSecret(struct bundle *bundle, const char *fname, const char *system,
2017a6f8720SBrian Somers               int len, int setaddr, struct physical *physical)
2021ae349f5Scvs2svn {
203d5015272SBrian Somers   /* Used by CHAP routines */
204d5015272SBrian Somers 
2051ae349f5Scvs2svn   FILE *fp;
2061ae349f5Scvs2svn   int n;
2071ae349f5Scvs2svn   char *vector[5];
208d5015272SBrian Somers   static char buff[LINE_LEN];
2091ae349f5Scvs2svn 
2101ae349f5Scvs2svn   fp = OpenSecret(fname);
2111ae349f5Scvs2svn   if (fp == NULL)
2121ae349f5Scvs2svn     return (NULL);
213d5015272SBrian Somers 
2141ae349f5Scvs2svn   while (fgets(buff, sizeof buff, fp)) {
2151ae349f5Scvs2svn     if (buff[0] == '#')
2161ae349f5Scvs2svn       continue;
2171ae349f5Scvs2svn     buff[strlen(buff) - 1] = 0;
2181ae349f5Scvs2svn     memset(vector, '\0', sizeof vector);
2191ae349f5Scvs2svn     n = MakeArgs(buff, vector, VECSIZE(vector));
2201ae349f5Scvs2svn     if (n < 2)
2211ae349f5Scvs2svn       continue;
2221ae349f5Scvs2svn     if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
22329e275ceSBrian Somers       if (setaddr)
2245828db6dSBrian Somers 	memset(&bundle->ncp.ipcp.cfg.peer_range, '\0',
2255828db6dSBrian Somers                sizeof bundle->ncp.ipcp.cfg.peer_range);
2261ae349f5Scvs2svn       if (n > 2 && setaddr)
2277a6f8720SBrian Somers 	if (UseHisaddr(bundle, vector[2], 1))
2287a6f8720SBrian Somers           /* XXX This should be deferred - we may join an existing bundle ! */
2295828db6dSBrian Somers 	  ipcp_Setup(&bundle->ncp.ipcp);
2301ae349f5Scvs2svn         else
2311ae349f5Scvs2svn           return NULL;
2321ae349f5Scvs2svn       if (n > 3)
2331ae349f5Scvs2svn         SetLabel(vector[3]);
234d5015272SBrian Somers       return vector[1];
2351ae349f5Scvs2svn     }
2361ae349f5Scvs2svn   }
2371ae349f5Scvs2svn   CloseSecret(fp);
2381ae349f5Scvs2svn   return (NULL);		/* Invalid */
2391ae349f5Scvs2svn }
2401ae349f5Scvs2svn 
2411ae349f5Scvs2svn static void
2421ae349f5Scvs2svn AuthTimeout(void *vauthp)
2431ae349f5Scvs2svn {
2441ae349f5Scvs2svn   struct authinfo *authp = (struct authinfo *)vauthp;
2451ae349f5Scvs2svn 
246e2ebb036SBrian Somers   StopTimer(&authp->authtimer);
2471ae349f5Scvs2svn   if (--authp->retry > 0) {
248e2ebb036SBrian Somers     StartTimer(&authp->authtimer);
249e2ebb036SBrian Somers     (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
2501ae349f5Scvs2svn   }
2511ae349f5Scvs2svn }
2521ae349f5Scvs2svn 
2531ae349f5Scvs2svn void
254e2ebb036SBrian Somers authinfo_Init(struct authinfo *authinfo)
2551ae349f5Scvs2svn {
256e2ebb036SBrian Somers   memset(authinfo, '\0', sizeof(struct authinfo));
257e2ebb036SBrian Somers }
2581ae349f5Scvs2svn 
259e2ebb036SBrian Somers void
260e2ebb036SBrian Somers StartAuthChallenge(struct authinfo *authp, struct physical *physical,
261e2ebb036SBrian Somers                    void (*fn)(struct authinfo *, int, struct physical *))
262e2ebb036SBrian Somers {
263e2ebb036SBrian Somers   authp->ChallengeFunc = fn;
26463b73463SBrian Somers   authp->physical = physical;
265e2ebb036SBrian Somers   StopTimer(&authp->authtimer);
266e2ebb036SBrian Somers   authp->authtimer.func = AuthTimeout;
2673b0f8d2eSBrian Somers   authp->authtimer.name = "auth";
268e2ebb036SBrian Somers   authp->authtimer.load = VarRetryTimeout * SECTICKS;
269e2ebb036SBrian Somers   authp->authtimer.state = TIMER_STOPPED;
270e2ebb036SBrian Somers   authp->authtimer.arg = (void *) authp;
2711ae349f5Scvs2svn   authp->retry = 3;
2721ae349f5Scvs2svn   authp->id = 1;
273e2ebb036SBrian Somers   (*authp->ChallengeFunc)(authp, authp->id, physical);
274e2ebb036SBrian Somers   StartTimer(&authp->authtimer);
2751ae349f5Scvs2svn }
2761ae349f5Scvs2svn 
2771ae349f5Scvs2svn void
2781ae349f5Scvs2svn StopAuthTimer(struct authinfo *authp)
2791ae349f5Scvs2svn {
2801ae349f5Scvs2svn   StopTimer(&authp->authtimer);
28163b73463SBrian Somers   authp->physical = NULL;
2821ae349f5Scvs2svn }
283