xref: /btstack/3rd-party/lwip/core/src/netif/ppp/upap.c (revision 97dc5e692c7d94a280158af58036a0efee5b0e56)
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      pcb->upap.us_clientstate = UPAPCS_OPEN;
485  
486      auth_withpeer_success(pcb, PPP_PAP, 0);
487  }
488  
489  
490  /*
491   * upap_rauthnak - Receive Authenticate-Nak.
492   */
upap_rauthnak(ppp_pcb * pcb,u_char * inp,int id,int len)493  static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) {
494      u_char msglen;
495      char *msg;
496      LWIP_UNUSED_ARG(id);
497  
498      if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */
499  	return;
500  
501      /*
502       * Parse message.
503       */
504      if (len < 1) {
505  	UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length."));
506      } else {
507  	GETCHAR(msglen, inp);
508  	if (msglen > 0) {
509  	    len -= sizeof (u_char);
510  	    if (len < msglen) {
511  		UPAPDEBUG(("pap_rauthnak: rcvd short packet."));
512  		return;
513  	    }
514  	    msg = (char *) inp;
515  	    PRINTMSG(msg, msglen);
516  	}
517      }
518  
519      pcb->upap.us_clientstate = UPAPCS_BADAUTH;
520  
521      ppp_error("PAP authentication failed");
522      auth_withpeer_fail(pcb, PPP_PAP);
523  }
524  
525  
526  /*
527   * upap_sauthreq - Send an Authenticate-Request.
528   */
upap_sauthreq(ppp_pcb * pcb)529  static void upap_sauthreq(ppp_pcb *pcb) {
530      struct pbuf *p;
531      u_char *outp;
532      int outlen;
533  
534      outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
535  	pcb->upap.us_userlen + pcb->upap.us_passwdlen;
536      p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
537      if(NULL == p)
538          return;
539      if(p->tot_len != p->len) {
540          pbuf_free(p);
541          return;
542      }
543  
544      outp = (u_char*)p->payload;
545      MAKEHEADER(outp, PPP_PAP);
546  
547      PUTCHAR(UPAP_AUTHREQ, outp);
548      PUTCHAR(++pcb->upap.us_id, outp);
549      PUTSHORT(outlen, outp);
550      PUTCHAR(pcb->upap.us_userlen, outp);
551      MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen);
552      INCPTR(pcb->upap.us_userlen, outp);
553      PUTCHAR(pcb->upap.us_passwdlen, outp);
554      MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen);
555  
556      ppp_write(pcb, p);
557  
558      TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time);
559      ++pcb->upap.us_transmits;
560      pcb->upap.us_clientstate = UPAPCS_AUTHREQ;
561  }
562  
563  #if PPP_SERVER
564  /*
565   * upap_sresp - Send a response (ack or nak).
566   */
upap_sresp(ppp_pcb * pcb,u_char code,u_char id,const char * msg,int msglen)567  static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) {
568      struct pbuf *p;
569      u_char *outp;
570      int outlen;
571  
572      outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
573      p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE);
574      if(NULL == p)
575          return;
576      if(p->tot_len != p->len) {
577          pbuf_free(p);
578          return;
579      }
580  
581      outp = (u_char*)p->payload;
582      MAKEHEADER(outp, PPP_PAP);
583  
584      PUTCHAR(code, outp);
585      PUTCHAR(id, outp);
586      PUTSHORT(outlen, outp);
587      PUTCHAR(msglen, outp);
588      MEMCPY(outp, msg, msglen);
589  
590      ppp_write(pcb, p);
591  }
592  #endif /* PPP_SERVER */
593  
594  #if PRINTPKT_SUPPORT
595  /*
596   * upap_printpkt - print the contents of a PAP packet.
597   */
598  static const char* const upap_codenames[] = {
599      "AuthReq", "AuthAck", "AuthNak"
600  };
601  
upap_printpkt(const u_char * p,int plen,void (* printer)(void *,const char *,...),void * arg)602  static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) {
603      int code, id, len;
604      int mlen, ulen, wlen;
605      const u_char *user, *pwd, *msg;
606      const u_char *pstart;
607  
608      if (plen < UPAP_HEADERLEN)
609  	return 0;
610      pstart = p;
611      GETCHAR(code, p);
612      GETCHAR(id, p);
613      GETSHORT(len, p);
614      if (len < UPAP_HEADERLEN || len > plen)
615  	return 0;
616  
617      if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(upap_codenames))
618  	printer(arg, " %s", upap_codenames[code-1]);
619      else
620  	printer(arg, " code=0x%x", code);
621      printer(arg, " id=0x%x", id);
622      len -= UPAP_HEADERLEN;
623      switch (code) {
624      case UPAP_AUTHREQ:
625  	if (len < 1)
626  	    break;
627  	ulen = p[0];
628  	if (len < ulen + 2)
629  	    break;
630  	wlen = p[ulen + 1];
631  	if (len < ulen + wlen + 2)
632  	    break;
633  	user = (const u_char *) (p + 1);
634  	pwd = (const u_char *) (p + ulen + 2);
635  	p += ulen + wlen + 2;
636  	len -= ulen + wlen + 2;
637  	printer(arg, " user=");
638  	ppp_print_string(user, ulen, printer, arg);
639  	printer(arg, " password=");
640  /* FIXME: require ppp_pcb struct as printpkt() argument */
641  #if 0
642  	if (!pcb->settings.hide_password)
643  #endif
644  	    ppp_print_string(pwd, wlen, printer, arg);
645  #if 0
646  	else
647  	    printer(arg, "<hidden>");
648  #endif
649  	break;
650      case UPAP_AUTHACK:
651      case UPAP_AUTHNAK:
652  	if (len < 1)
653  	    break;
654  	mlen = p[0];
655  	if (len < mlen + 1)
656  	    break;
657  	msg = (const u_char *) (p + 1);
658  	p += mlen + 1;
659  	len -= mlen + 1;
660  	printer(arg, " ");
661  	ppp_print_string(msg, mlen, printer, arg);
662  	break;
663      default:
664  	break;
665      }
666  
667      /* print the rest of the bytes in the packet */
668      for (; len > 0; --len) {
669  	GETCHAR(code, p);
670  	printer(arg, " %.2x", code);
671      }
672  
673      return p - pstart;
674  }
675  #endif /* PRINTPKT_SUPPORT */
676  
677  #endif /* PPP_SUPPORT && PAP_SUPPORT */
678