1 diff -Naur freeradius-server-2.1.12/src/modules/rlm_mschap/Makefile freeradius-server-2.1.12-patched/src/modules/rlm_mschap/Makefile
2 --- freeradius-server-2.1.12/src/modules/rlm_mschap/Makefile 2011-09-30 10:12:07.000000000 -0400
3 +++ freeradius-server-2.1.12-patched/src/modules/rlm_mschap/Makefile 2011-11-10 00:16:58.000000000 -0500
5 HEADERS = mschap.h smbdes.h
10 RLM_UTILS = smbencrypt
11 RLM_INSTALL = smbencrypt-install
13 diff -Naur freeradius-server-2.1.12/src/modules/rlm_mschap/rlm_mschap.c freeradius-server-2.1.12-patched/src/modules/rlm_mschap/rlm_mschap.c
14 --- freeradius-server-2.1.12/src/modules/rlm_mschap/rlm_mschap.c 2011-09-30 10:12:07.000000000 -0400
15 +++ freeradius-server-2.1.12-patched/src/modules/rlm_mschap/rlm_mschap.c 2011-11-10 00:16:46.000000000 -0500
23 extern int od_mschap_auth(REQUEST *request, VALUE_PAIR *challenge, VALUE_PAIR * usernamepair);
26 * then calculate the hash of the NT hash. Doing this
27 * here minimizes work for later.
30 if (password && (password->attribute == PW_NT_PASSWORD)) {
31 fr_md4_calc(nthashhash, password->vp_octets, 16);
33 memset(nthashhash, 0, 16);
37 + fr_bin2hex(nthashhash, nthh_hex, 16);
39 + RDEBUG2("MD4(LM(password)) = %s", nthh_hex);
41 + fr_bin2hex(password->vp_octets, nthh_hex, 16);
42 + /* nthh_hex[16] = 0; */
43 + RDEBUG2("LM(password) = %s", nthh_hex);
45 } else { /* run ntlm_auth */
48 @@ -754,11 +767,101 @@
49 RDEBUG2("Invalid output from ntlm_auth: NT_KEY has non-hex values");
53 + RDEBUG2("NT hash hash: %s", buffer + 8);
59 +static int do_kcrap(REQUEST *request, uint8_t *challenge, VALUE_PAIR *response, unsigned int offset, uint8_t *nthashhash)
61 + RDEBUG2("I think I can try KCRAP here");
62 + int kcrap_success = 0;
64 + /* Start talking with KCRAP */
65 + struct kcrap_context *kcontext = kcrap_init(NULL, NULL);
66 + if ( kcontext == NULL )
68 + RDEBUG2("FAILED: Could not init KCRAP context.");
72 + RDEBUG2("Got KCRAP context");
74 + /* Build our authentication request */
75 + struct kcrap_auth_req_data req;
76 + VALUE_PAIR *username;
77 + username = pairfind(request->packet->vps, PW_USER_NAME);
78 + bzero(&req, sizeof(req));
79 + req.chal_type.data = "NTLM";
80 + req.chal_type.length = 4;
81 + req.client_challenge.data = (char *)challenge;
82 + req.client_challenge.length = 8;
83 + req.response.data = (char *)(response->vp_octets + offset);
84 + req.response.length = 50 - offset;
85 + req.principal.data = username->vp_strvalue;
86 + req.principal.length = username->length;
87 + RDEBUG2("Challenge: 0x%016llx (principal = %s, response = 0x%016llx)", *((unsigned long long *)challenge), username->vp_strvalue, *((unsigned long long *)req.response.data));
88 + int kcrap_auth_status;
91 + kcrap_auth_status = kcrap_try(kcontext, &req, &kcrap_success);
93 + /* Free our instance */
94 + kcrap_free(kcontext);
96 + /* Deal with the results */
97 + if ( kcrap_auth_status != 0 )
99 + RDEBUG2("KCRAP: Rejected, errno %d (%s)", kcrap_auth_status, kcrap_errmsg());
103 + if ( kcrap_success )
105 + RDEBUG2("KCRAP: Authentication succeeded.");
108 + * Update the NT hash hash, from the NT key.
111 + struct kcrap_data extra = kcrap_get_extra_data();
113 + if ( extra.length == 16 )
115 + /* This is the LM hash */
116 + fr_md4_calc(nthashhash, extra.data, 16);
120 + fr_bin2hex(nthashhash, nthh_hex, 16);
122 + RDEBUG2("MD4(LM(password)) = %s", nthh_hex);
124 + fr_bin2hex(extra.data, nthh_hex, 16);
125 + RDEBUG2("LM(password) = %s", nthh_hex);
127 + /* memset(nthashhash, 0, 16); */
129 + MS-CHAP doesn't tell us the password, so I don't know how we can calculate this...
130 + or if this is even what we want to calculate :(
131 + if (password && (password->attribute == PW_NT_PASSWORD)) {
132 + fr_md4_calc(nthashhash, password->vp_octets, 16);
134 + memset(nthashhash, 0, 16);
142 + RDEBUG2("KCRAP: Wrong credentials");
149 * Data for the hashes.
150 @@ -1131,8 +1234,11 @@
151 if (do_mschap(inst, request, password, challenge->vp_octets,
152 response->vp_octets + offset, nthashhash,
154 - RDEBUG2("MS-CHAP-Response is incorrect.");
156 + if ( do_kcrap(request, challenge->vp_octets, response, offset, nthashhash) < 0 )
158 + RDEBUG2("MS-CHAP-Response is incorrect.");
164 @@ -1237,34 +1343,37 @@
165 RDEBUG2("Told to do MS-CHAPv2 for %s with NT-Password",
168 - if (do_mschap(inst, request, nt_password, mschapv1_challenge,
169 + if (do_kcrap(request, mschapv1_challenge, response, 26, nthashhash) < 0 ) {
170 + if ( do_mschap(inst, request, nt_password, mschapv1_challenge,
171 response->vp_octets + 26, nthashhash,
172 - do_ntlm_auth) < 0) {
176 - RDEBUG2("FAILED: MS-CHAP2-Response is incorrect");
179 - snprintf(buffer, sizeof(buffer), "E=691 R=%d",
180 - inst->allow_retry);
182 - if (inst->retry_msg) {
183 - snprintf(buffer + 9, sizeof(buffer) - 9, " C=");
184 - for (i = 0; i < 16; i++) {
185 - snprintf(buffer + 12 + i*2,
186 - sizeof(buffer) - 12 - i*2, "%02x",
188 + do_ntlm_auth) < 0 ) {
193 + RDEBUG2("FAILED: MS-CHAP2-Response is incorrect");
196 + snprintf(buffer, sizeof(buffer), "E=691 R=%d",
197 + inst->allow_retry);
199 + if (inst->retry_msg) {
200 + snprintf(buffer + 9, sizeof(buffer) - 9, " C=");
201 + for (i = 0; i < 16; i++) {
202 + snprintf(buffer + 12 + i*2,
203 + sizeof(buffer) - 12 - i*2, "%02x",
206 + snprintf(buffer + 12 + 32, sizeof(buffer) - 45,
207 + " V=3 M=%s", inst->retry_msg);
209 - snprintf(buffer + 12 + 32, sizeof(buffer) - 45,
210 - " V=3 M=%s", inst->retry_msg);
211 + mschap_add_reply(request, &request->reply->vps,
212 + *response->vp_octets, "MS-CHAP-Error",
213 + buffer, strlen(buffer));
214 + return RLM_MODULE_REJECT;
216 - mschap_add_reply(request, &request->reply->vps,
217 - *response->vp_octets, "MS-CHAP-Error",
218 - buffer, strlen(buffer));
219 - return RLM_MODULE_REJECT;
223 mschap_auth_response(username_string, /* without the domain */
224 nthashhash, /* nt-hash-hash */
225 response->vp_octets + 26, /* peer response */