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 * 205ca5389aSBrian Somers * $Id: auth.c,v 1.27.2.13 1998/03/13 21:07:26 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> 271ae349f5Scvs2svn 2863b73463SBrian Somers #include <assert.h> 29d5015272SBrian Somers #include <pwd.h> 301ae349f5Scvs2svn #include <stdio.h> 311ae349f5Scvs2svn #include <string.h> 326140ba11SBrian Somers #include <termios.h> 331ae349f5Scvs2svn #include <unistd.h> 341ae349f5Scvs2svn 351ae349f5Scvs2svn #include "command.h" 361ae349f5Scvs2svn #include "mbuf.h" 371ae349f5Scvs2svn #include "defs.h" 381ae349f5Scvs2svn #include "timer.h" 391ae349f5Scvs2svn #include "fsm.h" 4029e275ceSBrian Somers #include "iplist.h" 4129e275ceSBrian Somers #include "throughput.h" 421ae349f5Scvs2svn #include "ipcp.h" 431ae349f5Scvs2svn #include "loadalias.h" 441ae349f5Scvs2svn #include "vars.h" 451ae349f5Scvs2svn #include "auth.h" 461ae349f5Scvs2svn #include "systems.h" 476140ba11SBrian Somers #include "lcp.h" 48879ed6faSBrian Somers #include "lqr.h" 496140ba11SBrian Somers #include "hdlc.h" 506140ba11SBrian Somers #include "async.h" 516140ba11SBrian Somers #include "link.h" 5242d4d396SBrian Somers #include "descriptor.h" 538c07a7b2SBrian Somers #include "physical.h" 54b6dec9f0SBrian Somers #include "chat.h" 55455aabc3SBrian Somers #include "lcpproto.h" 565ca5389aSBrian Somers #include "filter.h" 575828db6dSBrian Somers #include "bundle.h" 58455aabc3SBrian Somers 59455aabc3SBrian Somers const char * 60455aabc3SBrian Somers Auth2Nam(u_short auth) 61455aabc3SBrian Somers { 62455aabc3SBrian Somers switch (auth) { 63455aabc3SBrian Somers case PROTO_PAP: 64455aabc3SBrian Somers return "PAP"; 65455aabc3SBrian Somers case PROTO_CHAP: 66455aabc3SBrian Somers return "CHAP"; 67455aabc3SBrian Somers case 0: 68455aabc3SBrian Somers return "none"; 69455aabc3SBrian Somers } 70455aabc3SBrian Somers return "unknown"; 71455aabc3SBrian Somers } 721ae349f5Scvs2svn 731ae349f5Scvs2svn void 741ae349f5Scvs2svn LocalAuthInit() 751ae349f5Scvs2svn { 761ae349f5Scvs2svn if (!(mode&MODE_DAEMON)) 771ae349f5Scvs2svn /* We're allowed in interactive mode */ 781ae349f5Scvs2svn VarLocalAuth = LOCAL_AUTH; 791ae349f5Scvs2svn else if (VarHaveLocalAuthKey) 801ae349f5Scvs2svn VarLocalAuth = *VarLocalAuthKey == '\0' ? LOCAL_AUTH : LOCAL_NO_AUTH; 811ae349f5Scvs2svn else 821ae349f5Scvs2svn switch (LocalAuthValidate(SECRETFILE, VarShortHost, "")) { 831ae349f5Scvs2svn case NOT_FOUND: 841ae349f5Scvs2svn VarLocalAuth = LOCAL_DENY; 851ae349f5Scvs2svn break; 861ae349f5Scvs2svn case VALID: 871ae349f5Scvs2svn VarLocalAuth = LOCAL_AUTH; 881ae349f5Scvs2svn break; 891ae349f5Scvs2svn case INVALID: 901ae349f5Scvs2svn VarLocalAuth = LOCAL_NO_AUTH; 911ae349f5Scvs2svn break; 921ae349f5Scvs2svn } 931ae349f5Scvs2svn } 941ae349f5Scvs2svn 951ae349f5Scvs2svn LOCAL_AUTH_VALID 961ae349f5Scvs2svn LocalAuthValidate(const char *fname, const char *system, const char *key) 971ae349f5Scvs2svn { 981ae349f5Scvs2svn FILE *fp; 991ae349f5Scvs2svn int n; 1001ae349f5Scvs2svn char *vector[3]; 1011ae349f5Scvs2svn char buff[LINE_LEN]; 1021ae349f5Scvs2svn LOCAL_AUTH_VALID rc; 1031ae349f5Scvs2svn 1041ae349f5Scvs2svn rc = NOT_FOUND; /* No system entry */ 1051ae349f5Scvs2svn fp = OpenSecret(fname); 1061ae349f5Scvs2svn if (fp == NULL) 1071ae349f5Scvs2svn return (rc); 1081ae349f5Scvs2svn while (fgets(buff, sizeof buff, fp)) { 1091ae349f5Scvs2svn if (buff[0] == '#') 1101ae349f5Scvs2svn continue; 1111ae349f5Scvs2svn buff[strlen(buff) - 1] = 0; 1121ae349f5Scvs2svn memset(vector, '\0', sizeof vector); 1131ae349f5Scvs2svn n = MakeArgs(buff, vector, VECSIZE(vector)); 1141ae349f5Scvs2svn if (n < 1) 1151ae349f5Scvs2svn continue; 1161ae349f5Scvs2svn if (strcmp(vector[0], system) == 0) { 1171ae349f5Scvs2svn if ((vector[1] == (char *) NULL && (key == NULL || *key == '\0')) || 1181ae349f5Scvs2svn (vector[1] != (char *) NULL && strcmp(vector[1], key) == 0)) { 1191ae349f5Scvs2svn rc = VALID; /* Valid */ 1201ae349f5Scvs2svn } else { 1211ae349f5Scvs2svn rc = INVALID; /* Invalid */ 1221ae349f5Scvs2svn } 1231ae349f5Scvs2svn break; 1241ae349f5Scvs2svn } 1251ae349f5Scvs2svn } 1261ae349f5Scvs2svn CloseSecret(fp); 1271ae349f5Scvs2svn return (rc); 1281ae349f5Scvs2svn } 1291ae349f5Scvs2svn 130d5015272SBrian Somers static int 131d5015272SBrian Somers auth_CheckPasswd(const char *name, const char *data, const char *key) 132d5015272SBrian Somers { 133d5015272SBrian Somers if (!strcmp(data, "*")) { 134d5015272SBrian Somers /* Then look up the real password database */ 135d5015272SBrian Somers struct passwd *pw; 136d5015272SBrian Somers int result; 137d5015272SBrian Somers 138d5015272SBrian Somers result = (pw = getpwnam(name)) && 139d5015272SBrian Somers !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 140d5015272SBrian Somers endpwent(); 141d5015272SBrian Somers return result; 142d5015272SBrian Somers } 143d5015272SBrian Somers 144d5015272SBrian Somers return !strcmp(data, key); 145d5015272SBrian Somers } 146d5015272SBrian Somers 1471ae349f5Scvs2svn int 1487a6f8720SBrian Somers AuthValidate(struct bundle *bundle, const char *fname, const char *system, 1497a6f8720SBrian Somers const char *key, struct physical *physical) 1501ae349f5Scvs2svn { 151d5015272SBrian Somers /* Used by PAP routines */ 152d5015272SBrian Somers 1531ae349f5Scvs2svn FILE *fp; 1541ae349f5Scvs2svn int n; 1551ae349f5Scvs2svn char *vector[5]; 1561ae349f5Scvs2svn char buff[LINE_LEN]; 1571ae349f5Scvs2svn 1581ae349f5Scvs2svn fp = OpenSecret(fname); 159d5015272SBrian Somers if (fp != NULL) { 1601ae349f5Scvs2svn while (fgets(buff, sizeof buff, fp)) { 1611ae349f5Scvs2svn if (buff[0] == '#') 1621ae349f5Scvs2svn continue; 1631ae349f5Scvs2svn buff[strlen(buff) - 1] = 0; 1641ae349f5Scvs2svn memset(vector, '\0', sizeof vector); 1651ae349f5Scvs2svn n = MakeArgs(buff, vector, VECSIZE(vector)); 1661ae349f5Scvs2svn if (n < 2) 1671ae349f5Scvs2svn continue; 168d5015272SBrian Somers if (strcmp(vector[0], system) == 0) 169d5015272SBrian Somers if (auth_CheckPasswd(vector[0], vector[1], key)) { 1701ae349f5Scvs2svn CloseSecret(fp); 1717a6f8720SBrian Somers if (n > 2 && !UseHisaddr(bundle, vector[2], 1)) 1721ae349f5Scvs2svn return (0); 1737a6f8720SBrian Somers /* XXX This should be deferred - we may join an existing bundle ! */ 1745828db6dSBrian Somers ipcp_Setup(&bundle->ncp.ipcp); 1751ae349f5Scvs2svn if (n > 3) 1761ae349f5Scvs2svn SetLabel(vector[3]); 177d5015272SBrian Somers return 1; /* Valid */ 178d5015272SBrian Somers } else { 179d5015272SBrian Somers CloseSecret(fp); 180d5015272SBrian Somers return 0; /* Invalid */ 1811ae349f5Scvs2svn } 1821ae349f5Scvs2svn } 1831ae349f5Scvs2svn CloseSecret(fp); 184d5015272SBrian Somers } 185d5015272SBrian Somers 186d5015272SBrian Somers #ifndef NOPASSWDAUTH 187d5015272SBrian Somers if (Enabled(ConfPasswdAuth)) 188d5015272SBrian Somers return auth_CheckPasswd(system, "*", key); 189d5015272SBrian Somers #endif 190d5015272SBrian Somers 191d5015272SBrian Somers return 0; /* Invalid */ 1921ae349f5Scvs2svn } 1931ae349f5Scvs2svn 1941ae349f5Scvs2svn char * 1957a6f8720SBrian Somers AuthGetSecret(struct bundle *bundle, const char *fname, const char *system, 1967a6f8720SBrian Somers int len, int setaddr, struct physical *physical) 1971ae349f5Scvs2svn { 198d5015272SBrian Somers /* Used by CHAP routines */ 199d5015272SBrian Somers 2001ae349f5Scvs2svn FILE *fp; 2011ae349f5Scvs2svn int n; 2021ae349f5Scvs2svn char *vector[5]; 203d5015272SBrian Somers static char buff[LINE_LEN]; 2041ae349f5Scvs2svn 2051ae349f5Scvs2svn fp = OpenSecret(fname); 2061ae349f5Scvs2svn if (fp == NULL) 2071ae349f5Scvs2svn return (NULL); 208d5015272SBrian Somers 2091ae349f5Scvs2svn while (fgets(buff, sizeof buff, fp)) { 2101ae349f5Scvs2svn if (buff[0] == '#') 2111ae349f5Scvs2svn continue; 2121ae349f5Scvs2svn buff[strlen(buff) - 1] = 0; 2131ae349f5Scvs2svn memset(vector, '\0', sizeof vector); 2141ae349f5Scvs2svn n = MakeArgs(buff, vector, VECSIZE(vector)); 2151ae349f5Scvs2svn if (n < 2) 2161ae349f5Scvs2svn continue; 2171ae349f5Scvs2svn if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) { 21829e275ceSBrian Somers if (setaddr) 2195828db6dSBrian Somers memset(&bundle->ncp.ipcp.cfg.peer_range, '\0', 2205828db6dSBrian Somers sizeof bundle->ncp.ipcp.cfg.peer_range); 2211ae349f5Scvs2svn if (n > 2 && setaddr) 2227a6f8720SBrian Somers if (UseHisaddr(bundle, vector[2], 1)) 2237a6f8720SBrian Somers /* XXX This should be deferred - we may join an existing bundle ! */ 2245828db6dSBrian Somers ipcp_Setup(&bundle->ncp.ipcp); 2251ae349f5Scvs2svn else 2261ae349f5Scvs2svn return NULL; 2271ae349f5Scvs2svn if (n > 3) 2281ae349f5Scvs2svn SetLabel(vector[3]); 229d5015272SBrian Somers return vector[1]; 2301ae349f5Scvs2svn } 2311ae349f5Scvs2svn } 2321ae349f5Scvs2svn CloseSecret(fp); 2331ae349f5Scvs2svn return (NULL); /* Invalid */ 2341ae349f5Scvs2svn } 2351ae349f5Scvs2svn 2361ae349f5Scvs2svn static void 2371ae349f5Scvs2svn AuthTimeout(void *vauthp) 2381ae349f5Scvs2svn { 2391ae349f5Scvs2svn struct authinfo *authp = (struct authinfo *)vauthp; 2401ae349f5Scvs2svn 241e2ebb036SBrian Somers StopTimer(&authp->authtimer); 2421ae349f5Scvs2svn if (--authp->retry > 0) { 243e2ebb036SBrian Somers StartTimer(&authp->authtimer); 244e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 2451ae349f5Scvs2svn } 2461ae349f5Scvs2svn } 2471ae349f5Scvs2svn 2481ae349f5Scvs2svn void 249e2ebb036SBrian Somers authinfo_Init(struct authinfo *authinfo) 2501ae349f5Scvs2svn { 251e2ebb036SBrian Somers memset(authinfo, '\0', sizeof(struct authinfo)); 252e2ebb036SBrian Somers } 2531ae349f5Scvs2svn 254e2ebb036SBrian Somers void 255e2ebb036SBrian Somers StartAuthChallenge(struct authinfo *authp, struct physical *physical, 256e2ebb036SBrian Somers void (*fn)(struct authinfo *, int, struct physical *)) 257e2ebb036SBrian Somers { 258e2ebb036SBrian Somers authp->ChallengeFunc = fn; 25963b73463SBrian Somers authp->physical = physical; 260e2ebb036SBrian Somers StopTimer(&authp->authtimer); 261e2ebb036SBrian Somers authp->authtimer.func = AuthTimeout; 262e2ebb036SBrian Somers authp->authtimer.load = VarRetryTimeout * SECTICKS; 263e2ebb036SBrian Somers authp->authtimer.state = TIMER_STOPPED; 264e2ebb036SBrian Somers authp->authtimer.arg = (void *) authp; 2651ae349f5Scvs2svn authp->retry = 3; 2661ae349f5Scvs2svn authp->id = 1; 267e2ebb036SBrian Somers (*authp->ChallengeFunc)(authp, authp->id, physical); 268e2ebb036SBrian Somers StartTimer(&authp->authtimer); 2691ae349f5Scvs2svn } 2701ae349f5Scvs2svn 2711ae349f5Scvs2svn void 2721ae349f5Scvs2svn StopAuthTimer(struct authinfo *authp) 2731ae349f5Scvs2svn { 2741ae349f5Scvs2svn StopTimer(&authp->authtimer); 27563b73463SBrian Somers authp->physical = NULL; 2761ae349f5Scvs2svn } 277