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

📄 chap.c

📁 轻量级TCP/IP协议栈最新版本
💻 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.\n"));		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'\n",	       rhostname));		/* Microsoft doesn't send their name back in the PPP packet */	if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {		strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));		rhostname[sizeof(rhostname) - 1] = 0;		CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n",			   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 */		CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", 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, (u_char*)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\n", 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.\n", id));		if (cstate->serverstate == CHAPSS_CLOSED ||			cstate->serverstate == CHAPSS_PENDING) {		CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",		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.\n"));		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.\n"));		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\n",				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)) {/*        CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */		CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",		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, (u_char*)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\n", 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 {		CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));		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.\n", 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.\n", 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);		CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));	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.\n", 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)		strcpy(msg, "Welcome!");	else		strcpy(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.\n", 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;	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) (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#endif /* PPP_SUPPORT */

⌨️ 快捷键说明

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