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.4 1996/01/30 11:08:45 dfr Exp $ 22 * 23 * TODO: 24 */ 25 #include "fsm.h" 26 #include "lcp.h" 27 #include "pap.h" 28 #include "vars.h" 29 #include "hdlc.h" 30 #include "lcpproto.h" 31 #include "phase.h" 32 #include "auth.h" 33 34 static char *papcodes[] = { 35 "???", "REQUEST", "ACK", "NAK" 36 }; 37 38 struct authinfo AuthPapInfo = { 39 SendPapChallenge, 40 }; 41 42 void 43 SendPapChallenge(papid) 44 int papid; 45 { 46 struct fsmheader lh; 47 struct mbuf *bp; 48 u_char *cp; 49 int namelen, keylen, plen; 50 51 namelen = strlen(VarAuthName); 52 keylen = strlen(VarAuthKey); 53 plen = namelen + keylen + 2; 54 #ifdef DEBUG 55 logprintf("namelen = %d, keylen = %d\n", namelen, keylen); 56 #endif 57 LogPrintf(LOG_PHASE_BIT, "PAP: %s (%s)\n", VarAuthName, VarAuthKey); 58 lh.code = PAP_REQUEST; 59 lh.id = papid; 60 lh.length = htons(plen + sizeof(struct fsmheader)); 61 bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM); 62 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 63 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 64 *cp++ = namelen; 65 bcopy(VarAuthName, cp, namelen); 66 cp += namelen; 67 *cp++ = keylen; 68 bcopy(VarAuthKey, cp, keylen); 69 70 HdlcOutput(PRI_LINK, PROTO_PAP, bp); 71 } 72 73 static void 74 SendPapCode(id, code, message) 75 int id; 76 char *message; 77 int code; 78 { 79 struct fsmheader lh; 80 struct mbuf *bp; 81 u_char *cp; 82 int plen, mlen; 83 84 lh.code = code; 85 lh.id = id; 86 mlen = strlen(message); 87 plen = mlen + 1; 88 lh.length = htons(plen + sizeof(struct fsmheader)); 89 bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM); 90 bcopy(&lh, MBUF_CTOP(bp), sizeof(struct fsmheader)); 91 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 92 *cp++ = mlen; 93 bcopy(message, cp, mlen); 94 LogPrintf(LOG_PHASE_BIT, "PapOutput: %s\n", papcodes[code]); 95 HdlcOutput(PRI_LINK, PROTO_PAP, bp); 96 } 97 98 /* 99 * Validate given username and passwrd against with secret table 100 */ 101 static int 102 PapValidate(name, key) 103 u_char *name, *key; 104 { 105 int nlen, klen; 106 107 nlen = *name++; 108 klen = *key; 109 *key++ = 0; 110 key[klen] = 0; 111 #ifdef DEBUG 112 logprintf("name: %s (%d), key: %s (%d)\n", name, nlen, key, klen); 113 #endif 114 return(AuthValidate(SECRETFILE, name, key)); 115 } 116 117 void 118 PapInput(bp) 119 struct mbuf *bp; 120 { 121 int len = plength(bp); 122 struct fsmheader *php; 123 struct lcpstate *lcp = &LcpInfo; 124 u_char *cp; 125 126 if (len >= sizeof(struct fsmheader)) { 127 php = (struct fsmheader *)MBUF_CTOP(bp); 128 if (len >= ntohs(php->length)) { 129 if (php->code < PAP_REQUEST || php->code > PAP_NAK) 130 php->code = 0; 131 LogPrintf(LOG_PHASE_BIT, "PapInput: %s\n", papcodes[php->code]); 132 133 switch (php->code) { 134 case PAP_REQUEST: 135 cp = (u_char *) (php + 1); 136 if (PapValidate(cp, cp + *cp + 1)) { 137 SendPapCode(php->id, PAP_ACK, "Greetings!!"); 138 lcp->auth_ineed = 0; 139 if (lcp->auth_iwait == 0) 140 NewPhase(PHASE_NETWORK); 141 } else { 142 SendPapCode(php->id, PAP_NAK, "Login incorrect"); 143 LcpClose(); 144 } 145 break; 146 case PAP_ACK: 147 StopAuthTimer(&AuthPapInfo); 148 cp = (u_char *)(php + 1); 149 len = *cp++; 150 cp[len] = 0; 151 LogPrintf(LOG_PHASE_BIT, "Received PAP_ACK (%s)\n", cp); 152 if (lcp->auth_iwait == PROTO_PAP) { 153 lcp->auth_iwait = 0; 154 if (lcp->auth_ineed == 0) 155 NewPhase(PHASE_NETWORK); 156 } 157 break; 158 case PAP_NAK: 159 StopAuthTimer(&AuthPapInfo); 160 cp = (u_char *)(php + 1); 161 len = *cp++; 162 cp[len] = 0; 163 LogPrintf(LOG_PHASE_BIT, "Received PAP_NAK (%s)\n", cp); 164 LcpClose(); 165 break; 166 } 167 } 168 } 169 pfree(bp); 170 } 171