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.4
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, 0);
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 
551  //Return status code
552  return error;
553 }
554 
555 
556 /**
557  * @brief Send Response packet
558  * @param[in] context PPP context
559  * @param[in] value Response value
560  * @return Error code
561  **/
562 
563 error_t chapSendResponse(PppContext *context, const uint8_t *value)
564 {
565  error_t error;
566  size_t n;
567  size_t length;
568  size_t offset;
569  NetBuffer *buffer;
570  ChapResponsePacket *responsePacket;
571 
572  //Retrieve the length of the username
573  n = osStrlen(context->username);
574  //Calculate the length of the Response packet
576 
577  //Allocate a buffer memory to hold the Response packet
578  buffer = pppAllocBuffer(length, &offset);
579  //Failed to allocate memory?
580  if(buffer == NULL)
581  return ERROR_OUT_OF_MEMORY;
582 
583  //Point to the Response packet
584  responsePacket = netBufferAt(buffer, offset, 0);
585 
586  //Format packet header
587  responsePacket->code = CHAP_CODE_RESPONSE;
588  responsePacket->identifier = context->chapFsm.peerIdentifier;
589  responsePacket->length = htons(length);
590  responsePacket->valueSize = MD5_DIGEST_SIZE;
591 
592  //Copy the Response value
593  osMemcpy(responsePacket->value, value, MD5_DIGEST_SIZE);
594 
595  //The Name field is one or more octets representing the
596  //identification of the system transmitting the packet
597  osMemcpy(responsePacket->value + MD5_DIGEST_SIZE, context->username, n);
598 
599  //Debug message
600  TRACE_INFO("Sending CHAP Response packet (%" PRIuSIZE " bytes)...\r\n", length);
601  //Dump packet contents for debugging purpose
602  pppDumpPacket((PppPacket *) responsePacket, length, PPP_PROTOCOL_CHAP);
603 
604  //Send PPP frame
605  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
606 
607  //Free previously allocated memory block
608  netBufferFree(buffer);
609 
610  //Return status code
611  return error;
612 }
613 
614 
615 /**
616  * @brief Send Success packet
617  * @param[in] context PPP context
618  * @return Error code
619  **/
620 
622 {
623  error_t error;
624  size_t length;
625  size_t offset;
626  NetBuffer *buffer;
627  PppPacket *successPacket;
628 
629  //Retrieve the length of the Success packet
630  length = sizeof(PppPacket);
631 
632  //Allocate a buffer memory to hold the Success packet
633  buffer = pppAllocBuffer(length, &offset);
634  //Failed to allocate memory?
635  if(buffer == NULL)
636  return ERROR_OUT_OF_MEMORY;
637 
638  //Point to the Success packet
639  successPacket = netBufferAt(buffer, offset, 0);
640 
641  //Format packet header
642  successPacket->code = CHAP_CODE_SUCCESS;
643  successPacket->identifier = context->chapFsm.localIdentifier;
644  successPacket->length = htons(length);
645 
646  //Debug message
647  TRACE_INFO("Sending CHAP Success packet (%" PRIuSIZE " bytes)...\r\n", length);
648  //Dump packet contents for debugging purpose
649  pppDumpPacket((PppPacket *) successPacket, length, PPP_PROTOCOL_CHAP);
650 
651  //Send PPP frame
652  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
653 
654  //Free previously allocated memory block
655  netBufferFree(buffer);
656 
657  //Return status code
658  return error;
659 }
660 
661 
662 /**
663  * @brief Send Failure packet
664  * @param[in] context PPP context
665  * @return Error code
666  **/
667 
669 {
670  error_t error;
671  size_t length;
672  size_t offset;
673  NetBuffer *buffer;
674  PppPacket *failurePacket;
675 
676  //Retrieve the length of the Failure packet
677  length = sizeof(PppPacket);
678 
679  //Allocate a buffer memory to hold the Failure packet
680  buffer = pppAllocBuffer(length, &offset);
681  //Failed to allocate memory?
682  if(buffer == NULL)
683  return ERROR_OUT_OF_MEMORY;
684 
685  //Point to the Failure packet
686  failurePacket = netBufferAt(buffer, offset, 0);
687 
688  //Format packet header
689  failurePacket->code = CHAP_CODE_FAILURE;
690  failurePacket->identifier = context->chapFsm.localIdentifier;
691  failurePacket->length = htons(length);
692 
693  //Debug message
694  TRACE_INFO("Sending CHAP Failure packet (%" PRIuSIZE " bytes)...\r\n", length);
695  //Dump packet contents for debugging purpose
696  pppDumpPacket((PppPacket *) failurePacket, length, PPP_PROTOCOL_CHAP);
697 
698  //Send PPP frame
699  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
700 
701  //Free previously allocated memory block
702  netBufferFree(buffer);
703 
704  //Return status code
705  return error;
706 }
707 
708 
709 /**
710  * @brief Password verification
711  * @param[in] context PPP context
712  * @param[in] password NULL-terminated string containing the password to be checked
713  * @return TRUE if the password is valid, else FALSE
714  **/
715 
716 bool_t chapCheckPassword(PppContext *context, const char_t *password)
717 {
718  size_t n;
719  Md5Context md5Context;
720 
721  //Retrieve the length of the password
722  n = osStrlen(password);
723 
724  //The response value is the one-way hash calculated over a stream
725  //of octets consisting of the identifier, followed by the secret,
726  //followed by the challenge value
727  md5Init(&md5Context);
728  md5Update(&md5Context, &context->chapFsm.localIdentifier, sizeof(uint8_t));
729  md5Update(&md5Context, password, n);
730  md5Update(&md5Context, context->chapFsm.challenge, MD5_DIGEST_SIZE);
731  md5Final(&md5Context, NULL);
732 
733  //Check the resulting digest value
734  if(!osMemcmp(md5Context.digest, context->chapFsm.response, MD5_DIGEST_SIZE))
735  {
736  return TRUE;
737  }
738  else
739  {
740  return FALSE;
741  }
742 }
743 
744 #endif
@ CHAP_STATE_0_INITIAL
Definition: chap.h:71
#define htons(value)
Definition: cpu_endian.h:413
error_t chapProcessSuccess(PppContext *context, const ChapSuccessPacket *successPacket, size_t length)
Process Success packet.
Definition: chap.c:388
Data logging functions for debugging purpose (PPP)
int bool_t
Definition: compiler_port.h:53
#define PppPacket
Definition: ppp.h:37
uint8_t digest[16]
Definition: md5.h:66
error_t chapSendResponse(PppContext *context, const uint8_t *value)
Send Response packet.
Definition: chap.c:563
CHAP (Challenge Handshake Authentication Protocol)
@ CHAP_CODE_SUCCESS
Success.
Definition: chap.h:92
#define CHAP_MAX_CHALLENGES
Definition: chap.h:54
void chapProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming CHAP packet.
Definition: chap.c:149
@ PPP_PROTOCOL_CHAP
Challenge Handshake Authentication Protocol.
Definition: ppp.h:206
uint8_t p
Definition: ndp.h:300
@ CHAP_STATE_6_SUCCESS_SENT
Definition: chap.h:77
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define TRUE
Definition: os_port.h:50
IPV6CP (PPP IPv6 Control Protocol)
@ CHAP_STATE_1_STARTED
Definition: chap.h:72
void chapTick(PppContext *context)
CHAP timer handler.
Definition: chap.c:110
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
#define CHAP_RESTART_TIMER
Definition: chap.h:47
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ CHAP_CODE_CHALLENGE
Challenge.
Definition: chap.h:90
@ PPP_PHASE_NETWORK
Network-layer protocol phase.
Definition: ppp.h:169
@ CHAP_STATE_2_CHALLENGE_SENT
Definition: chap.h:73
@ CHAP_CODE_RESPONSE
Response.
Definition: chap.h:91
NetBuffer * pppAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold a PPP frame.
Definition: ppp.c:1305
#define osStrlen(s)
Definition: os_port.h:165
ChapChallengePacket
Definition: chap.h:128
#define PppContext
Definition: ppp.h:38
IPCP (PPP Internet Protocol Control Protocol)
LCP (PPP Link Control Protocol)
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
#define FALSE
Definition: os_port.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
ChapResponsePacket
Definition: chap.h:142
error_t
Error codes.
Definition: error.h:43
@ CHAP_CODE_FAILURE
Failure.
Definition: chap.h:93
error_t chapAbortAuth(PppContext *context)
Abort CHAP authentication.
Definition: chap.c:91
@ PPP_PHASE_AUTHENTICATE
Authentication phase.
Definition: ppp.h:168
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ CHAP_STATE_4_RESPONSE_SENT
Definition: chap.h:75
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
@ CHAP_STATE_7_SUCCESS_RCVD
Definition: chap.h:78
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
ChapSuccessPacket
Definition: chap.h:155
error_t chapSendSuccess(PppContext *context)
Send Success packet.
Definition: chap.c:621
MD5 algorithm context.
Definition: md5.h:62
@ CHAP_STATE_9_FAILURE_RCVD
Definition: chap.h:80
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
error_t chapProcessFailure(PppContext *context, const ChapFailurePacket *failurePacket, size_t length)
Process Failure packet.
Definition: chap.c:445
#define MIN(a, b)
Definition: os_port.h:63
error_t ipcpOpen(PppContext *context)
IPCP Open event.
Definition: ipcp.c:76
#define MD5_DIGEST_SIZE
Definition: md5.h:45
uint32_t systime_t
System time.
#define ntohs(value)
Definition: cpu_endian.h:421
char char_t
Definition: compiler_port.h:48
uint32_t time
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1035
uint8_t n
error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump LCP/NCP packet for debugging purpose.
Definition: ppp_debug.c:143
MD5 (Message-Digest Algorithm)
bool_t chapCheckPassword(PppContext *context, const char_t *password)
Password verification.
Definition: chap.c:716
error_t chapSendChallenge(PppContext *context)
Send Challenge packet.
Definition: chap.c:480
error_t chapProcessChallenge(PppContext *context, const ChapChallengePacket *challengePacket, size_t length)
Process Challenge packet.
Definition: chap.c:218
error_t chapProcessResponse(PppContext *context, const ChapResponsePacket *responsePacket, size_t length)
Process Response packet.
Definition: chap.c:273
uint8_t value[]
Definition: tcp.h:369
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
error_t ipv6cpOpen(PppContext *context)
IPV6CP Open event.
Definition: ipv6cp.c:77
error_t chapStartAuth(PppContext *context)
Start CHAP authentication.
Definition: chap.c:57
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
error_t chapSendFailure(PppContext *context)
Send Failure packet.
Definition: chap.c:668
error_t lcpClose(PppContext *context)
LCP Close event.
Definition: lcp.c:103
#define PRIuSIZE
TCP/IP stack core.
ChapFailurePacket
Definition: chap.h:168
@ CHAP_STATE_8_FAILURE_SENT
Definition: chap.h:79
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
systime_t osGetSystemTime(void)
Retrieve system time.
#define PPP_MAX_USERNAME_LEN
Definition: ppp.h:68