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

📄 netchap.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	

	GETCHAR(rchallenge_len, inp);

	len -= sizeof (u_char) + rchallenge_len;	/* now name field length */

	if (len < 0) {

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

		return;

	}

	rchallenge = inp;

	INCPTR(rchallenge_len, inp);

	

	if (len >= sizeof(rhostname))

		len = sizeof(rhostname) - 1;

	BCOPY(inp, rhostname, len);

	rhostname[len] = '\000';

	

	CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'",

	       rhostname));

	

	/* Microsoft doesn't send their name back in the PPP packet */

	if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) {

		strncpy(rhostname, remote_name, sizeof(rhostname));

		rhostname[sizeof(rhostname) - 1] = 0;

		CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name",

			   rhostname));

	}

	

	/* get secret for authenticating ourselves with the specified host */

	if (!get_secret(cstate->unit, cstate->resp_name, rhostname,

			    secret, &secret_len, 0)) {

		secret_len = 0;		/* assume null secret if can't find one */

		trace(LOG_WARNING, "No CHAP secret found for authenticating us to %s",

		       rhostname);

	}

	

	/* cancel response send timeout if necessary */

	if (cstate->clientstate == CHAPCS_RESPONSE)

		UNTIMEOUT(ChapResponseTimeout, cstate);

	

	cstate->resp_id = id;

	cstate->resp_transmits = 0;

	

	/*  generate MD based on negotiated type */

	switch (cstate->resp_type) { 

	

	case CHAP_DIGEST_MD5:

		MD5Init(&mdContext);

		MD5Update(&mdContext, &cstate->resp_id, 1);

		MD5Update(&mdContext, secret, secret_len);

		MD5Update(&mdContext, rchallenge, rchallenge_len);

		MD5Final(hash, &mdContext);

		BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);

		cstate->resp_length = MD5_SIGNATURE_SIZE;

		break;

	

#ifdef CHAPMS

	case CHAP_MICROSOFT:

		ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);

		break;

#endif

	

	default:

		CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));

		return;

	}

	

	BZERO(secret, sizeof(secret));

	ChapSendResponse(cstate);

}





/*

 * ChapReceiveResponse - Receive and process response.

 */

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

{

	u_char *remmd, remmd_len;

	int secret_len, old_state;

	int code;

	char rhostname[256];

	MD5_CTX mdContext;

	char secret[MAXSECRETLEN];

	u_char hash[MD5_SIGNATURE_SIZE];

	

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

	

	if (cstate->serverstate == CHAPSS_CLOSED ||

			cstate->serverstate == CHAPSS_PENDING) {

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

		cstate->serverstate));

		return;

	}

	

	if (id != cstate->chal_id)

		return;			/* doesn't match ID of last challenge */

	

	/*

	* If we have received a duplicate or bogus Response,

	* we have to send the same answer (Success/Failure)

	* as we did for the first Response we saw.

	*/

	if (cstate->serverstate == CHAPSS_OPEN) {

		ChapSendStatus(cstate, CHAP_SUCCESS);

		return;

	}

	if (cstate->serverstate == CHAPSS_BADAUTH) {

		ChapSendStatus(cstate, CHAP_FAILURE);

		return;

	}

	

	if (len < 2) {

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

		return;

	}

	GETCHAR(remmd_len, inp);		/* get length of MD */

	remmd = inp;			/* get pointer to MD */

	INCPTR(remmd_len, inp);

	

	len -= sizeof (u_char) + remmd_len;

	if (len < 0) {

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

		return;

	}

	

	UNTIMEOUT(ChapChallengeTimeout, cstate);

	

	if (len >= sizeof(rhostname))

		len = sizeof(rhostname) - 1;

	BCOPY(inp, rhostname, len);

	rhostname[len] = '\000';

	

	CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s",

				rhostname));

	

	/*

	* Get secret for authenticating them with us,

	* do the hash ourselves, and compare the result.

	*/

	code = CHAP_FAILURE;

	if (!get_secret(cstate->unit, rhostname, cstate->chal_name,

	secret, &secret_len, 1)) {

		trace(LOG_WARNING, "No CHAP secret found for authenticating %s",

		rhostname);

	} else {

	

		/*  generate MD based on negotiated type */

		switch (cstate->chal_type) { 

		

		case CHAP_DIGEST_MD5:		/* only MD5 is defined for now */

			if (remmd_len != MD5_SIGNATURE_SIZE)

				break;			/* it's not even the right length */

			MD5Init(&mdContext);

			MD5Update(&mdContext, &cstate->chal_id, 1);

			MD5Update(&mdContext, secret, secret_len);

			MD5Update(&mdContext, cstate->challenge, cstate->chal_len);

			MD5Final(hash, &mdContext); 

			

			/* compare local and remote MDs and send the appropriate status */

			if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)

				code = CHAP_SUCCESS;	/* they are the same! */

			break;

		

		default:

			CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type));

		}

	}

	

	BZERO(secret, sizeof(secret));

	ChapSendStatus(cstate, code);

	

	if (code == CHAP_SUCCESS) {

		old_state = cstate->serverstate;

		cstate->serverstate = CHAPSS_OPEN;

		if (old_state == CHAPSS_INITIAL_CHAL) {

			auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);

		}

		if (cstate->chal_interval != 0)

			TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);

	} else {

		trace(LOG_ERR, "CHAP peer authentication failed");

		cstate->serverstate = CHAPSS_BADAUTH;

		auth_peer_fail(cstate->unit, PPP_CHAP);

	}

}



