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

📄 netchap.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/

/*****************************************************************************

* netchap.c - Network Challenge Handshake Authentication Protocol program file.

*

* portions Copyright (c) 1997 by Global Election Systems Inc.

*

* The authors hereby grant permission to use, copy, modify, distribute,

* and license this software and its documentation for any purpose, provided

* that existing copyright notices are retained in all copies and that this

* notice and the following disclaimer are included verbatim in any 

* distributions. No written agreement, license, or royalty fee is required

* for any of the authorized uses.

*

* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 

* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF

* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*

******************************************************************************

* REVISION HISTORY

*

* 97-12-04 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.

*	Original based on BSD chap.c.

*****************************************************************************/

/*

 * chap.c - Challenge Handshake Authentication Protocol.

 *

 * Copyright (c) 1993 The Australian National University.

 * 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 the Australian National University.  The name of the University

 * may not be used to endorse or promote products derived from this

 * software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR

 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED

 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

 *

 * 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.

 *

 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR

 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED

 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

 */



#include "netconf.h"

#include "net.h"

#include "netbuf.h"



#if CHAP_SUPPORT > 0



#include <string.h>

#include "nettimer.h"



#include "netppp.h"

#include "netrand.h"

#include "netauth.h"

#include "netmd5.h"

#include "netchap.h"

#include "netchpms.h"



#include <stdio.h>

#include "netdebug.h"





/*************************/

/*** LOCAL DEFINITIONS ***/

/*************************/





/************************/

/*** LOCAL DATA TYPES ***/

/************************/





/***********************************/

/*** LOCAL FUNCTION DECLARATIONS ***/

/***********************************/

/*

 * Protocol entry points.

 */

static void ChapInit __P((int));

static void ChapLowerUp __P((int));

static void ChapLowerDown __P((int));

static void ChapInput __P((int, u_char *, int));

static void ChapProtocolReject __P((int));

static int  ChapPrintPkt __P((u_char *, int,

			      void (*) __P((void *, char *, ...)), void *));



static void ChapChallengeTimeout __P((void *));

static void ChapResponseTimeout __P((void *));

static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));

static void ChapRechallenge __P((void *));

static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));

static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);

static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);

static void ChapSendStatus __P((chap_state *, int));

static void ChapSendChallenge __P((chap_state *));

static void ChapSendResponse __P((chap_state *));

static void ChapGenChallenge __P((chap_state *));





/******************************/

/*** PUBLIC DATA STRUCTURES ***/

/******************************/

chap_state chap[NUM_PPP];		/* CHAP state; one for each unit */



struct protent chap_protent = {

    PPP_CHAP,

    ChapInit,

    ChapInput,

    ChapProtocolReject,

    ChapLowerUp,

    ChapLowerDown,

    NULL,

    NULL,

    ChapPrintPkt,

    NULL,

    1,

    "CHAP",

    NULL,

    NULL,

    NULL

};







/*****************************/

/*** LOCAL DATA STRUCTURES ***/

/*****************************/

static char *ChapCodenames[] = {

	"Challenge", "Response", "Success", "Failure"

};







/***********************************/

/*** PUBLIC FUNCTION DEFINITIONS ***/

/***********************************/

/*

 * ChapAuthWithPeer - Authenticate us with our peer (start client).

 *

 */

void ChapAuthWithPeer(int unit, char *our_name, int digest)

{

	chap_state *cstate = &chap[unit];

	

	cstate->resp_name = our_name;

	cstate->resp_type = digest;

	

	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.

	 * So even if CHAP was open before, we will 

	 * have to re-authenticate ourselves.

	 */

	cstate->clientstate = CHAPCS_LISTEN;

}





/*

 * ChapAuthPeer - Authenticate our peer (start server).

 */

void ChapAuthPeer(int unit, char *our_name, int digest)

{

	chap_state *cstate = &chap[unit];

	

	cstate->chal_name = our_name;

	cstate->chal_type = digest;

	

	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;

}









/**********************************/

/*** LOCAL FUNCTION DEFINITIONS ***/

/**********************************/

/*

 * ChapInit - Initialize a CHAP unit.

 */

static void ChapInit(int unit)

{

	chap_state *cstate = &chap[unit];

	

	BZERO(cstate, sizeof(*cstate));

	cstate->unit = unit;

	cstate->clientstate = CHAPCS_INITIAL;

	cstate->serverstate = CHAPSS_INITIAL;

	cstate->timeouttime = CHAP_DEFTIMEOUT;

	cstate->max_transmits = CHAP_DEFTRANSMITS;

	/* random number generator is initialized in magic_init */

}





/*

 * ChapChallengeTimeout - Timeout expired on sending challenge.

 */

static void ChapChallengeTimeout(void *arg)

