mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Merge pull request #1775 from domosekai/radius2
Support more EAP methods for RADIUS auth
This commit is contained in:
commit
adccc6b7d4
@ -366,6 +366,7 @@
|
|||||||
#define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority
|
#define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority
|
||||||
#define AUTHTYPE_RADIUS 4 // Radius authentication
|
#define AUTHTYPE_RADIUS 4 // Radius authentication
|
||||||
#define AUTHTYPE_NT 5 // Windows NT authentication
|
#define AUTHTYPE_NT 5 // Windows NT authentication
|
||||||
|
#define AUTHTYPE_EXTERNAL 96 // External authentication (completed)
|
||||||
#define AUTHTYPE_WIREGUARD_KEY 97 // WireGuard public key authentication
|
#define AUTHTYPE_WIREGUARD_KEY 97 // WireGuard public key authentication
|
||||||
#define AUTHTYPE_OPENVPN_CERT 98 // TLS client certificate authentication
|
#define AUTHTYPE_OPENVPN_CERT 98 // TLS client certificate authentication
|
||||||
#define AUTHTYPE_TICKET 99 // Ticket authentication
|
#define AUTHTYPE_TICKET 99 // Ticket authentication
|
||||||
|
@ -91,7 +91,8 @@ UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION);
|
|||||||
|
|
||||||
|
|
||||||
// Create an EAP client for the specified Virtual Hub
|
// Create an EAP client for the specified Virtual Hub
|
||||||
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str)
|
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str, bool proxy_only,
|
||||||
|
PPP_LCP **response, UCHAR last_recv_eapid)
|
||||||
{
|
{
|
||||||
HUB *hub = NULL;
|
HUB *hub = NULL;
|
||||||
EAP_CLIENT *ret = NULL;
|
EAP_CLIENT *ret = NULL;
|
||||||
@ -137,7 +138,7 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
|
|||||||
if (GetIP(&ip, radius_servers_list->Token[i]))
|
if (GetIP(&ip, radius_servers_list->Token[i]))
|
||||||
{
|
{
|
||||||
eap = NewEapClient(&ip, radius_port, radius_secret, radius_retry_interval,
|
eap = NewEapClient(&ip, radius_port, radius_secret, radius_retry_interval,
|
||||||
RADIUS_INITIAL_EAP_TIMEOUT, client_ip_str, username, hubname);
|
RADIUS_INITIAL_EAP_TIMEOUT, client_ip_str, username, hubname, last_recv_eapid);
|
||||||
|
|
||||||
if (eap != NULL)
|
if (eap != NULL)
|
||||||
{
|
{
|
||||||
@ -146,7 +147,19 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
|
|||||||
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), vpn_protocol_state_str);
|
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), vpn_protocol_state_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_peap == false)
|
if (proxy_only && response != NULL)
|
||||||
|
{
|
||||||
|
// EAP proxy for EAP-capable clients
|
||||||
|
PPP_LCP *lcp = EapClientSendEapIdentity(eap);
|
||||||
|
if (lcp != NULL)
|
||||||
|
{
|
||||||
|
*response = lcp;
|
||||||
|
eap->GiveupTimeout = RADIUS_RETRY_TIMEOUT;
|
||||||
|
ret = eap;
|
||||||
|
finish = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (use_peap == false)
|
||||||
{
|
{
|
||||||
// EAP
|
// EAP
|
||||||
if (EapClientSendMsChapv2AuthRequest(eap))
|
if (EapClientSendMsChapv2AuthRequest(eap))
|
||||||
|
@ -537,7 +537,8 @@ bool IsUserMatchInUserList(LIST *o, char *filename, UINT64 user_hash);
|
|||||||
bool IsUserMatchInUserListWithCacheExpires(LIST *o, char *filename, UINT64 user_hash, UINT64 lifetime);
|
bool IsUserMatchInUserListWithCacheExpires(LIST *o, char *filename, UINT64 user_hash, UINT64 lifetime);
|
||||||
bool IsUserMatchInUserListWithCacheExpiresAcl(LIST *o, char *name_in_acl, UINT64 user_hash, UINT64 lifetime);
|
bool IsUserMatchInUserListWithCacheExpiresAcl(LIST *o, char *name_in_acl, UINT64 user_hash, UINT64 lifetime);
|
||||||
bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
|
bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
|
||||||
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str);
|
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str, bool proxy_only,
|
||||||
|
PPP_LCP **response, UCHAR last_recv_eapid);
|
||||||
|
|
||||||
#endif // HUB_H
|
#endif // HUB_H
|
||||||
|
|
||||||
|
@ -244,7 +244,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
|||||||
param->UserName, param->Password, param->WgKey, error_code,
|
param->UserName, param->Password, param->WgKey, error_code,
|
||||||
¶m->ClientIp, param->ClientPort, ¶m->ServerIp, param->ServerPort,
|
¶m->ClientIp, param->ClientPort, ¶m->ServerIp, param->ServerPort,
|
||||||
param->ClientHostname, param->CryptName,
|
param->ClientHostname, param->CryptName,
|
||||||
param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer);
|
param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->RadiusOK,
|
||||||
|
param->Layer);
|
||||||
|
|
||||||
return ipc;
|
return ipc;
|
||||||
}
|
}
|
||||||
@ -253,7 +254,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
|
|||||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
||||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||||
char *client_hostname, char *crypt_name,
|
char *client_hostname, char *crypt_name,
|
||||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
|
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate, bool external_auth,
|
||||||
UINT layer)
|
UINT layer)
|
||||||
{
|
{
|
||||||
IPC *ipc;
|
IPC *ipc;
|
||||||
@ -360,6 +361,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
|
|||||||
{
|
{
|
||||||
p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate);
|
p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate);
|
||||||
}
|
}
|
||||||
|
else if (external_auth)
|
||||||
|
{
|
||||||
|
p = PackLoginWithExternal(hubname, username);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = PackLoginWithPlainPassword(hubname, username, password);
|
p = PackLoginWithPlainPassword(hubname, username, password);
|
||||||
|
@ -91,6 +91,7 @@ struct IPC_PARAM
|
|||||||
UINT Mss;
|
UINT Mss;
|
||||||
bool IsL3Mode;
|
bool IsL3Mode;
|
||||||
X *ClientCertificate;
|
X *ClientCertificate;
|
||||||
|
bool RadiusOK;
|
||||||
UINT Layer;
|
UINT Layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -180,7 +181,7 @@ struct IPC_IPV6_ROUTER_ADVERTISEMENT
|
|||||||
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, char *wg_key,
|
||||||
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
|
||||||
char *client_hostname, char *crypt_name,
|
char *client_hostname, char *crypt_name,
|
||||||
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
|
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate, bool external_auth,
|
||||||
UINT layer);
|
UINT layer);
|
||||||
IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
|
IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
|
||||||
IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
|
IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
|
||||||
|
@ -75,7 +75,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
|
|||||||
&s->ClientIP, s->ClientPort,
|
&s->ClientIP, s->ClientPort,
|
||||||
&s->ServerIP, s->ServerPort,
|
&s->ServerIP, s->ServerPort,
|
||||||
tmp,
|
tmp,
|
||||||
s->CryptName, true, mss, NULL, NULL, IPC_LAYER_2);
|
s->CryptName, true, mss, NULL, NULL, false, IPC_LAYER_2);
|
||||||
|
|
||||||
if (ipc != NULL)
|
if (ipc != NULL)
|
||||||
{
|
{
|
||||||
|
@ -50,9 +50,9 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
p->SentReqPacketList = NewList(NULL);
|
p->SentReqPacketList = NewList(NULL);
|
||||||
p->DelayedPackets = NewList(PPPDelayedPacketsComparator);
|
p->DelayedPackets = NewList(PPPDelayedPacketsComparator);
|
||||||
|
|
||||||
p->MsChapV2_UseDoubleMsChapV2 = CedarIsThereAnyEapEnabledRadiusConfig(p->Cedar);
|
p->UseEapRadius = CedarIsThereAnyEapEnabledRadiusConfig(p->Cedar);
|
||||||
|
|
||||||
Debug("MsChapV2_UseDoubleMsChapV2 = 0x%x\n", p->MsChapV2_UseDoubleMsChapV2);
|
Debug("UseEapRadius = 0x%x\n", p->UseEapRadius);
|
||||||
|
|
||||||
//// Link establishment phase
|
//// Link establishment phase
|
||||||
|
|
||||||
@ -292,6 +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);
|
||||||
|
PPPFreeEapClient(p);
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap) == false)
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcpEap) == false)
|
||||||
{
|
{
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
@ -1056,7 +1057,7 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
ok = PPPParseMSCHAP2ResponsePacketEx(p, chap, use_eap);
|
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->UseEapRadius && p->EapClient != NULL && p->Ipc == NULL)
|
||||||
{
|
{
|
||||||
lcp = BuildMSCHAP2ChallengePacket(p);
|
lcp = BuildMSCHAP2ChallengePacket(p);
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false)
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_CHAP, lcp) == false)
|
||||||
@ -1273,6 +1274,12 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
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;
|
||||||
|
|
||||||
|
// Forward EAP response to Radius server
|
||||||
|
if (p->EapClient != NULL)
|
||||||
|
{
|
||||||
|
return PPPProcessEapResponseForRadius(p, eap_packet, eap_datasize);
|
||||||
|
}
|
||||||
|
|
||||||
switch (eap_packet->Type)
|
switch (eap_packet->Type)
|
||||||
{
|
{
|
||||||
case PPP_EAP_TYPE_IDENTITY:
|
case PPP_EAP_TYPE_IDENTITY:
|
||||||
@ -1339,20 +1346,23 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
{
|
{
|
||||||
case AUTHTYPE_RADIUS:
|
case AUTHTYPE_RADIUS:
|
||||||
// Create EAP client if needed
|
// Create EAP client if needed
|
||||||
if (p->MsChapV2_UseDoubleMsChapV2 && p->EapClient == NULL)
|
if (p->EapClient == NULL)
|
||||||
{
|
{
|
||||||
char client_ip_tmp[256];
|
char client_ip_tmp[256];
|
||||||
|
PPP_LCP *response = NULL;
|
||||||
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
|
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
|
||||||
Debug("EAP-MSCHAPv2 creating EAP RADIUS client\n");
|
Debug("Creating EAP RADIUS client\n");
|
||||||
p->EapClient = HubNewEapClient(p->Cedar, p->Eap_Identity.HubName, client_ip_tmp, p->Eap_Identity.UserName, "L3:PPP");
|
p->EapClient = HubNewEapClient(p->Cedar, p->Eap_Identity.HubName, client_ip_tmp, p->Eap_Identity.UserName, "L3:PPP", true,
|
||||||
|
&response, pp->Lcp->Id);
|
||||||
|
|
||||||
if (p->EapClient == NULL)
|
if (p->EapClient == NULL || response == NULL)
|
||||||
{
|
{
|
||||||
PPP_PACKET *pack = ZeroMalloc(sizeof(PPP_PACKET));
|
PPP_PACKET *pack = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
pack->IsControl = true;
|
pack->IsControl = true;
|
||||||
pack->Protocol = PPP_PROTOCOL_EAP;
|
pack->Protocol = PPP_PROTOCOL_EAP;
|
||||||
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
|
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
|
||||||
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, p->Eap_PacketId);
|
pack->Lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, p->Eap_PacketId);
|
||||||
|
Debug("Failed to connect to a RADIUS server\n");
|
||||||
|
|
||||||
if (PPPSendPacketAndFree(p, pack) == false)
|
if (PPPSendPacketAndFree(p, pack) == false)
|
||||||
{
|
{
|
||||||
@ -1360,8 +1370,19 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
WHERE;
|
WHERE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send first response to client
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, response) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case AUTHTYPE_ANONYMOUS:
|
case AUTHTYPE_ANONYMOUS:
|
||||||
case AUTHTYPE_PASSWORD:
|
case AUTHTYPE_PASSWORD:
|
||||||
@ -1505,6 +1526,84 @@ bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process EAP response for RADIUS (as proxy)
|
||||||
|
bool PPPProcessEapResponseForRadius(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eap_datasize)
|
||||||
|
{
|
||||||
|
PPP_LCP *lcp;
|
||||||
|
IPC *ipc;
|
||||||
|
UINT error_code;
|
||||||
|
|
||||||
|
if (p == NULL || eap_packet == NULL || p->EapClient == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcp = EapClientSendEapRequest(p->EapClient, eap_packet, eap_datasize);
|
||||||
|
if (lcp == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (lcp->Code)
|
||||||
|
{
|
||||||
|
case PPP_EAP_CODE_REQUEST:
|
||||||
|
// Send back to client
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
case PPP_EAP_CODE_SUCCESS:
|
||||||
|
if (p->Ipc == NULL)
|
||||||
|
{
|
||||||
|
Debug("PPP Radius creating IPC\n");
|
||||||
|
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, p->Eap_Identity.HubName, p->Eap_Identity.UserName, "", NULL,
|
||||||
|
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||||
|
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
|
||||||
|
true, IPC_LAYER_3);
|
||||||
|
|
||||||
|
if (ipc != NULL)
|
||||||
|
{
|
||||||
|
p->Ipc = ipc;
|
||||||
|
|
||||||
|
// Setting user timeouts
|
||||||
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
if (p->TubeRecv != NULL)
|
||||||
|
{
|
||||||
|
p->TubeRecv->DataTimeout = p->DataTimeout;
|
||||||
|
}
|
||||||
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
|
p->UserConnectionTick = Tick64();
|
||||||
|
p->AuthOk = true;
|
||||||
|
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PPP_EAP_CODE_FAILURE:
|
||||||
|
default:
|
||||||
|
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send success or failure
|
||||||
|
PPP_PACKET* pack;
|
||||||
|
pack = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
|
pack->IsControl = true;
|
||||||
|
pack->Protocol = PPP_PROTOCOL_EAP;
|
||||||
|
pack->Lcp = lcp;
|
||||||
|
if (PPPSendPacketAndFree(p, pack) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Processes request packets
|
// Processes request packets
|
||||||
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
||||||
@ -1754,7 +1853,7 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
||||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL,
|
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL,
|
||||||
IPC_LAYER_3);
|
false, IPC_LAYER_3);
|
||||||
|
|
||||||
if (ipc != NULL)
|
if (ipc != NULL)
|
||||||
{
|
{
|
||||||
@ -3063,10 +3162,10 @@ bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp, bool use_eap)
|
|||||||
|
|
||||||
// Normal MSCHAPv2 only
|
// Normal MSCHAPv2 only
|
||||||
// For EAP-MSCHAPv2, EAP client is created before sending the challenge
|
// For EAP-MSCHAPv2, EAP client is created before sending the challenge
|
||||||
if (p->MsChapV2_UseDoubleMsChapV2 && p->EapClient == NULL && use_eap == false)
|
if (p->UseEapRadius && 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", false, NULL, 0);
|
||||||
|
|
||||||
// We do not know the user's auth type, so do not fail PPP if eap is null
|
// We do not know the user's auth type, so do not fail PPP if eap is null
|
||||||
if (eap)
|
if (eap)
|
||||||
@ -3083,7 +3182,7 @@ bool PPPParseMSCHAP2ResponsePacketEx(PPP_SESSION *p, PPP_LCP *lcp, bool use_eap)
|
|||||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, NULL,
|
||||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
|
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
|
||||||
+ IPC_LAYER_3);
|
false, IPC_LAYER_3);
|
||||||
|
|
||||||
if (ipc != NULL)
|
if (ipc != NULL)
|
||||||
{
|
{
|
||||||
@ -3708,7 +3807,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapSize)
|
|||||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, p->Eap_Identity.HubName, p->Eap_Identity.UserName, "", NULL,
|
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, p->Eap_Identity.HubName, p->Eap_Identity.UserName, "", NULL,
|
||||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, p->Eap_TlsCtx.ClientCert.X,
|
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, p->Eap_TlsCtx.ClientCert.X,
|
||||||
IPC_LAYER_3);
|
false, IPC_LAYER_3);
|
||||||
|
|
||||||
// We use the SAM authentication here, because the handshake can still fail at this point
|
// We use the SAM authentication here, because the handshake can still fail at this point
|
||||||
if (ipc != NULL)
|
if (ipc != NULL)
|
||||||
|
@ -294,7 +294,7 @@ struct PPP_SESSION
|
|||||||
UINT MsChapV2_ErrorCode; // Authentication failure error code of MS-CHAPv2
|
UINT MsChapV2_ErrorCode; // Authentication failure error code of MS-CHAPv2
|
||||||
UINT MsChapV2_PacketId; // MS-CHAPv2 Packet ID
|
UINT MsChapV2_PacketId; // MS-CHAPv2 Packet ID
|
||||||
|
|
||||||
bool MsChapV2_UseDoubleMsChapV2; // Use the double-MSCHAPv2 technique
|
bool UseEapRadius; // Use EAP for RADIUS authentication
|
||||||
EAP_CLIENT *EapClient; // EAP client
|
EAP_CLIENT *EapClient; // EAP client
|
||||||
|
|
||||||
UCHAR ServerInterfaceId[8]; // Server IPv6CP Interface Identifier
|
UCHAR ServerInterfaceId[8]; // Server IPv6CP Interface Identifier
|
||||||
@ -343,6 +343,7 @@ bool PPPProcessCHAPResponsePacketEx(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *
|
|||||||
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);
|
||||||
|
bool PPPProcessEapResponseForRadius(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eap_datasize);
|
||||||
// Request packets
|
// Request packets
|
||||||
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
@ -413,6 +414,7 @@ bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst);
|
|||||||
void GenerateNtPasswordHash(UCHAR *dst, char *password);
|
void GenerateNtPasswordHash(UCHAR *dst, char *password);
|
||||||
void GenerateNtPasswordHashHash(UCHAR *dst_hash, UCHAR *src_hash);
|
void GenerateNtPasswordHashHash(UCHAR *dst_hash, UCHAR *src_hash);
|
||||||
void MsChapV2Server_GenerateChallenge(UCHAR *dst);
|
void MsChapV2Server_GenerateChallenge(UCHAR *dst);
|
||||||
|
void MsChapV2Client_GenerateChallenge(UCHAR *dst);
|
||||||
void MsChapV2_GenerateChallenge8(UCHAR *dst, UCHAR *client_challenge, UCHAR *server_challenge, char *username);
|
void MsChapV2_GenerateChallenge8(UCHAR *dst, UCHAR *client_challenge, UCHAR *server_challenge, char *username);
|
||||||
void MsChapV2Client_GenerateResponse(UCHAR *dst, UCHAR *challenge8, UCHAR *nt_password_hash);
|
void MsChapV2Client_GenerateResponse(UCHAR *dst, UCHAR *challenge8, UCHAR *nt_password_hash);
|
||||||
void MsChapV2Server_GenerateResponse(UCHAR *dst, UCHAR *nt_password_hash_hash, UCHAR *client_response, UCHAR *challenge8);
|
void MsChapV2Server_GenerateResponse(UCHAR *dst, UCHAR *nt_password_hash_hash, UCHAR *client_response, UCHAR *challenge8);
|
||||||
|
@ -1702,6 +1702,9 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
case CLIENT_AUTHTYPE_CERT:
|
case CLIENT_AUTHTYPE_CERT:
|
||||||
authtype_str = _UU("LH_AUTH_CERT");
|
authtype_str = _UU("LH_AUTH_CERT");
|
||||||
break;
|
break;
|
||||||
|
case AUTHTYPE_EXTERNAL:
|
||||||
|
authtype_str = _UU("LH_AUTH_EXTERNAL");
|
||||||
|
break;
|
||||||
case AUTHTYPE_WIREGUARD_KEY:
|
case AUTHTYPE_WIREGUARD_KEY:
|
||||||
authtype_str = _UU("LH_AUTH_WIREGUARD_KEY");
|
authtype_str = _UU("LH_AUTH_WIREGUARD_KEY");
|
||||||
break;
|
break;
|
||||||
@ -1829,6 +1832,11 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
// Anonymous authentication (this have been already attempted)
|
// Anonymous authentication (this have been already attempted)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AUTHTYPE_EXTERNAL:
|
||||||
|
// External authentication already completed
|
||||||
|
auth_ret = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case AUTHTYPE_TICKET:
|
case AUTHTYPE_TICKET:
|
||||||
// Ticket authentication
|
// Ticket authentication
|
||||||
if (PackGetDataSize(p, "ticket") == SHA1_SIZE)
|
if (PackGetDataSize(p, "ticket") == SHA1_SIZE)
|
||||||
@ -1914,7 +1922,7 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
|
|
||||||
if (auth_ret == false)
|
if (auth_ret == false)
|
||||||
{
|
{
|
||||||
// Attempt external authentication registered users
|
// Attempt external authentication
|
||||||
bool fail_ext_user_auth = false;
|
bool fail_ext_user_auth = false;
|
||||||
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
||||||
{
|
{
|
||||||
@ -1923,7 +1931,7 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
|
|
||||||
if (fail_ext_user_auth == false)
|
if (fail_ext_user_auth == false)
|
||||||
{
|
{
|
||||||
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, false, mschap_v2_server_response_20, &radius_login_opt);
|
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth_ret && pol == NULL)
|
if (auth_ret && pol == NULL)
|
||||||
@ -1932,37 +1940,6 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth_ret == false)
|
|
||||||
{
|
|
||||||
// Attempt external authentication asterisk user
|
|
||||||
bool b = false;
|
|
||||||
bool fail_ext_user_auth = false;
|
|
||||||
|
|
||||||
if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
|
|
||||||
{
|
|
||||||
fail_ext_user_auth = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fail_ext_user_auth == false)
|
|
||||||
{
|
|
||||||
AcLock(hub);
|
|
||||||
{
|
|
||||||
b = AcIsUser(hub, "*");
|
|
||||||
}
|
|
||||||
AcUnlock(hub);
|
|
||||||
|
|
||||||
// If there is asterisk user, log on as the user
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
|
|
||||||
if (auth_ret && pol == NULL)
|
|
||||||
{
|
|
||||||
pol = SamGetUserPolicy(hub, "*");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pol != NULL)
|
if (pol != NULL)
|
||||||
{
|
{
|
||||||
no_save_password = pol->NoSavePassword;
|
no_save_password = pol->NoSavePassword;
|
||||||
@ -6742,6 +6719,25 @@ PACK *PackLoginWithAnonymous(char *hubname, char *username)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a packet for external login
|
||||||
|
PACK *PackLoginWithExternal(char *hubname, char *username)
|
||||||
|
{
|
||||||
|
PACK *p;
|
||||||
|
// Validate arguments
|
||||||
|
if (hubname == NULL || username == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = NewPack();
|
||||||
|
PackAddStr(p, "method", "login");
|
||||||
|
PackAddStr(p, "hubname", hubname);
|
||||||
|
PackAddStr(p, "username", username);
|
||||||
|
PackAddInt(p, "authtype", AUTHTYPE_EXTERNAL);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a packet for the additional connection
|
// Create a packet for the additional connection
|
||||||
PACK *PackAdditionalConnect(UCHAR *session_key)
|
PACK *PackAdditionalConnect(UCHAR *session_key)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +134,7 @@ void PackAddPolicy(PACK *p, POLICY *y);
|
|||||||
PACK *PackWelcome(SESSION *s);
|
PACK *PackWelcome(SESSION *s);
|
||||||
PACK *PackHello(void *random, UINT ver, UINT build, char *server_str);
|
PACK *PackHello(void *random, UINT ver, UINT build, char *server_str);
|
||||||
bool GetHello(PACK *p, void *random, UINT *ver, UINT *build, char *server_str, UINT server_str_size);
|
bool GetHello(PACK *p, void *random, UINT *ver, UINT *build, char *server_str, UINT server_str_size);
|
||||||
|
PACK *PackLoginWithExternal(char *hubname, char *username);
|
||||||
PACK *PackLoginWithAnonymous(char *hubname, char *username);
|
PACK *PackLoginWithAnonymous(char *hubname, char *username);
|
||||||
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password);
|
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password);
|
||||||
PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password);
|
PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "Connection.h"
|
#include "Connection.h"
|
||||||
#include "IPC.h"
|
#include "IPC.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
#include "Proto_PPP.h"
|
||||||
|
|
||||||
#include "Mayaqua/DNS.h"
|
#include "Mayaqua/DNS.h"
|
||||||
#include "Mayaqua/Internat.h"
|
#include "Mayaqua/Internat.h"
|
||||||
@ -19,7 +20,7 @@
|
|||||||
#include "Mayaqua/Tick64.h"
|
#include "Mayaqua/Tick64.h"
|
||||||
|
|
||||||
// send PEAP-MSCHAPv2 auth client response
|
// send PEAP-MSCHAPv2 auth client response
|
||||||
bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge)
|
bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge, char *username)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
EAP_MSCHAPV2_RESPONSE msg1;
|
EAP_MSCHAPV2_RESPONSE msg1;
|
||||||
@ -37,13 +38,13 @@ bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_respo
|
|||||||
msg1.Type = EAP_TYPE_MS_AUTH;
|
msg1.Type = EAP_TYPE_MS_AUTH;
|
||||||
msg1.Chap_Opcode = EAP_MSCHAPV2_OP_RESPONSE;
|
msg1.Chap_Opcode = EAP_MSCHAPV2_OP_RESPONSE;
|
||||||
msg1.Chap_Id = e->MsChapV2Challenge.Chap_Id;
|
msg1.Chap_Id = e->MsChapV2Challenge.Chap_Id;
|
||||||
msg1.Chap_Len = Endian16(54 + StrLen(e->Username));
|
msg1.Chap_Len = Endian16(54 + StrLen(username));
|
||||||
msg1.Chap_ValueSize = 49;
|
msg1.Chap_ValueSize = 49;
|
||||||
Copy(msg1.Chap_PeerChallenge, client_challenge, 16);
|
Copy(msg1.Chap_PeerChallenge, client_challenge, 16);
|
||||||
Copy(msg1.Chap_NtResponse, client_response, 24);
|
Copy(msg1.Chap_NtResponse, client_response, 24);
|
||||||
Copy(msg1.Chap_Name, e->Username, MIN(StrLen(e->Username), 255));
|
Copy(msg1.Chap_Name, username, MIN(StrLen(username), 255));
|
||||||
|
|
||||||
if (SendPeapPacket(e, &msg1, 59 + StrLen(e->Username)) &&
|
if (SendPeapPacket(e, &msg1, 59 + StrLen(username)) &&
|
||||||
GetRecvPeapMessage(e, &msg2))
|
GetRecvPeapMessage(e, &msg2))
|
||||||
{
|
{
|
||||||
if (msg2.Type == EAP_TYPE_MS_AUTH &&
|
if (msg2.Type == EAP_TYPE_MS_AUTH &&
|
||||||
@ -300,7 +301,7 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size)
|
|||||||
|
|
||||||
Add(send_packet->AvpList, eap_avp);
|
Add(send_packet->AvpList, eap_avp);
|
||||||
|
|
||||||
response_packet = EapSendPacketAndRecvResponse(e, send_packet);
|
response_packet = EapSendPacketAndRecvResponse(e, send_packet, true);
|
||||||
|
|
||||||
if (response_packet != NULL)
|
if (response_packet != NULL)
|
||||||
{
|
{
|
||||||
@ -502,7 +503,7 @@ bool StartPeapClient(EAP_CLIENT *e)
|
|||||||
Copy(eap1->Data, e->Username, StrLen(e->Username));
|
Copy(eap1->Data, e->Username, StrLen(e->Username));
|
||||||
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 5));
|
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 5));
|
||||||
|
|
||||||
response1 = EapSendPacketAndRecvResponse(e, request1);
|
response1 = EapSendPacketAndRecvResponse(e, request1, true);
|
||||||
|
|
||||||
if (response1 != NULL)
|
if (response1 != NULL)
|
||||||
{
|
{
|
||||||
@ -532,7 +533,7 @@ bool StartPeapClient(EAP_CLIENT *e)
|
|||||||
|
|
||||||
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
||||||
|
|
||||||
response2 = EapSendPacketAndRecvResponse(e, request2);
|
response2 = EapSendPacketAndRecvResponse(e, request2, true);
|
||||||
|
|
||||||
if (response2 != NULL && response2->Parse_EapMessage_DataSize != 0 && response2->Parse_EapMessage != NULL)
|
if (response2 != NULL && response2->Parse_EapMessage_DataSize != 0 && response2->Parse_EapMessage != NULL)
|
||||||
{
|
{
|
||||||
@ -632,7 +633,7 @@ void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send a MSCHAPv2 client auth response1
|
// Send a MSCHAPv2 client auth response1
|
||||||
bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge)
|
bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge, char *username)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
RADIUS_PACKET *request1 = NULL;
|
RADIUS_PACKET *request1 = NULL;
|
||||||
@ -657,20 +658,20 @@ bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_respon
|
|||||||
|
|
||||||
eap1 = ZeroMalloc(sizeof(EAP_MSCHAPV2_RESPONSE));
|
eap1 = ZeroMalloc(sizeof(EAP_MSCHAPV2_RESPONSE));
|
||||||
eap1->Code = EAP_CODE_RESPONSE;
|
eap1->Code = EAP_CODE_RESPONSE;
|
||||||
eap1->Id = e->NextEapId++;
|
eap1->Id = e->LastRecvEapId;
|
||||||
eap1->Len = Endian16(59 + StrLen(e->Username));
|
eap1->Len = Endian16(59 + StrLen(username));
|
||||||
eap1->Type = EAP_TYPE_MS_AUTH;
|
eap1->Type = EAP_TYPE_MS_AUTH;
|
||||||
eap1->Chap_Opcode = EAP_MSCHAPV2_OP_RESPONSE;
|
eap1->Chap_Opcode = EAP_MSCHAPV2_OP_RESPONSE;
|
||||||
eap1->Chap_Id = e->MsChapV2Challenge.Chap_Id;
|
eap1->Chap_Id = e->MsChapV2Challenge.Chap_Id;
|
||||||
eap1->Chap_Len = Endian16(54 + StrLen(e->Username));
|
eap1->Chap_Len = Endian16(54 + StrLen(username));
|
||||||
eap1->Chap_ValueSize = 49;
|
eap1->Chap_ValueSize = 49;
|
||||||
Copy(eap1->Chap_PeerChallenge, client_challenge, 16);
|
Copy(eap1->Chap_PeerChallenge, client_challenge, 16);
|
||||||
Copy(eap1->Chap_NtResponse, client_response, 24);
|
Copy(eap1->Chap_NtResponse, client_response, 24);
|
||||||
Copy(eap1->Chap_Name, e->Username, MIN(StrLen(e->Username), 255));
|
Copy(eap1->Chap_Name, username, MIN(StrLen(username), 255));
|
||||||
|
|
||||||
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 59));
|
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(username) + 59));
|
||||||
|
|
||||||
response1 = EapSendPacketAndRecvResponse(e, request1);
|
response1 = EapSendPacketAndRecvResponse(e, request1, false);
|
||||||
|
|
||||||
if (response1 != NULL)
|
if (response1 != NULL)
|
||||||
{
|
{
|
||||||
@ -713,14 +714,14 @@ bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_respon
|
|||||||
|
|
||||||
eap2 = ZeroMalloc(sizeof(EAP_MSCHAPV2_SUCCESS_CLIENT));
|
eap2 = ZeroMalloc(sizeof(EAP_MSCHAPV2_SUCCESS_CLIENT));
|
||||||
eap2->Code = EAP_CODE_RESPONSE;
|
eap2->Code = EAP_CODE_RESPONSE;
|
||||||
eap2->Id = e->NextEapId++;
|
eap2->Id = e->LastRecvEapId;
|
||||||
eap2->Len = Endian16(6);
|
eap2->Len = Endian16(6);
|
||||||
eap2->Type = EAP_TYPE_MS_AUTH;
|
eap2->Type = EAP_TYPE_MS_AUTH;
|
||||||
eap2->Chap_Opcode = EAP_MSCHAPV2_OP_SUCCESS;
|
eap2->Chap_Opcode = EAP_MSCHAPV2_OP_SUCCESS;
|
||||||
|
|
||||||
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
||||||
|
|
||||||
response2 = EapSendPacketAndRecvResponse(e, request2);
|
response2 = EapSendPacketAndRecvResponse(e, request2, false);
|
||||||
|
|
||||||
if (response2 != NULL)
|
if (response2 != NULL)
|
||||||
{
|
{
|
||||||
@ -770,13 +771,13 @@ bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e)
|
|||||||
|
|
||||||
eap1 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
eap1 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
||||||
eap1->Code = EAP_CODE_RESPONSE;
|
eap1->Code = EAP_CODE_RESPONSE;
|
||||||
eap1->Id = e->NextEapId++;
|
eap1->Id = e->LastRecvEapId;
|
||||||
eap1->Len = Endian16(StrLen(e->Username) + 5);
|
eap1->Len = Endian16(StrLen(e->Username) + 5);
|
||||||
eap1->Type = EAP_TYPE_IDENTITY;
|
eap1->Type = EAP_TYPE_IDENTITY;
|
||||||
Copy(eap1->Data, e->Username, StrLen(e->Username));
|
Copy(eap1->Data, e->Username, StrLen(e->Username));
|
||||||
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 5));
|
Add(request1->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 5));
|
||||||
|
|
||||||
response1 = EapSendPacketAndRecvResponse(e, request1);
|
response1 = EapSendPacketAndRecvResponse(e, request1, false);
|
||||||
|
|
||||||
if (response1 != NULL)
|
if (response1 != NULL)
|
||||||
{
|
{
|
||||||
@ -799,14 +800,14 @@ bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e)
|
|||||||
|
|
||||||
eap2 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
eap2 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
||||||
eap2->Code = EAP_CODE_RESPONSE;
|
eap2->Code = EAP_CODE_RESPONSE;
|
||||||
eap2->Id = e->NextEapId++;
|
eap2->Id = e->LastRecvEapId;
|
||||||
eap2->Len = Endian16(6);
|
eap2->Len = Endian16(6);
|
||||||
eap2->Type = EAP_TYPE_LEGACY_NAK;
|
eap2->Type = EAP_TYPE_LEGACY_NAK;
|
||||||
eap2->Data[0] = EAP_TYPE_MS_AUTH;
|
eap2->Data[0] = EAP_TYPE_MS_AUTH;
|
||||||
|
|
||||||
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
Add(request2->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap2, 6));
|
||||||
|
|
||||||
response2 = EapSendPacketAndRecvResponse(e, request2);
|
response2 = EapSendPacketAndRecvResponse(e, request2, false);
|
||||||
|
|
||||||
if (response2 != NULL && response2->Parse_EapMessage_DataSize != 0 && response2->Parse_EapMessage != NULL)
|
if (response2 != NULL && response2->Parse_EapMessage_DataSize != 0 && response2->Parse_EapMessage != NULL)
|
||||||
{
|
{
|
||||||
@ -849,8 +850,141 @@ LABEL_PARSE_EAP:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send a EAP identity request to Radius
|
||||||
|
PPP_LCP *EapClientSendEapIdentity(EAP_CLIENT *e)
|
||||||
|
{
|
||||||
|
PPP_LCP *lcp = NULL;
|
||||||
|
RADIUS_PACKET *request = NULL;
|
||||||
|
RADIUS_PACKET *response = NULL;
|
||||||
|
EAP_MESSAGE *eap1 = NULL;
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = NewRadiusPacket(RADIUS_CODE_ACCESS_REQUEST, e->NextRadiusPacketId++);
|
||||||
|
EapSetRadiusGeneralAttributes(request, e);
|
||||||
|
|
||||||
|
eap1 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
||||||
|
eap1->Code = EAP_CODE_RESPONSE;
|
||||||
|
eap1->Id = e->LastRecvEapId;
|
||||||
|
eap1->Len = Endian16(StrLen(e->Username) + 5);
|
||||||
|
eap1->Type = EAP_TYPE_IDENTITY;
|
||||||
|
Copy(eap1->Data, e->Username, StrLen(e->Username));
|
||||||
|
Add(request->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, eap1, StrLen(e->Username) + 5));
|
||||||
|
Debug("Radius proxy: send access-request %d with EAP code %d id %d type %d datasize %d\n",
|
||||||
|
request->PacketId, eap1->Code, eap1->Id, eap1->Type, StrLen(e->Username));
|
||||||
|
|
||||||
|
response = EapSendPacketAndRecvResponse(e, request, false);
|
||||||
|
|
||||||
|
if (response != NULL)
|
||||||
|
{
|
||||||
|
if (response->Parse_EapMessage_DataSize >= 5 && response->Parse_EapMessage != NULL)
|
||||||
|
{
|
||||||
|
EAP_MESSAGE *eap2 = response->Parse_EapMessage;
|
||||||
|
UINT datasize = response->Parse_EapMessage_DataSize - 5;
|
||||||
|
lcp = BuildEAPPacketEx(eap2->Code, eap2->Id, eap2->Type, datasize);
|
||||||
|
PPP_EAP *eap_packet = lcp->Data;
|
||||||
|
Copy(eap_packet->Data, eap2->Data, datasize);
|
||||||
|
Debug("Radius proxy: received access-challenge %d with EAP code %d id %d type %d datasize %d\n",
|
||||||
|
response->PacketId, eap2->Code, eap2->Id, eap2->Type, datasize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeRadiusPacket(request);
|
||||||
|
FreeRadiusPacket(response);
|
||||||
|
Free(eap1);
|
||||||
|
|
||||||
|
return lcp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send generic EAP Radius request (client EAP response) and get reply
|
||||||
|
PPP_LCP *EapClientSendEapRequest(EAP_CLIENT *e, PPP_EAP *eap_request, UINT request_datasize)
|
||||||
|
{
|
||||||
|
PPP_LCP *lcp = NULL;
|
||||||
|
RADIUS_PACKET *request = NULL;
|
||||||
|
RADIUS_PACKET *response = NULL;
|
||||||
|
EAP_MESSAGE *eap1 = NULL;
|
||||||
|
UCHAR *pos;
|
||||||
|
UINT remaining;
|
||||||
|
if (e == NULL || eap_request == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = NewRadiusPacket(RADIUS_CODE_ACCESS_REQUEST, e->NextRadiusPacketId++);
|
||||||
|
EapSetRadiusGeneralAttributes(request, e);
|
||||||
|
|
||||||
|
if (e->LastStateSize != 0)
|
||||||
|
{
|
||||||
|
Add(request->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_STATE, 0, 0,
|
||||||
|
e->LastState, e->LastStateSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
eap1 = ZeroMalloc(sizeof(EAP_MESSAGE));
|
||||||
|
eap1->Code = EAP_CODE_RESPONSE;
|
||||||
|
eap1->Id = e->LastRecvEapId;
|
||||||
|
eap1->Len = Endian16(request_datasize + 5);
|
||||||
|
eap1->Type = eap_request->Type;
|
||||||
|
Copy(eap1->Data, eap_request->Data, request_datasize);
|
||||||
|
|
||||||
|
// Fragmentation
|
||||||
|
pos = (UCHAR *)eap1;
|
||||||
|
remaining = request_datasize + 5;
|
||||||
|
while (remaining > 0)
|
||||||
|
{
|
||||||
|
UINT size = MIN(253, remaining);
|
||||||
|
Add(request->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_EAP_MESSAGE, 0, 0, pos, size));
|
||||||
|
pos += size;
|
||||||
|
remaining -= size;
|
||||||
|
}
|
||||||
|
Debug("Radius proxy: send access-request %d with EAP code %d id %d type %d datasize %d\n",
|
||||||
|
request->PacketId, eap1->Code, eap1->Id, eap1->Type, request_datasize);
|
||||||
|
|
||||||
|
response = EapSendPacketAndRecvResponse(e, request, false);
|
||||||
|
|
||||||
|
if (response != NULL)
|
||||||
|
{
|
||||||
|
switch (response->Code)
|
||||||
|
{
|
||||||
|
case RADIUS_CODE_ACCESS_CHALLENGE:
|
||||||
|
if (response->Parse_EapMessage_DataSize >= 5 && response->Parse_EapMessage != NULL)
|
||||||
|
{
|
||||||
|
EAP_MESSAGE *eap2 = response->Parse_EapMessage;
|
||||||
|
UINT datasize = response->Parse_EapMessage_DataSize - 5;
|
||||||
|
lcp = BuildEAPPacketEx(eap2->Code, eap2->Id, eap2->Type, datasize);
|
||||||
|
PPP_EAP *eap_packet = lcp->Data;
|
||||||
|
Copy(eap_packet->Data, eap2->Data, datasize);
|
||||||
|
Debug("Radius proxy: received access-challenge %d with EAP code %d id %d type %d datasize %d\n",
|
||||||
|
response->PacketId, eap2->Code, eap2->Id, eap2->Type, datasize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug("Radius proxy error: received access-challenge %d without EAP\n", response->PacketId);
|
||||||
|
lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, e->LastRecvEapId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RADIUS_CODE_ACCESS_ACCEPT:
|
||||||
|
Debug("Radius proxy: received access-accept %d\n", response->PacketId);
|
||||||
|
lcp = NewPPPLCP(PPP_EAP_CODE_SUCCESS, e->LastRecvEapId);
|
||||||
|
break;
|
||||||
|
case RADIUS_CODE_ACCESS_REJECT:
|
||||||
|
default:
|
||||||
|
Debug("Radius proxy: received access-reject %d\n", response->PacketId);
|
||||||
|
lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, e->LastRecvEapId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeRadiusPacket(request);
|
||||||
|
FreeRadiusPacket(response);
|
||||||
|
Free(eap1);
|
||||||
|
|
||||||
|
return lcp;
|
||||||
|
}
|
||||||
|
|
||||||
// Send a packet and recv a response
|
// Send a packet and recv a response
|
||||||
RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r)
|
RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r, bool parse_inner)
|
||||||
{
|
{
|
||||||
SOCKSET set;
|
SOCKSET set;
|
||||||
UINT64 giveup_tick = 0;
|
UINT64 giveup_tick = 0;
|
||||||
@ -990,7 +1124,7 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r)
|
|||||||
{
|
{
|
||||||
EAP_MESSAGE *eap_msg = (EAP_MESSAGE *)rp->Parse_EapMessage;
|
EAP_MESSAGE *eap_msg = (EAP_MESSAGE *)rp->Parse_EapMessage;
|
||||||
|
|
||||||
if (eap_msg->Type == EAP_TYPE_PEAP)
|
if (parse_inner && eap_msg->Type == EAP_TYPE_PEAP)
|
||||||
{
|
{
|
||||||
EAP_PEAP *peap_message = (EAP_PEAP *)eap_msg;
|
EAP_PEAP *peap_message = (EAP_PEAP *)eap_msg;
|
||||||
|
|
||||||
@ -1166,7 +1300,8 @@ bool EapSendPacket(EAP_CLIENT *e, RADIUS_PACKET *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New EAP client
|
// New EAP client
|
||||||
EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str, char *username, char *hubname)
|
EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str,
|
||||||
|
char *username, char *hubname, UCHAR last_recv_eapid)
|
||||||
{
|
{
|
||||||
EAP_CLIENT *e;
|
EAP_CLIENT *e;
|
||||||
if (server_ip == NULL)
|
if (server_ip == NULL)
|
||||||
@ -1198,7 +1333,7 @@ EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, U
|
|||||||
StrCpy(e->CalledStationStr, sizeof(e->CalledStationStr), hubname);
|
StrCpy(e->CalledStationStr, sizeof(e->CalledStationStr), hubname);
|
||||||
StrCpy(e->ClientIpStr, sizeof(e->ClientIpStr), client_ip_str);
|
StrCpy(e->ClientIpStr, sizeof(e->ClientIpStr), client_ip_str);
|
||||||
StrCpy(e->Username, sizeof(e->Username), username);
|
StrCpy(e->Username, sizeof(e->Username), username);
|
||||||
e->LastRecvEapId = 0;
|
e->LastRecvEapId = last_recv_eapid;
|
||||||
|
|
||||||
e->PEAP_CurrentReceivingMsg = NewBuf();
|
e->PEAP_CurrentReceivingMsg = NewBuf();
|
||||||
|
|
||||||
@ -1679,15 +1814,16 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
|
|||||||
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), opt->In_VpnProtocolState);
|
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), opt->In_VpnProtocolState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the username known to the client instead of parsed by us, or response may be invalid
|
||||||
if (eap->PeapMode == false)
|
if (eap->PeapMode == false)
|
||||||
{
|
{
|
||||||
ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
|
ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
|
||||||
mschap.MsChapV2_ClientChallenge);
|
mschap.MsChapV2_ClientChallenge, mschap.MsChapV2_PPPUsername);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = PeapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
|
ret = PeapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
|
||||||
mschap.MsChapV2_ClientChallenge);
|
mschap.MsChapV2_ClientChallenge, mschap.MsChapV2_PPPUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -215,7 +215,6 @@ struct EAP_CLIENT
|
|||||||
UINT ResendTimeout;
|
UINT ResendTimeout;
|
||||||
UINT GiveupTimeout;
|
UINT GiveupTimeout;
|
||||||
UCHAR TmpBuffer[4096];
|
UCHAR TmpBuffer[4096];
|
||||||
UCHAR NextEapId;
|
|
||||||
UCHAR LastRecvEapId;
|
UCHAR LastRecvEapId;
|
||||||
|
|
||||||
bool PeapMode;
|
bool PeapMode;
|
||||||
@ -249,17 +248,20 @@ RADIUS_AVP *GetRadiusAvp(RADIUS_PACKET *p, UCHAR type);
|
|||||||
void RadiusTest();
|
void RadiusTest();
|
||||||
|
|
||||||
|
|
||||||
EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str, char *username, char *hubname);
|
EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str,
|
||||||
|
char *username, char *hubname, UCHAR last_recv_eapid);
|
||||||
void ReleaseEapClient(EAP_CLIENT *e);
|
void ReleaseEapClient(EAP_CLIENT *e);
|
||||||
void CleanupEapClient(EAP_CLIENT *e);
|
void CleanupEapClient(EAP_CLIENT *e);
|
||||||
bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e);
|
bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e);
|
||||||
bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
|
bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge, char *username);
|
||||||
|
PPP_LCP *EapClientSendEapIdentity(EAP_CLIENT *e);
|
||||||
|
PPP_LCP *EapClientSendEapRequest(EAP_CLIENT *e, PPP_EAP *eap_request, UINT request_datasize);
|
||||||
void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e);
|
void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e);
|
||||||
bool EapSendPacket(EAP_CLIENT *e, RADIUS_PACKET *r);
|
bool EapSendPacket(EAP_CLIENT *e, RADIUS_PACKET *r);
|
||||||
RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r);
|
RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r, bool parse_inner);
|
||||||
|
|
||||||
bool PeapClientSendMsChapv2AuthRequest(EAP_CLIENT *eap);
|
bool PeapClientSendMsChapv2AuthRequest(EAP_CLIENT *eap);
|
||||||
bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
|
bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge, char *username);
|
||||||
|
|
||||||
bool StartPeapClient(EAP_CLIENT *e);
|
bool StartPeapClient(EAP_CLIENT *e);
|
||||||
bool StartPeapSslClient(EAP_CLIENT *e);
|
bool StartPeapSslClient(EAP_CLIENT *e);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "Cedar.h"
|
#include "Cedar.h"
|
||||||
|
#include "Connection.h"
|
||||||
#include "Hub.h"
|
#include "Hub.h"
|
||||||
#include "IPC.h"
|
#include "IPC.h"
|
||||||
#include "Proto_PPP.h"
|
#include "Proto_PPP.h"
|
||||||
@ -420,7 +421,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
bool auth_by_nt = false;
|
bool auth_by_nt = false;
|
||||||
HUB *h;
|
HUB *h;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (hub == NULL || c == NULL || username == NULL)
|
if (hub == NULL || c == NULL || username == NULL || password == NULL || opt == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -438,7 +439,14 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
AcLock(hub);
|
AcLock(hub);
|
||||||
{
|
{
|
||||||
USER *u;
|
USER *u;
|
||||||
u = AcGetUser(hub, ast == false ? username : "*");
|
|
||||||
|
// Find exact user first
|
||||||
|
u = AcGetUser(hub, username);
|
||||||
|
if (u == NULL && ast)
|
||||||
|
{
|
||||||
|
u = AcGetUser(hub, "*");
|
||||||
|
}
|
||||||
|
|
||||||
if (u)
|
if (u)
|
||||||
{
|
{
|
||||||
Lock(u->lock);
|
Lock(u->lock);
|
||||||
@ -447,7 +455,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
{
|
{
|
||||||
// Radius authentication
|
// Radius authentication
|
||||||
AUTHRADIUS *auth = (AUTHRADIUS *)u->AuthData;
|
AUTHRADIUS *auth = (AUTHRADIUS *)u->AuthData;
|
||||||
if (ast || auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
|
if (auth->RadiusUsername == NULL || UniStrLen(auth->RadiusUsername) == 0)
|
||||||
{
|
{
|
||||||
if( IsEmptyStr(h->RadiusRealm) == false )
|
if( IsEmptyStr(h->RadiusRealm) == false )
|
||||||
{
|
{
|
||||||
@ -472,7 +480,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
{
|
{
|
||||||
// NT authentication
|
// NT authentication
|
||||||
AUTHNT *auth = (AUTHNT *)u->AuthData;
|
AUTHNT *auth = (AUTHNT *)u->AuthData;
|
||||||
if (ast || auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
|
if (auth->NtUsername == NULL || UniStrLen(auth->NtUsername) == 0)
|
||||||
{
|
{
|
||||||
name = CopyStrToUni(username);
|
name = CopyStrToUni(username);
|
||||||
}
|
}
|
||||||
@ -508,10 +516,75 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
char suffix_filter[MAX_SIZE];
|
char suffix_filter[MAX_SIZE];
|
||||||
wchar_t suffix_filter_w[MAX_SIZE];
|
wchar_t suffix_filter_w[MAX_SIZE];
|
||||||
UINT interval;
|
UINT interval;
|
||||||
|
EAP_CLIENT *eap = NULL;
|
||||||
|
char password1[MAX_SIZE];
|
||||||
|
UCHAR client_challenge[16];
|
||||||
|
UCHAR server_challenge[16];
|
||||||
|
UCHAR challenge8[8];
|
||||||
|
UCHAR client_response[24];
|
||||||
|
UCHAR ntlm_hash[MD5_SIZE];
|
||||||
|
|
||||||
Zero(suffix_filter, sizeof(suffix_filter));
|
Zero(suffix_filter, sizeof(suffix_filter));
|
||||||
Zero(suffix_filter_w, sizeof(suffix_filter_w));
|
Zero(suffix_filter_w, sizeof(suffix_filter_w));
|
||||||
|
|
||||||
|
// MSCHAPv2 / EAP wrapper for SEVPN
|
||||||
|
if (c->IsInProc == false && StartWith(password, IPC_PASSWORD_MSCHAPV2_TAG) == false)
|
||||||
|
{
|
||||||
|
char client_ip_str[MAX_SIZE];
|
||||||
|
char utf8[MAX_SIZE];
|
||||||
|
|
||||||
|
// Convert the user name to a Unicode string
|
||||||
|
UniToStr(utf8, sizeof(utf8), name);
|
||||||
|
utf8[MAX_SIZE-1] = 0;
|
||||||
|
|
||||||
|
Zero(client_ip_str, sizeof(client_ip_str));
|
||||||
|
if (c != NULL && c->FirstSock != NULL)
|
||||||
|
{
|
||||||
|
IPToStr(client_ip_str, sizeof(client_ip_str), &c->FirstSock->RemoteIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
|
||||||
|
{
|
||||||
|
// Do EAP or PEAP
|
||||||
|
eap = HubNewEapClient(hub->Cedar, hub->Name, client_ip_str, utf8, opt->In_VpnProtocolState, false, NULL, 0);
|
||||||
|
|
||||||
|
// Prepare MSCHAP response and replace plain password
|
||||||
|
if (eap != NULL)
|
||||||
|
{
|
||||||
|
char server_challenge_hex[MAX_SIZE];
|
||||||
|
char client_challenge_hex[MAX_SIZE];
|
||||||
|
char client_response_hex[MAX_SIZE];
|
||||||
|
char eap_client_hex[64];
|
||||||
|
|
||||||
|
MsChapV2Client_GenerateChallenge(client_challenge);
|
||||||
|
GenerateNtPasswordHash(ntlm_hash, password);
|
||||||
|
Copy(server_challenge, eap->MsChapV2Challenge.Chap_ChallengeValue, 16);
|
||||||
|
MsChapV2_GenerateChallenge8(challenge8, client_challenge, server_challenge, utf8);
|
||||||
|
MsChapV2Client_GenerateResponse(client_response, challenge8, ntlm_hash);
|
||||||
|
|
||||||
|
BinToStr(server_challenge_hex, sizeof(server_challenge_hex),
|
||||||
|
server_challenge, sizeof(server_challenge));
|
||||||
|
BinToStr(client_challenge_hex, sizeof(client_challenge_hex),
|
||||||
|
client_challenge, sizeof(client_challenge));
|
||||||
|
BinToStr(client_response_hex, sizeof(client_response_hex),
|
||||||
|
client_response, sizeof(client_response));
|
||||||
|
BinToStr(eap_client_hex, sizeof(eap_client_hex), &eap, 8);
|
||||||
|
Format(password1, sizeof(password1), "%s%s:%s:%s:%s:%s",
|
||||||
|
IPC_PASSWORD_MSCHAPV2_TAG,
|
||||||
|
utf8,
|
||||||
|
server_challenge_hex,
|
||||||
|
client_challenge_hex,
|
||||||
|
client_response_hex,
|
||||||
|
eap_client_hex);
|
||||||
|
password = password1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Todo: Do MSCHAPv2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the Radius server information
|
// Get the Radius server information
|
||||||
if (GetRadiusServerEx2(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, suffix_filter, sizeof(suffix_filter)))
|
if (GetRadiusServerEx2(hub, radius_server_addr, sizeof(radius_server_addr), &radius_server_port, radius_secret, sizeof(radius_secret), &interval, suffix_filter, sizeof(suffix_filter)))
|
||||||
{
|
{
|
||||||
@ -527,13 +600,10 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
name, password, interval, mschap_v2_server_response_20, opt, hub->Name);
|
name, password, interval, mschap_v2_server_response_20, opt, hub->Name);
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
{
|
|
||||||
if (opt != NULL)
|
|
||||||
{
|
{
|
||||||
opt->Out_IsRadiusLogin = true;
|
opt->Out_IsRadiusLogin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Lock(hub->lock);
|
Lock(hub->lock);
|
||||||
}
|
}
|
||||||
@ -541,6 +611,11 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
|||||||
{
|
{
|
||||||
HLog(hub, "LH_NO_RADIUS_SETTING", name);
|
HLog(hub, "LH_NO_RADIUS_SETTING", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eap != NULL)
|
||||||
|
{
|
||||||
|
ReleaseEapClient(eap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1939,6 +1939,7 @@ LH_AUTH_PASSWORD 密码验证
|
|||||||
LH_AUTH_PLAIN_PASSWORD 外部服务器身份验证
|
LH_AUTH_PLAIN_PASSWORD 外部服务器身份验证
|
||||||
LH_AUTH_CERT 证书验证
|
LH_AUTH_CERT 证书验证
|
||||||
LH_AUTH_TICKET 票证验证
|
LH_AUTH_TICKET 票证验证
|
||||||
|
LH_AUTH_EXTERNAL 外部服务器身份验证
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT 连接 "%S": 用户 "%S" 身份验证方法 RADIUS 或 Active Directory (NT 域),但 VPN Server 是 "%S",因为 RADIUS 或 Active Directory (NT 域)不能使用。连接被拒绝。
|
LH_AUTH_RADIUS_NOT_SUPPORT 连接 "%S": 用户 "%S" 身份验证方法 RADIUS 或 Active Directory (NT 域),但 VPN Server 是 "%S",因为 RADIUS 或 Active Directory (NT 域)不能使用。连接被拒绝。
|
||||||
|
@ -1925,6 +1925,7 @@ LH_AUTH_PASSWORD Password authentication
|
|||||||
LH_AUTH_PLAIN_PASSWORD External server authentication
|
LH_AUTH_PLAIN_PASSWORD External server authentication
|
||||||
LH_AUTH_CERT Certificate authentication
|
LH_AUTH_CERT Certificate authentication
|
||||||
LH_AUTH_TICKET Ticket authentication
|
LH_AUTH_TICKET Ticket authentication
|
||||||
|
LH_AUTH_EXTERNAL External server authentication
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
||||||
|
@ -1927,6 +1927,7 @@ LH_AUTH_PASSWORD パスワード認証
|
|||||||
LH_AUTH_PLAIN_PASSWORD 外部サーバー認証
|
LH_AUTH_PLAIN_PASSWORD 外部サーバー認証
|
||||||
LH_AUTH_CERT 証明書認証
|
LH_AUTH_CERT 証明書認証
|
||||||
LH_AUTH_TICKET チケット認証
|
LH_AUTH_TICKET チケット認証
|
||||||
|
LH_AUTH_EXTERNAL 外部サーバー認証
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard 公開鍵認証
|
LH_AUTH_WIREGUARD_KEY WireGuard 公開鍵認証
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN 証明書認証
|
LH_AUTH_OPENVPN_CERT OpenVPN 証明書認証
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT コネクション "%S": ユーザー "%S" の認証方法として RADIUS 認証または Active Directory 認証 (NT ドメイン認証) が指定されましたが、現在の VPN Server のエディションは "%S" であるため、RADIUS 認証または Active Directory 認証 (NT ドメイン認証) を使用することができません。接続は拒否されます。
|
LH_AUTH_RADIUS_NOT_SUPPORT コネクション "%S": ユーザー "%S" の認証方法として RADIUS 認証または Active Directory 認証 (NT ドメイン認証) が指定されましたが、現在の VPN Server のエディションは "%S" であるため、RADIUS 認証または Active Directory 認証 (NT ドメイン認証) を使用することができません。接続は拒否されます。
|
||||||
|
@ -1905,6 +1905,7 @@ LH_AUTH_PASSWORD 암호 인증
|
|||||||
LH_AUTH_PLAIN_PASSWORD 외부 서버 인증
|
LH_AUTH_PLAIN_PASSWORD 외부 서버 인증
|
||||||
LH_AUTH_CERT 인증서 인증
|
LH_AUTH_CERT 인증서 인증
|
||||||
LH_AUTH_TICKET 티켓 인증
|
LH_AUTH_TICKET 티켓 인증
|
||||||
|
LH_AUTH_EXTERNAL 외부 서버 인증
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT 연결 "%S"사용자 "%S"의 인증 방법으로 RADIUS 인증 또는 Active Directory 인증 (NT 도메인 인증)이 지정 되었으나, 현재 VPN Server 버전은 "%S"이기 때문에 RADIUS 인증 또는 Active Directory 인증 (NT 도메인 인증)을 사용할 수 없습니다. 연결이 거부됩니다.
|
LH_AUTH_RADIUS_NOT_SUPPORT 연결 "%S"사용자 "%S"의 인증 방법으로 RADIUS 인증 또는 Active Directory 인증 (NT 도메인 인증)이 지정 되었으나, 현재 VPN Server 버전은 "%S"이기 때문에 RADIUS 인증 또는 Active Directory 인증 (NT 도메인 인증)을 사용할 수 없습니다. 연결이 거부됩니다.
|
||||||
|
@ -1924,6 +1924,7 @@ LH_AUTH_PASSWORD Senha
|
|||||||
LH_AUTH_PLAIN_PASSWORD External server authentication
|
LH_AUTH_PLAIN_PASSWORD External server authentication
|
||||||
LH_AUTH_CERT Certificate authentication
|
LH_AUTH_CERT Certificate authentication
|
||||||
LH_AUTH_TICKET Ticket authentication
|
LH_AUTH_TICKET Ticket authentication
|
||||||
|
LH_AUTH_EXTERNAL External server authentication
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
||||||
|
@ -1924,6 +1924,7 @@ LH_AUTH_PASSWORD Password authentication
|
|||||||
LH_AUTH_PLAIN_PASSWORD External server authentication
|
LH_AUTH_PLAIN_PASSWORD External server authentication
|
||||||
LH_AUTH_CERT Certificate authentication
|
LH_AUTH_CERT Certificate authentication
|
||||||
LH_AUTH_TICKET Ticket authentication
|
LH_AUTH_TICKET Ticket authentication
|
||||||
|
LH_AUTH_EXTERNAL External server authentication
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
LH_AUTH_RADIUS_NOT_SUPPORT Connection "%S": The authentication method of the user "%S" has been specified as RADIUS Authentication or Active Directory Authentication (NT Domain Authentication). However, the edition of the VPN Server is "%S". This edition does not support RADIUS Authentication nor Active Directory Authentication (NT Domain Authentication). The connection will be denied.
|
||||||
|
@ -1941,6 +1941,7 @@ LH_AUTH_PASSWORD 密碼驗證
|
|||||||
LH_AUTH_PLAIN_PASSWORD 外部伺服器身份驗證
|
LH_AUTH_PLAIN_PASSWORD 外部伺服器身份驗證
|
||||||
LH_AUTH_CERT 證書驗證
|
LH_AUTH_CERT 證書驗證
|
||||||
LH_AUTH_TICKET 票證驗證
|
LH_AUTH_TICKET 票證驗證
|
||||||
|
LH_AUTH_EXTERNAL 外部伺服器身份驗證
|
||||||
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
LH_AUTH_WIREGUARD_KEY WireGuard public key authentication
|
||||||
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
LH_AUTH_OPENVPN_CERT OpenVPN certificate authentication
|
||||||
LH_AUTH_RADIUS_NOT_SUPPORT 連接 "%S": 用戶 "%S" 身份驗證方法 RADIUS 或 Active Directory (NT 域),但 VPN Server 是 "%S",因為 RADIUS 或 Active Directory (NT 域)不能使用。連接被拒絕。
|
LH_AUTH_RADIUS_NOT_SUPPORT 連接 "%S": 用戶 "%S" 身份驗證方法 RADIUS 或 Active Directory (NT 域),但 VPN Server 是 "%S",因為 RADIUS 或 Active Directory (NT 域)不能使用。連接被拒絕。
|
||||||
|
Loading…
Reference in New Issue
Block a user