/*

 * ChapReceiveSuccess - Receive Success

 */

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

{



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

	

	if (cstate->clientstate == CHAPCS_OPEN)

		/* presumably an answer to a duplicate response */

		return;

	

	if (cstate->clientstate != CHAPCS_RESPONSE) {

		/* don't know what this is */

		CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",

			   cstate->clientstate));

		return;

	}

	

	UNTIMEOUT(ChapResponseTimeout, cstate);

	

	/*

	 * Print message.

	 */

	if (len > 0)

		PRINTMSG(inp, len);

	

	cstate->clientstate = CHAPCS_OPEN;

	

	auth_withpeer_success(cstate->unit, PPP_CHAP);

}





/*

 * ChapReceiveFailure - Receive failure.

 */

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

{

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

	

	if (cstate->clientstate != CHAPCS_RESPONSE) {

		/* don't know what this is */

		CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",

			   cstate->clientstate));

		return;

	}

	

	UNTIMEOUT(ChapResponseTimeout, cstate);

	

	/*

	 * Print message.

	 */

	if (len > 0)

		PRINTMSG(inp, len);

	

	trace(LOG_ERR, "CHAP authentication failed");

	auth_withpeer_fail(cstate->unit, PPP_CHAP);

}





/*

 * ChapSendChallenge - Send an Authenticate challenge.

 */

static void ChapSendChallenge(chap_state *cstate)

{

	u_char *outp;

	int chal_len, name_len;

	int outlen;

	

	chal_len = cstate->chal_len;

	name_len = strlen(cstate->chal_name);

	outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;

	outp = outpacket_buf[cstate->unit];

	

	MAKEHEADER(outp, PPP_CHAP);		/* paste in a CHAP header */

	

	PUTCHAR(CHAP_CHALLENGE, outp);

	PUTCHAR(cstate->chal_id, outp);

	PUTSHORT(outlen, outp);

	

	PUTCHAR(chal_len, outp);		/* put length of challenge */

	BCOPY(cstate->challenge, outp, chal_len);

	INCPTR(chal_len, outp);

	

	BCOPY(cstate->chal_name, outp, name_len);	/* append hostname */

	

	pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);

	

	CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));

	

	TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);

	++cstate->chal_transmits;

}





/*

 * ChapSendStatus - Send a status response (ack or nak).

 */

static void ChapSendStatus(chap_state *cstate, int code)

