xref: /freebsd/usr.sbin/ppp/pap.c (revision eaa4df37f41891389081dc62e17cc172b36b8736)
11ae349f5Scvs2svn /*
21ae349f5Scvs2svn  *			PPP PAP Module
31ae349f5Scvs2svn  *
41ae349f5Scvs2svn  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
51ae349f5Scvs2svn  *
61ae349f5Scvs2svn  *   Copyright (C) 1993-94, Internet Initiative Japan, Inc.
71ae349f5Scvs2svn  *		     All rights reserverd.
81ae349f5Scvs2svn  *
91ae349f5Scvs2svn  * Redistribution and use in source and binary forms are permitted
101ae349f5Scvs2svn  * provided that the above copyright notice and this paragraph are
111ae349f5Scvs2svn  * duplicated in all such forms and that any documentation,
121ae349f5Scvs2svn  * advertising materials, and other materials related to such
131ae349f5Scvs2svn  * distribution and use acknowledge that the software was developed
141ae349f5Scvs2svn  * by the Internet Initiative Japan, Inc.  The name of the
151ae349f5Scvs2svn  * IIJ may not be used to endorse or promote products derived
161ae349f5Scvs2svn  * from this software without specific prior written permission.
171ae349f5Scvs2svn  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
181ae349f5Scvs2svn  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
191ae349f5Scvs2svn  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
201ae349f5Scvs2svn  *
21eaa4df37SBrian Somers  * $Id: pap.c,v 1.20.2.18 1998/03/16 22:52:35 brian Exp $
221ae349f5Scvs2svn  *
231ae349f5Scvs2svn  *	TODO:
241ae349f5Scvs2svn  */
251ae349f5Scvs2svn #include <sys/param.h>
261ae349f5Scvs2svn #include <netinet/in.h>
27eaa4df37SBrian Somers #include <netinet/in_systm.h>
28eaa4df37SBrian Somers #include <netinet/ip.h>
291ae349f5Scvs2svn 
301ae349f5Scvs2svn #include <pwd.h>
311ae349f5Scvs2svn #include <stdio.h>
321ae349f5Scvs2svn #include <string.h>
331ae349f5Scvs2svn #include <time.h>
346140ba11SBrian Somers #include <termios.h>
351ae349f5Scvs2svn #include <unistd.h>
361ae349f5Scvs2svn #ifdef __OpenBSD__
371ae349f5Scvs2svn #include <util.h>
381ae349f5Scvs2svn #else
391ae349f5Scvs2svn #include <libutil.h>
401ae349f5Scvs2svn #endif
411ae349f5Scvs2svn 
421ae349f5Scvs2svn #include "command.h"
431ae349f5Scvs2svn #include "mbuf.h"
441ae349f5Scvs2svn #include "log.h"
451ae349f5Scvs2svn #include "defs.h"
461ae349f5Scvs2svn #include "timer.h"
471ae349f5Scvs2svn #include "fsm.h"
481ae349f5Scvs2svn #include "lcp.h"
49e2ebb036SBrian Somers #include "auth.h"
501ae349f5Scvs2svn #include "pap.h"
511ae349f5Scvs2svn #include "loadalias.h"
521ae349f5Scvs2svn #include "vars.h"
53879ed6faSBrian Somers #include "lqr.h"
541ae349f5Scvs2svn #include "hdlc.h"
551ae349f5Scvs2svn #include "lcpproto.h"
566140ba11SBrian Somers #include "async.h"
576140ba11SBrian Somers #include "throughput.h"
586140ba11SBrian Somers #include "link.h"
5942d4d396SBrian Somers #include "descriptor.h"
6063b73463SBrian Somers #include "physical.h"
615828db6dSBrian Somers #include "iplist.h"
62eaa4df37SBrian Somers #include "slcompress.h"
635828db6dSBrian Somers #include "ipcp.h"
645ca5389aSBrian Somers #include "filter.h"
65455aabc3SBrian Somers #include "bundle.h"
66e2ebb036SBrian Somers #include "chat.h"
67e2ebb036SBrian Somers #include "ccp.h"
68e2ebb036SBrian Somers #include "chap.h"
69e2ebb036SBrian Somers #include "datalink.h"
701ae349f5Scvs2svn 
711ae349f5Scvs2svn static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
721ae349f5Scvs2svn 
73e2ebb036SBrian Somers void
74e2ebb036SBrian Somers SendPapChallenge(struct authinfo *auth, int papid, struct physical *physical)
751ae349f5Scvs2svn {
761ae349f5Scvs2svn   struct fsmheader lh;
771ae349f5Scvs2svn   struct mbuf *bp;
781ae349f5Scvs2svn   u_char *cp;
791ae349f5Scvs2svn   int namelen, keylen, plen;
801ae349f5Scvs2svn 
811ae349f5Scvs2svn   namelen = strlen(VarAuthName);
821ae349f5Scvs2svn   keylen = strlen(VarAuthKey);
831ae349f5Scvs2svn   plen = namelen + keylen + 2;
841ae349f5Scvs2svn   LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n",
851ae349f5Scvs2svn 	    namelen, keylen);
861ae349f5Scvs2svn   if (LogIsKept(LogDEBUG))
871ae349f5Scvs2svn     LogPrintf(LogPHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey);
881ae349f5Scvs2svn   else
891ae349f5Scvs2svn     LogPrintf(LogPHASE, "PAP: %s\n", VarAuthName);
901ae349f5Scvs2svn   lh.code = PAP_REQUEST;
911ae349f5Scvs2svn   lh.id = papid;
921ae349f5Scvs2svn   lh.length = htons(plen + sizeof(struct fsmheader));
931ae349f5Scvs2svn   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
941ae349f5Scvs2svn   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
951ae349f5Scvs2svn   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
961ae349f5Scvs2svn   *cp++ = namelen;
971ae349f5Scvs2svn   memcpy(cp, VarAuthName, namelen);
981ae349f5Scvs2svn   cp += namelen;
991ae349f5Scvs2svn   *cp++ = keylen;
1001ae349f5Scvs2svn   memcpy(cp, VarAuthKey, keylen);
1011ae349f5Scvs2svn 
1028c07a7b2SBrian Somers   HdlcOutput(physical2link(physical), PRI_LINK, PROTO_PAP, bp);
1031ae349f5Scvs2svn }
1041ae349f5Scvs2svn 
1051ae349f5Scvs2svn static void
10663b73463SBrian Somers SendPapCode(int id, int code, const char *message, struct physical *physical)
1071ae349f5Scvs2svn {
1081ae349f5Scvs2svn   struct fsmheader lh;
1091ae349f5Scvs2svn   struct mbuf *bp;
1101ae349f5Scvs2svn   u_char *cp;
1111ae349f5Scvs2svn   int plen, mlen;
1121ae349f5Scvs2svn 
1131ae349f5Scvs2svn   lh.code = code;
1141ae349f5Scvs2svn   lh.id = id;
1151ae349f5Scvs2svn   mlen = strlen(message);
1161ae349f5Scvs2svn   plen = mlen + 1;
1171ae349f5Scvs2svn   lh.length = htons(plen + sizeof(struct fsmheader));
1181ae349f5Scvs2svn   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
1191ae349f5Scvs2svn   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
1201ae349f5Scvs2svn   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
1211ae349f5Scvs2svn   *cp++ = mlen;
1221ae349f5Scvs2svn   memcpy(cp, message, mlen);
1231ae349f5Scvs2svn   LogPrintf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
1248c07a7b2SBrian Somers   HdlcOutput(physical2link(physical), PRI_LINK, PROTO_PAP, bp);
1251ae349f5Scvs2svn }
1261ae349f5Scvs2svn 
1271ae349f5Scvs2svn /*
1281ae349f5Scvs2svn  * Validate given username and passwrd against with secret table
1291ae349f5Scvs2svn  */
1301ae349f5Scvs2svn static int
1317a6f8720SBrian Somers PapValidate(struct bundle *bundle, u_char *name, u_char *key,
1327a6f8720SBrian Somers             struct physical *physical)
1331ae349f5Scvs2svn {
1341ae349f5Scvs2svn   int nlen, klen;
1351ae349f5Scvs2svn 
1361ae349f5Scvs2svn   nlen = *name++;
1371ae349f5Scvs2svn   klen = *key;
1381ae349f5Scvs2svn   *key++ = 0;
1391ae349f5Scvs2svn   key[klen] = 0;
1401ae349f5Scvs2svn   LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
1411ae349f5Scvs2svn 	    name, nlen, key, klen);
1421ae349f5Scvs2svn 
1437a6f8720SBrian Somers   return AuthValidate(bundle, SECRETFILE, name, key, physical);
1441ae349f5Scvs2svn }
1451ae349f5Scvs2svn 
1461ae349f5Scvs2svn void
1477a6f8720SBrian Somers PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
1481ae349f5Scvs2svn {
149e2ebb036SBrian Somers   struct datalink *dl = bundle2datalink(bundle, physical->link.name);
1501ae349f5Scvs2svn   int len = plength(bp);
1511ae349f5Scvs2svn   struct fsmheader *php;
1521ae349f5Scvs2svn   u_char *cp;
1531ae349f5Scvs2svn 
1541ae349f5Scvs2svn   if (len >= sizeof(struct fsmheader)) {
1551ae349f5Scvs2svn     php = (struct fsmheader *) MBUF_CTOP(bp);
1561ae349f5Scvs2svn     if (len >= ntohs(php->length)) {
1571ae349f5Scvs2svn       if (php->code < PAP_REQUEST || php->code > PAP_NAK)
1581ae349f5Scvs2svn 	php->code = 0;
1591ae349f5Scvs2svn       LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]);
1601ae349f5Scvs2svn 
1611ae349f5Scvs2svn       switch (php->code) {
1621ae349f5Scvs2svn       case PAP_REQUEST:
1631ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
1647a6f8720SBrian Somers 	if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
16563b73463SBrian Somers 	  SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
166a611cad6SBrian Somers 	  dl->lcp.auth_ineed = 0;
167fc1141b2SBrian Somers           Physical_Login(physical, cp + 1);
168455aabc3SBrian Somers 
169a611cad6SBrian Somers           if (dl->lcp.auth_iwait == 0)
170455aabc3SBrian Somers             /*
171455aabc3SBrian Somers              * Either I didn't need to authenticate, or I've already been
172455aabc3SBrian Somers              * told that I got the answer right.
173455aabc3SBrian Somers              */
174e2ebb036SBrian Somers             datalink_AuthOk(dl);
175455aabc3SBrian Somers 
1761ae349f5Scvs2svn 	} else {
17763b73463SBrian Somers 	  SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
178e2ebb036SBrian Somers           datalink_AuthNotOk(dl);
1791ae349f5Scvs2svn 	}
1801ae349f5Scvs2svn 	break;
1811ae349f5Scvs2svn       case PAP_ACK:
182e2ebb036SBrian Somers 	StopAuthTimer(&dl->pap);
1831ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
1841ae349f5Scvs2svn 	len = *cp++;
1851ae349f5Scvs2svn 	cp[len] = 0;
1861ae349f5Scvs2svn 	LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
187a611cad6SBrian Somers 	if (dl->lcp.auth_iwait == PROTO_PAP) {
188a611cad6SBrian Somers 	  dl->lcp.auth_iwait = 0;
189a611cad6SBrian Somers 	  if (dl->lcp.auth_ineed == 0)
190455aabc3SBrian Somers             /*
191455aabc3SBrian Somers              * We've succeeded in our ``login''
192455aabc3SBrian Somers              * If we're not expecting  the peer to authenticate (or he already
193455aabc3SBrian Somers              * has), proceed to network phase.
194455aabc3SBrian Somers              */
195e2ebb036SBrian Somers             datalink_AuthOk(dl);
1961ae349f5Scvs2svn 	}
1971ae349f5Scvs2svn 	break;
1981ae349f5Scvs2svn       case PAP_NAK:
199e2ebb036SBrian Somers 	StopAuthTimer(&dl->pap);
2001ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
2011ae349f5Scvs2svn 	len = *cp++;
2021ae349f5Scvs2svn 	cp[len] = 0;
2031ae349f5Scvs2svn 	LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
204e2ebb036SBrian Somers         datalink_AuthNotOk(dl);
2051ae349f5Scvs2svn 	break;
2061ae349f5Scvs2svn       }
2071ae349f5Scvs2svn     }
2081ae349f5Scvs2svn   }
2091ae349f5Scvs2svn   pfree(bp);
2101ae349f5Scvs2svn }
211