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