{

	u_char *outp;

	int outlen, msglen;

	char msg[256];

	

	if (code == CHAP_SUCCESS)

		sprintf(msg, "Welcome to %s.", hostname);

	else

		sprintf(msg, "I don't like you.  Go 'way.");

	msglen = strlen(msg);

	

	outlen = CHAP_HEADERLEN + msglen;

	outp = outpacket_buf[cstate->unit];

	

	MAKEHEADER(outp, PPP_CHAP);		/* paste in a header */

	

	PUTCHAR(code, outp);

	PUTCHAR(cstate->chal_id, outp);

	PUTSHORT(outlen, outp);

	BCOPY(msg, outp, msglen);

	pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);

	

	CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,

	       cstate->chal_id));

}



/*

 * ChapGenChallenge is used to generate a pseudo-random challenge string of

 * a pseudo-random length between min_len and max_len.  The challenge

 * string and its length are stored in *cstate, and various other fields of

 * *cstate are initialized.

 */



static void ChapGenChallenge(chap_state *cstate)

{

	int chal_len;

	u_char *ptr = cstate->challenge;

	unsigned int i;

	

	/* pick a random challenge length between MIN_CHALLENGE_LENGTH and 

	   MAX_CHALLENGE_LENGTH */  

	chal_len = (unsigned)

				((((magic() >> 16) *

			        (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)

			     + MIN_CHALLENGE_LENGTH);

	cstate->chal_len = chal_len;

	cstate->chal_id = ++cstate->id;

	cstate->chal_transmits = 0;

	

	/* generate a random string */

	for (i = 0; i < chal_len; i++ )

		*ptr++ = (char) (magic() & 0xff);

}



/*

 * ChapSendResponse - send a response packet with values as specified

 * in *cstate.

 */

/* ARGSUSED */

static void ChapSendResponse(chap_state *cstate)

{

	u_char *outp;

	int outlen, md_len, name_len;

	

	md_len = cstate->resp_length;

	name_len = strlen(cstate->resp_name);

	outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;

	outp = outpacket_buf[cstate->unit];

	

	MAKEHEADER(outp, PPP_CHAP);

	

	PUTCHAR(CHAP_RESPONSE, outp);	/* we are a response */

	PUTCHAR(cstate->resp_id, outp);	/* copy id from challenge packet */

	PUTSHORT(outlen, outp);			/* packet length */

	

	PUTCHAR(md_len, outp);			/* length of MD */

	BCOPY(cstate->response, outp, md_len);		/* copy MD to buffer */

	INCPTR(md_len, outp);

	

	BCOPY(cstate->resp_name, outp, name_len);	/* append our name */

	

	/* send the packet */

	pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);

	

	cstate->clientstate = CHAPCS_RESPONSE;

	TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);

	++cstate->resp_transmits;

}



/*

 * ChapPrintPkt - print the contents of a CHAP packet.

 */

static int ChapPrintPkt(

	u_char *p,

	int plen,

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

	void *arg

)

{

	int code, id, len;

	int clen, nlen;

	u_char x;

	

	if (plen < CHAP_HEADERLEN)

		return 0;

	GETCHAR(code, p);

	GETCHAR(id, p);

	GETSHORT(len, p);

	if (len < CHAP_HEADERLEN || len > plen)

		return 0;

	

	if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))

		printer(arg, " %s", ChapCodenames[code-1]);

	else

		printer(arg, " code=0x%x", code);

	printer(arg, " id=0x%x", id);

	len -= CHAP_HEADERLEN;

	switch (code) {

	case CHAP_CHALLENGE:

	case CHAP_RESPONSE:

		if (len < 1)

			break;

		clen = p[0];

		if (len < clen + 1)

			break;

		++p;

		nlen = len - clen - 1;

		printer(arg, " <");

		for (; clen > 0; --clen) {

			GETCHAR(x, p);

			printer(arg, "%.2x", x);

		}

		printer(arg, ">, name = %.*Z", nlen, p);

		break;

	case CHAP_FAILURE:

	case CHAP_SUCCESS:

		printer(arg, " %.*Z", len, p);

		break;

	default:

		for (clen = len; clen > 0; --clen) {

			GETCHAR(x, p);

			printer(arg, " %.2x", x);

		}

	}

	

	return len + CHAP_HEADERLEN;

}



#endif



⌨️ 快捷键说明

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