diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c index 1843ed94..ee3eb88d 100644 --- a/src/Cedar/Proto_PPP.c +++ b/src/Cedar/Proto_PPP.c @@ -86,9 +86,9 @@ void PPPThread(THREAD *thread, void *param) receivedPacketProcessed = PPPRejectUnsupportedPacket(p, p->CurrentPacket); // 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 PPP_PACKET *pp2 = ZeroMalloc(sizeof(PPP_PACKET)); @@ -107,17 +107,17 @@ void PPPThread(THREAD *thread, void *param) 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; // 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; // 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; // Ignore the Identification packet @@ -155,7 +155,7 @@ void PPPThread(THREAD *thread, void *param) } // 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; // Removing from resend list @@ -177,14 +177,14 @@ void PPPThread(THREAD *thread, void *param) } // 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); receivedPacketProcessed = true; } // 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(); 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); } @@ -260,7 +260,24 @@ void PPPThread(THREAD *thread, void *param) p->Eap_PacketId = p->NextId++; lcpEap = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags); 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); WHERE; @@ -275,7 +292,7 @@ void PPPThread(THREAD *thread, void *param) eapPacket = lcpEap->Data; Copy(eapPacket->Data, welcomeMessage, StrLen(welcomeMessage)); 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; @@ -291,7 +308,7 @@ void PPPThread(THREAD *thread, void *param) Debug("Starting PPP Authentication phase MS-CHAP v2\n"); lcp = BuildMSCHAP2ChallengePacket(p); - if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp)) + if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -300,7 +317,7 @@ void PPPThread(THREAD *thread, void *param) PPPSetStatus(p, PPP_STATUS_AUTHENTICATING); } - if (p->PPPStatus == PPP_STATUS_CONNECTED && !authReqSent) + if (p->PPPStatus == PPP_STATUS_CONNECTED && authReqSent == false) { // EAP code PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); @@ -308,7 +325,7 @@ void PPPThread(THREAD *thread, void *param) Debug("Request EAP\n"); 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); WHERE; @@ -444,14 +461,14 @@ void PPPThread(THREAD *thread, void *param) Debug("Trying to cleanly close the connection, status = 0x%x\n", p->PPPStatus); PPPSetStatus(p, PPP_STATUS_CLOSING_WAIT); 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); 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); PPPSendEchoRequest(p); @@ -681,7 +698,7 @@ bool PPPRejectUnsupportedPacketEx(PPP_SESSION *p, PPP_PACKET *pp, bool force) FreeBuf(buf); - if (!PPPSendPacketAndFree(p, pp2)) + if (PPPSendPacketAndFree(p, pp2) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -721,7 +738,7 @@ bool PPPProcessRetransmissions(PPP_SESSION *p) else if (t->ResendTime <= now) { 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); WHERE; @@ -762,7 +779,7 @@ bool PPPSendEchoRequest(PPP_SESSION *p) pp->Lcp->Data = Clone(echo_data, sizeof(echo_data)); pp->Lcp->DataSize = sizeof(echo_data); - if (!PPPSendPacketAndFree(p, pp)) + if (PPPSendPacketAndFree(p, pp) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); 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) { 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; // MSCHAPv2 code 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; // 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 // 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); WHERE; @@ -872,7 +889,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req if (t->DataSize == sizeof(USHORT)) { USHORT value = READ_USHORT(t->Data); - if (!isAccepted) + if (isAccepted == false) { 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); 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); 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)) { // Try to request MS-CHAPv2 then - if (!isAccepted) + if (isAccepted == false) { UINT64 offer = 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("Request MSCHAPv2\n"); 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); 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) { // Try to request PAP then - if (!isAccepted || !p->EnableMSCHAPv2) + if (isAccepted == false || p->EnableMSCHAPv2 == false) { UINT64 offer = 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("Request PAP\n"); 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); 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)) { // We couldn't agree on auth proto, failing connection - if (!isAccepted) + if (isAccepted == false) { UINT64 offer = 0; 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 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; - if (pp->Lcp->Code == PPP_CHAP_CODE_RESPONSE) + if (chap->Code == PPP_CHAP_CODE_RESPONSE) { 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!"); PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; 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); 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; } - ok = PPPParseMSCHAP2ResponsePacket(p, pp); + ok = PPPParseMSCHAP2ResponsePacketEx(p, chap, use_eap); // If we got only first packet of double CHAP then send second challenge if (ok && p->MsChapV2_UseDoubleMsChapV2 && p->EapClient != NULL && p->Ipc == NULL) { lcp = BuildMSCHAP2ChallengePacket(p); - if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp)) + if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -1048,7 +1069,6 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re char hex[MAX_SIZE]; char ret_str[MAX_SIZE]; BUF *lcp_ret_data = NewBuf(); - PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET)); BinToStr(hex, sizeof(hex), p->MsChapV2_ServerResponse, 20); 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); } - res->Lcp = lcp; - res->IsControl = true; - res->Protocol = PPP_PROTOCOL_CHAP; - - if (!PPPSendPacketAndFree(p, res)) + if (use_eap == false) { - PPPSetStatus(p, PPP_STATUS_FAIL); - WHERE; - return false; + PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET)); + res->Lcp = lcp; + 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; - PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS); } // We failed MSCHAPv2 auth else @@ -1085,7 +1125,6 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re char hex[MAX_SIZE]; char ret_str[MAX_SIZE]; BUF *lcp_ret_data = NewBuf(); - PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET)); 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); } - res->Lcp = lcp; - res->IsControl = true; - res->Protocol = PPP_PROTOCOL_CHAP; - - if (!PPPSendPacketAndFree(p, res)) + if (use_eap == false) { - PPPSetStatus(p, PPP_STATUS_FAIL); - WHERE; - return false; + PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET)); + res->Lcp = lcp; + 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"); - PPPSetStatus(p, PPP_STATUS_AUTH_FAIL); } return ok; @@ -1126,7 +1185,7 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re // Process IPCP responses 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; char addrStr[MAX_SIZE]; @@ -1137,7 +1196,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re PPP_LCP *c; 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"); 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); 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))); - if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c)) + if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPCP, c) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -1201,6 +1260,12 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req UINT64 offer = 0; PPP_LCP *c; 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); 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) { case PPP_EAP_TYPE_IDENTITY: + // Parse username 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 - p->Eap_Protocol = PPP_EAP_TYPE_TLS; - PPPSetStatus(p, PPP_STATUS_BEFORE_AUTH); + Zero(&d, sizeof(d)); + PPPParseUsername(p->Cedar, p->Eap_Identity, &d); + 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; case PPP_EAP_TYPE_NOTIFICATION: // Basically this is just an acknoweldgment that the notification was accepted by the client. Nothing to do here... break; case PPP_EAP_TYPE_NAK: - /// TODO: implement alternative EAP protocol selection based on received NAK - // For now just fallback to auth protocol selection to try to select MSCHAP or PAP + if (p->Eap_Protocol == PPP_EAP_TYPE_TLS) + { + // 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"); PPPRejectUnsupportedPacketEx(p, pp, true); 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)); Debug("Request MSCHAPv2 from EAP NAK\n"); 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); WHERE; @@ -1237,6 +1398,52 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req case PPP_EAP_TYPE_TLS: PPPProcessEAPTlsResponse(p, eap_packet, eap_datasize); 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: Debug("We got an unexpected EAP response packet! Ignoring...\n"); break; @@ -1253,7 +1460,7 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req { p->Eap_PacketId = p->NextId++; 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); WHERE; @@ -1267,10 +1474,10 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req // Process IPv6CP responses 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 (!isAccepted) + if (isAccepted == false) { Debug("Unsupported IPv6CP protocol"); 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; } - if (!PPPAckLCPOptions(p, pp)) + if (PPPAckLCPOptions(p, pp) == false) { return false; } @@ -1441,7 +1648,7 @@ bool PPPProcessLCPRequestPacket(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_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET)); @@ -1451,7 +1658,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) ret->IsControl = true; ret->Protocol = PPP_PROTOCOL_PAP; ret->Lcp = lcp; - if (!PPPSendPacketAndFree(p, ret)) + if (PPPSendPacketAndFree(p, ret) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -1470,7 +1677,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) return false; } - if (!p->AuthOk) + if (p->AuthOk == false) { UCHAR *data; UINT size; @@ -1581,7 +1788,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) ret->IsControl = true; ret->Protocol = PPP_PROTOCOL_PAP; ret->Lcp = lcp; - if (!PPPSendPacketAndFree(p, ret)) + if (PPPSendPacketAndFree(p, ret) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -1594,14 +1801,14 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) } return true; } - if (!p->AuthOk) + if (p->AuthOk == false) { PPP_LCP *lcp = NewPPPLCP(PPP_PAP_CODE_NAK, pp->Lcp->Id); PPP_PACKET *ret = ZeroMalloc(sizeof(PPP_PACKET)); ret->IsControl = true; ret->Protocol = PPP_PROTOCOL_PAP; ret->Lcp = lcp; - if (!PPPSendPacketAndFree(p, ret)) + if (PPPSendPacketAndFree(p, ret) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -1641,7 +1848,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) 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"); isEmptyIpAddress = true; @@ -1914,14 +2121,14 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); UINT ui = p->ClientAddressOption.ServerAddress; 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); WHERE; return false; } IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG); - if (!processed) + if (processed == false) { 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... 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); return false; } //Debug("PPPAckLCPOptionsEx ok=%x, processed=%x", ok, processed); - if (!ok || !PPPAckLCPOptionsEx(p, pp, processed)) + if (ok == false || PPPAckLCPOptionsEx(p, pp, processed) == false) { return false; } @@ -1981,7 +2188,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) { UINT64 newValue = 0; UINT64 value = READ_UINT64(t->Data); - if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) + if (value != 0 && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false) { t->IsAccepted = true; p->Ipc->IPv6ClientEUI = value; @@ -1990,7 +2197,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) { t->IsAccepted = false; 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); t->AltDataSize = sizeof(UINT64); @@ -2000,7 +2207,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) while (true) { newValue = Rand64(); - if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue)) + if (IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false) { WRITE_UINT64(t->AltData, newValue); 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))); } - if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c)) + if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -2047,13 +2254,13 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) 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); return false; } - if (!PPPAckLCPOptionsEx(p, pp, processed)) + if (PPPAckLCPOptionsEx(p, pp, processed) == false) { return false; } @@ -2257,7 +2464,7 @@ bool PPPSendAndRetransmitRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c) } // Send the PPP packet - if (!PPPSendPacketEx(p, pp, false)) + if (PPPSendPacketEx(p, pp, false) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -2688,6 +2895,15 @@ PPP_LCP *PPPParseLCP(USHORT protocol, void *data, UINT size) goto LABEL_ERROR; } len = READ_USHORT(buf); + // Fix bad endianness + if (len > size) + { + USHORT len1 = Swap16(len); + if (len1 <= size) + { + len = len1; + } + } if (len < 4) { goto LABEL_ERROR; @@ -2763,6 +2979,10 @@ LABEL_ERROR: // Analyse MS CHAP v2 Response packet 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; @@ -2785,18 +3005,18 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp) UINT error_code; UINT64 eap_client_ptr = (UINT64)p->EapClient; - if (pp->Lcp != NULL && pp->Lcp->DataSize >= 51) + if (lcp != NULL && lcp->DataSize >= 51) { 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); - 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 = lcp->Id; } b = NewBuf(); - WriteBuf(b, pp->Lcp->Data, pp->Lcp->DataSize); + WriteBuf(b, lcp->Data, lcp->DataSize); SeekBuf(b, 0, 0); if (ReadBufChar(b) == 49) @@ -2844,24 +3064,23 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp) client_response_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"); 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) { ok = true; p->EapClient = eap; - } - else - { - PPPSetStatus(p, PPP_STATUS_FAIL); - WHERE; - return false; + FreeBuf(b); + return ok; } } - else if (p->Ipc == NULL) + if (p->Ipc == NULL) { Debug("MSCHAPv2 creating IPC\n"); 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); 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); WHERE; @@ -3308,7 +3527,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi lcp = NewPPPLCP(PPP_EAP_CODE_SUCCESS, identificator); pack->Lcp = lcp; Debug("Sent EAP-TLS size=%i SUCCESS\n", lcp->DataSize); - if (!PPPSendPacketAndFree(p, pack)) + if (PPPSendPacketAndFree(p, pack) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -3329,7 +3548,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, identificator); pack->Lcp = lcp; Debug("Sent EAP-TLS size=%i FAILURE\n", lcp->DataSize); - if (!PPPSendPacketAndFree(p, pack)) + if (PPPSendPacketAndFree(p, pack) == false) { PPPSetStatus(p, PPP_STATUS_FAIL); WHERE; @@ -3345,7 +3564,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi p->Eap_PacketId = p->NextId++; lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags); 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); WHERE; @@ -3423,7 +3642,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi { p->Eap_PacketId = p->NextId++; 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); WHERE; @@ -3474,7 +3693,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi eap->Tls.TlsDataWithLength.TlsLength = Endian32(tlsLength); Copy(eap->Tls.TlsDataWithLength.Data, p->Eap_TlsCtx.CachedBufferSend, 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); WHERE; @@ -3488,7 +3707,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, 0); eap = lcp->Data; 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); WHERE; @@ -3591,7 +3810,7 @@ void PPPSetStatus(PPP_SESSION *p, UINT status) { 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; } diff --git a/src/Cedar/Proto_PPP.h b/src/Cedar/Proto_PPP.h index 4bca3249..c7a333f7 100644 --- a/src/Cedar/Proto_PPP.h +++ b/src/Cedar/Proto_PPP.h @@ -111,6 +111,7 @@ #define PPP_EAP_TYPE_NOTIFICATION 2 #define PPP_EAP_TYPE_NAK 3 #define PPP_EAP_TYPE_TLS 13 +#define PPP_EAP_TYPE_MSCHAPV2 26 // EAP-TLS Flags #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 PPPProcessLCPResponsePacket(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 PPPProcessEAPResponsePacket(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 PPP_PACKET *ParsePPPPacket(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 BUF *BuildPPPPacketData(PPP_PACKET *pp); BUF *BuildLCPData(PPP_LCP *c); diff --git a/src/Cedar/Radius.c b/src/Cedar/Radius.c index aa2b358e..067ea5c5 100644 --- a/src/Cedar/Radius.c +++ b/src/Cedar/Radius.c @@ -1069,7 +1069,8 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r) is_finish = true; 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; } } @@ -1508,7 +1509,8 @@ RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size) { 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; @@ -1603,7 +1605,8 @@ RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size) p->Parse_EapMessage_DataSize = b->Size; 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);