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