X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fchap.c;h=b8a5d0f726ffe9f723d1eaf344a52d45b1591ef9;hp=e0ea4afeee00e569bb28879fc4f32909043ae20d;hb=31b4bba68d46b38119fd8620ee09ff7f8831f4b5;hpb=0b63a24d54ba4708c88e31bdd74b0145956c1478 diff --git a/pppd/chap.c b/pppd/chap.c index e0ea4af..b8a5d0f 100644 --- a/pppd/chap.c +++ b/pppd/chap.c @@ -1,5 +1,20 @@ /* - * chap.c - Crytographic Handshake Authentication Protocol. + * chap.c - Challenge Handshake Authentication Protocol. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Copyright (c) 1991 Gregory M. Christy. * All rights reserved. @@ -18,44 +33,95 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static char rcsid[] = "$Id: chap.c,v 1.1 1993/11/11 03:54:25 paulus Exp $"; -#endif +#define RCSID "$Id: chap.c,v 1.23 1999/08/13 06:46:11 paulus Exp $" /* * TODO: */ #include +#include #include #include -#include -#include "ppp.h" #include "pppd.h" #include "chap.h" #include "md5.h" +#ifdef CHAPMS +#include "chap_ms.h" +#endif -chap_state chap[NPPP]; /* CHAP state; one for each unit */ +static const char rcsid[] = RCSID; -static void ChapChallengeTimeout __ARGS((caddr_t)); -static void ChapResponseTimeout __ARGS((caddr_t)); -static void ChapReceiveChallenge __ARGS((chap_state *, u_char *, int, int)); -static void ChapReceiveResponse __ARGS((chap_state *, u_char *, int, int)); -static void ChapReceiveSuccess __ARGS((chap_state *, u_char *, int, int)); -static void ChapReceiveFailure __ARGS((chap_state *, u_char *, int, int)); -static void ChapSendStatus __ARGS((chap_state *, int)); -static void ChapSendChallenge __ARGS((chap_state *)); -static void ChapSendResponse __ARGS((chap_state *)); -static void ChapGenChallenge __ARGS((chap_state *)); +/* + * Command-line options. + */ +static option_t chap_option_list[] = { + { "chap-restart", o_int, &chap[0].timeouttime, + "Set timeout for CHAP" }, + { "chap-max-challenge", o_int, &chap[0].max_transmits, + "Set max #xmits for challenge" }, + { "chap-interval", o_int, &chap[0].chal_interval, + "Set interval for rechallenge" }, +#ifdef MSLANMAN + { "ms-lanman", o_bool, &ms_lanman, + "Use LanMan passwd when using MS-CHAP", 1 }, +#endif + { NULL } +}; -extern double drand48 __ARGS((void)); -extern void srand48 __ARGS((long)); +/* + * Protocol entry points. + */ +static void ChapInit __P((int)); +static void ChapLowerUp __P((int)); +static void ChapLowerDown __P((int)); +static void ChapInput __P((int, u_char *, int)); +static void ChapProtocolReject __P((int)); +static int ChapPrintPkt __P((u_char *, int, + void (*) __P((void *, char *, ...)), void *)); + +struct protent chap_protent = { + PPP_CHAP, + ChapInit, + ChapInput, + ChapProtocolReject, + ChapLowerUp, + ChapLowerDown, + NULL, + NULL, + ChapPrintPkt, + NULL, + 1, + "CHAP", + NULL, + chap_option_list, + NULL, + NULL, + NULL +}; + +chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ + +static void ChapChallengeTimeout __P((void *)); +static void ChapResponseTimeout __P((void *)); +static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int)); +static void ChapRechallenge __P((void *)); +static void ChapReceiveResponse __P((chap_state *, u_char *, int, int)); +static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int)); +static void ChapReceiveFailure __P((chap_state *, u_char *, int, int)); +static void ChapSendStatus __P((chap_state *, int)); +static void ChapSendChallenge __P((chap_state *)); +static void ChapSendResponse __P((chap_state *)); +static void ChapGenChallenge __P((chap_state *)); + +extern double drand48 __P((void)); +extern void srand48 __P((long)); /* * ChapInit - Initialize a CHAP unit. */ -void +static void ChapInit(unit) int unit; { @@ -67,7 +133,7 @@ ChapInit(unit) cstate->serverstate = CHAPSS_INITIAL; cstate->timeouttime = CHAP_DEFTIMEOUT; cstate->max_transmits = CHAP_DEFTRANSMITS; - srand48((long) time(NULL)); /* joggle random number generator */ + /* random number generator is initialized in magic_init */ } @@ -134,7 +200,7 @@ ChapAuthPeer(unit, our_name, digest) */ static void ChapChallengeTimeout(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -146,9 +212,9 @@ ChapChallengeTimeout(arg) if (cstate->chal_transmits >= cstate->max_transmits) { /* give up on peer */ - syslog(LOG_ERR, "Peer failed to respond to CHAP challenge"); + error("Peer failed to respond to CHAP challenge"); cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, CHAP); + auth_peer_fail(cstate->unit, PPP_CHAP); return; } @@ -161,7 +227,7 @@ ChapChallengeTimeout(arg) */ static void ChapResponseTimeout(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -178,7 +244,7 @@ ChapResponseTimeout(arg) */ static void ChapRechallenge(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -189,9 +255,6 @@ ChapRechallenge(arg) ChapGenChallenge(cstate); ChapSendChallenge(cstate); cstate->serverstate = CHAPSS_RECHALLENGE; - - if (cstate->chal_interval != 0) - TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval); } @@ -200,7 +263,7 @@ ChapRechallenge(arg) * * Start up if we have pending requests. */ -void +static void ChapLowerUp(unit) int unit; { @@ -226,7 +289,7 @@ ChapLowerUp(unit) * * Cancel all timeouts. */ -void +static void ChapLowerDown(unit) int unit; { @@ -235,12 +298,12 @@ ChapLowerDown(unit) /* Timeout(s) pending? Cancel if so. */ if (cstate->serverstate == CHAPSS_INITIAL_CHAL || cstate->serverstate == CHAPSS_RECHALLENGE) - UNTIMEOUT(ChapChallengeTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapChallengeTimeout, cstate); else if (cstate->serverstate == CHAPSS_OPEN && cstate->chal_interval != 0) - UNTIMEOUT(ChapRechallenge, (caddr_t) cstate); + UNTIMEOUT(ChapRechallenge, cstate); if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapResponseTimeout, cstate); cstate->clientstate = CHAPCS_INITIAL; cstate->serverstate = CHAPSS_INITIAL; @@ -250,7 +313,7 @@ ChapLowerDown(unit) /* * ChapProtocolReject - Peer doesn't grok CHAP. */ -void +static void ChapProtocolReject(unit) int unit; { @@ -258,10 +321,10 @@ ChapProtocolReject(unit) if (cstate->serverstate != CHAPSS_INITIAL && cstate->serverstate != CHAPSS_CLOSED) - auth_peer_fail(unit, CHAP); + auth_peer_fail(unit, PPP_CHAP); if (cstate->clientstate != CHAPCS_INITIAL && cstate->clientstate != CHAPCS_CLOSED) - auth_withpeer_fail(unit, CHAP); + auth_withpeer_fail(unit, PPP_CHAP); ChapLowerDown(unit); /* shutdown chap */ } @@ -269,7 +332,7 @@ ChapProtocolReject(unit) /* * ChapInput - Input CHAP packet. */ -void +static void ChapInput(unit, inpacket, packet_len) int unit; u_char *inpacket; @@ -286,18 +349,18 @@ ChapInput(unit, inpacket, packet_len) */ inp = inpacket; if (packet_len < CHAP_HEADERLEN) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.")); + CHAPDEBUG(("ChapInput: rcvd short header.")); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < CHAP_HEADERLEN) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.")); + CHAPDEBUG(("ChapInput: rcvd illegal length.")); return; } if (len > packet_len) { - CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.")); + CHAPDEBUG(("ChapInput: rcvd short packet.")); return; } len -= CHAP_HEADERLEN; @@ -323,7 +386,7 @@ ChapInput(unit, inpacket, packet_len) break; default: /* Need code reject? */ - syslog(LOG_WARNING, "Unknown CHAP code (%d) received.", code); + warn("Unknown CHAP code (%d) received.", code); break; } } @@ -345,24 +408,23 @@ ChapReceiveChallenge(cstate, inp, id, len) char secret[MAXSECRETLEN]; char rhostname[256]; MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id)); if (cstate->clientstate == CHAPCS_CLOSED || cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d", - cstate->clientstate)); + CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate)); return; } if (len < 2) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.")); + CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); return; } GETCHAR(rchallenge_len, inp); len -= sizeof (u_char) + rchallenge_len; /* now name field length */ if (len < 0) { - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.")); + CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); return; } rchallenge = inp; @@ -373,20 +435,23 @@ ChapReceiveChallenge(cstate, inp, id, len) BCOPY(inp, rhostname, len); rhostname[len] = '\000'; - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: %s", - rhostname)); + /* Microsoft doesn't send their name back in the PPP packet */ + if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) { + strlcpy(rhostname, remote_name, sizeof(rhostname)); + CHAPDEBUG(("ChapReceiveChallenge: using '%q' as remote name", + rhostname)); + } /* get secret for authenticating ourselves with the specified host */ if (!get_secret(cstate->unit, cstate->resp_name, rhostname, secret, &secret_len, 0)) { secret_len = 0; /* assume null secret if can't find one */ - syslog(LOG_WARNING, "No CHAP secret found for authenticating us to %s", - rhostname); + warn("No CHAP secret found for authenticating us to %q", rhostname); } /* cancel response send timeout if necessary */ if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapResponseTimeout, cstate); cstate->resp_id = id; cstate->resp_transmits = 0; @@ -394,21 +459,28 @@ ChapReceiveChallenge(cstate, inp, id, len) /* generate MD based on negotiated type */ switch (cstate->resp_type) { - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ + case CHAP_DIGEST_MD5: MD5Init(&mdContext); MD5Update(&mdContext, &cstate->resp_id, 1); MD5Update(&mdContext, secret, secret_len); MD5Update(&mdContext, rchallenge, rchallenge_len); - MD5Final(&mdContext); - BCOPY(mdContext.digest, cstate->response, MD5_SIGNATURE_SIZE); + MD5Final(hash, &mdContext); + BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); cstate->resp_length = MD5_SIGNATURE_SIZE; break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); + break; +#endif + default: - CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type)); + CHAPDEBUG(("unknown digest type %d", cstate->resp_type)); return; } + BZERO(secret, sizeof(secret)); ChapSendResponse(cstate); } @@ -427,17 +499,13 @@ ChapReceiveResponse(cstate, inp, id, len) int secret_len, old_state; int code; char rhostname[256]; - u_char buf[256]; MD5_CTX mdContext; - u_char msg[256]; char secret[MAXSECRETLEN]; - - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id)); + u_char hash[MD5_SIGNATURE_SIZE]; if (cstate->serverstate == CHAPSS_CLOSED || cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d", - cstate->serverstate)); + CHAPDEBUG(("ChapReceiveResponse: in state %d", cstate->serverstate)); return; } @@ -459,7 +527,7 @@ ChapReceiveResponse(cstate, inp, id, len) } if (len < 2) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.")); + CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); return; } GETCHAR(remmd_len, inp); /* get length of MD */ @@ -468,29 +536,25 @@ ChapReceiveResponse(cstate, inp, id, len) len -= sizeof (u_char) + remmd_len; if (len < 0) { - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.")); + CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); return; } - UNTIMEOUT(ChapChallengeTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapChallengeTimeout, cstate); if (len >= sizeof(rhostname)) len = sizeof(rhostname) - 1; BCOPY(inp, rhostname, len); rhostname[len] = '\000'; - CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s", - rhostname)); - /* * Get secret for authenticating them with us, * do the hash ourselves, and compare the result. */ code = CHAP_FAILURE; - if (!get_secret(cstate->unit, rhostname, cstate->chal_name, - secret, &secret_len, 1)) { - syslog(LOG_WARNING, "No CHAP secret found for authenticating %s", - rhostname); + if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname), + cstate->chal_name, secret, &secret_len, 1)) { + warn("No CHAP secret found for authenticating %q", rhostname); } else { /* generate MD based on negotiated type */ @@ -503,33 +567,35 @@ ChapReceiveResponse(cstate, inp, id, len) MD5Update(&mdContext, &cstate->chal_id, 1); MD5Update(&mdContext, secret, secret_len); MD5Update(&mdContext, cstate->challenge, cstate->chal_len); - MD5Final(&mdContext); + MD5Final(hash, &mdContext); /* compare local and remote MDs and send the appropriate status */ - if (bcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0) + if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) code = CHAP_SUCCESS; /* they are the same! */ break; default: - CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type)); + CHAPDEBUG(("unknown digest type %d", cstate->chal_type)); } } + BZERO(secret, sizeof(secret)); ChapSendStatus(cstate, code); if (code == CHAP_SUCCESS) { old_state = cstate->serverstate; cstate->serverstate = CHAPSS_OPEN; if (old_state == CHAPSS_INITIAL_CHAL) { - auth_peer_success(cstate->unit, CHAP); + auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); } if (cstate->chal_interval != 0) - TIMEOUT(ChapRechallenge, (caddr_t) cstate, cstate->chal_interval); + TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); + notice("CHAP peer authentication succeeded for %q", rhostname); } else { - syslog(LOG_ERR, "CHAP peer authentication failed"); + error("CHAP peer authentication failed for remote host %q", rhostname); cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, CHAP); + auth_peer_fail(cstate->unit, PPP_CHAP); } } @@ -544,19 +610,18 @@ ChapReceiveSuccess(cstate, inp, id, len) int len; { - CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.", id)); - if (cstate->clientstate == CHAPCS_OPEN) /* presumably an answer to a duplicate response */ return; if (cstate->clientstate != CHAPCS_RESPONSE) { /* don't know what this is */ - CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n", - cstate->clientstate)); + CHAPDEBUG(("ChapReceiveSuccess: in state %d\n", cstate->clientstate)); return; } + UNTIMEOUT(ChapResponseTimeout, cstate); + /* * Print message. */ @@ -565,7 +630,7 @@ ChapReceiveSuccess(cstate, inp, id, len) cstate->clientstate = CHAPCS_OPEN; - auth_withpeer_success(cstate->unit, CHAP); + auth_withpeer_success(cstate->unit, PPP_CHAP); } @@ -579,26 +644,22 @@ ChapReceiveFailure(cstate, inp, id, len) u_char id; int len; { - u_char msglen; - u_char *msg; - - CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id)); - if (cstate->clientstate != CHAPCS_RESPONSE) { /* don't know what this is */ - CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n", - cstate->clientstate)); + CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate)); return; } + UNTIMEOUT(ChapResponseTimeout, cstate); + /* * Print message. */ if (len > 0) PRINTMSG(inp, len); - syslog(LOG_ERR, "CHAP authentication failed"); - auth_withpeer_fail(cstate->unit, CHAP); + error("CHAP authentication failed"); + auth_withpeer_fail(cstate->unit, PPP_CHAP); } @@ -618,7 +679,7 @@ ChapSendChallenge(cstate) outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; outp = outpacket_buf; - MAKEHEADER(outp, CHAP); /* paste in a CHAP header */ + MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ PUTCHAR(CHAP_CHALLENGE, outp); PUTCHAR(cstate->chal_id, outp); @@ -630,11 +691,9 @@ ChapSendChallenge(cstate) BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ - output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN); + output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id)); - - TIMEOUT(ChapChallengeTimeout, (caddr_t) cstate, cstate->timeouttime); + TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); ++cstate->chal_transmits; } @@ -652,24 +711,21 @@ ChapSendStatus(cstate, code) char msg[256]; if (code == CHAP_SUCCESS) - sprintf(msg, "Welcome to %s.", hostname); + slprintf(msg, sizeof(msg), "Welcome to %s.", hostname); else - sprintf(msg, "I don't like you. Go 'way."); + slprintf(msg, sizeof(msg), "I don't like you. Go 'way."); msglen = strlen(msg); outlen = CHAP_HEADERLEN + msglen; outp = outpacket_buf; - MAKEHEADER(outp, CHAP); /* paste in a header */ + MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ PUTCHAR(code, outp); PUTCHAR(cstate->chal_id, outp); PUTSHORT(outlen, outp); BCOPY(msg, outp, msglen); - output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN); - - CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code, - cstate->chal_id)); + output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); } /* @@ -718,7 +774,7 @@ ChapSendResponse(cstate) outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; outp = outpacket_buf; - MAKEHEADER(outp, CHAP); + MAKEHEADER(outp, PPP_CHAP); PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ @@ -731,24 +787,74 @@ ChapSendResponse(cstate) BCOPY(cstate->resp_name, outp, name_len); /* append our name */ /* send the packet */ - output(cstate->unit, outpacket_buf, outlen + DLLHEADERLEN); + output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, (caddr_t) cstate, cstate->timeouttime); + TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); ++cstate->resp_transmits; } -#ifdef NO_DRAND48 - -double drand48() +/* + * ChapPrintPkt - print the contents of a CHAP packet. + */ +static char *ChapCodenames[] = { + "Challenge", "Response", "Success", "Failure" +}; + +static int +ChapPrintPkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; { - return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ -} + int code, id, len; + int clen, nlen; + u_char x; + + if (plen < CHAP_HEADERLEN) + return 0; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < CHAP_HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) + printer(arg, " %s", ChapCodenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= CHAP_HEADERLEN; + switch (code) { + case CHAP_CHALLENGE: + case CHAP_RESPONSE: + if (len < 1) + break; + clen = p[0]; + if (len < clen + 1) + break; + ++p; + nlen = len - clen - 1; + printer(arg, " <"); + for (; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, "%.2x", x); + } + printer(arg, ">, name = "); + print_string((char *)p, nlen, printer, arg); + break; + case CHAP_FAILURE: + case CHAP_SUCCESS: + printer(arg, " "); + print_string((char *)p, len, printer, arg); + break; + default: + for (clen = len; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, " %.2x", x); + } + } -void srand48(seedval) -long seedval; -{ - srand((int)seedval); + return len + CHAP_HEADERLEN; } - -#endif