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

📄 chap.c

📁 unix and linux net driver
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (len >= sizeof(rhostname))	len = sizeof(rhostname) - 1;    BCOPY(inp, rhostname, len);    rhostname[len] = '\000';    /* Microsoft doesn't send their name back in the PPP packet */    if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) {	strlcpy(rhostname, remote_name, sizeof(rhostname));	CHAPDEBUG(("ChapReceiveChallenge: using '%q' 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 */	warn("No CHAP secret found for authenticating us to %q", 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(("unknown digest type %d", cstate->resp_type));	return;    }    BZERO(secret, sizeof(secret));    ChapSendResponse(cstate);}/* * ChapReceiveResponse - Receive and process response. */static voidChapReceiveResponse(cstate, inp, id, len)    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];    if (cstate->serverstate == CHAPSS_CLOSED ||	cstate->serverstate == CHAPSS_PENDING) {	CHAPDEBUG(("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(("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(("ChapReceiveResponse: rcvd short packet."));	return;    }    UNTIMEOUT(ChapChallengeTimeout, cstate);    if (len >= sizeof(rhostname))	len = sizeof(rhostname) - 1;    BCOPY(inp, rhostname, len);    rhostname[len] = '\000';    /*     * Get secret for authenticating them with us,     * do the hash ourselves, and compare the result.     */    code = CHAP_FAILURE;    if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname),		    cstate->chal_name, secret, &secret_len, 1)) {	warn("No CHAP secret found for authenticating %q", 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(("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);	notice("CHAP peer authentication succeeded for %q", rhostname);    } else {	error("CHAP peer authentication failed for remote host %q", rhostname);	cstate->serverstate = CHAPSS_BADAUTH;	auth_peer_fail(cstate->unit, PPP_CHAP);    }}/* * ChapReceiveSuccess - Receive Success */static voidChapReceiveSuccess(cstate, inp, id, len)    chap_state *cstate;    u_char *inp;    u_char id;    int len;{    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(("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 voidChapReceiveFailure(cstate, inp, id, len)    chap_state *cstate;    u_char *inp;    u_char id;    int len;{    if (cstate->clientstate != CHAPCS_RESPONSE) {	/* don't know what this is */	CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate));	return;    }    UNTIMEOUT(ChapResponseTimeout, cstate);    /*     * Print message.     */    if (len > 0)	PRINTMSG(inp, len);    error("CHAP authentication failed");    auth_withpeer_fail(cstate->unit, PPP_CHAP);}/* * ChapSendChallenge - Send an Authenticate challenge. */static voidChapSendChallenge(cstate)    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;    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 */    output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);      TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);    ++cstate->chal_transmits;}/* * ChapSendStatus - Send a status response (ack or nak). */static voidChapSendStatus(cstate, code)    chap_state *cstate;    int code;{    u_char *outp;    int outlen, msglen;    char msg[256];    if (code == CHAP_SUCCESS)	slprintf(msg, sizeof(msg), "Welcome to %s.", hostname);    else	slprintf(msg, sizeof(msg), "I don't like you.  Go 'way.");    msglen = strlen(msg);    outlen = CHAP_HEADERLEN + msglen;    outp = outpacket_buf;    MAKEHEADER(outp, PPP_CHAP);	/* paste in a header */      PUTCHAR(code, outp);    PUTCHAR(cstate->chal_id, outp);    PUTSHORT(outlen, outp);    BCOPY(msg, outp, msglen);    output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);}/* * 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 voidChapGenChallenge(cstate)    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) ((drand48() *			     (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +			    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) (drand48() * 0xff);}/* * ChapSendResponse - send a response packet with values as specified * in *cstate. *//* ARGSUSED */static voidChapSendResponse(cstate)    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;    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 */    output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);    cstate->clientstate = CHAPCS_RESPONSE;    TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);    ++cstate->resp_transmits;}/* * ChapPrintPkt - print the contents of a CHAP packet. */static char *ChapCodenames[] = {    "Challenge", "Response", "Success", "Failure"};static intChapPrintPkt(p, plen, printer, arg)    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 = ");	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_HEADERLEN;}

⌨️ 快捷键说明

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