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

📄 eap.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 4 页
字号:
			esp->es_server.ea_skey = NULL;		}#endif /* USE_SRP */		if (status != 0 || esp->es_server.ea_session == NULL) {			esp->es_server.ea_state = eapBadAuth;		} else {			esp->es_server.ea_state = eapOpen;		}		break;	case eapMD5Chall:		if (status != 0) {			esp->es_server.ea_state = eapBadAuth;		} else {			esp->es_server.ea_state = eapOpen;		}		break;	default:		esp->es_server.ea_state = eapBadAuth;		break;	}	if (esp->es_server.ea_state == eapBadAuth)		eap_send_failure(esp);}/* * Format an EAP Request message and send it to the peer.  Message * type depends on current state.  (Server operation) */static voideap_send_request(esp)eap_state *esp;{	u_char *outp;	u_char *lenloc;	u_char *ptr;	int outlen;	int challen;	char *str;#ifdef USE_SRP	struct t_server *ts;	u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;	int i, j;	struct b64state b64;	SHA1_CTX ctxt;#endif /* USE_SRP */	/* Handle both initial auth and restart */	if (esp->es_server.ea_state < eapIdentify &&	    esp->es_server.ea_state != eapInitial) {		esp->es_server.ea_state = eapIdentify;		if (explicit_remote) {			/*			 * If we already know the peer's			 * unauthenticated name, then there's no			 * reason to ask.  Go to next state instead.			 */			esp->es_server.ea_peer = remote_name;			esp->es_server.ea_peerlen = strlen(remote_name);			eap_figure_next_state(esp, 0);		}	}	if (esp->es_server.ea_maxrequests > 0 &&	    esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {		if (esp->es_server.ea_responses > 0)			error("EAP: too many Requests sent");		else			error("EAP: no response to Requests");		eap_send_failure(esp);		return;	}	outp = outpacket_buf;    	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_REQUEST, outp);	PUTCHAR(esp->es_server.ea_id, outp);	lenloc = outp;	INCPTR(2, outp);	switch (esp->es_server.ea_state) {	case eapIdentify:		PUTCHAR(EAPT_IDENTITY, outp);		str = "Name";		challen = strlen(str);		BCOPY(str, outp, challen);		INCPTR(challen, outp);		break;	case eapMD5Chall:		PUTCHAR(EAPT_MD5CHAP, outp);		/*		 * pick a random challenge length between		 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH		 */		challen = (drand48() *		    (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +			    MIN_CHALLENGE_LENGTH;		PUTCHAR(challen, outp);		esp->es_challen = challen;		ptr = esp->es_challenge;		while (--challen >= 0)			*ptr++ = (u_char) (drand48() * 0x100);		BCOPY(esp->es_challenge, outp, esp->es_challen);		INCPTR(esp->es_challen, outp);		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);		INCPTR(esp->es_server.ea_namelen, outp);		break;#ifdef USE_SRP	case eapSRP1:		PUTCHAR(EAPT_SRP, outp);		PUTCHAR(EAPSRP_CHALLENGE, outp);		PUTCHAR(esp->es_server.ea_namelen, outp);		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);		INCPTR(esp->es_server.ea_namelen, outp);		ts = (struct t_server *)esp->es_server.ea_session;		assert(ts != NULL);		PUTCHAR(ts->s.len, outp);		BCOPY(ts->s.data, outp, ts->s.len);		INCPTR(ts->s.len, outp);		if (ts->g.len == 1 && ts->g.data[0] == 2) {			PUTCHAR(0, outp);		} else {			PUTCHAR(ts->g.len, outp);			BCOPY(ts->g.data, outp, ts->g.len);			INCPTR(ts->g.len, outp);		}		if (ts->n.len != sizeof (wkmodulus) ||		    BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {			BCOPY(ts->n.data, outp, ts->n.len);			INCPTR(ts->n.len, outp);		}		break;	case eapSRP2:		PUTCHAR(EAPT_SRP, outp);		PUTCHAR(EAPSRP_SKEY, outp);		ts = (struct t_server *)esp->es_server.ea_session;		assert(ts != NULL);		BCOPY(ts->B.data, outp, ts->B.len);		INCPTR(ts->B.len, outp);		break;	case eapSRP3:		PUTCHAR(EAPT_SRP, outp);		PUTCHAR(EAPSRP_SVALIDATOR, outp);		PUTLONG(SRPVAL_EBIT, outp);		ts = (struct t_server *)esp->es_server.ea_session;		assert(ts != NULL);		BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);		INCPTR(SHA_DIGESTSIZE, outp);		if (pncrypt_setkey(0)) {			/* Generate pseudonym */			optr = outp;			cp = (unsigned char *)esp->es_server.ea_peer;			if ((j = i = esp->es_server.ea_peerlen) > 7)				j = 7;			clear[0] = i;			BCOPY(cp, clear + 1, j);			i -= j;			cp += j;			if (!DesEncrypt(clear, cipher)) {				dbglog("no DES here; not generating pseudonym");				break;			}			BZERO(&b64, sizeof (b64));			outp++;		/* space for pseudonym length */			outp += b64enc(&b64, cipher, 8, outp);			while (i >= 8) {				(void) DesEncrypt(cp, cipher);				outp += b64enc(&b64, cipher, 8, outp);				cp += 8;				i -= 8;			}			if (i > 0) {				BCOPY(cp, clear, i);				cp += i;				while (i < 8) {					*cp++ = drand48() * 0x100;					i++;				}				(void) DesEncrypt(clear, cipher);				outp += b64enc(&b64, cipher, 8, outp);			}			outp += b64flush(&b64, outp);			/* Set length and pad out to next 20 octet boundary */			i = outp - optr - 1;			*optr = i;			i %= SHA_DIGESTSIZE;			if (i != 0) {				while (i < SHA_DIGESTSIZE) {					*outp++ = drand48() * 0x100;					i++;				}			}			/* Obscure the pseudonym with SHA1 hash */			SHA1Init(&ctxt);			SHA1Update(&ctxt, &esp->es_server.ea_id, 1);			SHA1Update(&ctxt, esp->es_server.ea_skey,			    SESSION_KEY_LEN);			SHA1Update(&ctxt, esp->es_server.ea_peer,			    esp->es_server.ea_peerlen);			while (optr < outp) {				SHA1Final(dig, &ctxt);				cp = dig;				while (cp < dig + SHA_DIGESTSIZE)					*optr++ ^= *cp++;				SHA1Init(&ctxt);				SHA1Update(&ctxt, &esp->es_server.ea_id, 1);				SHA1Update(&ctxt, esp->es_server.ea_skey,				    SESSION_KEY_LEN);				SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,				    SHA_DIGESTSIZE);			}		}		break;	case eapSRP4:		PUTCHAR(EAPT_SRP, outp);		PUTCHAR(EAPSRP_LWRECHALLENGE, outp);		challen = MIN_CHALLENGE_LENGTH +		    ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());		esp->es_challen = challen;		ptr = esp->es_challenge;		while (--challen >= 0)			*ptr++ = drand48() * 0x100;		BCOPY(esp->es_challenge, outp, esp->es_challen);		INCPTR(esp->es_challen, outp);		break;#endif /* USE_SRP */	default:		return;	}	outlen = (outp - outpacket_buf) - PPP_HDRLEN;	PUTSHORT(outlen, lenloc);	output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);	esp->es_server.ea_requests++;	if (esp->es_server.ea_timeout > 0)		TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);}/* * eap_authpeer - Authenticate our peer (behave as server). * * Start server state and send first request.  This is called only * after eap_lowerup. */voideap_authpeer(unit, localname)int unit;char *localname;{	eap_state *esp = &eap_states[unit];	/* Save the name we're given. */	esp->es_server.ea_name = localname;	esp->es_server.ea_namelen = strlen(localname);	esp->es_savedtime = esp->es_server.ea_timeout;	/* Lower layer up yet? */	if (esp->es_server.ea_state == eapInitial ||	    esp->es_server.ea_state == eapPending) {		esp->es_server.ea_state = eapPending;		return;	}	esp->es_server.ea_state = eapPending;	/* ID number not updated here intentionally; hashed into M1 */	eap_send_request(esp);}/* * eap_server_timeout - Retransmission timer for sending Requests * expired. */static voideap_server_timeout(arg)void *arg;{	eap_state *esp = (eap_state *) arg;	if (!eap_server_active(esp))		return;	/* EAP ID number must not change on timeout. */	eap_send_request(esp);}/* * When it's time to send rechallenge the peer, this timeout is * called.  Once the rechallenge is successful, the response handler * will restart the timer.  If it fails, then the link is dropped. */static voideap_rechallenge(arg)void *arg;{	eap_state *esp = (eap_state *)arg;	if (esp->es_server.ea_state != eapOpen &&	    esp->es_server.ea_state != eapSRP4)		return;	esp->es_server.ea_requests = 0;	esp->es_server.ea_state = eapIdentify;	eap_figure_next_state(esp, 0);	esp->es_server.ea_id++;	eap_send_request(esp);}static voidsrp_lwrechallenge(arg)void *arg;{	eap_state *esp = (eap_state *)arg;	if (esp->es_server.ea_state != eapOpen ||	    esp->es_server.ea_type != EAPT_SRP)		return;	esp->es_server.ea_requests = 0;	esp->es_server.ea_state = eapSRP4;	esp->es_server.ea_id++;	eap_send_request(esp);}/* * eap_lowerup - The lower layer is now up. * * This is called before either eap_authpeer or eap_authwithpeer.  See * link_established() in auth.c.  All that's necessary here is to * return to closed state so that those two routines will do the right * thing. */static voideap_lowerup(unit)int unit;{	eap_state *esp = &eap_states[unit];	/* Discard any (possibly authenticated) peer name. */	if (esp->es_server.ea_peer != NULL &&	    esp->es_server.ea_peer != remote_name)		free(esp->es_server.ea_peer);	esp->es_server.ea_peer = NULL;	if (esp->es_client.ea_peer != NULL)		free(esp->es_client.ea_peer);	esp->es_client.ea_peer = NULL;	esp->es_client.ea_state = eapClosed;	esp->es_server.ea_state = eapClosed;}/* * eap_lowerdown - The lower layer is now down. * * Cancel all timeouts and return to initial state. */static voideap_lowerdown(unit)int unit;{	eap_state *esp = &eap_states[unit];	if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {		UNTIMEOUT(eap_client_timeout, (void *)esp);	}	if (eap_server_active(esp)) {		if (esp->es_server.ea_timeout > 0) {			UNTIMEOUT(eap_server_timeout, (void *)esp);		}	} else {		if ((esp->es_server.ea_state == eapOpen ||		    esp->es_server.ea_state == eapSRP4) &&		    esp->es_rechallenge > 0) {			UNTIMEOUT(eap_rechallenge, (void *)esp);		}		if (esp->es_server.ea_state == eapOpen &&		    esp->es_lwrechallenge > 0) {			UNTIMEOUT(srp_lwrechallenge, (void *)esp);		}	}	esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;	esp->es_client.ea_requests = esp->es_server.ea_requests = 0;}/* * eap_protrej - Peer doesn't speak this protocol. * * This shouldn't happen.  If it does, it represents authentication * failure. */static voideap_protrej(unit)int unit;{	eap_state *esp = &eap_states[unit];	if (eap_client_active(esp)) {		error("EAP authentication failed due to Protocol-Reject");		auth_withpeer_fail(unit, PPP_EAP);	}	if (eap_server_active(esp)) {		error("EAP authentication of peer failed on Protocol-Reject");		auth_peer_fail(unit, PPP_EAP);	}	eap_lowerdown(unit);}/* * Format and send a regular EAP Response message. */static voideap_send_response(esp, id, typenum, str, lenstr)eap_state *esp;u_char id;u_char typenum;u_char *str;int lenstr;{	u_char *outp;	int msglen;	outp = outpacket_buf;	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_RESPONSE, outp);	PUTCHAR(id, outp);	esp->es_client.ea_id = id;	msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;	PUTSHORT(msglen, outp);	PUTCHAR(typenum, outp);	if (lenstr > 0) {		BCOPY(str, outp, lenstr);	}	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);}/* * Format and send an MD5-Challenge EAP Response message. */static voideap_chap_response(esp, id, hash, name, namelen)eap_state *esp;u_char id;u_char *hash;char *name;int namelen;{	u_char *outp;	int msglen;	outp = outpacket_buf;    	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_RESPONSE, outp);	PUTCHAR(id, outp);	esp->es_client.ea_id = id;	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +	    namelen;	PUTSHORT(msglen, outp);	PUTCHAR(EAPT_MD5CHAP, outp);	PUTCHAR(MD5_SIGNATURE_SIZE, outp);	BCOPY(hash, outp, MD5_SIGNATURE_SIZE);	INCPTR(MD5_SIGNATURE_SIZE, outp);	if (namelen > 0) {		BCOPY(name, outp, namelen);	}	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);}#ifdef USE_SRP/* * Format and send a SRP EAP Response message. */static voideap_srp_response(esp, id, subtypenum, str, lenstr)eap_state *esp;u_char id;u_char subtypenum;u_char *str;int lenstr;{	u_char *outp;	int msglen;	outp = outpacket_buf;    	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_RESPONSE, outp);	PUTCHAR(id, outp);	esp->es_client.ea_id = id;	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;	PUTSHORT(msglen, outp);	PUTCHAR(EAPT_SRP, outp);	PUTCHAR(subtypenum, outp);	if (lenstr > 0) {		BCOPY(str, outp, lenstr);	}	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);}/* * Format and send a SRP EAP Client Validator Response message. */static voideap_srpval_response(esp, id, flags, str)eap_state *esp;u_char id;u_int32_t flags;u_char *str;{	u_char *outp;	int msglen;	outp = outpacket_buf;    	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_RESPONSE, outp);	PUTCHAR(id, outp);	esp->es_client.ea_id = id;	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +	    SHA_DIGESTSIZE;	PUTSHORT(msglen, outp);	PUTCHAR(EAPT_SRP, outp);	PUTCHAR(EAPSRP_CVALIDATOR, outp);	PUTLONG(flags, outp);	BCOPY(str, outp, SHA_DIGESTSIZE);	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);}#endif /* USE_SRP */static voideap_send_nak(esp, id, type)eap_state *esp;u_char id;u_char type;{	u_char *outp;	int msglen;	outp = outpacket_buf;	MAKEHEADER(outp, PPP_EAP);	PUTCHAR(EAP_RESPONSE, outp);	PUTCHAR(id, outp);	esp->es_client.ea_id = id;	msglen = EAP_HEADERLEN + 2 * sizeof (u_char);	PUTSHORT(msglen, outp);	PUTCHAR(EAPT_NAK, outp);	PUTCHAR(type, outp);	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);}#ifdef USE_SRPstatic char *name_of_pn_file(){	char *user, *path, *file;	struct passwd *pw;	size_t pl;	static bool pnlogged = 0;	pw = getpwuid(getuid());	if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {		errno = EINVAL;		return (NULL);	}	file = _PATH_PSEUDONYM;	pl = strlen(user) + strlen(file) + 2;	path = malloc(pl);	if (path == NULL)		return (NULL);	(void) slprintf(path, pl, "%s/%s", user, file);	if (!pnlogged) {		dbglog("pseudonym file: %s", path);		pnlogged = 1;	}

⌨️ 快捷键说明

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