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.12 1997/05/26 00:44:08 brian Exp $ 22 * 23 * TODO: 24 */ 25 #include "fsm.h" 26 #include "lcp.h" 27 #include "pap.h" 28 #include "loadalias.h" 29 #include "vars.h" 30 #include "hdlc.h" 31 #include "lcpproto.h" 32 #include "phase.h" 33 #include "auth.h" 34 35 #ifndef NOPASSWDAUTH 36 # include "passwdauth.h" 37 #endif 38 39 static char *papcodes[] = { 40 "???", "REQUEST", "ACK", "NAK" 41 }; 42 43 struct authinfo AuthPapInfo = { 44 SendPapChallenge, 45 }; 46 47 void 48 SendPapChallenge(papid) 49 int papid; 50 { 51 struct fsmheader lh; 52 struct mbuf *bp; 53 u_char *cp; 54 int namelen, keylen, plen; 55 56 namelen = strlen(VarAuthName); 57 keylen = strlen(VarAuthKey); 58 plen = namelen + keylen + 2; 59 LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n", 60 namelen, keylen); 61 LogPrintf(LogPHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey); 62 lh.code = PAP_REQUEST; 63 lh.id = papid; 64 lh.length = htons(plen + sizeof(struct fsmheader)); 65 bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM); 66 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 67 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 68 *cp++ = namelen; 69 bcopy(VarAuthName, cp, namelen); 70 cp += namelen; 71 *cp++ = keylen; 72 bcopy(VarAuthKey, cp, keylen); 73 74 HdlcOutput(PRI_LINK, PROTO_PAP, bp); 75 } 76 77 static void 78 SendPapCode(id, code, message) 79 int id; 80 char *message; 81 int code; 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(name, key) 107 u_char *name, *key; 108 { 109 int nlen, klen; 110 111 nlen = *name++; 112 klen = *key; 113 *key++ = 0; 114 key[klen] = 0; 115 LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n", 116 name, nlen, key, klen); 117 118 #ifndef NOPASSWDAUTH 119 if( Enabled( ConfPasswdAuth ) ) 120 { 121 LogPrintf( LogLCP, "PasswdAuth enabled - calling\n" ); 122 return PasswdAuth( name, key ); 123 } 124 #endif 125 126 return(AuthValidate(SECRETFILE, name, key)); 127 } 128 129 void 130 PapInput(bp) 131 struct mbuf *bp; 132 { 133 int len = plength(bp); 134 struct fsmheader *php; 135 struct lcpstate *lcp = &LcpInfo; 136 u_char *cp; 137 138 if (len >= sizeof(struct fsmheader)) { 139 php = (struct fsmheader *)MBUF_CTOP(bp); 140 if (len >= ntohs(php->length)) { 141 if (php->code < PAP_REQUEST || php->code > PAP_NAK) 142 php->code = 0; 143 LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]); 144 145 switch (php->code) { 146 case PAP_REQUEST: 147 cp = (u_char *) (php + 1); 148 if (PapValidate(cp, cp + *cp + 1)) { 149 SendPapCode(php->id, PAP_ACK, "Greetings!!"); 150 lcp->auth_ineed = 0; 151 if (lcp->auth_iwait == 0) 152 NewPhase(PHASE_NETWORK); 153 } else { 154 SendPapCode(php->id, PAP_NAK, "Login incorrect"); 155 reconnect(RECON_FALSE); 156 LcpClose(); 157 } 158 break; 159 case PAP_ACK: 160 StopAuthTimer(&AuthPapInfo); 161 cp = (u_char *)(php + 1); 162 len = *cp++; 163 cp[len] = 0; 164 LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp); 165 if (lcp->auth_iwait == PROTO_PAP) { 166 lcp->auth_iwait = 0; 167 if (lcp->auth_ineed == 0) 168 NewPhase(PHASE_NETWORK); 169 } 170 break; 171 case PAP_NAK: 172 StopAuthTimer(&AuthPapInfo); 173 cp = (u_char *)(php + 1); 174 len = *cp++; 175 cp[len] = 0; 176 LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp); 177 reconnect(RECON_FALSE); 178 LcpClose(); 179 break; 180 } 181 } 182 } 183 pfree(bp); 184 } 185