Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
chap.c
Go to the documentation of this file.
00001 /** 00002 * @file chap.c 00003 * @brief CHAP (Challenge Handshake Authentication Protocol) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL PPP_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "core/net.h" 00034 #include "ppp/ppp_debug.h" 00035 #include "ppp/lcp.h" 00036 #include "ppp/ipcp.h" 00037 #include "ppp/ipv6cp.h" 00038 #include "ppp/chap.h" 00039 #include "debug.h" 00040 00041 //Check TCP/IP stack configuration 00042 #if (PPP_SUPPORT == ENABLED && CHAP_SUPPORT == ENABLED) 00043 00044 //Additional dependencies 00045 #include "crypto.h" 00046 #include "md5.h" 00047 00048 00049 /** 00050 * @brief Start CHAP authentication 00051 * @param[in] context PPP context 00052 * @return Error code 00053 **/ 00054 00055 error_t chapStartAuth(PppContext *context) 00056 { 00057 //Debug message 00058 TRACE_INFO("\r\nStarting CHAP authentication...\r\n"); 00059 00060 //Check whether the other end of the PPP link is being authenticated 00061 if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP) 00062 { 00063 //Initialize restart counter 00064 context->chapFsm.restartCounter = CHAP_MAX_CHALLENGES; 00065 //Send a Challenge packet 00066 chapSendChallenge(context); 00067 //Switch to the Challenge-Sent state 00068 context->chapFsm.localState = CHAP_STATE_2_CHALLENGE_SENT; 00069 } 00070 00071 //Check whether the other end of the PPP link is the authenticator 00072 if(context->peerConfig.authProtocol == PPP_PROTOCOL_CHAP) 00073 { 00074 //Switch to the Started state 00075 context->chapFsm.peerState = CHAP_STATE_1_STARTED; 00076 } 00077 00078 //Successful processing 00079 return NO_ERROR; 00080 } 00081 00082 00083 /** 00084 * @brief Abort CHAP authentication 00085 * @param[in] context PPP context 00086 * @return Error code 00087 **/ 00088 00089 error_t chapAbortAuth(PppContext *context) 00090 { 00091 //Debug message 00092 TRACE_INFO("\r\nAborting CHAP authentication...\r\n"); 00093 00094 //Abort CHAP authentication process 00095 context->chapFsm.localState = CHAP_STATE_0_INITIAL; 00096 context->chapFsm.peerState = CHAP_STATE_0_INITIAL; 00097 00098 //Successful processing 00099 return NO_ERROR; 00100 } 00101 00102 00103 /** 00104 * @brief CHAP timer handler 00105 * @param[in] context PPP context 00106 **/ 00107 00108 void chapTick(PppContext *context) 00109 { 00110 //Check whether the restart timer is running 00111 if(context->chapFsm.localState == CHAP_STATE_2_CHALLENGE_SENT) 00112 { 00113 //Get current time 00114 systime_t time = osGetSystemTime(); 00115 00116 //Check restart timer 00117 if((time - context->chapFsm.timestamp) >= CHAP_RESTART_TIMER) 00118 { 00119 //Debug message 00120 TRACE_INFO("\r\nCHAP Timeout event\r\n"); 00121 00122 //Check whether the restart counter is greater than zero 00123 if(context->chapFsm.restartCounter > 0) 00124 { 00125 //Retransmit the Challenge packet 00126 chapSendChallenge(context); 00127 } 00128 else 00129 { 00130 //Abort CHAP authentication 00131 context->chapFsm.localState = CHAP_STATE_0_INITIAL; 00132 //Authentication failed 00133 lcpClose(context); 00134 } 00135 } 00136 } 00137 } 00138 00139 00140 /** 00141 * @brief Process an incoming CHAP packet 00142 * @param[in] context PPP context 00143 * @param[in] packet CHAP packet received from the peer 00144 * @param[in] length Length of the packet, in bytes 00145 **/ 00146 00147 void chapProcessPacket(PppContext *context, 00148 const PppPacket *packet, size_t length) 00149 { 00150 //Ensure the length of the incoming CHAP packet is valid 00151 if(length < sizeof(PppPacket)) 00152 return; 00153 00154 //Check the length field 00155 if(ntohs(packet->length) > length) 00156 return; 00157 if(ntohs(packet->length) < sizeof(PppPacket)) 00158 return; 00159 00160 //Save the length of the CHAP packet 00161 length = ntohs(packet->length); 00162 00163 //Debug message 00164 TRACE_INFO("CHAP packet received (%" PRIuSIZE " bytes)...\r\n", length); 00165 //Dump CHAP packet contents for debugging purpose 00166 pppDumpPacket(packet, length, PPP_PROTOCOL_CHAP); 00167 00168 //CHAP is done at initial link establishment, and could also be 00169 //requested after link establishment 00170 if(context->pppPhase != PPP_PHASE_AUTHENTICATE && 00171 context->pppPhase != PPP_PHASE_NETWORK) 00172 { 00173 //Any packets received during any other phase must be silently discarded 00174 return; 00175 } 00176 00177 //Check CHAP code field 00178 switch(packet->code) 00179 { 00180 //Challenge packet? 00181 case CHAP_CODE_CHALLENGE: 00182 //Process Challenge packet 00183 chapProcessChallenge(context, (ChapChallengePacket *) packet, length); 00184 break; 00185 //Response packet? 00186 case CHAP_CODE_RESPONSE: 00187 //Process Response packet 00188 chapProcessResponse(context, (ChapResponsePacket *) packet, length); 00189 break; 00190 //Success packet? 00191 case CHAP_CODE_SUCCESS: 00192 //Process Success packet 00193 chapProcessSuccess(context, (ChapSuccessPacket *) packet, length); 00194 break; 00195 //Failure packet? 00196 case CHAP_CODE_FAILURE: 00197 //Process Failure packet 00198 chapProcessFailure(context, (ChapFailurePacket *) packet, length); 00199 break; 00200 //Unknown code field 00201 default: 00202 //Silently drop the incoming packet 00203 break; 00204 } 00205 } 00206 00207 00208 /** 00209 * @brief Process Challenge packet 00210 * @param[in] context PPP context 00211 * @param[in] challengePacket Packet received from the peer 00212 * @param[in] length Length of the packet, in bytes 00213 * @return Error code 00214 **/ 00215 00216 error_t chapProcessChallenge(PppContext *context, 00217 const ChapChallengePacket *challengePacket, size_t length) 00218 { 00219 size_t n; 00220 Md5Context md5Context; 00221 00222 //Debug message 00223 TRACE_INFO("\r\nCHAP Challenge packet received\r\n"); 00224 00225 //Make sure the Challenge packet is acceptable 00226 if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP) 00227 return ERROR_FAILURE; 00228 00229 //Check the length of the packet 00230 if(length < sizeof(ChapChallengePacket)) 00231 return ERROR_INVALID_LENGTH; 00232 00233 //Malformed Challenge packet? 00234 if(length < (sizeof(ChapChallengePacket) + challengePacket->valueSize)) 00235 return ERROR_INVALID_LENGTH; 00236 00237 //Save the Identifier field 00238 context->chapFsm.peerIdentifier = challengePacket->identifier; 00239 00240 //Retrieve the length of the password 00241 n = strlen(context->password); 00242 00243 //The response value is the one-way hash calculated over a stream 00244 //of octets consisting of the identifier, followed by the secret, 00245 //followed by the challenge value 00246 md5Init(&md5Context); 00247 md5Update(&md5Context, &challengePacket->identifier, sizeof(uint8_t)); 00248 md5Update(&md5Context, context->password, n); 00249 md5Update(&md5Context, challengePacket->value, challengePacket->valueSize); 00250 md5Final(&md5Context, NULL); 00251 00252 //Whenever a Challenge packet is received, the peer must send a Response packet 00253 chapSendResponse(context, md5Context.digest); 00254 00255 //Switch to the Response-Sent state 00256 context->chapFsm.peerState = CHAP_STATE_4_RESPONSE_SENT; 00257 00258 //Successful processing 00259 return NO_ERROR; 00260 } 00261 00262 00263 /** 00264 * @brief Process Response packet 00265 * @param[in] context PPP context 00266 * @param[in] responsePacket Packet received from the peer 00267 * @param[in] length Length of the packet, in bytes 00268 * @return Error code 00269 **/ 00270 00271 error_t chapProcessResponse(PppContext *context, 00272 const ChapResponsePacket *responsePacket, size_t length) 00273 { 00274 bool_t status; 00275 const uint8_t *p; 00276 00277 //Debug message 00278 TRACE_INFO("\r\nCHAP Response packet received\r\n"); 00279 00280 //Make sure the Response packet is acceptable 00281 if(context->localConfig.authProtocol != PPP_PROTOCOL_CHAP) 00282 return ERROR_FAILURE; 00283 00284 //Check the length of the packet 00285 if(length < sizeof(ChapResponsePacket)) 00286 return ERROR_INVALID_LENGTH; 00287 00288 //When a packet is received with an invalid Identifier field, the 00289 //packet is silently discarded without affecting the automaton 00290 if(responsePacket->identifier != context->chapFsm.localIdentifier) 00291 return ERROR_WRONG_IDENTIFIER; 00292 00293 //Malformed Response packet? 00294 if(length < (sizeof(ChapResponsePacket) + responsePacket->valueSize)) 00295 return ERROR_INVALID_LENGTH; 00296 00297 //The length of the response value depends upon the hash algorithm used 00298 if(responsePacket->valueSize != MD5_DIGEST_SIZE) 00299 return ERROR_INVALID_LENGTH; 00300 00301 //Retrieve the response value 00302 context->chapFsm.response = responsePacket->value; 00303 00304 //Point to the Name field 00305 p = responsePacket->value + responsePacket->valueSize; 00306 //Retrieve the length of the Name field 00307 length -= sizeof(ChapResponsePacket) + responsePacket->valueSize; 00308 00309 //Limit the length of the string 00310 length = MIN(length, PPP_MAX_USERNAME_LEN); 00311 //Copy the name of the peer to be identified 00312 memcpy(context->peerName, p, length); 00313 //Properly terminate the string with a NULL character 00314 context->peerName[length] = '\0'; 00315 00316 //Invoke user-defined callback, if any 00317 if(context->settings.authCallback != NULL) 00318 { 00319 //Perfom username and password verification 00320 status = context->settings.authCallback(context->interface, 00321 context->peerName); 00322 } 00323 else 00324 { 00325 //Unable to perform authentication... 00326 status = FALSE; 00327 } 00328 00329 //Whenever a Response packet is received, the authenticator compares the 00330 //Response Value with its own calculation of the expected value. Based on 00331 //this comparison, the authenticator must send a Success or Failure packet 00332 if(status) 00333 { 00334 //Send a Success packet 00335 chapSendSuccess(context); 00336 00337 //Switch to the Success-Sent state 00338 context->chapFsm.localState = CHAP_STATE_6_SUCCESS_SENT; 00339 //The user has been successfully authenticated 00340 context->localAuthDone = TRUE; 00341 00342 //Check whether PPP authentication is complete 00343 if(context->localAuthDone && context->peerAuthDone) 00344 { 00345 //Check current PPP phase 00346 if(context->pppPhase == PPP_PHASE_AUTHENTICATE) 00347 { 00348 //Advance to the Network phase 00349 context->pppPhase = PPP_PHASE_NETWORK; 00350 00351 #if (IPV4_SUPPORT == ENABLED) 00352 //IPCP Open event 00353 ipcpOpen(context); 00354 #endif 00355 #if (IPV6_SUPPORT == ENABLED) 00356 //IPV6CP Open event 00357 ipv6cpOpen(context); 00358 #endif 00359 } 00360 } 00361 } 00362 else 00363 { 00364 //Send a Failure packet 00365 chapSendFailure(context); 00366 00367 //Switch to the Failure-Sent state 00368 context->chapFsm.localState = CHAP_STATE_8_FAILURE_SENT; 00369 //The authenticator should take action to terminate the link 00370 lcpClose(context); 00371 } 00372 00373 //Successful processing 00374 return NO_ERROR; 00375 } 00376 00377 00378 /** 00379 * @brief Process Success packet 00380 * @param[in] context PPP context 00381 * @param[in] successPacket Packet received from the peer 00382 * @param[in] length Length of the packet, in bytes 00383 * @return Error code 00384 **/ 00385 00386 error_t chapProcessSuccess(PppContext *context, 00387 const ChapSuccessPacket *successPacket, size_t length) 00388 { 00389 //Debug message 00390 TRACE_INFO("\r\nCHAP Success packet received\r\n"); 00391 00392 //Make sure the Success packet is acceptable 00393 if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP) 00394 return ERROR_FAILURE; 00395 00396 //Check the length of the packet 00397 if(length < sizeof(ChapSuccessPacket)) 00398 return ERROR_INVALID_LENGTH; 00399 00400 //When a packet is received with an invalid Identifier field, the 00401 //packet is silently discarded without affecting the automaton 00402 if(successPacket->identifier != context->chapFsm.peerIdentifier) 00403 return ERROR_WRONG_IDENTIFIER; 00404 00405 //Switch to the Success-Rcvd state 00406 context->chapFsm.peerState = CHAP_STATE_7_SUCCESS_RCVD; 00407 //The user name has been accepted by the authenticator 00408 context->peerAuthDone = TRUE; 00409 00410 //Check whether PPP authentication is complete 00411 if(context->localAuthDone && context->peerAuthDone) 00412 { 00413 //Check current PPP phase 00414 if(context->pppPhase == PPP_PHASE_AUTHENTICATE) 00415 { 00416 //Advance to the Network phase 00417 context->pppPhase = PPP_PHASE_NETWORK; 00418 00419 #if (IPV4_SUPPORT == ENABLED) 00420 //IPCP Open event 00421 ipcpOpen(context); 00422 #endif 00423 #if (IPV6_SUPPORT == ENABLED) 00424 //IPV6CP Open event 00425 ipv6cpOpen(context); 00426 #endif 00427 } 00428 } 00429 00430 //Successful processing 00431 return NO_ERROR; 00432 } 00433 00434 00435 /** 00436 * @brief Process Failure packet 00437 * @param[in] context PPP context 00438 * @param[in] failurePacket Packet received from the peer 00439 * @param[in] length Length of the packet, in bytes 00440 * @return Error code 00441 **/ 00442 00443 error_t chapProcessFailure(PppContext *context, 00444 const ChapFailurePacket *failurePacket, size_t length) 00445 { 00446 //Debug message 00447 TRACE_INFO("\r\nCHAP Failure packet received\r\n"); 00448 00449 //Make sure the Failure packet is acceptable 00450 if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP) 00451 return ERROR_FAILURE; 00452 00453 //Check the length of the packet 00454 if(length < sizeof(ChapFailurePacket)) 00455 return ERROR_INVALID_LENGTH; 00456 00457 //When a packet is received with an invalid Identifier field, the 00458 //packet is silently discarded without affecting the automaton 00459 if(failurePacket->identifier != context->chapFsm.peerIdentifier) 00460 return ERROR_WRONG_IDENTIFIER; 00461 00462 //Switch to the Failure-Rcvd state 00463 context->chapFsm.peerState = CHAP_STATE_9_FAILURE_RCVD; 00464 //Authentication failed 00465 lcpClose(context); 00466 00467 //Successful processing 00468 return NO_ERROR; 00469 } 00470 00471 00472 /** 00473 * @brief Send Challenge packet 00474 * @param[in] context PPP context 00475 * @return Error code 00476 **/ 00477 00478 error_t chapSendChallenge(PppContext *context) 00479 { 00480 error_t error; 00481 size_t n; 00482 size_t length; 00483 size_t offset; 00484 NetBuffer *buffer; 00485 ChapChallengePacket *challengePacket; 00486 00487 //Retrieve the length of the username 00488 n = strlen(context->username); 00489 //Calculate the length of the Challenge packet 00490 length = sizeof(ChapChallengePacket) + MD5_DIGEST_SIZE + n; 00491 00492 //Allocate a buffer memory to hold the Challenge packet 00493 buffer = pppAllocBuffer(length, &offset); 00494 //Failed to allocate memory? 00495 if(buffer == NULL) 00496 return ERROR_OUT_OF_MEMORY; 00497 00498 //Point to the Challenge packet 00499 challengePacket = netBufferAt(buffer, offset); 00500 00501 //Format packet header 00502 challengePacket->code = CHAP_CODE_CHALLENGE; 00503 challengePacket->identifier = ++context->chapFsm.localIdentifier; 00504 challengePacket->length = htons(length); 00505 challengePacket->valueSize = MD5_DIGEST_SIZE; 00506 00507 //Make sure that the callback function has been registered 00508 if(context->settings.randCallback != NULL) 00509 { 00510 //Generate a random challenge value 00511 error = context->settings.randCallback( 00512 context->chapFsm.challenge, MD5_DIGEST_SIZE); 00513 } 00514 else 00515 { 00516 //Report an error 00517 error = ERROR_FAILURE; 00518 } 00519 00520 //Check status code 00521 if(!error) 00522 { 00523 //Copy the challenge value 00524 memcpy(challengePacket->value, context->chapFsm.challenge, MD5_DIGEST_SIZE); 00525 00526 //The Name field is one or more octets representing the 00527 //identification of the system transmitting the packet 00528 memcpy(challengePacket->value + MD5_DIGEST_SIZE, context->username, n); 00529 00530 //Debug message 00531 TRACE_INFO("Sending CHAP Challenge packet (%" PRIuSIZE " bytes)...\r\n", length); 00532 //Dump packet contents for debugging purpose 00533 pppDumpPacket((PppPacket *) challengePacket, length, PPP_PROTOCOL_CHAP); 00534 00535 //Send PPP frame 00536 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP); 00537 00538 //The restart counter is decremented each time a Challenge packet is sent 00539 if(context->chapFsm.restartCounter > 0) 00540 context->chapFsm.restartCounter--; 00541 00542 //Save the time at which the packet was sent 00543 context->chapFsm.timestamp = osGetSystemTime(); 00544 } 00545 00546 //Free previously allocated memory block 00547 netBufferFree(buffer); 00548 //Return status code 00549 return error; 00550 } 00551 00552 00553 /** 00554 * @brief Send Response packet 00555 * @param[in] context PPP context 00556 * @param[in] value Response value 00557 * @return Error code 00558 **/ 00559 00560 error_t chapSendResponse(PppContext *context, const uint8_t *value) 00561 { 00562 error_t error; 00563 size_t n; 00564 size_t length; 00565 size_t offset; 00566 NetBuffer *buffer; 00567 ChapResponsePacket *responsePacket; 00568 00569 //Retrieve the length of the username 00570 n = strlen(context->username); 00571 //Calculate the length of the Response packet 00572 length = sizeof(ChapResponsePacket) + MD5_DIGEST_SIZE + n; 00573 00574 //Allocate a buffer memory to hold the Response packet 00575 buffer = pppAllocBuffer(length, &offset); 00576 //Failed to allocate memory? 00577 if(buffer == NULL) 00578 return ERROR_OUT_OF_MEMORY; 00579 00580 //Point to the Response packet 00581 responsePacket = netBufferAt(buffer, offset); 00582 00583 //Format packet header 00584 responsePacket->code = CHAP_CODE_RESPONSE; 00585 responsePacket->identifier = context->chapFsm.peerIdentifier; 00586 responsePacket->length = htons(length); 00587 responsePacket->valueSize = MD5_DIGEST_SIZE; 00588 00589 //Copy the Response value 00590 memcpy(responsePacket->value, value, MD5_DIGEST_SIZE); 00591 00592 //The Name field is one or more octets representing the 00593 //identification of the system transmitting the packet 00594 memcpy(responsePacket->value + MD5_DIGEST_SIZE, context->username, n); 00595 00596 //Debug message 00597 TRACE_INFO("Sending CHAP Response packet (%" PRIuSIZE " bytes)...\r\n", length); 00598 //Dump packet contents for debugging purpose 00599 pppDumpPacket((PppPacket *) responsePacket, length, PPP_PROTOCOL_CHAP); 00600 00601 //Send PPP frame 00602 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP); 00603 00604 //Free previously allocated memory block 00605 netBufferFree(buffer); 00606 //Return status code 00607 return error; 00608 } 00609 00610 00611 /** 00612 * @brief Send Success packet 00613 * @param[in] context PPP context 00614 * @return Error code 00615 **/ 00616 00617 error_t chapSendSuccess(PppContext *context) 00618 { 00619 error_t error; 00620 size_t length; 00621 size_t offset; 00622 NetBuffer *buffer; 00623 PppPacket *successPacket; 00624 00625 //Retrieve the length of the Success packet 00626 length = sizeof(PppPacket); 00627 00628 //Allocate a buffer memory to hold the Success packet 00629 buffer = pppAllocBuffer(length, &offset); 00630 //Failed to allocate memory? 00631 if(buffer == NULL) 00632 return ERROR_OUT_OF_MEMORY; 00633 00634 //Point to the Success packet 00635 successPacket = netBufferAt(buffer, offset); 00636 00637 //Format packet header 00638 successPacket->code = CHAP_CODE_SUCCESS; 00639 successPacket->identifier = context->chapFsm.localIdentifier; 00640 successPacket->length = htons(length); 00641 00642 //Debug message 00643 TRACE_INFO("Sending CHAP Success packet (%" PRIuSIZE " bytes)...\r\n", length); 00644 //Dump packet contents for debugging purpose 00645 pppDumpPacket((PppPacket *) successPacket, length, PPP_PROTOCOL_CHAP); 00646 00647 //Send PPP frame 00648 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP); 00649 00650 //Free previously allocated memory block 00651 netBufferFree(buffer); 00652 //Return status code 00653 return error; 00654 } 00655 00656 00657 /** 00658 * @brief Send Failure packet 00659 * @param[in] context PPP context 00660 * @return Error code 00661 **/ 00662 00663 error_t chapSendFailure(PppContext *context) 00664 { 00665 error_t error; 00666 size_t length; 00667 size_t offset; 00668 NetBuffer *buffer; 00669 PppPacket *failurePacket; 00670 00671 //Retrieve the length of the Failure packet 00672 length = sizeof(PppPacket); 00673 00674 //Allocate a buffer memory to hold the Failure packet 00675 buffer = pppAllocBuffer(length, &offset); 00676 //Failed to allocate memory? 00677 if(buffer == NULL) 00678 return ERROR_OUT_OF_MEMORY; 00679 00680 //Point to the Failure packet 00681 failurePacket = netBufferAt(buffer, offset); 00682 00683 //Format packet header 00684 failurePacket->code = CHAP_CODE_FAILURE; 00685 failurePacket->identifier = context->chapFsm.localIdentifier; 00686 failurePacket->length = htons(length); 00687 00688 //Debug message 00689 TRACE_INFO("Sending CHAP Failure packet (%" PRIuSIZE " bytes)...\r\n", length); 00690 //Dump packet contents for debugging purpose 00691 pppDumpPacket((PppPacket *) failurePacket, length, PPP_PROTOCOL_CHAP); 00692 00693 //Send PPP frame 00694 error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP); 00695 00696 //Free previously allocated memory block 00697 netBufferFree(buffer); 00698 //Return status code 00699 return error; 00700 } 00701 00702 00703 /** 00704 * @brief Password verification 00705 * @param[in] context PPP context 00706 * @param[in] password NULL-terminated string containing the password to be checked 00707 * @return TRUE if the password is valid, else FALSE 00708 **/ 00709 00710 bool_t chapCheckPassword(PppContext *context, const char_t *password) 00711 { 00712 size_t n; 00713 Md5Context md5Context; 00714 00715 //Retrieve the length of the password 00716 n = strlen(password); 00717 00718 //The response value is the one-way hash calculated over a stream 00719 //of octets consisting of the identifier, followed by the secret, 00720 //followed by the challenge value 00721 md5Init(&md5Context); 00722 md5Update(&md5Context, &context->chapFsm.localIdentifier, sizeof(uint8_t)); 00723 md5Update(&md5Context, password, n); 00724 md5Update(&md5Context, context->chapFsm.challenge, MD5_DIGEST_SIZE); 00725 md5Final(&md5Context, NULL); 00726 00727 //Check the resulting digest value 00728 if(!memcmp(md5Context.digest, context->chapFsm.response, MD5_DIGEST_SIZE)) 00729 return TRUE; 00730 else 00731 return FALSE; 00732 } 00733 00734 #endif 00735
Generated on Tue Jul 12 2022 17:10:12 by
