pap.c revision 37210
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.23 1998/05/21 21:47:18 brian Exp $ 22 * 23 * TODO: 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 <string.h> 32#include <termios.h> 33 34#include "mbuf.h" 35#include "log.h" 36#include "defs.h" 37#include "timer.h" 38#include "fsm.h" 39#include "lcp.h" 40#include "auth.h" 41#include "pap.h" 42#include "lqr.h" 43#include "hdlc.h" 44#include "lcpproto.h" 45#include "async.h" 46#include "throughput.h" 47#include "ccp.h" 48#include "link.h" 49#include "descriptor.h" 50#include "physical.h" 51#include "iplist.h" 52#include "slcompress.h" 53#include "ipcp.h" 54#include "filter.h" 55#include "mp.h" 56#include "bundle.h" 57#include "chat.h" 58#include "chap.h" 59#include "datalink.h" 60 61static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" }; 62 63void 64pap_SendChallenge(struct authinfo *auth, int papid, struct physical *physical) 65{ 66 struct fsmheader lh; 67 struct mbuf *bp; 68 u_char *cp; 69 int namelen, keylen, plen; 70 71 namelen = strlen(physical->dl->bundle->cfg.auth.name); 72 keylen = strlen(physical->dl->bundle->cfg.auth.key); 73 plen = namelen + keylen + 2; 74 log_Printf(LogDEBUG, "pap_SendChallenge: namelen = %d, keylen = %d\n", 75 namelen, keylen); 76 log_Printf(LogPHASE, "PAP: %s\n", physical->dl->bundle->cfg.auth.name); 77 lh.code = PAP_REQUEST; 78 lh.id = papid; 79 lh.length = htons(plen + sizeof(struct fsmheader)); 80 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM); 81 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 82 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 83 *cp++ = namelen; 84 memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen); 85 cp += namelen; 86 *cp++ = keylen; 87 memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen); 88 89 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp); 90} 91 92static void 93SendPapCode(int id, int code, const char *message, struct physical *physical) 94{ 95 struct fsmheader lh; 96 struct mbuf *bp; 97 u_char *cp; 98 int plen, mlen; 99 100 lh.code = code; 101 lh.id = id; 102 mlen = strlen(message); 103 plen = mlen + 1; 104 lh.length = htons(plen + sizeof(struct fsmheader)); 105 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM); 106 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 107 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 108 *cp++ = mlen; 109 memcpy(cp, message, mlen); 110 log_Printf(LogPHASE, "PapOutput: %s\n", papcodes[code]); 111 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp); 112} 113 114/* 115 * Validate given username and passwrd against with secret table 116 */ 117static int 118PapValidate(struct bundle *bundle, u_char *name, u_char *key, 119 struct physical *physical) 120{ 121 int nlen, klen; 122 123 nlen = *name++; 124 klen = *key; 125 *key++ = 0; 126 key[klen] = 0; 127 log_Printf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n", 128 name, nlen, key, klen); 129 130 return auth_Validate(bundle, name, key, physical); 131} 132 133void 134pap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical) 135{ 136 int len = mbuf_Length(bp); 137 struct fsmheader *php; 138 u_char *cp; 139 140 if (len >= sizeof(struct fsmheader)) { 141 php = (struct fsmheader *) MBUF_CTOP(bp); 142 if (len >= ntohs(php->length)) { 143 if (php->code < PAP_REQUEST || php->code > PAP_NAK) 144 php->code = 0; 145 log_Printf(LogPHASE, "pap_Input: %s\n", papcodes[php->code]); 146 147 switch (php->code) { 148 case PAP_REQUEST: 149 cp = (u_char *) (php + 1); 150 if (PapValidate(bundle, cp, cp + *cp + 1, physical)) { 151 datalink_GotAuthname(physical->dl, cp+1, *cp); 152 SendPapCode(php->id, PAP_ACK, "Greetings!!", physical); 153 physical->link.lcp.auth_ineed = 0; 154 if (Enabled(bundle, OPT_UTMP)) 155 physical_Login(physical, cp + 1); 156 157 if (physical->link.lcp.auth_iwait == 0) 158 /* 159 * Either I didn't need to authenticate, or I've already been 160 * told that I got the answer right. 161 */ 162 datalink_AuthOk(physical->dl); 163 164 } else { 165 SendPapCode(php->id, PAP_NAK, "Login incorrect", physical); 166 datalink_AuthNotOk(physical->dl); 167 } 168 break; 169 case PAP_ACK: 170 auth_StopTimer(&physical->dl->pap); 171 cp = (u_char *) (php + 1); 172 len = *cp++; 173 cp[len] = 0; 174 log_Printf(LogPHASE, "Received PAP_ACK (%s)\n", cp); 175 if (physical->link.lcp.auth_iwait == PROTO_PAP) { 176 physical->link.lcp.auth_iwait = 0; 177 if (physical->link.lcp.auth_ineed == 0) 178 /* 179 * We've succeeded in our ``login'' 180 * If we're not expecting the peer to authenticate (or he already 181 * has), proceed to network phase. 182 */ 183 datalink_AuthOk(physical->dl); 184 } 185 break; 186 case PAP_NAK: 187 auth_StopTimer(&physical->dl->pap); 188 cp = (u_char *) (php + 1); 189 len = *cp++; 190 cp[len] = 0; 191 log_Printf(LogPHASE, "Received PAP_NAK (%s)\n", cp); 192 datalink_AuthNotOk(physical->dl); 193 break; 194 } 195 } 196 } 197 mbuf_Free(bp); 198} 199