📄 chap.c
字号:
/*
* FILENAME: chap.c
*
* Copyright 1997- 2001 By InterNiche Technologies Inc. All rights reserved
*
* Crytographic Handshake Authentication Protocol.
*
* MODULE: PPP
*
* ROUTINES: ChapInit(), ChapAuthWithPeer(), ChapAuthPeer(),
* ROUTINES: ChapChallengeTimeout(), ChapResponseTimeout(),
* ROUTINES: ChapRechallenge(), ChapLowerUp(), ChapLowerDown(),
* ROUTINES: ChapProtocolReject(), ChapInput(), ChapReceiveChallenge(),
* ROUTINES: ChapReceiveResponse(), ChapReceiveSuccess(),
* ROUTINES: ChapReceiveFailure(), ChapSendChallenge(), ChapSendStatus(),
* ROUTINES: ChapGenChallenge(), ChapSendResponse(), ChapPrintPkt(),
* ROUTINES: chap_stat(),
*
* PORTABLE: yes
*/
/* Additional Copyrights: */
/* Portions Copyright (C) ARM Limited 1998,1999. All rights reserved.
* Portions Copyright 1996 by NetPort Software.
* Portions Copyright (c) 1991 Gregory M. Christy. All rights
* reserved. Redistribution and use in source and binary forms are
* permitted provided that the above copyright notice and this
* paragraph are duplicated in all such forms and that any
* documentation, advertising materials, and other materials related
* to such distribution and use acknowledge that the software was
* developed by Gregory M. Christy. The name of the author may not be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*/
#include "ppp_port.h"
#ifdef CHAP_SUPPORT /* whole file can be ifdeffed out */
#include "mppp.h"
#include "md5.h"
#ifdef MSCHAP_SUPPORT
#include "mschap.h"
#endif
#define CHAPME_DEBUG 0
#if CHAPME_DEBUG > 0
#include "ZPrint.h"
#endif
/* Code + ID + (unshort)length = */
#define CHAP_HEADERLEN 4
/* number of seconds to wait for a challenge form the other guy before we
* get bored and move to IPCP. This can be overwritten by application code.
*/
int chap_delay = 5;
/* timer expirey routines */
static void ChapChallengeTimeout (M_PPP, long arg);
static void ChapResponseTimeout (M_PPP, long arg);
void ChapRechallenge(M_PPP, long arg);
/* internal routines */
static void ChapReceiveChallenge (chap_state *, u_char *, int, int);
static void ChapReceiveResponse (chap_state *, u_char *, int, int);
static void ChapReceiveSuccess (chap_state *, int,u_char*,int);
static void ChapReceiveFailure (chap_state *, u_char);
static void ChapSendStatus (chap_state *, int);
static void ChapSendChallenge (chap_state *);
static void ChapSendResponse (chap_state *);
static void ChapGenChallenge (chap_state *);
auth_funcs ChapAuthTable =
{
ChapInit,
ChapAuthWithPeer,
ChapAuthPeer,
ChapLowerUp,
ChapLowerDown,
ChapInput,
ChapProtocolReject,
};
/* FUNCTION: ChapInit()
*
* ChapInit - Initialize a CHAP unit.
*
*
* PARAM1: int unit
*
* RETURNS:
*/
void
ChapInit(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
MEMSET(cstate, 0, sizeof(*cstate));
cstate->mppp = mppp;
cstate->clientstate = CHAPCS_INITIAL;
cstate->serverstate = CHAPSS_INITIAL;
cstate->timeouttime = CHAP_DEFTIMEOUT;
cstate->max_transmits = CHAP_DEFTRANSMITS;
if (mppp->lcp_hisoptions.neg_chap)
cstate->resp_type = mppp->lcp_hisoptions.chap_mdtype;
else if ((mppp->lcp_gotoptions.neg_chap) &&
(mppp->pppflags & PPP_SERVER))
cstate->resp_type = mppp->lcp_gotoptions.chap_mdtype;
}
/* FUNCTION: ChapAuthWithPeer()
*
* ChapAuthWithPeer - Authenticate us with our peer (start client).
*
*
* PARAM1: int unit
* PARAM2: char * our_name
* PARAM3: int digest
*
* RETURNS:
*/
void
ChapAuthWithPeer(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
// ConPrintf("ChapAuthWithPeer: link:%lx, our_name:%s, digest(type):%d",
// mppp, mppp->username, cstate->resp_type);
cstate->resp_name = mppp->username;
if (cstate->clientstate == CHAPCS_INITIAL ||
cstate->clientstate == CHAPCS_PENDING)
{
/* lower layer isn't up - wait until later */
cstate->clientstate = CHAPCS_PENDING;
return;
}
/* We get here as a result of LCP coming up. Even if CHAP was open
* before, we will have to re-authenticate ourselves. Go into listen
* state and wait for the Challenge.
*/
cstate->clientstate = CHAPCS_LISTEN;
/* Some systems negotiate CHAP and then never send a challenge. to avoid
* getting stuck here forever, we set a long timer to kick off IPCP.
*/
ppp_settimer(mppp, ppp_fsm_tmo, chap_delay, IPCP_STATE);
return;
}
/* FUNCTION: ChapAuthPeer()
*
* ChapAuthPeer - Authenticate our peer (start server).
*
*
* PARAM1: M_PPP mppp
* PARAM2: char * our_name
* PARAM3: int digest
*
* RETURNS:
*/
void
ChapAuthPeer(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
cstate->chal_name = mppp->username;
cstate->chal_type = (u_char)CHAP_DIGEST_MD5;
if (cstate->serverstate == CHAPSS_INITIAL ||
cstate->serverstate == CHAPSS_PENDING)
{
/* lower layer isn't up - wait until later */
cstate->serverstate = CHAPSS_PENDING;
return;
}
ChapGenChallenge(cstate);
ChapSendChallenge(cstate); /* crank it up dude! */
cstate->serverstate = CHAPSS_INITIAL_CHAL;
}
/* FUNCTION: ChapChallengeTimeout()
*
* ChapChallengeTimeout - Timeout expired on sending challenge.
*
*
* PARAM1: void * arg
*
* RETURNS:
*/
static void
ChapChallengeTimeout(M_PPP mppp, long arg)
{
chap_state * cstate = &mppp->chap;
USE_ARG(arg);
/* if we aren't sending challenges, don't worry.
* then again we probably shouldn't be here
* either
*/
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
cstate->serverstate != CHAPSS_RECHALLENGE)
{
dtrap("chap 0\n");
return;
}
if (cstate->chal_transmits >= cstate->max_transmits)
{
/* give up on peer */
// ConPrintf("Peer failed to respond to CHAP challenge");
cstate->serverstate = CHAPSS_BADAUTH;
ppp_auth_failed(cstate->mppp, 1);
return;
}
ChapSendChallenge(cstate); /* Re-send challenge */
}
/* FUNCTION: ChapResponseTimeout()
*
* ChapResponseTimeout - Timeout expired on sending response.
*
* PARAM1: M_PPP mppp
*
* RETURNS:
*/
static void
ChapResponseTimeout(M_PPP mppp, long arg)
{
chap_state * cstate = &mppp->chap;
USE_ARG(arg);
/* if we aren't sending a response, don't worry. */
if (cstate->clientstate != CHAPCS_RESPONSE)
return;
ChapSendResponse(cstate); /* re-send response */
}
/* FUNCTION: ChapRechallenge()
*
* ChapRechallenge - Time to challenge the peer again.
*
*
* PARAM1: M_PPP
* PARAM1: void * arg
*
* RETURNS:
*/
void
ChapRechallenge(M_PPP mppp, long arg)
{
chap_state * cstate = &mppp->chap;
USE_ARG(arg);
/* if we aren't sending a response, don't worry. */
if (cstate->serverstate != CHAPSS_OPEN)
return;
ChapGenChallenge(cstate);
ChapSendChallenge(cstate);
cstate->serverstate = CHAPSS_RECHALLENGE;
}
/* FUNCTION: ChapLowerUp()
*
* ChapLowerUp - The lower layer is up.
* Start up if we have pending requests.
*
* PARAM1: M_PPP mppp
*
* RETURNS:
*/
void
ChapLowerUp(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
if (cstate->clientstate == CHAPCS_INITIAL)
cstate->clientstate = CHAPCS_CLOSED;
else if (cstate->clientstate == CHAPCS_PENDING)
cstate->clientstate = CHAPCS_LISTEN;
if (cstate->serverstate == CHAPSS_INITIAL)
cstate->serverstate = CHAPSS_CLOSED;
else if (cstate->serverstate == CHAPSS_PENDING)
{
ChapGenChallenge(cstate);
ChapSendChallenge(cstate);
cstate->serverstate = CHAPSS_INITIAL_CHAL;
}
}
/* FUNCTION: ChapLowerDown()
*
* ChapLowerDown - The lower layer is down.
* Cancel all timeouts.
*
* PARAM1: M_PPP mppp
*
* RETURNS:
*/
void
ChapLowerDown(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
/* Timeout(s) pending? Cancel if so. */
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
cstate->serverstate == CHAPSS_RECHALLENGE)
{
ppp_cleartimer(mppp);
}
else if (cstate->serverstate == CHAPSS_OPEN
&& cstate->chal_interval != 0)
{
ppp_cleartimer(mppp);
}
if (cstate->clientstate == CHAPCS_RESPONSE)
ppp_cleartimer(mppp);
cstate->clientstate = CHAPCS_INITIAL;
cstate->serverstate = CHAPSS_INITIAL;
}
/* FUNCTION: ChapProtocolReject()
*
* ChapProtocolReject - Peer doesn't grok CHAP.
*
*
* PARAM1: M_PPP mppp
*
* RETURNS:
*/
void
ChapProtocolReject(M_PPP mppp)
{
chap_state * cstate = &mppp->chap;
if (cstate->serverstate != CHAPSS_INITIAL &&
cstate->serverstate != CHAPSS_CLOSED)
{
ppp_auth_failed(mppp, 1);
}
if (cstate->clientstate != CHAPCS_INITIAL &&
cstate->clientstate != CHAPCS_CLOSED)
{
ppp_auth_failed(mppp, 0);
}
ChapLowerDown(mppp); /* shutdown chap */
}
/* FUNCTION: ChapInput()
*
* ChapInput - Input CHAP packet.
*
* PARAM1: M_PPP mppp
* PARAM2: u_char *inpacket
* PARAM3: int packet_len
*
* RETURNS:
*/
void
ChapInput(M_PPP mppp,
u_char * inpacket,
int packet_len)
{
chap_state * cstate = &mppp->chap;
u_char * inp;
u_char code, id;
int len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -