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

📄 chap.c

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