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