📄 chap.c
字号:
/***************************************************************************
*
* Copyright (c) 1997 - 2001 by Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject
* matter of this material. All manufacturing, reproduction, use and sales
* rights pertaining to this subject matter are governed by the license
* agreement. The recipient of this software implicity accepts the terms
* of the license.
*
****************************************************************************
****************************************************************************
*
* FILENAME VERSION
*
* CHAP.C 2.4
*
* COMPONENT
*
* Challenge Handshake Authentication Protocol for PPP
*
* DESCRIPTION
*
* This file contains the challenge handshake authentication protocol
* that is used the log into a PPP server and to authenticate a calling
* PPP client.
*
* DATA STRUCTURES
*
* none
*
* FUNCTIONS
*
* PPP_CHAP_Interpret
* CHAP_MD5_Encrypt
* CHAP_Timer_Expire
* CHAP_Send_Challenge
* CHAP_Respond_To_Challenge
* CHAP_Check_Response
* CHAP_Send_Success
* CHAP_Send_Failure
*
* DEPENDENCIES
*
* nucleus.h
* externs.h
* tcp_errs.h"
* netevent.h
* target.h
* ppp.h
* md5_gbl.h
* md5.h
*
****************************************************************************/
#include "plus/nucleus.h"
#include "net/inc/externs.h"
#include "net/inc/tcp_errs.h"
#include "net/inc/netevent.h"
#include "net/target.h" /* Compiler typedefs for data type sizes */
#include "ppp/inc/nu_ppp.h"
/* These are part of the MD5 encryption */
#include "net/inc/md5_gbl.h"
#include "net/inc/md5.h"
/* Import all external variables */
extern struct pw_list _passwordlist[];
/***************************************************************************
* FUNCTION
*
* PPP_CHAP_Interpret
*
* DESCRIPTION
*
* This function processes the incoming CHAP packet. This envolves
* responding to an authentication request and informing the upper layer
* if CHAP has succeed or failed.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the incoming CHAP
* packet
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID PPP_CHAP_Interpret (NET_BUFFER *buf_ptr)
{
STATUS status;
LCP_LAYER *lcp;
IPCP_LAYER *ipcp;
AUTHENTICATION_LAYER *auth;
#ifdef NU_DEBUG_PPP
_PRINT ("\nchap interpret\r\n");
#endif
/* Get a pointer to the LCP structure. */
lcp = &(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)->lcp);
/* We must be in the opened state in order to authenticate */
if (lcp->state == OPENED)
{
/* Get a pointer to the authentication structure. */
ipcp = &(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)->ipcp);
/* Get a pointer to the authentication structure. */
auth = &(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)->authentication);
switch (*buf_ptr->data_ptr)
{
case CHAP_CHALLENGE :
#ifdef NU_DEBUG_PPP
_PRINT ("challenge\r\n");
#endif
/* We will only except a challenge if we are a client */
if (ipcp->mode == NCP_CLIENT)
{
CHAP_Respond_To_Challenge(buf_ptr);
}
break;
case CHAP_RESPONSE :
#ifdef NU_DEBUG_PPP
_PRINT ("response\r\n");
#endif
/* We only accept a response if we are in server mode and
if the IDs of the challenge and response match */
if ((ipcp->mode == NCP_SERVER) &&
(auth->chap.challenge_identifier == buf_ptr->data_ptr[LCP_ID_OFFSET]))
{
/* We must check the response to see if it is valid. */
status = CHAP_Check_Response (buf_ptr);
/* See if the client was successful at logging in. */
if (status == NU_TRUE)
{
/* Tell the client that it passed logging in. */
CHAP_Send_Success(buf_ptr);
NU_Set_Events (&(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)
->negotiation_progression), AUTHENTICATION_SUCCESS, NU_OR);
}
else
{
/* Stop the echo timer since we are leaving the open state */
NU_Control_Timer (&lcp->echo_timer, NU_DISABLE_TIMER);
/* The client failed the authentication. Let it
know. */
CHAP_Send_Failure(buf_ptr);
NU_Set_Events (&(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)
->negotiation_progression), LCP_CONFIG_FAIL, NU_OR);
}
}
break;
case CHAP_SUCCESS :
#ifdef NU_DEBUG_PPP
_PRINT ("success\r\n");
#endif
/* We have received a positive response from the server.
If NCP is in need of negotiation let it know, otherwise
CHAP is done. */
if (ipcp->state != OPENED)
NU_Set_Events (&(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)
->negotiation_progression), AUTHENTICATION_SUCCESS, NU_OR);
break;
case CHAP_FAILURE :
#ifdef NU_DEBUG_PPP
_PRINT ("failure\r\n");
#endif
/* Stop the echo timer since we are leaving the open state */
NU_Control_Timer (&lcp->echo_timer, NU_DISABLE_TIMER);
/* We have received a negative response from the server,
let the upper layer know. */
NU_Set_Events (&(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)
->negotiation_progression), LCP_CONFIG_FAIL, NU_OR);
break;
} /* switch */
} /* if */
/* Release the buffer space */
MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
}
/***************************************************************************
* FUNCTION
*
* CHAP_MD5_Encrypt
*
* DESCRIPTION
*
* This function encrypts a string using MD5 encryption.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* CHAR string Pointer to the string to encrypt
* CHAR digest Pointer to the area in which to
* return the encrypted string
* UINT16 len Length of the string to encrypt
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_MD5_Encrypt (UINT8 *string, UINT8 *digest, UINT16 len)
{
MD5_CTX context;
MD5Init (&context);
MD5Update (&context, string, (unsigned int)len);
MD5Final (digest, &context);
}
/***************************************************************************
* FUNCTION
*
* CHAP_Timer_Expire
*
* DESCRIPTION
*
* This function handles the authentication timer expiration. If the
* authentication challenge has not been sent more than
* LCP_MAX_AUTHENTICATE times then it will get sent again.
* Otherwise we will consider that the authentication failed.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* UNSIGNED dev_ptr Address of the device structure
* for the device that the timer
* is expiring.
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_Timer_Expire (UNSIGNED dev_ptr)
{
DV_DEVICE_ENTRY *device;
AUTHENTICATION_LAYER *auth;
#ifdef NU_DEBUG_PPP
_PRINT ("\nchap timer expire\r\n");
#endif
/* Point to the device that RX this packet. */
device = (DV_DEVICE_ENTRY *)dev_ptr;
/* Point to the authentication structure. */
auth = &(((LINK_LAYER *)device->link_layer)->authentication);
/* See if we have waited long enough for a reply. */
if (!(auth->num_timeouts-- > 0))
{
/* Since we have not received a response yet we will assume
that the authentication failed. */
/* Stop the echo timer since we are leaving the open state */
NU_Control_Timer (&(((LINK_LAYER *)device->link_layer)->lcp.echo_timer), NU_DISABLE_TIMER);
NU_Set_Events (&(((LINK_LAYER *)device->link_layer)->negotiation_progression),
LCP_CONFIG_FAIL, NU_OR);
}
else
{
#ifdef NU_DEBUG_PPP
_PRINT ("send response again\r\n");
#endif
if (((LINK_LAYER *)device->link_layer)->ipcp.mode == NCP_CLIENT)
{
/* Otherwise set the event that will send the response again. Only
bother the system with this event if there is a response packet
to resend. */
if (auth->negotiation_pkt != NU_NULL)
UTL_Timerset (CHAP_RESEND, dev_ptr, 0, 0);
}
else
{
/* Set the event that will send a challenge again */
UTL_Timerset (CHAP_CHALL, dev_ptr, 0, 0);
}
}
}
/***************************************************************************
* FUNCTION
*
* CHAP_Send_Challenge
*
* DESCRIPTION
*
* Sends a challenge request to the client that is trying to log into
* the system.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* DV_DEVICE_ENTRY *dev_ptr Pointer to the device to send the
* challenge to
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_Send_Challenge (DV_DEVICE_ENTRY *dev_ptr)
{
AUTHENTICATION_LAYER *auth;
NET_BUFFER *buf_ptr;
LCP_HEADER *lcp_pkt;
UINT8 HUGE *lcp_pkt_ptr;
UINT16 len;
#ifdef NU_DEBUG_PPP
_PRINT ("\nchap send challenge\r\n");
#endif
/* Allocate a buffer to send. */
buf_ptr = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
/* Make sure a buffer was available */
if (buf_ptr == NU_NULL)
{
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
/* Get out */
return;
}
/* Get a pointer to the authentication structure. */
auth = &((LINK_LAYER *)dev_ptr->link_layer)->authentication;
/* Set the data pointer and the reject packet pointer. */
buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + dev_ptr->dev_hdrlen);
lcp_pkt = (LCP_HEADER *) buf_ptr->data_ptr;
/* Get a pointer to the data part of the pkt. */
lcp_pkt_ptr = (UINT8 *)&lcp_pkt->data;
/* Init the length */
len = 0;
/* Lets create a challenge pkt. */
lcp_pkt->code = CHAP_CHALLENGE;
/* Fill in the ID */
auth->chap.challenge_identifier = LCP_Random_Number();
lcp_pkt->identifier = auth->chap.challenge_identifier;
/* Put in the value size. Ours will be 4 bytes */
lcp_pkt_ptr [len++] = CHAP_CHALLENGE_VALUE_SIZE;
/* Get a random value for the challenge value. */
auth->chap.challenge_value = LCP_Random_Number32();
/* Put the challenge value in the pkt */
PUT32 (lcp_pkt_ptr, (unsigned int)len, auth->chap.challenge_value);
/* Bump the length to account for the challenge value. */
len += CHAP_CHALLENGE_VALUE_SIZE;
/* Add the system name */
if ((NU_Get_Host_Name ((CHAR *)&lcp_pkt_ptr[len], MAX_HOST_NAME_LENGTH)) == NU_SUCCESS)
{
len += strlen((CHAR *)&lcp_pkt_ptr[len]);
}
else
{
/* The name was unavailable so just add something. */
lcp_pkt_ptr[len++] = 'A';
lcp_pkt_ptr[len++] = 'T';
lcp_pkt_ptr[len++] = 'I';
}
/* Add on the LCP header to the length and
put it in the pkt. */
len += LCP_HEADER_LENGTH;
lcp_pkt->length = INTSWAP (len);
/* Set the lengths for the packet buffer. */
buf_ptr->data_len = buf_ptr->mem_total_data_len = len;
/* Set the packet type. */
buf_ptr->mem_flags = NET_CHAP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -