xref: /freebsd/usr.sbin/ppp/pap.c (revision 1fa665f5b363853f2e5ebdf453e9af3b7e752729)
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  *
211fa665f5SBrian Somers  * $Id: pap.c,v 1.20.2.26 1998/04/24 19:16:12 brian Exp $
221ae349f5Scvs2svn  *
231ae349f5Scvs2svn  *	TODO:
241ae349f5Scvs2svn  */
252764b86aSBrian Somers #include <sys/types.h>
261ae349f5Scvs2svn #include <netinet/in.h>
27eaa4df37SBrian Somers #include <netinet/in_systm.h>
28eaa4df37SBrian Somers #include <netinet/ip.h>
291fa665f5SBrian Somers #include <sys/un.h>
301ae349f5Scvs2svn 
316140ba11SBrian Somers #include <termios.h>
321ae349f5Scvs2svn 
331ae349f5Scvs2svn #include "mbuf.h"
341ae349f5Scvs2svn #include "log.h"
351ae349f5Scvs2svn #include "defs.h"
361ae349f5Scvs2svn #include "timer.h"
371ae349f5Scvs2svn #include "fsm.h"
381ae349f5Scvs2svn #include "lcp.h"
39e2ebb036SBrian Somers #include "auth.h"
401ae349f5Scvs2svn #include "pap.h"
41879ed6faSBrian Somers #include "lqr.h"
421ae349f5Scvs2svn #include "hdlc.h"
431ae349f5Scvs2svn #include "lcpproto.h"
446140ba11SBrian Somers #include "async.h"
456140ba11SBrian Somers #include "throughput.h"
463b0f8d2eSBrian Somers #include "ccp.h"
476140ba11SBrian Somers #include "link.h"
4842d4d396SBrian Somers #include "descriptor.h"
4963b73463SBrian Somers #include "physical.h"
505828db6dSBrian Somers #include "iplist.h"
51eaa4df37SBrian Somers #include "slcompress.h"
525828db6dSBrian Somers #include "ipcp.h"
535ca5389aSBrian Somers #include "filter.h"
543b0f8d2eSBrian Somers #include "mp.h"
55455aabc3SBrian Somers #include "bundle.h"
56e2ebb036SBrian Somers #include "chat.h"
57e2ebb036SBrian Somers #include "chap.h"
58e2ebb036SBrian Somers #include "datalink.h"
591ae349f5Scvs2svn 
601ae349f5Scvs2svn static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
611ae349f5Scvs2svn 
62e2ebb036SBrian Somers void
63e2ebb036SBrian Somers SendPapChallenge(struct authinfo *auth, int papid, struct physical *physical)
641ae349f5Scvs2svn {
651ae349f5Scvs2svn   struct fsmheader lh;
661ae349f5Scvs2svn   struct mbuf *bp;
671ae349f5Scvs2svn   u_char *cp;
681ae349f5Scvs2svn   int namelen, keylen, plen;
691ae349f5Scvs2svn 
7092f4ff1cSBrian Somers   namelen = strlen(physical->dl->bundle->cfg.auth.name);
7192f4ff1cSBrian Somers   keylen = strlen(physical->dl->bundle->cfg.auth.key);
721ae349f5Scvs2svn   plen = namelen + keylen + 2;
731ae349f5Scvs2svn   LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n",
741ae349f5Scvs2svn 	    namelen, keylen);
7592f4ff1cSBrian Somers   LogPrintf(LogPHASE, "PAP: %s\n", physical->dl->bundle->cfg.auth.name);
761ae349f5Scvs2svn   lh.code = PAP_REQUEST;
771ae349f5Scvs2svn   lh.id = papid;
781ae349f5Scvs2svn   lh.length = htons(plen + sizeof(struct fsmheader));
791ae349f5Scvs2svn   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
801ae349f5Scvs2svn   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
811ae349f5Scvs2svn   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
821ae349f5Scvs2svn   *cp++ = namelen;
8392f4ff1cSBrian Somers   memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen);
841ae349f5Scvs2svn   cp += namelen;
851ae349f5Scvs2svn   *cp++ = keylen;
8692f4ff1cSBrian Somers   memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen);
8792f4ff1cSBrian Somers 
881ae349f5Scvs2svn 
898c07a7b2SBrian Somers   HdlcOutput(physical2link(physical), PRI_LINK, PROTO_PAP, bp);
901ae349f5Scvs2svn }
911ae349f5Scvs2svn 
921ae349f5Scvs2svn static void
9363b73463SBrian Somers SendPapCode(int id, int code, const char *message, struct physical *physical)
941ae349f5Scvs2svn {
951ae349f5Scvs2svn   struct fsmheader lh;
961ae349f5Scvs2svn   struct mbuf *bp;
971ae349f5Scvs2svn   u_char *cp;
981ae349f5Scvs2svn   int plen, mlen;
991ae349f5Scvs2svn 
1001ae349f5Scvs2svn   lh.code = code;
1011ae349f5Scvs2svn   lh.id = id;
1021ae349f5Scvs2svn   mlen = strlen(message);
1031ae349f5Scvs2svn   plen = mlen + 1;
1041ae349f5Scvs2svn   lh.length = htons(plen + sizeof(struct fsmheader));
1051ae349f5Scvs2svn   bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
1061ae349f5Scvs2svn   memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
1071ae349f5Scvs2svn   cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
1081ae349f5Scvs2svn   *cp++ = mlen;
1091ae349f5Scvs2svn   memcpy(cp, message, mlen);
1101ae349f5Scvs2svn   LogPrintf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
1118c07a7b2SBrian Somers   HdlcOutput(physical2link(physical), PRI_LINK, PROTO_PAP, bp);
1121ae349f5Scvs2svn }
1131ae349f5Scvs2svn 
1141ae349f5Scvs2svn /*
1151ae349f5Scvs2svn  * Validate given username and passwrd against with secret table
1161ae349f5Scvs2svn  */
1171ae349f5Scvs2svn static int
1187a6f8720SBrian Somers PapValidate(struct bundle *bundle, u_char *name, u_char *key,
1197a6f8720SBrian Somers             struct physical *physical)
1201ae349f5Scvs2svn {
1211ae349f5Scvs2svn   int nlen, klen;
1221ae349f5Scvs2svn 
1231ae349f5Scvs2svn   nlen = *name++;
1241ae349f5Scvs2svn   klen = *key;
1251ae349f5Scvs2svn   *key++ = 0;
1261ae349f5Scvs2svn   key[klen] = 0;
1271ae349f5Scvs2svn   LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
1281ae349f5Scvs2svn 	    name, nlen, key, klen);
1291ae349f5Scvs2svn 
130643f4904SBrian Somers   return AuthValidate(bundle, name, key, physical);
1311ae349f5Scvs2svn }
1321ae349f5Scvs2svn 
1331ae349f5Scvs2svn void
1347a6f8720SBrian Somers PapInput(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
1351ae349f5Scvs2svn {
1361ae349f5Scvs2svn   int len = plength(bp);
1371ae349f5Scvs2svn   struct fsmheader *php;
1381ae349f5Scvs2svn   u_char *cp;
1391ae349f5Scvs2svn 
1401ae349f5Scvs2svn   if (len >= sizeof(struct fsmheader)) {
1411ae349f5Scvs2svn     php = (struct fsmheader *) MBUF_CTOP(bp);
1421ae349f5Scvs2svn     if (len >= ntohs(php->length)) {
1431ae349f5Scvs2svn       if (php->code < PAP_REQUEST || php->code > PAP_NAK)
1441ae349f5Scvs2svn 	php->code = 0;
1451ae349f5Scvs2svn       LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]);
1461ae349f5Scvs2svn 
1471ae349f5Scvs2svn       switch (php->code) {
1481ae349f5Scvs2svn       case PAP_REQUEST:
1491ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
1507a6f8720SBrian Somers 	if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
151643f4904SBrian Somers           datalink_GotAuthname(physical->dl, cp+1, *cp);
15263b73463SBrian Somers 	  SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
153833882f7SBrian Somers 	  physical->link.lcp.auth_ineed = 0;
1541342caedSBrian Somers           if (Enabled(bundle, OPT_UTMP))
155fc1141b2SBrian Somers             Physical_Login(physical, cp + 1);
156455aabc3SBrian Somers 
157833882f7SBrian Somers           if (physical->link.lcp.auth_iwait == 0)
158455aabc3SBrian Somers             /*
159455aabc3SBrian Somers              * Either I didn't need to authenticate, or I've already been
160455aabc3SBrian Somers              * told that I got the answer right.
161455aabc3SBrian Somers              */
162833882f7SBrian Somers             datalink_AuthOk(physical->dl);
163455aabc3SBrian Somers 
1641ae349f5Scvs2svn 	} else {
16563b73463SBrian Somers 	  SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
166833882f7SBrian Somers           datalink_AuthNotOk(physical->dl);
1671ae349f5Scvs2svn 	}
1681ae349f5Scvs2svn 	break;
1691ae349f5Scvs2svn       case PAP_ACK:
170833882f7SBrian Somers 	StopAuthTimer(&physical->dl->pap);
1711ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
1721ae349f5Scvs2svn 	len = *cp++;
1731ae349f5Scvs2svn 	cp[len] = 0;
1741ae349f5Scvs2svn 	LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
175833882f7SBrian Somers 	if (physical->link.lcp.auth_iwait == PROTO_PAP) {
176833882f7SBrian Somers 	  physical->link.lcp.auth_iwait = 0;
177833882f7SBrian Somers 	  if (physical->link.lcp.auth_ineed == 0)
178455aabc3SBrian Somers             /*
179455aabc3SBrian Somers              * We've succeeded in our ``login''
180455aabc3SBrian Somers              * If we're not expecting  the peer to authenticate (or he already
181455aabc3SBrian Somers              * has), proceed to network phase.
182455aabc3SBrian Somers              */
183833882f7SBrian Somers             datalink_AuthOk(physical->dl);
1841ae349f5Scvs2svn 	}
1851ae349f5Scvs2svn 	break;
1861ae349f5Scvs2svn       case PAP_NAK:
187833882f7SBrian Somers 	StopAuthTimer(&physical->dl->pap);
1881ae349f5Scvs2svn 	cp = (u_char *) (php + 1);
1891ae349f5Scvs2svn 	len = *cp++;
1901ae349f5Scvs2svn 	cp[len] = 0;
1911ae349f5Scvs2svn 	LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
192833882f7SBrian Somers         datalink_AuthNotOk(physical->dl);
1931ae349f5Scvs2svn 	break;
1941ae349f5Scvs2svn       }
1951ae349f5Scvs2svn     }
1961ae349f5Scvs2svn   }
1971ae349f5Scvs2svn   pfree(bp);
1981ae349f5Scvs2svn }
199