1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Secret Key Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 2092b09558SBrian Somers * $Id: auth.c,v 1.31 1998/07/19 21:07:24 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23c3899f8dSAtsushi Murai * o Implement check against with registered IP addresses. 24af57ed9fSAtsushi Murai */ 252764b86aSBrian Somers #include <sys/types.h> 2675240ed1SBrian Somers #include <netinet/in.h> 27eaa4df37SBrian Somers #include <netinet/in_systm.h> 28eaa4df37SBrian Somers #include <netinet/ip.h> 291fa665f5SBrian Somers #include <sys/un.h> 3075240ed1SBrian Somers 31d5015272SBrian Somers #include <pwd.h> 3275240ed1SBrian Somers #include <stdio.h> 3375240ed1SBrian Somers #include <string.h> 3475240ed1SBrian Somers #include <unistd.h> 3575240ed1SBrian Somers 3675240ed1SBrian Somers #include "mbuf.h" 3775240ed1SBrian Somers #include "defs.h" 3875240ed1SBrian Somers #include "timer.h" 39af57ed9fSAtsushi Murai #include "fsm.h" 4029e275ceSBrian Somers #include "iplist.h" 4129e275ceSBrian Somers #include "throughput.h" 42eaa4df37SBrian Somers #include "slcompress.h" 43af57ed9fSAtsushi Murai #include "ipcp.h" 4453c9f6c0SAtsushi Murai #include "auth.h" 4575240ed1SBrian Somers #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" 57af57ed9fSAtsushi Murai 58455aabc3SBrian Somers const char * 59455aabc3SBrian Somers Auth2Nam(u_short auth) 60ed6a16c1SPoul-Henning Kamp { 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"; 68d025849cSBrian Somers } 69455aabc3SBrian Somers return "unknown"; 7053c9f6c0SAtsushi Murai } 7153c9f6c0SAtsushi Murai 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 9092b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen) 9192b09558SBrian Somers { 9292b09558SBrian Somers FILE *fp; 9392b09558SBrian Somers int n; 9492b09558SBrian Somers char *vector[6]; 9592b09558SBrian Somers char buff[LINE_LEN]; 9692b09558SBrian Somers 9792b09558SBrian Somers fp = OpenSecret(SECRETFILE); 9892b09558SBrian Somers if (fp != NULL) { 9992b09558SBrian Somers while (fgets(buff, sizeof buff, fp)) { 10092b09558SBrian Somers if (buff[0] == '#') 10192b09558SBrian Somers continue; 10292b09558SBrian Somers buff[strlen(buff) - 1] = '\0'; 10392b09558SBrian Somers memset(vector, '\0', sizeof vector); 10492b09558SBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 10592b09558SBrian Somers if (n < 5) 10692b09558SBrian Somers continue; 10792b09558SBrian Somers if (strcmp(vector[0], name) == 0) { 10892b09558SBrian Somers CloseSecret(fp); 10992b09558SBrian Somers if (*vector[4] == '\0') 11092b09558SBrian Somers return 0; 11192b09558SBrian Somers strncpy(phone, vector[4], phonelen - 1); 11292b09558SBrian Somers phone[phonelen - 1] = '\0'; 11392b09558SBrian Somers return 1; /* Valid */ 11492b09558SBrian Somers } 11592b09558SBrian Somers } 11692b09558SBrian Somers CloseSecret(fp); 11792b09558SBrian Somers } 11892b09558SBrian Somers *phone = '\0'; 11992b09558SBrian Somers return 0; 12092b09558SBrian Somers } 12192b09558SBrian Somers 12292b09558SBrian Somers int 12392b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name) 124944f7098SBrian Somers { 12553c9f6c0SAtsushi Murai FILE *fp; 12653c9f6c0SAtsushi Murai int n; 1271ae349f5Scvs2svn char *vector[5]; 12886e02934SBrian Somers char buff[LINE_LEN]; 12953c9f6c0SAtsushi Murai 130643f4904SBrian Somers if (*name == '\0') { 131643f4904SBrian Somers ipcp_Setup(&bundle->ncp.ipcp); 132643f4904SBrian Somers return 1; 133643f4904SBrian Somers } 134643f4904SBrian Somers 135643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 136d5015272SBrian Somers if (fp != NULL) { 13770ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 13853c9f6c0SAtsushi Murai if (buff[0] == '#') 13953c9f6c0SAtsushi Murai continue; 140501f5480SBrian Somers buff[strlen(buff) - 1] = '\0'; 14170ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 142e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 1431ae349f5Scvs2svn if (n < 2) 14453c9f6c0SAtsushi Murai continue; 145501f5480SBrian Somers if (strcmp(vector[0], name) == 0) { 1461ae349f5Scvs2svn CloseSecret(fp); 14792b09558SBrian Somers if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 14892b09558SBrian Somers !ipcp_UseHisaddr(bundle, vector[2], 1)) 149643f4904SBrian Somers return 0; 1505828db6dSBrian Somers ipcp_Setup(&bundle->ncp.ipcp); 15192b09558SBrian Somers if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 15249052c95SBrian Somers bundle_SetLabel(bundle, vector[3]); 153d5015272SBrian Somers return 1; /* Valid */ 15453c9f6c0SAtsushi Murai } 155501f5480SBrian Somers } 15653c9f6c0SAtsushi Murai CloseSecret(fp); 157643f4904SBrian Somers } 158643f4904SBrian Somers 159643f4904SBrian Somers #ifndef NOPASSWDAUTH 160643f4904SBrian Somers /* Let 'em in anyway - they must have been in the passwd file */ 161643f4904SBrian Somers ipcp_Setup(&bundle->ncp.ipcp); 162643f4904SBrian Somers return 1; 163643f4904SBrian Somers #else 164643f4904SBrian Somers /* Disappeared from ppp.secret ? */ 165643f4904SBrian Somers return 0; 166643f4904SBrian Somers #endif 16753c9f6c0SAtsushi Murai } 16853c9f6c0SAtsushi Murai 169af57ed9fSAtsushi Murai int 170dd7e2610SBrian Somers auth_Validate(struct bundle *bundle, const char *system, 171643f4904SBrian Somers const char *key, struct physical *physical) 172af57ed9fSAtsushi Murai { 173643f4904SBrian Somers /* Used by PAP routines */ 174643f4904SBrian Somers 175af57ed9fSAtsushi Murai FILE *fp; 176af57ed9fSAtsushi Murai int n; 1779c97abd8SBrian Somers char *vector[5]; 17886e02934SBrian Somers char buff[LINE_LEN]; 179af57ed9fSAtsushi Murai 180643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 181643f4904SBrian Somers if (fp != NULL) { 18270ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 183af57ed9fSAtsushi Murai if (buff[0] == '#') 184af57ed9fSAtsushi Murai continue; 185af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0; 18670ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 187e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 188af57ed9fSAtsushi Murai if (n < 2) 189af57ed9fSAtsushi Murai continue; 190af57ed9fSAtsushi Murai if (strcmp(vector[0], system) == 0) { 191af57ed9fSAtsushi Murai CloseSecret(fp); 192643f4904SBrian Somers return auth_CheckPasswd(vector[0], vector[1], key); 193af57ed9fSAtsushi Murai } 194af57ed9fSAtsushi Murai } 195af57ed9fSAtsushi Murai CloseSecret(fp); 196d5015272SBrian Somers } 197d5015272SBrian Somers 198d5015272SBrian Somers #ifndef NOPASSWDAUTH 1991342caedSBrian Somers if (Enabled(bundle, OPT_PASSWDAUTH)) 200d5015272SBrian Somers return auth_CheckPasswd(system, "*", key); 201d5015272SBrian Somers #endif 202d5015272SBrian Somers 203d5015272SBrian Somers return 0; /* Invalid */ 204af57ed9fSAtsushi Murai } 205af57ed9fSAtsushi Murai 206af57ed9fSAtsushi Murai char * 207dd7e2610SBrian Somers auth_GetSecret(struct bundle *bundle, const char *system, int len, 208643f4904SBrian Somers struct physical *physical) 209af57ed9fSAtsushi Murai { 210d5015272SBrian Somers /* Used by CHAP routines */ 211d5015272SBrian Somers 212af57ed9fSAtsushi Murai FILE *fp; 213af57ed9fSAtsushi Murai int n; 2149c97abd8SBrian Somers char *vector[5]; 215d93d3a9cSBrian Somers char buff[LINE_LEN]; 216af57ed9fSAtsushi Murai 217643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 218af57ed9fSAtsushi Murai if (fp == NULL) 219af57ed9fSAtsushi Murai return (NULL); 220d5015272SBrian Somers 22170ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 222af57ed9fSAtsushi Murai if (buff[0] == '#') 223af57ed9fSAtsushi Murai continue; 224af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0; 22570ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 226e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 227af57ed9fSAtsushi Murai if (n < 2) 228af57ed9fSAtsushi Murai continue; 229af57ed9fSAtsushi Murai if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) { 230643f4904SBrian Somers CloseSecret(fp); 231d5015272SBrian Somers return vector[1]; 232af57ed9fSAtsushi Murai } 233af57ed9fSAtsushi Murai } 234af57ed9fSAtsushi Murai CloseSecret(fp); 235af57ed9fSAtsushi Murai return (NULL); /* Invalid */ 236af57ed9fSAtsushi Murai } 23753c9f6c0SAtsushi Murai 23853c9f6c0SAtsushi Murai static void 239b6e82f33SBrian Somers AuthTimeout(void *vauthp) 24053c9f6c0SAtsushi Murai { 241b6e82f33SBrian Somers struct authinfo *authp = (struct authinfo *)vauthp; 24253c9f6c0SAtsushi Murai 243dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 24453c9f6c0SAtsushi Murai if (--authp->retry > 0) { 245dd7e2610SBrian Somers timer_Start(&authp->authtimer); 246e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 24753c9f6c0SAtsushi Murai } 24853c9f6c0SAtsushi Murai } 24953c9f6c0SAtsushi Murai 25053c9f6c0SAtsushi Murai void 251dd7e2610SBrian Somers auth_Init(struct authinfo *authinfo) 25253c9f6c0SAtsushi Murai { 253e2ebb036SBrian Somers memset(authinfo, '\0', sizeof(struct authinfo)); 254cd9647a1SBrian Somers authinfo->cfg.fsmretry = DEF_FSMRETRY; 255e2ebb036SBrian Somers } 25653c9f6c0SAtsushi Murai 257e2ebb036SBrian Somers void 258dd7e2610SBrian Somers auth_StartChallenge(struct authinfo *authp, struct physical *physical, 259e2ebb036SBrian Somers void (*fn)(struct authinfo *, int, struct physical *)) 260e2ebb036SBrian Somers { 261e2ebb036SBrian Somers authp->ChallengeFunc = fn; 26263b73463SBrian Somers authp->physical = physical; 263dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 264e2ebb036SBrian Somers authp->authtimer.func = AuthTimeout; 2653b0f8d2eSBrian Somers authp->authtimer.name = "auth"; 266cd9647a1SBrian Somers authp->authtimer.load = authp->cfg.fsmretry * SECTICKS; 267e2ebb036SBrian Somers authp->authtimer.arg = (void *) authp; 26853c9f6c0SAtsushi Murai authp->retry = 3; 26953c9f6c0SAtsushi Murai authp->id = 1; 270e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, authp->id, physical); 271dd7e2610SBrian Somers timer_Start(&authp->authtimer); 27253c9f6c0SAtsushi Murai } 27353c9f6c0SAtsushi Murai 27453c9f6c0SAtsushi Murai void 275dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp) 27653c9f6c0SAtsushi Murai { 277dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 27863b73463SBrian Somers authp->physical = NULL; 27953c9f6c0SAtsushi Murai } 280