1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-09-19 10:10:40 +03:00

Merge pull request #1420 from domosekai/eap

Implement EAP-MSCHAPv2
This commit is contained in:
Ilya Shipitsin 2021-07-10 23:27:10 +05:00 committed by GitHub
commit 7881f8657a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 335 additions and 110 deletions

View File

@ -86,9 +86,9 @@ void PPPThread(THREAD *thread, void *param)
receivedPacketProcessed = PPPRejectUnsupportedPacket(p, p->CurrentPacket); receivedPacketProcessed = PPPRejectUnsupportedPacket(p, p->CurrentPacket);
// Now do some basic processing // Now do some basic processing
if (!receivedPacketProcessed && p->CurrentPacket->IsControl && p->CurrentPacket->Protocol == PPP_PROTOCOL_LCP) if (receivedPacketProcessed == false && p->CurrentPacket->IsControl && p->CurrentPacket->Protocol == PPP_PROTOCOL_LCP)
{ {
if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_ECHO_REQUEST && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_ECHO_REQUEST && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
// Immediately return the echo response to the echo request // Immediately return the echo response to the echo request
PPP_PACKET *pp2 = ZeroMalloc(sizeof(PPP_PACKET)); PPP_PACKET *pp2 = ZeroMalloc(sizeof(PPP_PACKET));
@ -107,17 +107,17 @@ void PPPThread(THREAD *thread, void *param)
receivedPacketProcessed = true; receivedPacketProcessed = true;
} }
else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_ECHO_RESPONSE && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_ECHO_RESPONSE && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
receivedPacketProcessed = true; receivedPacketProcessed = true;
// Ignore the Echo response packet // Ignore the Echo response packet
} }
else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_DROP && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_DROP && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
receivedPacketProcessed = true; receivedPacketProcessed = true;
// Ignore the Drop packet // Ignore the Drop packet
} }
else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_IDENTIFICATION && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) else if (p->CurrentPacket->Lcp->Code == PPP_LCP_CODE_IDENTIFICATION && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
receivedPacketProcessed = true; receivedPacketProcessed = true;
// Ignore the Identification packet // Ignore the Identification packet
@ -155,7 +155,7 @@ void PPPThread(THREAD *thread, void *param)
} }
// Process responses // Process responses
if (!receivedPacketProcessed && p->CurrentPacket != NULL && p->CurrentPacket->IsControl && PPP_CODE_IS_RESPONSE(p->CurrentPacket->Protocol, p->CurrentPacket->Lcp->Code) && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) if (receivedPacketProcessed == false && p->CurrentPacket != NULL && p->CurrentPacket->IsControl && PPP_CODE_IS_RESPONSE(p->CurrentPacket->Protocol, p->CurrentPacket->Lcp->Code) && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
PPP_PACKET *request = NULL; PPP_PACKET *request = NULL;
// Removing from resend list // Removing from resend list
@ -177,14 +177,14 @@ void PPPThread(THREAD *thread, void *param)
} }
// Process requests // Process requests
if (!receivedPacketProcessed && p->CurrentPacket != NULL && p->CurrentPacket->IsControl && PPP_CODE_IS_REQUEST(p->CurrentPacket->Protocol, p->CurrentPacket->Lcp->Code) && !PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus)) if (receivedPacketProcessed == false && p->CurrentPacket != NULL && p->CurrentPacket->IsControl && PPP_CODE_IS_REQUEST(p->CurrentPacket->Protocol, p->CurrentPacket->Lcp->Code) && PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false)
{ {
PPPProcessRequestPacket(p, p->CurrentPacket); PPPProcessRequestPacket(p, p->CurrentPacket);
receivedPacketProcessed = true; receivedPacketProcessed = true;
} }
// Process data packets, discarded before we got any links up // Process data packets, discarded before we got any links up
if (!receivedPacketProcessed && p->CurrentPacket != NULL && !p->CurrentPacket->IsControl && p->PPPStatus == PPP_STATUS_NETWORK_LAYER && p->Ipc != NULL) if (receivedPacketProcessed == false && p->CurrentPacket != NULL && p->CurrentPacket->IsControl == false && p->PPPStatus == PPP_STATUS_NETWORK_LAYER && p->Ipc != NULL)
{ {
UINT64 timeBeforeLoop = Tick64(); UINT64 timeBeforeLoop = Tick64();
while (true) while (true)
@ -238,7 +238,7 @@ void PPPThread(THREAD *thread, void *param)
} }
} }
if (!receivedPacketProcessed && p->CurrentPacket != NULL) if (receivedPacketProcessed == false && p->CurrentPacket != NULL)
{ {
Debug("Unprocessed and unrejected packet, protocol = 0x%x\n", p->CurrentPacket->Protocol); Debug("Unprocessed and unrejected packet, protocol = 0x%x\n", p->CurrentPacket->Protocol);
} }
@ -260,7 +260,24 @@ void PPPThread(THREAD *thread, void *param)
p->Eap_PacketId = p->NextId++; p->Eap_PacketId = p->NextId++;
lcpEap = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags); lcpEap = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags);
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING); PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
break;
}
break;
case PPP_EAP_TYPE_MSCHAPV2:
// Sending challenge
p->Eap_PacketId = p->NextId; // Do not increase NextId so that MSCHAPv2 could use the same id
lcp = BuildMSCHAP2ChallengePacket(p);
BUF *b = BuildLCPData(lcp);
lcpEap = BuildEAPPacketEx(PPP_EAP_CODE_REQUEST, p->Eap_PacketId, PPP_EAP_TYPE_MSCHAPV2, b->Size);
eapPacket = lcpEap->Data;
Copy(eapPacket->Data, b->Buf, b->Size);
Free(b);
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -275,7 +292,7 @@ void PPPThread(THREAD *thread, void *param)
eapPacket = lcpEap->Data; eapPacket = lcpEap->Data;
Copy(eapPacket->Data, welcomeMessage, StrLen(welcomeMessage)); Copy(eapPacket->Data, welcomeMessage, StrLen(welcomeMessage));
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING); PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -291,7 +308,7 @@ void PPPThread(THREAD *thread, void *param)
Debug("Starting PPP Authentication phase MS-CHAP v2\n"); Debug("Starting PPP Authentication phase MS-CHAP v2\n");
lcp = BuildMSCHAP2ChallengePacket(p); lcp = BuildMSCHAP2ChallengePacket(p);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -300,7 +317,7 @@ void PPPThread(THREAD *thread, void *param)
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING); PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
} }
if (p->PPPStatus == PPP_STATUS_CONNECTED && !authReqSent) if (p->PPPStatus == PPP_STATUS_CONNECTED && authReqSent == false)
{ {
// EAP code // EAP code
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
@ -308,7 +325,7 @@ void PPPThread(THREAD *thread, void *param)
Debug("Request EAP\n"); Debug("Request EAP\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &eap_code, sizeof(eap_code))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &eap_code, sizeof(eap_code)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -444,14 +461,14 @@ void PPPThread(THREAD *thread, void *param)
Debug("Trying to cleanly close the connection, status = 0x%x\n", p->PPPStatus); Debug("Trying to cleanly close the connection, status = 0x%x\n", p->PPPStatus);
PPPSetStatus(p, PPP_STATUS_CLOSING_WAIT); PPPSetStatus(p, PPP_STATUS_CLOSING_WAIT);
lcp = NewPPPLCP(PPP_LCP_CODE_TERMINATE_REQ, 0); lcp = NewPPPLCP(PPP_LCP_CODE_TERMINATE_REQ, 0);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
} }
} }
if (!PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) || p->PPPStatus == PPP_STATUS_CLOSING_WAIT) if (PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false || p->PPPStatus == PPP_STATUS_CLOSING_WAIT)
{ {
PPPProcessRetransmissions(p); PPPProcessRetransmissions(p);
PPPSendEchoRequest(p); PPPSendEchoRequest(p);
@ -681,7 +698,7 @@ bool PPPRejectUnsupportedPacketEx(PPP_SESSION *p, PPP_PACKET *pp, bool force)
FreeBuf(buf); FreeBuf(buf);
if (!PPPSendPacketAndFree(p, pp2)) if (PPPSendPacketAndFree(p, pp2) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -721,7 +738,7 @@ bool PPPProcessRetransmissions(PPP_SESSION *p)
else if (t->ResendTime <= now) else if (t->ResendTime <= now)
{ {
Debug("Resending control packet protocol = 0x%x\n", t->Packet->Protocol); Debug("Resending control packet protocol = 0x%x\n", t->Packet->Protocol);
if (!PPPSendPacketEx(p, t->Packet, false)) if (PPPSendPacketEx(p, t->Packet, false) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -762,7 +779,7 @@ bool PPPSendEchoRequest(PPP_SESSION *p)
pp->Lcp->Data = Clone(echo_data, sizeof(echo_data)); pp->Lcp->Data = Clone(echo_data, sizeof(echo_data));
pp->Lcp->DataSize = sizeof(echo_data); pp->Lcp->DataSize = sizeof(echo_data);
if (!PPPSendPacketAndFree(p, pp)) if (PPPSendPacketAndFree(p, pp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -819,7 +836,7 @@ bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
{ {
UINT i; UINT i;
bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code); bool isAccepted = PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code) == false;
bool result = true; bool result = true;
// MSCHAPv2 code // MSCHAPv2 code
UCHAR ms_chap_v2_code[3]; UCHAR ms_chap_v2_code[3];
@ -827,7 +844,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2; ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2;
// We got one of rejects here, not NACKs // We got one of rejects here, not NACKs
if (!isAccepted && pp->Lcp->Code == PPP_LCP_CODE_PROTOCOL_REJECT) if (isAccepted == false && pp->Lcp->Code == PPP_LCP_CODE_PROTOCOL_REJECT)
{ {
// If we receive a protocol reject before we finished authenticating // If we receive a protocol reject before we finished authenticating
// probably means the PPP client is not compatible anyway so we fail the connection // probably means the PPP client is not compatible anyway so we fail the connection
@ -853,7 +870,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
} }
} }
if (!isAccepted && pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT) if (isAccepted == false && pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -872,7 +889,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
if (t->DataSize == sizeof(USHORT)) if (t->DataSize == sizeof(USHORT))
{ {
USHORT value = READ_USHORT(t->Data); USHORT value = READ_USHORT(t->Data);
if (!isAccepted) if (isAccepted == false)
{ {
if (pp->Lcp->Code != PPP_LCP_CODE_NAK) if (pp->Lcp->Code != PPP_LCP_CODE_NAK)
{ {
@ -890,7 +907,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
{ {
PPP_LCP *lcp = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *lcp = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
Add(lcp->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &value, sizeof(USHORT))); Add(lcp->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &value, sizeof(USHORT)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -925,7 +942,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_EAP)) if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_EAP))
{ {
// Try to request MS-CHAPv2 then // Try to request MS-CHAPv2 then
if (!isAccepted) if (isAccepted == false)
{ {
UINT64 offer = 0; UINT64 offer = 0;
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
@ -938,7 +955,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer); Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer);
Debug("Request MSCHAPv2\n"); Debug("Request MSCHAPv2\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -955,7 +972,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
else if (opt->DataSize == sizeof(ms_chap_v2_code) && Cmp(opt->Data, ms_chap_v2_code, opt->DataSize) == 0) else if (opt->DataSize == sizeof(ms_chap_v2_code) && Cmp(opt->Data, ms_chap_v2_code, opt->DataSize) == 0)
{ {
// Try to request PAP then // Try to request PAP then
if (!isAccepted || !p->EnableMSCHAPv2) if (isAccepted == false || p->EnableMSCHAPv2 == false)
{ {
UINT64 offer = 0; UINT64 offer = 0;
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
@ -964,7 +981,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer); Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer);
Debug("Request PAP\n"); Debug("Request PAP\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &proto, sizeof(USHORT))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &proto, sizeof(USHORT)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -982,7 +999,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
else if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_PAP)) else if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_PAP))
{ {
// We couldn't agree on auth proto, failing connection // We couldn't agree on auth proto, failing connection
if (!isAccepted) if (isAccepted == false)
{ {
UINT64 offer = 0; UINT64 offer = 0;
Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize); Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize);
@ -1009,19 +1026,23 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
// Process CHAP responses // Process CHAP responses
bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
{
return PPPProcessCHAPResponsePacketEx(p, pp, req, pp->Lcp, false);
}
bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req, PPP_LCP *chap, bool use_eap)
{ {
PPP_LCP *lcp; PPP_LCP *lcp;
if (pp->Lcp->Code == PPP_CHAP_CODE_RESPONSE) if (chap->Code == PPP_CHAP_CODE_RESPONSE)
{ {
bool ok = false; bool ok = false;
if (p->PPPStatus != PPP_STATUS_AUTHENTICATING && !p->AuthOk) if (p->PPPStatus != PPP_STATUS_AUTHENTICATING && p->AuthOk == false)
{ {
Debug("Receiving CHAP response packets outside of auth status, some errors probably!"); Debug("Receiving CHAP response packets outside of auth status, some errors probably!");
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
return false; return false;
} }
if (p->AuthProtocol != PPP_PROTOCOL_CHAP) if (p->AuthProtocol != PPP_PROTOCOL_CHAP && use_eap == false)
{ {
Debug("Receiving CHAP packet when auth protocol set to 0x%x\n", p->AuthProtocol); Debug("Receiving CHAP packet when auth protocol set to 0x%x\n", p->AuthProtocol);
PPPLog(p, "LP_NEXT_PROTOCOL_IS_NOT_PAP", pp->Protocol); PPPLog(p, "LP_NEXT_PROTOCOL_IS_NOT_PAP", pp->Protocol);
@ -1029,13 +1050,13 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
return false; return false;
} }
ok = PPPParseMSCHAP2ResponsePacket(p, pp); ok = PPPParseMSCHAP2ResponsePacketEx(p, chap, use_eap);
// If we got only first packet of double CHAP then send second challenge // If we got only first packet of double CHAP then send second challenge
if (ok && p->MsChapV2_UseDoubleMsChapV2 && p->EapClient != NULL && p->Ipc == NULL) if (ok && p->MsChapV2_UseDoubleMsChapV2 && p->EapClient != NULL && p->Ipc == NULL)
{ {
lcp = BuildMSCHAP2ChallengePacket(p); lcp = BuildMSCHAP2ChallengePacket(p);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1048,7 +1069,6 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
char hex[MAX_SIZE]; char hex[MAX_SIZE];
char ret_str[MAX_SIZE]; char ret_str[MAX_SIZE];
BUF *lcp_ret_data = NewBuf(); BUF *lcp_ret_data = NewBuf();
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
BinToStr(hex, sizeof(hex), p->MsChapV2_ServerResponse, 20); BinToStr(hex, sizeof(hex), p->MsChapV2_ServerResponse, 20);
Format(ret_str, sizeof(ret_str), Format(ret_str, sizeof(ret_str),
@ -1065,19 +1085,39 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
FreeBuf(lcp_ret_data); FreeBuf(lcp_ret_data);
} }
res->Lcp = lcp; if (use_eap == false)
res->IsControl = true;
res->Protocol = PPP_PROTOCOL_CHAP;
if (!PPPSendPacketAndFree(p, res))
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
WHERE; res->Lcp = lcp;
return false; res->IsControl = true;
res->Protocol = PPP_PROTOCOL_CHAP;
if (PPPSendPacketAndFree(p, res) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
}
else
{
BUF *b = BuildLCPData(lcp);
p->Eap_PacketId = p->NextId++;
lcp = BuildEAPPacketEx(PPP_EAP_CODE_REQUEST, p->Eap_PacketId, PPP_EAP_TYPE_MSCHAPV2, b->Size);
PPP_EAP *eapPacket = lcp->Data;
Copy(eapPacket->Data, b->Buf, b->Size);
Free(b);
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
} }
p->AuthOk = true; p->AuthOk = true;
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
} }
// We failed MSCHAPv2 auth // We failed MSCHAPv2 auth
else else
@ -1085,7 +1125,6 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
char hex[MAX_SIZE]; char hex[MAX_SIZE];
char ret_str[MAX_SIZE]; char ret_str[MAX_SIZE];
BUF *lcp_ret_data = NewBuf(); BUF *lcp_ret_data = NewBuf();
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
BinToStr(hex, sizeof(hex), p->MsChapV2_ServerChallenge, 16); BinToStr(hex, sizeof(hex), p->MsChapV2_ServerChallenge, 16);
@ -1103,19 +1142,39 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
FreeBuf(lcp_ret_data); FreeBuf(lcp_ret_data);
} }
res->Lcp = lcp; if (use_eap == false)
res->IsControl = true;
res->Protocol = PPP_PROTOCOL_CHAP;
if (!PPPSendPacketAndFree(p, res))
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
WHERE; res->Lcp = lcp;
return false; res->IsControl = true;
res->Protocol = PPP_PROTOCOL_CHAP;
if (PPPSendPacketAndFree(p, res) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
}
else
{
BUF *b = BuildLCPData(lcp);
p->Eap_PacketId = p->NextId++;
lcp = BuildEAPPacketEx(PPP_EAP_CODE_REQUEST, p->Eap_PacketId, PPP_EAP_TYPE_MSCHAPV2, b->Size);
PPP_EAP *eapPacket = lcp->Data;
Copy(eapPacket->Data, b->Buf, b->Size);
Free(b);
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
} }
PPPLog(p, "LP_CHAP_FAILED"); PPPLog(p, "LP_CHAP_FAILED");
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
} }
return ok; return ok;
@ -1126,7 +1185,7 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
// Process IPCP responses // Process IPCP responses
bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
{ {
bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code); bool isAccepted = PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code) == false;
IP addrStruct; IP addrStruct;
char addrStr[MAX_SIZE]; char addrStr[MAX_SIZE];
@ -1137,7 +1196,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
PPP_LCP *c; PPP_LCP *c;
UINT ui; UINT ui;
if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT) if (PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) == false || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT)
{ {
Debug("Unsupported IPCP protocol"); Debug("Unsupported IPCP protocol");
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED); IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
@ -1181,7 +1240,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
ui = Endian32(0xc0000008); // We always push 192.0.0.8, which is defined in RFC7600 as dummy IPv4 address. ui = Endian32(0xc0000008); // We always push 192.0.0.8, which is defined in RFC7600 as dummy IPv4 address.
Add(c->OptionList, NewPPPOption(PPP_IPCP_OPTION_IP, &ui, sizeof(UINT))); Add(c->OptionList, NewPPPOption(PPP_IPCP_OPTION_IP, &ui, sizeof(UINT)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1201,6 +1260,12 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
UINT64 offer = 0; UINT64 offer = 0;
PPP_LCP *c; PPP_LCP *c;
UCHAR ms_chap_v2_code[3]; UCHAR ms_chap_v2_code[3];
ETHERIP_ID d;
char username[MAX_SIZE];
char hubname[MAX_SIZE];
HUB *hub;
bool found = false;
UINT authtype;
WRITE_USHORT(ms_chap_v2_code, PPP_LCP_AUTH_CHAP); WRITE_USHORT(ms_chap_v2_code, PPP_LCP_AUTH_CHAP);
ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2; ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2;
@ -1208,17 +1273,113 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
switch (eap_packet->Type) switch (eap_packet->Type)
{ {
case PPP_EAP_TYPE_IDENTITY: case PPP_EAP_TYPE_IDENTITY:
// Parse username
Copy(p->Eap_Identity, eap_packet->Data, MIN(MAX_SIZE, eap_datasize)); Copy(p->Eap_Identity, eap_packet->Data, MIN(MAX_SIZE, eap_datasize));
// As we received the identity packet, we switch back to BEFORE_AUTH and switch to the EAP_TLS proto to send the TlsStart packet on the next tick Zero(&d, sizeof(d));
p->Eap_Protocol = PPP_EAP_TYPE_TLS; PPPParseUsername(p->Cedar, p->Eap_Identity, &d);
PPPSetStatus(p, PPP_STATUS_BEFORE_AUTH); StrCpy(username, sizeof(username), d.UserName);
StrCpy(hubname, sizeof(hubname), d.HubName);
Debug("EAP: username=%s, hubname=%s\n", username, hubname);
// Locate user
LockHubList(p->Cedar);
{
hub = GetHub(p->Cedar, hubname);
}
UnlockHubList(p->Cedar);
if (hub != NULL)
{
AcLock(hub);
{
USER *user = AcGetUser(hub, username);
if (user == NULL)
{
user = AcGetUser(hub, "*");
}
if (user != NULL)
{
found = true;
authtype = user->AuthType;
ReleaseUser(user);
}
}
AcUnlock(hub);
ReleaseHub(hub);
}
if (found == false)
{
// User not found, fail immediately
PPP_PACKET *pack = ZeroMalloc(sizeof(PPP_PACKET));
pack->IsControl = true;
pack->Protocol = PPP_PROTOCOL_EAP;
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, p->Eap_PacketId);
if (PPPSendPacketAndFree(p, pack) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
break;
}
// Select EAP method based on auth type
switch (authtype)
{
case AUTHTYPE_RADIUS:
// Create EAP client if needed
if (p->MsChapV2_UseDoubleMsChapV2 && p->EapClient == NULL)
{
char client_ip_tmp[256];
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
Debug("EAP-MSCHAPv2 creating EAP RADIUS client\n");
p->EapClient = HubNewEapClient(p->Cedar, hubname, client_ip_tmp, username, "L3:PPP");
if (p->EapClient == NULL)
{
PPP_PACKET *pack = ZeroMalloc(sizeof(PPP_PACKET));
pack->IsControl = true;
pack->Protocol = PPP_PROTOCOL_EAP;
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, p->Eap_PacketId);
if (PPPSendPacketAndFree(p, pack) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
break;
}
}
case AUTHTYPE_ANONYMOUS:
case AUTHTYPE_PASSWORD:
case AUTHTYPE_NT:
// Propose EAP-MSCHAPv2 directly
p->Eap_Protocol = PPP_EAP_TYPE_MSCHAPV2;
PPPSetStatus(p, PPP_STATUS_BEFORE_AUTH);
break;
default:
// Propose EAP-TLS first
p->Eap_Protocol = PPP_EAP_TYPE_TLS;
PPPSetStatus(p, PPP_STATUS_BEFORE_AUTH);
break;
}
break; break;
case PPP_EAP_TYPE_NOTIFICATION: case PPP_EAP_TYPE_NOTIFICATION:
// Basically this is just an acknoweldgment that the notification was accepted by the client. Nothing to do here... // Basically this is just an acknoweldgment that the notification was accepted by the client. Nothing to do here...
break; break;
case PPP_EAP_TYPE_NAK: case PPP_EAP_TYPE_NAK:
/// TODO: implement alternative EAP protocol selection based on received NAK if (p->Eap_Protocol == PPP_EAP_TYPE_TLS)
// For now just fallback to auth protocol selection to try to select MSCHAP or PAP {
// Propose EAP-MSCHAPv2
p->Eap_Protocol = PPP_EAP_TYPE_MSCHAPV2;
PPPSetStatus(p, PPP_STATUS_BEFORE_AUTH);
break;
}
// Fallback to auth protocol selection to try to select MSCHAP or PAP
Debug("Got a EAP_NAK, abandoning EAP protocol\n"); Debug("Got a EAP_NAK, abandoning EAP protocol\n");
PPPRejectUnsupportedPacketEx(p, pp, true); PPPRejectUnsupportedPacketEx(p, pp, true);
PPPSetStatus(p, PPP_STATUS_CONNECTED); PPPSetStatus(p, PPP_STATUS_CONNECTED);
@ -1227,7 +1388,7 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
Copy(&offer, ms_chap_v2_code, sizeof(ms_chap_v2_code)); Copy(&offer, ms_chap_v2_code, sizeof(ms_chap_v2_code));
Debug("Request MSCHAPv2 from EAP NAK\n"); Debug("Request MSCHAPv2 from EAP NAK\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1237,6 +1398,52 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
case PPP_EAP_TYPE_TLS: case PPP_EAP_TYPE_TLS:
PPPProcessEAPTlsResponse(p, eap_packet, eap_datasize); PPPProcessEAPTlsResponse(p, eap_packet, eap_datasize);
break; break;
case PPP_EAP_TYPE_MSCHAPV2:
if (p->PPPStatus != PPP_STATUS_AUTHENTICATING)
{
Debug("Received EAP-MSCHAPv2 response not during authentication\n");
break;
}
if (eap_datasize == 1)
{
// Success or failure response
PPP_PACKET *pack = ZeroMalloc(sizeof(PPP_PACKET));
pack->IsControl = true;
pack->Protocol = PPP_PROTOCOL_EAP;
if (p->AuthOk)
{
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_SUCCESS, p->Eap_PacketId);
}
else
{
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, p->Eap_PacketId);
}
if (PPPSendPacketAndFree(p, pack) == false)
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
}
else
{
// CHAP response
PPP_LCP *chap = PPPParseLCP(PPP_PROTOCOL_CHAP, eap_packet->Data, eap_datasize);
if (chap == NULL)
{
Debug("Received an invalid EAP-MSCHAPv2 packet\n");
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
PPPProcessCHAPResponsePacketEx(p, pp, req, chap, true);
FreePPPLCP(chap);
}
break;
default: default:
Debug("We got an unexpected EAP response packet! Ignoring...\n"); Debug("We got an unexpected EAP response packet! Ignoring...\n");
break; break;
@ -1253,7 +1460,7 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
{ {
p->Eap_PacketId = p->NextId++; p->Eap_PacketId = p->NextId++;
PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE); PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1267,10 +1474,10 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
// Process IPv6CP responses // Process IPv6CP responses
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req) bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
{ {
bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code); bool isAccepted = PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code) == false;
// If we got a reject or a NACK, we just reject the whole IPv6 configuration, there is no way we can recover even from a NACK as we can't change the link-local address of an already existing router // If we got a reject or a NACK, we just reject the whole IPv6 configuration, there is no way we can recover even from a NACK as we can't change the link-local address of an already existing router
if (!isAccepted) if (isAccepted == false)
{ {
Debug("Unsupported IPv6CP protocol"); Debug("Unsupported IPv6CP protocol");
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED); IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED);
@ -1417,7 +1624,7 @@ bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
return false; return false;
} }
if (!PPPAckLCPOptions(p, pp)) if (PPPAckLCPOptions(p, pp) == false)
{ {
return false; return false;
} }
@ -1441,7 +1648,7 @@ bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
if (p->PPPStatus != PPP_STATUS_BEFORE_AUTH && !p->AuthOk) if (p->PPPStatus != PPP_STATUS_BEFORE_AUTH && p->AuthOk == false)
{ {
PPP_LCP *lcp = NewPPPLCP(PPP_PAP_CODE_NAK, pp->Lcp->Id); PPP_LCP *lcp = NewPPPLCP(PPP_PAP_CODE_NAK, pp->Lcp->Id);
PPP_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET)); PPP_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET));
@ -1451,7 +1658,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
ret->IsControl = true; ret->IsControl = true;
ret->Protocol = PPP_PROTOCOL_PAP; ret->Protocol = PPP_PROTOCOL_PAP;
ret->Lcp = lcp; ret->Lcp = lcp;
if (!PPPSendPacketAndFree(p, ret)) if (PPPSendPacketAndFree(p, ret) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1470,7 +1677,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
return false; return false;
} }
if (!p->AuthOk) if (p->AuthOk == false)
{ {
UCHAR *data; UCHAR *data;
UINT size; UINT size;
@ -1581,7 +1788,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
ret->IsControl = true; ret->IsControl = true;
ret->Protocol = PPP_PROTOCOL_PAP; ret->Protocol = PPP_PROTOCOL_PAP;
ret->Lcp = lcp; ret->Lcp = lcp;
if (!PPPSendPacketAndFree(p, ret)) if (PPPSendPacketAndFree(p, ret) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1594,14 +1801,14 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
} }
return true; return true;
} }
if (!p->AuthOk) if (p->AuthOk == false)
{ {
PPP_LCP *lcp = NewPPPLCP(PPP_PAP_CODE_NAK, pp->Lcp->Id); PPP_LCP *lcp = NewPPPLCP(PPP_PAP_CODE_NAK, pp->Lcp->Id);
PPP_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET)); PPP_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET));
ret->IsControl = true; ret->IsControl = true;
ret->Protocol = PPP_PROTOCOL_PAP; ret->Protocol = PPP_PROTOCOL_PAP;
ret->Lcp = lcp; ret->Lcp = lcp;
if (!PPPSendPacketAndFree(p, ret)) if (PPPSendPacketAndFree(p, ret) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -1641,7 +1848,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
return PPPRejectUnsupportedPacketEx(p, pp, true); return PPPRejectUnsupportedPacketEx(p, pp, true);
} }
if (!PPPGetIPOptionFromLCP(&o, pp->Lcp)) if (PPPGetIPOptionFromLCP(&o, pp->Lcp) == false)
{ {
Debug("IPCP request without client IP address received! Treating as zeroed out client IP...\n"); Debug("IPCP request without client IP address received! Treating as zeroed out client IP...\n");
isEmptyIpAddress = true; isEmptyIpAddress = true;
@ -1914,14 +2121,14 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
UINT ui = p->ClientAddressOption.ServerAddress; UINT ui = p->ClientAddressOption.ServerAddress;
Add(c->OptionList, NewPPPOption(PPP_IPCP_OPTION_IP, &ui, sizeof(UINT))); Add(c->OptionList, NewPPPOption(PPP_IPCP_OPTION_IP, &ui, sizeof(UINT)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
return false; return false;
} }
IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG); IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG);
if (!processed) if (processed == false)
{ {
PPPAddNextPacket(p, pp, 1); PPPAddNextPacket(p, pp, 1);
} }
@ -1930,14 +2137,14 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
// We still haven't received any answer from client about server IP, keep waiting... // We still haven't received any answer from client about server IP, keep waiting...
if ((IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG || if ((IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG ||
IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED) && !processed) IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED) && processed == false)
{ {
PPPAddNextPacket(p, pp, 1); PPPAddNextPacket(p, pp, 1);
return false; return false;
} }
//Debug("PPPAckLCPOptionsEx ok=%x, processed=%x", ok, processed); //Debug("PPPAckLCPOptionsEx ok=%x, processed=%x", ok, processed);
if (!ok || !PPPAckLCPOptionsEx(p, pp, processed)) if (ok == false || PPPAckLCPOptionsEx(p, pp, processed) == false)
{ {
return false; return false;
} }
@ -1981,7 +2188,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
UINT64 newValue = 0; UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data); UINT64 value = READ_UINT64(t->Data);
if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) if (value != 0 && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false)
{ {
t->IsAccepted = true; t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value; p->Ipc->IPv6ClientEUI = value;
@ -1990,7 +2197,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
t->IsAccepted = false; t->IsAccepted = false;
GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress); GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress);
if (newValue != value && !IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue)) if (newValue != value && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
{ {
WRITE_UINT64(t->AltData, newValue); WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64); t->AltDataSize = sizeof(UINT64);
@ -2000,7 +2207,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
while (true) while (true)
{ {
newValue = Rand64(); newValue = Rand64();
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue)) if (IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
{ {
WRITE_UINT64(t->AltData, newValue); WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64); t->AltDataSize = sizeof(UINT64);
@ -2037,7 +2244,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64))); Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64)));
} }
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -2047,13 +2254,13 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG); IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG);
} }
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG && !processed) if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG && processed == false)
{ {
PPPAddNextPacket(p, pp, 1); PPPAddNextPacket(p, pp, 1);
return false; return false;
} }
if (!PPPAckLCPOptionsEx(p, pp, processed)) if (PPPAckLCPOptionsEx(p, pp, processed) == false)
{ {
return false; return false;
} }
@ -2257,7 +2464,7 @@ bool PPPSendAndRetransmitRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c)
} }
// Send the PPP packet // Send the PPP packet
if (!PPPSendPacketEx(p, pp, false)) if (PPPSendPacketEx(p, pp, false) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -2688,6 +2895,15 @@ PPP_LCP *PPPParseLCP(USHORT protocol, void *data, UINT size)
goto LABEL_ERROR; goto LABEL_ERROR;
} }
len = READ_USHORT(buf); len = READ_USHORT(buf);
// Fix bad endianness
if (len > size)
{
USHORT len1 = Swap16(len);
if (len1 <= size)
{
len = len1;
}
}
if (len < 4) if (len < 4)
{ {
goto LABEL_ERROR; goto LABEL_ERROR;
@ -2763,6 +2979,10 @@ LABEL_ERROR:
// Analyse MS CHAP v2 Response packet // Analyse MS CHAP v2 Response packet
bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp) bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
{
return PPPParseMSCHAP2ResponsePacketEx(p, pp->Lcp, false);
}
bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp, bool use_eap)
{ {
bool ok = false; bool ok = false;
@ -2785,18 +3005,18 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
UINT error_code; UINT error_code;
UINT64 eap_client_ptr = (UINT64)p->EapClient; UINT64 eap_client_ptr = (UINT64)p->EapClient;
if (pp->Lcp != NULL && pp->Lcp->DataSize >= 51) if (lcp != NULL && lcp->DataSize >= 51)
{ {
BUF *b; BUF *b;
if (pp->Lcp->Id != p->MsChapV2_PacketId) if (lcp->Id != p->MsChapV2_PacketId)
{ {
Debug("Got incorrect LCP PacketId! Should be 0x%x, got 0x%x\n", p->MsChapV2_PacketId, pp->Lcp->Id); Debug("Got incorrect LCP PacketId! Should be 0x%x, got 0x%x\n", p->MsChapV2_PacketId, lcp->Id);
p->MsChapV2_PacketId = pp->Lcp->Id; p->MsChapV2_PacketId = lcp->Id;
} }
b = NewBuf(); b = NewBuf();
WriteBuf(b, pp->Lcp->Data, pp->Lcp->DataSize); WriteBuf(b, lcp->Data, lcp->DataSize);
SeekBuf(b, 0, 0); SeekBuf(b, 0, 0);
if (ReadBufChar(b) == 49) if (ReadBufChar(b) == 49)
@ -2844,24 +3064,23 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
client_response_hex, client_response_hex,
eap_client_hex); eap_client_hex);
if (p->MsChapV2_UseDoubleMsChapV2 && p->EapClient == NULL) // Normal MSCHAPv2 only
// For EAP-MSCHAPv2, EAP client is created before sending the challenge
if (p->MsChapV2_UseDoubleMsChapV2 && p->EapClient == NULL && use_eap == false)
{ {
Debug("Double MSCHAPv2 creating EAP client\n"); Debug("Double MSCHAPv2 creating EAP client\n");
eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id, "L3:PPP"); eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id, "L3:PPP");
// We do not know the user's auth type, so do not fail PPP if eap is null
if (eap) if (eap)
{ {
ok = true; ok = true;
p->EapClient = eap; p->EapClient = eap;
} FreeBuf(b);
else return ok;
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
} }
} }
else if (p->Ipc == NULL) if (p->Ipc == NULL)
{ {
Debug("MSCHAPv2 creating IPC\n"); Debug("MSCHAPv2 creating IPC\n");
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
@ -3233,7 +3452,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize); Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize);
p->Eap_TlsCtx.CachedBufferSendPntr += (UINT64)dataSize; p->Eap_TlsCtx.CachedBufferSendPntr += (UINT64)dataSize;
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3308,7 +3527,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
lcp = NewPPPLCP(PPP_EAP_CODE_SUCCESS, identificator); lcp = NewPPPLCP(PPP_EAP_CODE_SUCCESS, identificator);
pack->Lcp = lcp; pack->Lcp = lcp;
Debug("Sent EAP-TLS size=%i SUCCESS\n", lcp->DataSize); Debug("Sent EAP-TLS size=%i SUCCESS\n", lcp->DataSize);
if (!PPPSendPacketAndFree(p, pack)) if (PPPSendPacketAndFree(p, pack) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3329,7 +3548,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, identificator); lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, identificator);
pack->Lcp = lcp; pack->Lcp = lcp;
Debug("Sent EAP-TLS size=%i FAILURE\n", lcp->DataSize); Debug("Sent EAP-TLS size=%i FAILURE\n", lcp->DataSize);
if (!PPPSendPacketAndFree(p, pack)) if (PPPSendPacketAndFree(p, pack) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3345,7 +3564,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
p->Eap_PacketId = p->NextId++; p->Eap_PacketId = p->NextId++;
lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags); lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags);
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING); PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3423,7 +3642,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
{ {
p->Eap_PacketId = p->NextId++; p->Eap_PacketId = p->NextId++;
PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE); PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3474,7 +3693,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
eap->Tls.TlsDataWithLength.TlsLength = Endian32(tlsLength); eap->Tls.TlsDataWithLength.TlsLength = Endian32(tlsLength);
Copy(eap->Tls.TlsDataWithLength.Data, p->Eap_TlsCtx.CachedBufferSend, dataSize); Copy(eap->Tls.TlsDataWithLength.Data, p->Eap_TlsCtx.CachedBufferSend, dataSize);
p->Eap_TlsCtx.CachedBufferSendPntr += dataSize; p->Eap_TlsCtx.CachedBufferSendPntr += dataSize;
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3488,7 +3707,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, 0); lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, 0);
eap = lcp->Data; eap = lcp->Data;
ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, &(eap->Tls.TlsDataWithoutLength), dataSize); ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, &(eap->Tls.TlsDataWithoutLength), dataSize);
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE; WHERE;
@ -3591,7 +3810,7 @@ void PPPSetStatus(PPP_SESSION *p, UINT status)
{ {
Debug("SETTING PPP_STATUS_FAIL!!!\n"); Debug("SETTING PPP_STATUS_FAIL!!!\n");
} }
if (!PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) || PPP_STATUS_IS_UNAVAILABLE(status)) if (PPP_STATUS_IS_UNAVAILABLE(p->PPPStatus) == false || PPP_STATUS_IS_UNAVAILABLE(status))
{ {
p->PPPStatus = status; p->PPPStatus = status;
} }

View File

@ -111,6 +111,7 @@
#define PPP_EAP_TYPE_NOTIFICATION 2 #define PPP_EAP_TYPE_NOTIFICATION 2
#define PPP_EAP_TYPE_NAK 3 #define PPP_EAP_TYPE_NAK 3
#define PPP_EAP_TYPE_TLS 13 #define PPP_EAP_TYPE_TLS 13
#define PPP_EAP_TYPE_MSCHAPV2 26
// EAP-TLS Flags // EAP-TLS Flags
#define PPP_EAP_TLS_FLAG_NONE 0 #define PPP_EAP_TLS_FLAG_NONE 0
@ -334,6 +335,7 @@ bool PPPSendEchoRequest(PPP_SESSION *p);
bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req, PPP_LCP *chap, bool use_eap);
bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
@ -373,7 +375,8 @@ PPP_OPTION *NewPPPOption(UCHAR type, void *data, UINT size);
// Packet parse utilities // Packet parse utilities
PPP_PACKET *ParsePPPPacket(void *data, UINT size); PPP_PACKET *ParsePPPPacket(void *data, UINT size);
PPP_LCP *PPPParseLCP(USHORT protocol, void *data, UINT size); PPP_LCP *PPPParseLCP(USHORT protocol, void *data, UINT size);
bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *req); bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp, bool use_eap);
// Packet building utilities // Packet building utilities
BUF *BuildPPPPacketData(PPP_PACKET *pp); BUF *BuildPPPPacketData(PPP_PACKET *pp);
BUF *BuildLCPData(PPP_LCP *c); BUF *BuildLCPData(PPP_LCP *c);

