xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.0.2/src/netif/ppp/upap.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * upap.c - User/Password Authentication Protocol.
3*10465441SEvalZero  *
4*10465441SEvalZero  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
5*10465441SEvalZero  *
6*10465441SEvalZero  * Redistribution and use in source and binary forms, with or without
7*10465441SEvalZero  * modification, are permitted provided that the following conditions
8*10465441SEvalZero  * are met:
9*10465441SEvalZero  *
10*10465441SEvalZero  * 1. Redistributions of source code must retain the above copyright
11*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer.
12*10465441SEvalZero  *
13*10465441SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright
14*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer in
15*10465441SEvalZero  *    the documentation and/or other materials provided with the
16*10465441SEvalZero  *    distribution.
17*10465441SEvalZero  *
18*10465441SEvalZero  * 3. The name "Carnegie Mellon University" must not be used to
19*10465441SEvalZero  *    endorse or promote products derived from this software without
20*10465441SEvalZero  *    prior written permission. For permission or any legal
21*10465441SEvalZero  *    details, please contact
22*10465441SEvalZero  *      Office of Technology Transfer
23*10465441SEvalZero  *      Carnegie Mellon University
24*10465441SEvalZero  *      5000 Forbes Avenue
25*10465441SEvalZero  *      Pittsburgh, PA  15213-3890
26*10465441SEvalZero  *      (412) 268-4387, fax: (412) 268-7395
27*10465441SEvalZero  *      [email protected]
28*10465441SEvalZero  *
29*10465441SEvalZero  * 4. Redistributions of any form whatsoever must retain the following
30*10465441SEvalZero  *    acknowledgment:
31*10465441SEvalZero  *    "This product includes software developed by Computing Services
32*10465441SEvalZero  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33*10465441SEvalZero  *
34*10465441SEvalZero  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35*10465441SEvalZero  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36*10465441SEvalZero  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37*10465441SEvalZero  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38*10465441SEvalZero  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39*10465441SEvalZero  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40*10465441SEvalZero  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41*10465441SEvalZero  */
42*10465441SEvalZero 
43*10465441SEvalZero #include "netif/ppp/ppp_opts.h"
44*10465441SEvalZero #if PPP_SUPPORT && PAP_SUPPORT  /* don't build if not configured for use in lwipopts.h */
45*10465441SEvalZero 
46*10465441SEvalZero /*
47*10465441SEvalZero  * @todo:
48*10465441SEvalZero  */
49*10465441SEvalZero 
50*10465441SEvalZero #if 0 /* UNUSED */
51*10465441SEvalZero #include <stdio.h>
52*10465441SEvalZero #include <string.h>
53*10465441SEvalZero #endif /* UNUSED */
54*10465441SEvalZero 
55*10465441SEvalZero #include "netif/ppp/ppp_impl.h"
56*10465441SEvalZero 
57*10465441SEvalZero #include "netif/ppp/upap.h"
58*10465441SEvalZero 
59*10465441SEvalZero #if PPP_OPTIONS
60*10465441SEvalZero /*
61*10465441SEvalZero  * Command-line options.
62*10465441SEvalZero  */
63*10465441SEvalZero static option_t pap_option_list[] = {
64*10465441SEvalZero     { "hide-password", o_bool, &hide_password,
65*10465441SEvalZero       "Don't output passwords to log", OPT_PRIO | 1 },
66*10465441SEvalZero     { "show-password", o_bool, &hide_password,
67*10465441SEvalZero       "Show password string in debug log messages", OPT_PRIOSUB | 0 },
68*10465441SEvalZero 
69*10465441SEvalZero     { "pap-restart", o_int, &upap[0].us_timeouttime,
70*10465441SEvalZero       "Set retransmit timeout for PAP", OPT_PRIO },
71*10465441SEvalZero     { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
72*10465441SEvalZero       "Set max number of transmissions for auth-reqs", OPT_PRIO },
73*10465441SEvalZero     { "pap-timeout", o_int, &upap[0].us_reqtimeout,
74*10465441SEvalZero       "Set time limit for peer PAP authentication", OPT_PRIO },
75*10465441SEvalZero 
76*10465441SEvalZero     { NULL }
77*10465441SEvalZero };
78*10465441SEvalZero #endif /* PPP_OPTIONS */
79*10465441SEvalZero 
80*10465441SEvalZero /*
81*10465441SEvalZero  * Protocol entry points.
82*10465441SEvalZero  */
83*10465441SEvalZero static void upap_init(ppp_pcb *pcb);
84*10465441SEvalZero static void upap_lowerup(ppp_pcb *pcb);
85*10465441SEvalZero static void upap_lowerdown(ppp_pcb *pcb);
86*10465441SEvalZero static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l);
87*10465441SEvalZero static void upap_protrej(ppp_pcb *pcb);
88*10465441SEvalZero #if PRINTPKT_SUPPORT
89*10465441SEvalZero static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg);
90*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
91*10465441SEvalZero 
92*10465441SEvalZero const struct protent pap_protent = {
93*10465441SEvalZero     PPP_PAP,
94*10465441SEvalZero     upap_init,
95*10465441SEvalZero     upap_input,
96*10465441SEvalZero     upap_protrej,
97*10465441SEvalZero     upap_lowerup,
98*10465441SEvalZero     upap_lowerdown,
99*10465441SEvalZero     NULL,
100*10465441SEvalZero     NULL,
101*10465441SEvalZero #if PRINTPKT_SUPPORT
102*10465441SEvalZero     upap_printpkt,
103*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
104*10465441SEvalZero #if PPP_DATAINPUT
105*10465441SEvalZero     NULL,
106*10465441SEvalZero #endif /* PPP_DATAINPUT */
107*10465441SEvalZero #if PRINTPKT_SUPPORT
108*10465441SEvalZero     "PAP",
109*10465441SEvalZero     NULL,
110*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
111*10465441SEvalZero #if PPP_OPTIONS
112*10465441SEvalZero     pap_option_list,
113*10465441SEvalZero     NULL,
114*10465441SEvalZero #endif /* PPP_OPTIONS */
115*10465441SEvalZero #if DEMAND_SUPPORT
116*10465441SEvalZero     NULL,
117*10465441SEvalZero     NULL
118*10465441SEvalZero #endif /* DEMAND_SUPPORT */
119*10465441SEvalZero };
120*10465441SEvalZero 
121*10465441SEvalZero static void upap_timeout(void *arg);
122*10465441SEvalZero #if PPP_SERVER
123*10465441SEvalZero static void upap_reqtimeout(void *arg);
124*10465441SEvalZero static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len);
125*10465441SEvalZero #endif /* PPP_SERVER */
126*10465441SEvalZero static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len);
127*10465441SEvalZero static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len);
128*10465441SEvalZero static void upap_sauthreq(ppp_pcb *pcb);
129*10465441SEvalZero #if PPP_SERVER
130*10465441SEvalZero static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen);
131*10465441SEvalZero #endif /* PPP_SERVER */
132*10465441SEvalZero 
133*10465441SEvalZero 
134*10465441SEvalZero /*
135*10465441SEvalZero  * upap_init - Initialize a UPAP unit.
136*10465441SEvalZero  */
upap_init(ppp_pcb * pcb)137*10465441SEvalZero static void upap_init(ppp_pcb *pcb) {
138*10465441SEvalZero     pcb->upap.us_user = NULL;
139*10465441SEvalZero     pcb->upap.us_userlen = 0;
140*10465441SEvalZero     pcb->upap.us_passwd = NULL;
141*10465441SEvalZero     pcb->upap.us_passwdlen = 0;
142*10465441SEvalZero     pcb->upap.us_clientstate = UPAPCS_INITIAL;
143*10465441SEvalZero #if PPP_SERVER
144*10465441SEvalZero     pcb->upap.us_serverstate = UPAPSS_INITIAL;
145*10465441SEvalZero #endif /* PPP_SERVER */
146*10465441SEvalZero     pcb->upap.us_id = 0;
147*10465441SEvalZero }
148*10465441SEvalZero 
149*10465441SEvalZero 
150*10465441SEvalZero /*
151*10465441SEvalZero  * upap_authwithpeer - Authenticate us with our peer (start client).
152*10465441SEvalZero  *
153*10465441SEvalZero  * Set new state and send authenticate's.
154*10465441SEvalZero  */
upap_authwithpeer(ppp_pcb * pcb,const char * user,const char * password)155*10465441SEvalZero void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password) {
156*10465441SEvalZero 
157*10465441SEvalZero     if(!user || !password)
158*10465441SEvalZero         return;
159*10465441SEvalZero 
160*10465441SEvalZero     /* Save the username and password we're given */
161*10465441SEvalZero     pcb->upap.us_user = user;
162*10465441SEvalZero     pcb->upap.us_userlen = LWIP_MIN(strlen(user), 0xff);
163*10465441SEvalZero     pcb->upap.us_passwd = password;
164*10465441SEvalZero     pcb->upap.us_passwdlen = LWIP_MIN(strlen(password), 0xff);
165*10465441SEvalZero     pcb->upap.us_transmits = 0;
166*10465441SEvalZero 
167*10465441SEvalZero     /* Lower layer up yet? */
168*10465441SEvalZero     if (pcb->upap.us_clientstate == UPAPCS_INITIAL ||
169*10465441SEvalZero 	pcb->upap.us_clientstate == UPAPCS_PENDING) {
170*10465441SEvalZero 	pcb->upap.us_clientstate = UPAPCS_PENDING;
171*10465441SEvalZero 	return;
172*10465441SEvalZero     }
173*10465441SEvalZero 
174*10465441SEvalZero     upap_sauthreq(pcb);		/* Start protocol */
175*10465441SEvalZero }
176*10465441SEvalZero 
177*10465441SEvalZero #if PPP_SERVER
178*10465441SEvalZero /*
179*10465441SEvalZero  * upap_authpeer - Authenticate our peer (start server).
180*10465441SEvalZero  *
181*10465441SEvalZero  * Set new state.
182*10465441SEvalZero  */
upap_authpeer(ppp_pcb * pcb)183*10465441SEvalZero void upap_authpeer(ppp_pcb *pcb) {
184*10465441SEvalZero 
185*10465441SEvalZero     /* Lower layer up yet? */
186*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_INITIAL ||
187*10465441SEvalZero 	pcb->upap.us_serverstate == UPAPSS_PENDING) {
188*10465441SEvalZero 	pcb->upap.us_serverstate = UPAPSS_PENDING;
189*10465441SEvalZero 	return;
190*10465441SEvalZero     }
191*10465441SEvalZero 
192*10465441SEvalZero     pcb->upap.us_serverstate = UPAPSS_LISTEN;
193*10465441SEvalZero     if (pcb->settings.pap_req_timeout > 0)
194*10465441SEvalZero 	TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout);
195*10465441SEvalZero }
196*10465441SEvalZero #endif /* PPP_SERVER */
197*10465441SEvalZero 
198*10465441SEvalZero /*
199*10465441SEvalZero  * upap_timeout - Retransmission timer for sending auth-reqs expired.
200*10465441SEvalZero  */
upap_timeout(void * arg)201*10465441SEvalZero static void upap_timeout(void *arg) {
202*10465441SEvalZero     ppp_pcb *pcb = (ppp_pcb*)arg;
203*10465441SEvalZero 
204*10465441SEvalZero     if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ)
205*10465441SEvalZero 	return;
206*10465441SEvalZero 
207*10465441SEvalZero     if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) {
208*10465441SEvalZero 	/* give up in disgust */
209*10465441SEvalZero 	ppp_error("No response to PAP authenticate-requests");
210*10465441SEvalZero 	pcb->upap.us_clientstate = UPAPCS_BADAUTH;
211*10465441SEvalZero 	auth_withpeer_fail(pcb, PPP_PAP);
212*10465441SEvalZero 	return;
213*10465441SEvalZero     }
214*10465441SEvalZero 
215*10465441SEvalZero     upap_sauthreq(pcb);		/* Send Authenticate-Request */
216*10465441SEvalZero }
217*10465441SEvalZero 
218*10465441SEvalZero 
219*10465441SEvalZero #if PPP_SERVER
220*10465441SEvalZero /*
221*10465441SEvalZero  * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
222*10465441SEvalZero  */
upap_reqtimeout(void * arg)223*10465441SEvalZero static void upap_reqtimeout(void *arg) {
224*10465441SEvalZero     ppp_pcb *pcb = (ppp_pcb*)arg;
225*10465441SEvalZero 
226*10465441SEvalZero     if (pcb->upap.us_serverstate != UPAPSS_LISTEN)
227*10465441SEvalZero 	return;			/* huh?? */
228*10465441SEvalZero 
229*10465441SEvalZero     auth_peer_fail(pcb, PPP_PAP);
230*10465441SEvalZero     pcb->upap.us_serverstate = UPAPSS_BADAUTH;
231*10465441SEvalZero }
232*10465441SEvalZero #endif /* PPP_SERVER */
233*10465441SEvalZero 
234*10465441SEvalZero 
235*10465441SEvalZero /*
236*10465441SEvalZero  * upap_lowerup - The lower layer is up.
237*10465441SEvalZero  *
238*10465441SEvalZero  * Start authenticating if pending.
239*10465441SEvalZero  */
upap_lowerup(ppp_pcb * pcb)240*10465441SEvalZero static void upap_lowerup(ppp_pcb *pcb) {
241*10465441SEvalZero 
242*10465441SEvalZero     if (pcb->upap.us_clientstate == UPAPCS_INITIAL)
243*10465441SEvalZero 	pcb->upap.us_clientstate = UPAPCS_CLOSED;
244*10465441SEvalZero     else if (pcb->upap.us_clientstate == UPAPCS_PENDING) {
245*10465441SEvalZero 	upap_sauthreq(pcb);	/* send an auth-request */
246*10465441SEvalZero     }
247*10465441SEvalZero 
248*10465441SEvalZero #if PPP_SERVER
249*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_INITIAL)
250*10465441SEvalZero 	pcb->upap.us_serverstate = UPAPSS_CLOSED;
251*10465441SEvalZero     else if (pcb->upap.us_serverstate == UPAPSS_PENDING) {
252*10465441SEvalZero 	pcb->upap.us_serverstate = UPAPSS_LISTEN;
253*10465441SEvalZero 	if (pcb->settings.pap_req_timeout > 0)
254*10465441SEvalZero 	    TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout);
255*10465441SEvalZero     }
256*10465441SEvalZero #endif /* PPP_SERVER */
257*10465441SEvalZero }
258*10465441SEvalZero 
259*10465441SEvalZero 
260*10465441SEvalZero /*
261*10465441SEvalZero  * upap_lowerdown - The lower layer is down.
262*10465441SEvalZero  *
263*10465441SEvalZero  * Cancel all timeouts.
264*10465441SEvalZero  */
upap_lowerdown(ppp_pcb * pcb)265*10465441SEvalZero static void upap_lowerdown(ppp_pcb *pcb) {
266*10465441SEvalZero 
267*10465441SEvalZero     if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ)	/* Timeout pending? */
268*10465441SEvalZero 	UNTIMEOUT(upap_timeout, pcb);		/* Cancel timeout */
269*10465441SEvalZero #if PPP_SERVER
270*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0)
271*10465441SEvalZero 	UNTIMEOUT(upap_reqtimeout, pcb);
272*10465441SEvalZero #endif /* PPP_SERVER */
273*10465441SEvalZero 
274*10465441SEvalZero     pcb->upap.us_clientstate = UPAPCS_INITIAL;
275*10465441SEvalZero #if PPP_SERVER
276*10465441SEvalZero     pcb->upap.us_serverstate = UPAPSS_INITIAL;
277*10465441SEvalZero #endif /* PPP_SERVER */
278*10465441SEvalZero }
279*10465441SEvalZero 
280*10465441SEvalZero 
281*10465441SEvalZero /*
282*10465441SEvalZero  * upap_protrej - Peer doesn't speak this protocol.
283*10465441SEvalZero  *
284*10465441SEvalZero  * This shouldn't happen.  In any case, pretend lower layer went down.
285*10465441SEvalZero  */
upap_protrej(ppp_pcb * pcb)286*10465441SEvalZero static void upap_protrej(ppp_pcb *pcb) {
287*10465441SEvalZero 
288*10465441SEvalZero     if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) {
289*10465441SEvalZero 	ppp_error("PAP authentication failed due to protocol-reject");
290*10465441SEvalZero 	auth_withpeer_fail(pcb, PPP_PAP);
291*10465441SEvalZero     }
292*10465441SEvalZero #if PPP_SERVER
293*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_LISTEN) {
294*10465441SEvalZero 	ppp_error("PAP authentication of peer failed (protocol-reject)");
295*10465441SEvalZero 	auth_peer_fail(pcb, PPP_PAP);
296*10465441SEvalZero     }
297*10465441SEvalZero #endif /* PPP_SERVER */
298*10465441SEvalZero     upap_lowerdown(pcb);
299*10465441SEvalZero }
300*10465441SEvalZero 
301*10465441SEvalZero 
302*10465441SEvalZero /*
303*10465441SEvalZero  * upap_input - Input UPAP packet.
304*10465441SEvalZero  */
upap_input(ppp_pcb * pcb,u_char * inpacket,int l)305*10465441SEvalZero static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) {
306*10465441SEvalZero     u_char *inp;
307*10465441SEvalZero     u_char code, id;
308*10465441SEvalZero     int len;
309*10465441SEvalZero 
310*10465441SEvalZero     /*
311*10465441SEvalZero      * Parse header (code, id and length).
312*10465441SEvalZero      * If packet too short, drop it.
313*10465441SEvalZero      */
314*10465441SEvalZero     inp = inpacket;
315*10465441SEvalZero     if (l < UPAP_HEADERLEN) {
316*10465441SEvalZero 	UPAPDEBUG(("pap_input: rcvd short header."));
317*10465441SEvalZero 	return;
318*10465441SEvalZero     }
319*10465441SEvalZero     GETCHAR(code, inp);
320*10465441SEvalZero     GETCHAR(id, inp);
321*10465441SEvalZero     GETSHORT(len, inp);
322*10465441SEvalZero     if (len < UPAP_HEADERLEN) {
323*10465441SEvalZero 	UPAPDEBUG(("pap_input: rcvd illegal length."));
324*10465441SEvalZero 	return;
325*10465441SEvalZero     }
326*10465441SEvalZero     if (len > l) {
327*10465441SEvalZero 	UPAPDEBUG(("pap_input: rcvd short packet."));
328*10465441SEvalZero 	return;
329*10465441SEvalZero     }
330*10465441SEvalZero     len -= UPAP_HEADERLEN;
331*10465441SEvalZero 
332*10465441SEvalZero     /*
333*10465441SEvalZero      * Action depends on code.
334*10465441SEvalZero      */
335*10465441SEvalZero     switch (code) {
336*10465441SEvalZero     case UPAP_AUTHREQ:
337*10465441SEvalZero #if PPP_SERVER
338*10465441SEvalZero 	upap_rauthreq(pcb, inp, id, len);
339*10465441SEvalZero #endif /* PPP_SERVER */
340*10465441SEvalZero 	break;
341*10465441SEvalZero 
342*10465441SEvalZero     case UPAP_AUTHACK:
343*10465441SEvalZero 	upap_rauthack(pcb, inp, id, len);
344*10465441SEvalZero 	break;
345*10465441SEvalZero 
346*10465441SEvalZero     case UPAP_AUTHNAK:
347*10465441SEvalZero 	upap_rauthnak(pcb, inp, id, len);
348*10465441SEvalZero 	break;
349*10465441SEvalZero 
350*10465441SEvalZero     default:				/* XXX Need code reject */
351*10465441SEvalZero 	break;
352*10465441SEvalZero     }
353*10465441SEvalZero }
354*10465441SEvalZero 
355*10465441SEvalZero #if PPP_SERVER
356*10465441SEvalZero /*
357*10465441SEvalZero  * upap_rauth - Receive Authenticate.
358*10465441SEvalZero  */
upap_rauthreq(ppp_pcb * pcb,u_char * inp,int id,int len)359*10465441SEvalZero static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) {
360*10465441SEvalZero     u_char ruserlen, rpasswdlen;
361*10465441SEvalZero     char *ruser;
362*10465441SEvalZero     char *rpasswd;
363*10465441SEvalZero     char rhostname[256];
364*10465441SEvalZero     int retcode;
365*10465441SEvalZero     const char *msg;
366*10465441SEvalZero     int msglen;
367*10465441SEvalZero 
368*10465441SEvalZero     if (pcb->upap.us_serverstate < UPAPSS_LISTEN)
369*10465441SEvalZero 	return;
370*10465441SEvalZero 
371*10465441SEvalZero     /*
372*10465441SEvalZero      * If we receive a duplicate authenticate-request, we are
373*10465441SEvalZero      * supposed to return the same status as for the first request.
374*10465441SEvalZero      */
375*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_OPEN) {
376*10465441SEvalZero 	upap_sresp(pcb, UPAP_AUTHACK, id, "", 0);	/* return auth-ack */
377*10465441SEvalZero 	return;
378*10465441SEvalZero     }
379*10465441SEvalZero     if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) {
380*10465441SEvalZero 	upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0);	/* return auth-nak */
381*10465441SEvalZero 	return;
382*10465441SEvalZero     }
383*10465441SEvalZero 
384*10465441SEvalZero     /*
385*10465441SEvalZero      * Parse user/passwd.
386*10465441SEvalZero      */
387*10465441SEvalZero     if (len < 1) {
388*10465441SEvalZero 	UPAPDEBUG(("pap_rauth: rcvd short packet."));
389*10465441SEvalZero 	return;
390*10465441SEvalZero     }
391*10465441SEvalZero     GETCHAR(ruserlen, inp);
392*10465441SEvalZero     len -= sizeof (u_char) + ruserlen + sizeof (u_char);
393*10465441SEvalZero     if (len < 0) {
394*10465441SEvalZero 	UPAPDEBUG(("pap_rauth: rcvd short packet."));
395*10465441SEvalZero 	return;
396*10465441SEvalZero     }
397*10465441SEvalZero     ruser = (char *) inp;
398*10465441SEvalZero     INCPTR(ruserlen, inp);
399*10465441SEvalZero     GETCHAR(rpasswdlen, inp);
400*10465441SEvalZero     if (len < rpasswdlen) {
401*10465441SEvalZero 	UPAPDEBUG(("pap_rauth: rcvd short packet."));
402*10465441SEvalZero 	return;
403*10465441SEvalZero     }
404*10465441SEvalZero 
405*10465441SEvalZero     rpasswd = (char *) inp;
406*10465441SEvalZero 
407*10465441SEvalZero     /*
408*10465441SEvalZero      * Check the username and password given.
409*10465441SEvalZero      */
410*10465441SEvalZero     retcode = UPAP_AUTHNAK;
411*10465441SEvalZero     if (auth_check_passwd(pcb, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen)) {
412*10465441SEvalZero       retcode = UPAP_AUTHACK;
413*10465441SEvalZero     }
414*10465441SEvalZero     BZERO(rpasswd, rpasswdlen);
415*10465441SEvalZero 
416*10465441SEvalZero #if 0 /* UNUSED */
417*10465441SEvalZero     /*
418*10465441SEvalZero      * Check remote number authorization.  A plugin may have filled in
419*10465441SEvalZero      * the remote number or added an allowed number, and rather than
420*10465441SEvalZero      * return an authenticate failure, is leaving it for us to verify.
421*10465441SEvalZero      */
422*10465441SEvalZero     if (retcode == UPAP_AUTHACK) {
423*10465441SEvalZero 	if (!auth_number()) {
424*10465441SEvalZero 	    /* We do not want to leak info about the pap result. */
425*10465441SEvalZero 	    retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */
426*10465441SEvalZero 	    warn("calling number %q is not authorized", remote_number);
427*10465441SEvalZero 	}
428*10465441SEvalZero     }
429*10465441SEvalZero 
430*10465441SEvalZero     msglen = strlen(msg);
431*10465441SEvalZero     if (msglen > 255)
432*10465441SEvalZero 	msglen = 255;
433*10465441SEvalZero #endif /* UNUSED */
434*10465441SEvalZero 
435*10465441SEvalZero     upap_sresp(pcb, retcode, id, msg, msglen);
436*10465441SEvalZero 
437*10465441SEvalZero     /* Null terminate and clean remote name. */
438*10465441SEvalZero     ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser);
439*10465441SEvalZero 
440*10465441SEvalZero     if (retcode == UPAP_AUTHACK) {
441*10465441SEvalZero 	pcb->upap.us_serverstate = UPAPSS_OPEN;
442*10465441SEvalZero 	ppp_notice("PAP peer authentication succeeded for %q", rhostname);
443*10465441SEvalZero 	auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen);
444*10465441SEvalZero     } else {
445*10465441SEvalZero 	pcb->upap.us_serverstate = UPAPSS_BADAUTH;
446*10465441SEvalZero 	ppp_warn("PAP peer authentication failed for %q", rhostname);
447*10465441SEvalZero 	auth_peer_fail(pcb, PPP_PAP);
448*10465441SEvalZero     }
449*10465441SEvalZero 
450*10465441SEvalZero     if (pcb->settings.pap_req_timeout > 0)
451*10465441SEvalZero 	UNTIMEOUT(upap_reqtimeout, pcb);
452*10465441SEvalZero }
453*10465441SEvalZero #endif /* PPP_SERVER */
454*10465441SEvalZero 
455*10465441SEvalZero /*
456*10465441SEvalZero  * upap_rauthack - Receive Authenticate-Ack.
457*10465441SEvalZero  */
upap_rauthack(ppp_pcb * pcb,u_char * inp,int id,int len)458*10465441SEvalZero static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) {
459*10465441SEvalZero     u_char msglen;
460*10465441SEvalZero     char *msg;
461*10465441SEvalZero     LWIP_UNUSED_ARG(id);
462*10465441SEvalZero 
463*10465441SEvalZero     if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
464*10465441SEvalZero 	return;
465*10465441SEvalZero 
466*10465441SEvalZero     /*
467*10465441SEvalZero      * Parse message.
468*10465441SEvalZero      */
469*10465441SEvalZero     if (len < 1) {
470*10465441SEvalZero 	UPAPDEBUG(("pap_rauthack: ignoring missing msg-length."));
471*10465441SEvalZero     } else {
472*10465441SEvalZero 	GETCHAR(msglen, inp);
473*10465441SEvalZero 	if (msglen > 0) {
474*10465441SEvalZero 	    len -= sizeof (u_char);
475*10465441SEvalZero 	    if (len < msglen) {
476*10465441SEvalZero 		UPAPDEBUG(("pap_rauthack: rcvd short packet."));
477*10465441SEvalZero 		return;
478*10465441SEvalZero 	    }
479*10465441SEvalZero 	    msg = (char *) inp;
480*10465441SEvalZero 	    PRINTMSG(msg, msglen);
481*10465441SEvalZero 	}
482*10465441SEvalZero     }
483*10465441SEvalZero 
484*10465441SEvalZero     pcb->upap.us_clientstate = UPAPCS_OPEN;
485*10465441SEvalZero 
486*10465441SEvalZero     auth_withpeer_success(pcb, PPP_PAP, 0);
487*10465441SEvalZero }
488*10465441SEvalZero 
489*10465441SEvalZero 
490*10465441SEvalZero /*
491*10465441SEvalZero  * upap_rauthnak - Receive Authenticate-Nak.
492*10465441SEvalZero  */
upap_rauthnak(ppp_pcb * pcb,u_char * inp,int id,int len)493*10465441SEvalZero static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) {
494*10465441SEvalZero     u_char msglen;
495*10465441SEvalZero     char *msg;
496*10465441SEvalZero     LWIP_UNUSED_ARG(id);
497*10465441SEvalZero 
498*10465441SEvalZero     if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
499*10465441SEvalZero 	return;
500*10465441SEvalZero 
501*10465441SEvalZero     /*
502*10465441SEvalZero      * Parse message.
503*10465441SEvalZero      */
504*10465441SEvalZero     if (len < 1) {
505*10465441SEvalZero 	UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
506*10465441SEvalZero     } else {
507*10465441SEvalZero 	GETCHAR(msglen, inp);
508*10465441SEvalZero 	if (msglen > 0) {
509*10465441SEvalZero 	    len -= sizeof (u_char);
510*10465441SEvalZero 	    if (len < msglen) {
511*10465441SEvalZero 		UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
512*10465441SEvalZero 		return;
513*10465441SEvalZero 	    }
514*10465441SEvalZero 	    msg = (char *) inp;
515*10465441SEvalZero 	    PRINTMSG(msg, msglen);
516*10465441SEvalZero 	}
517*10465441SEvalZero     }
518*10465441SEvalZero 
519*10465441SEvalZero     pcb->upap.us_clientstate = UPAPCS_BADAUTH;
520*10465441SEvalZero 
521*10465441SEvalZero     ppp_error("PAP authentication failed");
522*10465441SEvalZero     auth_withpeer_fail(pcb, PPP_PAP);
523*10465441SEvalZero }
524*10465441SEvalZero 
525*10465441SEvalZero 
526*10465441SEvalZero /*
527*10465441SEvalZero  * upap_sauthreq - Send an Authenticate-Request.
528*10465441SEvalZero  */
upap_sauthreq(ppp_pcb * pcb)529*10465441SEvalZero static void upap_sauthreq(ppp_pcb *pcb) {
530*10465441SEvalZero     struct pbuf *p;
531*10465441SEvalZero     u_char *outp;
532*10465441SEvalZero     int outlen;
533*10465441SEvalZero 
534*10465441SEvalZero     outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
535*10465441SEvalZero 	pcb->upap.us_userlen + pcb->upap.us_passwdlen;
536*10465441SEvalZero     p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
537*10465441SEvalZero     if(NULL == p)
538*10465441SEvalZero         return;
539*10465441SEvalZero     if(p->tot_len != p->len) {
540*10465441SEvalZero         pbuf_free(p);
541*10465441SEvalZero         return;
542*10465441SEvalZero     }
543*10465441SEvalZero 
544*10465441SEvalZero     outp = (u_char*)p->payload;
545*10465441SEvalZero     MAKEHEADER(outp, PPP_PAP);
546*10465441SEvalZero 
547*10465441SEvalZero     PUTCHAR(UPAP_AUTHREQ, outp);
548*10465441SEvalZero     PUTCHAR(++pcb->upap.us_id, outp);
549*10465441SEvalZero     PUTSHORT(outlen, outp);
550*10465441SEvalZero     PUTCHAR(pcb->upap.us_userlen, outp);
551*10465441SEvalZero     MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen);
552*10465441SEvalZero     INCPTR(pcb->upap.us_userlen, outp);
553*10465441SEvalZero     PUTCHAR(pcb->upap.us_passwdlen, outp);
554*10465441SEvalZero     MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen);
555*10465441SEvalZero 
556*10465441SEvalZero     ppp_write(pcb, p);
557*10465441SEvalZero 
558*10465441SEvalZero     TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time);
559*10465441SEvalZero     ++pcb->upap.us_transmits;
560*10465441SEvalZero     pcb->upap.us_clientstate = UPAPCS_AUTHREQ;
561*10465441SEvalZero }
562*10465441SEvalZero 
563*10465441SEvalZero #if PPP_SERVER
564*10465441SEvalZero /*
565*10465441SEvalZero  * upap_sresp - Send a response (ack or nak).
566*10465441SEvalZero  */
upap_sresp(ppp_pcb * pcb,u_char code,u_char id,const char * msg,int msglen)567*10465441SEvalZero static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) {
568*10465441SEvalZero     struct pbuf *p;
569*10465441SEvalZero     u_char *outp;
570*10465441SEvalZero     int outlen;
571*10465441SEvalZero 
572*10465441SEvalZero     outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
573*10465441SEvalZero     p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
574*10465441SEvalZero     if(NULL == p)
575*10465441SEvalZero         return;
576*10465441SEvalZero     if(p->tot_len != p->len) {
577*10465441SEvalZero         pbuf_free(p);
578*10465441SEvalZero         return;
579*10465441SEvalZero     }
580*10465441SEvalZero 
581*10465441SEvalZero     outp = (u_char*)p->payload;
582*10465441SEvalZero     MAKEHEADER(outp, PPP_PAP);
583*10465441SEvalZero 
584*10465441SEvalZero     PUTCHAR(code, outp);
585*10465441SEvalZero     PUTCHAR(id, outp);
586*10465441SEvalZero     PUTSHORT(outlen, outp);
587*10465441SEvalZero     PUTCHAR(msglen, outp);
588*10465441SEvalZero     MEMCPY(outp, msg, msglen);
589*10465441SEvalZero 
590*10465441SEvalZero     ppp_write(pcb, p);
591*10465441SEvalZero }
592*10465441SEvalZero #endif /* PPP_SERVER */
593*10465441SEvalZero 
594*10465441SEvalZero #if PRINTPKT_SUPPORT
595*10465441SEvalZero /*
596*10465441SEvalZero  * upap_printpkt - print the contents of a PAP packet.
597*10465441SEvalZero  */
598*10465441SEvalZero static const char* const upap_codenames[] = {
599*10465441SEvalZero     "AuthReq", "AuthAck", "AuthNak"
600*10465441SEvalZero };
601*10465441SEvalZero 
upap_printpkt(const u_char * p,int plen,void (* printer)(void *,const char *,...),void * arg)602*10465441SEvalZero static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) {
603*10465441SEvalZero     int code, id, len;
604*10465441SEvalZero     int mlen, ulen, wlen;
605*10465441SEvalZero     const u_char *user, *pwd, *msg;
606*10465441SEvalZero     const u_char *pstart;
607*10465441SEvalZero 
608*10465441SEvalZero     if (plen < UPAP_HEADERLEN)
609*10465441SEvalZero 	return 0;
610*10465441SEvalZero     pstart = p;
611*10465441SEvalZero     GETCHAR(code, p);
612*10465441SEvalZero     GETCHAR(id, p);
613*10465441SEvalZero     GETSHORT(len, p);
614*10465441SEvalZero     if (len < UPAP_HEADERLEN || len > plen)
615*10465441SEvalZero 	return 0;
616*10465441SEvalZero 
617*10465441SEvalZero     if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(upap_codenames))
618*10465441SEvalZero 	printer(arg, " %s", upap_codenames[code-1]);
619*10465441SEvalZero     else
620*10465441SEvalZero 	printer(arg, " code=0x%x", code);
621*10465441SEvalZero     printer(arg, " id=0x%x", id);
622*10465441SEvalZero     len -= UPAP_HEADERLEN;
623*10465441SEvalZero     switch (code) {
624*10465441SEvalZero     case UPAP_AUTHREQ:
625*10465441SEvalZero 	if (len < 1)
626*10465441SEvalZero 	    break;
627*10465441SEvalZero 	ulen = p[0];
628*10465441SEvalZero 	if (len < ulen + 2)
629*10465441SEvalZero 	    break;
630*10465441SEvalZero 	wlen = p[ulen + 1];
631*10465441SEvalZero 	if (len < ulen + wlen + 2)
632*10465441SEvalZero 	    break;
633*10465441SEvalZero 	user = (const u_char *) (p + 1);
634*10465441SEvalZero 	pwd = (const u_char *) (p + ulen + 2);
635*10465441SEvalZero 	p += ulen + wlen + 2;
636*10465441SEvalZero 	len -= ulen + wlen + 2;
637*10465441SEvalZero 	printer(arg, " user=");
638*10465441SEvalZero 	ppp_print_string(user, ulen, printer, arg);
639*10465441SEvalZero 	printer(arg, " password=");
640*10465441SEvalZero /* FIXME: require ppp_pcb struct as printpkt() argument */
641*10465441SEvalZero #if 0
642*10465441SEvalZero 	if (!pcb->settings.hide_password)
643*10465441SEvalZero #endif
644*10465441SEvalZero 	    ppp_print_string(pwd, wlen, printer, arg);
645*10465441SEvalZero #if 0
646*10465441SEvalZero 	else
647*10465441SEvalZero 	    printer(arg, "<hidden>");
648*10465441SEvalZero #endif
649*10465441SEvalZero 	break;
650*10465441SEvalZero     case UPAP_AUTHACK:
651*10465441SEvalZero     case UPAP_AUTHNAK:
652*10465441SEvalZero 	if (len < 1)
653*10465441SEvalZero 	    break;
654*10465441SEvalZero 	mlen = p[0];
655*10465441SEvalZero 	if (len < mlen + 1)
656*10465441SEvalZero 	    break;
657*10465441SEvalZero 	msg = (const u_char *) (p + 1);
658*10465441SEvalZero 	p += mlen + 1;
659*10465441SEvalZero 	len -= mlen + 1;
660*10465441SEvalZero 	printer(arg, " ");
661*10465441SEvalZero 	ppp_print_string(msg, mlen, printer, arg);
662*10465441SEvalZero 	break;
663*10465441SEvalZero     default:
664*10465441SEvalZero 	break;
665*10465441SEvalZero     }
666*10465441SEvalZero 
667*10465441SEvalZero     /* print the rest of the bytes in the packet */
668*10465441SEvalZero     for (; len > 0; --len) {
669*10465441SEvalZero 	GETCHAR(code, p);
670*10465441SEvalZero 	printer(arg, " %.2x", code);
671*10465441SEvalZero     }
672*10465441SEvalZero 
673*10465441SEvalZero     return p - pstart;
674*10465441SEvalZero }
675*10465441SEvalZero #endif /* PRINTPKT_SUPPORT */
676*10465441SEvalZero 
677*10465441SEvalZero #endif /* PPP_SUPPORT && PAP_SUPPORT */
678