auth.c revision 41888
16059Samurai/* 26059Samurai * PPP Secret Key Module 36059Samurai * 46059Samurai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 56059Samurai * 66059Samurai * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 76059Samurai * 86059Samurai * Redistribution and use in source and binary forms are permitted 96059Samurai * provided that the above copyright notice and this paragraph are 106059Samurai * duplicated in all such forms and that any documentation, 116059Samurai * advertising materials, and other materials related to such 126059Samurai * distribution and use acknowledge that the software was developed 136059Samurai * by the Internet Initiative Japan, Inc. The name of the 146059Samurai * IIJ may not be used to endorse or promote products derived 156059Samurai * from this software without specific prior written permission. 166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 198857Srgrimes * 2041888Sbrian * $Id: auth.c,v 1.33 1998/08/26 17:39:36 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 2310528Samurai * o Implement check against with registered IP addresses. 246059Samurai */ 2536285Sbrian#include <sys/types.h> 2630715Sbrian#include <netinet/in.h> 2736285Sbrian#include <netinet/in_systm.h> 2836285Sbrian#include <netinet/ip.h> 2936285Sbrian#include <sys/un.h> 3030715Sbrian 3136285Sbrian#include <pwd.h> 3230715Sbrian#include <stdio.h> 3330715Sbrian#include <string.h> 3430715Sbrian#include <unistd.h> 3530715Sbrian 3630715Sbrian#include "mbuf.h" 3730715Sbrian#include "defs.h" 3830715Sbrian#include "timer.h" 396059Samurai#include "fsm.h" 4036285Sbrian#include "iplist.h" 4136285Sbrian#include "throughput.h" 4236285Sbrian#include "slcompress.h" 4338557Sbrian#include "lqr.h" 4438557Sbrian#include "hdlc.h" 456059Samurai#include "ipcp.h" 466735Samurai#include "auth.h" 4736285Sbrian#include "systems.h" 4836285Sbrian#include "lcp.h" 4936285Sbrian#include "ccp.h" 5036285Sbrian#include "link.h" 5136285Sbrian#include "descriptor.h" 5213389Sphk#include "chat.h" 5336285Sbrian#include "lcpproto.h" 5436285Sbrian#include "filter.h" 5536285Sbrian#include "mp.h" 5636285Sbrian#include "bundle.h" 576059Samurai 5836285Sbrianconst char * 5936285SbrianAuth2Nam(u_short auth) 6013389Sphk{ 6136285Sbrian switch (auth) { 6236285Sbrian case PROTO_PAP: 6336285Sbrian return "PAP"; 6436285Sbrian case PROTO_CHAP: 6536285Sbrian return "CHAP"; 6636285Sbrian case 0: 6736285Sbrian return "none"; 6836285Sbrian } 6936285Sbrian return "unknown"; 706735Samurai} 716735Samurai 7236285Sbrianstatic int 7336285Sbrianauth_CheckPasswd(const char *name, const char *data, const char *key) 7428679Sbrian{ 7536285Sbrian if (!strcmp(data, "*")) { 7636285Sbrian /* Then look up the real password database */ 7736285Sbrian struct passwd *pw; 7836285Sbrian int result; 7936285Sbrian 8036285Sbrian result = (pw = getpwnam(name)) && 8136285Sbrian !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 8236285Sbrian endpwent(); 8336285Sbrian return result; 8436285Sbrian } 8536285Sbrian 8636285Sbrian return !strcmp(data, key); 8736285Sbrian} 8836285Sbrian 8936285Sbrianint 9038174Sbrianauth_SetPhoneList(const char *name, char *phone, int phonelen) 9136285Sbrian{ 926735Samurai FILE *fp; 936735Samurai int n; 9438174Sbrian char *vector[6]; 9538174Sbrian char buff[LINE_LEN]; 9638174Sbrian 9738174Sbrian fp = OpenSecret(SECRETFILE); 9838174Sbrian if (fp != NULL) { 9938174Sbrian while (fgets(buff, sizeof buff, fp)) { 10038174Sbrian if (buff[0] == '#') 10138174Sbrian continue; 10238174Sbrian buff[strlen(buff) - 1] = '\0'; 10338174Sbrian memset(vector, '\0', sizeof vector); 10438174Sbrian n = MakeArgs(buff, vector, VECSIZE(vector)); 10538174Sbrian if (n < 5) 10638174Sbrian continue; 10738174Sbrian if (strcmp(vector[0], name) == 0) { 10838174Sbrian CloseSecret(fp); 10938174Sbrian if (*vector[4] == '\0') 11038174Sbrian return 0; 11138174Sbrian strncpy(phone, vector[4], phonelen - 1); 11238174Sbrian phone[phonelen - 1] = '\0'; 11338174Sbrian return 1; /* Valid */ 11438174Sbrian } 11538174Sbrian } 11638174Sbrian CloseSecret(fp); 11738174Sbrian } 11838174Sbrian *phone = '\0'; 11938174Sbrian return 0; 12038174Sbrian} 12138174Sbrian 12238174Sbrianint 12338174Sbrianauth_Select(struct bundle *bundle, const char *name) 12438174Sbrian{ 12538174Sbrian FILE *fp; 12638174Sbrian int n; 12736285Sbrian char *vector[5]; 12831070Sbrian char buff[LINE_LEN]; 1296735Samurai 13036285Sbrian if (*name == '\0') { 13136285Sbrian ipcp_Setup(&bundle->ncp.ipcp); 13236285Sbrian return 1; 13336285Sbrian } 13436285Sbrian 13536285Sbrian fp = OpenSecret(SECRETFILE); 13636285Sbrian if (fp != NULL) { 13736285Sbrian while (fgets(buff, sizeof buff, fp)) { 13836285Sbrian if (buff[0] == '#') 13936285Sbrian continue; 14037763Sbrian buff[strlen(buff) - 1] = '\0'; 14136285Sbrian memset(vector, '\0', sizeof vector); 14236285Sbrian n = MakeArgs(buff, vector, VECSIZE(vector)); 14336285Sbrian if (n < 2) 14436285Sbrian continue; 14537763Sbrian if (strcmp(vector[0], name) == 0) { 14636285Sbrian CloseSecret(fp); 14738174Sbrian if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 14838174Sbrian !ipcp_UseHisaddr(bundle, vector[2], 1)) 14936285Sbrian return 0; 15036285Sbrian ipcp_Setup(&bundle->ncp.ipcp); 15138174Sbrian if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 15236285Sbrian bundle_SetLabel(bundle, vector[3]); 15336285Sbrian return 1; /* Valid */ 15437763Sbrian } 1556735Samurai } 15636285Sbrian CloseSecret(fp); 1576735Samurai } 15836285Sbrian 15936285Sbrian#ifndef NOPASSWDAUTH 16036285Sbrian /* Let 'em in anyway - they must have been in the passwd file */ 16136285Sbrian ipcp_Setup(&bundle->ncp.ipcp); 16236285Sbrian return 1; 16336285Sbrian#else 16436285Sbrian /* Disappeared from ppp.secret ? */ 16536285Sbrian return 0; 16636285Sbrian#endif 1676735Samurai} 1686735Samurai 1696059Samuraiint 17036285Sbrianauth_Validate(struct bundle *bundle, const char *system, 17136285Sbrian const char *key, struct physical *physical) 1726059Samurai{ 17336285Sbrian /* Used by PAP routines */ 17436285Sbrian 1756059Samurai FILE *fp; 1766059Samurai int n; 17732267Sbrian char *vector[5]; 17831070Sbrian char buff[LINE_LEN]; 1796059Samurai 18036285Sbrian fp = OpenSecret(SECRETFILE); 18136285Sbrian if (fp != NULL) { 18236285Sbrian while (fgets(buff, sizeof buff, fp)) { 18336285Sbrian if (buff[0] == '#') 18436285Sbrian continue; 18536285Sbrian buff[strlen(buff) - 1] = 0; 18636285Sbrian memset(vector, '\0', sizeof vector); 18736285Sbrian n = MakeArgs(buff, vector, VECSIZE(vector)); 18836285Sbrian if (n < 2) 18936285Sbrian continue; 19036285Sbrian if (strcmp(vector[0], system) == 0) { 1916059Samurai CloseSecret(fp); 19236285Sbrian return auth_CheckPasswd(vector[0], vector[1], key); 1936059Samurai } 1946059Samurai } 19536285Sbrian CloseSecret(fp); 1966059Samurai } 19736285Sbrian 19836285Sbrian#ifndef NOPASSWDAUTH 19936285Sbrian if (Enabled(bundle, OPT_PASSWDAUTH)) 20036285Sbrian return auth_CheckPasswd(system, "*", key); 20136285Sbrian#endif 20236285Sbrian 20336285Sbrian return 0; /* Invalid */ 2046059Samurai} 2056059Samurai 2066059Samuraichar * 20736285Sbrianauth_GetSecret(struct bundle *bundle, const char *system, int len, 20836285Sbrian struct physical *physical) 2096059Samurai{ 21036285Sbrian /* Used by CHAP routines */ 21136285Sbrian 2126059Samurai FILE *fp; 2136059Samurai int n; 21432267Sbrian char *vector[5]; 21541888Sbrian static char buff[LINE_LEN]; 2166059Samurai 21736285Sbrian fp = OpenSecret(SECRETFILE); 2186059Samurai if (fp == NULL) 21928679Sbrian return (NULL); 22036285Sbrian 22131962Sbrian while (fgets(buff, sizeof buff, fp)) { 2226059Samurai if (buff[0] == '#') 2236059Samurai continue; 22428679Sbrian buff[strlen(buff) - 1] = 0; 22531962Sbrian memset(vector, '\0', sizeof vector); 22625560Sbrian n = MakeArgs(buff, vector, VECSIZE(vector)); 2276059Samurai if (n < 2) 2286059Samurai continue; 2296059Samurai if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) { 23036285Sbrian CloseSecret(fp); 23136285Sbrian return vector[1]; 2326059Samurai } 2336059Samurai } 2346059Samurai CloseSecret(fp); 23528679Sbrian return (NULL); /* Invalid */ 2366059Samurai} 2376735Samurai 2386735Samuraistatic void 23931343SbrianAuthTimeout(void *vauthp) 2406735Samurai{ 24131343Sbrian struct authinfo *authp = (struct authinfo *)vauthp; 2426735Samurai 24336285Sbrian timer_Stop(&authp->authtimer); 2446735Samurai if (--authp->retry > 0) { 24536285Sbrian timer_Start(&authp->authtimer); 24636285Sbrian (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 2476735Samurai } 2486735Samurai} 2496735Samurai 2506735Samuraivoid 25136285Sbrianauth_Init(struct authinfo *authinfo) 2526735Samurai{ 25336285Sbrian memset(authinfo, '\0', sizeof(struct authinfo)); 25436285Sbrian authinfo->cfg.fsmretry = DEF_FSMRETRY; 25536285Sbrian} 2566735Samurai 25736285Sbrianvoid 25836285Sbrianauth_StartChallenge(struct authinfo *authp, struct physical *physical, 25936285Sbrian void (*fn)(struct authinfo *, int, struct physical *)) 26036285Sbrian{ 26136285Sbrian authp->ChallengeFunc = fn; 26236285Sbrian authp->physical = physical; 26336285Sbrian timer_Stop(&authp->authtimer); 26436285Sbrian authp->authtimer.func = AuthTimeout; 26536285Sbrian authp->authtimer.name = "auth"; 26636285Sbrian authp->authtimer.load = authp->cfg.fsmretry * SECTICKS; 26736285Sbrian authp->authtimer.arg = (void *) authp; 2686735Samurai authp->retry = 3; 2696735Samurai authp->id = 1; 27036285Sbrian (*authp->ChallengeFunc)(authp, authp->id, physical); 27136285Sbrian timer_Start(&authp->authtimer); 2726735Samurai} 2736735Samurai 2746735Samuraivoid 27536285Sbrianauth_StopTimer(struct authinfo *authp) 2766735Samurai{ 27736285Sbrian timer_Stop(&authp->authtimer); 27836285Sbrian authp->physical = NULL; 2796735Samurai} 280