chap.c
Go to the documentation of this file.
1 /**
2  * @file chap.c
3  * @brief CHAP (Challenge Handshake Authentication Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL PPP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ppp/ppp_debug.h"
37 #include "ppp/lcp.h"
38 #include "ppp/ipcp.h"
39 #include "ppp/ipv6cp.h"
40 #include "ppp/chap.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (PPP_SUPPORT == ENABLED && CHAP_SUPPORT == ENABLED)
45 
46 //Additional dependencies
47 #include "core/crypto.h"
48 #include "hash/md5.h"
49 
50 
51 /**
52  * @brief Start CHAP authentication
53  * @param[in] context PPP context
54  * @return Error code
55  **/
56 
58 {
59  //Debug message
60  TRACE_INFO("\r\nStarting CHAP authentication...\r\n");
61 
62  //Check whether the other end of the PPP link is being authenticated
63  if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP)
64  {
65  //Initialize restart counter
66  context->chapFsm.restartCounter = CHAP_MAX_CHALLENGES;
67  //Send a Challenge packet
68  chapSendChallenge(context);
69  //Switch to the Challenge-Sent state
70  context->chapFsm.localState = CHAP_STATE_2_CHALLENGE_SENT;
71  }
72 
73  //Check whether the other end of the PPP link is the authenticator
74  if(context->peerConfig.authProtocol == PPP_PROTOCOL_CHAP)
75  {
76  //Switch to the Started state
77  context->chapFsm.peerState = CHAP_STATE_1_STARTED;
78  }
79 
80  //Successful processing
81  return NO_ERROR;
82 }
83 
84 
85 /**
86  * @brief Abort CHAP authentication
87  * @param[in] context PPP context
88  * @return Error code
89  **/
90 
92 {
93  //Debug message
94  TRACE_INFO("\r\nAborting CHAP authentication...\r\n");
95 
96  //Abort CHAP authentication process
97  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
98  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
99 
100  //Successful processing
101  return NO_ERROR;
102 }
103 
104 
105 /**
106  * @brief CHAP timer handler
107  * @param[in] context PPP context
108  **/
109 
110 void chapTick(PppContext *context)
111 {
112  //Check whether the restart timer is running
113  if(context->chapFsm.localState == CHAP_STATE_2_CHALLENGE_SENT)
114  {
115  //Get current time
117 
118  //Check restart timer
119  if((time - context->chapFsm.timestamp) >= CHAP_RESTART_TIMER)
120  {
121  //Debug message
122  TRACE_INFO("\r\nCHAP Timeout event\r\n");
123 
124  //Check whether the restart counter is greater than zero
125  if(context->chapFsm.restartCounter > 0)
126  {
127  //Retransmit the Challenge packet
128  chapSendChallenge(context);
129  }
130  else
131  {
132  //Abort CHAP authentication
133  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
134  //Authentication failed
135  lcpClose(context);
136  }
137  }
138  }
139 }
140 
141 
142 /**
143  * @brief Process an incoming CHAP packet
144  * @param[in] context PPP context
145  * @param[in] packet CHAP packet received from the peer
146  * @param[in] length Length of the packet, in bytes
147  **/
148 
150  const PppPacket *packet, size_t length)
151 {
152  //Ensure the length of the incoming CHAP packet is valid
153  if(length < sizeof(PppPacket))
154  return;
155 
156  //Check the length field
157  if(ntohs(packet->length) > length)
158  return;
159  if(ntohs(packet->length) < sizeof(PppPacket))
160  return;
161 
162  //Save the length of the CHAP packet
163  length = ntohs(packet->length);
164 
165  //Debug message
166  TRACE_INFO("CHAP packet received (%" PRIuSIZE " bytes)...\r\n", length);
167  //Dump CHAP packet contents for debugging purpose
169 
170  //CHAP is done at initial link establishment, and could also be
171  //requested after link establishment
172  if(context->pppPhase != PPP_PHASE_AUTHENTICATE &&
173  context->pppPhase != PPP_PHASE_NETWORK)
174  {
175  //Any packets received during any other phase must be silently discarded
176  return;
177  }
178 
179  //Check CHAP code field
180  switch(packet->code)
181  {
182  //Challenge packet?
183  case CHAP_CODE_CHALLENGE:
184  //Process Challenge packet
185  chapProcessChallenge(context, (ChapChallengePacket *) packet, length);
186  break;
187  //Response packet?
188  case CHAP_CODE_RESPONSE:
189  //Process Response packet
190  chapProcessResponse(context, (ChapResponsePacket *) packet, length);
191  break;
192  //Success packet?
193  case CHAP_CODE_SUCCESS:
194  //Process Success packet
195  chapProcessSuccess(context, (ChapSuccessPacket *) packet, length);
196  break;
197  //Failure packet?
198  case CHAP_CODE_FAILURE:
199  //Process Failure packet
200  chapProcessFailure(context, (ChapFailurePacket *) packet, length);
201  break;
202  //Unknown code field
203  default:
204  //Silently drop the incoming packet
205  break;
206  }
207 }
208 
209 
210 /**
211  * @brief Process Challenge packet
212  * @param[in] context PPP context
213  * @param[in] challengePacket Packet received from the peer
214  * @param[in] length Length of the packet, in bytes
215  * @return Error code
216  **/
217 
219  const ChapChallengePacket *challengePacket, size_t length)
220 {
221  size_t n;
222  Md5Context md5Context;
223 
224  //Debug message
225  TRACE_INFO("\r\nCHAP Challenge packet received\r\n");
226 
227  //Make sure the Challenge packet is acceptable
228  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
229  return ERROR_FAILURE;
230 
231  //Check the length of the packet
232  if(length < sizeof(ChapChallengePacket))
233  return ERROR_INVALID_LENGTH;
234 
235  //Malformed Challenge packet?
236  if(length < (sizeof(ChapChallengePacket) + challengePacket->valueSize))
237  return ERROR_INVALID_LENGTH;
238 
239  //Save the Identifier field
240  context->chapFsm.peerIdentifier = challengePacket->identifier;
241 
242  //Retrieve the length of the password
243  n = osStrlen(context->password);
244 
245  //The response value is the one-way hash calculated over a stream
246  //of octets consisting of the identifier, followed by the secret,
247  //followed by the challenge value
248  md5Init(&md5Context);
249  md5Update(&md5Context, &challengePacket->identifier, sizeof(uint8_t));
250  md5Update(&md5Context, context->password, n);
251  md5Update(&md5Context, challengePacket->value, challengePacket->valueSize);
252  md5Final(&md5Context, NULL);
253 
254  //Whenever a Challenge packet is received, the peer must send a Response packet
255  chapSendResponse(context, md5Context.digest);
256 
257  //Switch to the Response-Sent state
258  context->chapFsm.peerState = CHAP_STATE_4_RESPONSE_SENT;
259 
260  //Successful processing
261  return NO_ERROR;
262 }
263 
264 
265 /**
266  * @brief Process Response packet
267  * @param[in] context PPP context
268  * @param[in] responsePacket Packet received from the peer
269  * @param[in] length Length of the packet, in bytes
270  * @return Error code
271  **/
272 
274  const ChapResponsePacket *responsePacket, size_t length)
275 {
276  bool_t status;
277  const uint8_t *p;
278 
279  //Debug message
280  TRACE_INFO("\r\nCHAP Response packet received\r\n");
281 
282  //Make sure the Response packet is acceptable
283  if(context->localConfig.authProtocol != PPP_PROTOCOL_CHAP)
284  return ERROR_FAILURE;
285 
286  //Check the length of the packet
287  if(length < sizeof(ChapResponsePacket))
288  return ERROR_INVALID_LENGTH;
289 
290  //When a packet is received with an invalid Identifier field, the
291  //packet is silently discarded without affecting the automaton
292  if(responsePacket->identifier != context->chapFsm.localIdentifier)
293  return ERROR_WRONG_IDENTIFIER;
294 
295  //Malformed Response packet?
296  if(length < (sizeof(ChapResponsePacket) + responsePacket->valueSize))
297  return ERROR_INVALID_LENGTH;
298 
299  //The length of the response value depends upon the hash algorithm used
300  if(responsePacket->valueSize != MD5_DIGEST_SIZE)
301  return ERROR_INVALID_LENGTH;
302 
303  //Retrieve the response value
304  context->chapFsm.response = responsePacket->value;
305 
306  //Point to the Name field
307  p = responsePacket->value + responsePacket->valueSize;
308  //Retrieve the length of the Name field
309  length -= sizeof(ChapResponsePacket) + responsePacket->valueSize;
310 
311  //Limit the length of the string
313  //Copy the name of the peer to be identified
314  osMemcpy(context->peerName, p, length);
315  //Properly terminate the string with a NULL character
316  context->peerName[length] = '\0';
317 
318  //Invoke user-defined callback, if any
319  if(context->settings.authCallback != NULL)
320  {
321  //Perfom username and password verification
322  status = context->settings.authCallback(context->interface,
323  context->peerName);
324  }
325  else
326  {
327  //Unable to perform authentication...
328  status = FALSE;
329  }
330 
331  //Whenever a Response packet is received, the authenticator compares the
332  //Response Value with its own calculation of the expected value. Based on
333  //this comparison, the authenticator must send a Success or Failure packet
334  if(status)
335  {
336  //Send a Success packet
337  chapSendSuccess(context);
338 
339  //Switch to the Success-Sent state
340  context->chapFsm.localState = CHAP_STATE_6_SUCCESS_SENT;
341  //The user has been successfully authenticated
342  context->localAuthDone = TRUE;
343 
344  //Check whether PPP authentication is complete
345  if(context->localAuthDone && context->peerAuthDone)
346  {
347  //Check current PPP phase
348  if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
349  {
350  //Advance to the Network phase
351  context->pppPhase = PPP_PHASE_NETWORK;
352 
353 #if (IPV4_SUPPORT == ENABLED)
354  //IPCP Open event
355  ipcpOpen(context);
356 #endif
357 #if (IPV6_SUPPORT == ENABLED)
358  //IPV6CP Open event
359  ipv6cpOpen(context);
360 #endif
361  }
362  }
363  }
364  else
365  {
366  //Send a Failure packet
367  chapSendFailure(context);
368 
369  //Switch to the Failure-Sent state
370  context->chapFsm.localState = CHAP_STATE_8_FAILURE_SENT;
371  //The authenticator should take action to terminate the link
372  lcpClose(context);
373  }
374 
375  //Successful processing
376  return NO_ERROR;
377 }
378 
379 
380 /**
381  * @brief Process Success packet
382  * @param[in] context PPP context
383  * @param[in] successPacket Packet received from the peer
384  * @param[in] length Length of the packet, in bytes
385  * @return Error code
386  **/
387 
389  const ChapSuccessPacket *successPacket, size_t length)
390 {
391  //Debug message
392  TRACE_INFO("\r\nCHAP Success packet received\r\n");
393 
394  //Make sure the Success packet is acceptable
395  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
396  return ERROR_FAILURE;
397 
398  //Check the length of the packet
399  if(length < sizeof(ChapSuccessPacket))
400  return ERROR_INVALID_LENGTH;
401 
402  //When a packet is received with an invalid Identifier field, the
403  //packet is silently discarded without affecting the automaton
404  if(successPacket->identifier != context->chapFsm.peerIdentifier)
405  return ERROR_WRONG_IDENTIFIER;
406 
407  //Switch to the Success-Rcvd state
408  context->chapFsm.peerState = CHAP_STATE_7_SUCCESS_RCVD;
409  //The user name has been accepted by the authenticator
410  context->peerAuthDone = TRUE;
411 
412  //Check whether PPP authentication is complete
413  if(context->localAuthDone && context->peerAuthDone)
414  {
415  //Check current PPP phase
416  if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
417  {
418  //Advance to the Network phase
419  context->pppPhase = PPP_PHASE_NETWORK;
420 
421 #if (IPV4_SUPPORT == ENABLED)
422  //IPCP Open event
423  ipcpOpen(context);
424 #endif
425 #if (IPV6_SUPPORT == ENABLED)
426  //IPV6CP Open event
427  ipv6cpOpen(context);
428 #endif
429  }
430  }
431 
432  //Successful processing
433  return NO_ERROR;
434 }
435 
436 
437 /**
438  * @brief Process Failure packet
439  * @param[in] context PPP context
440  * @param[in] failurePacket Packet received from the peer
441  * @param[in] length Length of the packet, in bytes
442  * @return Error code
443  **/
444 
446  const ChapFailurePacket *failurePacket, size_t length)
447 {
448  //Debug message
449  TRACE_INFO("\r\nCHAP Failure packet received\r\n");
450 
451  //Make sure the Failure packet is acceptable
452  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
453  return ERROR_FAILURE;
454 
455  //Check the length of the packet
456  if(length < sizeof(ChapFailurePacket))
457  return ERROR_INVALID_LENGTH;
458 
459  //When a packet is received with an invalid Identifier field, the
460  //packet is silently discarded without affecting the automaton
461  if(failurePacket->identifier != context->chapFsm.peerIdentifier)
462  return ERROR_WRONG_IDENTIFIER;
463 
464  //Switch to the Failure-Rcvd state
465  context->chapFsm.peerState = CHAP_STATE_9_FAILURE_RCVD;
466  //Authentication failed
467  lcpClose(context);
468 
469  //Successful processing
470  return NO_ERROR;
471 }
472 
473 
474 /**
475  * @brief Send Challenge packet
476  * @param[in] context PPP context
477  * @return Error code
478  **/
479 
481 {
482  error_t error;
483  size_t n;
484  size_t length;
485  size_t offset;
486  NetBuffer *buffer;
487  ChapChallengePacket *challengePacket;
488 
489  //Retrieve the length of the username
490  n = osStrlen(context->username);
491  //Calculate the length of the Challenge packet
493 
494  //Allocate a buffer memory to hold the Challenge packet
495  buffer = pppAllocBuffer(length, &offset);
496  //Failed to allocate memory?
497  if(buffer == NULL)
498  return ERROR_OUT_OF_MEMORY;
499 
500  //Point to the Challenge packet
501  challengePacket = netBufferAt(buffer, offset);
502 
503  //Format packet header
504  challengePacket->code = CHAP_CODE_CHALLENGE;
505  challengePacket->identifier = ++context->chapFsm.localIdentifier;
506  challengePacket->length = htons(length);
507  challengePacket->valueSize = MD5_DIGEST_SIZE;
508 
509  //Make sure that the callback function has been registered
510  if(context->settings.randCallback != NULL)
511  {
512  //Generate a random challenge value
513  error = context->settings.randCallback(
514  context->chapFsm.challenge, MD5_DIGEST_SIZE);
515  }
516  else
517  {
518  //Report an error
519  error = ERROR_FAILURE;
520  }
521 
522  //Check status code
523  if(!error)
524  {
525  //Copy the challenge value
526  osMemcpy(challengePacket->value, context->chapFsm.challenge, MD5_DIGEST_SIZE);
527 
528  //The Name field is one or more octets representing the
529  //identification of the system transmitting the packet
530  osMemcpy(challengePacket->value + MD5_DIGEST_SIZE, context->username, n);
531 
532  //Debug message
533  TRACE_INFO("Sending CHAP Challenge packet (%" PRIuSIZE " bytes)...\r\n", length);
534  //Dump packet contents for debugging purpose
535  pppDumpPacket((PppPacket *) challengePacket, length, PPP_PROTOCOL_CHAP);
536 
537  //Send PPP frame
538  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
539 
540  //The restart counter is decremented each time a Challenge packet is sent
541  if(context->chapFsm.restartCounter > 0)
542  context->chapFsm.restartCounter--;
543 
544  //Save the time at which the packet was sent
545  context->chapFsm.timestamp = osGetSystemTime();
546  }
547 
548  //Free previously allocated memory block
549  netBufferFree(buffer);
550  //Return status code
551  return error;
552 }
553 
554 
555 /**
556  * @brief Send Response packet
557  * @param[in] context PPP context
558  * @param[in] value Response value
559  * @return Error code
560  **/
561 
562 error_t chapSendResponse(PppContext *context, const uint8_t *value)
563 {
564  error_t error;
565  size_t n;
566  size_t length;
567  size_t offset;
568  NetBuffer *buffer;
569  ChapResponsePacket *responsePacket;
570 
571  //Retrieve the length of the username
572  n = osStrlen(context->username);
573  //Calculate the length of the Response packet
575 
576  //Allocate a buffer memory to hold the Response packet
577  buffer = pppAllocBuffer(length, &offset);
578  //Failed to allocate memory?
579  if(buffer == NULL)
580  return ERROR_OUT_OF_MEMORY;
581 
582  //Point to the Response packet
583  responsePacket = netBufferAt(buffer, offset);
584 
585  //Format packet header
586  responsePacket->code = CHAP_CODE_RESPONSE;
587  responsePacket->identifier = context->chapFsm.peerIdentifier;
588  responsePacket->length = htons(length);
589  responsePacket->valueSize = MD5_DIGEST_SIZE;
590 
591  //Copy the Response value
592  osMemcpy(responsePacket->value, value, MD5_DIGEST_SIZE);
593 
594  //The Name field is one or more octets representing the
595  //identification of the system transmitting the packet
596  osMemcpy(responsePacket->value + MD5_DIGEST_SIZE, context->username, n);
597 
598  //Debug message
599  TRACE_INFO("Sending CHAP Response packet (%" PRIuSIZE " bytes)...\r\n", length);
600  //Dump packet contents for debugging purpose
601  pppDumpPacket((PppPacket *) responsePacket, length, PPP_PROTOCOL_CHAP);
602 
603  //Send PPP frame
604  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
605 
606  //Free previously allocated memory block
607  netBufferFree(buffer);
608  //Return status code
609  return error;
610 }
611 
612 
613 /**
614  * @brief Send Success packet
615  * @param[in] context PPP context
616  * @return Error code
617  **/
618 
620 {
621  error_t error;
622  size_t length;
623  size_t offset;
624  NetBuffer *buffer;
625  PppPacket *successPacket;
626 
627  //Retrieve the length of the Success packet
628  length = sizeof(PppPacket);
629 
630  //Allocate a buffer memory to hold the Success packet
631  buffer = pppAllocBuffer(length, &offset);
632  //Failed to allocate memory?
633  if(buffer == NULL)
634  return ERROR_OUT_OF_MEMORY;
635 
636  //Point to the Success packet
637  successPacket = netBufferAt(buffer, offset);
638 
639  //Format packet header
640  successPacket->code = CHAP_CODE_SUCCESS;
641  successPacket->identifier = context->chapFsm.localIdentifier;
642  successPacket->length = htons(length);
643 
644  //Debug message
645  TRACE_INFO("Sending CHAP Success packet (%" PRIuSIZE " bytes)...\r\n", length);
646  //Dump packet contents for debugging purpose
647  pppDumpPacket((PppPacket *) successPacket, length, PPP_PROTOCOL_CHAP);
648 
649  //Send PPP frame
650  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
651 
652  //Free previously allocated memory block
653  netBufferFree(buffer);
654  //Return status code
655  return error;
656 }
657 
658 
659 /**
660  * @brief Send Failure packet
661  * @param[in] context PPP context
662  * @return Error code
663  **/
664 
666 {
667  error_t error;
668  size_t length;
669  size_t offset;
670  NetBuffer *buffer;
671  PppPacket *failurePacket;
672 
673  //Retrieve the length of the Failure packet
674  length = sizeof(PppPacket);
675 
676  //Allocate a buffer memory to hold the Failure packet
677  buffer = pppAllocBuffer(length, &offset);
678  //Failed to allocate memory?
679  if(buffer == NULL)
680  return ERROR_OUT_OF_MEMORY;
681 
682  //Point to the Failure packet
683  failurePacket = netBufferAt(buffer, offset);
684 
685  //Format packet header
686  failurePacket->code = CHAP_CODE_FAILURE;
687  failurePacket->identifier = context->chapFsm.localIdentifier;
688  failurePacket->length = htons(length);
689 
690  //Debug message
691  TRACE_INFO("Sending CHAP Failure packet (%" PRIuSIZE " bytes)...\r\n", length);
692  //Dump packet contents for debugging purpose
693  pppDumpPacket((PppPacket *) failurePacket, length, PPP_PROTOCOL_CHAP);
694 
695  //Send PPP frame
696  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
697 
698  //Free previously allocated memory block
699  netBufferFree(buffer);
700  //Return status code
701  return error;
702 }
703 
704 
705 /**
706  * @brief Password verification
707  * @param[in] context PPP context
708  * @param[in] password NULL-terminated string containing the password to be checked
709  * @return TRUE if the password is valid, else FALSE
710  **/
711 
712 bool_t chapCheckPassword(PppContext *context, const char_t *password)
713 {
714  size_t n;
715  Md5Context md5Context;
716 
717  //Retrieve the length of the password
718  n = osStrlen(password);
719 
720  //The response value is the one-way hash calculated over a stream
721  //of octets consisting of the identifier, followed by the secret,
722  //followed by the challenge value
723  md5Init(&md5Context);
724  md5Update(&md5Context, &context->chapFsm.localIdentifier, sizeof(uint8_t));
725  md5Update(&md5Context, password, n);
726  md5Update(&md5Context, context->chapFsm.challenge, MD5_DIGEST_SIZE);
727  md5Final(&md5Context, NULL);
728 
729  //Check the resulting digest value
730  if(!osMemcmp(md5Context.digest, context->chapFsm.response, MD5_DIGEST_SIZE))
731  {
732  return TRUE;
733  }
734  else
735  {
736  return FALSE;
737  }
738 }
739 
740 #endif
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
error_t chapProcessSuccess(PppContext *context, const ChapSuccessPacket *successPacket, size_t length)
Process Success packet.
Definition: chap.c:388
error_t chapAbortAuth(PppContext *context)
Abort CHAP authentication.
Definition: chap.c:91
error_t chapSendFailure(PppContext *context)
Send Failure packet.
Definition: chap.c:665
void chapProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming CHAP packet.
Definition: chap.c:149
error_t chapProcessChallenge(PppContext *context, const ChapChallengePacket *challengePacket, size_t length)
Process Challenge packet.
Definition: chap.c:218
bool_t chapCheckPassword(PppContext *context, const char_t *password)
Password verification.
Definition: chap.c:712
error_t chapSendSuccess(PppContext *context)
Send Success packet.
Definition: chap.c:619
error_t chapProcessFailure(PppContext *context, const ChapFailurePacket *failurePacket, size_t length)
Process Failure packet.
Definition: chap.c:445
error_t chapSendResponse(PppContext *context, const uint8_t *value)
Send Response packet.
Definition: chap.c:562
error_t chapProcessResponse(PppContext *context, const ChapResponsePacket *responsePacket, size_t length)
Process Response packet.
Definition: chap.c:273
error_t chapSendChallenge(PppContext *context)
Send Challenge packet.
Definition: chap.c:480
void chapTick(PppContext *context)
CHAP timer handler.
Definition: chap.c:110
error_t chapStartAuth(PppContext *context)
Start CHAP authentication.
Definition: chap.c:57
CHAP (Challenge Handshake Authentication Protocol)
ChapFailurePacket
Definition: chap.h:168
ChapChallengePacket
Definition: chap.h:128
@ CHAP_STATE_2_CHALLENGE_SENT
Definition: chap.h:73
@ CHAP_STATE_7_SUCCESS_RCVD
Definition: chap.h:78
@ CHAP_STATE_8_FAILURE_SENT
Definition: chap.h:79
@ CHAP_STATE_6_SUCCESS_SENT
Definition: chap.h:77
@ CHAP_STATE_9_FAILURE_RCVD
Definition: chap.h:80
@ CHAP_STATE_4_RESPONSE_SENT
Definition: chap.h:75
@ CHAP_STATE_1_STARTED
Definition: chap.h:72
@ CHAP_STATE_0_INITIAL
Definition: chap.h:71
@ CHAP_CODE_RESPONSE
Response.
Definition: chap.h:91
@ CHAP_CODE_SUCCESS
Success.
Definition: chap.h:92
@ CHAP_CODE_CHALLENGE
Challenge.
Definition: chap.h:90
@ CHAP_CODE_FAILURE
Failure.
Definition: chap.h:93
ChapResponsePacket
Definition: chap.h:142
ChapSuccessPacket
Definition: chap.h:155
#define CHAP_MAX_CHALLENGES
Definition: chap.h:54
#define CHAP_RESTART_TIMER
Definition: chap.h:47
#define PRIuSIZE
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint32_t time
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t ipcpOpen(PppContext *context)
IPCP Open event.
Definition: ipcp.c:76
IPCP (PPP Internet Protocol Control Protocol)
error_t ipv6cpOpen(PppContext *context)
IPV6CP Open event.
Definition: ipv6cp.c:77
IPV6CP (PPP IPv6 Control Protocol)
error_t lcpClose(PppContext *context)
LCP Close event.
Definition: lcp.c:103
LCP (PPP Link Control Protocol)
MD5 (Message-Digest Algorithm)
#define MD5_DIGEST_SIZE
Definition: md5.h:45
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:415
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define osStrlen(s)
Definition: os_port.h:165
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
systime_t osGetSystemTime(void)
Retrieve system time.
uint32_t systime_t
System time.
NetBuffer * pppAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold a PPP frame.
Definition: ppp.c:1305
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1035
@ PPP_PROTOCOL_CHAP
Challenge Handshake Authentication Protocol.
Definition: ppp.h:206
#define PppContext
Definition: ppp.h:38
@ PPP_PHASE_AUTHENTICATE
Authentication phase.
Definition: ppp.h:168
@ PPP_PHASE_NETWORK
Network-layer protocol phase.
Definition: ppp.h:169
#define PppPacket
Definition: ppp.h:37
#define PPP_MAX_USERNAME_LEN
Definition: ppp.h:68
error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump LCP/NCP packet for debugging purpose.
Definition: ppp_debug.c:143
Data logging functions for debugging purpose (PPP)
MD5 algorithm context.
Definition: md5.h:62
uint8_t digest[16]
Definition: md5.h:66
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369