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.26 1998/08/07 18:42:50 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 "cbcp.h" 60 #include "datalink.h" 61 62 static const char *papcodes[] = { "???", "REQUEST", "SUCCESS", "FAILURE" }; 63 64 void 65 pap_SendChallenge(struct authinfo *auth, int papid, struct physical *physical) 66 { 67 struct fsmheader lh; 68 struct mbuf *bp; 69 u_char *cp; 70 int namelen, keylen, plen; 71 72 namelen = strlen(physical->dl->bundle->cfg.auth.name); 73 keylen = strlen(physical->dl->bundle->cfg.auth.key); 74 plen = namelen + keylen + 2; 75 log_Printf(LogDEBUG, "pap_SendChallenge: namelen = %d, keylen = %d\n", 76 namelen, keylen); 77 log_Printf(LogPHASE, "Pap Output: %s ********\n", 78 physical->dl->bundle->cfg.auth.name); 79 if (*physical->dl->bundle->cfg.auth.name == '\0') 80 log_Printf(LogWARN, "Sending empty PAP authname!\n"); 81 lh.code = PAP_REQUEST; 82 lh.id = papid; 83 lh.length = htons(plen + sizeof(struct fsmheader)); 84 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM); 85 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 86 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 87 *cp++ = namelen; 88 memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen); 89 cp += namelen; 90 *cp++ = keylen; 91 memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen); 92 93 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp); 94 } 95 96 static void 97 SendPapCode(int id, int code, const char *message, struct physical *physical) 98 { 99 struct fsmheader lh; 100 struct mbuf *bp; 101 u_char *cp; 102 int plen, mlen; 103 104 lh.code = code; 105 lh.id = id; 106 mlen = strlen(message); 107 plen = mlen + 1; 108 lh.length = htons(plen + sizeof(struct fsmheader)); 109 bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM); 110 memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader)); 111 cp = MBUF_CTOP(bp) + sizeof(struct fsmheader); 112 *cp++ = mlen; 113 memcpy(cp, message, mlen); 114 log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]); 115 hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp); 116 } 117 118 /* 119 * Validate given username and passwrd against with secret table 120 */ 121 static int 122 PapValidate(struct bundle *bundle, u_char *name, u_char *key, 123 struct physical *physical) 124 { 125 int nlen, klen; 126 127 nlen = *name++; 128 klen = *key; 129 *key++ = 0; 130 key[klen] = 0; 131 log_Printf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n", 132 name, nlen, key, klen); 133 134 return auth_Validate(bundle, name, key, physical); 135 } 136 137 void 138 pap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical) 139 { 140 int len = mbuf_Length(bp); 141 struct fsmheader *php; 142 u_char *cp; 143 144 if (len >= sizeof(struct fsmheader)) { 145 php = (struct fsmheader *) MBUF_CTOP(bp); 146 if (len >= ntohs(php->length)) { 147 if (php->code < PAP_REQUEST || php->code > PAP_NAK) 148 php->code = 0; 149 switch (php->code) { 150 case PAP_REQUEST: 151 cp = (u_char *) (php + 1); 152 log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n", 153 papcodes[php->code], *cp, cp + 1); 154 if (PapValidate(bundle, cp, cp + *cp + 1, physical)) { 155 datalink_GotAuthname(physical->dl, cp+1, *cp); 156 SendPapCode(php->id, PAP_ACK, "Greetings!!", physical); 157 physical->link.lcp.auth_ineed = 0; 158 if (Enabled(bundle, OPT_UTMP)) 159 physical_Login(physical, cp + 1); 160 161 if (physical->link.lcp.auth_iwait == 0) 162 /* 163 * Either I didn't need to authenticate, or I've already been 164 * told that I got the answer right. 165 */ 166 datalink_AuthOk(physical->dl); 167 168 } else { 169 SendPapCode(php->id, PAP_NAK, "Login incorrect", physical); 170 datalink_AuthNotOk(physical->dl); 171 } 172 break; 173 case PAP_ACK: 174 auth_StopTimer(&physical->dl->pap); 175 cp = (u_char *) (php + 1); 176 len = *cp++; 177 cp[len] = 0; 178 log_Printf(LogPHASE, "Pap Input: %s (%s)\n", papcodes[php->code], cp); 179 if (physical->link.lcp.auth_iwait == PROTO_PAP) { 180 physical->link.lcp.auth_iwait = 0; 181 if (physical->link.lcp.auth_ineed == 0) 182 /* 183 * We've succeeded in our ``login'' 184 * If we're not expecting the peer to authenticate (or he already 185 * has), proceed to network phase. 186 */ 187 datalink_AuthOk(physical->dl); 188 } 189 break; 190 case PAP_NAK: 191 auth_StopTimer(&physical->dl->pap); 192 cp = (u_char *) (php + 1); 193 len = *cp++; 194 cp[len] = 0; 195 log_Printf(LogPHASE, "Pap Input: %s (%s)\n", papcodes[php->code], cp); 196 datalink_AuthNotOk(physical->dl); 197 break; 198 } 199 } 200 } 201 mbuf_Free(bp); 202 } 203