1 /* 2 * PPP PAP Module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993-94, Internet Initiative Japan, Inc. 7 * All rights reserverd. 8 * 9 * Redistribution and use in source and binary forms are permitted 10 * provided that the above copyright notice and this paragraph are 11 * duplicated in all such forms and that any documentation, 12 * advertising materials, and other materials related to such 13 * distribution and use acknowledge that the software was developed 14 * by the Internet Initiative Japan, Inc. The name of the 15 * IIJ may not be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * $Id: pap.c,v 1.15 1997/09/22 23:59:15 brian Exp $ 22 * 23 * TODO: 24 */ 25 #include <time.h> 26 #include <utmp.h> 27 #include <pwd.h> 28 #include "fsm.h" 29 #include "lcp.h" 30 #include "pap.h" 31 #include "loadalias.h" 32 #include "vars.h" 33 #include "hdlc.h" 34 #include "lcpproto.h" 35 #include "phase.h" 36 #include "auth.h" 37 #ifdef __OpenBSD__ 38 #include "util.h" 39 #else 40 #include "libutil.h" 41 #endif 42 43 static char *papcodes[] = { 44 "???", "REQUEST", "ACK", "NAK" 45 }; 46 47 struct authinfo AuthPapInfo = { 48 SendPapChallenge, 49 }; 50 51 void 52 SendPapChallenge(int papid) 53 { 54 struct fsmheader lh; 55 struct mbuf *bp; 56 u_char *cp; 57 int namelen, keylen, plen; 58 59 namelen = strlen(VarAuthName); 60 keylen = strlen(VarAuthKey); 61 plen = namelen + keylen + 2; 62 LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n", 63 namelen, keylen); 64 LogPrintf(LogPHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey); 65 lh.code = PAP_REQUEST; 66 lh.id = papid; 67 lh.length = htons(plen + sizeof(struct fsmheader)); 68 bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM); 69 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 70 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 71 *cp++ = namelen; 72 bcopy(VarAuthName, cp, namelen); 73 cp += namelen; 74 *cp++ = keylen; 75 bcopy(VarAuthKey, cp, keylen); 76 77 HdlcOutput(PRI_LINK, PROTO_PAP, bp); 78 } 79 80 static void 81 SendPapCode(int id, int code, char *message) 82 { 83 struct fsmheader lh; 84 struct mbuf *bp; 85 u_char *cp; 86 int plen, mlen; 87 88 lh.code = code; 89 lh.id = id; 90 mlen = strlen(message); 91 plen = mlen + 1; 92 lh.length = htons(plen + sizeof(struct fsmheader)); 93 bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM); 94 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 95 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 96 *cp++ = mlen; 97 bcopy(message, cp, mlen); 98 LogPrintf(LogPHASE, "PapOutput: %s\n", papcodes[code]); 99 HdlcOutput(PRI_LINK, PROTO_PAP, bp); 100 } 101 102 /* 103 * Validate given username and passwrd against with secret table 104 */ 105 static int 106 PapValidate(u_char * name, u_char * key) 107 { 108 int nlen, klen; 109 110 nlen = *name++; 111 klen = *key; 112 *key++ = 0; 113 key[klen] = 0; 114 LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n", 115 name, nlen, key, klen); 116 117 #ifndef NOPASSWDAUTH 118 if (Enabled(ConfPasswdAuth)) { 119 struct passwd *pwd; 120 int result; 121 122 LogPrintf(LogLCP, "Using PasswdAuth\n"); 123 result = (pwd = getpwnam(name)) && 124 !strcmp(crypt(key, pwd->pw_passwd), pwd->pw_passwd); 125 endpwent(); 126 return result; 127 } 128 #endif 129 130 return (AuthValidate(SECRETFILE, name, key)); 131 } 132 133 void 134 PapInput(struct mbuf * bp) 135 { 136 int len = plength(bp); 137 struct fsmheader *php; 138 struct lcpstate *lcp = &LcpInfo; 139 u_char *cp; 140 141 if (len >= sizeof(struct fsmheader)) { 142 php = (struct fsmheader *) MBUF_CTOP(bp); 143 if (len >= ntohs(php->length)) { 144 if (php->code < PAP_REQUEST || php->code > PAP_NAK) 145 php->code = 0; 146 LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]); 147 148 switch (php->code) { 149 case PAP_REQUEST: 150 cp = (u_char *) (php + 1); 151 if (PapValidate(cp, cp + *cp + 1)) { 152 SendPapCode(php->id, PAP_ACK, "Greetings!!"); 153 lcp->auth_ineed = 0; 154 if (lcp->auth_iwait == 0) { 155 if ((mode & MODE_DIRECT) && isatty(modem) && Enabled(ConfUtmp)) 156 if (Utmp) 157 LogPrintf(LogERROR, "Oops, already logged in on %s\n", 158 VarBaseDevice); 159 else { 160 struct utmp ut; 161 memset(&ut, 0, sizeof(ut)); 162 time(&ut.ut_time); 163 strncpy(ut.ut_name, cp+1, sizeof(ut.ut_name)-1); 164 strncpy(ut.ut_line, VarBaseDevice, sizeof(ut.ut_line)-1); 165 if (logout(ut.ut_line)) 166 logwtmp(ut.ut_line, "", ""); 167 login(&ut); 168 Utmp = 1; 169 } 170 NewPhase(PHASE_NETWORK); 171 } 172 } else { 173 SendPapCode(php->id, PAP_NAK, "Login incorrect"); 174 reconnect(RECON_FALSE); 175 LcpClose(); 176 } 177 break; 178 case PAP_ACK: 179 StopAuthTimer(&AuthPapInfo); 180 cp = (u_char *) (php + 1); 181 len = *cp++; 182 cp[len] = 0; 183 LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp); 184 if (lcp->auth_iwait == PROTO_PAP) { 185 lcp->auth_iwait = 0; 186 if (lcp->auth_ineed == 0) 187 NewPhase(PHASE_NETWORK); 188 } 189 break; 190 case PAP_NAK: 191 StopAuthTimer(&AuthPapInfo); 192 cp = (u_char *) (php + 1); 193 len = *cp++; 194 cp[len] = 0; 195 LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp); 196 reconnect(RECON_FALSE); 197 LcpClose(); 198 break; 199 } 200 } 201 } 202 pfree(bp); 203 } 204