1*10465441SEvalZero /*****************************************************************************
2*10465441SEvalZero * pap.c - Network Password Authentication Protocol program file.
3*10465441SEvalZero *
4*10465441SEvalZero * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
5*10465441SEvalZero * portions Copyright (c) 1997 by Global Election Systems Inc.
6*10465441SEvalZero *
7*10465441SEvalZero * The authors hereby grant permission to use, copy, modify, distribute,
8*10465441SEvalZero * and license this software and its documentation for any purpose, provided
9*10465441SEvalZero * that existing copyright notices are retained in all copies and that this
10*10465441SEvalZero * notice and the following disclaimer are included verbatim in any
11*10465441SEvalZero * distributions. No written agreement, license, or royalty fee is required
12*10465441SEvalZero * for any of the authorized uses.
13*10465441SEvalZero *
14*10465441SEvalZero * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
15*10465441SEvalZero * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*10465441SEvalZero * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*10465441SEvalZero * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18*10465441SEvalZero * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*10465441SEvalZero * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*10465441SEvalZero * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*10465441SEvalZero * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*10465441SEvalZero * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*10465441SEvalZero * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*10465441SEvalZero *
25*10465441SEvalZero ******************************************************************************
26*10465441SEvalZero * REVISION HISTORY
27*10465441SEvalZero *
28*10465441SEvalZero * 03-01-01 Marc Boucher <[email protected]>
29*10465441SEvalZero * Ported to lwIP.
30*10465441SEvalZero * 97-12-12 Guy Lancaster <[email protected]>, Global Election Systems Inc.
31*10465441SEvalZero * Original.
32*10465441SEvalZero *****************************************************************************/
33*10465441SEvalZero /*
34*10465441SEvalZero * upap.c - User/Password Authentication Protocol.
35*10465441SEvalZero *
36*10465441SEvalZero * Copyright (c) 1989 Carnegie Mellon University.
37*10465441SEvalZero * All rights reserved.
38*10465441SEvalZero *
39*10465441SEvalZero * Redistribution and use in source and binary forms are permitted
40*10465441SEvalZero * provided that the above copyright notice and this paragraph are
41*10465441SEvalZero * duplicated in all such forms and that any documentation,
42*10465441SEvalZero * advertising materials, and other materials related to such
43*10465441SEvalZero * distribution and use acknowledge that the software was developed
44*10465441SEvalZero * by Carnegie Mellon University. The name of the
45*10465441SEvalZero * University may not be used to endorse or promote products derived
46*10465441SEvalZero * from this software without specific prior written permission.
47*10465441SEvalZero * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
48*10465441SEvalZero * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
49*10465441SEvalZero * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
50*10465441SEvalZero */
51*10465441SEvalZero
52*10465441SEvalZero #include "lwip/opt.h"
53*10465441SEvalZero
54*10465441SEvalZero #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
55*10465441SEvalZero
56*10465441SEvalZero #if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
57*10465441SEvalZero
58*10465441SEvalZero #include "ppp_impl.h"
59*10465441SEvalZero #include "pppdebug.h"
60*10465441SEvalZero
61*10465441SEvalZero #include "auth.h"
62*10465441SEvalZero #include "pap.h"
63*10465441SEvalZero
64*10465441SEvalZero #include <string.h>
65*10465441SEvalZero
66*10465441SEvalZero #if 0 /* UNUSED */
67*10465441SEvalZero static bool hide_password = 1;
68*10465441SEvalZero
69*10465441SEvalZero /*
70*10465441SEvalZero * Command-line options.
71*10465441SEvalZero */
72*10465441SEvalZero static option_t pap_option_list[] = {
73*10465441SEvalZero { "hide-password", o_bool, &hide_password,
74*10465441SEvalZero "Don't output passwords to log", 1 },
75*10465441SEvalZero { "show-password", o_bool, &hide_password,
76*10465441SEvalZero "Show password string in debug log messages", 0 },
77*10465441SEvalZero { "pap-restart", o_int, &upap[0].us_timeouttime,
78*10465441SEvalZero "Set retransmit timeout for PAP" },
79*10465441SEvalZero { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
80*10465441SEvalZero "Set max number of transmissions for auth-reqs" },
81*10465441SEvalZero { "pap-timeout", o_int, &upap[0].us_reqtimeout,
82*10465441SEvalZero "Set time limit for peer PAP authentication" },
83*10465441SEvalZero { NULL }
84*10465441SEvalZero };
85*10465441SEvalZero #endif
86*10465441SEvalZero
87*10465441SEvalZero /*
88*10465441SEvalZero * Protocol entry points.
89*10465441SEvalZero */
90*10465441SEvalZero static void upap_init (int);
91*10465441SEvalZero static void upap_lowerup (int);
92*10465441SEvalZero static void upap_lowerdown (int);
93*10465441SEvalZero static void upap_input (int, u_char *, int);
94*10465441SEvalZero static void upap_protrej (int);
95*10465441SEvalZero #if PPP_ADDITIONAL_CALLBACKS
96*10465441SEvalZero static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
97*10465441SEvalZero #endif /* PPP_ADDITIONAL_CALLBACKS */
98*10465441SEvalZero
99*10465441SEvalZero struct protent pap_protent = {
100*10465441SEvalZero PPP_PAP,
101*10465441SEvalZero upap_init,
102*10465441SEvalZero upap_input,
103*10465441SEvalZero upap_protrej,
104*10465441SEvalZero upap_lowerup,
105*10465441SEvalZero upap_lowerdown,
106*10465441SEvalZero NULL,
107*10465441SEvalZero NULL,
108*10465441SEvalZero #if PPP_ADDITIONAL_CALLBACKS
109*10465441SEvalZero upap_printpkt,
110*10465441SEvalZero NULL,
111*10465441SEvalZero #endif /* PPP_ADDITIONAL_CALLBACKS */
112*10465441SEvalZero 1,
113*10465441SEvalZero "PAP",
114*10465441SEvalZero #if PPP_ADDITIONAL_CALLBACKS
115*10465441SEvalZero NULL,
116*10465441SEvalZero NULL,
117*10465441SEvalZero NULL
118*10465441SEvalZero #endif /* PPP_ADDITIONAL_CALLBACKS */
119*10465441SEvalZero };
120*10465441SEvalZero
121*10465441SEvalZero upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
122*10465441SEvalZero
123*10465441SEvalZero static void upap_timeout (void *);
124*10465441SEvalZero static void upap_reqtimeout(void *);
125*10465441SEvalZero static void upap_rauthreq (upap_state *, u_char *, u_char, int);
126*10465441SEvalZero static void upap_rauthack (upap_state *, u_char *, int, int);
127*10465441SEvalZero static void upap_rauthnak (upap_state *, u_char *, int, int);
128*10465441SEvalZero static void upap_sauthreq (upap_state *);
129*10465441SEvalZero static void upap_sresp (upap_state *, u_char, u_char, char *, int);
130*10465441SEvalZero
131*10465441SEvalZero
132*10465441SEvalZero /*
133*10465441SEvalZero * upap_init - Initialize a UPAP unit.
134*10465441SEvalZero */
135*10465441SEvalZero static void
upap_init(int unit)136*10465441SEvalZero upap_init(int unit)
137*10465441SEvalZero {
138*10465441SEvalZero upap_state *u = &upap[unit];
139*10465441SEvalZero
140*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
141*10465441SEvalZero u->us_unit = unit;
142*10465441SEvalZero u->us_user = NULL;
143*10465441SEvalZero u->us_userlen = 0;
144*10465441SEvalZero u->us_passwd = NULL;
145*10465441SEvalZero u->us_passwdlen = 0;
146*10465441SEvalZero u->us_clientstate = UPAPCS_INITIAL;
147*10465441SEvalZero u->us_serverstate = UPAPSS_INITIAL;
148*10465441SEvalZero u->us_id = 0;
149*10465441SEvalZero u->us_timeouttime = UPAP_DEFTIMEOUT;
150*10465441SEvalZero u->us_maxtransmits = 10;
151*10465441SEvalZero u->us_reqtimeout = UPAP_DEFREQTIME;
152*10465441SEvalZero }
153*10465441SEvalZero
154*10465441SEvalZero /*
155*10465441SEvalZero * upap_authwithpeer - Authenticate us with our peer (start client).
156*10465441SEvalZero *
157*10465441SEvalZero * Set new state and send authenticate's.
158*10465441SEvalZero */
159*10465441SEvalZero void
upap_authwithpeer(int unit,char * user,char * password)160*10465441SEvalZero upap_authwithpeer(int unit, char *user, char *password)
161*10465441SEvalZero {
162*10465441SEvalZero upap_state *u = &upap[unit];
163*10465441SEvalZero
164*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
165*10465441SEvalZero unit, user, password, u->us_clientstate));
166*10465441SEvalZero
167*10465441SEvalZero /* Save the username and password we're given */
168*10465441SEvalZero u->us_user = user;
169*10465441SEvalZero u->us_userlen = (int)strlen(user);
170*10465441SEvalZero u->us_passwd = password;
171*10465441SEvalZero u->us_passwdlen = (int)strlen(password);
172*10465441SEvalZero
173*10465441SEvalZero u->us_transmits = 0;
174*10465441SEvalZero
175*10465441SEvalZero /* Lower layer up yet? */
176*10465441SEvalZero if (u->us_clientstate == UPAPCS_INITIAL ||
177*10465441SEvalZero u->us_clientstate == UPAPCS_PENDING) {
178*10465441SEvalZero u->us_clientstate = UPAPCS_PENDING;
179*10465441SEvalZero return;
180*10465441SEvalZero }
181*10465441SEvalZero
182*10465441SEvalZero upap_sauthreq(u); /* Start protocol */
183*10465441SEvalZero }
184*10465441SEvalZero
185*10465441SEvalZero
186*10465441SEvalZero /*
187*10465441SEvalZero * upap_authpeer - Authenticate our peer (start server).
188*10465441SEvalZero *
189*10465441SEvalZero * Set new state.
190*10465441SEvalZero */
191*10465441SEvalZero void
upap_authpeer(int unit)192*10465441SEvalZero upap_authpeer(int unit)
193*10465441SEvalZero {
194*10465441SEvalZero upap_state *u = &upap[unit];
195*10465441SEvalZero
196*10465441SEvalZero /* Lower layer up yet? */
197*10465441SEvalZero if (u->us_serverstate == UPAPSS_INITIAL ||
198*10465441SEvalZero u->us_serverstate == UPAPSS_PENDING) {
199*10465441SEvalZero u->us_serverstate = UPAPSS_PENDING;
200*10465441SEvalZero return;
201*10465441SEvalZero }
202*10465441SEvalZero
203*10465441SEvalZero u->us_serverstate = UPAPSS_LISTEN;
204*10465441SEvalZero if (u->us_reqtimeout > 0) {
205*10465441SEvalZero TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
206*10465441SEvalZero }
207*10465441SEvalZero }
208*10465441SEvalZero
209*10465441SEvalZero /*
210*10465441SEvalZero * upap_timeout - Retransmission timer for sending auth-reqs expired.
211*10465441SEvalZero */
212*10465441SEvalZero static void
upap_timeout(void * arg)213*10465441SEvalZero upap_timeout(void *arg)
214*10465441SEvalZero {
215*10465441SEvalZero upap_state *u = (upap_state *) arg;
216*10465441SEvalZero
217*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n",
218*10465441SEvalZero u->us_unit, u->us_timeouttime, u->us_clientstate));
219*10465441SEvalZero
220*10465441SEvalZero if (u->us_clientstate != UPAPCS_AUTHREQ) {
221*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
222*10465441SEvalZero return;
223*10465441SEvalZero }
224*10465441SEvalZero
225*10465441SEvalZero if (u->us_transmits >= u->us_maxtransmits) {
226*10465441SEvalZero /* give up in disgust */
227*10465441SEvalZero UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
228*10465441SEvalZero u->us_clientstate = UPAPCS_BADAUTH;
229*10465441SEvalZero auth_withpeer_fail(u->us_unit, PPP_PAP);
230*10465441SEvalZero return;
231*10465441SEvalZero }
232*10465441SEvalZero
233*10465441SEvalZero upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/
234*10465441SEvalZero }
235*10465441SEvalZero
236*10465441SEvalZero
237*10465441SEvalZero /*
238*10465441SEvalZero * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
239*10465441SEvalZero */
240*10465441SEvalZero static void
upap_reqtimeout(void * arg)241*10465441SEvalZero upap_reqtimeout(void *arg)
242*10465441SEvalZero {
243*10465441SEvalZero upap_state *u = (upap_state *) arg;
244*10465441SEvalZero
245*10465441SEvalZero if (u->us_serverstate != UPAPSS_LISTEN) {
246*10465441SEvalZero return; /* huh?? */
247*10465441SEvalZero }
248*10465441SEvalZero
249*10465441SEvalZero auth_peer_fail(u->us_unit, PPP_PAP);
250*10465441SEvalZero u->us_serverstate = UPAPSS_BADAUTH;
251*10465441SEvalZero }
252*10465441SEvalZero
253*10465441SEvalZero
254*10465441SEvalZero /*
255*10465441SEvalZero * upap_lowerup - The lower layer is up.
256*10465441SEvalZero *
257*10465441SEvalZero * Start authenticating if pending.
258*10465441SEvalZero */
259*10465441SEvalZero static void
upap_lowerup(int unit)260*10465441SEvalZero upap_lowerup(int unit)
261*10465441SEvalZero {
262*10465441SEvalZero upap_state *u = &upap[unit];
263*10465441SEvalZero
264*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
265*10465441SEvalZero
266*10465441SEvalZero if (u->us_clientstate == UPAPCS_INITIAL) {
267*10465441SEvalZero u->us_clientstate = UPAPCS_CLOSED;
268*10465441SEvalZero } else if (u->us_clientstate == UPAPCS_PENDING) {
269*10465441SEvalZero upap_sauthreq(u); /* send an auth-request */
270*10465441SEvalZero /* now client state is UPAPCS__AUTHREQ */
271*10465441SEvalZero }
272*10465441SEvalZero
273*10465441SEvalZero if (u->us_serverstate == UPAPSS_INITIAL) {
274*10465441SEvalZero u->us_serverstate = UPAPSS_CLOSED;
275*10465441SEvalZero } else if (u->us_serverstate == UPAPSS_PENDING) {
276*10465441SEvalZero u->us_serverstate = UPAPSS_LISTEN;
277*10465441SEvalZero if (u->us_reqtimeout > 0) {
278*10465441SEvalZero TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
279*10465441SEvalZero }
280*10465441SEvalZero }
281*10465441SEvalZero }
282*10465441SEvalZero
283*10465441SEvalZero
284*10465441SEvalZero /*
285*10465441SEvalZero * upap_lowerdown - The lower layer is down.
286*10465441SEvalZero *
287*10465441SEvalZero * Cancel all timeouts.
288*10465441SEvalZero */
289*10465441SEvalZero static void
upap_lowerdown(int unit)290*10465441SEvalZero upap_lowerdown(int unit)
291*10465441SEvalZero {
292*10465441SEvalZero upap_state *u = &upap[unit];
293*10465441SEvalZero
294*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
295*10465441SEvalZero
296*10465441SEvalZero if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
297*10465441SEvalZero UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
298*10465441SEvalZero }
299*10465441SEvalZero if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
300*10465441SEvalZero UNTIMEOUT(upap_reqtimeout, u);
301*10465441SEvalZero }
302*10465441SEvalZero
303*10465441SEvalZero u->us_clientstate = UPAPCS_INITIAL;
304*10465441SEvalZero u->us_serverstate = UPAPSS_INITIAL;
305*10465441SEvalZero }
306*10465441SEvalZero
307*10465441SEvalZero
308*10465441SEvalZero /*
309*10465441SEvalZero * upap_protrej - Peer doesn't speak this protocol.
310*10465441SEvalZero *
311*10465441SEvalZero * This shouldn't happen. In any case, pretend lower layer went down.
312*10465441SEvalZero */
313*10465441SEvalZero static void
upap_protrej(int unit)314*10465441SEvalZero upap_protrej(int unit)
315*10465441SEvalZero {
316*10465441SEvalZero upap_state *u = &upap[unit];
317*10465441SEvalZero
318*10465441SEvalZero if (u->us_clientstate == UPAPCS_AUTHREQ) {
319*10465441SEvalZero UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
320*10465441SEvalZero auth_withpeer_fail(unit, PPP_PAP);
321*10465441SEvalZero }
322*10465441SEvalZero if (u->us_serverstate == UPAPSS_LISTEN) {
323*10465441SEvalZero UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
324*10465441SEvalZero auth_peer_fail(unit, PPP_PAP);
325*10465441SEvalZero }
326*10465441SEvalZero upap_lowerdown(unit);
327*10465441SEvalZero }
328*10465441SEvalZero
329*10465441SEvalZero
330*10465441SEvalZero /*
331*10465441SEvalZero * upap_input - Input UPAP packet.
332*10465441SEvalZero */
333*10465441SEvalZero static void
upap_input(int unit,u_char * inpacket,int l)334*10465441SEvalZero upap_input(int unit, u_char *inpacket, int l)
335*10465441SEvalZero {
336*10465441SEvalZero upap_state *u = &upap[unit];
337*10465441SEvalZero u_char *inp;
338*10465441SEvalZero u_char code, id;
339*10465441SEvalZero int len;
340*10465441SEvalZero
341*10465441SEvalZero /*
342*10465441SEvalZero * Parse header (code, id and length).
343*10465441SEvalZero * If packet too short, drop it.
344*10465441SEvalZero */
345*10465441SEvalZero inp = inpacket;
346*10465441SEvalZero if (l < (int)UPAP_HEADERLEN) {
347*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
348*10465441SEvalZero return;
349*10465441SEvalZero }
350*10465441SEvalZero GETCHAR(code, inp);
351*10465441SEvalZero GETCHAR(id, inp);
352*10465441SEvalZero GETSHORT(len, inp);
353*10465441SEvalZero if (len < (int)UPAP_HEADERLEN) {
354*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
355*10465441SEvalZero return;
356*10465441SEvalZero }
357*10465441SEvalZero if (len > l) {
358*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
359*10465441SEvalZero return;
360*10465441SEvalZero }
361*10465441SEvalZero len -= UPAP_HEADERLEN;
362*10465441SEvalZero
363*10465441SEvalZero /*
364*10465441SEvalZero * Action depends on code.
365*10465441SEvalZero */
366*10465441SEvalZero switch (code) {
367*10465441SEvalZero case UPAP_AUTHREQ:
368*10465441SEvalZero upap_rauthreq(u, inp, id, len);
369*10465441SEvalZero break;
370*10465441SEvalZero
371*10465441SEvalZero case UPAP_AUTHACK:
372*10465441SEvalZero upap_rauthack(u, inp, id, len);
373*10465441SEvalZero break;
374*10465441SEvalZero
375*10465441SEvalZero case UPAP_AUTHNAK:
376*10465441SEvalZero upap_rauthnak(u, inp, id, len);
377*10465441SEvalZero break;
378*10465441SEvalZero
379*10465441SEvalZero default: /* XXX Need code reject */
380*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
381*10465441SEvalZero break;
382*10465441SEvalZero }
383*10465441SEvalZero }
384*10465441SEvalZero
385*10465441SEvalZero
386*10465441SEvalZero /*
387*10465441SEvalZero * upap_rauth - Receive Authenticate.
388*10465441SEvalZero */
389*10465441SEvalZero static void
upap_rauthreq(upap_state * u,u_char * inp,u_char id,int len)390*10465441SEvalZero upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
391*10465441SEvalZero {
392*10465441SEvalZero u_char ruserlen, rpasswdlen;
393*10465441SEvalZero char *ruser, *rpasswd;
394*10465441SEvalZero u_char retcode;
395*10465441SEvalZero char *msg;
396*10465441SEvalZero int msglen;
397*10465441SEvalZero
398*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
399*10465441SEvalZero
400*10465441SEvalZero if (u->us_serverstate < UPAPSS_LISTEN) {
401*10465441SEvalZero return;
402*10465441SEvalZero }
403*10465441SEvalZero
404*10465441SEvalZero /*
405*10465441SEvalZero * If we receive a duplicate authenticate-request, we are
406*10465441SEvalZero * supposed to return the same status as for the first request.
407*10465441SEvalZero */
408*10465441SEvalZero if (u->us_serverstate == UPAPSS_OPEN) {
409*10465441SEvalZero upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
410*10465441SEvalZero return;
411*10465441SEvalZero }
412*10465441SEvalZero if (u->us_serverstate == UPAPSS_BADAUTH) {
413*10465441SEvalZero upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
414*10465441SEvalZero return;
415*10465441SEvalZero }
416*10465441SEvalZero
417*10465441SEvalZero /*
418*10465441SEvalZero * Parse user/passwd.
419*10465441SEvalZero */
420*10465441SEvalZero if (len < (int)sizeof (u_char)) {
421*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
422*10465441SEvalZero return;
423*10465441SEvalZero }
424*10465441SEvalZero GETCHAR(ruserlen, inp);
425*10465441SEvalZero len -= sizeof (u_char) + ruserlen + sizeof (u_char);
426*10465441SEvalZero if (len < 0) {
427*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
428*10465441SEvalZero return;
429*10465441SEvalZero }
430*10465441SEvalZero ruser = (char *) inp;
431*10465441SEvalZero INCPTR(ruserlen, inp);
432*10465441SEvalZero GETCHAR(rpasswdlen, inp);
433*10465441SEvalZero if (len < rpasswdlen) {
434*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
435*10465441SEvalZero return;
436*10465441SEvalZero }
437*10465441SEvalZero rpasswd = (char *) inp;
438*10465441SEvalZero
439*10465441SEvalZero /*
440*10465441SEvalZero * Check the username and password given.
441*10465441SEvalZero */
442*10465441SEvalZero retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
443*10465441SEvalZero /* lwip: currently retcode is always UPAP_AUTHACK */
444*10465441SEvalZero BZERO(rpasswd, rpasswdlen);
445*10465441SEvalZero
446*10465441SEvalZero upap_sresp(u, retcode, id, msg, msglen);
447*10465441SEvalZero
448*10465441SEvalZero if (retcode == UPAP_AUTHACK) {
449*10465441SEvalZero u->us_serverstate = UPAPSS_OPEN;
450*10465441SEvalZero auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
451*10465441SEvalZero } else {
452*10465441SEvalZero u->us_serverstate = UPAPSS_BADAUTH;
453*10465441SEvalZero auth_peer_fail(u->us_unit, PPP_PAP);
454*10465441SEvalZero }
455*10465441SEvalZero
456*10465441SEvalZero if (u->us_reqtimeout > 0) {
457*10465441SEvalZero UNTIMEOUT(upap_reqtimeout, u);
458*10465441SEvalZero }
459*10465441SEvalZero }
460*10465441SEvalZero
461*10465441SEvalZero
462*10465441SEvalZero /*
463*10465441SEvalZero * upap_rauthack - Receive Authenticate-Ack.
464*10465441SEvalZero */
465*10465441SEvalZero static void
upap_rauthack(upap_state * u,u_char * inp,int id,int len)466*10465441SEvalZero upap_rauthack(upap_state *u, u_char *inp, int id, int len)
467*10465441SEvalZero {
468*10465441SEvalZero u_char msglen;
469*10465441SEvalZero char *msg;
470*10465441SEvalZero
471*10465441SEvalZero LWIP_UNUSED_ARG(id);
472*10465441SEvalZero
473*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
474*10465441SEvalZero
475*10465441SEvalZero if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
476*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
477*10465441SEvalZero return;
478*10465441SEvalZero }
479*10465441SEvalZero
480*10465441SEvalZero /*
481*10465441SEvalZero * Parse message.
482*10465441SEvalZero */
483*10465441SEvalZero if (len < (int)sizeof (u_char)) {
484*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
485*10465441SEvalZero } else {
486*10465441SEvalZero GETCHAR(msglen, inp);
487*10465441SEvalZero if (msglen > 0) {
488*10465441SEvalZero len -= sizeof (u_char);
489*10465441SEvalZero if (len < msglen) {
490*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
491*10465441SEvalZero return;
492*10465441SEvalZero }
493*10465441SEvalZero msg = (char *) inp;
494*10465441SEvalZero PRINTMSG(msg, msglen);
495*10465441SEvalZero }
496*10465441SEvalZero }
497*10465441SEvalZero UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
498*10465441SEvalZero u->us_clientstate = UPAPCS_OPEN;
499*10465441SEvalZero
500*10465441SEvalZero auth_withpeer_success(u->us_unit, PPP_PAP);
501*10465441SEvalZero }
502*10465441SEvalZero
503*10465441SEvalZero
504*10465441SEvalZero /*
505*10465441SEvalZero * upap_rauthnak - Receive Authenticate-Nak.
506*10465441SEvalZero */
507*10465441SEvalZero static void
upap_rauthnak(upap_state * u,u_char * inp,int id,int len)508*10465441SEvalZero upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
509*10465441SEvalZero {
510*10465441SEvalZero u_char msglen;
511*10465441SEvalZero char *msg;
512*10465441SEvalZero
513*10465441SEvalZero LWIP_UNUSED_ARG(id);
514*10465441SEvalZero
515*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
516*10465441SEvalZero
517*10465441SEvalZero if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
518*10465441SEvalZero return;
519*10465441SEvalZero }
520*10465441SEvalZero
521*10465441SEvalZero /*
522*10465441SEvalZero * Parse message.
523*10465441SEvalZero */
524*10465441SEvalZero if (len < sizeof (u_char)) {
525*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
526*10465441SEvalZero } else {
527*10465441SEvalZero GETCHAR(msglen, inp);
528*10465441SEvalZero if(msglen > 0) {
529*10465441SEvalZero len -= sizeof (u_char);
530*10465441SEvalZero if (len < msglen) {
531*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
532*10465441SEvalZero return;
533*10465441SEvalZero }
534*10465441SEvalZero msg = (char *) inp;
535*10465441SEvalZero PRINTMSG(msg, msglen);
536*10465441SEvalZero }
537*10465441SEvalZero }
538*10465441SEvalZero
539*10465441SEvalZero u->us_clientstate = UPAPCS_BADAUTH;
540*10465441SEvalZero
541*10465441SEvalZero UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
542*10465441SEvalZero auth_withpeer_fail(u->us_unit, PPP_PAP);
543*10465441SEvalZero }
544*10465441SEvalZero
545*10465441SEvalZero
546*10465441SEvalZero /*
547*10465441SEvalZero * upap_sauthreq - Send an Authenticate-Request.
548*10465441SEvalZero */
549*10465441SEvalZero static void
upap_sauthreq(upap_state * u)550*10465441SEvalZero upap_sauthreq(upap_state *u)
551*10465441SEvalZero {
552*10465441SEvalZero u_char *outp;
553*10465441SEvalZero int outlen;
554*10465441SEvalZero
555*10465441SEvalZero outlen = UPAP_HEADERLEN + 2 * sizeof (u_char)
556*10465441SEvalZero + u->us_userlen + u->us_passwdlen;
557*10465441SEvalZero outp = outpacket_buf[u->us_unit];
558*10465441SEvalZero
559*10465441SEvalZero MAKEHEADER(outp, PPP_PAP);
560*10465441SEvalZero
561*10465441SEvalZero PUTCHAR(UPAP_AUTHREQ, outp);
562*10465441SEvalZero PUTCHAR(++u->us_id, outp);
563*10465441SEvalZero PUTSHORT(outlen, outp);
564*10465441SEvalZero PUTCHAR(u->us_userlen, outp);
565*10465441SEvalZero BCOPY(u->us_user, outp, u->us_userlen);
566*10465441SEvalZero INCPTR(u->us_userlen, outp);
567*10465441SEvalZero PUTCHAR(u->us_passwdlen, outp);
568*10465441SEvalZero BCOPY(u->us_passwd, outp, u->us_passwdlen);
569*10465441SEvalZero
570*10465441SEvalZero pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
571*10465441SEvalZero
572*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
573*10465441SEvalZero
574*10465441SEvalZero TIMEOUT(upap_timeout, u, u->us_timeouttime);
575*10465441SEvalZero ++u->us_transmits;
576*10465441SEvalZero u->us_clientstate = UPAPCS_AUTHREQ;
577*10465441SEvalZero }
578*10465441SEvalZero
579*10465441SEvalZero
580*10465441SEvalZero /*
581*10465441SEvalZero * upap_sresp - Send a response (ack or nak).
582*10465441SEvalZero */
583*10465441SEvalZero static void
upap_sresp(upap_state * u,u_char code,u_char id,char * msg,int msglen)584*10465441SEvalZero upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
585*10465441SEvalZero {
586*10465441SEvalZero u_char *outp;
587*10465441SEvalZero int outlen;
588*10465441SEvalZero
589*10465441SEvalZero outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
590*10465441SEvalZero outp = outpacket_buf[u->us_unit];
591*10465441SEvalZero MAKEHEADER(outp, PPP_PAP);
592*10465441SEvalZero
593*10465441SEvalZero PUTCHAR(code, outp);
594*10465441SEvalZero PUTCHAR(id, outp);
595*10465441SEvalZero PUTSHORT(outlen, outp);
596*10465441SEvalZero PUTCHAR(msglen, outp);
597*10465441SEvalZero BCOPY(msg, outp, msglen);
598*10465441SEvalZero pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
599*10465441SEvalZero
600*10465441SEvalZero UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
601*10465441SEvalZero }
602*10465441SEvalZero
603*10465441SEvalZero #if PPP_ADDITIONAL_CALLBACKS
604*10465441SEvalZero static char *upap_codenames[] = {
605*10465441SEvalZero "AuthReq", "AuthAck", "AuthNak"
606*10465441SEvalZero };
607*10465441SEvalZero
608*10465441SEvalZero /*
609*10465441SEvalZero * upap_printpkt - print the contents of a PAP packet.
610*10465441SEvalZero */
upap_printpkt(u_char * p,int plen,void (* printer)(void *,char *,...),void * arg)611*10465441SEvalZero static int upap_printpkt(
612*10465441SEvalZero u_char *p,
613*10465441SEvalZero int plen,
614*10465441SEvalZero void (*printer) (void *, char *, ...),
615*10465441SEvalZero void *arg
616*10465441SEvalZero )
617*10465441SEvalZero {
618*10465441SEvalZero LWIP_UNUSED_ARG(p);
619*10465441SEvalZero LWIP_UNUSED_ARG(plen);
620*10465441SEvalZero LWIP_UNUSED_ARG(printer);
621*10465441SEvalZero LWIP_UNUSED_ARG(arg);
622*10465441SEvalZero return 0;
623*10465441SEvalZero }
624*10465441SEvalZero #endif /* PPP_ADDITIONAL_CALLBACKS */
625*10465441SEvalZero
626*10465441SEvalZero #endif /* PAP_SUPPORT */
627*10465441SEvalZero
628*10465441SEvalZero #endif /* PPP_SUPPORT */
629