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