1 /* 2 * PPP Secret Key Module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $Id: auth.c,v 1.30 1998/06/15 19:06:35 brian Exp $ 21 * 22 * TODO: 23 * o Implement check against with registered IP addresses. 24 */ 25 #include <sys/types.h> 26 #include <netinet/in.h> 27 #include <netinet/in_systm.h> 28 #include <netinet/ip.h> 29 #include <sys/un.h> 30 31 #include <pwd.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <unistd.h> 35 36 #include "mbuf.h" 37 #include "defs.h" 38 #include "timer.h" 39 #include "fsm.h" 40 #include "iplist.h" 41 #include "throughput.h" 42 #include "slcompress.h" 43 #include "ipcp.h" 44 #include "auth.h" 45 #include "systems.h" 46 #include "lcp.h" 47 #include "lqr.h" 48 #include "hdlc.h" 49 #include "ccp.h" 50 #include "link.h" 51 #include "descriptor.h" 52 #include "chat.h" 53 #include "lcpproto.h" 54 #include "filter.h" 55 #include "mp.h" 56 #include "bundle.h" 57 58 const char * 59 Auth2Nam(u_short auth) 60 { 61 switch (auth) { 62 case PROTO_PAP: 63 return "PAP"; 64 case PROTO_CHAP: 65 return "CHAP"; 66 case 0: 67 return "none"; 68 } 69 return "unknown"; 70 } 71 72 static int 73 auth_CheckPasswd(const char *name, const char *data, const char *key) 74 { 75 if (!strcmp(data, "*")) { 76 /* Then look up the real password database */ 77 struct passwd *pw; 78 int result; 79 80 result = (pw = getpwnam(name)) && 81 !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 82 endpwent(); 83 return result; 84 } 85 86 return !strcmp(data, key); 87 } 88 89 int 90 auth_Select(struct bundle *bundle, const char *name, struct physical *physical) 91 { 92 FILE *fp; 93 int n; 94 char *vector[5]; 95 char buff[LINE_LEN]; 96 97 if (*name == '\0') { 98 ipcp_Setup(&bundle->ncp.ipcp); 99 return 1; 100 } 101 102 fp = OpenSecret(SECRETFILE); 103 if (fp != NULL) { 104 while (fgets(buff, sizeof buff, fp)) { 105 if (buff[0] == '#') 106 continue; 107 buff[strlen(buff) - 1] = '\0'; 108 memset(vector, '\0', sizeof vector); 109 n = MakeArgs(buff, vector, VECSIZE(vector)); 110 if (n < 2) 111 continue; 112 if (strcmp(vector[0], name) == 0) { 113 CloseSecret(fp); 114 if (n > 2 && !ipcp_UseHisaddr(bundle, vector[2], 1)) 115 return 0; 116 ipcp_Setup(&bundle->ncp.ipcp); 117 if (n > 3) 118 bundle_SetLabel(bundle, vector[3]); 119 return 1; /* Valid */ 120 } 121 } 122 CloseSecret(fp); 123 } 124 125 #ifndef NOPASSWDAUTH 126 /* Let 'em in anyway - they must have been in the passwd file */ 127 ipcp_Setup(&bundle->ncp.ipcp); 128 return 1; 129 #else 130 /* Disappeared from ppp.secret ? */ 131 return 0; 132 #endif 133 } 134 135 int 136 auth_Validate(struct bundle *bundle, const char *system, 137 const char *key, struct physical *physical) 138 { 139 /* Used by PAP routines */ 140 141 FILE *fp; 142 int n; 143 char *vector[5]; 144 char buff[LINE_LEN]; 145 146 fp = OpenSecret(SECRETFILE); 147 if (fp != NULL) { 148 while (fgets(buff, sizeof buff, fp)) { 149 if (buff[0] == '#') 150 continue; 151 buff[strlen(buff) - 1] = 0; 152 memset(vector, '\0', sizeof vector); 153 n = MakeArgs(buff, vector, VECSIZE(vector)); 154 if (n < 2) 155 continue; 156 if (strcmp(vector[0], system) == 0) { 157 CloseSecret(fp); 158 return auth_CheckPasswd(vector[0], vector[1], key); 159 } 160 } 161 CloseSecret(fp); 162 } 163 164 #ifndef NOPASSWDAUTH 165 if (Enabled(bundle, OPT_PASSWDAUTH)) 166 return auth_CheckPasswd(system, "*", key); 167 #endif 168 169 return 0; /* Invalid */ 170 } 171 172 char * 173 auth_GetSecret(struct bundle *bundle, const char *system, int len, 174 struct physical *physical) 175 { 176 /* Used by CHAP routines */ 177 178 FILE *fp; 179 int n; 180 char *vector[5]; 181 char buff[LINE_LEN]; 182 183 fp = OpenSecret(SECRETFILE); 184 if (fp == NULL) 185 return (NULL); 186 187 while (fgets(buff, sizeof buff, fp)) { 188 if (buff[0] == '#') 189 continue; 190 buff[strlen(buff) - 1] = 0; 191 memset(vector, '\0', sizeof vector); 192 n = MakeArgs(buff, vector, VECSIZE(vector)); 193 if (n < 2) 194 continue; 195 if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) { 196 CloseSecret(fp); 197 return vector[1]; 198 } 199 } 200 CloseSecret(fp); 201 return (NULL); /* Invalid */ 202 } 203 204 static void 205 AuthTimeout(void *vauthp) 206 { 207 struct authinfo *authp = (struct authinfo *)vauthp; 208 209 timer_Stop(&authp->authtimer); 210 if (--authp->retry > 0) { 211 timer_Start(&authp->authtimer); 212 (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 213 } 214 } 215 216 void 217 auth_Init(struct authinfo *authinfo) 218 { 219 memset(authinfo, '\0', sizeof(struct authinfo)); 220 authinfo->cfg.fsmretry = DEF_FSMRETRY; 221 } 222 223 void 224 auth_StartChallenge(struct authinfo *authp, struct physical *physical, 225 void (*fn)(struct authinfo *, int, struct physical *)) 226 { 227 authp->ChallengeFunc = fn; 228 authp->physical = physical; 229 timer_Stop(&authp->authtimer); 230 authp->authtimer.func = AuthTimeout; 231 authp->authtimer.name = "auth"; 232 authp->authtimer.load = authp->cfg.fsmretry * SECTICKS; 233 authp->authtimer.arg = (void *) authp; 234 authp->retry = 3; 235 authp->id = 1; 236 (*authp->ChallengeFunc)(authp, authp->id, physical); 237 timer_Start(&authp->authtimer); 238 } 239 240 void 241 auth_StopTimer(struct authinfo *authp) 242 { 243 timer_Stop(&authp->authtimer); 244 authp->physical = NULL; 245 } 246