3 --- pppd/chap.c.orig Fri Aug 13 02:46:11 1999
4 +++ pppd/chap.c Sat Sep 25 13:23:26 1999
15 static void ChapSendStatus __P((chap_state *, int));
16 static void ChapSendChallenge __P((chap_state *));
17 static void ChapSendResponse __P((chap_state *));
18 -static void ChapGenChallenge __P((chap_state *));
19 +void ChapGenChallenge __P((chap_state *));
21 extern double drand48 __P((void));
22 extern void srand48 __P((long));
24 switch (cstate->resp_type) {
27 + CHAPDEBUG(("ChapReceiveChallenge: rcvd type CHAP-DIGEST-MD5"));
29 MD5Update(&mdContext, &cstate->resp_id, 1);
30 MD5Update(&mdContext, secret, secret_len);
35 + CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V1."));
36 + if(rchallenge_len != 8)
38 + CHAPDEBUG(("Invalid challenge length for MS-CHAP-V1"));
41 ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
44 + case CHAP_MICROSOFT_V2:
45 + CHAPDEBUG(("ChapReceiveChallenge: rcvd type MS-CHAP-V2."));
46 + if(rchallenge_len != 16)
48 + CHAPDEBUG(("Invalid challenge length for MS-CHAP-V2"));
51 + ChapMS_v2(cstate, rchallenge, rchallenge_len, secret, secret_len);
57 /* generate MD based on negotiated type */
58 switch (cstate->chal_type) {
60 - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
61 + case CHAP_DIGEST_MD5:
62 + CHAPDEBUG(("ChapReceiveResponse: rcvd type CHAP-DIGEST-MD5"));
63 if (remmd_len != MD5_SIGNATURE_SIZE)
64 break; /* it's not even the right length */
67 code = CHAP_SUCCESS; /* they are the same! */
71 + case CHAP_MICROSOFT:
72 + CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V1"));
73 + if(remmd_len != MS_CHAP_RESPONSE_LEN)
75 + if(ChapMS_Resp(cstate, secret, secret_len, remmd) == 0)
76 + code = CHAP_SUCCESS;
79 + case CHAP_MICROSOFT_V2:
80 + CHAPDEBUG(("ChapReceiveResponse: rcvd type MS-CHAP-V2"));
81 + if(remmd_len != MS_CHAP_RESPONSE_LEN)
83 + if(ChapMS_v2_Resp(cstate,secret,secret_len,remmd,rhostname) == 0)
85 + code = CHAP_SUCCESS_R;
86 + ChapMS_v2_Auth(cstate, secret, secret_len, remmd, rhostname);
92 CHAPDEBUG(("unknown digest type %d", cstate->chal_type));
95 BZERO(secret, sizeof(secret));
96 ChapSendStatus(cstate, code);
98 - if (code == CHAP_SUCCESS) {
99 + if ((code == CHAP_SUCCESS) || (code == CHAP_SUCCESS_R)) {
100 old_state = cstate->serverstate;
101 cstate->serverstate = CHAPSS_OPEN;
102 if (old_state == CHAPSS_INITIAL_CHAL) {
103 @@ -590,10 +631,43 @@
105 if (cstate->chal_interval != 0)
106 TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
107 - notice("CHAP peer authentication succeeded for %q", rhostname);
109 + switch (cstate->chal_type) {
110 + case CHAP_DIGEST_MD5:
111 + notice("CHAP peer authentication succeeded for %q", rhostname);
114 + case CHAP_MICROSOFT:
115 + notice("MSCHAP peer authentication succeeded for %q", rhostname);
117 + case CHAP_MICROSOFT_V2:
118 + notice("MSCHAP-v2 peer authentication succeeded for %q", rhostname);
122 + notice("CHAP (unknown) peer authentication succeeded for %q",
127 - error("CHAP peer authentication failed for remote host %q", rhostname);
128 + switch (cstate->chal_type) {
129 + case CHAP_DIGEST_MD5:
130 + error("CHAP peer authentication failed for remote host %q",
134 + case CHAP_MICROSOFT:
135 + error("MSCHAP peer authentication failed for remote host %q",
138 + case CHAP_MICROSOFT_V2:
139 + error("MSCHAP-v2 peer authentication failed for remote host %q",
144 + error("CHAP (unknown) peer authentication failed for remote host %q", rhostname);
147 cstate->serverstate = CHAPSS_BADAUTH;
148 auth_peer_fail(cstate->unit, PPP_CHAP);
152 if (code == CHAP_SUCCESS)
153 slprintf(msg, sizeof(msg), "Welcome to %s.", hostname);
154 + else if(code == CHAP_SUCCESS_R)
155 + strcpy(msg, cstate->response);
157 slprintf(msg, sizeof(msg), "I don't like you. Go 'way.");
158 msglen = strlen(msg);
161 MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
163 - PUTCHAR(code, outp);
164 + PUTCHAR(code == CHAP_SUCCESS_R ? CHAP_SUCCESS : code, outp);
165 PUTCHAR(cstate->chal_id, outp);
166 PUTSHORT(outlen, outp);
167 BCOPY(msg, outp, msglen);
169 * *cstate are initialized.
174 ChapGenChallenge(cstate)
178 u_char *ptr = cstate->challenge;
182 + if(cstate->chal_type == CHAP_MICROSOFT)
184 + else if(cstate->chal_type == CHAP_MICROSOFT_V2)
189 /* pick a random challenge length between MIN_CHALLENGE_LENGTH and
190 MAX_CHALLENGE_LENGTH */
191 chal_len = (unsigned) ((drand48() *
195 return len + CHAP_HEADERLEN;
202 + lcp_wantoptions[0].neg_chap = 1;
203 + lcp_wantoptions[0].use_digest = 1;