X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fchap.c;h=b418f6f493f002a192b0d8699a3530dcd5becc02;hp=d72c36d4a9896e964e97ddd13c6e8a72e0b3baad;hb=96dad36e1d37716004171559280613739e7df29e;hpb=68497c7d9717fc53f7864d6555be1e0b5e15e696 diff --git a/pppd/chap.c b/pppd/chap.c index d72c36d..b418f6f 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. @@ -19,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: chap.c,v 1.8 1995/07/04 12:32:26 paulus Exp $"; +static char rcsid[] = "$Id: chap.c,v 1.14 1997/04/30 05:51:08 paulus Exp $"; #endif /* @@ -35,12 +50,45 @@ static char rcsid[] = "$Id: chap.c,v 1.8 1995/07/04 12:32:26 paulus Exp $"; #include "pppd.h" #include "chap.h" #include "md5.h" +#ifdef CHAPMS +#include "chap_ms.h" +#endif + +/* + * 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, + NULL, + NULL +}; chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ -static void ChapChallengeTimeout __P((caddr_t)); -static void ChapResponseTimeout __P((caddr_t)); +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)); @@ -55,7 +103,7 @@ extern void srand48 __P((long)); /* * ChapInit - Initialize a CHAP unit. */ -void +static void ChapInit(unit) int unit; { @@ -134,7 +182,7 @@ ChapAuthPeer(unit, our_name, digest) */ static void ChapChallengeTimeout(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -161,7 +209,7 @@ ChapChallengeTimeout(arg) */ static void ChapResponseTimeout(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -178,7 +226,7 @@ ChapResponseTimeout(arg) */ static void ChapRechallenge(arg) - caddr_t arg; + void *arg; { chap_state *cstate = (chap_state *) arg; @@ -197,7 +245,7 @@ ChapRechallenge(arg) * * Start up if we have pending requests. */ -void +static void ChapLowerUp(unit) int unit; { @@ -223,7 +271,7 @@ ChapLowerUp(unit) * * Cancel all timeouts. */ -void +static void ChapLowerDown(unit) int unit; { @@ -232,12 +280,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; @@ -247,7 +295,7 @@ ChapLowerDown(unit) /* * ChapProtocolReject - Peer doesn't grok CHAP. */ -void +static void ChapProtocolReject(unit) int unit; { @@ -266,7 +314,7 @@ ChapProtocolReject(unit) /* * ChapInput - Input CHAP packet. */ -void +static void ChapInput(unit, inpacket, packet_len) int unit; u_char *inpacket; @@ -342,6 +390,7 @@ 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 || @@ -370,9 +419,17 @@ ChapReceiveChallenge(cstate, inp, id, len) BCOPY(inp, rhostname, len); rhostname[len] = '\000'; - CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field: %s", + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'", rhostname)); + /* Microsoft doesn't send their name back in the PPP packet */ + if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) { + strncpy(rhostname, remote_name, sizeof(rhostname)); + rhostname[sizeof(rhostname) - 1] = 0; + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' 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)) { @@ -383,7 +440,7 @@ ChapReceiveChallenge(cstate, inp, id, len) /* 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; @@ -391,21 +448,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)); return; } + BZERO(secret, sizeof(secret)); ChapSendResponse(cstate); } @@ -424,10 +488,9 @@ 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]; + u_char hash[MD5_SIGNATURE_SIZE]; CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id)); @@ -469,7 +532,7 @@ ChapReceiveResponse(cstate, inp, id, len) return; } - UNTIMEOUT(ChapChallengeTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapChallengeTimeout, cstate); if (len >= sizeof(rhostname)) len = sizeof(rhostname) - 1; @@ -500,10 +563,10 @@ 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 (memcmp (mdContext.digest, remmd, MD5_SIGNATURE_SIZE) == 0) + if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) code = CHAP_SUCCESS; /* they are the same! */ break; @@ -512,16 +575,17 @@ ChapReceiveResponse(cstate, inp, id, len) } } + 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, PPP_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); } else { syslog(LOG_ERR, "CHAP peer authentication failed"); @@ -554,7 +618,7 @@ ChapReceiveSuccess(cstate, inp, id, len) return; } - UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapResponseTimeout, cstate); /* * Print message. @@ -578,9 +642,6 @@ 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) { @@ -590,7 +651,7 @@ ChapReceiveFailure(cstate, inp, id, len) return; } - UNTIMEOUT(ChapResponseTimeout, (caddr_t) cstate); + UNTIMEOUT(ChapResponseTimeout, cstate); /* * Print message. @@ -635,7 +696,7 @@ ChapSendChallenge(cstate) 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; } @@ -735,18 +796,18 @@ ChapSendResponse(cstate) 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; } /* * ChapPrintPkt - print the contents of a CHAP packet. */ -char *ChapCodenames[] = { +static char *ChapCodenames[] = { "Challenge", "Response", "Success", "Failure" }; -int +static int ChapPrintPkt(p, plen, printer, arg) u_char *p; int plen;