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.32 1998/08/07 18:42:47 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 "lqr.h" 44 #include "hdlc.h" 45 #include "ipcp.h" 46 #include "auth.h" 47 #include "systems.h" 48 #include "lcp.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_SetPhoneList(const char *name, char *phone, int phonelen) 91 { 92 FILE *fp; 93 int n; 94 char *vector[6]; 95 char buff[LINE_LEN]; 96 97 fp = OpenSecret(SECRETFILE); 98 if (fp != NULL) { 99 while (fgets(buff, sizeof buff, fp)) { 100 if (buff[0] == '#') 101 continue; 102 buff[strlen(buff) - 1] = '\0'; 103 memset(vector, '\0', sizeof vector); 104 n = MakeArgs(buff, vector, VECSIZE(vector)); 105 if (n < 5) 106 continue; 107 if (strcmp(vector[0], name) == 0) { 108 CloseSecret(fp); 109 if (*vector[4] == '\0') 110 return 0; 111 strncpy(phone, vector[4], phonelen - 1); 112 phone[phonelen - 1] = '\0'; 113 return 1; /* Valid */ 114 } 115 } 116 CloseSecret(fp); 117 } 118 *phone = '\0'; 119 return 0; 120 } 121 122 int 123 auth_Select(struct bundle *bundle, const char *name) 124 { 125 FILE *fp; 126 int n; 127 char *vector[5]; 128 char buff[LINE_LEN]; 129 130 if (*name == '\0') { 131 ipcp_Setup(&bundle->ncp.ipcp); 132 return 1; 133 } 134 135 fp = OpenSecret(SECRETFILE); 136 if (fp != NULL) { 137 while (fgets(buff, sizeof buff, fp)) { 138 if (buff[0] == '#') 139 continue; 140 buff[strlen(buff) - 1] = '\0'; 141 memset(vector, '\0', sizeof vector); 142 n = MakeArgs(buff, vector, VECSIZE(vector)); 143 if (n < 2) 144 continue; 145 if (strcmp(vector[0], name) == 0) { 146 CloseSecret(fp); 147 if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 148 !ipcp_UseHisaddr(bundle, vector[2], 1)) 149 return 0; 150 ipcp_Setup(&bundle->ncp.ipcp); 151 if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 152 bundle_SetLabel(bundle, vector[3]); 153 return 1; /* Valid */ 154 } 155 } 156 CloseSecret(fp); 157 } 158 159 #ifndef NOPASSWDAUTH 160 /* Let 'em in anyway - they must have been in the passwd file */ 161 ipcp_Setup(&bundle->ncp.ipcp); 162 return 1; 163 #else 164 /* Disappeared from ppp.secret ? */ 165 return 0; 166 #endif 167 } 168 169 int 170 auth_Validate(struct bundle *bundle, const char *system, 171 const char *key, struct physical *physical) 172 { 173 /* Used by PAP routines */ 174 175 FILE *fp; 176 int n; 177 char *vector[5]; 178 char buff[LINE_LEN]; 179 180 fp = OpenSecret(SECRETFILE); 181 if (fp != NULL) { 182 while (fgets(buff, sizeof buff, fp)) { 183 if (buff[0] == '#') 184 continue; 185 buff[strlen(buff) - 1] = 0; 186 memset(vector, '\0', sizeof vector); 187 n = MakeArgs(buff, vector, VECSIZE(vector)); 188 if (n < 2) 189 continue; 190 if (strcmp(vector[0], system) == 0) { 191 CloseSecret(fp); 192 return auth_CheckPasswd(vector[0], vector[1], key); 193 } 194 } 195 CloseSecret(fp); 196 } 197 198 #ifndef NOPASSWDAUTH 199 if (Enabled(bundle, OPT_PASSWDAUTH)) 200 return auth_CheckPasswd(system, "*", key); 201 #endif 202 203 return 0; /* Invalid */ 204 } 205 206 char * 207 auth_GetSecret(struct bundle *bundle, const char *system, int len, 208 struct physical *physical) 209 { 210 /* Used by CHAP routines */ 211 212 FILE *fp; 213 int n; 214 char *vector[5]; 215 char buff[LINE_LEN]; 216 217 fp = OpenSecret(SECRETFILE); 218 if (fp == NULL) 219 return (NULL); 220 221 while (fgets(buff, sizeof buff, fp)) { 222 if (buff[0] == '#') 223 continue; 224 buff[strlen(buff) - 1] = 0; 225 memset(vector, '\0', sizeof vector); 226 n = MakeArgs(buff, vector, VECSIZE(vector)); 227 if (n < 2) 228 continue; 229 if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) { 230 CloseSecret(fp); 231 return vector[1]; 232 } 233 } 234 CloseSecret(fp); 235 return (NULL); /* Invalid */ 236 } 237 238 static void 239 AuthTimeout(void *vauthp) 240 { 241 struct authinfo *authp = (struct authinfo *)vauthp; 242 243 timer_Stop(&authp->authtimer); 244 if (--authp->retry > 0) { 245 timer_Start(&authp->authtimer); 246 (*authp->ChallengeFunc)(authp, ++authp->id, authp->physical); 247 } 248 } 249 250 void 251 auth_Init(struct authinfo *authinfo) 252 { 253 memset(authinfo, '\0', sizeof(struct authinfo)); 254 authinfo->cfg.fsmretry = DEF_FSMRETRY; 255 } 256 257 void 258 auth_StartChallenge(struct authinfo *authp, struct physical *physical, 259 void (*fn)(struct authinfo *, int, struct physical *)) 260 { 261 authp->ChallengeFunc = fn; 262 authp->physical = physical; 263 timer_Stop(&authp->authtimer); 264 authp->authtimer.func = AuthTimeout; 265 authp->authtimer.name = "auth"; 266 authp->authtimer.load = authp->cfg.fsmretry * SECTICKS; 267 authp->authtimer.arg = (void *) authp; 268 authp->retry = 3; 269 authp->id = 1; 270 (*authp->ChallengeFunc)(authp, authp->id, physical); 271 timer_Start(&authp->authtimer); 272 } 273 274 void 275 auth_StopTimer(struct authinfo *authp) 276 { 277 timer_Stop(&authp->authtimer); 278 authp->physical = NULL; 279 } 280