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 * $FreeBSD$ 21 * 22 * TODO: 23 * o Implement check against with registered IP addresses. 24 */ 25 #include <sys/param.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 <termios.h> 35 #include <unistd.h> 36 37 #include "layer.h" 38 #include "mbuf.h" 39 #include "defs.h" 40 #include "log.h" 41 #include "timer.h" 42 #include "fsm.h" 43 #include "iplist.h" 44 #include "throughput.h" 45 #include "slcompress.h" 46 #include "lqr.h" 47 #include "hdlc.h" 48 #include "ipcp.h" 49 #include "auth.h" 50 #include "systems.h" 51 #include "lcp.h" 52 #include "ccp.h" 53 #include "link.h" 54 #include "descriptor.h" 55 #include "chat.h" 56 #include "proto.h" 57 #include "filter.h" 58 #include "mp.h" 59 #ifndef NORADIUS 60 #include "radius.h" 61 #endif 62 #include "cbcp.h" 63 #include "chap.h" 64 #include "async.h" 65 #include "physical.h" 66 #include "datalink.h" 67 #include "bundle.h" 68 69 const char * 70 Auth2Nam(u_short auth, u_char type) 71 { 72 static char chap[10]; 73 74 switch (auth) { 75 case PROTO_PAP: 76 return "PAP"; 77 case PROTO_CHAP: 78 snprintf(chap, sizeof chap, "CHAP 0x%02x", type); 79 return chap; 80 case 0: 81 return "none"; 82 } 83 return "unknown"; 84 } 85 86 static int 87 auth_CheckPasswd(const char *name, const char *data, const char *key) 88 { 89 if (!strcmp(data, "*")) { 90 /* Then look up the real password database */ 91 struct passwd *pw; 92 int result; 93 94 result = (pw = getpwnam(name)) && 95 !strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd); 96 endpwent(); 97 return result; 98 } 99 100 return !strcmp(data, key); 101 } 102 103 int 104 auth_SetPhoneList(const char *name, char *phone, int phonelen) 105 { 106 FILE *fp; 107 int n; 108 char *vector[6]; 109 char buff[LINE_LEN]; 110 111 fp = OpenSecret(SECRETFILE); 112 if (fp != NULL) { 113 while (fgets(buff, sizeof buff, fp)) { 114 if (buff[0] == '#') 115 continue; 116 buff[strlen(buff) - 1] = '\0'; 117 memset(vector, '\0', sizeof vector); 118 n = MakeArgs(buff, vector, VECSIZE(vector)); 119 if (n < 5) 120 continue; 121 if (strcmp(vector[0], name) == 0) { 122 CloseSecret(fp); 123 if (*vector[4] == '\0') 124 return 0; 125 strncpy(phone, vector[4], phonelen - 1); 126 phone[phonelen - 1] = '\0'; 127 return 1; /* Valid */ 128 } 129 } 130 CloseSecret(fp); 131 } 132 *phone = '\0'; 133 return 0; 134 } 135 136 int 137 auth_Select(struct bundle *bundle, const char *name) 138 { 139 FILE *fp; 140 int n; 141 char *vector[5]; 142 char buff[LINE_LEN]; 143 144 if (*name == '\0') { 145 ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 146 return 1; 147 } 148 149 #ifndef NORADIUS 150 if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE) { 151 /* We've got a radius IP - it overrides everything */ 152 if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip)) 153 return 0; 154 ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr); 155 /* Continue with ppp.secret in case we've got a new label */ 156 } 157 #endif 158 159 fp = OpenSecret(SECRETFILE); 160 if (fp != NULL) { 161 while (fgets(buff, sizeof buff, fp)) { 162 if (buff[0] == '#') 163 continue; 164 buff[strlen(buff) - 1] = '\0'; 165 memset(vector, '\0', sizeof vector); 166 n = MakeArgs(buff, vector, VECSIZE(vector)); 167 if (n < 2) 168 continue; 169 if (strcmp(vector[0], name) == 0) { 170 CloseSecret(fp); 171 #ifndef NORADIUS 172 if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) { 173 #endif 174 if (n > 2 && *vector[2] && strcmp(vector[2], "*") && 175 !ipcp_UseHisaddr(bundle, vector[2], 1)) 176 return 0; 177 ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 178 #ifndef NORADIUS 179 } 180 #endif 181 if (n > 3 && *vector[3] && strcmp(vector[3], "*")) 182 bundle_SetLabel(bundle, vector[3]); 183 return 1; /* Valid */ 184 } 185 } 186 CloseSecret(fp); 187 } 188 189 #ifndef NOPASSWDAUTH 190 /* Let 'em in anyway - they must have been in the passwd file */ 191 ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); 192 return 1; 193 #else 194 #ifndef NORADIUS 195 if (bundle->radius.valid) 196 return 1; 197 #endif 198 199 /* Disappeared from ppp.secret ??? */ 200 return 0; 201 #endif 202 } 203 204 int 205 auth_Validate(struct bundle *bundle, const char *name, 206 const char *key, struct physical *physical) 207 { 208 /* Used by PAP routines */ 209 210 FILE *fp; 211 int n; 212 char *vector[5]; 213 char buff[LINE_LEN]; 214 215 fp = OpenSecret(SECRETFILE); 216 if (fp != NULL) { 217 while (fgets(buff, sizeof buff, fp)) { 218 if (buff[0] == '#') 219 continue; 220 buff[strlen(buff) - 1] = 0; 221 memset(vector, '\0', sizeof vector); 222 n = MakeArgs(buff, vector, VECSIZE(vector)); 223 if (n < 2) 224 continue; 225 if (strcmp(vector[0], name) == 0) { 226 CloseSecret(fp); 227 return auth_CheckPasswd(name, vector[1], key); 228 } 229 } 230 CloseSecret(fp); 231 } 232 233 #ifndef NOPASSWDAUTH 234 if (Enabled(bundle, OPT_PASSWDAUTH)) 235 return auth_CheckPasswd(name, "*", key); 236 #endif 237 238 return 0; /* Invalid */ 239 } 240 241 char * 242 auth_GetSecret(struct bundle *bundle, const char *name, int len, 243 struct physical *physical) 244 { 245 /* Used by CHAP routines */ 246 247 FILE *fp; 248 int n; 249 char *vector[5]; 250 static char buff[LINE_LEN]; /* vector[] will point here when returned */ 251 252 fp = OpenSecret(SECRETFILE); 253 if (fp == NULL) 254 return (NULL); 255 256 while (fgets(buff, sizeof buff, fp)) { 257 if (buff[0] == '#') 258 continue; 259 n = strlen(buff) - 1; 260 if (buff[n] == '\n') 261 buff[n] = '\0'; /* Trim the '\n' */ 262 memset(vector, '\0', sizeof vector); 263 n = MakeArgs(buff, vector, VECSIZE(vector)); 264 if (n < 2) 265 continue; 266 if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) { 267 CloseSecret(fp); 268 return vector[1]; 269 } 270 } 271 CloseSecret(fp); 272 return (NULL); /* Invalid */ 273 } 274 275 static void 276 AuthTimeout(void *vauthp) 277 { 278 struct authinfo *authp = (struct authinfo *)vauthp; 279 280 timer_Stop(&authp->authtimer); 281 if (--authp->retry > 0) { 282 authp->id++; 283 (*authp->fn.req)(authp); 284 timer_Start(&authp->authtimer); 285 } else { 286 log_Printf(LogPHASE, "Auth: No response from server\n"); 287 datalink_AuthNotOk(authp->physical->dl); 288 } 289 } 290 291 void 292 auth_Init(struct authinfo *authp, struct physical *p, auth_func req, 293 auth_func success, auth_func failure) 294 { 295 memset(authp, '\0', sizeof(struct authinfo)); 296 authp->cfg.fsm.timeout = DEF_FSMRETRY; 297 authp->cfg.fsm.maxreq = DEF_FSMAUTHTRIES; 298 authp->cfg.fsm.maxtrm = 0; /* not used */ 299 authp->fn.req = req; 300 authp->fn.success = success; 301 authp->fn.failure = failure; 302 authp->physical = p; 303 } 304 305 void 306 auth_StartReq(struct authinfo *authp) 307 { 308 timer_Stop(&authp->authtimer); 309 authp->authtimer.func = AuthTimeout; 310 authp->authtimer.name = "auth"; 311 authp->authtimer.load = authp->cfg.fsm.timeout * SECTICKS; 312 authp->authtimer.arg = (void *)authp; 313 authp->retry = authp->cfg.fsm.maxreq; 314 authp->id = 1; 315 (*authp->fn.req)(authp); 316 timer_Start(&authp->authtimer); 317 } 318 319 void 320 auth_StopTimer(struct authinfo *authp) 321 { 322 timer_Stop(&authp->authtimer); 323 } 324 325 struct mbuf * 326 auth_ReadHeader(struct authinfo *authp, struct mbuf *bp) 327 { 328 int len; 329 330 len = mbuf_Length(bp); 331 if (len >= sizeof authp->in.hdr) { 332 bp = mbuf_Read(bp, (u_char *)&authp->in.hdr, sizeof authp->in.hdr); 333 if (len >= ntohs(authp->in.hdr.length)) 334 return bp; 335 authp->in.hdr.length = htons(0); 336 log_Printf(LogWARN, "auth_ReadHeader: Short packet (%d > %d) !\n", 337 ntohs(authp->in.hdr.length), len); 338 } else { 339 authp->in.hdr.length = htons(0); 340 log_Printf(LogWARN, "auth_ReadHeader: Short packet header (%d > %d) !\n", 341 (int)(sizeof authp->in.hdr), len); 342 } 343 344 mbuf_Free(bp); 345 return NULL; 346 } 347 348 struct mbuf * 349 auth_ReadName(struct authinfo *authp, struct mbuf *bp, int len) 350 { 351 if (len > sizeof authp->in.name - 1) 352 log_Printf(LogWARN, "auth_ReadName: Name too long (%d) !\n", len); 353 else { 354 int mlen = mbuf_Length(bp); 355 356 if (len > mlen) 357 log_Printf(LogWARN, "auth_ReadName: Short packet (%d > %d) !\n", 358 len, mlen); 359 else { 360 bp = mbuf_Read(bp, (u_char *)authp->in.name, len); 361 authp->in.name[len] = '\0'; 362 return bp; 363 } 364 } 365 366 *authp->in.name = '\0'; 367 mbuf_Free(bp); 368 return NULL; 369 } 370