void PAP_send ( _ppp_handle handle /* [IN] - the PPP state structure */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_CFG_PTR ppp_ptr = handle; PAP_DATA_PTR pap_ptr = &ppp_ptr->PAP_STATE; PCB_PTR pcb; unsigned char *outp; uint16_t len; pap_ptr->CLIENT_STATE = PAP_STATE_INITIAL; pap_ptr->CURID = RTCS_rand() & 0xFF; /* Acquire a PCB */ len = PAP_HDR_LEN + 2 /* Start CR 2207 */ + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH) + PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH); /* End CR 2207 */ pcb = PPP_pcballoc(PPP_PROT_PAP, len); if (pcb == NULL) { return; } /* Endif */ /* Build an Authenticate-Request packet */ outp = pcb->FRAG[0].FRAGMENT + 2; *outp++ = PAP_CODE_AUTH_REQ; *outp++ = pap_ptr->CURID; *outp++ = (len >> 8) & 0xFF; *outp++ = len & 0xFF; /* Start CR 2207 */ *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_LENGTH); PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_ID_PTR), outp, len); outp += len; *outp++ = len = PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_LENGTH); PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_PAP_LSECRET->PPP_PW_PTR), outp, len); /* End CR 2207 */ /* Send the PCB */ PPP_send_rexmit(ppp_ptr, PPP_PROT_PAP, pcb, 0, PAP_timeout, pap_ptr); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void CHAP_challenge ( _ppp_handle handle /* [IN] - the PPP state structure */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = handle; CHAP_DATA_PTR chap_ptr = &ppp_ptr->CHAP_STATE; PCB_PTR pcb; uchar_ptr outp; uint_16 len; uint_16 i, idlen; chap_ptr->SERVER_STATE = CHAP_STATE_INITIAL; chap_ptr->CURID = RTCS_rand() & 0xFF; /* Acquire a message buffer */ /* Start CR 2207 */ idlen = strlen(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME)); /* End CR 2207 */ len = CHAP_HDR_LEN + 1 + CHAP_CHALLENGE_LEN + idlen; pcb = PPP_pcballoc(PPP_PROT_CHAP, len); if (pcb == NULL) { return; } /* Endif */ /* Build a Challenge packet */ outp = pcb->FRAG[0].FRAGMENT + 2; *outp++ = CHAP_CODE_CHALLENGE; *outp++ = chap_ptr->CURID; *outp++ = (len >> 8) & 0xFF; *outp++ = len & 0xFF; *outp++ = CHAP_CHALLENGE_LEN; for (i=0; i<CHAP_CHALLENGE_LEN; i++) { *outp++ = chap_ptr->MD5[i] = RTCS_rand() & 0xFF; } /* Endfor */ /* Start CR 2207 */ PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME), outp, idlen); /* End CR 2207 */ /* Send the PCB */ PPP_send_rexmit(ppp_ptr, PPP_PROT_CHAP, pcb, 0, CHAP_timeout, chap_ptr); } /* Endbody */
void CHAP_input ( PCB_PTR pcb, /* [IN] - CHAP packet */ _ppp_handle handle /* [IN] - the PPP state structure */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = handle; CHAP_DATA_PTR chap_ptr = &ppp_ptr->CHAP_STATE; PPP_SECRET_PTR secret; uchar_ptr inp = pcb->FRAG[0].FRAGMENT + 2; uchar_ptr valp, idp; uchar code, id; uchar vallen, idlen, namelen; uint_16 len; boolean delay = FALSE; /* ** Parse header (code, id and length). ** If packet too short, drop it. */ if (pcb->FRAG[0].LENGTH < 2 + CHAP_HDR_LEN) { chap_ptr->ST_CHAP_SHORT++; PCB_free(pcb); return; } /* Endif */ code = *inp++; id = *inp++; len = *inp++ << 8; len += *inp++; if ((len < CHAP_HDR_LEN) || (len > pcb->FRAG[0].LENGTH - 2)) { chap_ptr->ST_CHAP_SHORT++; PCB_free(pcb); return; } /* Endif */ len -= CHAP_HDR_LEN; /* ** For Challenge and Response packets, also parse the ** value and name fields. */ if ((code == CHAP_CODE_CHALLENGE) || (code == CHAP_CODE_RESPONSE)) { if (len < 1) { chap_ptr->ST_CHAP_SHORT++; PCB_free(pcb); return; } /* Endif */ valp = inp; vallen = *valp++; len--; if (len < vallen) { chap_ptr->ST_CHAP_SHORT++; PCB_free(pcb); return; } /* Endif */ idp = valp + vallen; idlen = len - vallen; } /* Endif */ switch (code) { case CHAP_CODE_CHALLENGE: if (chap_ptr->CLIENT_STATE != CHAP_STATE_INITIAL) { chap_ptr->ST_CHAP_NOAUTH++; PCB_free(pcb); break; } /* Endif */ /* OK -- Generate a Response packet */ /* Start CR 2207 */ secret = PPP_SECRET(ppp_ptr,_PPP_CHAP_LSECRETS); /* End CR 2207 */ inp = pcb->FRAG[0].FRAGMENT + 2; *inp++ = CHAP_CODE_RESPONSE; inp++; /* Keep same ID */ /* Start CR 2207 */ namelen = strlen(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME)); /* End CR 2207 */ len = CHAP_HDR_LEN + 1 + 16 + namelen; *inp++ = (len >> 8) & 0xFF; *inp++ = len & 0xFF; *inp++ = 16; for (;;) { if ((secret->PPP_ID_LENGTH == 0) && (secret->PPP_PW_LENGTH == 0)) { /* Couldn't find a secret for this peer */ chap_ptr->ST_CHAP_NOPW++; PPP_MD5(inp, (uint_32)1, &id, /* id */ (uint_32)vallen, valp, /* challenge */ (uint_32)0); break; } /* Endif */ if ((secret->PPP_ID_LENGTH == idlen) && (memcmp(secret->PPP_ID_PTR, idp, idlen) == 0)) { /* Found a secret; send response */ PPP_MD5(inp, (uint_32)1, &id, /* id */ (uint_32)secret->PPP_PW_LENGTH, /* secret */ secret->PPP_PW_PTR, (uint_32)vallen, valp, /* challenge */ (uint_32)0); break; } /* Endif */ secret++; } /* Endfor */ inp += 16; /* Start CR 2207 */ PPP_memcopy(PPP_SECRET(ppp_ptr,_PPP_CHAP_LNAME), inp, namelen); /* End CR 2207 */ pcb->FRAG[0].LENGTH = len + 2; PPP_send_one(ppp_ptr, PPP_PROT_CHAP, pcb); break; case CHAP_CODE_RESPONSE: switch (chap_ptr->SERVER_STATE) { case CHAP_STATE_INITIAL: /* Check the ID against our last challenge */ if (id != chap_ptr->CURID) { chap_ptr->ST_CHAP_ID++; PCB_free(pcb); break; } /* Endif */ /* Stop the challenge, whether or not the response is correct */ PPP_send_stop(ppp_ptr, PPP_PROT_CHAP); chap_ptr->SERVER_STATE = CHAP_STATE_FAILURE; if (vallen != 16) { delay = TRUE; CHAP_fail(handle); } else { /* Search for name in the secrets table */ /* Start CR 2207 */ secret = PPP_SECRET(ppp_ptr,_PPP_CHAP_RSECRETS); /* End CR 2207 */ for (;;) { if ((secret->PPP_ID_LENGTH == 0) && (secret->PPP_PW_LENGTH == 0)) { /* Couldn't find a secret for this peer */ delay = TRUE; CHAP_fail(handle); break; } /* Endif */ if ((secret->PPP_ID_LENGTH == idlen) && (memcmp(secret->PPP_ID_PTR, idp, idlen) == 0)) { /* Found a secret; compute hash */ uchar digest[16]; PPP_MD5(digest, (uint_32)1, &id, /* id */ (uint_32)secret->PPP_PW_LENGTH, /* secret */ secret->PPP_PW_PTR, (uint_32)CHAP_CHALLENGE_LEN, /* challenge */ chap_ptr->MD5, (uint_32)0); if (memcmp(digest, valp, vallen) == 0) { chap_ptr->SERVER_STATE = CHAP_STATE_SUCCESS; CHAP_up(handle); } else { delay = TRUE; CHAP_fail(handle); } /* Endif */ break; } /* Endif */ secret++; } /* Endfor */ } /* Endif */ /* fall through */ case CHAP_STATE_SUCCESS: case CHAP_STATE_FAILURE: /* Build a Success or Failure reply */ inp = pcb->FRAG[0].FRAGMENT + 2; *inp++ = chap_ptr->SERVER_STATE; inp++; /* Keep same ID */ *inp++ = 0; *inp++ = 4; pcb->FRAG[0].LENGTH = 6; if (delay) { PPP_send_rexmit(ppp_ptr, PPP_PROT_CHAP, pcb, 1, CHAP_close, handle); } else { PPP_send_one(ppp_ptr, PPP_PROT_CHAP, pcb); } /* Endif */ break; default: chap_ptr->ST_CHAP_NOCHAL++; PCB_free(pcb); break; } /* Endswitch */ break; case CHAP_CODE_SUCCESS: /* Authentication success */ chap_ptr->CLIENT_STATE = CHAP_STATE_SUCCESS; CHAP_up(handle); case CHAP_CODE_FAILURE: /* Authentication failure */ if (chap_ptr->CLIENT_STATE != CHAP_STATE_SUCCESS) { /* Change client state when authenticate failure */ chap_ptr->CLIENT_STATE = CHAP_STATE_FAILURE; if (chap_ptr->CLIENT_STATE != CHAP_STATE_INITIAL) { chap_ptr->ST_CHAP_NOAUTH++; } CHAP_fail(handle); } /* Endif */ PCB_free(pcb); break; default: chap_ptr->ST_CHAP_CODE++; PCB_free(pcb); break; } /* Endswitch */ } /* Endbody */