1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Support all EAP methods for PPP sessions with RADIUS

This commit is contained in:
Yihong Wu 2023-02-25 06:18:56 +00:00
parent e81ecbb0ec
commit 4ff9c6393a
20 changed files with 334 additions and 41 deletions

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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,
&param->ClientIp, param->ClientPort, &param->ServerIp, param->ServerPort, &param->ClientIp, param->ClientPort, &param->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);

View File

@ -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);

View File

@ -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)
{ {

View File

@ -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)

View File

@ -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);

View File

@ -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)
@ -6711,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)
{ {

View File

@ -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);

View File

@ -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"
@ -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)
{ {
@ -657,7 +658,7 @@ 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(e->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;
@ -670,7 +671,7 @@ bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_respon
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(e->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();

View File

@ -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,14 +248,17 @@ 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);
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);

View File

@ -546,7 +546,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
if (hub->RadiusConvertAllMsChapv2AuthRequestToEap) if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
{ {
// Do EAP or PEAP // Do EAP or PEAP
eap = HubNewEapClient(hub->Cedar, hub->Name, client_ip_str, utf8, opt->In_VpnProtocolState); eap = HubNewEapClient(hub->Cedar, hub->Name, client_ip_str, utf8, opt->In_VpnProtocolState, false, NULL, 0);
// Prepare MSCHAP response and replace plain password // Prepare MSCHAP response and replace plain password
if (eap != NULL) if (eap != NULL)

View File

@ -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 域)不能使用。连接被拒绝。

View File

@ -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.

View File

@ -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 ドメイン認証) を使用することができません。接続は拒否されます。

View File

@ -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 도메인 인증)을 사용할 수 없습니다. 연결이 거부됩니다.

View File

@ -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.

View File

@ -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.

View File

@ -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 域)不能使用。連接被拒絕。