static void chapms_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, const unsigned char *challenge, const char *secret, int secret_len, unsigned char *private_) { LWIP_UNUSED_ARG(id); LWIP_UNUSED_ARG(our_name); LWIP_UNUSED_ARG(private_); challenge++; /* skip length, should be 8 */ *response++ = MS_CHAP_RESPONSE_LEN; ChapMS(pcb, challenge, secret, secret_len, response); }
static int chapms_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space) { MS_ChapResponse *rmd; MS_ChapResponse md; int diff; int challenge_len, response_len; challenge_len = *challenge++; /* skip length, is 8 */ response_len = *response++; if (response_len != MS_CHAP_RESPONSE_LEN) goto bad; rmd = (MS_ChapResponse *) response; #ifndef MSLANMAN if (!rmd->UseNT[0]) { /* Should really propagate this into the error packet. */ notice("Peer request for LANMAN auth not supported"); goto bad; } #endif /* Generate the expected response. */ ChapMS(challenge, (char *)secret, secret_len, &md); #ifdef MSLANMAN /* Determine which part of response to verify against */ if (!rmd->UseNT[0]) diff = memcmp(&rmd->LANManResp, &md.LANManResp, sizeof(md.LANManResp)); else #endif diff = memcmp(&rmd->NTResp, &md.NTResp, sizeof(md.NTResp)); if (diff == 0) { slprintf(message, message_space, "Access granted"); return 1; } bad: /* See comments below for MS-CHAP V2 */ slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return 0; }
static int chapms_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space) { MS_ChapResponse *rmd; MS_ChapResponse md; int diff; int challenge_len, response_len; challenge_len = *challenge++; response_len = *response++; if (response_len != MS_CHAP_RESPONSE_LEN) goto bad; rmd = (MS_ChapResponse *) response; #ifndef MSLANMAN if (!rmd->UseNT[0]) { notice("Peer request for LANMAN auth not supported"); goto bad; } #endif ChapMS(challenge, (char *)secret, secret_len, &md); #ifdef MSLANMAN if (!rmd->UseNT[0]) diff = memcmp(&rmd->LANManResp, &md.LANManResp, sizeof(md.LANManResp)); else #endif diff = memcmp(&rmd->NTResp, &md.NTResp, sizeof(md.NTResp)); if (diff == 0) { slprintf(message, message_space, "Access granted"); return 1; } bad: slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return 0; }
static int chapms_verify_response(ppp_pcb *pcb, int id, const char *name, const unsigned char *secret, int secret_len, const unsigned char *challenge, const unsigned char *response, char *message, int message_space) { unsigned char md[MS_CHAP_RESPONSE_LEN]; int diff; int challenge_len, response_len; LWIP_UNUSED_ARG(id); LWIP_UNUSED_ARG(name); challenge_len = *challenge++; /* skip length, is 8 */ response_len = *response++; if (response_len != MS_CHAP_RESPONSE_LEN) goto bad; #ifndef MSLANMAN if (!response[MS_CHAP_USENT]) { /* Should really propagate this into the error packet. */ ppp_notice("Peer request for LANMAN auth not supported"); goto bad; } #endif /* Generate the expected response. */ ChapMS(pcb, (const u_char *)challenge, (const char *)secret, secret_len, md); #ifdef MSLANMAN /* Determine which part of response to verify against */ if (!response[MS_CHAP_USENT]) diff = memcmp(&response[MS_CHAP_LANMANRESP], &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); else #endif diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], MS_CHAP_NTRESP_LEN); if (diff == 0) { ppp_slprintf(message, message_space, "Access granted"); return 1; } bad: /* See comments below for MS-CHAP V2 */ ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return 0; }
/* * ChapReceiveChallenge - Receive Challenge and send Response. */ static void ChapReceiveChallenge( chap_state *cstate, u_char *inp, int id, int len) { int rchallenge_len; u_char *rchallenge; int secret_len; unsigned char secret[MAXSECRETLEN]; char rhostname[256]; MD5_CTX mdContext; u_char hash[MD5_SIGNATURE_SIZE]; if (cstate->clientstate == CHAPCS_CLOSED || cstate->clientstate == CHAPCS_PENDING) { CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate)); return; } if (len < 2) { CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); return; } GETCHAR(rchallenge_len, inp); len -= sizeof (u_char) + rchallenge_len; /* now name field length */ if (len < 0) { CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); return; } rchallenge = inp; INCPTR(rchallenge_len, inp); if (len >= sizeof(rhostname)) len = sizeof(rhostname) - 1; BCOPY(inp, rhostname, len); rhostname[len] = '\000'; /* Microsoft doesn't send their name back in the PPP packet */ if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) { strlcpy(rhostname, remote_name, sizeof(rhostname)); CHAPDEBUG(("ChapReceiveChallenge: using '%q' 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)) { secret_len = 0; /* assume null secret if can't find one */ warn("No CHAP secret found for authenticating us to %q", rhostname); } /* cancel response send timeout if necessary */ if (cstate->clientstate == CHAPCS_RESPONSE) UNTIMEOUT(ChapResponseTimeout, cstate); cstate->resp_id = id; cstate->resp_transmits = 0; /* generate MD based on negotiated type */ switch (cstate->resp_type) { case CHAP_DIGEST_MD5: MD5Init(&mdContext); MD5Update(&mdContext, &cstate->resp_id, 1); MD5Update(&mdContext, secret, secret_len); MD5Update(&mdContext, rchallenge, rchallenge_len); 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(("unknown digest type %d", cstate->resp_type)); return; } BZERO(secret, sizeof(secret)); ChapSendResponse(cstate); }