chap-new.c

来自「自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多」· C语言 代码 · 共 640 行 · 第 1/2 页

C
640
字号
		GETCHAR(response_len, pkt);		len -= response_len + 1;	/* length of name */		name = (char *)pkt + response_len;		if (len < 0)			return;		if (ss->flags & TIMEOUT_PENDING) {			ss->flags &= ~TIMEOUT_PENDING;			UNTIMEOUT(chap_timeout, ss);		}		if (explicit_remote) {			name = remote_name;		} else {			/* Null terminate and clean remote name. */			slprintf(rname, sizeof(rname), "%.*v", len, name);			name = rname;		}		if (chap_verify_hook)			verifier = chap_verify_hook;		else			verifier = chap_verify_response;		ok = (*verifier)(name, ss->name, id, ss->digest,				 ss->challenge + PPP_HDRLEN + CHAP_HDRLEN,				 response, ss->message, sizeof(ss->message));		if (!ok || !auth_number()) {			ss->flags |= AUTH_FAILED;			warn("Peer %q failed CHAP authentication", name);		}	} else if ((ss->flags & AUTH_DONE) == 0)		return;	/* send the response */	p = outpacket_buf;	MAKEHEADER(p, PPP_CHAP);	mlen = strlen(ss->message);	len = CHAP_HDRLEN + mlen;	p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS;	p[1] = id;	p[2] = len >> 8;	p[3] = len;	if (mlen > 0)		memcpy(p + CHAP_HDRLEN, ss->message, mlen);	output(0, outpacket_buf, PPP_HDRLEN + len);	if (ss->flags & CHALLENGE_VALID) {		ss->flags &= ~CHALLENGE_VALID;		if (ss->flags & AUTH_FAILED) {			auth_peer_fail(0, PPP_CHAP);		} else {			if ((ss->flags & AUTH_DONE) == 0)				auth_peer_success(0, PPP_CHAP,						  ss->digest->code,						  name, strlen(name));			if (chap_rechallenge_time) {				ss->flags |= TIMEOUT_PENDING;				TIMEOUT(chap_timeout, ss,					chap_rechallenge_time);			}		}		ss->flags |= AUTH_DONE;	}}/* * chap_verify_response - check whether the peer's response matches * what we think it should be.  Returns 1 if it does (authentication * succeeded), or 0 if it doesn't. */static intchap_verify_response(char *name, char *ourname, int id,		     struct chap_digest_type *digest,		     unsigned char *challenge, unsigned char *response,		     char *message, int message_space){	int ok;	unsigned char secret[MAXSECRETLEN];	int secret_len;	/* Get the secret that the peer is supposed to know */	if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {		error("No CHAP secret found for authenticating %q", name);		return 0;	}	ok = digest->verify_response(id, name, secret, secret_len, challenge,				     response, message, message_space);	memset(secret, 0, sizeof(secret));	return ok;}/* * chap_respond - Generate and send a response to a challenge. */static voidchap_respond(struct chap_client_state *cs, int id,	     unsigned char *pkt, int len){	int clen, nlen;	int secret_len;	unsigned char *p;	unsigned char response[RESP_MAX_PKTLEN];	char rname[MAXNAMELEN+1];	char secret[MAXSECRETLEN+1];	if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED))		return;		/* not ready */	if (len < 2 || len < pkt[0] + 1)		return;		/* too short */	clen = pkt[0];	nlen = len - (clen + 1);	/* Null terminate and clean remote name. */	slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1);	/* Microsoft doesn't send their name back in the PPP packet */	if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0))		strlcpy(rname, remote_name, sizeof(rname));	/* get secret for authenticating ourselves with the specified host */	if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) {		secret_len = 0;	/* assume null secret if can't find one */		warn("No CHAP secret found for authenticating us to %q", rname);	}	p = response;	MAKEHEADER(p, PPP_CHAP);	p += CHAP_HDRLEN;	cs->digest->make_response(p, id, cs->name, pkt,				  secret, secret_len, cs->priv);	memset(secret, 0, secret_len);	clen = *p;	nlen = strlen(cs->name);	memcpy(p + clen + 1, cs->name, nlen);	p = response + PPP_HDRLEN;	len = CHAP_HDRLEN + clen + 1 + nlen;	p[0] = CHAP_RESPONSE;	p[1] = id;	p[2] = len >> 8;	p[3] = len;	output(0, response, PPP_HDRLEN + len);}static voidchap_handle_status(struct chap_client_state *cs, int code, int id,		   unsigned char *pkt, int len){	const char *msg = NULL;	if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP))	    != (AUTH_STARTED|LOWERUP))		return;	cs->flags |= AUTH_DONE;	if (code == CHAP_SUCCESS) {		/* used for MS-CHAP v2 mutual auth, yuck */		if (cs->digest->check_success != NULL) {			if (!(*cs->digest->check_success)(pkt, len, cs->priv))				code = CHAP_FAILURE;		} else			msg = "CHAP authentication succeeded";	} else {		if (cs->digest->handle_failure != NULL)			(*cs->digest->handle_failure)(pkt, len);		else			msg = "CHAP authentication failed";	}	if (msg) {		if (len > 0)			info("%s: %.*v", msg, len, pkt);		else			info("%s", msg);	}	if (code == CHAP_SUCCESS)		auth_withpeer_success(0, PPP_CHAP, cs->digest->code);	else {		cs->flags |= AUTH_FAILED;		error("CHAP authentication failed");		auth_withpeer_fail(0, PPP_CHAP);	}}static voidchap_input(int unit, unsigned char *pkt, int pktlen){	struct chap_client_state *cs = &client;	struct chap_server_state *ss = &server;	unsigned char code, id;	int len;	if (pktlen < CHAP_HDRLEN)		return;	GETCHAR(code, pkt);	GETCHAR(id, pkt);	GETSHORT(len, pkt);	if (len < CHAP_HDRLEN || len > pktlen)		return;	len -= CHAP_HDRLEN;	switch (code) {	case CHAP_CHALLENGE:		chap_respond(cs, id, pkt, len);		break;	case CHAP_RESPONSE:		chap_handle_response(ss, id, pkt, len);		break;	case CHAP_FAILURE:	case CHAP_SUCCESS:		chap_handle_status(cs, code, id, pkt, len);		break;	}}static voidchap_protrej(int unit){	struct chap_client_state *cs = &client;	struct chap_server_state *ss = &server;	if (ss->flags & TIMEOUT_PENDING) {		ss->flags &= ~TIMEOUT_PENDING;		UNTIMEOUT(chap_timeout, ss);	}	if (ss->flags & AUTH_STARTED) {		ss->flags = 0;		auth_peer_fail(0, PPP_CHAP);	}	if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {		cs->flags &= ~AUTH_STARTED;		error("CHAP authentication failed due to protocol-reject");		auth_withpeer_fail(0, PPP_CHAP);	}}/* * chap_print_pkt - print the contents of a CHAP packet. */static char *chap_code_names[] = {	"Challenge", "Response", "Success", "Failure"};static intchap_print_pkt(unsigned char *p, int plen,	       void (*printer) __P((void *, char *, ...)), void *arg){	int code, id, len;	int clen, nlen;	unsigned char x;	if (plen < CHAP_HDRLEN)		return 0;	GETCHAR(code, p);	GETCHAR(id, p);	GETSHORT(len, p);	if (len < CHAP_HDRLEN || len > plen)		return 0;	if (code >= 1 && code <= sizeof(chap_code_names) / sizeof(char *))		printer(arg, " %s", chap_code_names[code-1]);	else		printer(arg, " code=0x%x", code);	printer(arg, " id=0x%x", id);	len -= CHAP_HDRLEN;	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 = ");		print_string((char *)p, nlen, printer, arg);		break;	case CHAP_FAILURE:	case CHAP_SUCCESS:		printer(arg, " ");		print_string((char *)p, len, printer, arg);		break;	default:		for (clen = len; clen > 0; --clen) {			GETCHAR(x, p);			printer(arg, " %.2x", x);		}	}	return len + CHAP_HDRLEN;}struct protent chap_protent = {	PPP_CHAP,	chap_init,	chap_input,	chap_protrej,	chap_lowerup,	chap_lowerdown,	NULL,		/* open */	NULL,		/* close */	chap_print_pkt,	NULL,		/* datainput */	1,		/* enabled_flag */	"CHAP",		/* name */	NULL,		/* data_name */	chap_option_list,	NULL,		/* check_options */};

⌨️ 快捷键说明

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