xref: /nrf52832-nimble/rt-thread/components/net/lwip-1.4.1/src/netif/ppp/pap.c (revision 104654410c56c573564690304ae786df310c91fc)
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