View File

@ -1069,7 +1069,8 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r)
is_finish = true; is_finish = true;
Free(rp->Parse_EapMessage); Free(rp->Parse_EapMessage);
rp->Parse_EapMessage = Clone(e->PEAP_CurrentReceivingMsg->Buf, e->PEAP_CurrentReceivingMsg->Size); rp->Parse_EapMessage = ZeroMalloc(sizeof(EAP_MESSAGE));
Copy(rp->Parse_EapMessage, e->PEAP_CurrentReceivingMsg->Buf, e->PEAP_CurrentReceivingMsg->Size);
rp->Parse_EapMessage_DataSize = e->PEAP_CurrentReceivingMsg->Size; rp->Parse_EapMessage_DataSize = e->PEAP_CurrentReceivingMsg->Size;
} }
} }
@ -1508,7 +1509,8 @@ RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size)
{ {
if (p->Parse_EapMessage == NULL) if (p->Parse_EapMessage == NULL)
{ {
EAP_MESSAGE *eap = Clone(a.Data, a.DataSize); EAP_MESSAGE *eap = ZeroMalloc(sizeof(EAP_MESSAGE));
Copy(eap, a.Data, a.DataSize);
p->Parse_EapMessage_DataSize = sz_tmp; p->Parse_EapMessage_DataSize = sz_tmp;
@ -1603,7 +1605,8 @@ RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size)
p->Parse_EapMessage_DataSize = b->Size; p->Parse_EapMessage_DataSize = b->Size;
p->Parse_EapMessage_DataSize = MIN(p->Parse_EapMessage_DataSize, 1500); p->Parse_EapMessage_DataSize = MIN(p->Parse_EapMessage_DataSize, 1500);
p->Parse_EapMessage = Clone(b->Buf, p->Parse_EapMessage_DataSize); p->Parse_EapMessage = ZeroMalloc(sizeof(EAP_MESSAGE));
Copy(p->Parse_EapMessage, b->Buf, p->Parse_EapMessage_DataSize);
} }
FreeBuf(b); FreeBuf(b);