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