⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap.c

📁 PPP协议C语言源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* 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 + -