{

	chap_state *cstate = (chap_state *) 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)

		return;

	

	if (cstate->chal_transmits >= cstate->max_transmits) {

		/* give up on peer */

		trace(LOG_ERR, "Peer failed to respond to CHAP challenge");

		cstate->serverstate = CHAPSS_BADAUTH;

		auth_peer_fail(cstate->unit, PPP_CHAP);

		return;

	}

	

	ChapSendChallenge(cstate);		/* Re-send challenge */

}





/*

 * ChapResponseTimeout - Timeout expired on sending response.

 */

static void ChapResponseTimeout(void *arg)

{

	chap_state *cstate = (chap_state *) arg;

	

	/* if we aren't sending a response, don't worry. */

	if (cstate->clientstate != CHAPCS_RESPONSE)

		return;

	

	ChapSendResponse(cstate);		/* re-send response */

}





/*

 * ChapRechallenge - Time to challenge the peer again.

 */

static void ChapRechallenge(void *arg)

{

	chap_state *cstate = (chap_state *) 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;

}





/*

 * ChapLowerUp - The lower layer is up.

 *

 * Start up if we have pending requests.

 */

static void ChapLowerUp(int unit)

{

	chap_state *cstate = &chap[unit];

	

	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;

	}

}





/*

 * ChapLowerDown - The lower layer is down.

 *

 * Cancel all timeouts.

 */

static void ChapLowerDown(int unit)

{

	chap_state *cstate = &chap[unit];

	

	/* Timeout(s) pending?  Cancel if so. */

	if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||

			cstate->serverstate == CHAPSS_RECHALLENGE)

		UNTIMEOUT(ChapChallengeTimeout, cstate);

	else if (cstate->serverstate == CHAPSS_OPEN

			&& cstate->chal_interval != 0)

		UNTIMEOUT(ChapRechallenge, cstate);

	if (cstate->clientstate == CHAPCS_RESPONSE)

		UNTIMEOUT(ChapResponseTimeout, cstate);

	

	cstate->clientstate = CHAPCS_INITIAL;

	cstate->serverstate = CHAPSS_INITIAL;

}





/*

 * ChapProtocolReject - Peer doesn't grok CHAP.

 */

static void ChapProtocolReject(int unit)

{

	chap_state *cstate = &chap[unit];

	

	if (cstate->serverstate != CHAPSS_INITIAL &&

			cstate->serverstate != CHAPSS_CLOSED)

		auth_peer_fail(unit, PPP_CHAP);

	if (cstate->clientstate != CHAPCS_INITIAL &&

			cstate->clientstate != CHAPCS_CLOSED)

		auth_withpeer_fail(unit, PPP_CHAP);

	ChapLowerDown(unit);		/* shutdown chap */

}





/*

 * ChapInput - Input CHAP packet.

 */

static void ChapInput(int unit, u_char *inpacket, int packet_len)

{

	chap_state *cstate = &chap[unit];

	u_char *inp;

	u_char code, id;

	int len;

	

	/*

	 * Parse header (code, id and length).

	 * If packet too short, drop it.

	 */

	inp = inpacket;

	if (packet_len < CHAP_HEADERLEN) {

		CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header."));

		return;

	}

	GETCHAR(code, inp);

	GETCHAR(id, inp);

	GETSHORT(len, inp);

	if (len < CHAP_HEADERLEN) {

		CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length."));

		return;

	}

	if (len > packet_len) {

		CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet."));

		return;

	}

	len -= CHAP_HEADERLEN;

	

	/*

	 * Action depends on code (as in fact it usually does :-).

	 */

	switch (code) {

	case CHAP_CHALLENGE:

		ChapReceiveChallenge(cstate, inp, id, len);

		break;

	

	case CHAP_RESPONSE:

		ChapReceiveResponse(cstate, inp, id, len);

		break;

	

	case CHAP_FAILURE:

		ChapReceiveFailure(cstate, inp, id, len);

		break;

	

	case CHAP_SUCCESS:

		ChapReceiveSuccess(cstate, inp, id, len);

		break;

	

	default:				/* Need code reject? */

		trace(LOG_WARNING, "Unknown CHAP code (%d) received.", code);

		break;

	}

}





/*

 * ChapReceiveChallenge - Receive Challenge and send Response.

 */

static void ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)

{

	int rchallenge_len;

	u_char *rchallenge;

	int secret_len;

	char secret[MAXSECRETLEN];

	char rhostname[256];

	MD5_CTX mdContext;

	u_char hash[MD5_SIGNATURE_SIZE];

	

	CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id));

	if (cstate->clientstate == CHAPCS_CLOSED ||

		cstate->clientstate == CHAPCS_PENDING) {

		CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d",

			   cstate->clientstate));

		return;

	}

	

	if (len < 2) {

		CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));

		return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -