$NetBSD: patch-bf,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $ --- pppd/chap.c.orig Fri Aug 13 02:46:11 1999 +++ pppd/chap.c Sat Sep 25 13:23:26 1999 @@ -47,6 +47,8 @@ #include "pppd.h" #include "chap.h" #include "md5.h" +#include "fsm.h" +#include "lcp.h" #ifdef CHAPMS #include "chap_ms.h" #endif @@ -113,7 +115,7 @@ 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 *)); +void ChapGenChallenge __P((chap_state *)); extern double drand48 __P((void)); extern void srand48 __P((long)); @@ -460,6 +462,7 @@ switch (cstate->resp_type) { case CHAP_DIGEST_MD5: + CHAPDEBUG(("ChapReceiveChallenge: rcvd type CHAP-DIGEST-MD5")); MD5Init(&mdContext); MD5Update(&mdContext, &cstate->resp_id, 1); MD5Update(&mdContext, secret, secret_len); @@ -471,8 +474,24 @@ #ifdef CHAPMS case CHAP_MICROSOFT: + CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V1.")); + if(rchallenge_len != 8) + { + CHAPDEBUG(("Invalid challenge length for MS-CHAP-V1")); + return; + } ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); break; + + case CHAP_MICROSOFT_V2: + CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V2.")); + if(rchallenge_len != 16) + { + CHAPDEBUG(("Invalid challenge length for MS-CHAP-V2")); + return; + } + ChapMS_v2(cstate, rchallenge, rchallenge_len, secret, secret_len); + break; #endif default: @@ -560,7 +579,8 @@ /* generate MD based on negotiated type */ switch (cstate->chal_type) { - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ + case CHAP_DIGEST_MD5: + CHAPDEBUG(("ChapReceiveResponse: rcvd type CHAP-DIGEST-MD5")); if (remmd_len != MD5_SIGNATURE_SIZE) break; /* it's not even the right length */ MD5Init(&mdContext); @@ -574,6 +594,27 @@ code = CHAP_SUCCESS; /* they are the same! */ break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V1")); + if(remmd_len != MS_CHAP_RESPONSE_LEN) + break; + if(ChapMS_Resp(cstate, secret, secret_len, remmd) == 0) + code = CHAP_SUCCESS; + break; + + case CHAP_MICROSOFT_V2: + CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V2")); + if(remmd_len != MS_CHAP_RESPONSE_LEN) + break; + if(ChapMS_v2_Resp(cstate,secret,secret_len,remmd,rhostname) == 0) + { + code = CHAP_SUCCESS_R; + ChapMS_v2_Auth(cstate, secret, secret_len, remmd, rhostname); + } + break; +#endif + default: CHAPDEBUG(("unknown digest type %d", cstate->chal_type)); } @@ -582,7 +623,7 @@ BZERO(secret, sizeof(secret)); ChapSendStatus(cstate, code); - if (code == CHAP_SUCCESS) { + if ((code == CHAP_SUCCESS) || (code == CHAP_SUCCESS_R)) { old_state = cstate->serverstate; cstate->serverstate = CHAPSS_OPEN; if (old_state == CHAPSS_INITIAL_CHAL) { @@ -590,10 +631,43 @@ } if (cstate->chal_interval != 0) TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); - notice("CHAP peer authentication succeeded for %q", rhostname); - + switch (cstate->chal_type) { + case CHAP_DIGEST_MD5: + notice("CHAP peer authentication succeeded for %q", rhostname); + break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + notice("MSCHAP peer authentication succeeded for %q", rhostname); + break; + case CHAP_MICROSOFT_V2: + notice("MSCHAP-v2 peer authentication succeeded for %q", rhostname); + break; +#endif + default: + notice("CHAP (unknown) peer authentication succeeded for %q", + rhostname); + break; + } } else { - error("CHAP peer authentication failed for remote host %q", rhostname); + switch (cstate->chal_type) { + case CHAP_DIGEST_MD5: + error("CHAP peer authentication failed for remote host %q", + rhostname); + break; +#ifdef CHAPMS + case CHAP_MICROSOFT: + error("MSCHAP peer authentication failed for remote host %q", + rhostname); + break; + case CHAP_MICROSOFT_V2: + error("MSCHAP-v2 peer authentication failed for remote host %q", + rhostname); + break; +#endif + default: + error("CHAP (unknown) peer authentication failed for remote host %q", rhostname); + break; + } cstate->serverstate = CHAPSS_BADAUTH; auth_peer_fail(cstate->unit, PPP_CHAP); } @@ -712,6 +786,8 @@ if (code == CHAP_SUCCESS) slprintf(msg, sizeof(msg), "Welcome to %s.", hostname); + else if(code == CHAP_SUCCESS_R) + strcpy(msg, cstate->response); else slprintf(msg, sizeof(msg), "I don't like you. Go 'way."); msglen = strlen(msg); @@ -721,7 +797,7 @@ MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - PUTCHAR(code, outp); + PUTCHAR(code == CHAP_SUCCESS_R ? CHAP_SUCCESS : code, outp); PUTCHAR(cstate->chal_id, outp); PUTSHORT(outlen, outp); BCOPY(msg, outp, msglen); @@ -735,7 +811,7 @@ * *cstate are initialized. */ -static void +void ChapGenChallenge(cstate) chap_state *cstate; { @@ -743,6 +819,14 @@ u_char *ptr = cstate->challenge; unsigned int i; +#ifdef CHAPMS + if(cstate->chal_type == CHAP_MICROSOFT) + chal_len = 8; + else if(cstate->chal_type == CHAP_MICROSOFT_V2) + chal_len = 16; + else +#endif + /* pick a random challenge length between MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH */ chal_len = (unsigned) ((drand48() * @@ -857,4 +941,14 @@ } return len + CHAP_HEADERLEN; +} + +int +reqchap(argv) + char **argv; +{ + lcp_wantoptions[0].neg_chap = 1; + lcp_wantoptions[0].use_digest = 1; + auth_required = 1; + return 1; }