mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 01:49:53 +03:00
Improve EAP behavior with RADIUS
This commit is contained in:
parent
22a9231c33
commit
eff784b624
@ -269,7 +269,7 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
break;
|
break;
|
||||||
case PPP_EAP_TYPE_MSCHAPV2:
|
case PPP_EAP_TYPE_MSCHAPV2:
|
||||||
// Sending challenge
|
// Sending challenge
|
||||||
p->Eap_PacketId = p->NextId;
|
p->Eap_PacketId = p->NextId; // Do not increase NextId so that MSCHAPv2 could use the same id
|
||||||
lcp = BuildMSCHAP2ChallengePacket(p);
|
lcp = BuildMSCHAP2ChallengePacket(p);
|
||||||
BUF *b = BuildLCPData(lcp);
|
BUF *b = BuildLCPData(lcp);
|
||||||
lcpEap = BuildEAPPacketEx(PPP_EAP_CODE_REQUEST, p->Eap_PacketId, PPP_EAP_TYPE_MSCHAPV2, b->Size);
|
lcpEap = BuildEAPPacketEx(PPP_EAP_CODE_REQUEST, p->Eap_PacketId, PPP_EAP_TYPE_MSCHAPV2, b->Size);
|
||||||
@ -281,6 +281,7 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
{
|
{
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
WHERE;
|
WHERE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PPP_EAP_TYPE_IDENTITY:
|
case PPP_EAP_TYPE_IDENTITY:
|
||||||
@ -1030,7 +1031,7 @@ bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
|
|||||||
{
|
{
|
||||||
return PPPProcessCHAPResponsePacketEx(p, pp, req, pp->Lcp, false);
|
return PPPProcessCHAPResponsePacketEx(p, pp, req, pp->Lcp, false);
|
||||||
}
|
}
|
||||||
bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req, PPP_LCP *chap, bool eap)
|
bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req, PPP_LCP *chap, bool use_eap)
|
||||||
{
|
{
|
||||||
PPP_LCP *lcp;
|
PPP_LCP *lcp;
|
||||||
if (chap->Code == PPP_CHAP_CODE_RESPONSE)
|
if (chap->Code == PPP_CHAP_CODE_RESPONSE)
|
||||||
@ -1043,7 +1044,7 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
WHERE;
|
WHERE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (p->AuthProtocol != PPP_PROTOCOL_CHAP && !eap)
|
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);
|
||||||
@ -1051,10 +1052,10 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = PPPParseMSCHAP2ResponsePacketEx(p, chap);
|
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 && !eap)
|
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))
|
||||||
@ -1086,7 +1087,7 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
FreeBuf(lcp_ret_data);
|
FreeBuf(lcp_ret_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eap)
|
if (use_eap == false)
|
||||||
{
|
{
|
||||||
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
|
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
res->Lcp = lcp;
|
res->Lcp = lcp;
|
||||||
@ -1143,7 +1144,7 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
FreeBuf(lcp_ret_data);
|
FreeBuf(lcp_ret_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eap)
|
if (use_eap == false)
|
||||||
{
|
{
|
||||||
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
|
PPP_PACKET *res = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
res->Lcp = lcp;
|
res->Lcp = lcp;
|
||||||
@ -1261,6 +1262,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;
|
||||||
@ -1268,10 +1275,100 @@ 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)
|
||||||
|
{
|
||||||
|
// 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))
|
||||||
|
{
|
||||||
|
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...
|
||||||
@ -1331,6 +1428,7 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
{
|
{
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
WHERE;
|
WHERE;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1342,7 +1440,7 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
Debug("Received an invalid EAP-MSCHAPv2 packet\n");
|
Debug("Received an invalid EAP-MSCHAPv2 packet\n");
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
WHERE;
|
WHERE;
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
PPPProcessCHAPResponsePacketEx(p, pp, req, chap, true);
|
PPPProcessCHAPResponsePacketEx(p, pp, req, chap, true);
|
||||||
FreePPPLCP(chap);
|
FreePPPLCP(chap);
|
||||||
@ -2880,9 +2978,9 @@ 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);
|
return PPPParseMSCHAP2ResponsePacketEx(p, pp->Lcp, false);
|
||||||
}
|
}
|
||||||
bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp)
|
bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp, bool use_eap)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
@ -2964,24 +3062,23 @@ bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp)
|
|||||||
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,
|
||||||
|
@ -337,7 +337,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 eap);
|
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);
|
||||||
@ -377,8 +377,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 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user