?? ppp.c
字號:
#endif
}
break;
#if defined(LQRP) && QUALITY
case LCPopt_LQPT:
if (cp2[2] != 0xc0 || cp2[3] != 0x25)
goto rej3;
cp2 += 2;
if ((!cp2[0] || !cp2[1] || !cp2[2] || !cp2[3]) &&
netp->peerLQRPms == 0)
goto rej3;
netp->ownLQRPms = cp2[0] << 24 +
cp2[1] << 16 +
cp2[2] << 8 +
cp2[3];
netp->ownLQRPms *= 10;
#endif
case LCPopt_MNUM:
break;
case LCPopt_RES6:
goto rej3;
#if COMPRESSION & 1
case LCPopt_PCMP:
case LCPopt_ACMP:
netp->hw.remopts |= 1<<us1;
break;
#endif
#if MP
#if 0
case LCPopt_SNHF: /* Not supported */
netp->hw.opt5 |= MPsnhf;
break;
#endif
case LCPopt_ENDD:
if (us2 > 20 + 3)
goto rej3;
if (mpFindBundle(netno, cp2[2], us2-3, (char *)cp2+3) < 0)
goto rej3;
break;
#endif
default:
rej3:
/* Build reject at +400 in buffer */
Nmemcpy((char *)mess+400+rejlen, cp2, us2);
rejlen += us2;
rej4:
break;
}
}
if (naklen || rejlen) {
netp->hw.remopts = 0;
if (naklen) {
*cp = LCPconf_nak; /* Nak with hint */
Nmemcpy((char *)cp + 4, (char *)mess + 200, naklen);
i2 = naklen + 4;
}
else if (rejlen) {
*cp = LCPconf_rej; /* Reject others */
Nmemcpy((char *)cp + 4, (char *)mess + 400, rejlen);
i2 = rejlen + 4;
}
mess->mlen = MESSH_SZ + LHDRSZ + i2;
cp[2] = i2 >> 8, cp[3] = i2;
netp->state &= ~(LCPrxREQ + LCPtxACK);
}
else
netp->state |= (LCPrxREQ | LCPtxACK);
pppWrite(mess);
break;
case LCPconf_ack:
if (cp[1] != netp->hw.opt1 || (prevstate & LCPtxREQ) == 0)
goto rej1;
if ((prevstate & LCPopen) == LCPopen)
pppStart(netno, 1); /* tld, restart LCP */
else if (prevstate & LCPrxACK) /* If ack-rcvd already, */
netp->state = 0; /* send conf-req */
else {
netp->state |= LCPrxACK; /* ack-rcvd */
netp->hw.opt7 = MAXCONF; /* Initialize restart counter */
netp->hw.timems = TimeMS(); /* Initialize timer */
}
break;
case LCPconf_nak:
case LCPconf_rej:
if (cp[1] != netp->hw.opt1)
goto rej1;
/* Find and disable unaccepted options */
for (; i1>0; cp2+=us2) {
us1 = cp2[0]; /* type */
us2 = cp2[1]; /* length */
i1 -= us2; /* length - 1 */
if (us1 > 19 || us2 < 2)
break;
#if REQAUTH
if (us1 == 3) {
#if NTRACE >= 3
Nprintf("PPP: Peer refused requested authentication.\n");
#endif
goto term;
}
#endif
#if MP
if (us1 > 15)
netp->hw.opt5 &= ~(1<<(us1-16));/* disable MP opts */
else
#endif
if (*cp == LCPconf_nak && us1 == LCPopt_ASYC)
netp->hw.ul1 = cp2[2] << 24 +
cp2[3] << 16 +
cp2[4] << 8 +
cp2[5];
else {
netp->hw.locopts &= ~(1<<us1); /* disable option */
if (us1 == LCPopt_ASYC)
netp->hw.ul1 = 0xffffffff;
}
}
if ((prevstate & LCPopen) == LCPopen)
pppStart(netno, 1); /* tld, restart LCP */
else if (prevstate & LCPrxACK)
netp->state = 0;
else {
netp->hw.opt7 = MAXCONF; /* Initialize restart counter */
netp->hw.timems = TimeMS(); /* Initialize timer */
netp->state &= ~(LCPtxREQ | LCPrxACK);
}
break;
case LCPterm_req:
if ((prevstate & LCPopen) == LCPopen) {
netp->state = PPPclsng;
netp->hw.opt7 = 0; /* Zero restart counter */
pppDQ(netno);
}
else if (prevstate != PPPclsd && prevstate != PPPclsng)
netp->state = LCPtxREQ; /* Wait for TO+/- */
*cp = LCPterm_ack; /* Set new type */
pppWrite(mess); /* Send term-ack */
break;
case LCPterm_ack:
if (cp[1] != netp->hw.opt1) /* reject bad ID */
goto rej1;
if (prevstate != PPPclsng)
if ((prevstate & LCPopen) == LCPopen)
netp->state = 0; /* resend conf-req */
else
netp->state &= ~(LCPrxACK);
else { /* If closing/stopping, */
#if MP
mpShut(netno);
#endif
netp->state = PPPclsd; /* link layer closed */
netp->hw.opt7 = 0;
pppDQ(netno);
PPPSIG_LCP_DOWN(netno);
#if DIALD
if ((netconf[netp->confix].flags & DIAL) == 0)
#endif
{
PPPSIG_PPP_DOWN(netno);
}
pppForceDown(netno);
return -2;
}
case LCPcode_rej:
#if NTRACE
Nprintf("PPP: Peer may be using an unknown version of PPP\n");
#endif
break;
case LCPprot_rej:
us1 = cp2[0] << 8 + cp2[1];
if (us1 == PROTlqp)
netp->hw.locopts &= ~(1<<LCPopt_LQPT);
else if (us1 == PROTipcp) {
#if NTRACE
Nprintf("PPP: Peer does not support IPCP!\n");
#endif
goto term;
}
break;
case LCPecho_req:
if ((prevstate & LCPopen) == LCPopen) {
*cp = LCPecho_rep;
#if MAGICNUM
if (netp->hw.locopts & (1<<LCPopt_MNUM)) {
netp->hw.mnum = TimeMS();
Nmemcpy((char *)cp+4, (char *)&netp->hw.mnum, 4);
}
else
#endif
memset((char *)cp+4, 0, 4);
pppWrite(mess);
}
break;
#if ECHO_TOUTMS
case LCPecho_rep:
/*
** There is no check for packet id. This could be bad if the
** peer is delayed in it's responses beyond the timeout period
** for echo-req. This is, however, very unlikely as the timeout
** period should generally be in seconds, not milliseconds.
*/
#if MAGICNUM
if (netp->hw.locopts & (1<<LCPopt_MNUM)) {
/* Magic number in reply shouldn't match request */
if (memcmp(cp+4, (char *)&netp->hw.mnum, 4) != 0)
netp->hw.opt6--;
#if NTRACE >= 3
else
Nprintf("PPP: Possible loop-back condition on echo-rep\n");
#endif
}
else
#endif
netp->hw.opt6--;
#endif
case LCPdisc_req:
break;
default: /* Unknown code */
i1 += 4; /* Length of packet */
us1 = i1 + 4; /* Length of new packet */
for (; i1 >= 0; i1--) /* Copy packet */
cp2[i1] = cp[i1];
*cp = LCPcode_rej; /* New code field */
cp[2] = us1 >> 8, cp[3] = us1; /* New length field */
mess->mlen = MESSH_SZ + LHDRSZ + us1;
pppWrite(mess);
break;
}
}
else if ((prevstate & LCPopen) != LCPopen)
goto rej1; /* Only LCP until LCP is open */
#if AUTHENT & 1 || REQAUTH == PROTpap
else if (protocol == NC2(PROTpap)) {
switch (us1) {
#if REQAUTH == PROTpap
case PAPauth_req:
netp->hw.opt4 &= ~AUTHhwat; /* Peer responded */
cp3 = ussGetPasswd(netno, *cp2, cp2+1);
cp2 += *cp2 + 1;
if (strlen(cp3) == *cp2 && strncmp(cp3, cp2+1, *cp2) == 0) {
*cp = PAPauth_ack; /* Set response to ACK */
cp[4] = strlen(AUTH_ACK_REPLY); /* Size of reply */
strcpy((char *)cp+5,AUTH_ACK_REPLY);/* insert reply text */
netp->hw.opt4 &= ~AUTHhpap; /* Peer accepted */
}
else {
*cp = PAPauth_nak; /* Set response to NAK */
cp[4] = strlen(AUTH_NAK_REPLY); /* Size of reply */
strcpy((char *)cp+5,AUTH_NAK_REPLY);/* insert reply text */
#if NTRACE >= 3
Nprintf("PPP: Peer failed PAP authentication\n");
#endif
}
rejlen = cp[4] + 5; /* Determine length */
cp[2] = rejlen >> 8, cp[3] = rejlen;/* Set value in packet*/
mess->mlen = MESSH_SZ + LHDRSZ + rejlen;
pppWrite(mess); /* Drop it on line */
if (*cp == PAPauth_nak) {
PPPSIG_PAUTH_DOWN(netno);
goto term;
}
else {
PPPSIG_PAUTH_UP(netno);
}
break;
#endif
#if AUTHENT & 1
case PAPauth_ack:
netp->hw.opt4 &= ~(AUTHppap|AUTHpwat); /* Host accepted */
PPPSIG_HAUTH_UP(netno);
break;
case PAPauth_nak:
#if NTRACE >= 3
Nprintf("PPP: Host failed PAP authentication.\n");
#endif
PPPSIG_HAUTH_DOWN(netno);
break;
#endif
}
}
#endif
#if AUTHENT & 6 || REQAUTH == PROTchap /* CHAP/MS-CHAP auth allowed */
else if (protocol == NC2(PROTchap)) {
switch (us1) {
#if AUTHENT & 6
case CHAPchallenge:
netp->hw.opt4 |= AUTHpwat; /* Wait for success/fail */
*cp = CHAPresponse; /* Signal a response (2) */
us2 = *cp2; /* Value size */
#if AUTHENT & 4
if (netp->hw.opt4 & AUTHpmsc) {
cp3 = cp2 + 50; /* End of data field */
Nmemcpy(cp3, cp2+1, us2); /* Save challenge value */
*cp2 = 49; /* value size is 49 */
memset(cp2+1, 0, 49); /* Zero value field */
i2 = ((i1 = strlen(netp->hw.passwd)) > 14) ? 14 : i1;
for (i3=0; i3 < i2*2; i3++) {
*((char *)cp3+8+i3*2) = netp->hw.passwd[i3];
*((char *)cp3+9+i3*2) = 0;
}
NtChallengeResponse(cp3, cp3+8, i2*2, cp2+25);
LmChallengeResponse(cp3, (unsigned char *)netp->hw.passwd,
cp2+1);
cp2[49] = USE_NT; /* Use (0=LM, 1=NT) ChRe */
i2 = 50; /* place to add id */
rejlen = 54; /* add name length */
}
#endif
#if AUTHENT & 2
if (netp->hw.opt4 & AUTHpchp) {
/* CHAP response:
** MD5(id + secret + challenge) ==> new value field
*/
cp3 = cp2 + i1;
*cp3 = cp[1];
strcpy((char *)cp3+1, netp->hw.passwd); /* PassWd */
i1 = strlen(netp->hw.passwd) + 1; /* PassWd len + ID */
Nmemcpy((char *)cp3+i1, cp2+1, us2); /* Copy challenge */
i1 += us2; /* Length to hash */
*cp2 = 16; /* Value size is 16 */
MD5digest(cp3, i1, cp2+1);
i2 = 17; /* Place to add id */
rejlen = 21; /* Add name length */
}
#endif
strcpy((char *)cp2 + i2, netp->hw.userid); /* Add name */
rejlen += strlen(netp->hw.userid); /* Add length of name */
cp[2] = rejlen >> 8, cp[3] = rejlen; /* Length */
mess->mlen = MESSH_SZ + LHDRSZ + rejlen;/* Set mess buf len */
pppWrite(mess);
break;
#endif
#if REQAUTH == PROTchap
case CHAPresponse:
if (cp[1] != netp->hw.opt1) /* Match challenge ID */
goto rej1;
netp->hw.opt4 &= ~AUTHhwat; /* Peer responded */
/* CHAP length = 16, MS-CHAP length = 49 */
us2 = *cp2; /* length of value */
rejlen = 4;
/* Re-create the peer's response to our challenge.
** Variables used:
** i1 is the length of the response
** us2 is the value size
** cp2 points to the value size (data area of PPP packet)
** cp3 will point to the challenge (in scratch area)
** cp4 will point to the password (derived from the userid)
** i2 will be the length of the new challenge value
**
** CHAP:
** value size = 16
** MD5(id + secret + challenge, length, value)
** MS-CHAP:
** value size = 49
** NT(challenge, unicode secret, value)
** LM(challenge, secret, value + 24)
** USE_NT at value + 48
*/
cp3 = cp2 + i1; /* Point to scratch area */
i2 = 0; /* Length of value to hash */
cp4 = (unsigned char *)ussGetPasswd(netno, i1-us2-1,
(char *)cp2+us2+1);
#if AUTH_ALG == CHAPalg_MD5
/* Identifier*/
cp3[i2++] = cp[1];
/* Secret */
strcpy((char *)cp3+i2, (char *)cp4);
i2 += strlen((char *)cp4);
#endif
/* Challenge */
cp3[i2++] = (unsigned char)strlen(netp->hw.userid);
Nmemcpy((char *)cp3+i2, (char *)&netp->hw.ul2, 4);
i2 += 4;
cp3[i2++] = (unsigned char)(netp->hw.ul2 >> 3);
cp3[i2++] = (unsigned char)(netp->hw.ul2 >> 10);
cp3[i2++] = (unsigned char)(netp->hw.ul2 >> 15);
#if AUTH_ALG == CHAPalg_MD5
MD5digest(cp3, i2, cp3+i2); /* HASH the challenge */
if (memcmp(cp2+1, cp3+i2, 16) == 0)
#elif AUTH_ALG == CHAPalg_MD4
if (cp2[49] == 1) {
/* Make Unicode password for NT response after challenge. */
for (i3=i2, us1=strlen((char *)cp4), us2=0; us2 < us1; us2++) {
cp3[i3++] = cp4[us2];
cp3[i3++] = 0;
}
/* Make NT Response (last parameter) after unicode password. */
NtChallengeResponse(cp3, cp3+i2, us1<<1, cp3+i3);
i2 = 25;
}
else if (cp2[49]
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -