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 * 20972a1bcfSBrian Somers * $Id: auth.c,v 1.34 1998/12/17 00:28:12 brian Exp $ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai * TODO: 23c3899f8dSAtsushi Murai * o Implement check against with registered IP addresses. 24af57ed9fSAtsushi Murai */ 25972a1bcfSBrian Somers #include <sys/param.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" 435a72b6edSBrian Somers #include "lqr.h" 445a72b6edSBrian Somers #include "hdlc.h" 45af57ed9fSAtsushi Murai #include "ipcp.h" 4653c9f6c0SAtsushi Murai #include "auth.h" 4775240ed1SBrian Somers #include "systems.h" 486140ba11SBrian Somers #include "lcp.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" 56972a1bcfSBrian Somers #ifndef NORADIUS 57972a1bcfSBrian Somers #include "radius.h" 58972a1bcfSBrian Somers #endif 595828db6dSBrian Somers #include "bundle.h" 60af57ed9fSAtsushi Murai 61455aabc3SBrian Somers const char * 62455aabc3SBrian Somers Auth2Nam(u_short auth) 63ed6a16c1SPoul-Henning Kamp { 64455aabc3SBrian Somers switch (auth) { 65455aabc3SBrian Somers case PROTO_PAP: 66455aabc3SBrian Somers return "PAP"; 67455aabc3SBrian Somers case PROTO_CHAP: 68455aabc3SBrian Somers return "CHAP"; 69455aabc3SBrian Somers case 0: 70455aabc3SBrian Somers return "none"; 71d025849cSBrian Somers } 72455aabc3SBrian Somers return "unknown"; 7353c9f6c0SAtsushi Murai } 7453c9f6c0SAtsushi Murai 75d5015272SBrian Somers static int 76d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key) 77d5015272SBrian Somers { 78d5015272SBrian Somers if (!strcmp(data, "*")) { 79d5015272SBrian Somers /* Then look up the real password database */ 80d5015272SBrian Somers struct passwd *pw; 81d5015272SBrian Somers int result; 82d5015272SBrian Somers 83d5015272SBrian Somers result = (pw = getpwnam(name)) && 84d5015272SBrian Somers !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 85d5015272SBrian Somers endpwent(); 86d5015272SBrian Somers return result; 87d5015272SBrian Somers } 88d5015272SBrian Somers 89d5015272SBrian Somers return !strcmp(data, key); 90d5015272SBrian Somers } 91d5015272SBrian Somers 921ae349f5Scvs2svn int 9392b09558SBrian Somers auth_SetPhoneList(const char *name, char *phone, int phonelen) 9492b09558SBrian Somers { 9592b09558SBrian Somers FILE *fp; 9692b09558SBrian Somers int n; 9792b09558SBrian Somers char *vector[6]; 9892b09558SBrian Somers char buff[LINE_LEN]; 9992b09558SBrian Somers 10092b09558SBrian Somers fp = OpenSecret(SECRETFILE); 10192b09558SBrian Somers if (fp != NULL) { 10292b09558SBrian Somers while (fgets(buff, sizeof buff, fp)) { 10392b09558SBrian Somers if (buff[0] == '#') 10492b09558SBrian Somers continue; 10592b09558SBrian Somers buff[strlen(buff) - 1] = '\0'; 10692b09558SBrian Somers memset(vector, '\0', sizeof vector); 10792b09558SBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 10892b09558SBrian Somers if (n < 5) 10992b09558SBrian Somers continue; 11092b09558SBrian Somers if (strcmp(vector[0], name) == 0) { 11192b09558SBrian Somers CloseSecret(fp); 11292b09558SBrian Somers if (*vector[4] == '\0') 11392b09558SBrian Somers return 0; 11492b09558SBrian Somers strncpy(phone, vector[4], phonelen - 1); 11592b09558SBrian Somers phone[phonelen - 1] = '\0'; 11692b09558SBrian Somers return 1; /* Valid */ 11792b09558SBrian Somers } 11892b09558SBrian Somers } 11992b09558SBrian Somers CloseSecret(fp); 12092b09558SBrian Somers } 12192b09558SBrian Somers *phone = '\0'; 12292b09558SBrian Somers return 0; 12392b09558SBrian Somers } 12492b09558SBrian Somers 12592b09558SBrian Somers int 12692b09558SBrian Somers auth_Select(struct bundle *bundle, const char *name) 127944f7098SBrian Somers { 12853c9f6c0SAtsushi Murai FILE *fp; 12953c9f6c0SAtsushi Murai int n; 1301ae349f5Scvs2svn char *vector[5]; 13186e02934SBrian Somers char buff[LINE_LEN]; 13253c9f6c0SAtsushi Murai 133643f4904SBrian Somers if (*name == '\0') { 134972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 135643f4904SBrian Somers return 1; 136643f4904SBrian Somers } 137643f4904SBrian Somers 138972a1bcfSBrian Somers #ifndef NORADIUS 139972a1bcfSBrian Somers if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE) { 140972a1bcfSBrian Somers /* We've got a radius IP - it overrides everything */ 141972a1bcfSBrian Somers if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip)) 142972a1bcfSBrian Somers return 0; 143972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr); 144972a1bcfSBrian Somers /* Continue with ppp.secret in case we've got a new label */ 145972a1bcfSBrian Somers } 146972a1bcfSBrian Somers #endif 147972a1bcfSBrian Somers 148643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 149d5015272SBrian Somers if (fp != NULL) { 15070ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 15153c9f6c0SAtsushi Murai if (buff[0] == '#') 15253c9f6c0SAtsushi Murai continue; 153501f5480SBrian Somers buff[strlen(buff) - 1] = '\0'; 15470ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 155e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 1561ae349f5Scvs2svn if (n < 2) 15753c9f6c0SAtsushi Murai continue; 158501f5480SBrian Somers if (strcmp(vector[0], name) == 0) { 1591ae349f5Scvs2svn CloseSecret(fp); 160972a1bcfSBrian Somers #ifndef NORADIUS 161972a1bcfSBrian Somers if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) { 162972a1bcfSBrian Somers #endif 16392b09558SBrian Somers if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 16492b09558SBrian Somers !ipcp_UseHisaddr(bundle, vector[2], 1)) 165643f4904SBrian Somers return 0; 166972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 167972a1bcfSBrian Somers #ifndef NORADIUS 168972a1bcfSBrian Somers } 169972a1bcfSBrian Somers #endif 17092b09558SBrian Somers if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 17149052c95SBrian Somers bundle_SetLabel(bundle, vector[3]); 172d5015272SBrian Somers return 1; /* Valid */ 17353c9f6c0SAtsushi Murai } 174501f5480SBrian Somers } 17553c9f6c0SAtsushi Murai CloseSecret(fp); 176643f4904SBrian Somers } 177643f4904SBrian Somers 178643f4904SBrian Somers #ifndef NOPASSWDAUTH 179643f4904SBrian Somers /* Let 'em in anyway - they must have been in the passwd file */ 180972a1bcfSBrian Somers ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 181643f4904SBrian Somers return 1; 182643f4904SBrian Somers #else 183972a1bcfSBrian Somers #ifndef NORADIUS 184972a1bcfSBrian Somers if (bundle->radius.valid) 185972a1bcfSBrian Somers return 1; 186972a1bcfSBrian Somers #endif 187972a1bcfSBrian Somers 188972a1bcfSBrian Somers /* Disappeared from ppp.secret ??? */ 189643f4904SBrian Somers return 0; 190643f4904SBrian Somers #endif 19153c9f6c0SAtsushi Murai } 19253c9f6c0SAtsushi Murai 193af57ed9fSAtsushi Murai int 194972a1bcfSBrian Somers auth_Validate(struct bundle *bundle, const char *name, 195643f4904SBrian Somers const char *key, struct physical *physical) 196af57ed9fSAtsushi Murai { 197643f4904SBrian Somers /* Used by PAP routines */ 198643f4904SBrian Somers 199af57ed9fSAtsushi Murai FILE *fp; 200af57ed9fSAtsushi Murai int n; 2019c97abd8SBrian Somers char *vector[5]; 20286e02934SBrian Somers char buff[LINE_LEN]; 203af57ed9fSAtsushi Murai 204972a1bcfSBrian Somers #ifndef NORADIUS 205972a1bcfSBrian Somers if (*bundle->radius.cfg.file) 206972a1bcfSBrian Somers return radius_Authenticate(&bundle->radius, bundle, name, key, NULL); 207972a1bcfSBrian Somers #endif 208972a1bcfSBrian Somers 209643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 210643f4904SBrian Somers if (fp != NULL) { 21170ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 212af57ed9fSAtsushi Murai if (buff[0] == '#') 213af57ed9fSAtsushi Murai continue; 214af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0; 21570ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 216e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 217af57ed9fSAtsushi Murai if (n < 2) 218af57ed9fSAtsushi Murai continue; 219972a1bcfSBrian Somers if (strcmp(vector[0], name) == 0) { 220af57ed9fSAtsushi Murai CloseSecret(fp); 221972a1bcfSBrian Somers return auth_CheckPasswd(name, vector[1], key); 222af57ed9fSAtsushi Murai } 223af57ed9fSAtsushi Murai } 224af57ed9fSAtsushi Murai CloseSecret(fp); 225d5015272SBrian Somers } 226d5015272SBrian Somers 227d5015272SBrian Somers #ifndef NOPASSWDAUTH 2281342caedSBrian Somers if (Enabled(bundle, OPT_PASSWDAUTH)) 229972a1bcfSBrian Somers return auth_CheckPasswd(name, "*", key); 230d5015272SBrian Somers #endif 231d5015272SBrian Somers 232d5015272SBrian Somers return 0; /* Invalid */ 233af57ed9fSAtsushi Murai } 234af57ed9fSAtsushi Murai 235af57ed9fSAtsushi Murai char * 236972a1bcfSBrian Somers auth_GetSecret(struct bundle *bundle, const char *name, int len, 237643f4904SBrian Somers struct physical *physical) 238af57ed9fSAtsushi Murai { 239d5015272SBrian Somers /* Used by CHAP routines */ 240d5015272SBrian Somers 241af57ed9fSAtsushi Murai FILE *fp; 242af57ed9fSAtsushi Murai int n; 2439c97abd8SBrian Somers char *vector[5]; 2442ff64793SBrian Somers static char buff[LINE_LEN]; 245af57ed9fSAtsushi Murai 246643f4904SBrian Somers fp = OpenSecret(SECRETFILE); 247af57ed9fSAtsushi Murai if (fp == NULL) 248af57ed9fSAtsushi Murai return (NULL); 249d5015272SBrian Somers 25070ee81ffSBrian Somers while (fgets(buff, sizeof buff, fp)) { 251af57ed9fSAtsushi Murai if (buff[0] == '#') 252af57ed9fSAtsushi Murai continue; 253af57ed9fSAtsushi Murai buff[strlen(buff) - 1] = 0; 25470ee81ffSBrian Somers memset(vector, '\0', sizeof vector); 255e68d210eSBrian Somers n = MakeArgs(buff, vector, VECSIZE(vector)); 256af57ed9fSAtsushi Murai if (n < 2) 257af57ed9fSAtsushi Murai continue; 258972a1bcfSBrian Somers if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) { 259643f4904SBrian Somers CloseSecret(fp); 260d5015272SBrian Somers return vector[1]; 261af57ed9fSAtsushi Murai } 262af57ed9fSAtsushi Murai } 263af57ed9fSAtsushi Murai CloseSecret(fp); 264af57ed9fSAtsushi Murai return (NULL); /* Invalid */ 265af57ed9fSAtsushi Murai } 26653c9f6c0SAtsushi Murai 26753c9f6c0SAtsushi Murai static void 268b6e82f33SBrian Somers AuthTimeout(void *vauthp) 26953c9f6c0SAtsushi Murai { 270b6e82f33SBrian Somers struct authinfo *authp = (struct authinfo *)vauthp; 27153c9f6c0SAtsushi Murai 272dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 27353c9f6c0SAtsushi Murai if (--authp->retry > 0) { 274dd7e2610SBrian Somers timer_Start(&authp->authtimer); 275e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 27653c9f6c0SAtsushi Murai } 27753c9f6c0SAtsushi Murai } 27853c9f6c0SAtsushi Murai 27953c9f6c0SAtsushi Murai void 280dd7e2610SBrian Somers auth_Init(struct authinfo *authinfo) 28153c9f6c0SAtsushi Murai { 282e2ebb036SBrian Somers memset(authinfo, '\0', sizeof(struct authinfo)); 283cd9647a1SBrian Somers authinfo->cfg.fsmretry = DEF_FSMRETRY; 284e2ebb036SBrian Somers } 28553c9f6c0SAtsushi Murai 286e2ebb036SBrian Somers void 287dd7e2610SBrian Somers auth_StartChallenge(struct authinfo *authp, struct physical *physical, 288e2ebb036SBrian Somers void (*fn)(struct authinfo *, int, struct physical *)) 289e2ebb036SBrian Somers { 290e2ebb036SBrian Somers authp->ChallengeFunc = fn; 29163b73463SBrian Somers authp->physical = physical; 292dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 293e2ebb036SBrian Somers authp->authtimer.func = AuthTimeout; 2943b0f8d2eSBrian Somers authp->authtimer.name = "auth"; 295cd9647a1SBrian Somers authp->authtimer.load = authp->cfg.fsmretry * SECTICKS; 296e2ebb036SBrian Somers authp->authtimer.arg = (void *) authp; 29753c9f6c0SAtsushi Murai authp->retry = 3; 29853c9f6c0SAtsushi Murai authp->id = 1; 299e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, authp->id, physical); 300dd7e2610SBrian Somers timer_Start(&authp->authtimer); 30153c9f6c0SAtsushi Murai } 30253c9f6c0SAtsushi Murai 30353c9f6c0SAtsushi Murai void 304dd7e2610SBrian Somers auth_StopTimer(struct authinfo *authp) 30553c9f6c0SAtsushi Murai { 306dd7e2610SBrian Somers timer_Stop(&authp->authtimer); 30763b73463SBrian Somers authp->physical = NULL; 30853c9f6c0SAtsushi Murai } 309