📄 pppchap.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/ppp/pppchap.c *//* Release: 2001.3 *//* Version: 2001.0 *//* Purpose: Challenge Handshake Authentication Protocol (CHAP) *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2001, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "pppp.h"#include <string.h>#include <stdlib.h>#include "md5.h"#if MAX_PPP_INTF/***********************************************************************//* Configuration *//***********************************************************************/#define CHAP_REQ_LIMIT 10 /* max REQ sends */#define CHAP_NAK_LIMIT 5 /* max NAK sends */#define CHAP_TIMEOUT 3 /* seconds to wait for response *//***********************************************************************//* Symbol Definitions *//***********************************************************************/#define CHALLENGE CONFIG_REQ#define RESPONSE CONFIG_ACK#define SUCCESS CONFIG_NAK#define FAILURE CONFIG_REJ/***********************************************************************//* Constant Data Definitions *//***********************************************************************/static const struct fsm_constants chap_constants ={ "CHAP", PPP_CHAP_PROTO, 0x000E, /* codes 1-3 recognized */ kCHAP, CHAP_REQ_LIMIT, CHAP_NAK_LIMIT, 0, CHAP_TIMEOUT * TICKS_PER_SEC, PppFsmNoAction, /* starting */ PppFsmNoAction, /* up */ PppFsmNoAction, /* down */ PppFsmNoAction, /* finished */ NULL, /* makereq */ PppFsmNoCheck, /* request */ PppFsmNoCheck, /* ack */ PppFsmNoCheck, /* nak */ PppFsmNoCheck, /* reject */};/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* prep_response: Prepare response to CHAP challenge *//* *//* Inputs: fsm = pointer to CHAP FSM *//* id = identifier from challenge packet *//* chal = pointer to buffer containing challenge *//* *//* Returns: 0 if successful, else -1 *//* *//***********************************************************************/static int prep_response(FSM *fsm, ui8 id, NetBuf *chal){ MD5_CTX context; /*-------------------------------------------------------------------*/ /* Ensure packet holds value and value-size. */ /*-------------------------------------------------------------------*/ if ((chal->length < 1) || (chal->length < chal->ip_pkt[0] + 1)) {#if PPP_TRACE pppFsmLog(fsm, "short authentication packet");#endif return -1; } /*-------------------------------------------------------------------*/ /* Remember identifier of most recent response. */ /*-------------------------------------------------------------------*/ Ppp->last_response = id; /*-------------------------------------------------------------------*/ /* Calculate MD5 hash value and copy to PPP control block. */ /*-------------------------------------------------------------------*/ MD5Init(&context); MD5Update(&context, &id, 1); MD5Update(&context, (ui8 *)Ppp->public.password, strlen(Ppp->public.password)); MD5Update(&context, &chal->ip_pkt[1], chal->ip_pkt[0]); MD5Final(Ppp->response_hash, &context); /*-------------------------------------------------------------------*/ /* Schedule resend in case message or reply is lost. */ /*-------------------------------------------------------------------*/ NetTimerStart(&fsm->timer, fsm->pdc->timeout); /*-------------------------------------------------------------------*/ /* Flag that response has been prepared and return success. */ /*-------------------------------------------------------------------*/ Ppp->public.flags |= PPPF_CHAP_RESPONDED; return 0;}/***********************************************************************//* send_response: Send prepared response to CHAP challenge *//* *//* Inputs: fsm = pointer to CHAP FSM *//* *//***********************************************************************/static void send_response(FSM *fsm){ int ulen; NetBuf *buf; ui8 *cp; /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return if unable. */ /*-------------------------------------------------------------------*/ ulen = strlen(Ppp->public.username); buf = tcpGetBuf(NIMHLEN + CONFIG_HDR_LEN + 1 + 16 + ulen + CRC16_LEN); if (buf == NULL) return; cp = buf->ip_pkt; /*-------------------------------------------------------------------*/ /* Write size of MD5 response to buffer. */ /*-------------------------------------------------------------------*/ *cp++ = (ui8)16; /*-------------------------------------------------------------------*/ /* Copy hash response and user name to buffer. */ /*-------------------------------------------------------------------*/ memcpy(cp, Ppp->response_hash, 16); memcpy(cp + 16, Ppp->public.username, ulen); /*-------------------------------------------------------------------*/ /* Assign buffer length and send buffer. */ /*-------------------------------------------------------------------*/ buf->length = 1 + 16 + ulen; pppFsmSend(fsm, RESPONSE, Ppp->last_response, buf);}/***********************************************************************//* send_challenge: Send CHAP challenge *//* *//***********************************************************************/static void send_challenge(FSM *fsm){ int ulen, i; NetBuf *buf; ui8 *cp; /*-------------------------------------------------------------------*/ /* Schedule resend in case no response is received. */ /*-------------------------------------------------------------------*/ NetTimerStart(&fsm->timer, fsm->pdc->timeout); /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return if unable. */ /*-------------------------------------------------------------------*/ ulen = strlen(Ppp->public.username); buf = tcpGetBuf(NIMHLEN + CONFIG_HDR_LEN + 1 + 16 + ulen + CRC16_LEN); if (buf == NULL) return; cp = buf->ip_pkt; /*-------------------------------------------------------------------*/ /* Write size of MD5 challenge to buffer. */ /*-------------------------------------------------------------------*/ *cp++ = (ui8)16; /*-------------------------------------------------------------------*/ /* Generate "random" challenge value and copy to PPP control block. */ /*-------------------------------------------------------------------*/ for (i = 0; i < 16;) Ppp->challenge_val[i++] = rand(); /*-------------------------------------------------------------------*/ /* Copy challenge value and user name to buffer. */ /*-------------------------------------------------------------------*/ memcpy(cp, Ppp->challenge_val, 16); memcpy(cp + 16, Ppp->public.username, ulen); /*-------------------------------------------------------------------*/ /* Assign buffer length and send challenge. */ /*-------------------------------------------------------------------*/ buf->length = 1 + 16 + ulen; pppFsmSend(fsm, CHALLENGE, 0, buf);}/***********************************************************************//* check_response: Check peer's response *//* *//* Returns: 0 iff response is good *//* *//***********************************************************************/static int check_response(FSM *fsm, ConfigHdr *hdr, NetBuf *buf){ ui8 *cp; MD5_CTX context; char *password; ui8 comparison[16]; /*-------------------------------------------------------------------*/ /* Check embedded value length and header length. */ /*-------------------------------------------------------------------*/ if ((pppRcvBuf->ip_pkt[0] != 16) || (hdr->len < 18)) {#if PPP_TRACE pppLog("CHAP: ill-formed response");#endif return -1; } /*-------------------------------------------------------------------*/ /* Point to, and NULL terminate, the user name. */ /*-------------------------------------------------------------------*/ cp = &pppRcvBuf->ip_pkt[17]; cp[hdr->len - 17] = 0; /*-------------------------------------------------------------------*/ /* Find password for this user, returning error if unable. */ /*-------------------------------------------------------------------*/ password = SysPassword(cp); if (password == NULL) return -1; /*-------------------------------------------------------------------*/ /* Calculate MD5 hash value for comparison with response value. */ /*-------------------------------------------------------------------*/ MD5Init(&context); MD5Update(&context, &fsm->lastid, 1); MD5Update(&context, (ui8 *)password, strlen(password)); MD5Update(&context, Ppp->challenge_val, 16); MD5Final(comparison, &context); /*-------------------------------------------------------------------*/ /* Return 0 iff returned hash equals expected value. */ /*-------------------------------------------------------------------*/ return memcmp(comparison, &pppRcvBuf->ip_pkt[1], 16);}/***********************************************************************//* send_success: Send CHAP authentication success message *//* *//* Inputs: fsm = pointer to CHAP FSM *//* id = identifier from response packet *//* *//***********************************************************************/static void send_success(FSM *fsm, int id){ NetBuf *buf; /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return if unable. */ /*-------------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + CONFIG_HDR_LEN + CRC16_LEN); if (buf == NULL) return; /*-------------------------------------------------------------------*/ /* Assign message code and identifier, and send buffer. */ /*-------------------------------------------------------------------*/ pppFsmSend(fsm, SUCCESS, id, buf);}/***********************************************************************//* send_failure: Send CHAP authentication failure message *//* *//* Inputs: fsm = pointer to CHAP FSM *//* id = identifier from response packet *//* *//***********************************************************************/static void send_failure(FSM *fsm, int id){ NetBuf *buf; /*-------------------------------------------------------------------*/ /* Attempt to allocate buffer. Return if unable. */ /*-------------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + CONFIG_HDR_LEN + CRC16_LEN); if (buf == NULL) return; /*-------------------------------------------------------------------*/ /* Assign message code and identifier, and send buffer. */ /*-------------------------------------------------------------------*/ pppFsmSend(fsm, FAILURE, id, buf);}/***********************************************************************//* chap_shutdown: Abandon CHAP attempt, shutdown LCP layer *//* *//***********************************************************************/static void chap_shutdown(FSM *fsm){#if PPP_TRACE pppFsmLog(fsm, "Failed; close connection");#endif fsm->state = fsmCLOSED; fsmLcpClose();}/***********************************************************************//* chap_up: CHAP authentication complete *//* *//***********************************************************************/static void chap_up(FSM *fsm){#if PPP_TRACE pppFsmLog(fsm, "Open");#endif NetTimerStop(&fsm->timer); Ppp->public.flags &= ~(PPPF_CHAP_LOCAL | PPPF_CHAP_REMOTE); fsm->state = fsmOPENED; pppReady();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -