📄 chap.c
字号:
/* Set the dlist for this buffer. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the pkt. */
dev_ptr->dev_output (buf_ptr, dev_ptr, NU_NULL, NU_NULL);
}
/***************************************************************************
* FUNCTION
*
* CHAP_Respond_To_Challenge
*
* DESCRIPTION
*
* This function responds to a challenge received from the server that
* is authenticating. It will encrypt the user password using MD5
* encryption
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the incoming CHAP
* packet
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_Respond_To_Challenge (NET_BUFFER *in_buf_ptr)
{
AUTHENTICATION_LAYER *auth;
NET_BUFFER *buf_ptr;
LCP_HEADER *lcp_pkt;
UINT8 HUGE *lcp_pkt_ptr, *secret;
UINT8 x, pw_id_len, value_len;
UINT16 len;
UINT8 HUGE *chap_pkt = in_buf_ptr->data_ptr;
UINT16 index;
/* Get a pointer to the authentication structure. */
auth = &(((LINK_LAYER *)in_buf_ptr->mem_buf_device->link_layer)->authentication);
/* Is there a negotiation packet that can be reused? */
if (auth->negotiation_pkt != NU_NULL)
buf_ptr = auth->negotiation_pkt;
else
/* Allocate a buffer for the CHAP packet. */
auth->negotiation_pkt = 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;
}
/* Allocate memory for the secret. This can be as long as
256 bytes + PPP_MAX_PW_LENGTH */
if ( (NU_Allocate_Memory(&System_Memory, (VOID **)&secret,
(CHAP_MAX_VALUE_SIZE + PPP_MAX_PW_LENGTH),
NU_NO_SUSPEND)) != NU_SUCCESS)
{
NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
/* Get out */
return;
}
/* Set the data pointer and the reject packet pointer. */
buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->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;
/* Lets create a response pkt with our login and PW. */
lcp_pkt->code = CHAP_RESPONSE;
/* The ID is the same as the ID of the challenge pkt. */
lcp_pkt->identifier = chap_pkt[LCP_ID_OFFSET];
index = 0;
len = 0;
/* Put in the value size. For MD5 it is 16 */
lcp_pkt_ptr [len++] = CHAP_MD5_VALUE_SIZE;
/* Build the string that we will encrypt, this consists of
the PW, the ID, and a value supplied by the
authenticator. */
secret [index++] = lcp_pkt->identifier;
/* Get the length of the PW to try */
pw_id_len = (UINT8) strlen (auth->login_pw);
/* Copy the PW over. */
for (x = 0; x < pw_id_len; x++)
secret [index++] = auth->login_pw [x];
/* Get the length of the value. */
value_len = chap_pkt [CHAP_VALUE_LENGTH_OFFSET];
/* Copy it over. */
for (x = 0; x < value_len; x++)
secret [index++] = chap_pkt [CHAP_VALUE_OFFSET + x];
/* Encrypt it. */
CHAP_MD5_Encrypt (secret, (UINT8 *)&lcp_pkt_ptr[len], index);
/* Update the length */
len += CHAP_MD5_VALUE_SIZE;
/* Get the length of the ID to try */
pw_id_len = (UINT8) strlen (auth->login_name);
/* Copy the login name into the pkt. */
for (x = 0; x < pw_id_len; x++, len++)
lcp_pkt_ptr[len] = auth->login_name[x];
/* Add on the LCP header to the length and
put it in the pkt. */
len += LCP_HEADER_LENGTH;
lcp_pkt->length = INTSWAP (len);
/* Reset the restart timer */
NU_Control_Timer (&auth->authentication_timer, NU_DISABLE_TIMER);
/* 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;
/* Set the dlist to NULL so this buffer will not be
put on the free list. */
buf_ptr->mem_dlist = NU_NULL;
/* Send the pkt. */
in_buf_ptr->mem_buf_device->dev_output (buf_ptr,
in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
/* Start the retransmission timer for it. */
NU_Reset_Timer (&auth->authentication_timer, CHAP_Timer_Expire,
LCP_TIMEOUT_VALUE, LCP_TIMEOUT_VALUE, NU_ENABLE_TIMER);
/* Done with the memory for the secret so give it back. */
if ( (NU_Deallocate_Memory (secret)) != NU_SUCCESS)
NERRS_Log_Error (NERR_SEVERE, __FILE__, __LINE__);
} /* end CHAP_Respond_To_Challenge */
/***************************************************************************
* FUNCTION
*
* CHAP_Check_Response
*
* DESCRIPTION
*
* Checks the ID and encrypted PW against what the encrypted PW should be.
* The correct encypted PW is computed from the password list.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* NET_BUFFER *buf_ptr Pointer to the incoming CHAP
* packet
*
* OUTPUTS
*
* STATUS Was the response correct
*
****************************************************************************/
STATUS CHAP_Check_Response (NET_BUFFER *buf_ptr)
{
AUTHENTICATION_LAYER *auth;
UINT16 name_length;
UINT8 client_secret[CHAP_MD5_VALUE_SIZE],
our_encrypt_secret[CHAP_MD5_VALUE_SIZE];
CHAR client_name[PPP_MAX_ID_LENGTH];
UINT8 x, pw_index, found_it, wrong_pw;
UINT8 secret[PPP_MAX_PW_LENGTH + (CHAP_MD5_VALUE_SIZE * 2)];
UINT8 HUGE *chap_pkt = buf_ptr->data_ptr;
UINT16 index;
/* Init */
found_it = NU_FALSE;
/* The size of the value must be correct for MD5 encryption. */
if (CHAP_MD5_VALUE_SIZE == chap_pkt[CHAP_VALUE_LENGTH_OFFSET])
{
/* Get a pointer to the authentication structure. */
auth = &(((LINK_LAYER *)buf_ptr->mem_buf_device->link_layer)->authentication);
/* copy out the secret value */
for (x = 0; x < CHAP_MD5_VALUE_SIZE; x++)
client_secret [x] = chap_pkt [CHAP_VALUE_OFFSET + x];
/* Copy out the name of the client. To get its length we must get
the total length of the pkt and compute what is left. */
name_length = (UINT16) ( ( *(chap_pkt + LCP_LENGTH_OFFSET) ) << 8 );
name_length = (name_length | *(chap_pkt + LCP_LENGTH_OFFSET + 1));
/* Now take off the header, value size, and value fields. Note
that the value size field is only 1 byte, that is the 1 that
is added below. */
name_length -= (LCP_HEADER_LENGTH + CHAP_MD5_VALUE_SIZE + 1);
/* Copy out the name */
for (x = 0; (x < name_length) && (x < PPP_MAX_ID_LENGTH); x++)
client_name [x] = chap_pkt [CHAP_VALUE_OFFSET +
CHAP_MD5_VALUE_SIZE + x];
/* Null it */
client_name [x] = 0;
/* Loop through the password list to find this client. */
for (x = 0, found_it = NU_FALSE, wrong_pw = NU_FALSE;
(_passwordlist[x].id[0] != 0) && (found_it == NU_FALSE) &&
(wrong_pw == NU_FALSE); x++)
{
/* If the IDs match, then we must compute what the encrypted
PW should be. */
if ((strcmp (client_name, _passwordlist[x].id)) == 0)
{
index = 0;
/* First is the pkt ID */
secret [index++] = auth->chap.challenge_identifier;
/* Now copy in the password */
for (pw_index = 0; pw_index < strlen (_passwordlist[x].pw);
pw_index++)
secret [index++] = _passwordlist[x].pw[pw_index];
/* Lastly put in the challenge value. */
PUT32 (secret, (unsigned int)index, auth->chap.challenge_value);
/* Bump the length to account for the challenge value. */
index += CHAP_CHALLENGE_VALUE_SIZE;
/* Compute the expected encrypted password */
CHAP_MD5_Encrypt (secret, (UINT8 *) our_encrypt_secret, index);
/* Compare the two encrypted secrets. They must be the same
for a successful login. */
if (memcmp (our_encrypt_secret, client_secret,
CHAP_MD5_VALUE_SIZE) == 0)
found_it = NU_TRUE;
else
wrong_pw = NU_TRUE;
}
}
}
return (found_it);
}
/***************************************************************************
* FUNCTION
*
* CHAP_Send_Success
*
* DESCRIPTION
*
* Sends a CHAP success packet, telling the CLIENT that it has logged in.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* NET_BUFFER *in_buf_ptr Pointer to the incoming CHAP
* packet
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_Send_Success (NET_BUFFER *in_buf_ptr)
{
NET_BUFFER *buf_ptr;
LCP_HEADER HUGE *lcp_pkt;
UINT16 len;
UINT8 HUGE *chap_pkt = in_buf_ptr->data_ptr;
#ifdef NU_DEBUG_PPP
_PRINT (" send success");
#endif
/* Allocate a buffer for the PAP packet. */
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;
}
/* Set the data ptr */
buf_ptr->data_ptr = buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen;
lcp_pkt = (LCP_HEADER *) buf_ptr->data_ptr;
/* Fill in the pkt */
lcp_pkt->code = CHAP_SUCCESS;
/* The ID comes from the response pkt */
lcp_pkt->identifier = chap_pkt [LCP_ID_OFFSET];
/* Since there is no data in the pkt the size is just that of the
header. */
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;
/* Set the dlist for this buffer. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the pkt. */
in_buf_ptr->mem_buf_device->dev_output (buf_ptr,
in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
/***************************************************************************
* FUNCTION
*
* CHAP_Send_Failure
*
* DESCRIPTION
*
* Sends a CHAP failure packet, telling the CLIENT that either the ID or
* PW was wrong and that it can not login.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* NET_BUFFER *in_buf_ptr Pointer to the incoming CHAP
* packet
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID CHAP_Send_Failure (NET_BUFFER *in_buf_ptr)
{
NET_BUFFER *buf_ptr;
LCP_HEADER *lcp_pkt;
UINT16 len;
UINT8 HUGE *chap_pkt = in_buf_ptr->data_ptr;
#ifdef NU_DEBUG_PPP
_PRINT (" send failure");
#endif
/* Allocate a buffer for the PAP packet. */
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;
}
/* Set the data ptr */
buf_ptr->data_ptr = buf_ptr->mem_parent_packet + in_buf_ptr->mem_buf_device->dev_hdrlen;
lcp_pkt = (LCP_HEADER *) buf_ptr->data_ptr;
/* Fill in the pkt */
lcp_pkt->code = CHAP_FAILURE;
/* The ID comes from the response pkt */
lcp_pkt->identifier = chap_pkt [LCP_ID_OFFSET];
/* Since there is no data in the pkt the size is just that of the
header. */
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;
/* Set the dlist for this buffer. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
/* Send the pkt. */
in_buf_ptr->mem_buf_device->dev_output (buf_ptr,
in_buf_ptr->mem_buf_device, NU_NULL, NU_NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -