+ /* If a plugin will verify the response, let the plugin do it. */
+ if (chap_auth_hook) {
+ code = (*chap_auth_hook) ( (explicit_remote ? remote_name : rhostname),
+ remmd, (int) remmd_len,
+ cstate );
+ } else {
+ 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 */
+ switch (cstate->chal_type) {
+
+ case CHAP_DIGEST_MD5:
+ if (remmd_len != MD5_SIGNATURE_SIZE)
+ break; /* not even the right length */
+ MD5Init(&mdContext);
+ MD5Update(&mdContext, &cstate->chal_id, 1);
+ MD5Update(&mdContext, secret, secret_len);
+ MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
+ MD5Final(hash, &mdContext);
+
+ /* compare MDs and send the appropriate status */
+ if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)
+ code = CHAP_SUCCESS; /* they are the same! */
+ break;
+
+#ifdef CHAPMS
+ case CHAP_MICROSOFT:
+ {
+ int response_offset, response_size;
+
+ if (remmd_len != MS_CHAP_RESPONSE_LEN)
+ break; /* not even the right length */
+ ChapMS(cstate, cstate->challenge, cstate->chal_len,
+ secret, secret_len);
+
+ /* Determine which part of response to verify against */
+ if ((u_char *) (remmd + offsetof(MS_ChapResponse, UseNT))) {
+ response_offset = offsetof(MS_ChapResponse, NTResp);
+ response_size = sizeof(((MS_ChapResponse *) remmd)->NTResp);
+ } else {
+ response_offset = offsetof(MS_ChapResponse, LANManResp);
+ response_size =
+ sizeof(((MS_ChapResponse *) remmd)->LANManResp);
+ }
+
+ /* compare MDs and send the appropriate status */
+ if (memcmp(cstate->response + response_offset,
+ remmd + response_offset, response_size) == 0)
+ code = CHAP_SUCCESS; /* they are the same! */
+ break;
+ }
+#endif /* CHAPMS */
+
+ default:
+ CHAPDEBUG(("unknown digest type %d", cstate->chal_type));
+ }